UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

148 lines 19.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = require("path"); const fs_1 = require("fs"); const strip_bom_1 = __importDefault(require("strip-bom")); const base_1 = __importDefault(require("./base")); const test_file_1 = __importDefault(require("../../api/structure/test-file")); const fixture_1 = __importDefault(require("../../api/structure/fixture")); const test_1 = __importDefault(require("../../api/structure/test")); const runtime_1 = require("../../errors/runtime"); const stack_cleaning_hook_1 = __importDefault(require("../../errors/stack-cleaning-hook")); const CWD = process.cwd(); const EXPORTABLE_LIB_PATH = path_1.join(__dirname, '../../api/exportable-lib'); const FIXTURE_RE = /(^|;|\s+)fixture\s*(\.|\(|`)/; const TEST_RE = /(^|;|\s+)test\s*(\.|\()/; const Module = module.constructor; class APIBasedTestFileCompilerBase extends base_1.default { constructor() { super(); this.cache = Object.create(null); this.origRequireExtensions = Object.create(null); } static get EXPORTABLE_LIB_PATH() { return EXPORTABLE_LIB_PATH; } static _getNodeModulesLookupPath(filename) { const dir = path_1.dirname(filename); return Module._nodeModulePaths(dir); } static _isNodeModulesDep(filename) { return path_1.relative(CWD, filename) .split(path_1.sep) .indexOf('node_modules') >= 0; } static _execAsModule(code, filename) { const mod = new Module(filename, module.parent); mod.filename = filename; mod.paths = APIBasedTestFileCompilerBase._getNodeModulesLookupPath(filename); mod._compile(code, filename); } _compileCode(code, filename) { if (this.canPrecompile) return this._precompileCode([{ code, filename }])[0]; throw new Error('Not implemented'); } _precompileCode( /* testFilesInfo */) { throw new Error('Not implemented'); } _getRequireCompilers() { throw new Error('Not implemented'); } _setupRequireHook(testFile) { const requireCompilers = this._getRequireCompilers(); this.origRequireExtensions = Object.create(null); Object.keys(requireCompilers).forEach(ext => { const origExt = require.extensions[ext]; this.origRequireExtensions[ext] = origExt; require.extensions[ext] = (mod, filename) => { // NOTE: remove global API so that it will be unavailable for the dependencies this._removeGlobalAPI(); if (APIBasedTestFileCompilerBase._isNodeModulesDep(filename) && origExt) origExt(mod, filename); else { const code = fs_1.readFileSync(filename).toString(); const compiledCode = requireCompilers[ext](strip_bom_1.default(code), filename); mod.paths = APIBasedTestFileCompilerBase._getNodeModulesLookupPath(filename); mod._compile(compiledCode, filename); } this._addGlobalAPI(testFile); }; }); } _removeRequireHook() { Object.keys(this.origRequireExtensions).forEach(ext => { require.extensions[ext] = this.origRequireExtensions[ext]; }); } _compileCodeForTestFiles(testFilesInfo) { stack_cleaning_hook_1.default.enabled = true; try { if (this.canPrecompile) return this._precompileCode(testFilesInfo); return testFilesInfo.map(({ code, filename }) => this._compileCode(code, filename)); } catch (err) { throw new runtime_1.TestCompilationError(stack_cleaning_hook_1.default.cleanError(err)); } finally { stack_cleaning_hook_1.default.enabled = false; } } _addGlobalAPI(testFile) { Object.defineProperty(global, 'fixture', { get: () => new fixture_1.default(testFile), configurable: true }); Object.defineProperty(global, 'test', { get: () => new test_1.default(testFile), configurable: true }); } _removeGlobalAPI() { delete global.fixture; delete global.test; } _runCompiledCode(compiledCode, filename) { const testFile = new test_file_1.default(filename); this._addGlobalAPI(testFile); stack_cleaning_hook_1.default.enabled = true; this._setupRequireHook(testFile); try { APIBasedTestFileCompilerBase._execAsModule(compiledCode, filename); } catch (err) { if (!(err instanceof runtime_1.APIError)) throw new runtime_1.TestCompilationError(stack_cleaning_hook_1.default.cleanError(err)); throw err; } finally { this._removeRequireHook(); stack_cleaning_hook_1.default.enabled = false; this._removeGlobalAPI(); } return testFile.getTests(); } precompile(testFilesInfo) { return this._compileCodeForTestFiles(testFilesInfo); } execute(compiledCode, filename) { return this._runCompiledCode(compiledCode, filename); } compile(code, filename) { const [compiledCode] = this.precompile([{ code, filename }]); return this.execute(compiledCode, filename); } _hasTests(code) { return FIXTURE_RE.test(code) && TEST_RE.test(code); } cleanUp() { this.cache = {}; } } exports.default = APIBasedTestFileCompilerBase; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLWJhc2VkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBpbGVyL3Rlc3QtZmlsZS9hcGktYmFzZWQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSwrQkFBK0Q7QUFDL0QsMkJBQWtDO0FBQ2xDLDBEQUFpQztBQUNqQyxrREFBMEM7QUFDMUMsOEVBQXFEO0FBQ3JELDBFQUFrRDtBQUNsRCxvRUFBNEM7QUFDNUMsa0RBQXNFO0FBQ3RFLDJGQUFpRTtBQUVqRSxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7QUFFMUIsTUFBTSxtQkFBbUIsR0FBRyxXQUFJLENBQUMsU0FBUyxFQUFFLDBCQUEwQixDQUFDLENBQUM7QUFFeEUsTUFBTSxVQUFVLEdBQUcsOEJBQThCLENBQUM7QUFDbEQsTUFBTSxPQUFPLEdBQU0seUJBQXlCLENBQUM7QUFFN0MsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFdBQVcsQ0FBQztBQUVsQyxNQUFxQiw0QkFBNkIsU0FBUSxjQUFvQjtJQUMxRTtRQUNJLEtBQUssRUFBRSxDQUFDO1FBRVIsSUFBSSxDQUFDLEtBQUssR0FBbUIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMscUJBQXFCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQsTUFBTSxLQUFLLG1CQUFtQjtRQUMxQixPQUFPLG1CQUFtQixDQUFDO0lBQy9CLENBQUM7SUFFRCxNQUFNLENBQUMseUJBQXlCLENBQUUsUUFBUTtRQUN0QyxNQUFNLEdBQUcsR0FBRyxjQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFOUIsT0FBTyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVELE1BQU0sQ0FBQyxpQkFBaUIsQ0FBRSxRQUFRO1FBQzlCLE9BQU8sZUFBUSxD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QztJQUVELFNBQVMsQ0FBRSxJQUFJO1FBQ1gsT0FBTyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVELE9BQU87UUFDSCxJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztJQUNwQixDQUFDO0NBQ0o7QUF6S0QsK0NBeUtDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZGlybmFtZSwgcmVsYXRpdmUsIGpvaW4sIHNlcCBhcyBwYXRoU2VwIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tICdmcyc7XG5pbXBvcnQgc3RyaXBCb20gZnJvbSAnc3RyaXAtYm9tJztcbmltcG9ydCBUZXN0RmlsZUNvbXBpbGVyQmFzZSBmcm9tICcuL2Jhc2UnO1xuaW1wb3J0IFRlc3RGaWxlIGZyb20gJy4uLy4uL2FwaS9zdHJ1Y3R1cmUvdGVzdC1maWxlJztcbmltcG9ydCBGaXh0dXJlIGZyb20gJy4uLy4uL2FwaS9zdHJ1Y3R1cmUvZml4dHVyZSc7XG5pbXBvcnQgVGVzdCBmcm9tICcuLi8uLi9hcGkvc3RydWN0dXJlL3Rlc3QnO1xuaW1wb3J0IHsgVGVzdENvbXBpbGF0aW9uRXJyb3IsIEFQSUVycm9yIH0gZnJvbSAnLi4vLi4vZXJyb3JzL3J1bnRpbWUnO1xuaW1wb3J0IHN0YWNrQ2xlYW5pbmdIb29rIGZyb20gJy4uLy4uL2Vycm9ycy9zdGFjay1jbGVhbmluZy1ob29rJztcblxuY29uc3QgQ1dEID0gcHJvY2Vzcy5jd2QoKTtcblxuY29uc3QgRVhQT1JUQUJMRV9MSUJfUEFUSCA9IGpvaW4oX19kaXJuYW1lLCAnLi4vLi4vYXBpL2V4cG9ydGFibGUtbGliJyk7XG5cbmNvbnN0IEZJWFRVUkVfUkUgPSAvKF58O3xcXHMrKWZpeHR1cmVcXHMqKFxcLnxcXCh8YCkvO1xuY29uc3QgVEVTVF9SRSAgICA9IC8oXnw7fFxccyspdGVzdFxccyooXFwufFxcKCkvO1xuXG5jb25zdCBNb2R1bGUgPSBtb2R1bGUuY29uc3RydWN0b3I7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFQSUJhc2VkVGVzdEZpbGVDb21waWxlckJhc2UgZXh0ZW5kcyBUZXN0RmlsZUNvbXBpbGVyQmFzZSB7XG4gICAgY29uc3RydWN0b3IgKCkge1xuICAgICAgICBzdXBlcigpO1xuXG4gICAgICAgIHRoaXMuY2FjaGUgICAgICAgICAgICAgICAgID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgdGhpcy5vcmlnUmVxdWlyZUV4dGVuc2lvbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIH1cblxuICAgIHN0YXRpYyBnZXQgRVhQT1JUQUJMRV9MSUJfUEFUSCAoKSB7XG4gICAgICAgIHJldHVybiBFWFBPUlRBQkxFX0xJQl9QQVRIO1xuICAgIH1cblxuICAgIHN0YXRpYyBfZ2V0Tm9kZU1vZHVsZXNMb29rdXBQYXRoIChmaWxlbmFtZSkge1xuICAgICAgICBjb25zdCBkaXIgPSBkaXJuYW1lKGZpbGVuYW1lKTtcblxuICAgICAgICByZXR1cm4gTW9kdWxlLl9ub2RlTW9kdWxlUGF0aHMoZGlyKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgX2lzTm9kZU1vZHVsZXNEZXAgKGZpbGVuYW1lKSB7XG4gICAgICAgIHJldHVybiByZWxhdGl2ZShDV0QsIGZpbGVuYW1lKVxuICAgICAgICAgICAgLnNwbGl0KHBhdGhTZXApXG4gICAgICAgICAgICAuaW5kZXhPZignbm9kZV9tb2R1bGVzJykgPj0gMDtcbiAgICB9XG5cbiAgICBzdGF0aWMgX2V4ZWNBc01vZHVsZSAoY29kZSwgZmlsZW5hbWUpIHtcbiAgICAgICAgY29uc3QgbW9kID0gbmV3IE1vZHVsZShmaWxlbmFtZSwgbW9kdWxlLnBhcmVudCk7XG5cbiAgICAgICAgbW9kLmZpbGVuYW1lID0gZmlsZW5hbWU7XG4gICAgICAgIG1vZC5wYXRocyAgICA9IEFQSUJhc2VkVGVzdEZpbGVDb21waWxlckJhc2UuX2dldE5vZGVNb2R1bGVzTG9va3VwUGF0aChmaWxlbmFtZSk7XG5cbiAgICAgICAgbW9kLl9jb21waWxlKGNvZGUsIGZpbGVuYW1lKTtcbiAgICB9XG5cbiAgICBfY29tcGlsZUNvZGUgKGNvZGUsIGZpbGVuYW1lKSB7XG4gICAgICAgIGlmICh0aGlzLmNhblByZWNvbXBpbGUpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fcHJlY29tcGlsZUNvZGUoW3sgY29kZSwgZmlsZW5hbWUgfV0pWzBdO1xuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgX3ByZWNvbXBpbGVDb2RlICgvKiB0ZXN0RmlsZXNJbmZvICovKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XG4gICAgfVxuXG4gICAgX2dldFJlcXVpcmVDb21waWxlcnMgKCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vdCBpbXBsZW1lbnRlZCcpO1xuICAgIH1cblxuICAgIF9zZXR1cFJlcXVpcmVIb29rICh0ZXN0RmlsZSkge1xuICAgICAgICBjb25zdCByZXF1aXJlQ29tcGlsZXJzID0gdGhpcy5fZ2V0UmVxdWlyZUNvbXBpbGVycygpO1xuXG4gICAgICAgIHRoaXMub3JpZ1JlcXVpcmVFeHRlbnNpb25zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAgICAgICBPYmplY3Qua2V5cyhyZXF1aXJlQ29tcGlsZXJzKS5mb3JFYWNoKGV4dCA9PiB7XG4gICAgICAgICAgICBjb25zdCBvcmlnRXh0ID0gcmVxdWlyZS5leHRlbnNpb25zW2V4dF07XG5cbiAgICAgICAgICAgIHRoaXMub3JpZ1JlcXVpcmVFeHRlbnNpb25zW2V4dF0gPSBvcmlnRXh0O1xuXG4gICAgICAgICAgICByZXF1aXJlLmV4dGVuc2lvbnNbZXh0XSA9IChtb2QsIGZpbGVuYW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gTk9URTogcmVtb3ZlIGdsb2JhbCBBUEkgc28gdGhhdCBpdCB3aWxsIGJlIHVuYXZhaWxhYmxlIGZvciB0aGUgZGVwZW5kZW5jaWVzXG4gICAgICAgICAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsQVBJKCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoQVBJQmFzZWRUZXN0RmlsZUNvbXBpbGVyQmFzZS5faXNOb2RlTW9kdWxlc0RlcChmaWxlbmFtZSkgJiYgb3JpZ0V4dClcbiAgICAgICAgICAgICAgICAgICAgb3JpZ0V4dChtb2QsIGZpbGVuYW1lKTtcblxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb2RlICAgICAgICAgPSByZWFkRmlsZVN5bmMoZmlsZW5hbWUpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbXBpbGVkQ29kZSA9IHJlcXVpcmVDb21waWxlcnNbZXh0XShzdHJpcEJvbShjb2RlKSwgZmlsZW5hbWUpO1xuXG4gICAgICAgICAgICAgICAgICAgIG1vZC5wYXRocyA9IEFQSUJhc2VkVGVzdEZpbGVDb21waWxlckJhc2UuX2dldE5vZGVNb2R1bGVzTG9va3VwUGF0aChmaWxlbmFtZSk7XG5cbiAgICAgICAgICAgICAgICAgICAgbW9kLl9jb21waWxlKGNvbXBpbGVkQ29kZSwgZmlsZW5hbWUpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuX2FkZEdsb2JhbEFQSSh0ZXN0RmlsZSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfcmVtb3ZlUmVxdWlyZUhvb2sgKCkge1xuICAgICAgICBPYmplY3Qua2V5cyh0aGlzLm9yaWdSZXF1aXJlRXh0ZW5zaW9ucykuZm9yRWFjaChleHQgPT4ge1xuICAgICAgICAgICAgcmVxdWlyZS5leHRlbnNpb25zW2V4dF0gPSB0aGlzLm9yaWdSZXF1aXJlRXh0ZW5zaW9uc1tleHRdO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfY29tcGlsZUNvZGVGb3JUZXN0RmlsZXMgKHRlc3RGaWxlc0luZm8pIHtcbiAgICAgICAgc3RhY2tDbGVhbmluZ0hvb2suZW5hYmxlZCA9IHRydWU7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNhblByZWNvbXBpbGUpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3ByZWNvbXBpbGVDb2RlKHRlc3RGaWxlc0luZm8pO1xuXG4gICAgICAgICAgICByZXR1cm4gdGVzdEZpbGVzSW5mby5tYXAoKHsgY29kZSwgZmlsZW5hbWUgfSkgPT4gdGhpcy5fY29tcGlsZUNvZGUoY29kZSwgZmlsZW5hbWUpKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVGVzdENvbXBpbGF0aW9uRXJyb3Ioc3RhY2tDbGVhbmluZ0hvb2suY2xlYW5FcnJvcihlcnIpKTtcbiAgICAgICAgfVxuICAgICAgICBmaW5hbGx5IHtcbiAgICAgICAgICAgIHN0YWNrQ2xlYW5pbmdIb29rLmVuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9hZGRHbG9iYWxBUEkgKHRlc3RGaWxlKSB7XG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWwsICdmaXh0dXJlJywge1xuICAgICAgICAgICAgZ2V0OiAgICAgICAgICAoKSA9PiBuZXcgRml4dHVyZSh0ZXN0RmlsZSksXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgfSk7XG5cbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGdsb2JhbCwgJ3Rlc3QnLCB7XG4gICAgICAgICAgICBnZXQ6ICAgICAgICAgICgpID0+IG5ldyBUZXN0KHRlc3RGaWxlKSxcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfcmVtb3ZlR2xvYmFsQVBJICgpIHtcbiAgICAgICAgZGVsZXRlIGdsb2JhbC5maXh0dXJlO1xuICAgICAgICBkZWxldGUgZ2xvYmFsLnRlc3Q7XG4gICAgfVxuXG4gICAgX3J1bkNvbXBpbGVkQ29kZSAoY29tcGlsZWRDb2RlLCBmaWxlbmFtZSkge1xuICAgICAgICBjb25zdCB0ZXN0RmlsZSA9IG5ldyBUZXN0RmlsZShmaWxlbmFtZSk7XG5cbiAgICAgICAgdGhpcy5fYWRkR2xvYmFsQVBJKHRlc3RGaWxlKTtcblxuICAgICAgICBzdGFja0NsZWFuaW5nSG9vay5lbmFibGVkID0gdHJ1ZTtcblxuICAgICAgICB0aGlzLl9zZXR1cFJlcXVpcmVIb29rKHRlc3RGaWxlKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgQVBJQmFzZWRUZXN0RmlsZUNvbXBpbGVyQmFzZS5fZXhlY0FzTW9kdWxlKGNvbXBpbGVkQ29kZSwgZmlsZW5hbWUpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGlmICghKGVyciBpbnN0YW5jZW9mIEFQSUVycm9yKSlcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVGVzdENvbXBpbGF0aW9uRXJyb3Ioc3RhY2tDbGVhbmluZ0hvb2suY2xlYW5FcnJvcihlcnIpKTtcblxuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgICAgIGZpbmFsbHkge1xuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlUmVxdWlyZUhvb2soKTtcbiAgICAgICAgICAgIHN0YWNrQ2xlYW5pbmdIb29rLmVuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgICAgdGhpcy5fcmVtb3ZlR2xvYmFsQVBJKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGVzdEZpbGUuZ2V0VGVzdHMoKTtcbiAgICB9XG5cblxuICAgIHByZWNvbXBpbGUgKHRlc3RGaWxlc0luZm8pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2NvbXBpbGVDb2RlRm9yVGVzdEZpbGVzKHRlc3RGaWxlc0luZm8pO1xuICAgIH1cblxuICAgIGV4ZWN1dGUgKGNvbXBpbGVkQ29kZSwgZmlsZW5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3J1bkNvbXBpbGVkQ29kZShjb21waWxlZENvZGUsIGZpbGVuYW1lKTtcbiAgICB9XG5cbiAgICBjb21waWxlIChjb2RlLCBmaWxlbmFtZSkge1xuICAgICAgICBjb25zdCBbY29tcGlsZWRDb2RlXSA9IHRoaXMucHJlY29tcGlsZShbeyBjb2RlLCBmaWxlbmFtZSB9XSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZShjb21waWxlZENvZGUsIGZpbGVuYW1lKTtcbiAgICB9XG5cbiAgICBfaGFzVGVzdHMgKGNvZGUpIHtcbiAgICAgICAgcmV0dXJuIEZJWFRVUkVfUkUudGVzdChjb2RlKSAmJiBURVNUX1JFLnRlc3QoY29kZSk7XG4gICAgfVxuXG4gICAgY2xlYW5VcCAoKSB7XG4gICAgICAgIHRoaXMuY2FjaGUgPSB7fTtcbiAgICB9XG59XG4iXX0=