UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

170 lines 24.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter")); const testcafe_legacy_api_1 = require("testcafe-legacy-api"); const test_run_1 = __importDefault(require("../test-run")); const session_controller_1 = __importDefault(require("../test-run/session-controller")); const QUARANTINE_THRESHOLD = 3; const DISCONNECT_THRESHOLD = 3; class Quarantine { constructor() { this.attempts = []; } getFailedAttempts() { return this.attempts.filter(errors => !!errors.length); } getPassedAttempts() { return this.attempts.filter(errors => errors.length === 0); } getNextAttemptNumber() { return this.attempts.length + 1; } isThresholdReached(extraErrors) { const { failedTimes, passedTimes } = this._getAttemptsResult(extraErrors); const failedThresholdReached = failedTimes >= QUARANTINE_THRESHOLD; const passedThresholdReached = passedTimes >= QUARANTINE_THRESHOLD; return failedThresholdReached || passedThresholdReached; } _getAttemptsResult(extraErrors) { let failedTimes = this.getFailedAttempts().length; let passedTimes = this.getPassedAttempts().length; if (extraErrors) { if (extraErrors.length) failedTimes += extraErrors.length; else passedTimes += 1; } return { failedTimes, passedTimes }; } } class TestRunController extends async_event_emitter_1.default { constructor(test, index, proxy, screenshots, warningLog, fixtureHookController, opts) { super(); this.test = test; this.index = index; this.opts = opts; this.proxy = proxy; this.screenshots = screenshots; this.warningLog = warningLog; this.fixtureHookController = fixtureHookController; this.TestRunCtor = TestRunController._getTestRunCtor(test, opts); this.testRun = null; this.done = false; this.quarantine = null; this.disconnectionCount = 0; if (this.opts.quarantineMode) this.quarantine = new Quarantine(); } static _getTestRunCtor(test, opts) { if (opts.TestRunCtor) return opts.TestRunCtor; return test.isLegacy ? testcafe_legacy_api_1.TestRun : test_run_1.default; } async _createTestRun(connection) { const screenshotCapturer = this.screenshots.createCapturerFor(this.test, this.index, this.quarantine, connection, this.warningLog); const TestRunCtor = this.TestRunCtor; this.testRun = new TestRunCtor(this.test, connection, screenshotCapturer, this.warningLog, this.opts); if (this.testRun.addQuarantineInfo) this.testRun.addQuarantineInfo(this.quarantine); if (!this.quarantine || this._isFirstQuarantineAttempt()) { await this.emit('test-run-create', { testRun: this.testRun, legacy: TestRunCtor === testcafe_legacy_api_1.TestRun, test: this.test, index: this.index, quarantine: this.quarantine, }); } return this.testRun; } async _endQuarantine() { if (this.quarantine.attempts.length > 1) this.testRun.unstable = this.quarantine.getPassedAttempts().length > 0; await this._emitTestRunDone(); } _shouldKeepInQuarantine() { const errors = this.testRun.errs; const hasErrors = !!errors.length; const attempts = this.quarantine.attempts; const isFirstAttempt = this._isFirstQuarantineAttempt(); attempts.push(errors); return isFirstAttempt ? hasErrors : !this.quarantine.isThresholdReached(); } _isFirstQuarantineAttempt() { return this.quarantine && !this.quarantine.attempts.length; } async _keepInQuarantine() { await this._restartTest(); } async _restartTest() { await this.emit('test-run-restart'); } async _testRunDoneInQuarantineMode() { if (this._shouldKeepInQuarantine()) await this._keepInQuarantine(); else await this._endQuarantine(); } async _testRunDone() { if (this.quarantine) await this._testRunDoneInQuarantineMode(); else await this._emitTestRunDone(); } async _emitTestRunDone() { // NOTE: we should report test run completion in order they were completed in browser. // To keep a sequence after fixture hook execution we use completion queue. await this.fixtureHookController.runFixtureAfterHookIfNecessary(this.testRun); this.done = true; await this.emit('test-run-done'); } async _testRunBeforeDone() { let raiseEvent = !this.quarantine; if (!raiseEvent) { const isSuccessfulQuarantineFirstAttempt = this._isFirstQuarantineAttempt() && !this.testRun.errs.length; const isAttemptsThresholdReached = this.quarantine.isThresholdReached(this.testRun.errs); raiseEvent = isSuccessfulQuarantineFirstAttempt || isAttemptsThresholdReached; } if (raiseEvent) await this.emit('test-run-before-done'); } _testRunDisconnected(connection) { this.disconnectionCount++; const disconnectionThresholdExceedeed = this.disconnectionCount >= DISCONNECT_THRESHOLD; return connection .processDisconnection(disconnectionThresholdExceedeed) .then(() => { return this._restartTest(); }); } get blocked() { return this.fixtureHookController.isTestBlocked(this.test); } async start(connection) { const testRun = await this._createTestRun(connection); const hookOk = await this.fixtureHookController.runFixtureBeforeHookIfNecessary(testRun); if (this.test.skip || !hookOk) { await this.emit('test-run-start'); await this._emitTestRunDone(); return null; } testRun.once('start', async () => { await this.emit('test-run-start'); }); testRun.once('ready', async () => { if (!this.quarantine || this._isFirstQuarantineAttempt()) await this.emit('test-run-ready'); }); testRun.once('before-done', () => this._testRunBeforeDone()); testRun.once('done', () => this._testRunDone()); testRun.once('disconnected', () => this._testRunDisconnected(connection)); testRun.start(); return session_controller_1.default.getSessionUrl(testRun, this.proxy); } } exports.default = TestRunController; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC1ydW4tY29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ydW5uZXIvdGVzdC1ydW4tY29udHJvbGxlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHVGQUE2RDtBQUM3RCw2REFBK0Q7QUFDL0QsMkRBQWtDO0FBQ2xDLHdGQUErRDtBQUUvRCxNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQUMvQixNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQztBQUUvQixNQUFNLFVBQVU7SUFDWjtRQUNJLElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxpQkFBaUI7UUFDYixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBRUQsaUJBQWlCO1FBQ2IsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVELG9CQUFvQjtRQUNoQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsa0JBQWtCLENBQUUsV0FBVztRQUMzQixNQUFNLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUUxRSxNQUFNLHNCQUFzQixHQUFHLFdBQVcsSUFBSSxvQkFBb0IsQ0FBQztRQUNuRSxNQUFNLHNCQUFzQixHQUFHLFdBQVcsSUFBSSxvQkFBb0IsQ0FBQztRQUVuRSxPQUFPLHNCQUFzQixJQUFJLHNCQUFzQixDQUFDO0lBQzVELENBQUM7SUFFRCxrQkFBa0IsQ0FBRSxXQUFXO1FBQzNC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LENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMseUJBQXlCLEVBQUU7Z0JBQ3BELE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsQ0FBQztRQUM3RCxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUNoRCxPQUFPLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUUxRSxPQUFPLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFaEIsT0FBTyw0QkFBaUIsQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoRSxDQUFDO0NBQ0o7QUFuS0Qsb0NBbUtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IEFzeW5jRXZlbnRFbWl0dGVyIGZyb20gJy4uL3V0aWxzL2FzeW5jLWV2ZW50LWVtaXR0ZXInO1xuaW1wb3J0IHsgVGVzdFJ1biBhcyBMZWdhY3lUZXN0UnVuIH0gZnJvbSAndGVzdGNhZmUtbGVnYWN5LWFwaSc7XG5pbXBvcnQgVGVzdFJ1biBmcm9tICcuLi90ZXN0LXJ1bic7XG5pbXBvcnQgU2Vzc2lvbkNvbnRyb2xsZXIgZnJvbSAnLi4vdGVzdC1ydW4vc2Vzc2lvbi1jb250cm9sbGVyJztcblxuY29uc3QgUVVBUkFOVElORV9USFJFU0hPTEQgPSAzO1xuY29uc3QgRElTQ09OTkVDVF9USFJFU0hPTEQgPSAzO1xuXG5jbGFzcyBRdWFyYW50aW5lIHtcbiAgICBjb25zdHJ1Y3RvciAoKSB7XG4gICAgICAgIHRoaXMuYXR0ZW1wdHMgPSBbXTtcbiAgICB9XG5cbiAgICBnZXRGYWlsZWRBdHRlbXB0cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmF0dGVtcHRzLmZpbHRlcihlcnJvcnMgPT4gISFlcnJvcnMubGVuZ3RoKTtcbiAgICB9XG5cbiAgICBnZXRQYXNzZWRBdHRlbXB0cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmF0dGVtcHRzLmZpbHRlcihlcnJvcnMgPT4gZXJyb3JzLmxlbmd0aCA9PT0gMCk7XG4gICAgfVxuXG4gICAgZ2V0TmV4dEF0dGVtcHROdW1iZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hdHRlbXB0cy5sZW5ndGggKyAxO1xuICAgIH1cblxuICAgIGlzVGhyZXNob2xkUmVhY2hlZCAoZXh0cmFFcnJvcnMpIHtcbiAgICAgICAgY29uc3QgeyBmYWlsZWRUaW1lcywgcGFzc2VkVGltZXMgfSA9IHRoaXMuX2dldEF0dGVtcHRzUmVzdWx0KGV4dHJhRXJyb3JzKTtcblxuICAgICAgICBjb25zdCBmYWlsZWRUaHJlc2hvbGRSZWFjaGVkID0gZmFpbGVkVGltZXMgPj0gUVVBUkFOVElORV9USFJFU0hPTEQ7XG4gICAgICAgIGNvbnN0IHBhc3NlZFRocmVzaG9sZFJlYWNoZWQgPSBwYXNzZWRUaW1lcyA+PSBRVUFSQU5USU5FX1RIUkVTSE9MRDtcblxuICAgICAgICByZXR1cm4gZmFpbGVkVGhyZXNob2xkUmVhY2hlZCB8fCBwYXNzZWRUaHJlc2hvbGRSZWFjaGVkO1xuICAgIH1cblxuICAgIF9nZXRBdHRlbXB0c1Jlc3VsdCAoZXh0cmFFcnJvcnMpIHtcbiAgICAgICAgbGV0IGZhaWxlZFRpbWVzID0gdGhpcy5nZXRGYWlsZWRBdHRlbXB0cygpLmxlbmd0aDtcbiAgICAgICAgbGV0IHBhc3NlZFRpbWVzID0gdGhpcy5nZXRQYXNzZWRBdHRlbXB0cygpLmxlbmd0aDtcblxuICAgICAgICBpZiAoZXh0cmFFcnJvcnMpIHtcbiAgICAgICAgICAgIGlmIChleHRyYUVycm9ycy5sZW5ndGgpXG4gICAgICAgICAgICAgICAgZmFpbGVkVGltZXMgKz0gZXh0cmFFcnJvcnMubGVuZ3RoO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHBhc3NlZFRpbWVzICs9IDE7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBmYWlsZWRUaW1lcywgcGFzc2VkVGltZXMgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlc3RSdW5Db250cm9sbGVyIGV4dGVuZHMgQXN5bmNFdmVudEVtaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yICh0ZXN0LCBpbmRleCwgcHJveHksIHNjcmVlbnNob3RzLCB3YXJuaW5nTG9nLCBmaXh0dXJlSG9va0NvbnRyb2xsZXIsIG9wdHMpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzLnRlc3QgID0gdGVzdDtcbiAgICAgICAgdGhpcy5pbmRleCA9IGluZGV4O1xuICAgICAgICB0aGlzLm9wdHMgID0gb3B0cztcblxuICAgICAgICB0aGlzLnByb3h5ICAgICAgICAgICAgICAgICA9IHByb3h5O1xuICAgICAgICB0aGlzLnNjcmVlbnNob3RzICAgICAgICAgICA9IHNjcmVlbnNob3RzO1xuICAgICAgICB0aGlzLndhcm5pbmdMb2cgICAgICAgICAgICA9IHdhcm5pbmdMb2c7XG4gICAgICAgIHRoaXMuZml4dHVyZUhvb2tDb250cm9sbGVyID0gZml4dHVyZUhvb2tDb250cm9sbGVyO1xuXG4gICAgICAgIHRoaXMuVGVzdFJ1bkN0b3IgPSBUZXN0UnVuQ29udHJvbGxlci5fZ2V0VGVzdFJ1bkN0b3IodGVzdCwgb3B0cyk7XG5cbiAgICAgICAgdGhpcy50ZXN0UnVuICAgICAgICAgICAgPSBudWxsO1xuICAgICAgICB0aGlzLmRvbmUgICAgICAgICAgICAgICA9IGZhbHNlO1xuICAgICAgICB0aGlzLnF1YXJhbnRpbmUgICAgICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMuZGlzY29ubmVjdGlvbkNvdW50ID0gMDtcblxuICAgICAgICBpZiAodGhpcy5vcHRzLnF1YXJhbnRpbmVNb2RlKVxuICAgICAgICAgICAgdGhpcy5xdWFyYW50aW5lID0gbmV3IFF1YXJhbnRpbmUoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgX2dldFRlc3RSdW5DdG9yICh0ZXN0LCBvcHRzKSB7XG4gICAgICAgIGlmIChvcHRzLlRlc3RSdW5DdG9yKVxuICAgICAgICAgICAgcmV0dXJuIG9wdHMuVGVzdFJ1bkN0b3I7XG5cbiAgICAgICAgcmV0dXJuIHRlc3QuaXNMZWdhY3kgPyBMZWdhY3lUZXN0UnVuIDogVGVzdFJ1bjtcbiAgICB9XG5cbiAgICBhc3luYyBfY3JlYXRlVGVzdFJ1biAoY29ubmVjdGlvbikge1xuICAgICAgICBjb25zdCBzY3JlZW5zaG90Q2FwdHVyZXIgPSB0aGlzLnNjcmVlbnNob3RzLmNyZWF0ZUNhcHR1cmVyRm9yKHRoaXMudGVzdCwgdGhpcy5pbmRleCwgdGhpcy5xdWFyYW50aW5lLCBjb25uZWN0aW9uLCB0aGlzLndhcm5pbmdMb2cpO1xuICAgICAgICBjb25zdCBUZXN0UnVuQ3RvciAgICAgICAgPSB0aGlzLlRlc3RSdW5DdG9yO1xuXG4gICAgICAgIHRoaXMudGVzdFJ1biA9IG5ldyBUZXN0UnVuQ3Rvcih0aGlzLnRlc3QsIGNvbm5lY3Rpb24sIHNjcmVlbnNob3RDYXB0dXJlciwgdGhpcy53YXJuaW5nTG9nLCB0aGlzLm9wdHMpO1xuXG4gICAgICAgIGlmICh0aGlzLnRlc3RSdW4uYWRkUXVhcmFudGluZUluZm8pXG4gICAgICAgICAgICB0aGlzLnRlc3RSdW4uYWRkUXVhcmFudGluZUluZm8odGhpcy5xdWFyYW50aW5lKTtcblxuICAgICAgICBpZiAoIXRoaXMucXVhcmFudGluZSB8fCB0aGlzLl9pc0ZpcnN0UXVhcmFudGluZUF0dGVtcHQoKSkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LXJ1bi1jcmVhdGUnLCB7XG4gICAgICAgICAgICAgICAgdGVzdFJ1bjogICAgdGhpcy50ZXN0UnVuLFxuICAgICAgICAgICAgICAgIGxlZ2FjeTogICAgIFRlc3RSdW5DdG9yID09PSBMZWdhY3lUZXN0UnVuLFxuICAgICAgICAgICAgICAgIHRlc3Q6ICAgICAgIHRoaXMudGVzdCxcbiAgICAgICAgICAgICAgICBpbmRleDogICAgICB0aGlzLmluZGV4LFxuICAgICAgICAgICAgICAgIHF1YXJhbnRpbmU6IHRoaXMucXVhcmFudGluZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdFJ1bjtcbiAgICB9XG5cbiAgICBhc3luYyBfZW5kUXVhcmFudGluZSAoKSB7XG4gICAgICAgIGlmICh0aGlzLnF1YXJhbnRpbmUuYXR0ZW1wdHMubGVuZ3RoID4gMSlcbiAgICAgICAgICAgIHRoaXMudGVzdFJ1bi51bnN0YWJsZSA9IHRoaXMucXVhcmFudGluZS5nZXRQYXNzZWRBdHRlbXB0cygpLmxlbmd0aCA+IDA7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fZW1pdFRlc3RSdW5Eb25lKCk7XG4gICAgfVxuXG4gICAgX3Nob3VsZEtlZXBJblF1YXJhbnRpbmUgKCkge1xuICAgICAgICBjb25zdCBlcnJvcnMgICAgICAgICA9IHRoaXMudGVzdFJ1bi5lcnJzO1xuICAgICAgICBjb25zdCBoYXNFcnJvcnMgICAgICA9ICEhZXJyb3JzLmxlbmd0aDtcbiAgICAgICAgY29uc3QgYXR0ZW1wdHMgICAgICAgPSB0aGlzLnF1YXJhbnRpbmUuYXR0ZW1wdHM7XG4gICAgICAgIGNvbnN0IGlzRmlyc3RBdHRlbXB0ID0gdGhpcy5faXNGaXJzdFF1YXJhbnRpbmVBdHRlbXB0KCk7XG5cbiAgICAgICAgYXR0ZW1wdHMucHVzaChlcnJvcnMpO1xuXG4gICAgICAgIHJldHVybiBpc0ZpcnN0QXR0ZW1wdCA/IGhhc0Vycm9ycyA6ICF0aGlzLnF1YXJhbnRpbmUuaXNUaHJlc2hvbGRSZWFjaGVkKCk7XG4gICAgfVxuXG4gICAgX2lzRmlyc3RRdWFyYW50aW5lQXR0ZW1wdCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnF1YXJhbnRpbmUgJiYgIXRoaXMucXVhcmFudGluZS5hdHRlbXB0cy5sZW5ndGg7XG4gICAgfVxuXG4gICAgYXN5bmMgX2tlZXBJblF1YXJhbnRpbmUgKCkge1xuICAgICAgICBhd2FpdCB0aGlzLl9yZXN0YXJ0VGVzdCgpO1xuICAgIH1cblxuICAgIGFzeW5jIF9yZXN0YXJ0VGVzdCAoKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tcmVzdGFydCcpO1xuICAgIH1cblxuICAgIGFzeW5jIF90ZXN0UnVuRG9uZUluUXVhcmFudGluZU1vZGUgKCkge1xuICAgICAgICBpZiAodGhpcy5fc2hvdWxkS2VlcEluUXVhcmFudGluZSgpKVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5fa2VlcEluUXVhcmFudGluZSgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9lbmRRdWFyYW50aW5lKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgX3Rlc3RSdW5Eb25lICgpIHtcbiAgICAgICAgaWYgKHRoaXMucXVhcmFudGluZSlcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX3Rlc3RSdW5Eb25lSW5RdWFyYW50aW5lTW9kZSgpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9lbWl0VGVzdFJ1bkRvbmUoKTtcbiAgICB9XG5cbiAgICBhc3luYyBfZW1pdFRlc3RSdW5Eb25lICgpIHtcbiAgICAgICAgLy8gTk9URTogd2Ugc2hvdWxkIHJlcG9ydCB0ZXN0IHJ1biBjb21wbGV0aW9uIGluIG9yZGVyIHRoZXkgd2VyZSBjb21wbGV0ZWQgaW4gYnJvd3Nlci5cbiAgICAgICAgLy8gVG8ga2VlcCBhIHNlcXVlbmNlIGFmdGVyIGZpeHR1cmUgaG9vayBleGVjdXRpb24gd2UgdXNlIGNvbXBsZXRpb24gcXVldWUuXG4gICAgICAgIGF3YWl0IHRoaXMuZml4dHVyZUhvb2tDb250cm9sbGVyLnJ1bkZpeHR1cmVBZnRlckhvb2tJZk5lY2Vzc2FyeSh0aGlzLnRlc3RSdW4pO1xuXG4gICAgICAgIHRoaXMuZG9uZSA9IHRydWU7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LXJ1bi1kb25lJyk7XG4gICAgfVxuXG4gICAgYXN5bmMgX3Rlc3RSdW5CZWZvcmVEb25lICgpIHtcbiAgICAgICAgbGV0IHJhaXNlRXZlbnQgPSAhdGhpcy5xdWFyYW50aW5lO1xuXG4gICAgICAgIGlmICghcmFpc2VFdmVudCkge1xuICAgICAgICAgICAgY29uc3QgaXNTdWNjZXNzZnVsUXVhcmFudGluZUZpcnN0QXR0ZW1wdCA9IHRoaXMuX2lzRmlyc3RRdWFyYW50aW5lQXR0ZW1wdCgpICYmICF0aGlzLnRlc3RSdW4uZXJycy5sZW5ndGg7XG4gICAgICAgICAgICBjb25zdCBpc0F0dGVtcHRzVGhyZXNob2xkUmVhY2hlZCAgICAgICAgID0gdGhpcy5xdWFyYW50aW5lLmlzVGhyZXNob2xkUmVhY2hlZCh0aGlzLnRlc3RSdW4uZXJycyk7XG5cbiAgICAgICAgICAgIHJhaXNlRXZlbnQgPSBpc1N1Y2Nlc3NmdWxRdWFyYW50aW5lRmlyc3RBdHRlbXB0IHx8IGlzQXR0ZW1wdHNUaHJlc2hvbGRSZWFjaGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJhaXNlRXZlbnQpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3Rlc3QtcnVuLWJlZm9yZS1kb25lJyk7XG4gICAgfVxuXG4gICAgX3Rlc3RSdW5EaXNjb25uZWN0ZWQgKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0aW9uQ291bnQrKztcblxuICAgICAgICBjb25zdCBkaXNjb25uZWN0aW9uVGhyZXNob2xkRXhjZWVkZWVkID0gdGhpcy5kaXNjb25uZWN0aW9uQ291bnQgPj0gRElTQ09OTkVDVF9USFJFU0hPTEQ7XG5cbiAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb25cbiAgICAgICAgICAgIC5wcm9jZXNzRGlzY29ubmVjdGlvbihkaXNjb25uZWN0aW9uVGhyZXNob2xkRXhjZWVkZWVkKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZXN0YXJ0VGVzdCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZ2V0IGJsb2NrZWQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5maXh0dXJlSG9va0NvbnRyb2xsZXIuaXNUZXN0QmxvY2tlZCh0aGlzLnRlc3QpO1xuICAgIH1cblxuICAgIGFzeW5jIHN0YXJ0IChjb25uZWN0aW9uKSB7XG4gICAgICAgIGNvbnN0IHRlc3RSdW4gPSBhd2FpdCB0aGlzLl9jcmVhdGVUZXN0UnVuKGNvbm5lY3Rpb24pO1xuXG4gICAgICAgIGNvbnN0IGhvb2tPayA9IGF3YWl0IHRoaXMuZml4dHVyZUhvb2tDb250cm9sbGVyLnJ1bkZpeHR1cmVCZWZvcmVIb29rSWZOZWNlc3NhcnkodGVzdFJ1bik7XG5cbiAgICAgICAgaWYgKHRoaXMudGVzdC5za2lwIHx8ICFob29rT2spIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tc3RhcnQnKTtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2VtaXRUZXN0UnVuRG9uZSgpO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB0ZXN0UnVuLm9uY2UoJ3N0YXJ0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LXJ1bi1zdGFydCcpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGVzdFJ1bi5vbmNlKCdyZWFkeScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5xdWFyYW50aW5lIHx8IHRoaXMuX2lzRmlyc3RRdWFyYW50aW5lQXR0ZW1wdCgpKVxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tcmVhZHknKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRlc3RSdW4ub25jZSgnYmVmb3JlLWRvbmUnLCAoKSA9PiB0aGlzLl90ZXN0UnVuQmVmb3JlRG9uZSgpKTtcbiAgICAgICAgdGVzdFJ1bi5vbmNlKCdkb25lJywgKCkgPT4gdGhpcy5fdGVzdFJ1bkRvbmUoKSk7XG4gICAgICAgIHRlc3RSdW4ub25jZSgnZGlzY29ubmVjdGVkJywgKCkgPT4gdGhpcy5fdGVzdFJ1bkRpc2Nvbm5lY3RlZChjb25uZWN0aW9uKSk7XG5cbiAgICAgICAgdGVzdFJ1bi5zdGFydCgpO1xuXG4gICAgICAgIHJldHVybiBTZXNzaW9uQ29udHJvbGxlci5nZXRTZXNzaW9uVXJsKHRlc3RSdW4sIHRoaXMucHJveHkpO1xuICAgIH1cbn1cbiJdfQ==