UNPKG

webdriverio

Version:

Next-gen browser and mobile automation test framework for Node.js

136 lines (105 loc) 2.79 kB
"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;