lib/actions.js
function waitForPage(page, optsOrFn) {
	var self = this;
	var args, value, fname, timeout = self.options.timeout, fn;

	if(typeof optsOrFn === "function"){
			fn = optsOrFn;
			args = Array.prototype.slice.call(arguments);
			value = args.pop();
			fname = fn.name || '<anonymous>';
	} else if(typeof optsOrFn === "object"){
			fn = optsOrFn.fn;
			args = [page, fn].concat(optsOrFn.args || []);
			value = optsOrFn.value;
			fname = fn.name || '<anonymous>';
			if(optsOrFn.timeout){
				timeout = optsOrFn.timeout;
			}
	}

	debug.apply(debug, ['.waitFor()', fname].concat(args.slice(2)));
	return this.ready.then(function() {
		return new HorsemanPromise(function(resolve, reject) {
			var start = Date.now();
			var checkInterval = setInterval(function waitForCheck() {
				var _page = page || self.page;
				var diff = Date.now() - start;
				if (diff > timeout) {
					clearInterval(checkInterval);
					debug('.waitFor() timed out');
					if (typeof _page.onTimeout === 'function') {
						_page.onTimeout('waitFor');
					}
					reject(new TimeoutError(
							'timeout during .waitFor() after ' + diff + ' ms'));
				} else {
					return evaluatePage.apply(self, args)
						.tap(function(res) {
							debugv('.waitFor() iteration',
									fname,
									res,
									diff,
									self.id
							);
						})
						.then(function(res) {
							if (res === value) {
								debug('.waitFor() completed successfully');
								clearInterval(checkInterval);
								resolve();
							}
						})
						.catch(function(err) {
							clearInterval(checkInterval);
							reject(err);
						});
				}
			}, self.options.interval);
		});
	});
}
function waitForPage(page, optsOrFn) {
	var self = this;
	var args, value, fname, timeout = self.options.timeout, fn;

	if(typeof optsOrFn === "function"){
			fn = optsOrFn;
			args = Array.prototype.slice.call(arguments);
			value = args.pop();
			fname = fn.name || '<anonymous>';
	} else if(typeof optsOrFn === "object"){
			fn = optsOrFn.fn;
			args = [page, fn].concat(optsOrFn.args || []);
			value = optsOrFn.value;
			fname = fn.name || '<anonymous>';
			if(optsOrFn.timeout){
				timeout = optsOrFn.timeout;
			}
	}

	debug.apply(debug, ['.waitFor()', fname].concat(args.slice(2)));
	return this.ready.then(function() {
		return new HorsemanPromise(function(resolve, reject) {
			var start = Date.now();
			var checkInterval = setInterval(function waitForCheck() {
				var _page = page || self.page;
				var diff = Date.now() - start;
				if (diff > timeout) {
					clearInterval(checkInterval);
					debug('.waitFor() timed out');
					if (typeof _page.onTimeout === 'function') {
						_page.onTimeout('waitFor');
					}
					reject(new TimeoutError(
							'timeout during .waitFor() after ' + diff + ' ms'));
				} else {
					return evaluatePage.apply(self, args)
						.tap(function(res) {
							debugv('.waitFor() iteration',
									fname,
									res,
									diff,
									self.id
							);
						})
						.then(function(res) {
							if (res === value) {
								debug('.waitFor() completed successfully');
								clearInterval(checkInterval);
								resolve();
							}
						})
						.catch(function(err) {
							clearInterval(checkInterval);
							reject(err);
						});
				}
			}, self.options.interval);
		});
	});
}
Waits for a function to evaluate to a given value on the given page
@param {Page | undefined} page
@param {function | object} optsOrFn - If optsOrFn is a function, use the classic signature waitForPage(page, fn, arg1, arg2, value), If arg is an object, use waitForPage(page, options)
@param {array} optsOrFn.args - arguments of fn
@param {function} optsOrFn.fn - function to evaluate
@param {*} optsOrFn.value - expected value of function
@param {number} [optsOrFn.timeout=null] - timeout in ms
@param {...*} [arguments]
@param {*} value
@emits Horseman#TimeoutError