Testing with a promise in an action


#1

I’m trying to write some acceptance tests using ember-testing. I have a test like the following:

  expect(1);

  visit("/sign-in");
  fillIn("[name=email]", "test@example.com");
  fillIn("[name=password]", "abcd1234");
  click(".button-loggins");

  andThen(function() {
    equal(currentRouteName(), "products.index");
  });

When I click the button, the signIn action on a route triggers. The action calls save() on a model and then do a little more work when that model’s promise resolves. Here is that action:

    signIn: function(session) {
      // during test, gets here before assertion
      session.save().then(function(session) {
        // set the user as signed in
        // assertion already run by the time this is resolved
      });
    });
  } 

The problem is, the route (and therefore ember-testing) doesn’t actually know anything about that last promise, so the andThen in the test runs before the final resolve.

Is there a better way to handle the promise on the button click? Or something small I’m missing?


#2

Thanks to the help of @rwjblue I was able to pin this on a bug in ember-testing. See my PR for more details.


#3

I have basically the same issue except I’m issuing a raw ajax call (not through a data layer.) For me the test gets to the code inside the andThen prior to the ajax call completing.

Controller

actions: {

  next: function() {

    promise = ic.ajax.request({
      url:         '/users',
      type:        'POST',
      data:        data,
      dataType:    'json',
      contentType: 'application/x-www-form-urlencoded'
    }).then(function(result) {
      this.send('createSucceeded', data)
    },function(result) {
      # GETS HERE SECOND (i'm testing a failure)
      this.send('createFailed', result.jqXHR)
    ).finally(function() {
      this.set("saving", false)
    })
  }

}

Test

fillIn('[data-test=first_name] input', 'Person')
fillIn('[data-test=last_name] input', 'Man')
click('[data-test=next]')
andThen(function() {
    # GETS HERE FIRST
    ok($('[data-test=email] .ui.red.pointing.label').length == 1, "errors aren't displaying")
})

This is running on Ember 1.5.1. I can’t readily tell whether the referenced pull request was included in 1.5.1 but it seems likely. I may try to upgrade to a beta to see if it solves the problem.

Without that fix though I’m having trouble coming up with a good solution to this problem. The test just isn’t waiting and it runs the OK assert prior to the ajax method finishing.


#4

Found the issue for anyone who is looking. If you have included httpRespond it removes the callbacks for ajaxStart/ajaxStop/ajaxSend/ajaxComplete even if you aren’t using the library. This removes the event tracking that Ember is using (it seems @trek, the author of httpRespond, is against or wants to find a better way.) You can see his comment on the pull request above.

For now I’m removing httpRespond to see if I can get this going without any http mocking.