webdriverio
Version:
Next-gen browser and mobile automation test framework for Node.js
136 lines (105 loc) • 2.79 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _utils = require("@wdio/utils");
const TIMEOUT_ERROR = 'timeout';
class Timer {
constructor(delay, timeout, fn, leading) {
this._delay = delay;
this._timeout = timeout;
this._fn = fn;
this._leading = leading;
this._conditionExecutedCnt = 0;
if (_utils.hasWdioSyncSupport && !fn.name.includes('async') && Boolean(global.browser)) {
this._fn = () => (0, _utils.runFnInFiberContext)(fn)();
}
const retPromise = new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
this.start();
return retPromise;
}
start() {
this._start = Date.now();
this._ticks = 0;
emitTimerEvent({
id: this._start,
start: true
});
if (this._leading) {
this.tick();
} else {
this._timeoutId = setTimeout(this.tick.bind(this), this._delay);
}
this._mainTimeoutId = setTimeout(() => {
if (!this.wasConditionExecuted()) {
return;
}
emitTimerEvent({
id: this._start,
timeout: true
});
const reason = this.lastError || new Error(TIMEOUT_ERROR);
this._reject(reason);
this.stop();
}, this._timeout);
}
stop() {
if (this._timeoutId) {
clearTimeout(this._timeoutId);
}
this._timeoutId = null;
}
stopMain() {
emitTimerEvent({
id: this._start
});
clearTimeout(this._mainTimeoutId);
}
tick() {
const result = this._fn();
if (typeof result.then !== 'function') {
if (!result) {
return this.checkCondition(new Error('return value was never truthy'));
}
return this.checkCondition(null, result);
}
result.then(res => this.checkCondition(null, res), err => this.checkCondition(err));
}
checkCondition(err, res) {
++this._conditionExecutedCnt;
this.lastError = err;
if (res) {
this._resolve(res);
this.stop();
this.stopMain();
return;
}
let diff = Date.now() - this._start - this._ticks++ * this._delay;
let delay = Math.max(0, this._delay - diff);
this.stop();
if (this.hasTime(delay)) {
this._timeoutId = setTimeout(this.tick.bind(this), delay);
} else {
this.stopMain();
const reason = this.lastError || new Error(TIMEOUT_ERROR);
this._reject(reason);
}
}
hasTime(delay) {
return Date.now() - this._start + delay <= this._timeout;
}
wasConditionExecuted() {
return this._conditionExecutedCnt > 0;
}
}
function emitTimerEvent(payload) {
if (_utils.hasWdioSyncSupport) {
process.emit('WDIO_TIMER', payload);
}
}
var _default = Timer;
exports.default = _default;