I have some async WebDriverJS processing that is being skipped because the test is completing before they are are being resolve. How do I get protractor to wait ?
e.g.: (both of these tests should fail (potential ticket submitted)
it('test promise ', function (done) {
var d = protractor.promise.defer();
d.fulfill(true)
d.promise.then(function (item) {
console.log("fulfill", item);
});
expect(d.promise)
.toBe(false);
console.log("test done");
});
it('test promise with timeout ', function (done) {
var d = protractor.promise.defer();
setTimeout(function () {
console.log("fulfill");
d.fulfill(true)
}, 3000);
d.promise.then(function (item) {
console.log("fulfill", item);
});
expect(d.promise)
.toBe(false);
console.log("test done");
});
Let me know if you need more information ... ?
This will return true.. if you remove the timeout and just set fulfill it will work...
Protractor side
The fix for this has been merged 11 days ago
You can have it working with createFlow
but solution will be much simpler, just call done()
after fulfill
like this:
it('test promise with setTimeout ', function(done) {
var d = protractor.promise.defer();
setTimeout(function() {
console.log("fulfill");
d.fulfill('ok');
done();
}, 3000);
expect(d).toBe('ok');
});
Currently on master branch so expect this to be shipped in protractor >= 0.23.0
Web app side (informative)
Protractor doesn't know how to wait for setTimeout
But does know how to wait for $timeout
I couldn't get Nix's example to work and so I took Kato's suggestion and did the following:
describe('Tests stuff', function () {
function do_work() {
var d = protractor.promise.defer();
protractor.promise.controlFlow().execute(function () {
setTimeout(function () {
console.log("fulfill");
d.fulfill(true)
}, 3000);
});
return d;
}
it('test promise with timeout ', function () {
protractor.promise.controlFlow().wait(do_work).then(function (done) {
console.log("test done:" + done);
});
});
});
The out put is as expected and the method waits correctly, and then follows the next flow. My output:
Started
fulfill
test done:true
I'm sure there's many other ways to get this to work, however this worked for me.
I need someone to validate this is the correct way to do it.. but I believe the issue was the promise was not being added to the current control flow.
Solution:
it('test promise with timeout ', function (done) {
var wait = protractor.promise.createFlow(function(flow){
var d = protractor.promise.defer();
flow.execute(function(){
setTimeout(function () {
console.log("fulfill");
d.fulfill(true)
}, 3000);
});
});
expect(wait).toBe(false);
console.log("test done");
});