UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

172 lines 27.6 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const pinkie_1 = __importDefault(require("pinkie")); const lodash_1 = require("lodash"); const is_stream_1 = require("is-stream"); const plugin_host_1 = __importDefault(require("./plugin-host")); class Reporter { constructor(plugin, task, outStream) { this.plugin = new plugin_host_1.default(plugin, outStream); this.task = task; this.disposed = false; this.passed = 0; this.failed = 0; this.skipped = 0; this.testCount = task.tests.filter(test => !test.skip).length; this.reportQueue = Reporter._createReportQueue(task); this.stopOnFirstFail = task.opts.stopOnFirstFail; this.outStream = outStream; this.pendingTaskDonePromise = Reporter._createPendingPromise(); this._assignTaskEventHandlers(); } static _isSpecialStream(stream) { return stream.isTTY || stream === process.stdout || stream === process.stderr; } static _createPendingPromise() { let resolver = null; const promise = new pinkie_1.default(resolve => { resolver = resolve; }); promise.resolve = resolver; return promise; } static _createReportItem(test, runsPerTest) { return { fixture: test.fixture, test: test, screenshotPath: null, screenshots: [], quarantine: null, errs: [], warnings: [], unstable: false, startTime: null, testRunInfo: null, pendingRuns: runsPerTest, pendingStarts: runsPerTest, pendingTestRunDonePromise: Reporter._createPendingPromise(), pendingTestRunStartPromise: Reporter._createPendingPromise() }; } static _createReportQueue(task) { const runsPerTest = task.browserConnectionGroups.length; return task.tests.map(test => Reporter._createReportItem(test, runsPerTest)); } static _createTestRunInfo(reportItem) { return { errs: lodash_1.sortBy(reportItem.errs, ['userAgent', 'code']), warnings: reportItem.warnings, durationMs: new Date() - reportItem.startTime, unstable: reportItem.unstable, screenshotPath: reportItem.screenshotPath, screenshots: reportItem.screenshots, quarantine: reportItem.quarantine, skipped: reportItem.test.skip }; } _getReportItemForTestRun(testRun) { return lodash_1.find(this.reportQueue, i => i.test === testRun.test); } async _shiftReportQueue(reportItem) { let currentFixture = null; let nextReportItem = null; while (this.reportQueue.length && this.reportQueue[0].testRunInfo) { reportItem = this.reportQueue.shift(); currentFixture = reportItem.fixture; await this.plugin.reportTestDone(reportItem.test.name, reportItem.testRunInfo, reportItem.test.meta); // NOTE: here we assume that tests are sorted by fixture. // Therefore, if the next report item has a different // fixture, we can report this fixture start. nextReportItem = this.reportQueue[0]; if (nextReportItem && nextReportItem.fixture !== currentFixture) await this.plugin.reportFixtureStart(nextReportItem.fixture.name, nextReportItem.fixture.path, nextReportItem.fixture.meta); } } async _resolveReportItem(reportItem, testRun) { if (this.task.screenshots.hasCapturedFor(testRun.test)) { reportItem.screenshotPath = this.task.screenshots.getPathFor(testRun.test); reportItem.screenshots = this.task.screenshots.getScreenshotsInfo(testRun.test); } if (testRun.quarantine) { reportItem.quarantine = testRun.quarantine.attempts.reduce((result, errors, index) => { const passed = !errors.length; const quarantineAttempt = index + 1; result[quarantineAttempt] = { passed }; return result; }, {}); } if (!reportItem.testRunInfo) { reportItem.testRunInfo = Reporter._createTestRunInfo(reportItem); if (reportItem.test.skip) this.skipped++; else if (reportItem.errs.length) this.failed++; else this.passed++; } await this._shiftReportQueue(reportItem); reportItem.pendingTestRunDonePromise.resolve(); } _assignTaskEventHandlers() { const task = this.task; task.once('start', async () => { const startTime = new Date(); const userAgents = task.browserConnectionGroups.map(group => group[0].userAgent); const first = this.reportQueue[0]; await this.plugin.reportTaskStart(startTime, userAgents, this.testCount); await this.plugin.reportFixtureStart(first.fixture.name, first.fixture.path, first.fixture.meta); }); task.on('test-run-start', async (testRun) => { const reportItem = this._getReportItemForTestRun(testRun); if (!reportItem.startTime) reportItem.startTime = new Date(); reportItem.pendingStarts--; if (!reportItem.pendingStarts) { if (this.plugin.reportTestStart) await this.plugin.reportTestStart(reportItem.test.name, reportItem.test.meta); reportItem.pendingTestRunStartPromise.resolve(); } return reportItem.pendingTestRunStartPromise; }); task.on('test-run-done', async (testRun) => { const reportItem = this._getReportItemForTestRun(testRun); const isTestRunStoppedTaskExecution = !!testRun.errs.length && this.stopOnFirstFail; reportItem.pendingRuns = isTestRunStoppedTaskExecution ? 0 : reportItem.pendingRuns - 1; reportItem.unstable = reportItem.unstable || testRun.unstable; reportItem.errs = reportItem.errs.concat(testRun.errs); reportItem.warnings = testRun.warningLog ? lodash_1.union(reportItem.warnings, testRun.warningLog.messages) : []; if (!reportItem.pendingRuns) await this._resolveReportItem(reportItem, testRun); await reportItem.pendingTestRunDonePromise; }); task.once('done', async () => { const endTime = new Date(); const result = { passedCount: this.passed, failedCount: this.failed, skippedCount: this.skipped }; await this.plugin.reportTaskDone(endTime, this.passed, task.warningLog.messages, result); this.pendingTaskDonePromise.resolve(); }); } async dispose() { if (this.disposed) return pinkie_1.default.resolve(); this.disposed = true; if (!this.outStream || Reporter._isSpecialStream(this.outStream) || !is_stream_1.writable(this.outStream)) return pinkie_1.default.resolve(); const streamFinishedPromise = new pinkie_1.default(resolve => { this.outStream.once('finish', resolve); this.outStream.once('error', resolve); }); this.outStream.end(); return streamFinishedPromise; } } exports.default = Reporter; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcmVwb3J0ZXIvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxvREFBNkI7QUFDN0IsbUNBQTZDO0FBQzdDLHlDQUF5RDtBQUN6RCxnRUFBK0M7QUFFL0MsTUFBcUIsUUFBUTtJQUN6QixZQUFhLE1BQU0sRUFBRSxJQUFJLEVBQUUsU0FBUztRQUNoQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUkscUJBQWtCLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxJQUFJLEdBQUssSUFBSSxDQUFDO1FBRW5CLElBQUksQ0FBQyxRQUFRLEdBQVUsS0FBSyxDQUFDO1FBQzdCLElBQUksQ0FBQyxNQUFNLEdBQVksQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQVksQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQVcsQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxTQUFTLEdBQVMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDcEUsSUFBSSxDQUFDLFdBQVcsR0FBTyxRQUFRLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQztRQUNqRCxJQUFJLENBQUMsU0FBUyxHQUFTLFNBQVMsQ0FBQztRQUVqQyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsUUFBUSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFFL0QsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7SUFDcEMsQ0FBQztJQUVELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBRSxNQUFNO1FBQzNCLE9BQU8sTUFBTSxDQUFDLEtBQUssSUFB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Q0FBQyxRQUFRO1lBQ2IsT0FBTyxnQkFBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRTdCLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBRXJCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxvQkFBZ0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ2pHLE9BQU8sZ0JBQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUU3QixNQUFNLHFCQUFxQixHQUFHLElBQUksZ0JBQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUNoRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDdkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUVyQixPQUFPLHFCQUFxQixDQUFDO0lBQ2pDLENBQUM7Q0FDSjtBQWhORCwyQkFnTkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUHJvbWlzZSBmcm9tICdwaW5raWUnO1xuaW1wb3J0IHsgZmluZCwgc29ydEJ5LCB1bmlvbiB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyB3cml0YWJsZSBhcyBpc1dyaXRhYmxlU3RyZWFtIH0gZnJvbSAnaXMtc3RyZWFtJztcbmltcG9ydCBSZXBvcnRlclBsdWdpbkhvc3QgZnJvbSAnLi9wbHVnaW4taG9zdCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlcG9ydGVyIHtcbiAgICBjb25zdHJ1Y3RvciAocGx1Z2luLCB0YXNrLCBvdXRTdHJlYW0pIHtcbiAgICAgICAgdGhpcy5wbHVnaW4gPSBuZXcgUmVwb3J0ZXJQbHVnaW5Ib3N0KHBsdWdpbiwgb3V0U3RyZWFtKTtcbiAgICAgICAgdGhpcy50YXNrICAgPSB0YXNrO1xuXG4gICAgICAgIHRoaXMuZGlzcG9zZWQgICAgICAgID0gZmFsc2U7XG4gICAgICAgIHRoaXMucGFzc2VkICAgICAgICAgID0gMDtcbiAgICAgICAgdGhpcy5mYWlsZWQgICAgICAgICAgPSAwO1xuICAgICAgICB0aGlzLnNraXBwZWQgICAgICAgICA9IDA7XG4gICAgICAgIHRoaXMudGVzdENvdW50ICAgICAgID0gdGFzay50ZXN0cy5maWx0ZXIodGVzdCA9PiAhdGVzdC5za2lwKS5sZW5ndGg7XG4gICAgICAgIHRoaXMucmVwb3J0UXVldWUgICAgID0gUmVwb3J0ZXIuX2NyZWF0ZVJlcG9ydFF1ZXVlKHRhc2spO1xuICAgICAgICB0aGlzLnN0b3BPbkZpcnN0RmFpbCA9IHRhc2sub3B0cy5zdG9wT25GaXJzdEZhaWw7XG4gICAgICAgIHRoaXMub3V0U3RyZWFtICAgICAgID0gb3V0U3RyZWFtO1xuXG4gICAgICAgIHRoaXMucGVuZGluZ1Rhc2tEb25lUHJvbWlzZSA9IFJlcG9ydGVyLl9jcmVhdGVQZW5kaW5nUHJvbWlzZSgpO1xuXG4gICAgICAgIHRoaXMuX2Fzc2lnblRhc2tFdmVudEhhbmRsZXJzKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIF9pc1NwZWNpYWxTdHJlYW0gKHN0cmVhbSkge1xuICAgICAgICByZXR1cm4gc3RyZWFtLmlzVFRZIHx8IHN0cmVhbSA9PT0gcHJvY2Vzcy5zdGRvdXQgfHwgc3RyZWFtID09PSBwcm9jZXNzLnN0ZGVycjtcbiAgICB9XG5cbiAgICBzdGF0aWMgX2NyZWF0ZVBlbmRpbmdQcm9taXNlICgpIHtcbiAgICAgICAgbGV0IHJlc29sdmVyID0gbnVsbDtcblxuICAgICAgICBjb25zdCBwcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICByZXNvbHZlciA9IHJlc29sdmU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHByb21pc2UucmVzb2x2ZSA9IHJlc29sdmVyO1xuXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cblxuICAgIHN0YXRpYyBfY3JlYXRlUmVwb3J0SXRlbSAodGVzdCwgcnVuc1BlclRlc3QpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZpeHR1cmU6ICAgICAgICAgICAgICAgICAgICB0ZXN0LmZpeHR1cmUsXG4gICAgICAgICAgICB0ZXN0OiAgICAgICAgICAgICAgICAgICAgICAgdGVzdCxcbiAgICAgICAgICAgIHNjcmVlbnNob3RQYXRoOiAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgc2NyZWVuc2hvdHM6ICAgICAgICAgICAgICAgIFtdLFxuICAgICAgICAgICAgcXVhcmFudGluZTogICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBlcnJzOiAgICAgICAgICAgICAgICAgICAgICAgW10sXG4gICAgICAgICAgICB3YXJuaW5nczogICAgICAgICAgICAgICAgICAgW10sXG4gICAgICAgICAgICB1bnN0YWJsZTogICAgICAgICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgICAgICBzdGFydFRpbWU6ICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIHRlc3RSdW5JbmZvOiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgcGVuZGluZ1J1bnM6ICAgICAgICAgICAgICAgIHJ1bnNQZXJUZXN0LFxuICAgICAgICAgICAgcGVuZGluZ1N0YXJ0czogICAgICAgICAgICAgIHJ1bnNQZXJUZXN0LFxuICAgICAgICAgICAgcGVuZGluZ1Rlc3RSdW5Eb25lUHJvbWlzZTogIFJlcG9ydGVyLl9jcmVhdGVQZW5kaW5nUHJvbWlzZSgpLFxuICAgICAgICAgICAgcGVuZGluZ1Rlc3RSdW5TdGFydFByb21pc2U6IFJlcG9ydGVyLl9jcmVhdGVQZW5kaW5nUHJvbWlzZSgpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgc3RhdGljIF9jcmVhdGVSZXBvcnRRdWV1ZSAodGFzaykge1xuICAgICAgICBjb25zdCBydW5zUGVyVGVzdCA9IHRhc2suYnJvd3NlckNvbm5lY3Rpb25Hcm91cHMubGVuZ3RoO1xuXG4gICAgICAgIHJldHVybiB0YXNrLnRlc3RzLm1hcCh0ZXN0ID0+IFJlcG9ydGVyLl9jcmVhdGVSZXBvcnRJdGVtKHRlc3QsIHJ1bnNQZXJUZXN0KSk7XG4gICAgfVxuXG4gICAgc3RhdGljIF9jcmVhdGVUZXN0UnVuSW5mbyAocmVwb3J0SXRlbSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZXJyczogICAgICAgICAgIHNvcnRCeShyZXBvcnRJdGVtLmVycnMsIFsndXNlckFnZW50JywgJ2NvZGUnXSksXG4gICAgICAgICAgICB3YXJuaW5nczogICAgICAgcmVwb3J0SXRlbS53YXJuaW5ncyxcbiAgICAgICAgICAgIGR1cmF0aW9uTXM6ICAgICBuZXcgRGF0ZSgpIC0gcmVwb3J0SXRlbS5zdGFydFRpbWUsXG4gICAgICAgICAgICB1bnN0YWJsZTogICAgICAgcmVwb3J0SXRlbS51bnN0YWJsZSxcbiAgICAgICAgICAgIHNjcmVlbnNob3RQYXRoOiByZXBvcnRJdGVtLnNjcmVlbnNob3RQYXRoLFxuICAgICAgICAgICAgc2NyZWVuc2hvdHM6ICAgIHJlcG9ydEl0ZW0uc2NyZWVuc2hvdHMsXG4gICAgICAgICAgICBxdWFyYW50aW5lOiAgICAgcmVwb3J0SXRlbS5xdWFyYW50aW5lLFxuICAgICAgICAgICAgc2tpcHBlZDogICAgICAgIHJlcG9ydEl0ZW0udGVzdC5za2lwXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgX2dldFJlcG9ydEl0ZW1Gb3JUZXN0UnVuICh0ZXN0UnVuKSB7XG4gICAgICAgIHJldHVybiBmaW5kKHRoaXMucmVwb3J0UXVldWUsIGkgPT4gaS50ZXN0ID09PSB0ZXN0UnVuLnRlc3QpO1xuICAgIH1cblxuICAgIGFzeW5jIF9zaGlmdFJlcG9ydFF1ZXVlIChyZXBvcnRJdGVtKSB7XG4gICAgICAgIGxldCBjdXJyZW50Rml4dHVyZSA9IG51bGw7XG4gICAgICAgIGxldCBuZXh0UmVwb3J0SXRlbSA9IG51bGw7XG5cbiAgICAgICAgd2hpbGUgKHRoaXMucmVwb3J0UXVldWUubGVuZ3RoICYmIHRoaXMucmVwb3J0UXVldWVbMF0udGVzdFJ1bkluZm8pIHtcbiAgICAgICAgICAgIHJlcG9ydEl0ZW0gICAgID0gdGhpcy5yZXBvcnRRdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgICAgY3VycmVudEZpeHR1cmUgPSByZXBvcnRJdGVtLmZpeHR1cmU7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMucGx1Z2luLnJlcG9ydFRlc3REb25lKHJlcG9ydEl0ZW0udGVzdC5uYW1lLCByZXBvcnRJdGVtLnRlc3RSdW5JbmZvLCByZXBvcnRJdGVtLnRlc3QubWV0YSk7XG5cbiAgICAgICAgICAgIC8vIE5PVEU6IGhlcmUgd2UgYXNzdW1lIHRoYXQgdGVzdHMgYXJlIHNvcnRlZCBieSBmaXh0dXJlLlxuICAgICAgICAgICAgLy8gVGhlcmVmb3JlLCBpZiB0aGUgbmV4dCByZXBvcnQgaXRlbSBoYXMgYSBkaWZmZXJlbnRcbiAgICAgICAgICAgIC8vIGZpeHR1cmUsIHdlIGNhbiByZXBvcnQgdGhpcyBmaXh0dXJlIHN0YXJ0LlxuICAgICAgICAgICAgbmV4dFJlcG9ydEl0ZW0gPSB0aGlzLnJlcG9ydFF1ZXVlWzBdO1xuXG4gICAgICAgICAgICBpZiAobmV4dFJlcG9ydEl0ZW0gJiYgbmV4dFJlcG9ydEl0ZW0uZml4dHVyZSAhPT0gY3VycmVudEZpeHR1cmUpXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4ucmVwb3J0Rml4dHVyZVN0YXJ0KG5leHRSZXBvcnRJdGVtLmZpeHR1cmUubmFtZSwgbmV4dFJlcG9ydEl0ZW0uZml4dHVyZS5wYXRoLCBuZXh0UmVwb3J0SXRlbS5maXh0dXJlLm1ldGEpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgX3Jlc29sdmVSZXBvcnRJdGVtIChyZXBvcnRJdGVtLCB0ZXN0UnVuKSB7XG4gICAgICAgIGlmICh0aGlzLnRhc2suc2NyZWVuc2hvdHMuaGFzQ2FwdHVyZWRGb3IodGVzdFJ1bi50ZXN0KSkge1xuICAgICAgICAgICAgcmVwb3J0SXRlbS5zY3JlZW5zaG90UGF0aCA9IHRoaXMudGFzay5zY3JlZW5zaG90cy5nZXRQYXRoRm9yKHRlc3RSdW4udGVzdCk7XG4gICAgICAgICAgICByZXBvcnRJdGVtLnNjcmVlbnNob3RzICAgID0gdGhpcy50YXNrLnNjcmVlbnNob3RzLmdldFNjcmVlbnNob3RzSW5mbyh0ZXN0UnVuLnRlc3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRlc3RSdW4ucXVhcmFudGluZSkge1xuICAgICAgICAgICAgcmVwb3J0SXRlbS5xdWFyYW50aW5lID0gdGVzdFJ1bi5xdWFyYW50aW5lLmF0dGVtcHRzLnJlZHVjZSgocmVzdWx0LCBlcnJvcnMsIGluZGV4KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFzc2VkICAgICAgICAgICAgPSAhZXJyb3JzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBjb25zdCBxdWFyYW50aW5lQXR0ZW1wdCA9IGluZGV4ICsgMTtcblxuICAgICAgICAgICAgICAgIHJlc3VsdFtxdWFyYW50aW5lQXR0ZW1wdF0gPSB7IHBhc3NlZCB9O1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgICAgIH0sIHt9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghcmVwb3J0SXRlbS50ZXN0UnVuSW5mbykge1xuICAgICAgICAgICAgcmVwb3J0SXRlbS50ZXN0UnVuSW5mbyA9IFJlcG9ydGVyLl9jcmVhdGVUZXN0UnVuSW5mbyhyZXBvcnRJdGVtKTtcblxuICAgICAgICAgICAgaWYgKHJlcG9ydEl0ZW0udGVzdC5za2lwKVxuICAgICAgICAgICAgICAgIHRoaXMuc2tpcHBlZCsrO1xuICAgICAgICAgICAgZWxzZSBpZiAocmVwb3J0SXRlbS5lcnJzLmxlbmd0aClcbiAgICAgICAgICAgICAgICB0aGlzLmZhaWxlZCsrO1xuICAgICAgICAgICAgZWxzZVxuICAgICAgICAgICAgICAgIHRoaXMucGFzc2VkKys7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLl9zaGlmdFJlcG9ydFF1ZXVlKHJlcG9ydEl0ZW0pO1xuXG4gICAgICAgIHJlcG9ydEl0ZW0ucGVuZGluZ1Rlc3RSdW5Eb25lUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgX2Fzc2lnblRhc2tFdmVudEhhbmRsZXJzICgpIHtcbiAgICAgICAgY29uc3QgdGFzayA9IHRoaXMudGFzaztcblxuICAgICAgICB0YXNrLm9uY2UoJ3N0YXJ0JywgYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3RhcnRUaW1lICA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICBjb25zdCB1c2VyQWdlbnRzID0gdGFzay5icm93c2VyQ29ubmVjdGlvbkdyb3Vwcy5tYXAoZ3JvdXAgPT4gZ3JvdXBbMF0udXNlckFnZW50KTtcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0ICAgICAgPSB0aGlzLnJlcG9ydFF1ZXVlWzBdO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5yZXBvcnRUYXNrU3RhcnQoc3RhcnRUaW1lLCB1c2VyQWdlbnRzLCB0aGlzLnRlc3RDb3VudCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5yZXBvcnRGaXh0dXJlU3RhcnQoZmlyc3QuZml4dHVyZS5uYW1lLCBmaXJzdC5maXh0dXJlLnBhdGgsIGZpcnN0LmZpeHR1cmUubWV0YSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRhc2sub24oJ3Rlc3QtcnVuLXN0YXJ0JywgYXN5bmMgdGVzdFJ1biA9PiB7XG4gICAgICAgICAgICBjb25zdCByZXBvcnRJdGVtID0gdGhpcy5fZ2V0UmVwb3J0SXRlbUZvclRlc3RSdW4odGVzdFJ1bik7XG5cbiAgICAgICAgICAgIGlmICghcmVwb3J0SXRlbS5zdGFydFRpbWUpXG4gICAgICAgICAgICAgICAgcmVwb3J0SXRlbS5zdGFydFRpbWUgPSBuZXcgRGF0ZSgpO1xuXG4gICAgICAgICAgICByZXBvcnRJdGVtLnBlbmRpbmdTdGFydHMtLTtcblxuICAgICAgICAgICAgaWYgKCFyZXBvcnRJdGVtLnBlbmRpbmdTdGFydHMpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wbHVnaW4ucmVwb3J0VGVzdFN0YXJ0KVxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnBsdWdpbi5yZXBvcnRUZXN0U3RhcnQocmVwb3J0SXRlbS50ZXN0Lm5hbWUsIHJlcG9ydEl0ZW0udGVzdC5tZXRhKTtcblxuICAgICAgICAgICAgICAgIHJlcG9ydEl0ZW0ucGVuZGluZ1Rlc3RSdW5TdGFydFByb21pc2UucmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVwb3J0SXRlbS5wZW5kaW5nVGVzdFJ1blN0YXJ0UHJvbWlzZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGFzay5vbigndGVzdC1ydW4tZG9uZScsIGFzeW5jIHRlc3RSdW4gPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVwb3J0SXRlbSAgICAgICAgICAgICAgICAgICAgPSB0aGlzLl9nZXRSZXBvcnRJdGVtRm9yVGVzdFJ1bih0ZXN0UnVuKTtcbiAgICAgICAgICAgIGNvbnN0IGlzVGVzdFJ1blN0b3BwZWRUYXNrRXhlY3V0aW9uID0gISF0ZXN0UnVuLmVycnMubGVuZ3RoICYmIHRoaXMuc3RvcE9uRmlyc3RGYWlsO1xuXG4gICAgICAgICAgICByZXBvcnRJdGVtLnBlbmRpbmdSdW5zID0gaXNUZXN0UnVuU3RvcHBlZFRhc2tFeGVjdXRpb24gPyAwIDogcmVwb3J0SXRlbS5wZW5kaW5nUnVucyAtIDE7XG4gICAgICAgICAgICByZXBvcnRJdGVtLnVuc3RhYmxlICAgID0gcmVwb3J0SXRlbS51bnN0YWJsZSB8fCB0ZXN0UnVuLnVuc3RhYmxlO1xuICAgICAgICAgICAgcmVwb3J0SXRlbS5lcnJzICAgICAgICA9IHJlcG9ydEl0ZW0uZXJycy5jb25jYXQodGVzdFJ1bi5lcnJzKTtcbiAgICAgICAgICAgIHJlcG9ydEl0ZW0ud2FybmluZ3MgICAgPSB0ZXN0UnVuLndhcm5pbmdMb2cgPyB1bmlvbihyZXBvcnRJdGVtLndhcm5pbmdzLCB0ZXN0UnVuLndhcm5pbmdMb2cubWVzc2FnZXMpIDogW107XG5cbiAgICAgICAgICAgIGlmICghcmVwb3J0SXRlbS5wZW5kaW5nUnVucylcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLl9yZXNvbHZlUmVwb3J0SXRlbShyZXBvcnRJdGVtLCB0ZXN0UnVuKTtcblxuICAgICAgICAgICAgYXdhaXQgcmVwb3J0SXRlbS5wZW5kaW5nVGVzdFJ1bkRvbmVQcm9taXNlO1xuICAgICAgICB9KTtcblxuICAgICAgICB0YXNrLm9uY2UoJ2RvbmUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbmRUaW1lID0gbmV3IERhdGUoKTtcblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0ge1xuICAgICAgICAgICAgICAgIHBhc3NlZENvdW50OiAgdGhpcy5wYXNzZWQsXG4gICAgICAgICAgICAgICAgZmFpbGVkQ291bnQ6ICB0aGlzLmZhaWxlZCxcbiAgICAgICAgICAgICAgICBza2lwcGVkQ291bnQ6IHRoaXMuc2tpcHBlZFxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgYXdhaXQgdGhpcy5wbHVnaW4ucmVwb3J0VGFza0RvbmUoZW5kVGltZSwgdGhpcy5wYXNzZWQsIHRhc2sud2FybmluZ0xvZy5tZXNzYWdlcywgcmVzdWx0KTtcblxuICAgICAgICAgICAgdGhpcy5wZW5kaW5nVGFza0RvbmVQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgZGlzcG9zZSAoKSB7XG4gICAgICAgIGlmICh0aGlzLmRpc3Bvc2VkKVxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXG4gICAgICAgIHRoaXMuZGlzcG9zZWQgPSB0cnVlO1xuXG4gICAgICAgIGlmICghdGhpcy5vdXRTdHJlYW0gfHwgUmVwb3J0ZXIuX2lzU3BlY2lhbFN0cmVhbSh0aGlzLm91dFN0cmVhbSkgfHwgIWlzV3JpdGFibGVTdHJlYW0odGhpcy5vdXRTdHJlYW0pKVxuICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuXG4gICAgICAgIGNvbnN0IHN0cmVhbUZpbmlzaGVkUHJvbWlzZSA9IG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICAgICAgdGhpcy5vdXRTdHJlYW0ub25jZSgnZmluaXNoJywgcmVzb2x2ZSk7XG4gICAgICAgICAgICB0aGlzLm91dFN0cmVhbS5vbmNlKCdlcnJvcicsIHJlc29sdmUpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLm91dFN0cmVhbS5lbmQoKTtcblxuICAgICAgICByZXR1cm4gc3RyZWFtRmluaXNoZWRQcm9taXNlO1xuICAgIH1cbn1cbiJdfQ==