1 | ;
|
2 | var __importDefault = (this && this.__importDefault) || function (mod) {
|
3 | return (mod && mod.__esModule) ? mod : { "default": mod };
|
4 | };
|
5 | Object.defineProperty(exports, "__esModule", { value: true });
|
6 | const lodash_1 = require("lodash");
|
7 | const is_stream_1 = require("is-stream");
|
8 | const plugin_host_1 = __importDefault(require("./plugin-host"));
|
9 | const command_report_item_1 = require("./command-report-item");
|
10 | const error_list_1 = __importDefault(require("../errors/error-list"));
|
11 | class Reporter {
|
12 | constructor(plugin, task, outStream) {
|
13 | this.plugin = new plugin_host_1.default(plugin, outStream);
|
14 | this.task = task;
|
15 | this.disposed = false;
|
16 | this.passed = 0;
|
17 | this.failed = 0;
|
18 | this.skipped = 0;
|
19 | this.testCount = task.tests.filter(test => !test.skip).length;
|
20 | this.reportQueue = Reporter._createReportQueue(task);
|
21 | this.stopOnFirstFail = task.opts.stopOnFirstFail;
|
22 | this.outStream = outStream;
|
23 | this.pendingTaskDonePromise = Reporter._createPendingPromise();
|
24 | this._assignTaskEventHandlers();
|
25 | }
|
26 | static _isSpecialStream(stream) {
|
27 | return stream.isTTY || stream === process.stdout || stream === process.stderr;
|
28 | }
|
29 | static _createPendingPromise() {
|
30 | let resolver = null;
|
31 | const promise = new Promise(resolve => {
|
32 | resolver = resolve;
|
33 | });
|
34 | promise.resolve = resolver;
|
35 | return promise;
|
36 | }
|
37 | static _createReportItem(test, runsPerTest) {
|
38 | return {
|
39 | fixture: test.fixture,
|
40 | test: test,
|
41 | screenshotPath: null,
|
42 | screenshots: [],
|
43 | quarantine: null,
|
44 | errs: [],
|
45 | warnings: [],
|
46 | unstable: false,
|
47 | startTime: null,
|
48 | testRunInfo: null,
|
49 | pendingRuns: runsPerTest,
|
50 | pendingStarts: runsPerTest,
|
51 | pendingTestRunDonePromise: Reporter._createPendingPromise(),
|
52 | pendingTestRunStartPromise: Reporter._createPendingPromise()
|
53 | };
|
54 | }
|
55 | static _createReportQueue(task) {
|
56 | const runsPerTest = task.browserConnectionGroups.length;
|
57 | return task.tests.map(test => Reporter._createReportItem(test, runsPerTest));
|
58 | }
|
59 | static _createTestRunInfo(reportItem) {
|
60 | return {
|
61 | errs: lodash_1.sortBy(reportItem.errs, ['userAgent', 'code']),
|
62 | warnings: reportItem.warnings,
|
63 | durationMs: new Date() - reportItem.startTime,
|
64 | unstable: reportItem.unstable,
|
65 | screenshotPath: reportItem.screenshotPath,
|
66 | screenshots: reportItem.screenshots,
|
67 | quarantine: reportItem.quarantine,
|
68 | skipped: reportItem.test.skip
|
69 | };
|
70 | }
|
71 | _getReportItemForTestRun(testRun) {
|
72 | return lodash_1.find(this.reportQueue, i => i.test === testRun.test);
|
73 | }
|
74 | async _shiftReportQueue(reportItem) {
|
75 | let currentFixture = null;
|
76 | let nextReportItem = null;
|
77 | while (this.reportQueue.length && this.reportQueue[0].testRunInfo) {
|
78 | reportItem = this.reportQueue.shift();
|
79 | currentFixture = reportItem.fixture;
|
80 | await this.plugin.reportTestDone(reportItem.test.name, reportItem.testRunInfo, reportItem.test.meta);
|
81 | // NOTE: here we assume that tests are sorted by fixture.
|
82 | // Therefore, if the next report item has a different
|
83 | // fixture, we can report this fixture start.
|
84 | nextReportItem = this.reportQueue[0];
|
85 | if (nextReportItem && nextReportItem.fixture !== currentFixture)
|
86 | await this.plugin.reportFixtureStart(nextReportItem.fixture.name, nextReportItem.fixture.path, nextReportItem.fixture.meta);
|
87 | }
|
88 | }
|
89 | async _resolveReportItem(reportItem, testRun) {
|
90 | if (this.task.screenshots.hasCapturedFor(testRun.test)) {
|
91 | reportItem.screenshotPath = this.task.screenshots.getPathFor(testRun.test);
|
92 | reportItem.screenshots = this.task.screenshots.getScreenshotsInfo(testRun.test);
|
93 | }
|
94 | if (testRun.quarantine) {
|
95 | reportItem.quarantine = testRun.quarantine.attempts.reduce((result, errors, index) => {
|
96 | const passed = !errors.length;
|
97 | const quarantineAttempt = index + 1;
|
98 | result[quarantineAttempt] = { passed };
|
99 | return result;
|
100 | }, {});
|
101 | }
|
102 | if (!reportItem.testRunInfo) {
|
103 | reportItem.testRunInfo = Reporter._createTestRunInfo(reportItem);
|
104 | if (reportItem.test.skip)
|
105 | this.skipped++;
|
106 | else if (reportItem.errs.length)
|
107 | this.failed++;
|
108 | else
|
109 | this.passed++;
|
110 | }
|
111 | await this._shiftReportQueue(reportItem);
|
112 | reportItem.pendingTestRunDonePromise.resolve();
|
113 | }
|
114 | _prepareReportTestActionEventArgs({ command, testRun, errors }) {
|
115 | const args = {};
|
116 | if (errors) {
|
117 | errors = errors instanceof error_list_1.default ? errors.items : [errors];
|
118 | args.errors = errors;
|
119 | }
|
120 | return Object.assign(args, {
|
121 | test: {
|
122 | name: testRun.test.name,
|
123 | phase: testRun.phase
|
124 | },
|
125 | command: new command_report_item_1.CommandReportItem(command),
|
126 | browser: testRun.controller.browser,
|
127 | });
|
128 | }
|
129 | _assignTaskEventHandlers() {
|
130 | const task = this.task;
|
131 | task.once('start', async () => {
|
132 | const startTime = new Date();
|
133 | const userAgents = task.browserConnectionGroups.map(group => group[0].userAgent);
|
134 | const first = this.reportQueue[0];
|
135 | await this.plugin.reportTaskStart(startTime, userAgents, this.testCount);
|
136 | await this.plugin.reportFixtureStart(first.fixture.name, first.fixture.path, first.fixture.meta);
|
137 | });
|
138 | task.on('test-run-start', async (testRun) => {
|
139 | const reportItem = this._getReportItemForTestRun(testRun);
|
140 | if (!reportItem.startTime)
|
141 | reportItem.startTime = new Date();
|
142 | reportItem.pendingStarts--;
|
143 | if (!reportItem.pendingStarts) {
|
144 | if (this.plugin.reportTestStart)
|
145 | await this.plugin.reportTestStart(reportItem.test.name, reportItem.test.meta);
|
146 | reportItem.pendingTestRunStartPromise.resolve();
|
147 | }
|
148 | return reportItem.pendingTestRunStartPromise;
|
149 | });
|
150 | task.on('test-run-done', async (testRun) => {
|
151 | const reportItem = this._getReportItemForTestRun(testRun);
|
152 | const isTestRunStoppedTaskExecution = !!testRun.errs.length && this.stopOnFirstFail;
|
153 | reportItem.pendingRuns = isTestRunStoppedTaskExecution ? 0 : reportItem.pendingRuns - 1;
|
154 | reportItem.unstable = reportItem.unstable || testRun.unstable;
|
155 | reportItem.errs = reportItem.errs.concat(testRun.errs);
|
156 | reportItem.warnings = testRun.warningLog ? lodash_1.union(reportItem.warnings, testRun.warningLog.messages) : [];
|
157 | if (!reportItem.pendingRuns)
|
158 | await this._resolveReportItem(reportItem, testRun);
|
159 | await reportItem.pendingTestRunDonePromise;
|
160 | });
|
161 | task.on('test-action-start', async ({ apiActionName, command, testRun }) => {
|
162 | if (this.plugin.reportTestActionStart) {
|
163 | const args = this._prepareReportTestActionEventArgs({ command, testRun });
|
164 | await this.plugin.reportTestActionStart(apiActionName, args);
|
165 | }
|
166 | });
|
167 | task.on('test-action-done', async ({ apiActionName, command, testRun, errors }) => {
|
168 | if (this.plugin.reportTestActionDone) {
|
169 | const args = this._prepareReportTestActionEventArgs({ command, testRun, errors });
|
170 | await this.plugin.reportTestActionDone(apiActionName, args);
|
171 | }
|
172 | });
|
173 | task.once('done', async () => {
|
174 | const endTime = new Date();
|
175 | const result = {
|
176 | passedCount: this.passed,
|
177 | failedCount: this.failed,
|
178 | skippedCount: this.skipped
|
179 | };
|
180 | await this.plugin.reportTaskDone(endTime, this.passed, task.warningLog.messages, result);
|
181 | this.pendingTaskDonePromise.resolve();
|
182 | });
|
183 | }
|
184 | async dispose() {
|
185 | if (this.disposed)
|
186 | return Promise.resolve();
|
187 | this.disposed = true;
|
188 | if (!this.outStream || Reporter._isSpecialStream(this.outStream) || !is_stream_1.writable(this.outStream))
|
189 | return Promise.resolve();
|
190 | const streamFinishedPromise = new Promise(resolve => {
|
191 | this.outStream.once('finish', resolve);
|
192 | this.outStream.once('error', resolve);
|
193 | });
|
194 | this.outStream.end();
|
195 | return streamFinishedPromise;
|
196 | }
|
197 | }
|
198 | exports.default = Reporter;
|
199 | module.exports = exports.default;
|
200 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVwb3J0ZXIvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxtQ0FBNkM7QUFDN0MseUNBQXlEO0FBQ3pELGdFQUErQztBQUMvQywrREFBMEQ7QUFDMUQsc0VBQXFEO0FBRXJELE1BQXFCLFFBQVE7SUFDekIsWUFBYSxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVM7UUFDaEMsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLHFCQUFrQixDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztRQUN4RCxJQUFJLENBQUMsSUFBSSxHQUFLLElBQUksQ0FBQztRQUVuQixJQUFJLENBQUMsUUFBUSxHQUFVLEtBQUssQ0FBQztRQUM3QixJQUFJLENBQUMsTUFBTSxHQUFZLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsTUFBTSxHQUFZLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFXLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsU0FBUyxHQUFTLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ3BFLElBQUksQ0FBQyxXQUFXLEdBQU8sUUFBUSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDakQsSUFBSSxDQUFDLFNBQVMsR0FBUyxTQUFTLENBQUM7UUFFakMsSUFBSSxDQUFDLHNCQUFzQixHQUFHLFFBQVEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBRS9ELElBQUksQ0FBQyx3QkFBd0IsRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxNQUFNLENBQUMsZ0JBQWdCLENBQUUsTUFBTTtRQUMzQixPQUFPLE1BQU0s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TzthQUM3QixDQUFDO1lBRUYsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUV6RixJQUFJLENBQUMsc0JBQXNCLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDMUMsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsS0FBSyxDQUFDLE9BQU87UUFDVCxJQUFJLElBQUksQ0FBQyxRQUFRO1lBQ2IsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFN0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFFckIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksUUFBUSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLG9CQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7WUFDakcsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFN0IsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUNoRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDdkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUVyQixPQUFPLHFCQUFxQixDQUFDO0lBQ2pDLENBQUM7Q0FDSjtBQW5QRCwyQkFtUEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmaW5kLCBzb3J0QnksIHVuaW9uIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IHdyaXRhYmxlIGFzIGlzV3JpdGFibGVTdHJlYW0gfSBmcm9tICdpcy1zdHJlYW0nO1xuaW1wb3J0IFJlcG9ydGVyUGx1Z2luSG9zdCBmcm9tICcuL3BsdWdpbi1ob3N0JztcbmltcG9ydCB7IENvbW1hbmRSZXBvcnRJdGVtIH0gZnJvbSAnLi9jb21tYW5kLXJlcG9ydC1pdGVtJztcbmltcG9ydCBUZXN0Q2FmZUVycm9yTGlzdCBmcm9tICcuLi9lcnJvcnMvZXJyb3ItbGlzdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlcG9ydGVyIHtcbiAgICBjb25zdHJ1Y3RvciAocGx1Z2luLCB0YXNrLCBvdXRTdHJlYW0pIHtcbiAgICAgICAgdGhpcy5wbHVnaW4gPSBuZXcgUmVwb3J0ZXJQbHVnaW5Ib3N0KHBsdWdpbiwgb3V0U3RyZWFtKTtcbiAgICAgICAgdGhpcy50YXNrICAgPSB0YXNrO1xuXG4gICAgICAgIHRoaXMuZGlzcG9zZWQgICAgICAgID0gZmFsc2U7XG4gICAgICAgIHRoaXMucGFzc2VkICAgICAgICAgID0gMDtcbiAgICAgICAgdGhpcy5mYWlsZWQgICAgICAgICAgPSAwO1xuICAgICAgICB0aGlzLnNraXBwZWQgICAgICAgICA9IDA7XG4gICAgICAgIHRoaXMudGVzdENvdW50ICAgICAgID0gdGFzay50ZXN0cy5maWx0ZXIodGVzdCA9PiAhdGVzdC5za2lwKS5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVwb3J0UXVldWUgICAgID0gUmVwb3J0ZXIuX2NyZWF0ZVJlcG9ydFF1ZXVlKHRhc2spO1xuICAgICAgICB0aGlzLnN0b3BPbkZpcnN0RmFpbCA9IHRhc2sub3B0cy5zdG9wT25GaXJzdEZhaWw7XG4gICAgICAgIHRoaXMub3V0U3RyZWFtICAgICAgID0gb3V0U3RyZWFtO1xuXG4gICAgICAgIHRoaXMucGVuZGluZ1Rhc2tEb25lUHJvbWlzZSA9IFJlcG9ydGVyLl9jcmVhdGVQZW5kaW5nUHJvbWlzZSgpO1xuXG4gICAgICAgIHRoaXMuX2Fzc2lnblRhc2tFdmVudEhhbmRsZXJzKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIF9pc1NwZWNpYWxTdHJlYW0gKHN0cmVhbSkge1xuICAgICAgICByZXR1cm4gc3RyZWFtLmlzVFRZIHx8IHN0cmVhbSA9PT0gcHJvY2Vzcy5zdGRvdXQgfHwgc3RyZWFtID09PSBwcm9jZXNzLnN0ZGVycjtcbiAgICB9XG5cbiAgICBzdGF0aWMgX2NyZWF0ZVBlbmRpbmdQcm9taXNlICgpIHtcbiAgICAgICAgbGV0IHJlc29sdmVyID0gbnVsbDtcblxuICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlciA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHByb21pc2UucmVzb2x2ZSA9IHJlc29sdmVyO1xuXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cblxuICAgIHN0YXRpYyBfY3JlYXRlUmVwb3J0SXRlbSAodGVzdCwgcnVuc1BlclRlc3QpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZpeHR1cmU6ICAgICAgICAgICAgICAgICAgICB0ZXN0LmZpeHR1cmUsXG4gICAgICAgICAgICB0ZXN0OiAgICAgICAgICAgICAgICAgICAgICAgdGVzdCxcbiAgICAgICAgICAgIHNjcmVlbnNob3RQYXRoOiAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgc2NyZWVuc2hvdHM6ICAgICAgICAgICAgICAgIFtdLFxuICAgICAgICAgICAgcXVhcmFudGluZTogICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBlcnJzOiAgICAgICAgICAgICAgICAgICAgICAgW10sXG4gICAgICAgICAgICB3YXJuaW5nczogICAgICAgICAgICAgICAgICAgW10sXG4gICAgICAgICAgICB1bnN0YWJsZTogICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICBzdGFydFRpbWU6ICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIHRlc3RSdW5JbmZvOiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgcGVuZGluZ1J1bnM6ICAgICAgICAgICAgICAgIHJ1bnNQZXJUZXN0LFxuICAgICAgICAgICAgcGVuZGluZ1N0YXJ0czogICAgICAgICAgICAgIHJ1bnNQZXJUZXN0LFxuICAgICAgICAgICAgcGVuZGluZ1Rlc3RSdW5Eb25lUHJvbWlzZTogIFJlcG9ydGVyLl9jcmVhdGVQZW5kaW5nUHJvbWlzZSgpLFxuICAgICAgICAgICAgcGVuZGluZ1Rlc3RSdW5TdGFydFByb21pc2U6IFJlcG9ydGVyLl9jcmVhdGVQZW5kaW5nUHJvbWlzZSgpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc3RhdGljIF9jcmVhdGVSZXBvcnRRdWV1ZSAodGFzaykge1xuICAgICAgICBjb25zdCBydW5zUGVyVGVzdCA9IHRhc2suYnJvd3NlckNvbm5lY3Rpb25Hcm91cHMubGVuZ3RoO1xuXG4gICAgICAgIHJldHVybiB0YXNrLnRlc3RzLm1hcCh0ZXN0ID0+IFJlcG9ydGVyLl9jcmVhdGVSZXBvcnRJdGVtKHRlc3QsIHJ1bnNQZXJUZXN0KSk7XG4gICAgfVxuXG4gICAgc3RhdGljIF9jcmVhdGVUZXN0UnVuSW5mbyAocmVwb3J0SXRlbSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZXJyczogICAgICAgICAgIHNvcnRCeShyZXBvcnRJdGVtLmVycnMsIFsndXNlckFnZW50JywgJ2NvZGUnXSksXG4gICAgICAgICAgICB3YXJuaW5nczogICAgICAgcmVwb3J0SXRlbS53YXJuaW5ncyxcbiAgICAgICAgICAgIGR1cmF0aW9uTXM6ICAgICBuZXcgRGF0ZSgpIC0gcmVwb3J0SXRlbS5zdGFydFRpbWUsXG4gICAgICAgICAgICB1bnN0YWJsZTogICAgICAgcmVwb3J0SXRlbS51bnN0YWJsZSxcbiAgICAgICAgICAgIHNjcmVlbnNob3RQYXRoOiByZXBvcnRJdGVtLnNjcmVlbnNob3RQYXRoLFxuICAgICAgICAgICAgc2NyZWVuc2hvdHM6ICAgIHJlcG9ydEl0ZW0uc2NyZWVuc2hvdHMsXG4gICAgICAgICAgICBxdWFyYW50aW5lOiAgICAgcmVwb3J0SXRlbS5xdWFyYW50aW5lLFxuICAgICAgICAgICAgc2tpcHBlZDogICAgICAgIHJlcG9ydEl0ZW0udGVzdC5za2lwXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgX2dldFJlcG9ydEl0ZW1Gb3JUZXN0UnVuICh0ZXN0UnVuKSB7XG4gICAgICAgIHJldHVybiBmaW5kKHRoaXMucmVwb3J0UXVldWUsIGkgPT4gaS50ZXN0ID09PSB0ZXN0UnVuLnRlc3QpO1xuICAgIH1cblxuICAgIGFzeW5jIF9zaGlmdFJlcG9ydFF1ZXVlIChyZXBvcnRJdGVtKSB7XG4gICAgICAgIGxldCBjdXJyZW50Rml4dHVyZSA9IG51bGw7XG4gICAgICAgIGxldCBuZXh0UmVwb3J0SXRlbSA9IG51bGw7XG5cbiAgICAgICAgd2hpbGUgKHRoaXMucmVwb3J0UXVldWUubGVuZ3RoICYmIHRoaXMucmVwb3J0UXVldWVbMF0udGVzdFJ1bkluZm8pIHtcbiAgICAgICAgICAgIHJlcG9ydEl0ZW0gICAgID0gdGhpcy5yZXBvcnRRdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgY3VycmVudEZpeHR1cmUgPSByZXBvcnRJdGVtLmZpeHR1cmU7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnJlcG9ydFRlc3REb25lKHJlcG9ydEl0ZW0udGVzdC5uYW1lLCByZXBvcnRJdGVtLnRlc3RSdW5JbmZvLCByZXBvcnRJdGVtLnRlc3QubWV0YSk7XG5cbiAgICAgICAgICAgIC8vIE5PVEU6IGhlcmUgd2UgYXNzdW1lIHRoYXQgdGVzdHMgYXJlIHNvcnRlZCBieSBmaXh0dXJlLlxuICAgICAgICAgICAgLy8gVGhlcmVmb3JlLCBpZiB0aGUgbmV4dCByZXBvcnQgaXRlbSBoYXMgYSBkaWZmZXJlbnRcbiAgICAgICAgICAgIC8vIGZpeHR1cmUsIHdlIGNhbiByZXBvcnQgdGhpcyBmaXh0dXJlIHN0YXJ0LlxuICAgICAgICAgICAgbmV4dFJlcG9ydEl0ZW0gPSB0aGlzLnJlcG9ydFF1ZXVlWzBdO1xuXG4gICAgICAgICAgICBpZiAobmV4dFJlcG9ydEl0ZW0gJiYgbmV4dFJlcG9ydEl0ZW0uZml4dHVyZSAhPT0gY3VycmVudEZpeHR1cmUpXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4ucmVwb3J0Rml4dHVyZVN0YXJ0KG5leHRSZXBvcnRJdGVtLmZpeHR1cmUubmFtZSwgbmV4dFJlcG9ydEl0ZW0uZml4dHVyZS5wYXRoLCBuZXh0UmVwb3J0SXRlbS5maXh0dXJlLm1ldGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgX3Jlc29sdmVSZXBvcnRJdGVtIChyZXBvcnRJdGVtLCB0ZXN0UnVuKSB7XG4gICAgICAgIGlmICh0aGlzLnRhc2suc2NyZWVuc2hvdHMuaGFzQ2FwdHVyZWRGb3IodGVzdFJ1bi50ZXN0KSkge1xuICAgICAgICAgICAgcmVwb3J0SXRlbS5zY3JlZW5zaG90UGF0aCA9IHRoaXMudGFzay5zY3JlZW5zaG90cy5nZXRQYXRoRm9yKHRlc3RSdW4udGVzdCk7XG4gICAgICAgICAgICByZXBvcnRJdGVtLnNjcmVlbnNob3RzICAgID0gdGhpcy50YXNrLnNjcmVlbnNob3RzLmdldFNjcmVlbnNob3RzSW5mbyh0ZXN0UnVuLnRlc3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRlc3RSdW4ucXVhcmFudGluZSkge1xuICAgICAgICAgICAgcmVwb3J0SXRlbS5xdWFyYW50aW5lID0gdGVzdFJ1bi5xdWFyYW50aW5lLmF0dGVtcHRzLnJlZHVjZSgocmVzdWx0LCBlcnJvcnMsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFzc2VkICAgICAgICAgICAgPSAhZXJyb3JzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBjb25zdCBxdWFyYW50aW5lQXR0ZW1wdCA9IGluZGV4ICsgMTtcblxuICAgICAgICAgICAgICAgIHJlc3VsdFtxdWFyYW50aW5lQXR0ZW1wdF0gPSB7IHBhc3NlZCB9O1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0sIHt9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghcmVwb3J0SXRlbS50ZXN0UnVuSW5mbykge1xuICAgICAgICAgICAgcmVwb3J0SXRlbS50ZXN0UnVuSW5mbyA9IFJlcG9ydGVyLl9jcmVhdGVUZXN0UnVuSW5mbyhyZXBvcnRJdGVtKTtcblxuICAgICAgICAgICAgaWYgKHJlcG9ydEl0ZW0udGVzdC5za2lwKVxuICAgICAgICAgICAgICAgIHRoaXMuc2tpcHBlZCsrO1xuICAgICAgICAgICAgZWxzZSBpZiAocmVwb3J0SXRlbS5lcnJzLmxlbmd0aClcbiAgICAgICAgICAgICAgICB0aGlzLmZhaWxlZCsrO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRoaXMucGFzc2VkKys7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLl9zaGlmdFJlcG9ydFF1ZXVlKHJlcG9ydEl0ZW0pO1xuXG4gICAgICAgIHJlcG9ydEl0ZW0ucGVuZGluZ1Rlc3RSdW5Eb25lUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgX3ByZXBhcmVSZXBvcnRUZXN0QWN0aW9uRXZlbnRBcmdzICh7IGNvbW1hbmQsIHRlc3RSdW4sIGVycm9ycyB9KSB7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSB7fTtcblxuICAgICAgICBpZiAoZXJyb3JzKSB7XG4gICAgICAgICAgICBlcnJvcnMgPSBlcnJvcnMgaW5zdGFuY2VvZiBUZXN0Q2FmZUVycm9yTGlzdCA/IGVycm9ycy5pdGVtcyA6IFtlcnJvcnNdO1xuXG4gICAgICAgICAgICBhcmdzLmVycm9ycyA9IGVycm9ycztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGFyZ3MsIHtcbiAgICAgICAgICAgIHRlc3Q6IHtcbiAgICAgICAgICAgICAgICBuYW1lOiAgdGVzdFJ1bi50ZXN0Lm5hbWUsXG4gICAgICAgICAgICAgICAgcGhhc2U6IHRlc3RSdW4ucGhhc2VcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjb21tYW5kOiBuZXcgQ29tbWFuZFJlcG9ydEl0ZW0oY29tbWFuZCksXG4gICAgICAgICAgICBicm93c2VyOiB0ZXN0UnVuLmNvbnRyb2xsZXIuYnJvd3NlcixcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX2Fzc2lnblRhc2tFdmVudEhhbmRsZXJzICgpIHtcbiAgICAgICAgY29uc3QgdGFzayA9IHRoaXMudGFzaztcblxuICAgICAgICB0YXNrLm9uY2UoJ3N0YXJ0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRUaW1lICA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICBjb25zdCB1c2VyQWdlbnRzID0gdGFzay5icm93c2VyQ29ubmVjdGlvbkdyb3Vwcy5tYXAoZ3JvdXAgPT4gZ3JvdXBbMF0udXNlckFnZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0ICAgICAgPSB0aGlzLnJlcG9ydFF1ZXVlWzBdO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5yZXBvcnRUYXNrU3RhcnQoc3RhcnRUaW1lLCB1c2VyQWdlbnRzLCB0aGlzLnRlc3RDb3VudCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5yZXBvcnRGaXh0dXJlU3RhcnQoZmlyc3QuZml4dHVyZS5uYW1lLCBmaXJzdC5maXh0dXJlLnBhdGgsIGZpcnN0LmZpeHR1cmUubWV0YSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRhc2sub24oJ3Rlc3QtcnVuLXN0YXJ0JywgYXN5bmMgdGVzdFJ1biA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXBvcnRJdGVtID0gdGhpcy5fZ2V0UmVwb3J0SXRlbUZvclRlc3RSdW4odGVzdFJ1bik7XG5cbiAgICAgICAgICAgIGlmICghcmVwb3J0SXRlbS5zdGFydFRpbWUpXG4gICAgICAgICAgICAgICAgcmVwb3J0SXRlbS5zdGFydFRpbWUgPSBuZXcgRGF0ZSgpO1xuXG4gICAgICAgICAgICByZXBvcnRJdGVtLnBlbmRpbmdTdGFydHMtLTtcblxuICAgICAgICAgICAgaWYgKCFyZXBvcnRJdGVtLnBlbmRpbmdTdGFydHMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wbHVnaW4ucmVwb3J0VGVzdFN0YXJ0KVxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5yZXBvcnRUZXN0U3RhcnQocmVwb3J0SXRlbS50ZXN0Lm5hbWUsIHJlcG9ydEl0ZW0udGVzdC5tZXRhKTtcblxuICAgICAgICAgICAgICAgIHJlcG9ydEl0ZW0ucGVuZGluZ1Rlc3RSdW5TdGFydFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0SXRlbS5wZW5kaW5nVGVzdFJ1blN0YXJ0UHJvbWlzZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGFzay5vbigndGVzdC1ydW4tZG9uZScsIGFzeW5jIHRlc3RSdW4gPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVwb3J0SXRlbSAgICAgICAgICAgICAgICAgICAgPSB0aGlzLl9nZXRSZXBvcnRJdGVtRm9yVGVzdFJ1bih0ZXN0UnVuKTtcbiAgICAgICAgICAgIGNvbnN0IGlzVGVzdFJ1blN0b3BwZWRUYXNrRXhlY3V0aW9uID0gISF0ZXN0UnVuLmVycnMubGVuZ3RoICYmIHRoaXMuc3RvcE9uRmlyc3RGYWlsO1xuXG4gICAgICAgICAgICByZXBvcnRJdGVtLnBlbmRpbmdSdW5zID0gaXNUZXN0UnVuU3RvcHBlZFRhc2tFeGVjdXRpb24gPyAwIDogcmVwb3J0SXRlbS5wZW5kaW5nUnVucyAtIDE7XG4gICAgICAgICAgICByZXBvcnRJdGVtLnVuc3RhYmxlICAgID0gcmVwb3J0SXRlbS51bnN0YWJsZSB8fCB0ZXN0UnVuLnVuc3RhYmxlO1xuICAgICAgICAgICAgcmVwb3J0SXRlbS5lcnJzICAgICAgICA9IHJlcG9ydEl0ZW0uZXJycy5jb25jYXQodGVzdFJ1bi5lcnJzKTtcbiAgICAgICAgICAgIHJlcG9ydEl0ZW0ud2FybmluZ3MgICAgPSB0ZXN0UnVuLndhcm5pbmdMb2cgPyB1bmlvbihyZXBvcnRJdGVtLndhcm5pbmdzLCB0ZXN0UnVuLndhcm5pbmdMb2cubWVzc2FnZXMpIDogW107XG5cbiAgICAgICAgICAgIGlmICghcmVwb3J0SXRlbS5wZW5kaW5nUnVucylcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLl9yZXNvbHZlUmVwb3J0SXRlbShyZXBvcnRJdGVtLCB0ZXN0UnVuKTtcblxuICAgICAgICAgICAgYXdhaXQgcmVwb3J0SXRlbS5wZW5kaW5nVGVzdFJ1bkRvbmVQcm9taXNlO1xuICAgICAgICB9KTtcblxuICAgICAgICB0YXNrLm9uKCd0ZXN0LWFjdGlvbi1zdGFydCcsIGFzeW5jICh7IGFwaUFjdGlvbk5hbWUsIGNvbW1hbmQsIHRlc3RSdW4gfSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucGx1Z2luLnJlcG9ydFRlc3RBY3Rpb25TdGFydCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSB0aGlzLl9wcmVwYXJlUmVwb3J0VGVzdEFjdGlvbkV2ZW50QXJncyh7IGNvbW1hbmQsIHRlc3RSdW4gfSk7XG5cbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5yZXBvcnRUZXN0QWN0aW9uU3RhcnQoYXBpQWN0aW9uTmFtZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRhc2sub24oJ3Rlc3QtYWN0aW9uLWRvbmUnLCBhc3luYyAoeyBhcGlBY3Rpb25OYW1lLCBjb21tYW5kLCB0ZXN0UnVuLCBlcnJvcnMgfSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMucGx1Z2luLnJlcG9ydFRlc3RBY3Rpb25Eb25lKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJncyA9IHRoaXMuX3ByZXBhcmVSZXBvcnRUZXN0QWN0aW9uRXZlbnRBcmdzKHsgY29tbWFuZCwgdGVzdFJ1biwgZXJyb3JzIH0pO1xuXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4ucmVwb3J0VGVzdEFjdGlvbkRvbmUoYXBpQWN0aW9uTmFtZSwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRhc2sub25jZSgnZG9uZScsIGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVuZFRpbWUgPSBuZXcgRGF0ZSgpO1xuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICAgICAgICAgICAgcGFzc2VkQ291bnQ6ICB0aGlzLnBhc3NlZCxcbiAgICAgICAgICAgICAgICBmYWlsZWRDb3VudDogIHRoaXMuZmFpbGVkLFxuICAgICAgICAgICAgICAgIHNraXBwZWRDb3VudDogdGhpcy5za2lwcGVkXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5yZXBvcnRUYXNrRG9uZShlbmRUaW1lLCB0aGlzLnBhc3NlZCwgdGFzay53YXJuaW5nTG9nLm1lc3NhZ2VzLCByZXN1bHQpO1xuXG4gICAgICAgICAgICB0aGlzLnBlbmRpbmdUYXNrRG9uZVByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBhc3luYyBkaXNwb3NlICgpIHtcbiAgICAgICAgaWYgKHRoaXMuZGlzcG9zZWQpXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgICAgICAgdGhpcy5kaXNwb3NlZCA9IHRydWU7XG5cbiAgICAgICAgaWYgKCF0aGlzLm91dFN0cmVhbSB8fCBSZXBvcnRlci5faXNTcGVjaWFsU3RyZWFtKHRoaXMub3V0U3RyZWFtKSB8fCAhaXNXcml0YWJsZVN0cmVhbSh0aGlzLm91dFN0cmVhbSkpXG4gICAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG5cbiAgICAgICAgY29uc3Qgc3RyZWFtRmluaXNoZWRQcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICB0aGlzLm91dFN0cmVhbS5vbmNlKCdmaW5pc2gnLCByZXNvbHZlKTtcbiAgICAgICAgICAgIHRoaXMub3V0U3RyZWFtLm9uY2UoJ2Vycm9yJywgcmVzb2x2ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMub3V0U3RyZWFtLmVuZCgpO1xuXG4gICAgICAgIHJldHVybiBzdHJlYW1GaW5pc2hlZFByb21pc2U7XG4gICAgfVxufVxuIl19 |
\ | No newline at end of file |