Issue #959💬 AnsweredOpened March 16, 2018by tommedema1 reactions

Intermittent test failure on `dev` branch due to race condition

快速解答by tommedema1

I haven't seen this in a while. Will close for now.

Read full answer below ↓

Question

I recommend adding --bail after the mocha command in package.json's test to make this easier to see, e.g.:

"test": "cross-env NODE_PATH=./src mocha --bail --compilers js:babel-core/register --require test/helper.js --timeout 10000 --recursive test/main.js",

On the latest dev branch, this is easy to reproduce by simply running npm test many times:

npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test && npm test

Sooner or later you will get:

  1 failing

  1) Main SelectorManager Views E2E tests "before each" hook:
     Uncaught TypeError: this.get(...).getComponent is not a function
      at child.getCss (src/editor/model/Editor.js:308:43)
      at Object.store (src/css_composer/index.js:154:52)
      at src/editor/model/Editor.js:345:19
      at Array.forEach (<anonymous>)
      at child.store (src/editor/model/Editor.js:344:27)
      at child.updateChanges (src/editor/model/Editor.js:119:12)
      at triggerEvents (node_modules/backbone/backbone.js:371:57)
      at triggerApi (node_modules/backbone/backbone.js:356:19)
      at eventsApi (node_modules/backbone/backbone.js:155:16)
      at child.Events.trigger (node_modules/backbone/backbone.js:346:5)
      at child.set (node_modules/backbone/backbone.js:516:16)
      at Timeout._onTimeout (src/editor/model/Editor.js:187:14)

This seems to go away if you .skip this test in test/specs/selector_manager/e2e/ClassManager.js on line 74:

it.skip('Class imported into component is the same model from main container', function() {
          var model = components.add({ classes: ['test1'] });
          var clModel = model.get('classes').at(0);
          var clModel2 = gjs.editor
            .get('SelectorManager')
            .getAll()
            .at(0);
          expect(clModel).toEqual(clModel2);
        });

Of course, that's not a solution. But it may indicate what the underlying issue is. It looks like a race condition of some sort.

It also goes away if you comment out the event listeners editor/model/Editor.js:

// Load modules
    deps.forEach(name => this.loadModule(name));
    // this.on('change:selectedComponent', this.componentSelected, this);
    // this.on('change:changesCount', this.updateChanges, this);

Perhaps the modules have not entirely loaded yet and there are already changes to be processed? Resulting in const wrp = this.get('DomComponents').getComponent(); on line 308 in Editor.js to throw.

Should we wait for all modules to have loaded prior to attaching the event listeners?

Answers (3)

tommedemaApril 12, 2018

I haven't seen this in a while. Will close for now.

artfMarch 17, 2018

Should we wait for all modules to have loaded prior to attaching the event listeners?

Mmmm that piece of code is running synchronously so I don't think it's gonna help

BTW never faced this issue within my environment 🤔

tommedemaMarch 17, 2018

@artf it's easily reproducible here. Try to run it repeatedly as suggested above.

Here's proof:

untitled-3

My environment:

OSX High Sierra 10.13.3 Node.js v9.2.1 Latest rapes dev branch commit #e6593e7ad9a

For some reason this.get('DomComponents') returns null when it should return the wrapper on line 308 in editor/model/Editor.js

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Free option

Check the open-source GrapesJS plugins on GitHub or run a quick search in our free catalog.

Browse free plugins →
Premium option

Premium plugins ship with support, regular updates, and production-ready features — save days of integration work.

Browse premium plugins →

Related tutorials

In-depth guides on the same topic.

All tutorials →

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.