testcafe
Version:
Automated browser testing for the modern web development stack.
449 lines • 71.8 kB
JavaScript
"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 time_limit_promise_1 = __importDefault(require("time-limit-promise"));
const events_1 = require("events");
const mustache_1 = __importDefault(require("mustache"));
const lodash_1 = require("lodash");
const parse_user_agent_1 = require("../../utils/parse-user-agent");
const read_file_relative_1 = require("read-file-relative");
const promisify_event_1 = __importDefault(require("promisify-event"));
const nanoid_1 = require("nanoid");
const command_1 = __importDefault(require("./command"));
const status_1 = __importDefault(require("./status"));
const heartbeat_status_1 = __importDefault(require("./heartbeat-status"));
const runtime_1 = require("../../errors/runtime");
const types_1 = require("../../errors/types");
const warning_log_1 = __importDefault(require("../../notifications/warning-log"));
const service_routes_1 = __importDefault(require("./service-routes"));
const browser_connection_timeouts_1 = require("../../utils/browser-connection-timeouts");
const tracker_1 = __importDefault(require("./tracker"));
const getBrowserConnectionDebugScope = (id) => `testcafe:browser:connection:${id}`;
const IDLE_PAGE_TEMPLATE = (0, read_file_relative_1.readSync)('../../client/browser/idle-page/index.html.mustache');
const DEFAULT_BROWSER_CONNECTION_OPTIONS = {
disableMultipleWindows: false,
developmentMode: false,
nativeAutomation: false,
};
class BrowserConnection extends events_1.EventEmitter {
constructor(gateway, browserInfo, permanent, options = {}, messageBus) {
super();
this._currentTestRun = null;
this.url = '';
this.idleUrl = '';
this.forcedIdleUrl = '';
this.initScriptUrl = '';
this.heartbeatUrl = '';
this.statusUrl = '';
this.activeWindowIdUrl = '';
this.ensureWindowInNativeAutomationUrl = '';
this.closeWindowUrl = '';
this.statusDoneUrl = '';
this.heartbeatRelativeUrl = '';
this.statusRelativeUrl = '';
this.statusDoneRelativeUrl = '';
this.idleRelativeUrl = '';
this.openFileProtocolRelativeUrl = '';
this.openFileProtocolUrl = '';
this.dispatchNativeAutomationEventRelativeUrl = '';
this.dispatchNativeAutomationEventSequenceRelativeUrl = '';
this.parseSelectorRelativeUrl = '';
this.HEARTBEAT_TIMEOUT = browser_connection_timeouts_1.HEARTBEAT_TIMEOUT;
this.BROWSER_CLOSE_TIMEOUT = browser_connection_timeouts_1.BROWSER_CLOSE_TIMEOUT;
this.BROWSER_RESTART_TIMEOUT = browser_connection_timeouts_1.BROWSER_RESTART_TIMEOUT;
this.id = BrowserConnection._generateId();
this.jobQueue = [];
this.initScriptsQueue = [];
this.browserConnectionGateway = gateway;
this.disconnectionPromise = null;
this.testRunAborted = false;
this.warningLog = new warning_log_1.default(null, warning_log_1.default.createAddWarningCallback(messageBus));
this.debugLogger = (0, debug_1.default)(getBrowserConnectionDebugScope(this.id));
if (messageBus) {
this.messageBus = messageBus;
this.initMessageBus();
}
this.browserInfo = browserInfo;
this.browserInfo.userAgentProviderMetaInfo = '';
this.provider = browserInfo.provider;
this.permanent = permanent;
this.status = status_1.default.uninitialized;
this.idle = true;
this.heartbeatTimeout = null;
this.pendingTestRunInfo = null;
this._options = this._calculateResultOptions(options);
this._setEventHandlers();
tracker_1.default.add(this);
this.previousActiveWindowId = null;
this.browserConnectionGateway.startServingConnection(this);
}
_calculateResultOptions(options) {
return Object.assign({}, DEFAULT_BROWSER_CONNECTION_OPTIONS, options);
}
_buildCommunicationUrls(proxy) {
this.url = proxy.resolveRelativeServiceUrl(`${service_routes_1.default.connect}/${this.id}`);
this.forcedIdleUrl = proxy.resolveRelativeServiceUrl(`${service_routes_1.default.idleForced}/${this.id}`);
this.initScriptUrl = proxy.resolveRelativeServiceUrl(`${service_routes_1.default.initScript}/${this.id}`);
this.heartbeatRelativeUrl = `${service_routes_1.default.heartbeat}/${this.id}`;
this.statusRelativeUrl = `${service_routes_1.default.status}/${this.id}`;
this.statusDoneRelativeUrl = `${service_routes_1.default.statusDone}/${this.id}`;
this.idleRelativeUrl = `${service_routes_1.default.idle}/${this.id}`;
this.activeWindowIdUrl = `${service_routes_1.default.activeWindowId}/${this.id}`;
this.ensureWindowInNativeAutomationUrl = `${service_routes_1.default.ensureWindowInNativeAutomation}/${this.id}`;
this.closeWindowUrl = `${service_routes_1.default.closeWindow}/${this.id}`;
this.openFileProtocolRelativeUrl = `${service_routes_1.default.openFileProtocol}/${this.id}`;
this.dispatchNativeAutomationEventRelativeUrl = `${service_routes_1.default.dispatchNativeAutomationEvent}/${this.id}`;
this.dispatchNativeAutomationEventSequenceRelativeUrl = `${service_routes_1.default.dispatchNativeAutomationEventSequence}/${this.id}`;
this.parseSelectorRelativeUrl = `${service_routes_1.default.parseSelector}/${this.id}`;
this.idleUrl = proxy.resolveRelativeServiceUrl(this.idleRelativeUrl);
this.heartbeatUrl = proxy.resolveRelativeServiceUrl(this.heartbeatRelativeUrl);
this.statusUrl = proxy.resolveRelativeServiceUrl(this.statusRelativeUrl);
this.statusDoneUrl = proxy.resolveRelativeServiceUrl(this.statusDoneRelativeUrl);
this.openFileProtocolUrl = proxy.resolveRelativeServiceUrl(this.openFileProtocolRelativeUrl);
}
initMessageBus() {
this.warningLog.callback = warning_log_1.default.createAddWarningCallback(this._messageBus);
this.assignTestRunStartEventListener();
this.emit('message-bus-initialized', this._messageBus);
}
assignTestRunStartEventListener() {
if (!this._messageBus)
return;
this._messageBus.on('test-run-start', testRun => {
if (testRun.browserConnection.id === this.id)
this._currentTestRun = testRun;
});
}
set messageBus(messageBus) {
this._messageBus = messageBus;
}
get messageBus() {
return this._messageBus;
}
_setEventHandlers() {
this.on('error', e => {
this.debugLogger(e);
this._forceIdle();
this.close();
});
for (const name in status_1.default) {
const status = status_1.default[name];
this.on(status, () => {
this.debugLogger(`status changed to '${status}'`);
});
}
}
static _generateId() {
return (0, nanoid_1.nanoid)(7);
}
_getAdditionalBrowserOptions() {
return {
disableMultipleWindows: this._options.disableMultipleWindows,
nativeAutomation: this._options.nativeAutomation,
developmentMode: this._options.developmentMode,
serviceDomains: [
this.browserConnectionGateway.proxy.server1Info.domain,
this.browserConnectionGateway.proxy.server2Info.domain,
],
};
}
async _runBrowser() {
try {
const additionalOptions = this._getAdditionalBrowserOptions();
await this.provider.openBrowser(this.id, this.url, this.browserInfo.browserOption, additionalOptions);
if (this.status !== status_1.default.ready)
await (0, promisify_event_1.default)(this, 'ready');
this.status = status_1.default.opened;
this.emit('opened');
}
catch (err) {
this.emit('error', new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.unableToOpenBrowser, this.browserInfo.providerName + ':' + this.browserInfo.browserName, err.stack));
}
}
async _closeBrowser(data = {}) {
if (!this.idle)
await (0, promisify_event_1.default)(this, 'idle');
try {
await this.provider.closeBrowser(this.id, data);
}
catch (err) {
// NOTE: A warning would be really nice here, but it can't be done while log is stored in a task.
this.debugLogger(err);
}
}
_forceIdle() {
if (!this.idle) {
this.idle = true;
this.emit('idle');
}
}
_createBrowserDisconnectedError() {
return new runtime_1.GeneralError(types_1.RUNTIME_ERRORS.browserDisconnected, this.userAgent);
}
_waitForHeartbeat() {
if (this._options.developmentMode)
return;
this.heartbeatTimeout = setTimeout(() => {
const err = this._createBrowserDisconnectedError();
this.status = status_1.default.disconnected;
this.testRunAborted = true;
this.emit('disconnected', err);
this._restartBrowserOnDisconnect(err);
}, this.HEARTBEAT_TIMEOUT);
}
async _getTestRunInfo(needPopNext) {
if (needPopNext || !this.pendingTestRunInfo)
this.pendingTestRunInfo = await this._popNextTestRunInfo();
return this.pendingTestRunInfo;
}
async _popNextTestRunInfo() {
while (this.hasQueuedJobs && !this.currentJob.hasQueuedTestRuns)
this.jobQueue.shift();
return this.hasQueuedJobs ? await this.currentJob.popNextTestRunInfo(this) : null;
}
getCurrentTestRun() {
return this._currentTestRun;
}
static getById(id) {
return tracker_1.default.activeBrowserConnections[id] || null;
}
async _restartBrowser() {
this.status = status_1.default.uninitialized;
this._forceIdle();
let resolveTimeout = null;
let isTimeoutExpired = false;
let timeout = null;
const restartPromise = (0, time_limit_promise_1.default)(this._closeBrowser({ isRestarting: true }), this.BROWSER_CLOSE_TIMEOUT, { rejectWith: new runtime_1.TimeoutError() })
.catch(err => this.debugLogger(err))
.then(() => this._runBrowser());
const timeoutPromise = new Promise(resolve => {
resolveTimeout = resolve;
timeout = setTimeout(() => {
isTimeoutExpired = true;
resolve();
}, this.BROWSER_RESTART_TIMEOUT);
});
return Promise.race([restartPromise, timeoutPromise])
.then(() => {
clearTimeout(timeout);
if (isTimeoutExpired)
this.emit('error', this._createBrowserDisconnectedError());
else
resolveTimeout();
});
}
_restartBrowserOnDisconnect(err) {
let resolveFn = null;
let rejectFn = null;
this.disconnectionPromise = new Promise((resolve, reject) => {
resolveFn = resolve;
rejectFn = () => {
reject(err);
};
setTimeout(() => {
rejectFn();
});
})
.then(() => {
return this._restartBrowser();
})
.catch(e => {
this.emit('error', e);
});
this.disconnectionPromise.resolve = resolveFn;
this.disconnectionPromise.reject = rejectFn;
}
async getDefaultBrowserInitTimeout() {
const isLocalBrowser = await this.provider.isLocalBrowser(this.id, this.browserInfo.browserName);
return isLocalBrowser ? browser_connection_timeouts_1.LOCAL_BROWSER_INIT_TIMEOUT : browser_connection_timeouts_1.REMOTE_BROWSER_INIT_TIMEOUT;
}
async processDisconnection(disconnectionThresholdExceeded) {
const { resolve, reject } = this.disconnectionPromise;
if (disconnectionThresholdExceeded)
reject();
else
resolve();
}
addWarning(message, ...args) {
if (this.currentJob)
this.currentJob.warningLog.addWarning(message, ...args);
else
this.warningLog.addWarning(message, ...args);
}
_appendToPrettyUserAgent(str) {
this.browserInfo.parsedUserAgent.prettyUserAgent += ` (${str})`;
}
_moveWarningLogToJob(job) {
job.warningLog.copyFrom(this.warningLog);
this.warningLog.clear();
}
setProviderMetaInfo(str, options) {
const appendToUserAgent = options === null || options === void 0 ? void 0 : options.appendToUserAgent;
if (appendToUserAgent) {
// NOTE:
// change prettyUserAgent only when connection already was established
if (this.isReady())
this._appendToPrettyUserAgent(str);
else
this.on('ready', () => this._appendToPrettyUserAgent(str));
return;
}
this.browserInfo.userAgentProviderMetaInfo = str;
}
get userAgent() {
let userAgent = this.browserInfo.parsedUserAgent.prettyUserAgent;
if (this.browserInfo.userAgentProviderMetaInfo)
userAgent += ` (${this.browserInfo.userAgentProviderMetaInfo})`;
return userAgent;
}
get retryTestPages() {
return this.browserConnectionGateway.retryTestPages;
}
get hasQueuedJobs() {
return !!this.jobQueue.length;
}
get currentJob() {
return this.jobQueue[0];
}
// API
runInitScript(code) {
return new Promise(resolve => this.initScriptsQueue.push({ code, resolve }));
}
addJob(job) {
this.jobQueue.push(job);
this._moveWarningLogToJob(job);
}
removeJob(job) {
(0, lodash_1.pull)(this.jobQueue, job);
}
async close() {
if (this.status === status_1.default.closing || this.status === status_1.default.closed)
return;
this.status = status_1.default.closing;
this.emit(status_1.default.closing);
await this._closeBrowser();
this.browserConnectionGateway.stopServingConnection(this);
if (this.heartbeatTimeout)
clearTimeout(this.heartbeatTimeout);
tracker_1.default.remove(this);
this.status = status_1.default.closed;
this.emit(status_1.default.closed);
}
async establish(userAgent) {
const osInfo = await this.provider.getOSInfo(this.id);
this.status = status_1.default.ready;
this.browserInfo.parsedUserAgent = (0, parse_user_agent_1.parseUserAgent)(userAgent, osInfo);
this._waitForHeartbeat();
this.emit('ready');
}
heartbeat() {
if (this.heartbeatTimeout)
clearTimeout(this.heartbeatTimeout);
this._waitForHeartbeat();
return {
code: this.status === status_1.default.closing ? heartbeat_status_1.default.closing : heartbeat_status_1.default.ok,
url: this.status === status_1.default.closing ? this.idleUrl : '',
};
}
renderIdlePage() {
return mustache_1.default.render(IDLE_PAGE_TEMPLATE, {
userAgent: this.userAgent,
statusUrl: this.statusUrl,
heartbeatUrl: this.heartbeatUrl,
initScriptUrl: this.initScriptUrl,
openFileProtocolUrl: this.openFileProtocolUrl,
retryTestPages: !!this.browserConnectionGateway.retryTestPages,
nativeAutomation: this._options.nativeAutomation,
});
}
getInitScript() {
const initScriptPromise = this.initScriptsQueue[0];
return { code: initScriptPromise ? initScriptPromise.code : null };
}
handleInitScriptResult(data) {
const initScriptPromise = this.initScriptsQueue.shift();
if (initScriptPromise)
initScriptPromise.resolve(JSON.parse(data));
}
isHeadlessBrowser() {
return this.provider.isHeadlessBrowser(this.id);
}
async reportJobResult(status, data) {
await this.provider.reportJobResult(this.id, status, data);
}
async getStatus(isTestDone) {
if (!this.idle && !isTestDone) {
this.idle = true;
this.emit('idle');
}
if (this.status === status_1.default.opened) {
const nextTestRunInfo = await this._getTestRunInfo(isTestDone || this.testRunAborted);
this.testRunAborted = false;
if (nextTestRunInfo) {
this.idle = false;
return {
cmd: command_1.default.run,
testRunId: nextTestRunInfo.testRunId,
url: nextTestRunInfo.url,
};
}
}
return {
cmd: command_1.default.idle,
url: this.idleUrl,
testRunId: null,
};
}
get activeWindowId() {
return this.provider.getActiveWindowId(this.id);
}
set activeWindowId(val) {
this.previousActiveWindowId = this.activeWindowId;
this.provider.setActiveWindowId(this.id, val);
}
async openFileProtocol(url) {
return this.provider.openFileProtocol(this.id, url);
}
async dispatchNativeAutomationEvent(type, options) {
return this.provider.dispatchNativeAutomationEvent(this.id, type, options);
}
async dispatchNativeAutomationEventSequence(eventSequence) {
return this.provider.dispatchNativeAutomationEventSequence(this.id, eventSequence);
}
async canUseDefaultWindowActions() {
return this.provider.canUseDefaultWindowActions(this.id);
}
isReady() {
return this.status === status_1.default.ready ||
this.status === status_1.default.opened ||
this.status === status_1.default.closing;
}
initialize() {
this._buildCommunicationUrls(this.browserConnectionGateway.proxy);
process.nextTick(() => this._runBrowser());
}
supportNativeAutomation() {
return this.provider.supportNativeAutomation();
}
getNativeAutomation() {
return this.provider.getNativeAutomation(this.id);
}
isNativeAutomationEnabled() {
return this._options.nativeAutomation;
}
async getNewWindowIdInNativeAutomation(windowId) {
return this.provider.getNewWindowIdInNativeAutomation(this.id, windowId);
}
async getCurrentCDPSession() {
return this.provider.getCurrentCDPSession(this.id);
}
resetActiveWindowId() {
this.provider.resetActiveWindowId(this.id);
}
}
exports.default = BrowserConnection;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYnJvd3Nlci9jb25uZWN0aW9uL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsa0RBQTBCO0FBQzFCLDRFQUEyQztBQUMzQyxtQ0FBc0M7QUFDdEMsd0RBQWdDO0FBQ2hDLG1DQUF3QztBQUN4QyxtRUFHc0M7QUFDdEMsMkRBQXNEO0FBQ3RELHNFQUE2QztBQUM3QyxtQ0FBZ0M7QUFDaEMsd0RBQWdDO0FBQ2hDLHNEQUErQztBQUMvQywwRUFBaUQ7QUFDakQsa0RBQWtFO0FBQ2xFLDhDQUFvRDtBQUdwRCxrRkFBeUQ7QUFFekQsc0VBQThDO0FBQzlDLHlGQU1pRDtBQUVqRCx3REFBaUQ7QUFVakQsTUFBTSw4QkFBOEIsR0FBRyxDQUFDLEVBQVUsRUFBVSxFQUFFLENBQUMsK0JBQStCLEVBQUUsRUFBRSxDQUFDO0FBRW5HLE1BQU0sa0JBQWtCLEdBQUcsSUFBQSw2QkFBSSxFQUFDLG9EQUFvRCxDQUFDLENBQUM7QUFtRHRGLE1BQU0sa0NBQWtDLEdBQUc7SUFDdkMsc0JBQXNCLEVBQUUsS0FBSztJQUM3QixlQUFlLEVBQVMsS0FBSztJQUM3QixnQkFBZ0IsRUFBUSxLQUFLO0NBQ2hDLENBQUM7QUFFRixNQUFxQixpQkFBa0IsU0FBUSxxQkFBWTtJQTZDdkQsWUFDSSxPQUFpQyxFQUNqQyxXQUF3QixFQUN4QixTQUFrQixFQUNsQixVQUE2QyxFQUFFLEVBQy9DLFVBQXVCO1FBQ3ZCLEtBQUssRUFBRSxDQUFDO1FBNUNKLG9CQUFlLEdBQW1CLElBQUksQ0FBQztRQVN4QyxRQUFHLEdBQUcsRUFBRSxDQUFDO1FBQ1QsWUFBTyxHQUFHLEVBQUUsQ0FBQztRQUNaLGtCQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ25CLGtCQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ3BCLGlCQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLGNBQVMsR0FBRyxFQUFFLENBQUM7UUFD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Q0FBQztJQUVELEtBQUssQ0FBQyxnQ0FBZ0MsQ0FBRSxRQUFnQjtRQUNwRCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsZ0NBQWdDLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUM3RSxDQUFDO0lBRU0sS0FBSyxDQUFDLG9CQUFvQjtRQUM3QixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3ZELENBQUM7SUFFTSxtQkFBbUI7UUFDdEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDL0MsQ0FBQztDQUNKO0FBM2pCRCxvQ0EyakJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGRlYnVnIGZyb20gJ2RlYnVnJztcbmltcG9ydCB0aW1lTGltaXQgZnJvbSAndGltZS1saW1pdC1wcm9taXNlJztcbmltcG9ydCB7IEV2ZW50RW1pdHRlciB9IGZyb20gJ2V2ZW50cyc7XG5pbXBvcnQgTXVzdGFjaGUgZnJvbSAnbXVzdGFjaGUnO1xuaW1wb3J0IHsgcHVsbCBhcyByZW1vdmUgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHtcbiAgICBQYXJzZWRVc2VyQWdlbnQsXG4gICAgcGFyc2VVc2VyQWdlbnQsXG59IGZyb20gJy4uLy4uL3V0aWxzL3BhcnNlLXVzZXItYWdlbnQnO1xuaW1wb3J0IHsgcmVhZFN5bmMgYXMgcmVhZCB9IGZyb20gJ3JlYWQtZmlsZS1yZWxhdGl2ZSc7XG5pbXBvcnQgcHJvbWlzaWZ5RXZlbnQgZnJvbSAncHJvbWlzaWZ5LWV2ZW50JztcbmltcG9ydCB7IG5hbm9pZCB9IGZyb20gJ25hbm9pZCc7XG5pbXBvcnQgQ09NTUFORCBmcm9tICcuL2NvbW1hbmQnO1xuaW1wb3J0IEJyb3dzZXJDb25uZWN0aW9uU3RhdHVzIGZyb20gJy4vc3RhdHVzJztcbmltcG9ydCBIZWFydGJlYXRTdGF0dXMgZnJvbSAnLi9oZWFydGJlYXQtc3RhdHVzJztcbmltcG9ydCB7IEdlbmVyYWxFcnJvciwgVGltZW91dEVycm9yIH0gZnJvbSAnLi4vLi4vZXJyb3JzL3J1bnRpbWUnO1xuaW1wb3J0IHsgUlVOVElNRV9FUlJPUlMgfSBmcm9tICcuLi8uLi9lcnJvcnMvdHlwZXMnO1xuaW1wb3J0IEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheSBmcm9tICcuL2dhdGV3YXknO1xuaW1wb3J0IEJyb3dzZXJKb2IgZnJvbSAnLi4vLi4vcnVubmVyL2Jyb3dzZXItam9iJztcbmltcG9ydCBXYXJuaW5nTG9nIGZyb20gJy4uLy4uL25vdGlmaWNhdGlvbnMvd2FybmluZy1sb2cnO1xuaW1wb3J0IEJyb3dzZXJQcm92aWRlciBmcm9tICcuLi9wcm92aWRlcic7XG5pbXBvcnQgU0VSVklDRV9ST1VURVMgZnJvbSAnLi9zZXJ2aWNlLXJvdXRlcyc7XG5pbXBvcnQge1xuICAgIEJST1dTRVJfUkVTVEFSVF9USU1FT1VULFxuICAgIEJST1dTRVJfQ0xPU0VfVElNRU9VVCxcbiAgICBIRUFSVEJFQVRfVElNRU9VVCxcbiAgICBMT0NBTF9CUk9XU0VSX0lOSVRfVElNRU9VVCxcbiAgICBSRU1PVEVfQlJPV1NFUl9JTklUX1RJTUVPVVQsXG59IGZyb20gJy4uLy4uL3V0aWxzL2Jyb3dzZXItY29ubmVjdGlvbi10aW1lb3V0cyc7XG5pbXBvcnQgTWVzc2FnZUJ1cyBmcm9tICcuLi8uLi91dGlscy9tZXNzYWdlLWJ1cyc7XG5pbXBvcnQgQnJvd3NlckNvbm5lY3Rpb25UcmFja2VyIGZyb20gJy4vdHJhY2tlcic7XG5pbXBvcnQgVGVzdFJ1biBmcm9tICcuLi8uLi90ZXN0LXJ1bic7XG4vLyBAdHMtaWdub3JlXG5pbXBvcnQgeyBUZXN0UnVuIGFzIExlZ2FjeVRlc3RSdW4gfSBmcm9tICd0ZXN0Y2FmZS1sZWdhY3ktYXBpJztcbmltcG9ydCB7IFByb3h5IH0gZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5pbXBvcnQgeyBOZXh0VGVzdFJ1bkluZm8sIE9wZW5Ccm93c2VyQWRkaXRpb25hbE9wdGlvbnMgfSBmcm9tICcuLi8uLi9zaGFyZWQvdHlwZXMnO1xuaW1wb3J0IHsgRXZlbnRUeXBlIH0gZnJvbSAnLi4vLi4vbmF0aXZlLWF1dG9tYXRpb24vdHlwZXMnO1xuaW1wb3J0IHsgTmF0aXZlQXV0b21hdGlvbkJhc2UgfSBmcm9tICcuLi8uLi9uYXRpdmUtYXV0b21hdGlvbic7XG5pbXBvcnQgcmVtb3RlQ2hyb21lIGZyb20gJ2Nocm9tZS1yZW1vdGUtaW50ZXJmYWNlJztcblxuY29uc3QgZ2V0QnJvd3NlckNvbm5lY3Rpb25EZWJ1Z1Njb3BlID0gKGlkOiBzdHJpbmcpOiBzdHJpbmcgPT4gYHRlc3RjYWZlOmJyb3dzZXI6Y29ubmVjdGlvbjoke2lkfWA7XG5cbmNvbnN0IElETEVfUEFHRV9URU1QTEFURSA9IHJlYWQoJy4uLy4uL2NsaWVudC9icm93c2VyL2lkbGUtcGFnZS9pbmRleC5odG1sLm11c3RhY2hlJyk7XG5cblxuaW50ZXJmYWNlIERpc2Nvbm5lY3Rpb25Qcm9taXNlPFQ+IGV4dGVuZHMgUHJvbWlzZTxUPiB7XG4gICAgcmVzb2x2ZTogRnVuY3Rpb247XG4gICAgcmVqZWN0OiBGdW5jdGlvbjtcbn1cblxuaW50ZXJmYWNlIEJyb3dzZXJDb25uZWN0aW9uU3RhdHVzUmVzdWx0IHtcbiAgICBjbWQ6IHN0cmluZztcbiAgICB1cmw6IHN0cmluZztcbiAgICB0ZXN0UnVuSWQ6IHN0cmluZyB8IG51bGw7XG59XG5cbmludGVyZmFjZSBIZWFydGJlYXRTdGF0dXNSZXN1bHQge1xuICAgIGNvZGU6IEhlYXJ0YmVhdFN0YXR1cztcbiAgICB1cmw6IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIEluaXRTY3JpcHQge1xuICAgIGNvZGU6IHN0cmluZyB8IG51bGw7XG59XG5cbmludGVyZmFjZSBJbml0U2NyaXB0VGFzayBleHRlbmRzIEluaXRTY3JpcHQge1xuICAgIHJlc29sdmU6IEZ1bmN0aW9uO1xufVxuXG5pbnRlcmZhY2UgUHJvdmlkZXJNZXRhSW5mb09wdGlvbnMge1xuICAgIGFwcGVuZFRvVXNlckFnZW50PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCcm93c2VyQ2xvc2luZ0luZm8ge1xuICAgIGlzUmVzdGFydGluZz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnJvd3NlckluZm8ge1xuICAgIGFsaWFzOiBzdHJpbmc7XG4gICAgYnJvd3Nlck5hbWU6IHN0cmluZztcbiAgICBicm93c2VyT3B0aW9uOiB1bmtub3duO1xuICAgIHByb3ZpZGVyTmFtZTogc3RyaW5nO1xuICAgIHByb3ZpZGVyOiBCcm93c2VyUHJvdmlkZXI7XG4gICAgdXNlckFnZW50UHJvdmlkZXJNZXRhSW5mbzogc3RyaW5nO1xuICAgIHBhcnNlZFVzZXJBZ2VudDogUGFyc2VkVXNlckFnZW50O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJyb3dzZXJDb25uZWN0aW9uT3B0aW9ucyB7XG4gICAgZGlzYWJsZU11bHRpcGxlV2luZG93czogYm9vbGVhbjtcbiAgICBkZXZlbG9wbWVudE1vZGU6IGJvb2xlYW47XG4gICAgbmF0aXZlQXV0b21hdGlvbjogYm9vbGVhbjtcbn1cblxuY29uc3QgREVGQVVMVF9CUk9XU0VSX0NPTk5FQ1RJT05fT1BUSU9OUyA9IHtcbiAgICBkaXNhYmxlTXVsdGlwbGVXaW5kb3dzOiBmYWxzZSxcbiAgICBkZXZlbG9wbWVudE1vZGU6ICAgICAgICBmYWxzZSxcbiAgICBuYXRpdmVBdXRvbWF0aW9uOiAgICAgICBmYWxzZSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJyb3dzZXJDb25uZWN0aW9uIGV4dGVuZHMgRXZlbnRFbWl0dGVyIHtcbiAgICBwdWJsaWMgcGVybWFuZW50OiBib29sZWFuO1xuICAgIHB1YmxpYyBwcmV2aW91c0FjdGl2ZVdpbmRvd0lkOiBzdHJpbmcgfCBudWxsO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgSEVBUlRCRUFUX1RJTUVPVVQ6IG51bWJlcjtcbiAgICBwcml2YXRlIHJlYWRvbmx5IEJST1dTRVJfQ0xPU0VfVElNRU9VVDogbnVtYmVyO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgQlJPV1NFUl9SRVNUQVJUX1RJTUVPVVQ6IG51bWJlcjtcbiAgICBwdWJsaWMgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgICBwcml2YXRlIF9jdXJyZW50VGVzdFJ1bjogVGVzdFJ1biB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgam9iUXVldWU6IEJyb3dzZXJKb2JbXTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGluaXRTY3JpcHRzUXVldWU6IEluaXRTY3JpcHRUYXNrW107XG4gICAgcHVibGljIGJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheTogQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5O1xuICAgIHByaXZhdGUgZGlzY29ubmVjdGlvblByb21pc2U6IERpc2Nvbm5lY3Rpb25Qcm9taXNlPHZvaWQ+IHwgbnVsbDtcbiAgICBwcml2YXRlIHRlc3RSdW5BYm9ydGVkOiBib29sZWFuO1xuICAgIHB1YmxpYyBzdGF0dXM6IEJyb3dzZXJDb25uZWN0aW9uU3RhdHVzO1xuICAgIHByaXZhdGUgaGVhcnRiZWF0VGltZW91dDogTm9kZUpTLlRpbWVvdXQgfCBudWxsO1xuICAgIHByaXZhdGUgcGVuZGluZ1Rlc3RSdW5JbmZvOiBOZXh0VGVzdFJ1bkluZm8gfCBudWxsO1xuICAgIHB1YmxpYyB1cmwgPSAnJztcbiAgICBwdWJsaWMgaWRsZVVybCA9ICcnO1xuICAgIHByaXZhdGUgZm9yY2VkSWRsZVVybCA9ICcnO1xuICAgIHByaXZhdGUgaW5pdFNjcmlwdFVybCA9ICcnO1xuICAgIHB1YmxpYyBoZWFydGJlYXRVcmwgPSAnJztcbiAgICBwdWJsaWMgc3RhdHVzVXJsID0gJyc7XG4gICAgcHVibGljIGFjdGl2ZVdpbmRvd0lkVXJsID0gJyc7XG4gICAgcHVibGljIGVuc3VyZVdpbmRvd0luTmF0aXZlQXV0b21hdGlvblVybCA9ICcnO1xuICAgIHB1YmxpYyBjbG9zZVdpbmRvd1VybCA9ICcnO1xuICAgIHB1YmxpYyBzdGF0dXNEb25lVXJsID0gJyc7XG4gICAgcHVibGljIGhlYXJ0YmVhdFJlbGF0aXZlVXJsID0gJyc7XG4gICAgcHVibGljIHN0YXR1c1JlbGF0aXZlVXJsID0gJyc7XG4gICAgcHVibGljIHN0YXR1c0RvbmVSZWxhdGl2ZVVybCA9ICcnO1xuICAgIHB1YmxpYyBpZGxlUmVsYXRpdmVVcmwgPSAnJztcbiAgICBwdWJsaWMgb3BlbkZpbGVQcm90b2NvbFJlbGF0aXZlVXJsID0gJyc7XG4gICAgcHVibGljIG9wZW5GaWxlUHJvdG9jb2xVcmwgPSAnJztcbiAgICBwdWJsaWMgZGlzcGF0Y2hOYXRpdmVBdXRvbWF0aW9uRXZlbnRSZWxhdGl2ZVVybCA9ICcnO1xuICAgIHB1YmxpYyBkaXNwYXRjaE5hdGl2ZUF1dG9tYXRpb25FdmVudFNlcXVlbmNlUmVsYXRpdmVVcmwgPSAnJztcbiAgICBwdWJsaWMgcGFyc2VTZWxlY3RvclJlbGF0aXZlVXJsID0gJyc7XG4gICAgcHJpdmF0ZSByZWFkb25seSBkZWJ1Z0xvZ2dlcjogZGVidWcuRGVidWdnZXI7XG4gICAgcHVibGljIHJlYWRvbmx5IHdhcm5pbmdMb2c6IFdhcm5pbmdMb2c7XG4gICAgcHJpdmF0ZSBfbWVzc2FnZUJ1cz86IE1lc3NhZ2VCdXM7XG4gICAgcHJpdmF0ZSByZWFkb25seSBfb3B0aW9uczogQnJvd3NlckNvbm5lY3Rpb25PcHRpb25zO1xuXG4gICAgcHVibGljIGlkbGU6IGJvb2xlYW47XG5cbiAgICBwdWJsaWMgYnJvd3NlckluZm86IEJyb3dzZXJJbmZvO1xuICAgIHB1YmxpYyBwcm92aWRlcjogYW55O1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yIChcbiAgICAgICAgZ2F0ZXdheTogQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5LFxuICAgICAgICBicm93c2VySW5mbzogQnJvd3NlckluZm8sXG4gICAgICAgIHBlcm1hbmVudDogYm9vbGVhbixcbiAgICAgICAgb3B0aW9uczogUGFydGlhbDxCcm93c2VyQ29ubmVjdGlvbk9wdGlvbnM+ID0ge30sXG4gICAgICAgIG1lc3NhZ2VCdXM/OiBNZXNzYWdlQnVzKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpcy5IRUFSVEJFQVRfVElNRU9VVCAgICAgICA9IEhFQVJUQkVBVF9USU1FT1VUO1xuICAgICAgICB0aGlzLkJST1dTRVJfQ0xPU0VfVElNRU9VVCAgID0gQlJPV1NFUl9DTE9TRV9USU1FT1VUO1xuICAgICAgICB0aGlzLkJST1dTRVJfUkVTVEFSVF9USU1FT1VUID0gQlJPV1NFUl9SRVNUQVJUX1RJTUVPVVQ7XG5cbiAgICAgICAgdGhpcy5pZCAgICAgICAgICAgICAgICAgICAgICAgPSBCcm93c2VyQ29ubmVjdGlvbi5fZ2VuZXJhdGVJZCgpO1xuICAgICAgICB0aGlzLmpvYlF1ZXVlICAgICAgICAgICAgICAgICA9IFtdO1xuICAgICAgICB0aGlzLmluaXRTY3JpcHRzUXVldWUgICAgICAgICA9IFtdO1xuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheSA9IGdhdGV3YXk7XG4gICAgICAgIHRoaXMuZGlzY29ubmVjdGlvblByb21pc2UgICAgID0gbnVsbDtcbiAgICAgICAgdGhpcy50ZXN0UnVuQWJvcnRlZCAgICAgICAgICAgPSBmYWxzZTtcbiAgICAgICAgdGhpcy53YXJuaW5nTG9nICAgICAgICAgICAgICAgPSBuZXcgV2FybmluZ0xvZyhudWxsLCBXYXJuaW5nTG9nLmNyZWF0ZUFkZFdhcm5pbmdDYWxsYmFjayhtZXNzYWdlQnVzKSk7XG4gICAgICAgIHRoaXMuZGVidWdMb2dnZXIgICAgICAgICAgICAgID0gZGVidWcoZ2V0QnJvd3NlckNvbm5lY3Rpb25EZWJ1Z1Njb3BlKHRoaXMuaWQpKTtcblxuICAgICAgICBpZiAobWVzc2FnZUJ1cykge1xuICAgICAgICAgICAgdGhpcy5tZXNzYWdlQnVzID0gbWVzc2FnZUJ1cztcblxuICAgICAgICAgICAgdGhpcy5pbml0TWVzc2FnZUJ1cygpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5icm93c2VySW5mbyAgICAgICAgICAgICAgICAgICAgICAgICAgID0gYnJvd3NlckluZm87XG4gICAgICAgIHRoaXMuYnJvd3NlckluZm8udXNlckFnZW50UHJvdmlkZXJNZXRhSW5mbyA9ICcnO1xuXG4gICAgICAgIHRoaXMucHJvdmlkZXIgPSBicm93c2VySW5mby5wcm92aWRlcjtcblxuICAgICAgICB0aGlzLnBlcm1hbmVudCAgICAgICAgICAgICAgPSBwZXJtYW5lbnQ7XG4gICAgICAgIHRoaXMuc3RhdHVzICAgICAgICAgICAgICAgICA9IEJyb3dzZXJDb25uZWN0aW9uU3RhdHVzLnVuaW5pdGlhbGl6ZWQ7XG4gICAgICAgIHRoaXMuaWRsZSAgICAgICAgICAgICAgICAgICA9IHRydWU7XG4gICAgICAgIHRoaXMuaGVhcnRiZWF0VGltZW91dCAgICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMucGVuZGluZ1Rlc3RSdW5JbmZvICAgICA9IG51bGw7XG4gICAgICAgIHRoaXMuX29wdGlvbnMgICAgICAgICAgICAgICA9IHRoaXMuX2NhbGN1bGF0ZVJlc3VsdE9wdGlvbnMob3B0aW9ucyk7XG5cbiAgICAgICAgdGhpcy5fc2V0RXZlbnRIYW5kbGVycygpO1xuXG4gICAgICAgIEJyb3dzZXJDb25uZWN0aW9uVHJhY2tlci5hZGQodGhpcyk7XG5cbiAgICAgICAgdGhpcy5wcmV2aW91c0FjdGl2ZVdpbmRvd0lkID0gbnVsbDtcblxuICAgICAgICB0aGlzLmJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5zdGFydFNlcnZpbmdDb25uZWN0aW9uKHRoaXMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2NhbGN1bGF0ZVJlc3VsdE9wdGlvbnMgKG9wdGlvbnM6IFBhcnRpYWw8QnJvd3NlckNvbm5lY3Rpb25PcHRpb25zPik6IEJyb3dzZXJDb25uZWN0aW9uT3B0aW9ucyB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBERUZBVUxUX0JST1dTRVJfQ09OTkVDVElPTl9PUFRJT05TLCBvcHRpb25zKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9idWlsZENvbW11bmljYXRpb25VcmxzIChwcm94eTogUHJveHkpOiB2b2lkIHtcbiAgICAgICAgdGhpcy51cmwgICAgICAgICAgID0gcHJveHkucmVzb2x2ZVJlbGF0aXZlU2VydmljZVVybChgJHtTRVJWSUNFX1JPVVRFUy5jb25uZWN0fS8ke3RoaXMuaWR9YCk7XG4gICAgICAgIHRoaXMuZm9yY2VkSWRsZVVybCA9IHByb3h5LnJlc29sdmVSZWxhdGl2ZVNlcnZpY2VVcmwoYCR7U0VSVklDRV9ST1VURVMuaWRsZUZvcmNlZH0vJHt0aGlzLmlkfWApO1xuICAgICAgICB0aGlzLmluaXRTY3JpcHRVcmwgPSBwcm94eS5yZXNvbHZlUmVsYXRpdmVTZXJ2aWNlVXJsKGAke1NFUlZJQ0VfUk9VVEVTLmluaXRTY3JpcHR9LyR7dGhpcy5pZH1gKTtcblxuICAgICAgICB0aGlzLmhlYXJ0YmVhdFJlbGF0aXZlVXJsICAgICAgICAgICAgICAgICAgICAgID0gYCR7U0VSVklDRV9ST1VURVMuaGVhcnRiZWF0fS8ke3RoaXMuaWR9YDtcbiAgICAgICAgdGhpcy5zdGF0dXNSZWxhdGl2ZVVybCAgICAgICAgICAgICAgICAgICAgICAgICA9IGAke1NFUlZJQ0VfUk9VVEVTLnN0YXR1c30vJHt0aGlzLmlkfWA7XG4gICAgICAgIHRoaXMuc3RhdHVzRG9uZVJlbGF0aXZlVXJsICAgICAgICAgICAgICAgICAgICAgPSBgJHtTRVJWSUNFX1JPVVRFUy5zdGF0dXNEb25lfS8ke3RoaXMuaWR9YDtcbiAgICAgICAgdGhpcy5pZGxlUmVsYXRpdmVVcmwgICAgICAgICAgICAgICAgICAgICAgICAgICA9IGAke1NFUlZJQ0VfUk9VVEVTLmlkbGV9LyR7dGhpcy5pZH1gO1xuICAgICAgICB0aGlzLmFjdGl2ZVdpbmRvd0lkVXJsICAgICAgICAgICAgICAgICAgICAgIC