UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

151 lines 23.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = __importDefault(require("debug")); const path_1 = require("path"); const fs_1 = __importDefault(require("fs")); const child_process_1 = require("child_process"); const make_dir_1 = __importDefault(require("make-dir")); const temp_directory_1 = __importDefault(require("../utils/temp-directory")); const path_pattern_1 = __importDefault(require("../utils/path-pattern")); const warning_message_1 = __importDefault(require("../notifications/warning-message")); const string_1 = require("../utils/string"); const test_run_video_recorder_1 = __importDefault(require("./test-run-video-recorder")); const events_1 = require("events"); const create_safe_listener_1 = __importDefault(require("../utils/create-safe-listener")); const DEBUG_LOGGER = (0, debug_1.default)('testcafe:video-recorder'); const VIDEO_EXTENSION = 'mp4'; const TEMP_DIR_PREFIX = 'video'; class VideoRecorder extends events_1.EventEmitter { constructor(browserJob, basePath, opts, encodingOpts, warningLog) { super(); this.browserJob = browserJob; this.basePath = basePath; this.failedOnly = opts.failedOnly; this.singleFile = opts.singleFile; this.ffmpegPath = opts.ffmpegPath; this.customPathPattern = opts.pathPattern; this.timeStamp = opts.timeStamp; this.encodingOptions = encodingOpts; this.warningLog = warningLog; this.tempDirectory = new temp_directory_1.default(TEMP_DIR_PREFIX); this.firstFile = true; this.testRunVideoRecorders = {}; this._assignEventHandlers(browserJob); } _createSafeListener(listener) { return (0, create_safe_listener_1.default)(this, listener, DEBUG_LOGGER); } _assignEventHandlers(browserJob) { browserJob.once('start', this._createSafeListener(() => { this.tempDirectoryInitializedPromise = this._onBrowserJobStart(); return this.tempDirectoryInitializedPromise; })); browserJob.once('done', this._createSafeListener(this._onBrowserJobDone)); browserJob.on('test-run-create', this._createSafeListener(this._onTestRunCreate)); browserJob.on('test-run-ready', this._createSafeListener(this._onTestRunReady)); browserJob.on('test-run-before-done', this._createSafeListener(this._onTestRunBeforeDone)); browserJob.on('test-run-restart', this._createSafeListener(this._onTestRunRestart)); } _addProblematicPlaceholdersWarning(placeholders) { const problematicPlaceholderListStr = (0, string_1.getConcatenatedValuesString)(placeholders); const suffix = (0, string_1.getPluralSuffix)(placeholders); const verb = (0, string_1.getToBeInPastTense)(placeholders); this.warningLog.addWarning(warning_message_1.default.problematicPathPatternPlaceholderForVideoRecording, suffix, problematicPlaceholderListStr, suffix, verb); } _getTargetVideoPath(testRunRecorder) { const data = Object.assign(testRunRecorder.testRunInfo, { now: this.timeStamp }); if (this.singleFile) { data.testIndex = null; data.fixture = null; data.test = null; } const pathPattern = new path_pattern_1.default(this.customPathPattern, VIDEO_EXTENSION, data); pathPattern.on('problematic-placeholders-found', ({ placeholders }) => this._addProblematicPlaceholdersWarning(placeholders)); return (0, path_1.join)(this.basePath, pathPattern.getPath()); } _concatVideo(targetVideoPath, { tempVideoPath, tempMergeConfigPath, tmpMergeName }) { if (this.firstFile) { this.firstFile = false; return; } fs_1.default.writeFileSync(tempMergeConfigPath, ` file '${targetVideoPath}' file '${tempVideoPath}' `); (0, child_process_1.spawnSync)(this.ffmpegPath, ['-y', '-f', 'concat', '-safe', '0', '-i', tempMergeConfigPath, '-c', 'copy', tmpMergeName], { stdio: 'ignore' }); fs_1.default.copyFileSync(tmpMergeName, tempVideoPath); } async _onBrowserJobStart() { await this.tempDirectory.init(); } async _onBrowserJobDone() { await this.tempDirectory.dispose(); } async _onTestRunCreate(testRunInfo) { if (testRunInfo.legacy) return; await this.tempDirectoryInitializedPromise; const recordingOptions = { path: this.tempDirectory.path, ffmpegPath: this.ffmpegPath, encodingOptions: this.encodingOptions, }; const testRunVideoRecorder = this._createTestRunVideoRecorder(testRunInfo, recordingOptions); const isVideoSupported = await testRunVideoRecorder.isVideoSupported(); if (!isVideoSupported) { this.warningLog.addWarning(warning_message_1.default.videoNotSupportedByBrowser, testRunVideoRecorder.testRunInfo.alias); return; } const isVideoEnabled = await testRunVideoRecorder.isVideoEnabled(); if (!isVideoEnabled) return; await testRunVideoRecorder.init(); this.testRunVideoRecorders[testRunVideoRecorder.index] = testRunVideoRecorder; } _createTestRunVideoRecorder(testRunInfo, recordingOptions) { return new test_run_video_recorder_1.default(testRunInfo, recordingOptions, this.warningLog); } async _onTestRunReady({ index }) { const testRunRecorder = this.testRunVideoRecorders[index]; if (!testRunRecorder) return; await testRunRecorder.startCapturing(); } async _onTestRunRestart({ index }) { const testRunRecorder = this.testRunVideoRecorders[index]; if (!testRunRecorder) return; testRunRecorder.onTestRunRestart(); } async _onTestRunBeforeDone({ index }) { const testRunRecorder = this.testRunVideoRecorders[index]; if (!testRunRecorder) return; delete this.testRunVideoRecorders[index]; await testRunRecorder.finishCapturing(); if (this.failedOnly && !testRunRecorder.hasErrors) return; const videoPath = this._getTargetVideoPath(testRunRecorder); await this._saveFiles(testRunRecorder, videoPath); const testRunVideoSavedEventArgs = { testRun: testRunRecorder.testRun, videoPath, singleFile: !!this.singleFile, }; if (!this.singleFile) testRunVideoSavedEventArgs.timecodes = testRunRecorder.testRunInfo.timecodes; this.emit('test-run-video-saved', testRunVideoSavedEventArgs); } async _saveFiles(testRunRecorder, videoPath) { await (0, make_dir_1.default)((0, path_1.dirname)(videoPath)); if (this.singleFile) this._concatVideo(videoPath, testRunRecorder.tempFiles); fs_1.default.copyFileSync(testRunRecorder.tempFiles.tempVideoPath, videoPath); } } exports.default = VideoRecorder; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdmlkZW8tcmVjb3JkZXIvcmVjb3JkZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxrREFBMEI7QUFDMUIsK0JBQXFDO0FBQ3JDLDRDQUFvQjtBQUNwQixpREFBMEM7QUFDMUMsd0RBQStCO0FBQy9CLDZFQUFvRDtBQUNwRCx5RUFBZ0Q7QUFDaEQsdUZBQWdFO0FBQ2hFLDRDQUl5QjtBQUV6Qix3RkFBNkQ7QUFDN0QsbUNBQXNDO0FBQ3RDLHlGQUErRDtBQUUvRCxNQUFNLFlBQVksR0FBRyxJQUFBLGVBQUssRUFBQyx5QkFBeUIsQ0FBQyxDQUFDO0FBRXRELE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQztBQUM5QixNQUFNLGVBQWUsR0FBRyxPQUFPLENBQUM7QUFFaEMsTUFBcUIsYUFBYyxTQUFRLHFCQUFZO0lBQ25ELFlBQWEsVUFBVSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLFVBQVU7UUFDN0QsS0FBSyxFQUFFLENBQUM7UUFFUixJQUFJLENBQUMsVUFBVSxHQUFVLFVBQVUsQ0FBQztRQUNwQyxJQUFJLENBQUMsUUFBUSxHQUFZLFFBQVEsQ0FBQztRQUNsQyxJQUFJLENBQUMsVUFBVSxHQUFVLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDekMsSUFBSSxDQUFDLFVBQVUsR0FBVSxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxVQUFVLEdBQVUsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUN6QyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQztRQUMxQyxJQUFJLENBQUMsU0FBUyxHQUFXLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDeEMsSUFBSSxDQUFDLGVBQWUsR0FBSyxZQUFZLENBQUM7UUFFdEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFFN0IsSUFBSSxDQUFDLGFBQWEs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QUFTLENBQUMsQ0FBQztJQUN4RSxDQUFDO0NBQ0o7QUFsTEQsZ0NBa0xDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGRlYnVnIGZyb20gJ2RlYnVnJztcbmltcG9ydCB7IGpvaW4sIGRpcm5hbWUgfSBmcm9tICdwYXRoJztcbmltcG9ydCBmcyBmcm9tICdmcyc7XG5pbXBvcnQgeyBzcGF3blN5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCBtYWtlRGlyIGZyb20gJ21ha2UtZGlyJztcbmltcG9ydCBUZW1wRGlyZWN0b3J5IGZyb20gJy4uL3V0aWxzL3RlbXAtZGlyZWN0b3J5JztcbmltcG9ydCBQYXRoUGF0dGVybiBmcm9tICcuLi91dGlscy9wYXRoLXBhdHRlcm4nO1xuaW1wb3J0IFdBUk5JTkdfTUVTU0FHRVMgZnJvbSAnLi4vbm90aWZpY2F0aW9ucy93YXJuaW5nLW1lc3NhZ2UnO1xuaW1wb3J0IHtcbiAgICBnZXRQbHVyYWxTdWZmaXgsXG4gICAgZ2V0Q29uY2F0ZW5hdGVkVmFsdWVzU3RyaW5nLFxuICAgIGdldFRvQmVJblBhc3RUZW5zZSxcbn0gZnJvbSAnLi4vdXRpbHMvc3RyaW5nJztcblxuaW1wb3J0IFRlc3RSdW5WaWRlb1JlY29yZGVyIGZyb20gJy4vdGVzdC1ydW4tdmlkZW8tcmVjb3JkZXInO1xuaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcbmltcG9ydCBjcmVhdGVTYWZlTGlzdGVuZXIgZnJvbSAnLi4vdXRpbHMvY3JlYXRlLXNhZmUtbGlzdGVuZXInO1xuXG5jb25zdCBERUJVR19MT0dHRVIgPSBkZWJ1ZygndGVzdGNhZmU6dmlkZW8tcmVjb3JkZXInKTtcblxuY29uc3QgVklERU9fRVhURU5TSU9OID0gJ21wNCc7XG5jb25zdCBURU1QX0RJUl9QUkVGSVggPSAndmlkZW8nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWaWRlb1JlY29yZGVyIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgICBjb25zdHJ1Y3RvciAoYnJvd3NlckpvYiwgYmFzZVBhdGgsIG9wdHMsIGVuY29kaW5nT3B0cywgd2FybmluZ0xvZykge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXMuYnJvd3NlckpvYiAgICAgICAgPSBicm93c2VySm9iO1xuICAgICAgICB0aGlzLmJhc2VQYXRoICAgICAgICAgID0gYmFzZVBhdGg7XG4gICAgICAgIHRoaXMuZmFpbGVkT25seSAgICAgICAgPSBvcHRzLmZhaWxlZE9ubHk7XG4gICAgICAgIHRoaXMuc2luZ2xlRmlsZSAgICAgICAgPSBvcHRzLnNpbmdsZUZpbGU7XG4gICAgICAgIHRoaXMuZmZtcGVnUGF0aCAgICAgICAgPSBvcHRzLmZmbXBlZ1BhdGg7XG4gICAgICAgIHRoaXMuY3VzdG9tUGF0aFBhdHRlcm4gPSBvcHRzLnBhdGhQYXR0ZXJuO1xuICAgICAgICB0aGlzLnRpbWVTdGFtcCAgICAgICAgID0gb3B0cy50aW1lU3RhbXA7XG4gICAgICAgIHRoaXMuZW5jb2RpbmdPcHRpb25zICAgPSBlbmNvZGluZ09wdHM7XG5cbiAgICAgICAgdGhpcy53YXJuaW5nTG9nID0gd2FybmluZ0xvZztcblxuICAgICAgICB0aGlzLnRlbXBEaXJlY3RvcnkgPSBuZXcgVGVtcERpcmVjdG9yeShURU1QX0RJUl9QUkVGSVgpO1xuXG4gICAgICAgIHRoaXMuZmlyc3RGaWxlID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLnRlc3RSdW5WaWRlb1JlY29yZGVycyA9IHt9O1xuXG4gICAgICAgIHRoaXMuX2Fzc2lnbkV2ZW50SGFuZGxlcnMoYnJvd3NlckpvYik7XG4gICAgfVxuXG4gICAgX2NyZWF0ZVNhZmVMaXN0ZW5lciAobGlzdGVuZXIpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZVNhZmVMaXN0ZW5lcih0aGlzLCBsaXN0ZW5lciwgREVCVUdfTE9HR0VSKTtcbiAgICB9XG5cbiAgICBfYXNzaWduRXZlbnRIYW5kbGVycyAoYnJvd3NlckpvYikge1xuICAgICAgICBicm93c2VySm9iLm9uY2UoJ3N0YXJ0JywgdGhpcy5fY3JlYXRlU2FmZUxpc3RlbmVyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudGVtcERpcmVjdG9yeUluaXRpYWxpemVkUHJvbWlzZSA9IHRoaXMuX29uQnJvd3NlckpvYlN0YXJ0KCk7XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRlbXBEaXJlY3RvcnlJbml0aWFsaXplZFByb21pc2U7XG4gICAgICAgIH0pKTtcblxuICAgICAgICBicm93c2VySm9iLm9uY2UoJ2RvbmUnLCB0aGlzLl9jcmVhdGVTYWZlTGlzdGVuZXIodGhpcy5fb25Ccm93c2VySm9iRG9uZSkpO1xuICAgICAgICBicm93c2VySm9iLm9uKCd0ZXN0LXJ1bi1jcmVhdGUnLCB0aGlzLl9jcmVhdGVTYWZlTGlzdGVuZXIodGhpcy5fb25UZXN0UnVuQ3JlYXRlKSk7XG4gICAgICAgIGJyb3dzZXJKb2Iub24oJ3Rlc3QtcnVuLXJlYWR5JywgdGhpcy5fY3JlYXRlU2FmZUxpc3RlbmVyKHRoaXMuX29uVGVzdFJ1blJlYWR5KSk7XG4gICAgICAgIGJyb3dzZXJKb2Iub24oJ3Rlc3QtcnVuLWJlZm9yZS1kb25lJywgdGhpcy5fY3JlYXRlU2FmZUxpc3RlbmVyKHRoaXMuX29uVGVzdFJ1bkJlZm9yZURvbmUpKTtcbiAgICAgICAgYnJvd3NlckpvYi5vbigndGVzdC1ydW4tcmVzdGFydCcsIHRoaXMuX2NyZWF0ZVNhZmVMaXN0ZW5lcih0aGlzLl9vblRlc3RSdW5SZXN0YXJ0KSk7XG4gICAgfVxuXG4gICAgX2FkZFByb2JsZW1hdGljUGxhY2Vob2xkZXJzV2FybmluZyAocGxhY2Vob2xkZXJzKSB7XG4gICAgICAgIGNvbnN0IHByb2JsZW1hdGljUGxhY2Vob2xkZXJMaXN0U3RyID0gZ2V0Q29uY2F0ZW5hdGVkVmFsdWVzU3RyaW5nKHBsYWNlaG9sZGVycyk7XG4gICAgICAgIGNvbnN0IHN1ZmZpeCAgICAgICAgICAgICAgICAgICAgICAgID0gZ2V0UGx1cmFsU3VmZml4KHBsYWNlaG9sZGVycyk7XG4gICAgICAgIGNvbnN0IHZlcmIgICAgICAgICAgICAgICAgICAgICAgICAgID0gZ2V0VG9CZUluUGFzdFRlbnNlKHBsYWNlaG9sZGVycyk7XG5cbiAgICAgICAgdGhpcy53YXJuaW5nTG9nLmFkZFdhcm5pbmcoV0FSTklOR19NRVNTQUdFUy5wcm9ibGVtYXRpY1BhdGhQYXR0ZXJuUGxhY2Vob2xkZXJGb3JWaWRlb1JlY29yZGluZywgc3VmZml4LCBwcm9ibGVtYXRpY1BsYWNlaG9sZGVyTGlzdFN0ciwgc3VmZml4LCB2ZXJiKTtcbiAgICB9XG5cbiAgICBfZ2V0VGFyZ2V0VmlkZW9QYXRoICh0ZXN0UnVuUmVjb3JkZXIpIHtcbiAgICAgICAgY29uc3QgZGF0YSA9IE9iamVjdC5hc3NpZ24odGVzdFJ1blJlY29yZGVyLnRlc3RSdW5JbmZvLCB7IG5vdzogdGhpcy50aW1lU3RhbXAgfSk7XG5cbiAgICAgICAgaWYgKHRoaXMuc2luZ2xlRmlsZSkge1xuICAgICAgICAgICAgZGF0YS50ZXN0SW5kZXggPSBudWxsO1xuICAgICAgICAgICAgZGF0YS5maXh0dXJlID0gbnVsbDtcbiAgICAgICAgICAgIGRhdGEudGVzdCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYXRoUGF0dGVybiA9IG5ldyBQYXRoUGF0dGVybih0aGlzLmN1c3RvbVBhdGhQYXR0ZXJuLCBWSURFT19FWFRFTlNJT04sIGRhdGEpO1xuXG4gICAgICAgIHBhdGhQYXR0ZXJuLm9uKCdwcm9ibGVtYXRpYy1wbGFjZWhvbGRlcnMtZm91bmQnLCAoeyBwbGFjZWhvbGRlcnMgfSkgPT4gdGhpcy5fYWRkUHJvYmxlbWF0aWNQbGFjZWhvbGRlcnNXYXJuaW5nKHBsYWNlaG9sZGVycykpO1xuXG4gICAgICAgIHJldHVybiBqb2luKHRoaXMuYmFzZVBhdGgsIHBhdGhQYXR0ZXJuLmdldFBhdGgoKSk7XG4gICAgfVxuXG4gICAgX2NvbmNhdFZpZGVvICh0YXJnZXRWaWRlb1BhdGgsIHsgdGVtcFZpZGVvUGF0aCwgdGVtcE1lcmdlQ29uZmlnUGF0aCwgdG1wTWVyZ2VOYW1lIH0pIHtcbiAgICAgICAgaWYgKHRoaXMuZmlyc3RGaWxlKSB7XG4gICAgICAgICAgICB0aGlzLmZpcnN0RmlsZSA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0ZW1wTWVyZ2VDb25maWdQYXRoLCBgXG4gICAgICAgICAgICBmaWxlICcke3RhcmdldFZpZGVvUGF0aH0nXG4gICAgICAgICAgICBmaWxlICcke3RlbXBWaWRlb1BhdGh9J1xuICAgICAgICBgKTtcblxuICAgICAgICBzcGF3blN5bmModGhpcy5mZm1wZWdQYXRoLCBbJy15JywgJy1mJywgJ2NvbmNhdCcsICctc2FmZScsICcwJywgJy1pJywgdGVtcE1lcmdlQ29uZmlnUGF0aCwgJy1jJywgJ2NvcHknLCB0bXBNZXJnZU5hbWVdLCB7IHN0ZGlvOiAnaWdub3JlJyB9KTtcbiAgICAgICAgZnMuY29weUZpbGVTeW5jKHRtcE1lcmdlTmFtZSwgdGVtcFZpZGVvUGF0aCk7XG4gICAgfVxuXG4gICAgYXN5bmMgX29uQnJvd3NlckpvYlN0YXJ0ICgpIHtcbiAgICAgICAgYXdhaXQgdGhpcy50ZW1wRGlyZWN0b3J5LmluaXQoKTtcbiAgICB9XG5cbiAgICBhc3luYyBfb25Ccm93c2VySm9iRG9uZSAoKSB7XG4gICAgICAgIGF3YWl0IHRoaXMudGVtcERpcmVjdG9yeS5kaXNwb3NlKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgX29uVGVzdFJ1bkNyZWF0ZSAodGVzdFJ1bkluZm8pIHtcbiAgICAgICAgaWYgKHRlc3RSdW5JbmZvLmxlZ2FjeSlcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBhd2FpdCB0aGlzLnRlbXBEaXJlY3RvcnlJbml0aWFsaXplZFByb21pc2U7XG5cbiAgICAgICAgY29uc3QgcmVjb3JkaW5nT3B0aW9ucyA9IHtcbiAgICAgICAgICAgIHBhdGg6ICAgICAgICAgICAgdGhpcy50ZW1wRGlyZWN0b3J5LnBhdGgsXG4gICAgICAgICAgICBmZm1wZWdQYXRoOiAgICAgIHRoaXMuZmZtcGVnUGF0aCxcbiAgICAgICAgICAgIGVuY29kaW5nT3B0aW9uczogdGhpcy5lbmNvZGluZ09wdGlvbnMsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgdGVzdFJ1blZpZGVvUmVjb3JkZXIgPSB0aGlzLl9jcmVhdGVUZXN0UnVuVmlkZW9SZWNvcmRlcih0ZXN0UnVuSW5mbywgcmVjb3JkaW5nT3B0aW9ucyk7XG4gICAgICAgIGNvbnN0IGlzVmlkZW9TdXBwb3J0ZWQgICAgID0gYXdhaXQgdGVzdFJ1blZpZGVvUmVjb3JkZXIuaXNWaWRlb1N1cHBvcnRlZCgpO1xuXG4gICAgICAgIGlmICghaXNWaWRlb1N1cHBvcnRlZCkge1xuICAgICAgICAgICAgdGhpcy53YXJuaW5nTG9nLmFkZFdhcm5pbmcoV0FSTklOR19NRVNTQUdFUy52aWRlb05vdFN1cHBvcnRlZEJ5QnJvd3NlciwgdGVzdFJ1blZpZGVvUmVjb3JkZXIudGVzdFJ1bkluZm8uYWxpYXMpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXNWaWRlb0VuYWJsZWQgPSBhd2FpdCB0ZXN0UnVuVmlkZW9SZWNvcmRlci5pc1ZpZGVvRW5hYmxlZCgpO1xuXG4gICAgICAgIGlmICghaXNWaWRlb0VuYWJsZWQpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgYXdhaXQgdGVzdFJ1blZpZGVvUmVjb3JkZXIuaW5pdCgpO1xuXG4gICAgICAgIHRoaXMudGVzdFJ1blZpZGVvUmVjb3JkZXJzW3Rlc3RSdW5WaWRlb1JlY29yZGVyLmluZGV4XSA9IHRlc3RSdW5WaWRlb1JlY29yZGVyO1xuICAgIH1cblxuICAgIF9jcmVhdGVUZXN0UnVuVmlkZW9SZWNvcmRlciAodGVzdFJ1bkluZm8sIHJlY29yZGluZ09wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBUZXN0UnVuVmlkZW9SZWNvcmRlcih0ZXN0UnVuSW5mbywgcmVjb3JkaW5nT3B0aW9ucywgdGhpcy53YXJuaW5nTG9nKTtcbiAgICB9XG5cbiAgICBhc3luYyBfb25UZXN0UnVuUmVhZHkgKHsgaW5kZXggfSkge1xuICAgICAgICBjb25zdCB0ZXN0UnVuUmVjb3JkZXIgPSB0aGlzLnRlc3RSdW5WaWRlb1JlY29yZGVyc1tpbmRleF07XG5cbiAgICAgICAgaWYgKCF0ZXN0UnVuUmVjb3JkZXIpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgYXdhaXQgdGVzdFJ1blJlY29yZGVyLnN0YXJ0Q2FwdHVyaW5nKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgX29uVGVzdFJ1blJlc3RhcnQgKHsgaW5kZXggfSkge1xuICAgICAgICBjb25zdCB0ZXN0UnVuUmVjb3JkZXIgPSB0aGlzLnRlc3RSdW5WaWRlb1JlY29yZGVyc1tpbmRleF07XG5cbiAgICAgICAgaWYgKCF0ZXN0UnVuUmVjb3JkZXIpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGVzdFJ1blJlY29yZGVyLm9uVGVzdFJ1blJlc3RhcnQoKTtcbiAgICB9XG5cbiAgICBhc3luYyBfb25UZXN0UnVuQmVmb3JlRG9uZSAoeyBpbmRleCB9KSB7XG4gICAgICAgIGNvbnN0IHRlc3RSdW5SZWNvcmRlciA9IHRoaXMudGVzdFJ1blZpZGVvUmVjb3JkZXJzW2luZGV4XTtcblxuICAgICAgICBpZiAoIXRlc3RSdW5SZWNvcmRlcilcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBkZWxldGUgdGhpcy50ZXN0UnVuVmlkZW9SZWNvcmRlcnNbaW5kZXhdO1xuXG4gICAgICAgIGF3YWl0IHRlc3RSdW5SZWNvcmRlci5maW5pc2hDYXB0dXJpbmcoKTtcblxuICAgICAgICBpZiAodGhpcy5mYWlsZWRPbmx5ICYmICF0ZXN0UnVuUmVjb3JkZXIuaGFzRXJyb3JzKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHZpZGVvUGF0aCA9IHRoaXMuX2dldFRhcmdldFZpZGVvUGF0aCh0ZXN0UnVuUmVjb3JkZXIpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuX3NhdmVGaWxlcyh0ZXN0UnVuUmVjb3JkZXIsIHZpZGVvUGF0aCk7XG5cbiAgICAgICAgY29uc3QgdGVzdFJ1blZpZGVvU2F2ZWRFdmVudEFyZ3MgPSB7XG4gICAgICAgICAgICB0ZXN0UnVuOiAgICB0ZXN0UnVuUmVjb3JkZXIudGVzdFJ1bixcbiAgICAgICAgICAgIHZpZGVvUGF0aCxcbiAgICAgICAgICAgIHNpbmdsZUZpbGU6ICEhdGhpcy5zaW5nbGVGaWxlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICghdGhpcy5zaW5nbGVGaWxlKVxuICAgICAgICAgICAgdGVzdFJ1blZpZGVvU2F2ZWRFdmVudEFyZ3MudGltZWNvZGVzID0gdGVzdFJ1blJlY29yZGVyLnRlc3RSdW5JbmZvLnRpbWVjb2RlcztcblxuICAgICAgICB0aGlzLmVtaXQoJ3Rlc3QtcnVuLXZpZGVvLXNhdmVkJywgdGVzdFJ1blZpZGVvU2F2ZWRFdmVudEFyZ3MpO1xuICAgIH1cblxuICAgIGFzeW5jIF9zYXZlRmlsZXMgKHRlc3RSdW5SZWNvcmRlciwgdmlkZW9QYXRoKSB7XG4gICAgICAgIGF3YWl0IG1ha2VEaXIoZGlybmFtZSh2aWRlb1BhdGgpKTtcblxuICAgICAgICBpZiAodGhpcy5zaW5nbGVGaWxlKVxuICAgICAgICAgICAgdGhpcy5fY29uY2F0VmlkZW8odmlkZW9QYXRoLCB0ZXN0UnVuUmVjb3JkZXIudGVtcEZpbGVzKTtcblxuICAgICAgICBmcy5jb3B5RmlsZVN5bmModGVzdFJ1blJlY29yZGVyLnRlbXBGaWxlcy50ZW1wVmlkZW9QYXRoLCB2aWRlb1BhdGgpO1xuICAgIH1cbn1cbiJdfQ==