When should we use .then with Protractor Promise?
The answer of this question can be found in this post : http://spin.atomicobject.com/2014/12/17/asynchronous-testing-protractor-angular/
That is :
- Protractor enqueue all driver commands in the ControlFlow,
- when you need the result of a driver command you should use .then,
- when you don't need the result of a driver you can avoid .then but all following instructions must be enqueued in the ControlFlow else they will be run before commands in the queue leading to unpredictable result. So, if you want to run a non driver tests command, you should add it into the .then callback or wrap the test into a Promise and enqueue the test in the ControlFlow. See example below.
Here is an example of my test working without .then :
log.debug('test0');
// enqueue the click
submitButton.click();
var message = $('.alert-success');
// enqueue the wait for message to be visible
browser.wait(EC.visibilityOf(message), 5000);
log.debug('test1');
// enqueue a test
expect(message.isPresent()).to.be.eventually.true;
log.debug('test2');
// a function returning a promise that does an async test (check in MongoDB Collection)
var testAccount = function () {
var deferred = protractor.promise.defer();
// Verify that an account has been created
accountColl.find({}).toArray(function (err, accs) {
log.debug('test5');
expect(err).to.not.exist;
log.debug('test6');
expect(accs.length).to.equal(1);
return deferred.fulfill();
});
return deferred.promise;
};
log.debug('test3');
// Enqueue the testAccount function
browser.controlFlow().execute(testAccount);
log.debug('test4');
Output is now what we expect :
test0
test1
test2
test3
test4
test5
test6