testcafe
Version:
Automated browser testing for the modern web development stack.
134 lines • 19 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const chalk_1 = __importDefault(require("chalk"));
const runtime_1 = require("../errors/runtime");
const types_1 = require("../errors/types");
const argument_parser_1 = __importDefault(require("./argument-parser"));
const termination_handler_1 = __importDefault(require("./termination-handler"));
const log_1 = __importDefault(require("./log"));
const remotes_wizard_1 = __importDefault(require("./remotes-wizard"));
const correct_browsers_and_sources_1 = __importDefault(require("./correct-browsers-and-sources"));
const __1 = __importDefault(require("../"));
const marketing = __importStar(require("../marketing"));
// NOTE: Load the provider pool lazily to reduce startup time
const lazyRequire = require('import-lazy')(require);
const browserProviderPool = lazyRequire('../browser/provider/pool');
const NOT_PARSABLE_REPORTERS = ['spec', 'list', 'minimal'];
let showMessageOnExit = true;
let exitMessageShown = false;
let exiting = false;
function exitHandler(terminationLevel) {
if (showMessageOnExit && !exitMessageShown) {
exitMessageShown = true;
log_1.default.write('Stopping TestCafe...');
process.on('exit', () => log_1.default.hideSpinner(true));
}
if (exiting || terminationLevel < 2)
return;
exiting = true;
exit(0);
}
function exit(code) {
log_1.default.hideSpinner(true);
// NOTE: give a process time to flush the output.
// It's necessary in some environments.
setTimeout(() => process.exit(code), 0);
}
function error(err) {
log_1.default.hideSpinner();
let message = null;
if (err instanceof runtime_1.GeneralError)
message = err.message;
else if (err instanceof runtime_1.APIError)
message = err.coloredStack;
else
message = err.stack;
log_1.default.write(chalk_1.default.red('ERROR ') + message + '\n');
log_1.default.write(chalk_1.default.gray('Type "testcafe -h" for help.'));
exit(1);
}
function shouldShowMarketingMessage(reporterPlugings) {
const stdoutReporterPlugin = reporterPlugings.find(plugin => plugin.outStream === process.stdout || !plugin.outStream);
return stdoutReporterPlugin && NOT_PARSABLE_REPORTERS.includes(stdoutReporterPlugin.plugin.name);
}
async function runTests(argParser) {
const opts = argParser.opts;
const port1 = opts.ports && opts.ports[0];
const port2 = opts.ports && opts.ports[1];
const proxy = opts.proxy;
const proxyBypass = opts.proxyBypass;
log_1.default.showSpinner();
const testCafe = await __1.default(opts.hostname, port1, port2, opts.ssl, opts.dev);
const correctedBrowsersAndSources = await correct_browsers_and_sources_1.default(argParser, testCafe.configuration);
const automatedBrowsers = correctedBrowsersAndSources.browsers;
const remoteBrowsers = await remotes_wizard_1.default(testCafe, argParser.remoteCount, opts.qrCode);
const browsers = automatedBrowsers.concat(remoteBrowsers);
const sources = correctedBrowsersAndSources.sources;
const runner = opts.live ? testCafe.createLiveModeRunner() : testCafe.createRunner();
let failed = 0;
runner.isCli = true;
runner
.useProxy(proxy, proxyBypass)
.src(sources)
.browsers(browsers)
.reporter(argParser.opts.reporter)
.concurrency(argParser.opts.concurrency)
.filter(argParser.filter)
.video(opts.video, opts.videoOptions, opts.videoEncodingOptions)
.screenshots(opts.screenshots, opts.screenshotsOnFails, opts.screenshotPathPattern)
.startApp(opts.app, opts.appInitDelay);
runner.once('done-bootstrapping', () => log_1.default.hideSpinner());
try {
failed = await runner.run(opts);
if (shouldShowMarketingMessage(runner.reporterPlugings))
await marketing.showMessageWithLinkToTestCafeStudio();
}
finally {
showMessageOnExit = false;
await testCafe.close();
}
exit(failed);
}
async function listBrowsers(providerName = 'locally-installed') {
const provider = await browserProviderPool.getProvider(providerName);
if (!provider)
throw new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.browserProviderNotFound, providerName);
if (provider.isMultiBrowser) {
const browserNames = await provider.getBrowserList();
await browserProviderPool.dispose();
if (providerName === 'locally-installed')
console.log(browserNames.join('\n'));
else
console.log(browserNames.map(browserName => `"${providerName}:${browserName}"`).join('\n'));
}
else
console.log(`"${providerName}"`);
exit(0);
}
(async function cli() {
const terminationHandler = new termination_handler_1.default();
terminationHandler.on(termination_handler_1.default.TERMINATION_LEVEL_INCREASED_EVENT, exitHandler);
try {
const argParser = new argument_parser_1.default();
await argParser.parse(process.argv);
if (argParser.opts.listBrowsers)
await listBrowsers(argParser.opts.providerName);
else
await runTests(argParser);
}
catch (err) {
showMessageOnExit = false;
error(err);
}
})();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS9jbGkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBQUEsa0RBQTBCO0FBQzFCLCtDQUEyRDtBQUMzRCwyQ0FBaUQ7QUFDakQsd0VBQWtEO0FBQ2xELGdGQUF1RDtBQUN2RCxnREFBd0I7QUFDeEIsc0VBQTZDO0FBQzdDLGtHQUF1RTtBQUN2RSw0Q0FBaUM7QUFDakMsd0RBQTBDO0FBRTFDLDZEQUE2RDtBQUM3RCxNQUFNLFdBQVcsR0FBVyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7QUFDNUQsTUFBTSxtQkFBbUIsR0FBRyxXQUFXLENBQUMsMEJBQTBCLENBQUMsQ0FBQztBQUVwRSxNQUFNLHNCQUFzQixHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQztBQUUzRCxJQUFJLGlCQUFpQixHQUFHLElBQUksQ0FBQztBQUM3QixJQUFJLGdCQUFnQixHQUFJLEtBQUssQ0FBQztBQUM5QixJQUFJLE9BQU8sR0FBYSxLQUFLLENBQUM7QUFFOUIsU0FBUyxXQUFXLENBQUUsZ0JBQWdCO0lBQ2xDLElBQUksaUJBQWlCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtRQUN4QyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFFeEIsYUFBRyxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBRWxDLE9BQU8sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLGFBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztLQUNuRDtJQUVELElBQUksT0FBTyxJQUFJLGdCQUFnQixHQUFHLENBQUM7UUFDL0IsT0FBTztJQUVYLE9BQU8sR0FBRyxJQUFJLENBQUM7SUFFZixJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDWixDQUFDO0FBRUQsU0FBUyxJQUFJLENBQUUsSUFBSTtJQUNmLGFBQUcsQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7SUFFdEIsaURBQWlEO0lBQ2pELHVDQUF1QztJQUN2QyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM1QyxDQUFDO0FBRUQsU0FBUyxLQUFLLENBQUUsR0FBRztJQUNmLGFBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUVsQixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUM7SUFFbkIsSUFBSSxHQUFHLFlBQVksc0JBQVk7UUFDM0IsT0FBTyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUM7U0FFckIsSUFBSSxHQUFHLFlBQVksa0JBQVE7UUFDNUIsT0FBTyxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUM7O1FBRzNCLE9BQU8sR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDO0lBRXhCLGFBQUcsQ0FBQyxLQUFLLENBQUMsZUFBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxPQUFPLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFDaEQsYUFBRyxDQUFDLEtBQUssQ0FBQyxlQUFLLENBQUMsSUFBSSxDQUFDLDhCQUE4QixDQUFDLENBQUMsQ0FBQztJQUV0RCxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDWixDQUFDO0FBRUQsU0FBUywwQkFBMEIsQ0FBRSxnQkFBZ0I7SUFDakQsTUFBTSxvQkFBb0IsR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxLQUFLLE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFdkgsT0FBTyxvQkFBb0IsSUFBSSxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ3JHLENBQUM7QUFFRCxLQUFLLFVBQVUsUUFBUSxDQUFFLFNBQVM7SUFDOUIsTUFBTSxJQUFJLEdBQWdCLFNBQVMsQ0FBQyxJQUFJLENBQUM7SUFDekMsTUFBTSxLQUFLLEdBQWUsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sS0FBSyxHQUFlLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RCxNQUFNLEtBQUssR0FBZSxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3JDLE1BQU0sV0FBVyxHQUFTLElBQUksQ0FBQyxXQUFXLENBQUM7SUFFM0MsYUFBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO0lBRWxCLE1BQU0sUUFBUSxHQUFHLE1BQU0sV0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUV2RixNQUFNLDJCQUEyQixHQUFHLE1BQU0sc0NBQXlCLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUN2RyxNQUFNLGlCQUFpQixHQUFhLDJCQUEyQixDQUFDLFFBQVEsQ0FBQztJQUN6RSxNQUFNLGNBQWMsR0FBZ0IsTUFBTSx3QkFBYSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN0RyxNQUFNLFFBQVEsR0FBc0IsaUJBQWlCLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzdFLE1BQU0sT0FBTyxHQUF1QiwyQkFBMkIsQ0FBQyxPQUFPLENBQUM7SUFFeEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUVyRixJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFFZixNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQztJQUVwQixNQUFNO1NBQ0QsUUFBUSxDQUFDLEtBQUssRUFBRSxXQUFXLENBQUM7U0FDNUIsR0FBRyxDQUFDLE9BQU8sQ0FBQztTQUNaLFFBQVEsQ0FBQyxRQUFRLENBQUM7U0FDbEIsUUFBUSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1NBQ2pDLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQztTQUN2QyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztTQUN4QixLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztTQUMvRCxXQUFXLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDO1NBQ2xGLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUUzQyxNQUFNLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxDQUFDLGFBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBRTNELElBQUk7UUFDQSxNQUFNLEdBQUcsTUFBTSxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWhDLElBQUksMEJBQTBCLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDO1lBQ25ELE1BQU0sU0FBUyxDQUFDLG1DQUFtQyxFQUFFLENBQUM7S0FDN0Q7WUFFTztRQUNKLGlCQUFpQixHQUFHLEtBQUssQ0FBQztRQUMxQixNQUFNLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztLQUMxQjtJQUVELElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUNqQixDQUFDO0FBRUQsS0FBSyxVQUFVLFlBQVksQ0FBRSxZQUFZLEdBQUcsbUJBQW1CO0lBQzNELE1BQU0sUUFBUSxHQUFHLE1BQU0sbUJBQW1CLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXJFLElBQUksQ0FBQyxRQUFRO1FBQ1QsTUFBTSxJQUFJLHNCQUFZLENBQUMsc0JBQWMsQ0FBQyx1QkFBdUIsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUVqRixJQUFJLFFBQVEsQ0FBQyxjQUFjLEVBQUU7UUFDekIsTUFBTSxZQUFZLEdBQUcsTUFBTSxRQUFRLENBQUMsY0FBYyxFQUFFLENBQUM7UUFFckQsTUFBTSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUVwQyxJQUFJLFlBQVksS0FBSyxtQkFBbUI7WUFDcEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7O1lBRXJDLE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLElBQUksWUFBWSxJQUFJLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7S0FDbkc7O1FBRUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7SUFFckMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ1osQ0FBQztBQUVELENBQUMsS0FBSyxVQUFVLEdBQUc7SUFDZixNQUFNLGtCQUFrQixHQUFHLElBQUksNkJBQWtCLEVBQUUsQ0FBQztJQUVwRCxrQkFBa0IsQ0FBQyxFQUFFLENBQUMsNkJBQWtCLENBQUMsaUNBQWlDLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFFekYsSUFBSTtRQUNBLE1BQU0sU0FBUyxHQUFHLElBQUkseUJBQWlCLEVBQUUsQ0FBQztRQUUxQyxNQUFNLFNBQVMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXBDLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZO1lBQzNCLE1BQU0sWUFBWSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7O1lBRWhELE1BQU0sUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0tBQ2pDO0lBQ0QsT0FBTyxHQUFHLEVBQUU7UUFDUixpQkFBaUIsR0FBRyxLQUFLLENBQUM7UUFDMUIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0tBQ2Q7QUFDTCxDQUFDLENBQUMsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNoYWxrIGZyb20gJ2NoYWxrJztcbmltcG9ydCB7IEdlbmVyYWxFcnJvciwgQVBJRXJyb3IgfSBmcm9tICcuLi9lcnJvcnMvcnVudGltZSc7XG5pbXBvcnQgeyBSVU5USU1FX0VSUk9SUyB9IGZyb20gJy4uL2Vycm9ycy90eXBlcyc7XG5pbXBvcnQgQ2xpQXJndW1lbnRQYXJzZXIgZnJvbSAnLi9hcmd1bWVudC1wYXJzZXInO1xuaW1wb3J0IFRlcm1pbmF0aW9uSGFuZGxlciBmcm9tICcuL3Rlcm1pbmF0aW9uLWhhbmRsZXInO1xuaW1wb3J0IGxvZyBmcm9tICcuL2xvZyc7XG5pbXBvcnQgcmVtb3Rlc1dpemFyZCBmcm9tICcuL3JlbW90ZXMtd2l6YXJkJztcbmltcG9ydCBjb3JyZWN0QnJvd3NlcnNBbmRTb3VyY2VzIGZyb20gJy4vY29ycmVjdC1icm93c2Vycy1hbmQtc291cmNlcyc7XG5pbXBvcnQgY3JlYXRlVGVzdENhZmUgZnJvbSAnLi4vJztcbmltcG9ydCAqIGFzIG1hcmtldGluZyBmcm9tICcuLi9tYXJrZXRpbmcnO1xuXG4vLyBOT1RFOiBMb2FkIHRoZSBwcm92aWRlciBwb29sIGxhemlseSB0byByZWR1Y2Ugc3RhcnR1cCB0aW1lXG5jb25zdCBsYXp5UmVxdWlyZSAgICAgICAgID0gcmVxdWlyZSgnaW1wb3J0LWxhenknKShyZXF1aXJlKTtcbmNvbnN0IGJyb3dzZXJQcm92aWRlclBvb2wgPSBsYXp5UmVxdWlyZSgnLi4vYnJvd3Nlci9wcm92aWRlci9wb29sJyk7XG5cbmNvbnN0IE5PVF9QQVJTQUJMRV9SRVBPUlRFUlMgPSBbJ3NwZWMnLCAnbGlzdCcsICdtaW5pbWFsJ107XG5cbmxldCBzaG93TWVzc2FnZU9uRXhpdCA9IHRydWU7XG5sZXQgZXhpdE1lc3NhZ2VTaG93biAgPSBmYWxzZTtcbmxldCBleGl0aW5nICAgICAgICAgICA9IGZhbHNlO1xuXG5mdW5jdGlvbiBleGl0SGFuZGxlciAodGVybWluYXRpb25MZXZlbCkge1xuICAgIGlmIChzaG93TWVzc2FnZU9uRXhpdCAmJiAhZXhpdE1lc3NhZ2VTaG93bikge1xuICAgICAgICBleGl0TWVzc2FnZVNob3duID0gdHJ1ZTtcblxuICAgICAgICBsb2cud3JpdGUoJ1N0b3BwaW5nIFRlc3RDYWZlLi4uJyk7XG5cbiAgICAgICAgcHJvY2Vzcy5vbignZXhpdCcsICgpID0+IGxvZy5oaWRlU3Bpbm5lcih0cnVlKSk7XG4gICAgfVxuXG4gICAgaWYgKGV4aXRpbmcgfHwgdGVybWluYXRpb25MZXZlbCA8IDIpXG4gICAgICAgIHJldHVybjtcblxuICAgIGV4aXRpbmcgPSB0cnVlO1xuXG4gICAgZXhpdCgwKTtcbn1cblxuZnVuY3Rpb24gZXhpdCAoY29kZSkge1xuICAgIGxvZy5oaWRlU3Bpbm5lcih0cnVlKTtcblxuICAgIC8vIE5PVEU6IGdpdmUgYSBwcm9jZXNzIHRpbWUgdG8gZmx1c2ggdGhlIG91dHB1dC5cbiAgICAvLyBJdCdzIG5lY2Vzc2FyeSBpbiBzb21lIGVudmlyb25tZW50cy5cbiAgICBzZXRUaW1lb3V0KCgpID0+IHByb2Nlc3MuZXhpdChjb2RlKSwgMCk7XG59XG5cbmZ1bmN0aW9uIGVycm9yIChlcnIpIHtcbiAgICBsb2cuaGlkZVNwaW5uZXIoKTtcblxuICAgIGxldCBtZXNzYWdlID0gbnVsbDtcblxuICAgIGlmIChlcnIgaW5zdGFuY2VvZiBHZW5lcmFsRXJyb3IpXG4gICAgICAgIG1lc3NhZ2UgPSBlcnIubWVzc2FnZTtcblxuICAgIGVsc2UgaWYgKGVyciBpbnN0YW5jZW9mIEFQSUVycm9yKVxuICAgICAgICBtZXNzYWdlID0gZXJyLmNvbG9yZWRTdGFjaztcblxuICAgIGVsc2VcbiAgICAgICAgbWVzc2FnZSA9IGVyci5zdGFjaztcblxuICAgIGxvZy53cml0ZShjaGFsay5yZWQoJ0VSUk9SICcpICsgbWVzc2FnZSArICdcXG4nKTtcbiAgICBsb2cud3JpdGUoY2hhbGsuZ3JheSgnVHlwZSBcInRlc3RjYWZlIC1oXCIgZm9yIGhlbHAuJykpO1xuXG4gICAgZXhpdCgxKTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkU2hvd01hcmtldGluZ01lc3NhZ2UgKHJlcG9ydGVyUGx1Z2luZ3MpIHtcbiAgICBjb25zdCBzdGRvdXRSZXBvcnRlclBsdWdpbiA9IHJlcG9ydGVyUGx1Z2luZ3MuZmluZChwbHVnaW4gPT4gcGx1Z2luLm91dFN0cmVhbSA9PT0gcHJvY2Vzcy5zdGRvdXQgfHwgIXBsdWdpbi5vdXRTdHJlYW0pO1xuXG4gICAgcmV0dXJuIHN0ZG91dFJlcG9ydGVyUGx1Z2luICYmIE5PVF9QQVJTQUJMRV9SRVBPUlRFUlMuaW5jbHVkZXMoc3Rkb3V0UmVwb3J0ZXJQbHVnaW4ucGx1Z2luLm5hbWUpO1xufVxuXG5hc3luYyBmdW5jdGlvbiBydW5UZXN0cyAoYXJnUGFyc2VyKSB7XG4gICAgY29uc3Qgb3B0cyAgICAgICAgICAgICAgPSBhcmdQYXJzZXIub3B0cztcbiAgICBjb25zdCBwb3J0MSAgICAgICAgICAgICA9IG9wdHMucG9ydHMgJiYgb3B0cy5wb3J0c1swXTtcbiAgICBjb25zdCBwb3J0MiAgICAgICAgICAgICA9IG9wdHMucG9ydHMgJiYgb3B0cy5wb3J0c1sxXTtcbiAgICBjb25zdCBwcm94eSAgICAgICAgICAgICA9IG9wdHMucHJveHk7XG4gICAgY29uc3QgcHJveHlCeXBhc3MgICAgICAgPSBvcHRzLnByb3h5QnlwYXNzO1xuXG4gICAgbG9nLnNob3dTcGlubmVyKCk7XG5cbiAgICBjb25zdCB0ZXN0Q2FmZSA9IGF3YWl0IGNyZWF0ZVRlc3RDYWZlKG9wdHMuaG9zdG5hbWUsIHBvcnQxLCBwb3J0Miwgb3B0cy5zc2wsIG9wdHMuZGV2KTtcblxuICAgIGNvbnN0IGNvcnJlY3RlZEJyb3dzZXJzQW5kU291cmNlcyA9IGF3YWl0IGNvcnJlY3RCcm93c2Vyc0FuZFNvdXJjZXMoYXJnUGFyc2VyLCB0ZXN0Q2FmZS5jb25maWd1cmF0aW9uKTtcbiAgICBjb25zdCBhdXRvbWF0ZWRCcm93c2VycyAgICAgICAgICAgPSBjb3JyZWN0ZWRCcm93c2Vyc0FuZFNvdXJjZXMuYnJvd3NlcnM7XG4gICAgY29uc3QgcmVtb3RlQnJvd3NlcnMgICAgICAgICAgICAgID0gYXdhaXQgcmVtb3Rlc1dpemFyZCh0ZXN0Q2FmZSwgYXJnUGFyc2VyLnJlbW90ZUNvdW50LCBvcHRzLnFyQ29kZSk7XG4gICAgY29uc3QgYnJvd3NlcnMgICAgICAgICAgICAgICAgICAgID0gYXV0b21hdGVkQnJvd3NlcnMuY29uY2F0KHJlbW90ZUJyb3dzZXJzKTtcbiAgICBjb25zdCBzb3VyY2VzICAgICAgICAgICAgICAgICAgICAgPSBjb3JyZWN0ZWRCcm93c2Vyc0FuZFNvdXJjZXMuc291cmNlcztcblxuICAgIGNvbnN0IHJ1bm5lciA9IG9wdHMubGl2ZSA/IHRlc3RDYWZlLmNyZWF0ZUxpdmVNb2RlUnVubmVyKCkgOiB0ZXN0Q2FmZS5jcmVhdGVSdW5uZXIoKTtcblxuICAgIGxldCBmYWlsZWQgPSAwO1xuXG4gICAgcnVubmVyLmlzQ2xpID0gdHJ1ZTtcblxuICAgIHJ1bm5lclxuICAgICAgICAudXNlUHJveHkocHJveHksIHByb3h5QnlwYXNzKVxuICAgICAgICAuc3JjKHNvdXJjZXMpXG4gICAgICAgIC5icm93c2Vycyhicm93c2VycylcbiAgICAgICAgLnJlcG9ydGVyKGFyZ1BhcnNlci5vcHRzLnJlcG9ydGVyKVxuICAgICAgICAuY29uY3VycmVuY3koYXJnUGFyc2VyLm9wdHMuY29uY3VycmVuY3kpXG4gICAgICAgIC5maWx0ZXIoYXJnUGFyc2VyLmZpbHRlcilcbiAgICAgICAgLnZpZGVvKG9wdHMudmlkZW8sIG9wdHMudmlkZW9PcHRpb25zLCBvcHRzLnZpZGVvRW5jb2RpbmdPcHRpb25zKVxuICAgICAgICAuc2NyZWVuc2hvdHMob3B0cy5zY3JlZW5zaG90cywgb3B0cy5zY3JlZW5zaG90c09uRmFpbHMsIG9wdHMuc2NyZWVuc2hvdFBhdGhQYXR0ZXJuKVxuICAgICAgICAuc3RhcnRBcHAob3B0cy5hcHAsIG9wdHMuYXBwSW5pdERlbGF5KTtcblxuICAgIHJ1bm5lci5vbmNlKCdkb25lLWJvb3RzdHJhcHBpbmcnLCAoKSA9PiBsb2cuaGlkZVNwaW5uZXIoKSk7XG5cbiAgICB0cnkge1xuICAgICAgICBmYWlsZWQgPSBhd2FpdCBydW5uZXIucnVuKG9wdHMpO1xuXG4gICAgICAgIGlmIChzaG91bGRTaG93TWFya2V0aW5nTWVzc2FnZShydW5uZXIucmVwb3J0ZXJQbHVnaW5ncykpXG4gICAgICAgICAgICBhd2FpdCBtYXJrZXRpbmcuc2hvd01lc3NhZ2VXaXRoTGlua1RvVGVzdENhZmVTdHVkaW8oKTtcbiAgICB9XG5cbiAgICBmaW5hbGx5IHtcbiAgICAgICAgc2hvd01lc3NhZ2VPbkV4aXQgPSBmYWxzZTtcbiAgICAgICAgYXdhaXQgdGVzdENhZmUuY2xvc2UoKTtcbiAgICB9XG5cbiAgICBleGl0KGZhaWxlZCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGxpc3RCcm93c2VycyAocHJvdmlkZXJOYW1lID0gJ2xvY2FsbHktaW5zdGFsbGVkJykge1xuICAgIGNvbnN0IHByb3ZpZGVyID0gYXdhaXQgYnJvd3NlclByb3ZpZGVyUG9vbC5nZXRQcm92aWRlcihwcm92aWRlck5hbWUpO1xuXG4gICAgaWYgKCFwcm92aWRlcilcbiAgICAgICAgdGhyb3cgbmV3IEdlbmVyYWxFcnJvcihSVU5USU1FX0VSUk9SUy5icm93c2VyUHJvdmlkZXJOb3RGb3VuZCwgcHJvdmlkZXJOYW1lKTtcblxuICAgIGlmIChwcm92aWRlci5pc011bHRpQnJvd3Nlcikge1xuICAgICAgICBjb25zdCBicm93c2VyTmFtZXMgPSBhd2FpdCBwcm92aWRlci5nZXRCcm93c2VyTGlzdCgpO1xuXG4gICAgICAgIGF3YWl0IGJyb3dzZXJQcm92aWRlclBvb2wuZGlzcG9zZSgpO1xuXG4gICAgICAgIGlmIChwcm92aWRlck5hbWUgPT09ICdsb2NhbGx5LWluc3RhbGxlZCcpXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhicm93c2VyTmFtZXMuam9pbignXFxuJykpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhicm93c2VyTmFtZXMubWFwKGJyb3dzZXJOYW1lID0+IGBcIiR7cHJvdmlkZXJOYW1lfToke2Jyb3dzZXJOYW1lfVwiYCkuam9pbignXFxuJykpO1xuICAgIH1cbiAgICBlbHNlXG4gICAgICAgIGNvbnNvbGUubG9nKGBcIiR7cHJvdmlkZXJOYW1lfVwiYCk7XG5cbiAgICBleGl0KDApO1xufVxuXG4oYXN5bmMgZnVuY3Rpb24gY2xpICgpIHtcbiAgICBjb25zdCB0ZXJtaW5hdGlvbkhhbmRsZXIgPSBuZXcgVGVybWluYXRpb25IYW5kbGVyKCk7XG5cbiAgICB0ZXJtaW5hdGlvbkhhbmRsZXIub24oVGVybWluYXRpb25IYW5kbGVyLlRFUk1JTkFUSU9OX0xFVkVMX0lOQ1JFQVNFRF9FVkVOVCwgZXhpdEhhbmRsZXIpO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgY29uc3QgYXJnUGFyc2VyID0gbmV3IENsaUFyZ3VtZW50UGFyc2VyKCk7XG5cbiAgICAgICAgYXdhaXQgYXJnUGFyc2VyLnBhcnNlKHByb2Nlc3MuYXJndik7XG5cbiAgICAgICAgaWYgKGFyZ1BhcnNlci5vcHRzLmxpc3RCcm93c2VycylcbiAgICAgICAgICAgIGF3YWl0IGxpc3RCcm93c2VycyhhcmdQYXJzZXIub3B0cy5wcm92aWRlck5hbWUpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBhd2FpdCBydW5UZXN0cyhhcmdQYXJzZXIpO1xuICAgIH1cbiAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgIHNob3dNZXNzYWdlT25FeGl0ID0gZmFsc2U7XG4gICAgICAgIGVycm9yKGVycik7XG4gICAgfVxufSkoKTtcblxuIl19