UNPKG

20.2 kBJavaScriptView Raw
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6const lodash_1 = require("lodash");
7const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter"));
8const test_run_controller_1 = __importDefault(require("./test-run-controller"));
9const session_controller_1 = __importDefault(require("../test-run/session-controller"));
10const browser_job_result_1 = __importDefault(require("./browser-job-result"));
11// Browser job
12class BrowserJob extends async_event_emitter_1.default {
13 constructor(tests, browserConnections, proxy, screenshots, warningLog, fixtureHookController, opts) {
14 super();
15 this.started = false;
16 this.total = 0;
17 this.passed = 0;
18 this.opts = opts;
19 this.proxy = proxy;
20 this.browserConnections = browserConnections;
21 this.screenshots = screenshots;
22 this.warningLog = warningLog;
23 this.fixtureHookController = fixtureHookController;
24 this.result = null;
25 this.testRunControllerQueue = tests.map((test, index) => this._createTestRunController(test, index));
26 this.completionQueue = [];
27 this.connectionErrorListener = error => this._setResult(browser_job_result_1.default.errored, error);
28 this.browserConnections.map(bc => bc.once('error', this.connectionErrorListener));
29 }
30 _createTestRunController(test, index) {
31 const testRunController = new test_run_controller_1.default(test, index + 1, this.proxy, this.screenshots, this.warningLog, this.fixtureHookController, this.opts);
32 testRunController.on('test-run-create', async (testRunInfo) => {
33 await this.emit('test-run-create', testRunInfo);
34 });
35 testRunController.on('test-run-start', async () => {
36 await this.emit('test-run-start', testRunController.testRun);
37 });
38 testRunController.on('test-run-ready', async () => {
39 await this.emit('test-run-ready', testRunController);
40 });
41 testRunController.on('test-run-restart', async () => this._onTestRunRestart(testRunController));
42 testRunController.on('test-run-before-done', async () => {
43 await this.emit('test-run-before-done', testRunController);
44 });
45 testRunController.on('test-run-done', async () => this._onTestRunDone(testRunController));
46 testRunController.on('test-run-start', async () => {
47 await this.emit('test-run-start', testRunController.testRun);
48 });
49 testRunController.on('test-action-start', async (args) => {
50 await this.emit('test-action-start', args);
51 });
52 testRunController.on('test-action-done', async (args) => {
53 await this.emit('test-action-done', args);
54 });
55 return testRunController;
56 }
57 async _setResult(status, data) {
58 if (this.result)
59 return;
60 this.result = { status, data };
61 this.browserConnections.forEach(bc => bc.removeListener('error', this.connectionErrorListener));
62 await Promise.all(this.browserConnections.map(bc => bc.reportJobResult(this.result.status, this.result.data)));
63 }
64 _addToCompletionQueue(testRunInfo) {
65 this.completionQueue.push(testRunInfo);
66 }
67 _removeFromCompletionQueue(testRunInfo) {
68 lodash_1.remove(this.completionQueue, testRunInfo);
69 }
70 _onTestRunRestart(testRunController) {
71 this._removeFromCompletionQueue(testRunController);
72 this.testRunControllerQueue.unshift(testRunController);
73 }
74 async _onTestRunDone(testRunController) {
75 this.total++;
76 if (!testRunController.testRun.errs.length)
77 this.passed++;
78 while (this.completionQueue.length && this.completionQueue[0].done) {
79 testRunController = this.completionQueue.shift();
80 await this.emit('test-run-done', testRunController.testRun);
81 }
82 if (!this.completionQueue.length && !this.hasQueuedTestRuns) {
83 if (!this.opts.live)
84 session_controller_1.default.closeSession(testRunController.testRun);
85 this
86 ._setResult(browser_job_result_1.default.done, { total: this.total, passed: this.passed })
87 .then(() => this.emit('done'));
88 }
89 }
90 // API
91 get hasQueuedTestRuns() {
92 return !!this.testRunControllerQueue.length;
93 }
94 async popNextTestRunUrl(connection) {
95 while (this.testRunControllerQueue.length) {
96 // NOTE: before hook for test run fixture is currently
97 // executing, so test run is temporary blocked
98 const isBlocked = this.testRunControllerQueue[0].blocked;
99 const isConcurrency = this.opts.concurrency > 1;
100 const hasIncompleteTestRuns = this.completionQueue.some(controller => !controller.done);
101 if (isBlocked || hasIncompleteTestRuns && !isConcurrency)
102 break;
103 const testRunController = this.testRunControllerQueue.shift();
104 this._addToCompletionQueue(testRunController);
105 if (!this.started) {
106 this.started = true;
107 await this.emit('start');
108 }
109 const testRunUrl = await testRunController.start(connection);
110 if (testRunUrl)
111 return testRunUrl;
112 }
113 return null;
114 }
115 abort() {
116 this.clearListeners();
117 this._setResult(browser_job_result_1.default.aborted);
118 this.browserConnections.map(bc => bc.removeJob(this));
119 }
120}
121exports.default = BrowserJob;
122module.exports = exports.default;
123//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJvd3Nlci1qb2IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVubmVyL2Jyb3dzZXItam9iLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbUNBQWdDO0FBQ2hDLHVGQUE2RDtBQUM3RCxnRkFBc0Q7QUFDdEQsd0ZBQStEO0FBQy9ELDhFQUEwQztBQUcxQyxjQUFjO0FBQ2QsTUFBcUIsVUFBVyxTQUFRLDZCQUFpQjtJQUNyRCxZQUFhLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxxQkFBcUIsRUFBRSxJQUFJO1FBQy9GLEtBQUssRUFBRSxDQUFDO1FBRVIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFFckIsSUFBSSxDQUFDLEtBQUssR0FBbUIsQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQyxNQUFNLEdBQWtCLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsSUFBSSxHQUFvQixJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLEtBQUssR0FBbUIsS0FBSyxDQUFDO1FBQ25DLElBQUksQ0FBQyxrQkFBa0IsR0FBTSxrQkFBa0IsQ0FBQztRQUNoRCxJQUFJLENBQUMsV0FBVyxHQUFhLFdBQVcsQ0FBQztRQUN6QyxJQUFJLENBQUMsVUFBVSxHQUFjLFVBQVUsQ0FBQztRQUN4QyxJQUFJLENBQUMscUJBQXFCLEdBQUcscUJBQXFCLENBQUM7UUFDbkQsSUFBSSxDQUFDLE1BQU0sR0FBa0IsSUFBSSxDQUFDO1FBRWxDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBRXJHLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO1FBRTFCLElBQUksQ0FBQyx1QkFBdUIsR0FB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O1lBRVYsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQUMsS0FBSyxFQUFFLENBQUM7WUFFOUQsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFFOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7Z0JBQ2YsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7Z0JBQ3BCLE1BQU0sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzthQUM1QjtZQUVELE1BQU0sVUFBVSxHQUFHLE1BQU0saUJBQWlCLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRTdELElBQUksVUFBVTtnQkFDVixPQUFPLFVBQVUsQ0FBQztTQUN6QjtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxLQUFLO1FBQ0QsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxVQUFVLENBQUMsNEJBQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzFELENBQUM7Q0FDSjtBQWhKRCw2QkFnSkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyByZW1vdmUgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IEFzeW5jRXZlbnRFbWl0dGVyIGZyb20gJy4uL3V0aWxzL2FzeW5jLWV2ZW50LWVtaXR0ZXInO1xuaW1wb3J0IFRlc3RSdW5Db250cm9sbGVyIGZyb20gJy4vdGVzdC1ydW4tY29udHJvbGxlcic7XG5pbXBvcnQgU2Vzc2lvbkNvbnRyb2xsZXIgZnJvbSAnLi4vdGVzdC1ydW4vc2Vzc2lvbi1jb250cm9sbGVyJztcbmltcG9ydCBSRVNVTFQgZnJvbSAnLi9icm93c2VyLWpvYi1yZXN1bHQnO1xuXG5cbi8vIEJyb3dzZXIgam9iXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCcm93c2VySm9iIGV4dGVuZHMgQXN5bmNFdmVudEVtaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yICh0ZXN0cywgYnJvd3NlckNvbm5lY3Rpb25zLCBwcm94eSwgc2NyZWVuc2hvdHMsIHdhcm5pbmdMb2csIGZpeHR1cmVIb29rQ29udHJvbGxlciwgb3B0cykge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXMuc3RhcnRlZCA9IGZhbHNlO1xuXG4gICAgICAgIHRoaXMudG90YWwgICAgICAgICAgICAgICAgID0gMDtcbiAgICAgICAgdGhpcy5wYXNzZWQgICAgICAgICAgICAgICAgPSAwO1xuICAgICAgICB0aGlzLm9wdHMgICAgICAgICAgICAgICAgICA9IG9wdHM7XG4gICAgICAgIHRoaXMucHJveHkgICAgICAgICAgICAgICAgID0gcHJveHk7XG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zICAgID0gYnJvd3NlckNvbm5lY3Rpb25zO1xuICAgICAgICB0aGlzLnNjcmVlbnNob3RzICAgICAgICAgICA9IHNjcmVlbnNob3RzO1xuICAgICAgICB0aGlzLndhcm5pbmdMb2cgICAgICAgICAgICA9IHdhcm5pbmdMb2c7XG4gICAgICAgIHRoaXMuZml4dHVyZUhvb2tDb250cm9sbGVyID0gZml4dHVyZUhvb2tDb250cm9sbGVyO1xuICAgICAgICB0aGlzLnJlc3VsdCAgICAgICAgICAgICAgICA9IG51bGw7XG5cbiAgICAgICAgdGhpcy50ZXN0UnVuQ29udHJvbGxlclF1ZXVlID0gdGVzdHMubWFwKCh0ZXN0LCBpbmRleCkgPT4gdGhpcy5fY3JlYXRlVGVzdFJ1bkNvbnRyb2xsZXIodGVzdCwgaW5kZXgpKTtcblxuICAgICAgICB0aGlzLmNvbXBsZXRpb25RdWV1ZSA9IFtdO1xuXG4gICAgICAgIHRoaXMuY29ubmVjdGlvbkVycm9yTGlzdGVuZXIgPSBlcnJvciA9PiB0aGlzLl9zZXRSZXN1bHQoUkVTVUxULmVycm9yZWQsIGVycm9yKTtcblxuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9ucy5tYXAoYmMgPT4gYmMub25jZSgnZXJyb3InLCB0aGlzLmNvbm5lY3Rpb25FcnJvckxpc3RlbmVyKSk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZVRlc3RSdW5Db250cm9sbGVyICh0ZXN0LCBpbmRleCkge1xuICAgICAgICBjb25zdCB0ZXN0UnVuQ29udHJvbGxlciA9IG5ldyBUZXN0UnVuQ29udHJvbGxlcih0ZXN0LCBpbmRleCArIDEsIHRoaXMucHJveHksIHRoaXMuc2NyZWVuc2hvdHMsIHRoaXMud2FybmluZ0xvZyxcbiAgICAgICAgICAgIHRoaXMuZml4dHVyZUhvb2tDb250cm9sbGVyLCB0aGlzLm9wdHMpO1xuXG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1jcmVhdGUnLCBhc3luYyB0ZXN0UnVuSW5mbyA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3Rlc3QtcnVuLWNyZWF0ZScsIHRlc3RSdW5JbmZvKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1zdGFydCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tc3RhcnQnLCB0ZXN0UnVuQ29udHJvbGxlci50ZXN0UnVuKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1yZWFkeScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tcmVhZHknLCB0ZXN0UnVuQ29udHJvbGxlcik7XG4gICAgICAgIH0pO1xuICAgICAgICB0ZXN0UnVuQ29udHJvbGxlci5vbigndGVzdC1ydW4tcmVzdGFydCcsIGFzeW5jICgpID0+IHRoaXMuX29uVGVzdFJ1blJlc3RhcnQodGVzdFJ1bkNvbnRyb2xsZXIpKTtcbiAgICAgICAgdGVzdFJ1bkNvbnRyb2xsZXIub24oJ3Rlc3QtcnVuLWJlZm9yZS1kb25lJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LXJ1bi1iZWZvcmUtZG9uZScsIHRlc3RSdW5Db250cm9sbGVyKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1kb25lJywgYXN5bmMgKCkgPT4gdGhpcy5fb25UZXN0UnVuRG9uZSh0ZXN0UnVuQ29udHJvbGxlcikpO1xuXG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LXJ1bi1zdGFydCcsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuZW1pdCgndGVzdC1ydW4tc3RhcnQnLCB0ZXN0UnVuQ29udHJvbGxlci50ZXN0UnVuKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGVzdFJ1bkNvbnRyb2xsZXIub24oJ3Rlc3QtYWN0aW9uLXN0YXJ0JywgYXN5bmMgYXJncyA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3Rlc3QtYWN0aW9uLXN0YXJ0JywgYXJncyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRlc3RSdW5Db250cm9sbGVyLm9uKCd0ZXN0LWFjdGlvbi1kb25lJywgYXN5bmMgYXJncyA9PiB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLmVtaXQoJ3Rlc3QtYWN0aW9uLWRvbmUnLCBhcmdzKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHRlc3RSdW5Db250cm9sbGVyO1xuICAgIH1cblxuICAgIGFzeW5jIF9zZXRSZXN1bHQgKHN0YXR1cywgZGF0YSkge1xuICAgICAgICBpZiAodGhpcy5yZXN1bHQpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGhpcy5yZXN1bHQgPSB7IHN0YXR1cywgZGF0YSB9O1xuXG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zLmZvckVhY2goYmMgPT4gYmMucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgdGhpcy5jb25uZWN0aW9uRXJyb3JMaXN0ZW5lcikpO1xuXG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zLm1hcChiYyA9PiBiYy5yZXBvcnRKb2JSZXN1bHQodGhpcy5yZXN1bHQuc3RhdHVzLCB0aGlzLnJlc3VsdC5kYXRhKSkpO1xuICAgIH1cblxuICAgIF9hZGRUb0NvbXBsZXRpb25RdWV1ZSAodGVzdFJ1bkluZm8pIHtcbiAgICAgICAgdGhpcy5jb21wbGV0aW9uUXVldWUucHVzaCh0ZXN0UnVuSW5mbyk7XG4gICAgfVxuXG4gICAgX3JlbW92ZUZyb21Db21wbGV0aW9uUXVldWUgKHRlc3RSdW5JbmZvKSB7XG4gICAgICAgIHJlbW92ZSh0aGlzLmNvbXBsZXRpb25RdWV1ZSwgdGVzdFJ1bkluZm8pO1xuICAgIH1cblxuICAgIF9vblRlc3RSdW5SZXN0YXJ0ICh0ZXN0UnVuQ29udHJvbGxlcikge1xuICAgICAgICB0aGlzLl9yZW1vdmVGcm9tQ29tcGxldGlvblF1ZXVlKHRlc3RSdW5Db250cm9sbGVyKTtcbiAgICAgICAgdGhpcy50ZXN0UnVuQ29udHJvbGxlclF1ZXVlLnVuc2hpZnQodGVzdFJ1bkNvbnRyb2xsZXIpO1xuICAgIH1cblxuICAgIGFzeW5jIF9vblRlc3RSdW5Eb25lICh0ZXN0UnVuQ29udHJvbGxlcikge1xuICAgICAgICB0aGlzLnRvdGFsKys7XG5cbiAgICAgICAgaWYgKCF0ZXN0UnVuQ29udHJvbGxlci50ZXN0UnVuLmVycnMubGVuZ3RoKVxuICAgICAgICAgICAgdGhpcy5wYXNzZWQrKztcblxuICAgICAgICB3aGlsZSAodGhpcy5jb21wbGV0aW9uUXVldWUubGVuZ3RoICYmIHRoaXMuY29tcGxldGlvblF1ZXVlWzBdLmRvbmUpIHtcbiAgICAgICAgICAgIHRlc3RSdW5Db250cm9sbGVyID0gdGhpcy5jb21wbGV0aW9uUXVldWUuc2hpZnQoKTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCd0ZXN0LXJ1bi1kb25lJywgdGVzdFJ1bkNvbnRyb2xsZXIudGVzdFJ1bik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuY29tcGxldGlvblF1ZXVlLmxlbmd0aCAmJiAhdGhpcy5oYXNRdWV1ZWRUZXN0UnVucykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLm9wdHMubGl2ZSlcbiAgICAgICAgICAgICAgICBTZXNzaW9uQ29udHJvbGxlci5jbG9zZVNlc3Npb24odGVzdFJ1bkNvbnRyb2xsZXIudGVzdFJ1bik7XG5cbiAgICAgICAgICAgIHRoaXNcbiAgICAgICAgICAgICAgICAuX3NldFJlc3VsdChSRVNVTFQuZG9uZSwgeyB0b3RhbDogdGhpcy50b3RhbCwgcGFzc2VkOiB0aGlzLnBhc3NlZCB9KVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHRoaXMuZW1pdCgnZG9uZScpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFQSVxuICAgIGdldCBoYXNRdWV1ZWRUZXN0UnVucyAoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5sZW5ndGg7XG4gICAgfVxuXG4gICAgYXN5bmMgcG9wTmV4dFRlc3RSdW5VcmwgKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgd2hpbGUgKHRoaXMudGVzdFJ1bkNvbnRyb2xsZXJRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgICAgIC8vIE5PVEU6IGJlZm9yZSBob29rIGZvciB0ZXN0IHJ1biBmaXh0dXJlIGlzIGN1cnJlbnRseVxuICAgICAgICAgICAgLy8gZXhlY3V0aW5nLCBzbyB0ZXN0IHJ1biBpcyB0ZW1wb3JhcnkgYmxvY2tlZFxuICAgICAgICAgICAgY29uc3QgaXNCbG9ja2VkICAgICAgICAgICAgID0gdGhpcy50ZXN0UnVuQ29udHJvbGxlclF1ZXVlWzBdLmJsb2NrZWQ7XG4gICAgICAgICAgICBjb25zdCBpc0NvbmN1cnJlbmN5ICAgICAgICAgPSB0aGlzLm9wdHMuY29uY3VycmVuY3kgPiAxO1xuICAgICAgICAgICAgY29uc3QgaGFzSW5jb21wbGV0ZVRlc3RSdW5zID0gdGhpcy5jb21wbGV0aW9uUXVldWUuc29tZShjb250cm9sbGVyID0+ICFjb250cm9sbGVyLmRvbmUpO1xuXG4gICAgICAgICAgICBpZiAoaXNCbG9ja2VkIHx8IGhhc0luY29tcGxldGVUZXN0UnVucyAmJiAhaXNDb25jdXJyZW5jeSlcbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY29uc3QgdGVzdFJ1bkNvbnRyb2xsZXIgPSB0aGlzLnRlc3RSdW5Db250cm9sbGVyUXVldWUuc2hpZnQoKTtcblxuICAgICAgICAgICAgdGhpcy5fYWRkVG9Db21wbGV0aW9uUXVldWUodGVzdFJ1bkNvbnRyb2xsZXIpO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuc3RhcnRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhcnRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCdzdGFydCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB0ZXN0UnVuVXJsID0gYXdhaXQgdGVzdFJ1bkNvbnRyb2xsZXIuc3RhcnQoY29ubmVjdGlvbik7XG5cbiAgICAgICAgICAgIGlmICh0ZXN0UnVuVXJsKVxuICAgICAgICAgICAgICAgIHJldHVybiB0ZXN0UnVuVXJsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgYWJvcnQgKCkge1xuICAgICAgICB0aGlzLmNsZWFyTGlzdGVuZXJzKCk7XG4gICAgICAgIHRoaXMuX3NldFJlc3VsdChSRVNVTFQuYWJvcnRlZCk7XG4gICAgICAgIHRoaXMuYnJvd3NlckNvbm5lY3Rpb25zLm1hcChiYyA9PiBiYy5yZW1vdmVKb2IodGhpcykpO1xuICAgIH1cbn1cbiJdfQ==
\No newline at end of file