1
votes

Attempting to run acceptance tests in Ember:

test('successful login', (assert) => {

  Ember.run(() => {
    visit('/signin');
    fillIn('#email', '[email protected]');
    fillIn('#password', 'password');
    click(':submit');

    andThen(function() {
      assert.equal(currentURL(), '/');
    });
  });
});

Occasionally (and seemingly randomly) yields the error:

"Global error: Error: Assertion Failed: You have turned on testing mode, which disabled the run-loop's autorun. You will need to wrap any code with asynchronous side-effects in a run..."

I was able to get a working version:

test('successful login', (assert) => {
  const done = assert.async();

  Ember.run(() => {
    visit('/signin').then(() => {
      fillIn('#email', '[email protected]').then(() => {
        fillIn('#password', 'keen').then(() => {
          click(':submit').then(() => {
            assert.equal(currentURL(), '/');
            done();
          });
        });
      });
    });
  });
});

However, if I include a second test making use of the same route (for an unsuccessful login), one of them almost always ends up with the error listed above.

I am wondering what I am not understanding about the run-loop, Ember.run, and how to test with async behavior. Any help or pointers towards a good resource would be greatly appreciated!

2
Why are you wrapping everything in Ember.run? That is not needed and likely the cause of your issues.steveax

2 Answers

0
votes

According to the guide, your code should be like this:

test('successful login', (assert) => {
  visit('/signin');
  fillIn('#email', '[email protected]');
  fillIn('#password', 'password');
  click(':submit');

  andThen(function() {
    assert.equal(currentURL(), '/');
  });
});

You don't need to add an Ember.run to your cases.

0
votes

Most commonly, this problem occurs when you're doing something (asynchronously) in your application that isn't properly wrapped for Ember (by wrapped I mean executed inside the Ember run loop).

Most common causes

  1. You attached an event handler to the DOM, either directly or with jQuery without wrapping interaction with the Ember application in Ember.run()
  2. You executed a XHR (asynchronous), either directly or with jQuery without wrapping interaction with the Ember application inside the callback in Ember.run()

Generic fix

When you cause code execution that interacts with your application outside the runloop (XHR callback or event handlers) wrap that code with Ember.run().

Events:

Ember.$('div').on('mouseover',function() {
    Ember.run(function() {
       // Interaction with application
    });
});

XHR/Ajax:

Ember.$.ajax({
    success: function() {
        Ember.run(function() {
           // Interaction with application
        });
    }
});

Best practices

  1. When working with DOM events:
  2. When you want to do AJAX/XHR use ember-ajax (https://github.com/ember-cli/ember-ajax)