UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

177 lines 30.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const os_family_1 = __importDefault(require("os-family")); const url_1 = require("url"); const base_1 = __importDefault(require("../base")); const runtime_info_1 = __importDefault(require("./runtime-info")); const config_1 = __importDefault(require("./config")); const local_chrome_1 = require("./local-chrome"); const client_functions_1 = require("../../../utils/client-functions"); const cdp_client_1 = require("./cdp-client"); const cdp_1 = require("../../../../../native-automation/utils/cdp"); const debug_loggers_1 = require("../../../../../utils/debug-loggers"); const types_1 = require("../../../../../native-automation/types"); const delay_1 = __importDefault(require("../../../../../utils/delay")); const convert_1 = require("../../../../../native-automation/utils/convert"); const MIN_AVAILABLE_DIMENSION = 50; exports.default = Object.assign(Object.assign({}, base_1.default), { getConfig(name) { return (0, config_1.default)(name); }, async getCurrentCDPSession(browserId) { const { browserClient } = this.openedBrowsers[browserId]; const cdpClient = await browserClient.getActiveClient(); return cdpClient; }, _getBrowserProtocolClient(runtimeInfo) { return runtimeInfo.browserClient; }, async _createRunTimeInfo(hostName, config, disableMultipleWindows) { return runtime_info_1.default.create(hostName, config, disableMultipleWindows); }, _setUserAgentMetaInfoForEmulatingDevice(browserId, config) { const { emulation, deviceName } = config; const isDeviceEmulation = emulation && deviceName; if (!isDeviceEmulation) return; const metaInfo = `Emulating ${deviceName}`; const options = { appendToUserAgent: true, }; this.setUserAgentMetaInfo(browserId, metaInfo, options); }, async _setupNativeAutomation({ browserClient, runtimeInfo, nativeAutomationOptions }) { const nativeAutomation = await browserClient.createMainWindowNativeAutomation(nativeAutomationOptions); await nativeAutomation.start(); runtimeInfo.nativeAutomation = nativeAutomation; }, async _startChrome(startOptions, pageUrl) { if (startOptions.isContainerized) await (0, local_chrome_1.startOnDocker)(pageUrl, startOptions); else await (0, local_chrome_1.start)(pageUrl, startOptions); }, async openBrowser(browserId, pageUrl, config, additionalOptions) { var _a; const parsedPageUrl = (0, url_1.parse)(pageUrl); const runtimeInfo = await this._createRunTimeInfo(parsedPageUrl.hostname, config, additionalOptions.disableMultipleWindows); runtimeInfo.browserName = this._getBrowserName(); runtimeInfo.browserId = browserId; runtimeInfo.providerMethods = { resizeLocalBrowserWindow: (...args) => this.resizeLocalBrowserWindow(...args), reportWarning: (...args) => this.reportWarning(browserId, ...args), }; //NOTE: A not-working tab is opened when the browser start in the docker so we should create a new tab. await this._startChrome(Object.assign({ isNativeAutomation: additionalOptions.nativeAutomation }, runtimeInfo), pageUrl); await this.waitForConnectionReady(browserId); runtimeInfo.viewportSize = await this.runInitScript(browserId, client_functions_1.GET_WINDOW_DIMENSIONS_INFO_SCRIPT); runtimeInfo.activeWindowId = null; runtimeInfo.windowDescriptors = {}; const browserClient = new cdp_client_1.BrowserClient(runtimeInfo); this.openedBrowsers[browserId] = runtimeInfo; if (additionalOptions.nativeAutomation) await this._setupNativeAutomation({ browserId, browserClient, runtimeInfo, nativeAutomationOptions: (0, convert_1.toNativeAutomationSetupOptions)(additionalOptions, config.headless) }); if (additionalOptions.nativeAutomation || !additionalOptions.disableMultipleWindows) runtimeInfo.activeWindowId = ((_a = runtimeInfo === null || runtimeInfo === void 0 ? void 0 : runtimeInfo.nativeAutomation) === null || _a === void 0 ? void 0 : _a.windowId) || this.calculateWindowId(); await browserClient.initMainWindowCdpClient(); await this._ensureWindowIsExpanded(browserId, runtimeInfo.viewportSize); this._setUserAgentMetaInfoForEmulatingDevice(browserId, runtimeInfo.config); (0, debug_loggers_1.chromeBrowserProviderLogger)('browser opened %s', browserId); }, async closeBrowser(browserId, closingInfo = {}) { const runtimeInfo = this.openedBrowsers[browserId]; if (runtimeInfo.nativeAutomation) await runtimeInfo.nativeAutomation.dispose(); if (runtimeInfo.browserClient.isHeadlessTab()) await runtimeInfo.browserClient.closeTab(); else await this.closeLocalBrowser(browserId); if (os_family_1.default.mac || runtimeInfo.config.headless) await (0, local_chrome_1.stop)(runtimeInfo); if (runtimeInfo.tempProfileDir && !closingInfo.isRestarting) await runtimeInfo.tempProfileDir.dispose(); delete this.openedBrowsers[browserId]; (0, debug_loggers_1.chromeBrowserProviderLogger)('browser closed %s', browserId); }, async resizeWindow(browserId, width, height, currentWidth, currentHeight) { const runtimeInfo = this.openedBrowsers[browserId]; if (runtimeInfo.config.mobile) await runtimeInfo.browserClient.updateMobileViewportSize(); else { runtimeInfo.viewportSize.width = currentWidth; runtimeInfo.viewportSize.height = currentHeight; } await runtimeInfo.browserClient.resizeWindow({ width, height }); }, async maximizeWindowNativeAutomation(browserId) { const { browserClient } = this.openedBrowsers[browserId]; await browserClient.maximizeWindowNativeAutomation(); }, async resizeBounds(browserId, width, height, currentWidth, currentHeight) { const { browserClient } = this.openedBrowsers[browserId]; await browserClient.resizeBounds({ width, height, currentWidth, currentHeight }); }, async startCapturingVideo(browserId) { const { browserClient } = this.openedBrowsers[browserId]; await browserClient.startCapturingVideo(); }, async stopCapturingVideo(browserId) { const { browserClient } = this.openedBrowsers[browserId]; await browserClient.stopCapturingVideo(); }, async getVideoFrameData(browserId) { const { browserClient } = this.openedBrowsers[browserId]; return browserClient.getVideoFrameData(); }, async hasCustomActionForBrowser(browserId) { const { config, browserClient } = this.openedBrowsers[browserId]; const client = await browserClient.getActiveClient(); return { hasCloseBrowser: true, hasResizeWindow: !!client && (config.emulation || config.headless), hasMaximizeWindow: !!client && config.headless, hasTakeScreenshot: !!client, hasChromelessScreenshots: !!client, hasGetVideoFrameData: !!client, hasCanResizeWindowToDimensions: false, }; }, async _ensureWindowIsExpanded(browserId, { height, width, availableHeight, availableWidth, outerWidth, outerHeight }) { if (height < MIN_AVAILABLE_DIMENSION || width < MIN_AVAILABLE_DIMENSION) { const newHeight = Math.max(availableHeight, MIN_AVAILABLE_DIMENSION); const newWidth = Math.max(Math.floor(availableWidth / 2), MIN_AVAILABLE_DIMENSION); await this.resizeWindow(browserId, newWidth, newHeight, outerWidth, outerHeight); } }, async openFileProtocol(browserId, url) { const cdpClient = await this.getCurrentCDPSession(browserId); await (0, cdp_1.navigateTo)(cdpClient, url); }, async dispatchNativeAutomationEvent(browserId, type, options) { const cdpClient = await this.getCurrentCDPSession(browserId); await (0, cdp_1.dispatchEvent)(cdpClient, type, options); }, async dispatchNativeAutomationEventSequence(browserId, eventSequence) { const cdpClient = await this.getCurrentCDPSession(browserId); for (const event of eventSequence) { if (event.type === types_1.EventType.Delay) await (0, delay_1.default)(event.options.delay); else await (0, cdp_1.dispatchEvent)(cdpClient, event.type, event.options); } }, supportNativeAutomation() { return true; }, getNativeAutomation(browserId) { const runtimeInfo = this.openedBrowsers[browserId]; return runtimeInfo.nativeAutomation; }, async getNewWindowIdInNativeAutomation(browserId) { const runtimeInfo = this.openedBrowsers[browserId]; return runtimeInfo.nativeAutomation.getNewWindowIdInNativeAutomation(); } }); module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYnJvd3Nlci9wcm92aWRlci9idWlsdC1pbi9kZWRpY2F0ZWQvY2hyb21lL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsMERBQTJCO0FBQzNCLDZCQUF3QztBQUN4QyxtREFBNEM7QUFDNUMsa0VBQStDO0FBQy9DLHNEQUFpQztBQUNqQyxpREFJd0I7QUFDeEIsc0VBQW9GO0FBQ3BGLDZDQUE2QztBQUM3QyxvRUFBd0g7QUFDeEgsc0VBQWlGO0FBQ2pGLGtFQUFtRTtBQUNuRSx1RUFBK0M7QUFDL0MsNEVBQWdHO0FBRWhHLE1BQU0sdUJBQXVCLEdBQUcsRUFBRSxDQUFDO0FBRW5DLGtEQUNPLGNBQXFCLEtBRXhCLFNBQVMsQ0FBRSxJQUFJO1FBQ1gsT0FBTyxJQUFBLGdCQUFTLEVBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUVELEtBQUssQ0FBQyxvQkFBb0IsQ0FBRSxTQUFTO1FBQ2pDLE1BQU0sRUFBRSxhQUFhLEVBQUUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pELE1BQU0sU0FBUyxHQUFXLE1BQU0sYUFBYSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBRWhFLE9BQU8sU0FBUyxDQUFDO0lBQ3JCLENBQUM7SUFFRCx5QkFBeUIsQ0FBRSxXQUFXO1FBQ2xDLE9BQU8sV0FBVyxDQUFDLGFBQWEsQ0FBQztJQUNyQyxDQUFDO0lBRUQsS0FBSyxDQUFDLGtCQUFrQixDQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsc0JBQXNCO1FBQzlELE9BQU8sc0JBQWlCLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsc0JBQXNCLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBRUQsdUNBQXVDLENBQUUsU0FBUyxFQUFFLE1BQU07UUFDdEQsTUFBTSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVB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UyxDQUFDLENBQUM7UUFFN0QsS0FBSyxNQUFNLEtBQUssSUFBSSxhQUFhLEVBQUU7WUFDL0IsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLGlCQUFTLENBQUMsS0FBSztnQkFDOUIsTUFBTSxJQUFBLGVBQUssRUFBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDOztnQkFFakMsTUFBTSxJQUFBLG1CQUE2QixFQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNqRjtJQUNMLENBQUM7SUFFRCx1QkFBdUI7UUFDbkIsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELG1CQUFtQixDQUFFLFNBQVM7UUFDMUIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUVuRCxPQUFPLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQztJQUN4QyxDQUFDO0lBRUQsS0FBSyxDQUFDLGdDQUFnQyxDQUFFLFNBQVM7UUFDN0MsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUVuRCxPQUFPLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxnQ0FBZ0MsRUFBRSxDQUFDO0lBQzNFLENBQUMsSUFDSCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBPUyBmcm9tICdvcy1mYW1pbHknO1xuaW1wb3J0IHsgcGFyc2UgYXMgcGFyc2VVcmwgfSBmcm9tICd1cmwnO1xuaW1wb3J0IGRlZGljYXRlZFByb3ZpZGVyQmFzZSBmcm9tICcuLi9iYXNlJztcbmltcG9ydCBDaHJvbWVSdW5UaW1lSW5mbyBmcm9tICcuL3J1bnRpbWUtaW5mbyc7XG5pbXBvcnQgZ2V0Q29uZmlnIGZyb20gJy4vY29uZmlnJztcbmltcG9ydCB7XG4gICAgc3RhcnQgYXMgc3RhcnRMb2NhbENocm9tZSxcbiAgICBzdGFydE9uRG9ja2VyIGFzIHN0YXJ0TG9jYWxDaHJvbWVPbkRvY2tlcixcbiAgICBzdG9wIGFzIHN0b3BMb2NhbENocm9tZSxcbn0gZnJvbSAnLi9sb2NhbC1jaHJvbWUnO1xuaW1wb3J0IHsgR0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvY2xpZW50LWZ1bmN0aW9ucyc7XG5pbXBvcnQgeyBCcm93c2VyQ2xpZW50IH0gZnJvbSAnLi9jZHAtY2xpZW50JztcbmltcG9ydCB7IGRpc3BhdGNoRXZlbnQgYXMgZGlzcGF0Y2hOYXRpdmVBdXRvbWF0aW9uRXZlbnQsIG5hdmlnYXRlVG8gfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9uYXRpdmUtYXV0b21hdGlvbi91dGlscy9jZHAnO1xuaW1wb3J0IHsgY2hyb21lQnJvd3NlclByb3ZpZGVyTG9nZ2VyIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vdXRpbHMvZGVidWctbG9nZ2Vycyc7XG5pbXBvcnQgeyBFdmVudFR5cGUgfSBmcm9tICcuLi8uLi8uLi8uLi8uLi9uYXRpdmUtYXV0b21hdGlvbi90eXBlcyc7XG5pbXBvcnQgZGVsYXkgZnJvbSAnLi4vLi4vLi4vLi4vLi4vdXRpbHMvZGVsYXknO1xuaW1wb3J0IHsgdG9OYXRpdmVBdXRvbWF0aW9uU2V0dXBPcHRpb25zIH0gZnJvbSAnLi4vLi4vLi4vLi4vLi4vbmF0aXZlLWF1dG9tYXRpb24vdXRpbHMvY29udmVydCc7XG5cbmNvbnN0IE1JTl9BVkFJTEFCTEVfRElNRU5TSU9OID0gNTA7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgICAuLi5kZWRpY2F0ZWRQcm92aWRlckJhc2UsXG5cbiAgICBnZXRDb25maWcgKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGdldENvbmZpZyhuYW1lKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZ2V0Q3VycmVudENEUFNlc3Npb24gKGJyb3dzZXJJZCkge1xuICAgICAgICBjb25zdCB7IGJyb3dzZXJDbGllbnQgfSA9IHRoaXMub3BlbmVkQnJvd3NlcnNbYnJvd3NlcklkXTtcbiAgICAgICAgY29uc3QgY2RwQ2xpZW50ICAgICAgICAgPSBhd2FpdCBicm93c2VyQ2xpZW50LmdldEFjdGl2ZUNsaWVudCgpO1xuXG4gICAgICAgIHJldHVybiBjZHBDbGllbnQ7XG4gICAgfSxcblxuICAgIF9nZXRCcm93c2VyUHJvdG9jb2xDbGllbnQgKHJ1bnRpbWVJbmZvKSB7XG4gICAgICAgIHJldHVybiBydW50aW1lSW5mby5icm93c2VyQ2xpZW50O1xuICAgIH0sXG5cbiAgICBhc3luYyBfY3JlYXRlUnVuVGltZUluZm8gKGhvc3ROYW1lLCBjb25maWcsIGRpc2FibGVNdWx0aXBsZVdpbmRvd3MpIHtcbiAgICAgICAgcmV0dXJuIENocm9tZVJ1blRpbWVJbmZvLmNyZWF0ZShob3N0TmFtZSwgY29uZmlnLCBkaXNhYmxlTXVsdGlwbGVXaW5kb3dzKTtcbiAgICB9LFxuXG4gICAgX3NldFVzZXJBZ2VudE1ldGFJbmZvRm9yRW11bGF0aW5nRGV2aWNlIChicm93c2VySWQsIGNvbmZpZykge1xuICAgICAgICBjb25zdCB7IGVtdWxhdGlvbiwgZGV2aWNlTmFtZSB9ID0gY29uZmlnO1xuICAgICAgICBjb25zdCBpc0RldmljZUVtdWxhdGlvbiAgICAgICAgID0gZW11bGF0aW9uICYmIGRldmljZU5hbWU7XG5cbiAgICAgICAgaWYgKCFpc0RldmljZUVtdWxhdGlvbilcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjb25zdCBtZXRhSW5mbyA9IGBFbXVsYXRpbmcgJHtkZXZpY2VOYW1lfWA7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgID0ge1xuICAgICAgICAgICAgYXBwZW5kVG9Vc2VyQWdlbnQ6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgICAgdGhpcy5zZXRVc2VyQWdlbnRNZXRhSW5mbyhicm93c2VySWQsIG1ldGFJbmZvLCBvcHRpb25zKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgX3NldHVwTmF0aXZlQXV0b21hdGlvbiAoeyBicm93c2VyQ2xpZW50LCBydW50aW1lSW5mbywgbmF0aXZlQXV0b21hdGlvbk9wdGlvbnMgfSkge1xuICAgICAgICBjb25zdCBuYXRpdmVBdXRvbWF0aW9uID0gYXdhaXQgYnJvd3NlckNsaWVudC5jcmVhdGVNYWluV2luZG93TmF0aXZlQXV0b21hdGlvbihuYXRpdmVBdXRvbWF0aW9uT3B0aW9ucyk7XG5cbiAgICAgICAgYXdhaXQgbmF0aXZlQXV0b21hdGlvbi5zdGFydCgpO1xuXG4gICAgICAgIHJ1bnRpbWVJbmZvLm5hdGl2ZUF1dG9tYXRpb24gPSBuYXRpdmVBdXRvbWF0aW9uO1xuICAgIH0sXG5cbiAgICBhc3luYyBfc3RhcnRDaHJvbWUgKHN0YXJ0T3B0aW9ucywgcGFnZVVybCkge1xuICAgICAgICBpZiAoc3RhcnRPcHRpb25zLmlzQ29udGFpbmVyaXplZClcbiAgICAgICAgICAgIGF3YWl0IHN0YXJ0TG9jYWxDaHJvbWVPbkRvY2tlcihwYWdlVXJsLCBzdGFydE9wdGlvbnMpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBhd2FpdCBzdGFydExvY2FsQ2hyb21lKHBhZ2VVcmwsIHN0YXJ0T3B0aW9ucyk7XG4gICAgfSxcblxuICAgIGFzeW5jIG9wZW5Ccm93c2VyIChicm93c2VySWQsIHBhZ2VVcmwsIGNvbmZpZywgYWRkaXRpb25hbE9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkUGFnZVVybCA9IHBhcnNlVXJsKHBhZ2VVcmwpO1xuICAgICAgICBjb25zdCBydW50aW1lSW5mbyAgID0gYXdhaXQgdGhpcy5fY3JlYXRlUnVuVGltZUluZm8ocGFyc2VkUGFnZVVybC5ob3N0bmFtZSwgY29uZmlnLCBhZGRpdGlvbmFsT3B0aW9ucy5kaXNhYmxlTXVsdGlwbGVXaW5kb3dzKTtcblxuICAgICAgICBydW50aW1lSW5mby5icm93c2VyTmFtZSA9IHRoaXMuX2dldEJyb3dzZXJOYW1lKCk7XG4gICAgICAgIHJ1bnRpbWVJbmZvLmJyb3dzZXJJZCAgID0gYnJvd3NlcklkO1xuXG4gICAgICAgIHJ1bnRpbWVJbmZvLnByb3ZpZGVyTWV0aG9kcyA9IHtcbiAgICAgICAgICAgIHJlc2l6ZUxvY2FsQnJvd3NlcldpbmRvdzogKC4uLmFyZ3MpID0+IHRoaXMucmVzaXplTG9jYWxCcm93c2VyV2luZG93KC4uLmFyZ3MpLFxuICAgICAgICAgICAgcmVwb3J0V2FybmluZzogICAgICAgICAgICAoLi4uYXJncykgPT4gdGhpcy5yZXBvcnRXYXJuaW5nKGJyb3dzZXJJZCwgLi4uYXJncyksXG4gICAgICAgIH07XG5cbiAgICAgICAgLy9OT1RFOiBBIG5vdC13b3JraW5nIHRhYiBpcyBvcGVuZWQgd2hlbiB0aGUgYnJvd3NlciBzdGFydCBpbiB0aGUgZG9ja2VyIHNvIHdlIHNob3VsZCBjcmVhdGUgYSBuZXcgdGFiLlxuICAgICAgICBhd2FpdCB0aGlzLl9zdGFydENocm9tZShPYmplY3QuYXNzaWduKHsgaXNOYXRpdmVBdXRvbWF0aW9uOiBhZGRpdGlvbmFsT3B0aW9ucy5uYXRpdmVBdXRvbWF0aW9uIH0sIHJ1bnRpbWVJbmZvKSwgcGFnZVVybCk7XG4gICAgICAgIGF3YWl0IHRoaXMud2FpdEZvckNvbm5lY3Rpb25SZWFkeShicm93c2VySWQpO1xuXG4gICAgICAgIHJ1bnRpbWVJbmZvLnZpZXdwb3J0U2l6ZSAgICAgID0gYXdhaXQgdGhpcy5ydW5Jbml0U2NyaXB0KGJyb3dzZXJJZCwgR0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUKTtcbiAgICAgICAgcnVudGltZUluZm8uYWN0aXZlV2luZG93SWQgICAgPSBudWxsO1xuICAgICAgICBydW50aW1lSW5mby53aW5kb3dEZXNjcmlwdG9ycyA9IHt9O1xuXG4gICAgICAgIGNvbnN0IGJyb3dzZXJDbGllbnQgPSBuZXcgQnJvd3NlckNsaWVudChydW50aW1lSW5mbyk7XG5cbiAgICAgICAgdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdID0gcnVudGltZUluZm87XG5cbiAgICAgICAgaWYgKGFkZGl0aW9uYWxPcHRpb25zLm5hdGl2ZUF1dG9tYXRpb24pXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9zZXR1cE5hdGl2ZUF1dG9tYXRpb24oeyBicm93c2VySWQsIGJyb3dzZXJDbGllbnQsIHJ1bnRpbWVJbmZvLCBuYXRpdmVBdXRvbWF0aW9uT3B0aW9uczogdG9OYXRpdmVBdXRvbWF0aW9uU2V0dXBPcHRpb25zKGFkZGl0aW9uYWxPcHRpb25zLCBjb25maWcuaGVhZGxlc3MpIH0pO1xuXG4gICAgICAgIGlmIChhZGRpdGlvbmFsT3B0aW9ucy5uYXRpdmVBdXRvbWF0aW9uIHx8ICFhZGRpdGlvbmFsT3B0aW9ucy5kaXNhYmxlTXVsdGlwbGVXaW5kb3dzKVxuICAgICAgICAgICAgcnVudGltZUluZm8uYWN0aXZlV2luZG93SWQgPSBydW50aW1lSW5mbz8ubmF0aXZlQXV0b21hdGlvbj8ud2luZG93SWQgfHwgdGhpcy5jYWxjdWxhdGVXaW5kb3dJZCgpO1xuXG4gICAgICAgIGF3YWl0IGJyb3dzZXJDbGllbnQuaW5pdE1haW5XaW5kb3dDZHBDbGllbnQoKTtcblxuICAgICAgICBhd2FpdCB0aGlzLl9lbnN1cmVXaW5kb3dJc0V4cGFuZGVkKGJyb3dzZXJJZCwgcnVudGltZUluZm8udmlld3BvcnRTaXplKTtcblxuICAgICAgICB0aGlzLl9zZXRVc2VyQWdlbnRNZXRhSW5mb0ZvckVtdWxhdGluZ0RldmljZShicm93c2VySWQsIHJ1bnRpbWVJbmZvLmNvbmZpZyk7XG5cbiAgICAgICAgY2hyb21lQnJvd3NlclByb3ZpZGVyTG9nZ2VyKCdicm93c2VyIG9wZW5lZCAlcycsIGJyb3dzZXJJZCk7XG4gICAgfSxcblxuICAgIGFzeW5jIGNsb3NlQnJvd3NlciAoYnJvd3NlcklkLCBjbG9zaW5nSW5mbyA9IHt9KSB7XG4gICAgICAgIGNvbnN0IHJ1bnRpbWVJbmZvID0gdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdO1xuXG4gICAgICAgIGlmIChydW50aW1lSW5mby5uYXRpdmVBdXRvbWF0aW9uKVxuICAgICAgICAgICAgYXdhaXQgcnVudGltZUluZm8ubmF0aXZlQXV0b21hdGlvbi5kaXNwb3NlKCk7XG5cbiAgICAgICAgaWYgKHJ1bnRpbWVJbmZvLmJyb3dzZXJDbGllbnQuaXNIZWFkbGVzc1RhYigpKVxuICAgICAgICAgICAgYXdhaXQgcnVudGltZUluZm8uYnJvd3NlckNsaWVudC5jbG9zZVRhYigpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNsb3NlTG9jYWxCcm93c2VyKGJyb3dzZXJJZCk7XG5cbiAgICAgICAgaWYgKE9TLm1hYyB8fCBydW50aW1lSW5mby5jb25maWcuaGVhZGxlc3MpXG4gICAgICAgICAgICBhd2FpdCBzdG9wTG9jYWxDaHJvbWUocnVudGltZUluZm8pO1xuXG4gICAgICAgIGlmIChydW50aW1lSW5mby50ZW1wUHJvZmlsZURpciAmJiAhY2xvc2luZ0luZm8uaXNSZXN0YXJ0aW5nKVxuICAgICAgICAgICAgYXdhaXQgcnVudGltZUluZm8udGVtcFByb2ZpbGVEaXIuZGlzcG9zZSgpO1xuXG4gICAgICAgIGRlbGV0ZSB0aGlzLm9wZW5lZEJyb3dzZXJzW2Jyb3dzZXJJZF07XG5cbiAgICAgICAgY2hyb21lQnJvd3NlclByb3ZpZGVyTG9nZ2VyKCdicm93c2VyIGNsb3NlZCAlcycsIGJyb3dzZXJJZCk7XG4gICAgfSxcblxuICAgIGFzeW5jIHJlc2l6ZVdpbmRvdyAoYnJvd3NlcklkLCB3aWR0aCwgaGVpZ2h0LCBjdXJyZW50V2lkdGgsIGN1cnJlbnRIZWlnaHQpIHtcbiAgICAgICAgY29uc3QgcnVudGltZUluZm8gPSB0aGlzLm9wZW5lZEJyb3dzZXJzW2Jyb3dzZXJJZF07XG5cbiAgICAgICAgaWYgKHJ1bnRpbWVJbmZvLmNvbmZpZy5tb2JpbGUpXG4gICAgICAgICAgICBhd2FpdCBydW50aW1lSW5mby5icm93c2VyQ2xpZW50LnVwZGF0ZU1vYmlsZVZpZXdwb3J0U2l6ZSgpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJ1bnRpbWVJbmZvLnZpZXdwb3J0U2l6ZS53aWR0aCAgPSBjdXJyZW50V2lkdGg7XG4gICAgICAgICAgICBydW50aW1lSW5mby52aWV3cG9ydFNpemUuaGVpZ2h0ID0gY3VycmVudEhlaWdodDtcbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHJ1bnRpbWVJbmZvLmJyb3dzZXJDbGllbnQucmVzaXplV2luZG93KHsgd2lkdGgsIGhlaWdodCB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgbWF4aW1pemVXaW5kb3dOYXRpdmVBdXRvbWF0aW9uIChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgeyBicm93c2VyQ2xpZW50IH0gPSB0aGlzLm9wZW5lZEJyb3dzZXJzW2Jyb3dzZXJJZF07XG5cbiAgICAgICAgYXdhaXQgYnJvd3NlckNsaWVudC5tYXhpbWl6ZVdpbmRvd05hdGl2ZUF1dG9tYXRpb24oKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgcmVzaXplQm91bmRzIChicm93c2VySWQsIHdpZHRoLCBoZWlnaHQsIGN1cnJlbnRXaWR0aCwgY3VycmVudEhlaWdodCkge1xuICAgICAgICBjb25zdCB7IGJyb3dzZXJDbGllbnQgfSA9IHRoaXMub3BlbmVkQnJvd3NlcnNbYnJvd3NlcklkXTtcblxuICAgICAgICBhd2FpdCBicm93c2VyQ2xpZW50LnJlc2l6ZUJvdW5kcyh7IHdpZHRoLCBoZWlnaHQsIGN1cnJlbnRXaWR0aCwgY3VycmVudEhlaWdodCB9KTtcbiAgICB9LFxuXG4gICAgYXN5bmMgc3RhcnRDYXB0dXJpbmdWaWRlbyAoYnJvd3NlcklkKSB7XG4gICAgICAgIGNvbnN0IHsgYnJvd3NlckNsaWVudCB9ID0gdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdO1xuXG4gICAgICAgIGF3YWl0IGJyb3dzZXJDbGllbnQuc3RhcnRDYXB0dXJpbmdWaWRlbygpO1xuICAgIH0sXG5cbiAgICBhc3luYyBzdG9wQ2FwdHVyaW5nVmlkZW8gKGJyb3dzZXJJZCkge1xuICAgICAgICBjb25zdCB7IGJyb3dzZXJDbGllbnQgfSA9IHRoaXMub3BlbmVkQnJvd3NlcnNbYnJvd3NlcklkXTtcblxuICAgICAgICBhd2FpdCBicm93c2VyQ2xpZW50LnN0b3BDYXB0dXJpbmdWaWRlbygpO1xuICAgIH0sXG5cbiAgICBhc3luYyBnZXRWaWRlb0ZyYW1lRGF0YSAoYnJvd3NlcklkKSB7XG4gICAgICAgIGNvbnN0IHsgYnJvd3NlckNsaWVudCB9ID0gdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdO1xuXG4gICAgICAgIHJldHVybiBicm93c2VyQ2xpZW50LmdldFZpZGVvRnJhbWVEYXRhKCk7XG4gICAgfSxcblxuICAgIGFzeW5jIGhhc0N1c3RvbUFjdGlvbkZvckJyb3dzZXIgKGJyb3dzZXJJZCkge1xuICAgICAgICBjb25zdCB7IGNvbmZpZywgYnJvd3NlckNsaWVudCB9ID0gdGhpcy5vcGVuZWRCcm93c2Vyc1ticm93c2VySWRdO1xuICAgICAgICBjb25zdCBjbGllbnQgICAgICAgICAgICAgICAgICAgID0gYXdhaXQgYnJvd3NlckNsaWVudC5nZXRBY3RpdmVDbGllbnQoKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgaGFzQ2xvc2VCcm93c2VyOiAgICAgICAgICAgICAgICB0cnVlLFxuICAgICAgICAgICAgaGFzUmVzaXplV2luZG93OiAgICAgICAgICAgICAgICAhIWNsaWVudCAmJiAoY29uZmlnLmVtdWxhdGlvbiB8fCBjb25maWcuaGVhZGxlc3MpLFxuICAgICAgICAgICAgaGFzTWF4aW1pemVXaW5kb3c6ICAgICAgICAgICAgICAhIWNsaWVudCAmJiBjb25maWcuaGVhZGxlc3MsXG4gICAgICAgICAgICBoYXNUYWtlU2NyZWVuc2hvdDogICAgICAgICAgICAgICEhY2xpZW50LFxuICAgICAgICAgICAgaGFzQ2hyb21lbGVzc1NjcmVlbnNob3RzOiAgICAgICAhIWNsaWVudCxcbiAgICAgICAgICAgIGhhc0dldFZpZGVvRnJhbWVEYXRhOiAgICAgICAgICAgISFjbGllbnQsXG4gICAgICAgICAgICBoYXNDYW5SZXNpemVXaW5kb3dUb0RpbWVuc2lvbnM6IGZhbHNlLFxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBhc3luYyBfZW5zdXJlV2luZG93SXNFeHBhbmRlZCAoYnJvd3NlcklkLCB7IGhlaWdodCwgd2lkdGgsIGF2YWlsYWJsZUhlaWdodCwgYXZhaWxhYmxlV2lkdGgsIG91dGVyV2lkdGgsIG91dGVySGVpZ2h0IH0pIHtcbiAgICAgICAgaWYgKGhlaWdodCA8IE1JTl9BVkFJTEFCTEVfRElNRU5TSU9OIHx8IHdpZHRoIDwgTUlOX0FWQUlMQUJMRV9ESU1FTlNJT04pIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld0hlaWdodCA9IE1hdGgubWF4KGF2YWlsYWJsZUhlaWdodCwgTUlOX0FWQUlMQUJMRV9ESU1FTlNJT04pO1xuICAgICAgICAgICAgY29uc3QgbmV3V2lkdGggID0gTWF0aC5tYXgoTWF0aC5mbG9vcihhdmFpbGFibGVXaWR0aCAvIDIpLCBNSU5fQVZBSUxBQkxFX0RJTUVOU0lPTik7XG5cbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVzaXplV2luZG93KGJyb3dzZXJJZCwgbmV3V2lkdGgsIG5ld0hlaWdodCwgb3V0ZXJXaWR0aCwgb3V0ZXJIZWlnaHQpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGFzeW5jIG9wZW5GaWxlUHJvdG9jb2wgKGJyb3dzZXJJZCwgdXJsKSB7XG4gICAgICAgIGNvbnN0IGNkcENsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q3VycmVudENEUFNlc3Npb24oYnJvd3NlcklkKTtcblxuICAgICAgICBhd2FpdCBuYXZpZ2F0ZVRvKGNkcENsaWVudCwgdXJsKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGlzcGF0Y2hOYXRpdmVBdXRvbWF0aW9uRXZlbnQgKGJyb3dzZXJJZCwgdHlwZSwgb3B0aW9ucykge1xuICAgICAgICBjb25zdCBjZHBDbGllbnQgPSBhd2FpdCB0aGlzLmdldEN1cnJlbnRDRFBTZXNzaW9uKGJyb3dzZXJJZCk7XG5cbiAgICAgICAgYXdhaXQgZGlzcGF0Y2hOYXRpdmVBdXRvbWF0aW9uRXZlbnQoY2RwQ2xpZW50LCB0eXBlLCBvcHRpb25zKTtcbiAgICB9LFxuXG4gICAgYXN5bmMgZGlzcGF0Y2hOYXRpdmVBdXRvbWF0aW9uRXZlbnRTZXF1ZW5jZSAoYnJvd3NlcklkLCBldmVudFNlcXVlbmNlKSB7XG4gICAgICAgIGNvbnN0IGNkcENsaWVudCA9IGF3YWl0IHRoaXMuZ2V0Q3VycmVudENEUFNlc3Npb24oYnJvd3NlcklkKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGV2ZW50IG9mIGV2ZW50U2VxdWVuY2UpIHtcbiAgICAgICAgICAgIGlmIChldmVudC50eXBlID09PSBFdmVudFR5cGUuRGVsYXkpXG4gICAgICAgICAgICAgICAgYXdhaXQgZGVsYXkoZXZlbnQub3B0aW9ucy5kZWxheSk7XG4gICAgICAgICAgICBlbHNlXG4gICAgICAgICAgICAgICAgYXdhaXQgZGlzcGF0Y2hOYXRpdmVBdXRvbWF0aW9uRXZlbnQoY2RwQ2xpZW50LCBldmVudC50eXBlLCBldmVudC5vcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBzdXBwb3J0TmF0aXZlQXV0b21hdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICBnZXROYXRpdmVBdXRvbWF0aW9uIChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgcnVudGltZUluZm8gPSB0aGlzLm9wZW5lZEJyb3dzZXJzW2Jyb3dzZXJJZF07XG5cbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVJbmZvLm5hdGl2ZUF1dG9tYXRpb247XG4gICAgfSxcblxuICAgIGFzeW5jIGdldE5ld1dpbmRvd0lkSW5OYXRpdmVBdXRvbWF0aW9uIChicm93c2VySWQpIHtcbiAgICAgICAgY29uc3QgcnVudGltZUluZm8gPSB0aGlzLm9wZW5lZEJyb3dzZXJzW2Jyb3dzZXJJZF07XG5cbiAgICAgICAgcmV0dXJuIHJ1bnRpbWVJbmZvLm5hdGl2ZUF1dG9tYXRpb24uZ2V0TmV3V2luZG93SWRJbk5hdGl2ZUF1dG9tYXRpb24oKTtcbiAgICB9LFxufTtcbiJdfQ==