Setting up testing

I am trying to write a simple Ember integration test and continue to get the frustrating run loop error despite using Ember.run. I’ve had a nightmare of a time trying to get this to work, if anyone could help me I’d be so grateful. Specifically, I can see the test sign in and begin loading the next page (as it should), but as soon as the test finishes I get that error. This is regarding the second test, the first passes (as nothing is async I believe).

import Ember from 'ember';
import startApp from 'jobs-tuftsdaily/tests/helpers/start-app';
import exists from 'jobs-tuftsdaily/tests/helpers/start-app';

var App;

module('Integration - Landing Page', {
    setup: function() {
        App = startApp();
    },
    teardown: function() {
       Ember.run(App, 'destroy');
    }
});

test('Should load content', function() {
  visit('/').then(function() {
    ok(exists("*"), "Found HTML!");
    ok(exists('label:eq(4)'), "Slug label on page");
  });
});

test('Should sign in test user', function() {
  Ember.run(function() {
    visit('/').andThen(function() {
      return fillIn("input[name=email]", "test@test.com");
    }).andThen(function() {
      return fillIn("input[type=password]", "password");
    }).andThen(function() {
      return click("button");
    }).andThen(function() {
      ok(1, "stupid test passed");
    });
  });
});

I also modified it with the same issue:

test('Should sign in test user', function() {
  expect(2);

  Ember.run(function() {
    visit('/');
    fillIn("input[name=email]", "test@test.com");
    fillIn("input[type=password]", "password");
    click("button");

    andThen(function() {
      ok(true, "stupid test passed");
    });
  });
});

You have to use Ember.run in your application code. Anywhere there is async code, wrap it in an Ember.run.

Examples

With AJAX callbacks:

    App.User.login(data).then(function(response) {

      Ember.run(function() {
        self.handleLoginSuccess(response.user);
      });

    }, function(error) {

      Ember.run(function() {
        self.handleLoginError(error);
      });

    });

When setting a property:

Ember.run(function() {
    this.set('propertyName', newProperty);
});

It may seem annoying at first, but it makes sense once you understand what Ember has been doing for you behind the scenes with the Autorun. Ember has been wrapping your Async code automagically. In testing, that is disabled. It’s better to learn more about the run loop, and manage it yourself to make you app testable.

I hope this helps.

I can’t seriously have to wrap ALL my async calls in Ember.run in my application code just to test my application? Or do I? That seems incredibly tedious?

I have it confirmed from Toran Billups who gave a talk on testing in Ember at Ember Conf 2015. You do need to wrap your app code with the Ember run like I had posted. You can find libraries like one at his repo that abstracts it.

https://github.com/toranb/ember-promise/blob/master/addon/mixins/promise.js

I’ll try this out! Thank you for your help.

1 Like