Skip to content

Commit

Permalink
Merge pull request #844 from mjhm/mjhm-waituntil-interval
Browse files Browse the repository at this point in the history
add waitUntil interval
  • Loading branch information
christian-bromann committed Oct 28, 2015
2 parents f0092c4 + 3b19b93 commit d1f5354
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 20 deletions.
44 changes: 26 additions & 18 deletions lib/commands/waitUntil.js
Expand Up @@ -27,7 +27,8 @@
*
*
* @param {Function|Promise} condition condition to wait on
* @param {Number=} ms timeout in ms (default: 500)
* @param {Number=} timeout timeout in ms (default: 500)
* @param {Number=} interval interval between condition checks (default: 250)
*
* @uses utility/pause
* @type utility
Expand All @@ -40,17 +41,7 @@ var q = require('q'),
d.reject(new ErrorHandler.CommandError('Promise never resolved with an truthy value'));
};

module.exports = function waitUntil(condition, ms, starttime) {

starttime = starttime || new Date().getTime();

/*!
* ensure that ms is set properly
*/
if (typeof ms !== 'number') {
ms = this.options.waitforTimeout;
}

function waitUntilPrivate(condition, timeout, interval, starttime) {
var self = this,
defer = q.defer(),
promise;
Expand All @@ -64,38 +55,55 @@ module.exports = function waitUntil(condition, ms, starttime) {
}

var now = new Date().getTime();
var timeLeft = ms - (now - starttime);
var timeLeft = timeout - (now - starttime);
timeLeft = timeLeft < 0 ? 0 : timeLeft;

if(!timeLeft) {
reject(defer);
return defer.promise;
}

var timeout = setTimeout(function() {
var timeoutId = setTimeout(function() {
reject(defer);
}, timeLeft < 0 ? 0 : timeLeft);

promise.then(function(res) {
clearTimeout(timeout);
clearTimeout(timeoutId);

if(!res) {
if(q.isPromiseAlike(condition)) {
defer.reject(new ErrorHandler.CommandError('Promise was fulfilled with a falsy value'));
}

return defer.resolve(self.pause(250).waitUntil(condition, ms, starttime));
return defer.resolve(self.pause(interval)
.then(waitUntilPrivate.bind(self, condition, timeout, interval, starttime)));
}

defer.resolve(res);

}, function(err) {
clearTimeout(timeout);
clearTimeout(timeoutId);

defer.reject(new ErrorHandler.CommandError('Promise was fulfilled but got rejected with the following reason: ' + err));

});

return defer.promise;

}

module.exports = function waitUntil(condition, timeout, interval) {
/*!
* ensure that timeout and interval are set properly
*/
if (typeof timeout !== 'number') {
timeout = this.options.waitforTimeout;
}

if (typeof interval !== 'number') {
interval = this.options.waitforInterval;
}

var starttime = new Date().getTime();

return waitUntilPrivate.call(this, condition, timeout, interval, starttime);
};
3 changes: 2 additions & 1 deletion lib/webdriverio.js
Expand Up @@ -31,6 +31,7 @@ module.exports = function WebdriverIO(args, modifier) {
var options = merge({
protocol: 'http',
waitforTimeout: 500,
waitforInterval: 250,
coloredLogs: true,
logLevel: 'silent',
baseUrl: null
Expand Down Expand Up @@ -398,4 +399,4 @@ module.exports = function WebdriverIO(args, modifier) {
});

return unit;
};
};
50 changes: 49 additions & 1 deletion test/spec/functional/waitUntil.js
Expand Up @@ -60,6 +60,34 @@ describe('waitUntil', function() {
});
});

it('should pass fast with a short waitfor interval', function() {
var defer = q.defer();

setTimeout(function() {
defer.resolve('foobar');
}, 50);

return this.client.waitUntil(function() {
return defer.promise;
}, 100, 20).then(function(res) {
res.should.be.equal('foobar');
});
});

it('should timeout with a long waitfor interval', function() {
var defer = q.defer();

setTimeout(function() {
defer.resolve('foobar');
}, 50);

return this.client.waitUntil(function() {
return defer.promise;
}, 100, 250).catch(function(err) {
err.message.should.match(/Promise never resolved with an truthy value/);
});
});

it('should allow a promise condition', function() {
var defer = q.defer();

Expand All @@ -72,4 +100,24 @@ describe('waitUntil', function() {
});
});

});

it('should check a condition multiple times', function() {
var defer = q.defer(),
flag = false,
conditionCalledCount = 0,
testCondition = function () {
conditionCalledCount += 1;
return q(flag);
};

setTimeout(function() {
flag = 'foobar';
}, 50);

return this.client.waitUntil(testCondition, 100, 20).then(function(res) {
res.should.equal('foobar');
conditionCalledCount.should.equal(4);
});
});

});

0 comments on commit d1f5354

Please sign in to comment.