@browserstack/testcafe
Version:
Automated browser testing for the modern web development stack.
170 lines • 27.5 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable */
const lodash_1 = require("lodash");
const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter"));
const test_run_controller_1 = __importDefault(require("./test-run-controller"));
const session_controller_1 = __importDefault(require("../test-run/session-controller"));
const browser_job_result_1 = __importDefault(require("./browser-job-result"));
class BrowserJob extends async_event_emitter_1.default {
constructor(tests, browserConnections, proxy, screenshots, warningLog, fixtureHookController, opts) {
super();
this.started = false;
this.total = 0;
this.passed = 0;
this.opts = opts;
this.proxy = proxy;
this.browserConnections = browserConnections;
this.screenshots = screenshots;
this.warningLog = warningLog;
this.fixtureHookController = fixtureHookController;
this.result = null;
this.openingCount = 0;
this.testRunControllerQueue = tests.map((test, index) => this._createTestRunController(test, index));
this.totalGiven = tests.length;
this.completionQueue = [];
this.reportsPending = [];
this.connectionErrorListener = error => this._setResult(browser_job_result_1.default.errored, error);
this.browserConnections.map(bc => bc.once('error', this.connectionErrorListener));
}
_createTestRunController(test, index) {
const testRunController = new test_run_controller_1.default(test, index + 1, this.proxy, this.screenshots, this.warningLog, this.fixtureHookController, this.opts);
testRunController.on('test-run-create', async (testRunInfo) => {
await this.emit('test-run-create', testRunInfo);
});
testRunController.on('test-run-start', async () => {
await this.emit('test-run-start', testRunController.testRun);
});
testRunController.on('test-run-ready', async () => {
await this.emit('test-run-ready', testRunController);
});
testRunController.on('test-run-restart', async () => this._onTestRunRestart(testRunController));
testRunController.on('test-run-before-done', async () => {
await this.emit('test-run-before-done', testRunController);
});
testRunController.on('test-run-done', async () => this._onTestRunDone(testRunController));
testRunController.on('test-action-start', async (args) => {
await this.emit('test-action-start', args);
});
testRunController.on('test-action-done', async (args) => {
await this.emit('test-action-done', args);
});
return testRunController;
}
async _setResult(status, data) {
if (this.result)
return;
this.result = { status, data };
this.browserConnections.forEach(bc => bc.removeListener('error', this.connectionErrorListener));
await Promise.all(this.browserConnections.map(bc => bc.reportJobResult(this.result.status, this.result.data)));
}
_addToCompletionQueue(testRunInfo) {
this.completionQueue.push(testRunInfo);
}
_removeFromCompletionQueue(testRunInfo) {
lodash_1.pull(this.completionQueue, testRunInfo);
}
_onTestRunRestart(testRunController) {
console.log(`Test run restarted`);
this._removeFromCompletionQueue(testRunController);
this.testRunControllerQueue.unshift(testRunController);
}
async _onTestRunDone(testRunController) {
this.total++;
// console.log(`Test run done is called ${this.total}`);
if (!testRunController.testRun.errs.length)
this.passed++;
while (this.completionQueue.length && this.completionQueue[0].done) {
// console.log(`Completion queue`);
testRunController = this.completionQueue.shift();
await this.emit('test-run-done', testRunController.testRun);
lodash_1.pull(this.reportsPending, testRunController);
}
if (!this.completionQueue.length && !this.hasQueuedTestRuns) {
// console.log(`Emitting done for test run`);
if (!this.opts.live)
session_controller_1.default.closeSession(testRunController.testRun);
this
._setResult(browser_job_result_1.default.done, { total: this.total, passed: this.passed })
.then(() => this.emit('done'));
}
}
// API
get hasQueuedTestRuns() {
return !!this.testRunControllerQueue.length;
}
get queuedTestRuns() {
return this.testRunControllerQueue.length;
}
get incrementOpening() {
++this.openingCount;
// console.log(this.openingCount, this.totalGiven);
}
get leftCount() {
return this.totalGiven - this.openingCount;
}
get popTest() {
while (this.testRunControllerQueue.length) {
// NOTE: before hook for test run fixture is currently
// executing, so test run is temporary blocked
const testRunController = this.testRunControllerQueue[0];
const isBlocked = testRunController.blocked;
const isConcurrency = this.opts.concurrency > 1;
const hasIncompleteTestRuns = this.completionQueue.some(controller => !controller.done);
const needWaitLastTestInFixture = this.reportsPending.some(controller => controller.test.fixture !== testRunController.test.fixture);
if (isBlocked || (hasIncompleteTestRuns || needWaitLastTestInFixture) && !isConcurrency)
break;
this.testRunControllerQueue.shift();
return testRunController;
}
return null;
}
async setTestURL(testRunController, connection) {
this.reportsPending.push(testRunController);
this._addToCompletionQueue(testRunController);
if (!this.started) {
this.started = true;
await this.emit('start');
}
const testRunUrl = await testRunController.start(connection);
if (testRunUrl)
return testRunUrl;
}
async popNextTestRunUrl(connection) {
while (this.testRunControllerQueue.length) {
// console.log(`Popping the nextTestURL`);
// NOTE: before hook for test run fixture is currently
// executing, so test run is temporary blocked
const testRunController = this.testRunControllerQueue[0];
const isBlocked = testRunController.blocked;
const isConcurrency = this.opts.concurrency > 1;
const hasIncompleteTestRuns = this.completionQueue.some(controller => !controller.done);
const needWaitLastTestInFixture = this.reportsPending.some(controller => controller.test.fixture !== testRunController.test.fixture);
if (isBlocked || (hasIncompleteTestRuns || needWaitLastTestInFixture) && !isConcurrency)
break;
this.reportsPending.push(testRunController);
this.testRunControllerQueue.shift();
this._addToCompletionQueue(testRunController);
if (!this.started) {
this.started = true;
await this.emit('start');
}
const testRunUrl = await testRunController.start(connection);
if (testRunUrl)
return testRunUrl;
}
// console.log(`Sending null now...`);
return null;
}
abort() {
this.clearListeners();
this._setResult(browser_job_result_1.default.aborted);
this.browserConnections.map(bc => bc.removeJob(this));
}
}
exports.default = BrowserJob;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJvd3Nlci1qb2IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVubmVyL2Jyb3dzZXItam9iLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsb0JBQW9CO0FBQ3BCLG1DQUF3QztBQUN4Qyx1RkFBNkQ7QUFDN0QsZ0ZBQXNEO0FBQ3RELHdGQUErRDtBQUMvRCw4RUFBMEM7QUFFMUMsTUFBcUIsVUFBVyxTQUFRLDZCQUFpQjtJQUNyRCxZQUFhLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxxQkFBcUIsRUFBRSxJQUFJO1FBQy9GLEtBQUssRUFBRSxDQUFDO1FBRVIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFFckIsSUFBSSxDQUFDLEtBQUssR0FBbUIsQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxNQUFNLEdBQWtCLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsSUFBSSxHQUFvQixJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLEtBQUssR0FBbUIsS0FBSyxDQUFDO1FBQ25DLElBQUksQ0FBQyxrQkFBa0IsR0FBTSxrQkFBa0IsQ0FBQztRQUNoRCxJQUFJLENBQUMsV0FBVyxHQUFhLFdBQVcsQ0FBQztRQUN6QyxJQUFJLENBQUMsVUFBVSxHQUFjLFVBQVUsQ0FBQztRQUN4QyxJQUFJLENBQUMscUJBQXFCLEdBQUcscUJBQXFCLENBQUM7UUFDbkQsSUFBSSxDQUFDLE1BQU0sR0FBa0IsSUFBSSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxZQUFZLEdBQUcsQ0FBQyxDQUFDO1FBRXRCLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRXJHLElBQUksQ0FBQyxVQUFVLEdB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TUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQzVCO1lBRUQsTUFBTSxVQUFVLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFN0QsSUFBSSxVQUFVO2dCQUNWLE9BQU8sVUFBVSxDQUFDO1NBQ3pCO1FBQ0Qsc0NBQXNDO1FBRXRDLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxLQUFLO1FBQ0QsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxVQUFVLENBQUMsNEJBQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUM7Q0FDSjtBQXpNRCw2QkF5TUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSAqL1xuaW1wb3J0IHsgcHVsbCBhcyByZW1vdmUgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IEFzeW5jRXZlbnRFbWl0dGVyIGZyb20gJy4uL3V0aWxzL2FzeW5jLWV2ZW50LWVtaXR0ZXInO1xuaW1wb3J0IFRlc3RSdW5Db250cm9sbGVyIGZyb20gJy4vdGVzdC1ydW4tY29udHJvbGxlcic7XG5pbXBvcnQgU2Vzc2lvbkNvbnRyb2xsZXIgZnJvbSAnLi4vdGVzdC1ydW4vc2Vzc2lvbi1jb250cm9sbGVyJztcbmltcG9ydCBSRVNVTFQgZnJvbSAnLi9icm93c2VyLWpvYi1yZXN1bHQnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCcm93c2VySm9iIGV4dGVuZHMgQXN5bmNFdmVudEVtaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yICh0ZXN0cywgYnJvd3NlckNvbm5lY3Rpb25zLCBwcm94eSwgc2NyZWVuc2hvdHMsIHdhcm5pbmdMb2csIGZpeHR1cmVIb29rQ29udHJvbGxlciwgb3B0cykge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXMuc3RhcnRlZCA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMudG90YWwgICAgICAgICAgICAgICAgID0gMDtcbiAgICAgICAgdGhpcy5wYXNzZWQgICAgICAgICAgICAgICAgPSAwO1xuICAgICAgICB0aGlzLm9wdHMgICAgICAgICAgICAgICAgICA9IG9wdHM7XG4gICAgICAgIHRoaXMucHJveHkgICAgICAgICAgICAgICAgID0gcHJveHk7XG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zICAgID0gYnJvd3NlckNvbm5lY3Rpb25zO1xuICAgICAgICB0aGlzLnNjcmVlbnNob3RzICAgICAgICAgICA9IHNjcmVlbnNob3RzO1xuICAgICAgICB0aGlzLndhcm5pbmdMb2cgICAgICAgICAgICA9IHdhcm5pbmdMb2c7XG4gICAgICAgIHRoaXMuZml4dHVyZUhvb2tDb250cm9sbGVyID0gZml4dHVyZUhvb2tDb250cm9sbGVyO1xuICAgICAgICB0aGlzLnJlc3VsdCAgICAgICAgICAgICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMub3BlbmluZ0NvdW50ID0gMDtcblxuICAgICAgICB0aGlzLnRlc3RSdW5Db250cm9sbGVyUXVldWUgPSB0ZXN0cy5tYXAoKHRlc3QsIGluZGV4KSA9PiB0aGlzLl9jcmVhdGVUZXN0UnVuQ29udHJvbGxlcih0ZXN0LCBpbmRleCkpO1xuXG4gICAgICAgIHRoaXMudG90YWxHaXZlbiA9IHRlc3RzLmxlbmd0aDtcblxuICAgICAgICB0aGlzLmNvbXBsZXRpb25RdWV1ZSA9IFtdO1xuICAgICAgICB0aGlzLnJlcG9ydHNQZW5kaW5nICA9IFtdO1xuXG4gICAgICAgIHRoaXMuY29ubmVjdGlvbkVycm9yTGlzdGVuZXIgPSBlcnJvciA9PiB0aGlzLl9zZXRSZXN1bHQoUkVTVUxULmVycm9yZWQsIGVycm9yKTtcblxuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9ucy5tYXAoYmMgPT4gYmMub25jZSgnZXJyb3InLCB0aGlzLmNvbm5lY3Rpb25FcnJvckxpc3RlbmVyKSk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZVRlc3RSdW5Db250cm9sbGVyICh0ZXN0LCBpbmRleCkge1xuICAgICAgICBjb25zdCB0ZXN0UnVuQ29udHJvbGxlciA9IG5ldyBUZXN0UnVuQ29udHJvbGxlcih0ZXN0LCBpbmRleCArIDEsIHRoaXMucHJveHksIHRoaXMuc2NyZWVuc2hvdHMsIHRoaXMud2FybmluZ0xvZyxcbiAgICAgICAgICAgIHRoaXMuZml4dHVyZUhvb2tDb250cm9sbGVyLCB0aGlzLm9wdHMpO1xuXG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1jcmVhdGUnLCBhc3luYyB0ZXN0UnVuSW5mbyA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3Rlc3QtcnVuLWNyZWF0ZScsIHRlc3RSdW5JbmZvKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1zdGFydCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tc3RhcnQnLCB0ZXN0UnVuQ29udHJvbGxlci50ZXN0UnVuKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1yZWFkeScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tcmVhZHknLCB0ZXN0UnVuQ29udHJvbGxlcik7XG4gICAgICAgIH0pO1xuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1ydW4tcmVzdGFydCcsIGFzeW5jICgpID0+IHRoaXMuX29uVGVzdFJ1blJlc3RhcnQodGVzdFJ1bkNvbnRyb2xsZXIpKTtcbiAgICAgICAgdGVzdFJ1bkNvbnRyb2xsZXIub24oJ3Rlc3QtcnVuLWJlZm9yZS1kb25lJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LXJ1bi1iZWZvcmUtZG9uZScsIHRlc3RSdW5Db250cm9sbGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1kb25lJywgYXN5bmMgKCkgPT4gdGhpcy5fb25UZXN0UnVuRG9uZSh0ZXN0UnVuQ29udHJvbGxlcikpO1xuXG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LWFjdGlvbi1zdGFydCcsIGFzeW5jIGFyZ3MgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LWFjdGlvbi1zdGFydCcsIGFyZ3MpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1hY3Rpb24tZG9uZScsIGFzeW5jIGFyZ3MgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LWFjdGlvbi1kb25lJywgYXJncyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiB0ZXN0UnVuQ29udHJvbGxlcjtcbiAgICB9XG5cbiAgICBhc3luYyBfc2V0UmVzdWx0IChzdGF0dXMsIGRhdGEpIHtcbiAgICAgICAgaWYgKHRoaXMucmVzdWx0KVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIHRoaXMucmVzdWx0ID0geyBzdGF0dXMsIGRhdGEgfTtcblxuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9ucy5mb3JFYWNoKGJjID0+IGJjLnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIHRoaXMuY29ubmVjdGlvbkVycm9yTGlzdGVuZXIpKTtcblxuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbCh0aGlzLmJyb3dzZXJDb25uZWN0aW9ucy5tYXAoYmMgPT4gYmMucmVwb3J0Sm9iUmVzdWx0KHRoaXMucmVzdWx0LnN0YXR1cywgdGhpcy5yZXN1bHQuZGF0YSkpKTtcbiAgICB9XG5cbiAgICBfYWRkVG9Db21wbGV0aW9uUXVldWUgKHRlc3RSdW5JbmZvKSB7XG4gICAgICAgIHRoaXMuY29tcGxldGlvblF1ZXVlLnB1c2godGVzdFJ1bkluZm8pO1xuICAgIH1cblxuICAgIF9yZW1vdmVGcm9tQ29tcGxldGlvblF1ZXVlICh0ZXN0UnVuSW5mbykge1xuICAgICAgICByZW1vdmUodGhpcy5jb21wbGV0aW9uUXVldWUsIHRlc3RSdW5JbmZvKTtcbiAgICB9XG5cbiAgICBfb25UZXN0UnVuUmVzdGFydCAodGVzdFJ1bkNvbnRyb2xsZXIpIHtcbiAgICAgICAgY29uc29sZS5sb2coYFRlc3QgcnVuIHJlc3RhcnRlZGApO1xuICAgICAgICB0aGlzLl9yZW1vdmVGcm9tQ29tcGxldGlvblF1ZXVlKHRlc3RSdW5Db250cm9sbGVyKTtcbiAgICAgICAgdGhpcy50ZXN0UnVuQ29udHJvbGxlclF1ZXVlLnVuc2hpZnQodGVzdFJ1bkNvbnRyb2xsZXIpO1xuICAgIH1cblxuICAgIGFzeW5jIF9vblRlc3RSdW5Eb25lICh0ZXN0UnVuQ29udHJvbGxlcikge1xuICAgICAgICB0aGlzLnRvdGFsKys7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGBUZXN0IHJ1biBkb25lIGlzIGNhbGxlZCAke3RoaXMudG90YWx9YCk7XG5cbiAgICAgICAgaWYgKCF0ZXN0UnVuQ29udHJvbGxlci50ZXN0UnVuLmVycnMubGVuZ3RoKVxuICAgICAgICAgICAgdGhpcy5wYXNzZWQrKztcblxuICAgICAgICB3aGlsZSAodGhpcy5jb21wbGV0aW9uUXVldWUubGVuZ3RoICYmIHRoaXMuY29tcGxldGlvblF1ZXVlWzBdLmRvbmUpIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBDb21wbGV0aW9uIHF1ZXVlYCk7XG4gICAgICAgICAgICB0ZXN0UnVuQ29udHJvbGxlciA9IHRoaXMuY29tcGxldGlvblF1ZXVlLnNoaWZ0KCk7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tZG9uZScsIHRlc3RSdW5Db250cm9sbGVyLnRlc3RSdW4pO1xuXG4gICAgICAgICAgICByZW1vdmUodGhpcy5yZXBvcnRzUGVuZGluZywgdGVzdFJ1bkNvbnRyb2xsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmNvbXBsZXRpb25RdWV1ZS5sZW5ndGggJiYgIXRoaXMuaGFzUXVldWVkVGVzdFJ1bnMpIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBFbWl0dGluZyBkb25lIGZvciB0ZXN0IHJ1bmApO1xuICAgICAgICAgICAgaWYgKCF0aGlzLm9wdHMubGl2ZSlcbiAgICAgICAgICAgICAgICBTZXNzaW9uQ29udHJvbGxlci5jbG9zZVNlc3Npb24odGVzdFJ1bkNvbnRyb2xsZXIudGVzdFJ1bik7XG5cbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgICAgICAgICAuX3NldFJlc3VsdChSRVNVTFQuZG9uZSwgeyB0b3RhbDogdGhpcy50b3RhbCwgcGFzc2VkOiB0aGlzLnBhc3NlZCB9KVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMuZW1pdCgnZG9uZScpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFQSVxuICAgIGdldCBoYXNRdWV1ZWRUZXN0UnVucyAoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5sZW5ndGg7XG4gICAgfVxuXG4gICAgZ2V0IHF1ZXVlZFRlc3RSdW5zICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5sZW5ndGg7XG4gICAgfVxuXG4gICAgZ2V0IGluY3JlbWVudE9wZW5pbmcoKSB7XG4gICAgICAgICsrdGhpcy5vcGVuaW5nQ291bnQ7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMub3BlbmluZ0NvdW50LCB0aGlzLnRvdGFsR2l2ZW4pO1xuICAgIH1cblxuICAgIGdldCBsZWZ0Q291bnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvdGFsR2l2ZW4gLSB0aGlzLm9wZW5pbmdDb3VudDtcbiAgICB9XG5cbiAgICBnZXQgcG9wVGVzdCgpIHtcbiAgICAgICAgd2hpbGUgKHRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIC8vIE5PVEU6IGJlZm9yZSBob29rIGZvciB0ZXN0IHJ1biBmaXh0dXJlIGlzIGN1cnJlbnRseVxuICAgICAgICAgICAgLy8gZXhlY3V0aW5nLCBzbyB0ZXN0IHJ1biBpcyB0ZW1wb3JhcnkgYmxvY2tlZFxuICAgICAgICAgICAgY29uc3QgdGVzdFJ1bkNvbnRyb2xsZXIgICAgICAgICA9IHRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZVswXTtcbiAgICAgICAgICAgIGNvbnN0IGlzQmxvY2tlZCAgICAgICAgICAgICAgICAgPSB0ZXN0UnVuQ29udHJvbGxlci5ibG9ja2VkO1xuICAgICAgICAgICAgY29uc3QgaXNDb25jdXJyZW5jeSAgICAgICAgICAgICA9IHRoaXMub3B0cy5jb25jdXJyZW5jeSA+IDE7XG4gICAgICAgICAgICBjb25zdCBoYXNJbmNvbXBsZXRlVGVzdFJ1bnMgICAgID0gdGhpcy5jb21wbGV0aW9uUXVldWUuc29tZShjb250cm9sbGVyID0+ICFjb250cm9sbGVyLmRvbmUpO1xuICAgICAgICAgICAgY29uc3QgbmVlZFdhaXRMYXN0VGVzdEluRml4dHVyZSA9IHRoaXMucmVwb3J0c1BlbmRpbmcuc29tZShjb250cm9sbGVyID0+IGNvbnRyb2xsZXIudGVzdC5maXh0dXJlICE9PSB0ZXN0UnVuQ29udHJvbGxlci50ZXN0LmZpeHR1cmUpO1xuXG4gICAgICAgICAgICBpZiAoaXNCbG9ja2VkIHx8IChoYXNJbmNvbXBsZXRlVGVzdFJ1bnMgfHwgbmVlZFdhaXRMYXN0VGVzdEluRml4dHVyZSkgJiYgIWlzQ29uY3VycmVuY3kpXG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIHRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRlc3RSdW5Db250cm9sbGVyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGFzeW5jIHNldFRlc3RVUkwodGVzdFJ1bkNvbnRyb2xsZXIsIGNvbm5lY3Rpb24pIHtcbiAgICAgICAgdGhpcy5yZXBvcnRzUGVuZGluZy5wdXNoKHRlc3RSdW5Db250cm9sbGVyKTtcbiAgICAgICAgdGhpcy5fYWRkVG9Db21wbGV0aW9uUXVldWUodGVzdFJ1bkNvbnRyb2xsZXIpO1xuXG4gICAgICAgIGlmICghdGhpcy5zdGFydGVkKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCdzdGFydCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGVzdFJ1blVybCA9IGF3YWl0IHRlc3RSdW5Db250cm9sbGVyLnN0YXJ0KGNvbm5lY3Rpb24pO1xuXG4gICAgICAgIGlmICh0ZXN0UnVuVXJsKVxuICAgICAgICAgICAgcmV0dXJuIHRlc3RSdW5Vcmw7XG4gICAgfVxuXG4gICAgYXN5bmMgcG9wTmV4dFRlc3RSdW5VcmwgKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgd2hpbGUgKHRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBQb3BwaW5nIHRoZSBuZXh0VGVzdFVSTGApO1xuICAgICAgICAgICAgLy8gTk9URTogYmVmb3JlIGhvb2sgZm9yIHRlc3QgcnVuIGZpeHR1cmUgaXMgY3VycmVudGx5XG4gICAgICAgICAgICAvLyBleGVjdXRpbmcsIHNvIHRlc3QgcnVuIGlzIHRlbXBvcmFyeSBibG9ja2VkXG4gICAgICAgICAgICBjb25zdCB0ZXN0UnVuQ29udHJvbGxlciAgICAgICAgID0gdGhpcy50ZXN0UnVuQ29udHJvbGxlclF1ZXVlWzBdO1xuICAgICAgICAgICAgY29uc3QgaXNCbG9ja2VkICAgICAgICAgICAgICAgICA9IHRlc3RSdW5Db250cm9sbGVyLmJsb2NrZWQ7XG4gICAgICAgICAgICBjb25zdCBpc0NvbmN1cnJlbmN5ICAgICAgICAgICAgID0gdGhpcy5vcHRzLmNvbmN1cnJlbmN5ID4gMTtcbiAgICAgICAgICAgIGNvbnN0IGhhc0luY29tcGxldGVUZXN0UnVucyAgICAgPSB0aGlzLmNvbXBsZXRpb25RdWV1ZS5zb21lKGNvbnRyb2xsZXIgPT4gIWNvbnRyb2xsZXIuZG9uZSk7XG4gICAgICAgICAgICBjb25zdCBuZWVkV2FpdExhc3RUZXN0SW5GaXh0dXJlID0gdGhpcy5yZXBvcnRzUGVuZGluZy5zb21lKGNvbnRyb2xsZXIgPT4gY29udHJvbGxlci50ZXN0LmZpeHR1cmUgIT09IHRlc3RSdW5Db250cm9sbGVyLnRlc3QuZml4dHVyZSk7XG5cbiAgICAgICAgICAgIGlmIChpc0Jsb2NrZWQgfHwgKGhhc0luY29tcGxldGVUZXN0UnVucyB8fCBuZWVkV2FpdExhc3RUZXN0SW5GaXh0dXJlKSAmJiAhaXNDb25jdXJyZW5jeSlcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgdGhpcy5yZXBvcnRzUGVuZGluZy5wdXNoKHRlc3RSdW5Db250cm9sbGVyKTtcbiAgICAgICAgICAgIHRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgdGhpcy5fYWRkVG9Db21wbGV0aW9uUXVldWUodGVzdFJ1bkNvbnRyb2xsZXIpO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RhcnRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhcnRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCdzdGFydCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0ZXN0UnVuVXJsID0gYXdhaXQgdGVzdFJ1bkNvbnRyb2xsZXIuc3RhcnQoY29ubmVjdGlvbik7XG5cbiAgICAgICAgICAgIGlmICh0ZXN0UnVuVXJsKVxuICAgICAgICAgICAgICAgIHJldHVybiB0ZXN0UnVuVXJsO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKGBTZW5kaW5nIG51bGwgbm93Li4uYCk7XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgYWJvcnQgKCkge1xuICAgICAgICB0aGlzLmNsZWFyTGlzdGVuZXJzKCk7XG4gICAgICAgIHRoaXMuX3NldFJlc3VsdChSRVNVTFQuYWJvcnRlZCk7XG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zLm1hcChiYyA9PiBiYy5yZW1vdmVKb2IodGhpcykpO1xuICAgIH1cbn1cbiJdfQ==