UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

177 lines (174 loc) 29.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const testcafe_hammerhead_1 = require("testcafe-hammerhead"); const injectables_1 = require("../assets/injectables"); const empty_page_markup_1 = __importDefault(require("./empty-page-markup")); const http_status_codes_1 = require("http-status-codes"); const test_run_1 = require("../errors/test-run"); const cdp_1 = require("./utils/cdp"); const debug_loggers_1 = require("../utils/debug-loggers"); const string_1 = require("./utils/string"); const safe_api_1 = require("./request-pipeline/safe-api"); const errors_1 = require("./errors"); const RESPONSE_REMOVED_HEADERS = [ 'cross-origin-embedder-policy', 'cross-origin-opener-policy', 'cross-origin-resource-policy', ]; const DEFAULT_RESOURCE_INJECTOR_OPTIONS = { specialServiceRoutes: { errorPage1: '', errorPage2: '', openFileProtocolUrl: '', idlePage: '', }, developmentMode: false, }; class ResourceInjector { constructor(testRunBridge) { this._options = DEFAULT_RESOURCE_INJECTOR_OPTIONS; this._testRunBridge = testRunBridge; } _getRestoreContextStorageScript(contextStorage) { const currentTestRun = this._testRunBridge.getCurrentTestRun(); const value = JSON.stringify((contextStorage === null || contextStorage === void 0 ? void 0 : contextStorage[currentTestRun.id]) || ''); return `Object.defineProperty(window, '%nativeAutomationContextStorage%', { configurable: true, value: ${value} });`; } _getRestoreStoragesScript(restoringStorages) { if (!restoringStorages) return '(function() {})()'; return `(function() { window.localStorage.clear(); window.sessionStorage.clear(); const snapshot = ${JSON.stringify(restoringStorages)}; const ls = JSON.parse(snapshot.localStorage); const ss = JSON.parse(snapshot.sessionStorage); for (let i = 0; i < ls[0].length; i++) window.localStorage.setItem(ls[0][i], ls[1][i]); for (let i = 0; i < ss[0].length; i++) window.sessionStorage.setItem(ss[0][i], ss[1][i]); })(); `; } _resolveRelativeUrls(proxy, relativeUrls) { return relativeUrls.map(url => proxy.resolveRelativeServiceUrl(url)); } async _prepareInjectableResources({ isIframe, restoringStorages, contextStorage, userScripts }) { if (!this._testRunBridge.getCurrentTestRun()) return null; const taskScript = await this._testRunBridge.getTaskScript({ isIframe, restoringStorages, contextStorage, userScripts }); const proxy = this._testRunBridge.getBrowserConnection().browserConnectionGateway.proxy; const injectableResources = { stylesheets: [ injectables_1.TESTCAFE_UI_STYLES, ...this._testRunBridge.getInjectableStyles(), ], scripts: [ ...testcafe_hammerhead_1.INJECTABLE_SCRIPTS.map(hs => (0, testcafe_hammerhead_1.getAssetPath)(hs, this._options.developmentMode)), ...injectables_1.SCRIPTS.map(s => (0, testcafe_hammerhead_1.getAssetPath)(s, this._options.developmentMode)), ...this._testRunBridge.getInjectableScripts(), ], embeddedScripts: [this._getRestoreStoragesScript(restoringStorages), this._getRestoreContextStorageScript(contextStorage), taskScript], userScripts: userScripts || [], }; injectableResources.scripts = this._resolveRelativeUrls(proxy, injectableResources.scripts); injectableResources.userScripts = this._resolveRelativeUrls(proxy, injectableResources.userScripts); injectableResources.stylesheets = this._resolveRelativeUrls(proxy, injectableResources.stylesheets); return injectableResources; } _processResponseHeaders(headers) { if (!headers) return []; headers = headers.filter(header => !RESPONSE_REMOVED_HEADERS.includes(header.name.toLowerCase())); return (0, string_1.stringifyHeaderValues)(headers); } async _fulfillRequest(client, fulfillRequestInfo, body, sessionId, contentType) { await (0, safe_api_1.safeFulfillRequest)(client, { requestId: fulfillRequestInfo.requestId, responseCode: fulfillRequestInfo.responseCode || http_status_codes_1.StatusCodes.OK, responsePhrase: fulfillRequestInfo.responsePhrase, responseHeaders: this._processResponseHeaders(fulfillRequestInfo.responseHeaders), body: (0, string_1.toBase64String)(body, contentType), }, sessionId); } async redirectToErrorPage(client, err, url) { const currentTestRun = this._testRunBridge.getCurrentTestRun(); if (!currentTestRun) return; currentTestRun.pendingPageError = new test_run_1.PageLoadError(err, url); await (0, cdp_1.navigateTo)(client, this._options.specialServiceRoutes.errorPage1); } async getDocumentResourceInfo(event, client, contentType) { const { requestId, request, responseErrorReason, resourceType, } = event; if (resourceType !== 'Document') { return { error: null, body: null, }; } try { if (responseErrorReason === 'NameNotResolved') { const err = (0, errors_1.failedToFindDNSError)(request.url); return { error: err, body: null, }; } const responseObj = await client.Fetch.getResponseBody({ requestId }); const responseStr = (0, string_1.getResponseAsString)(responseObj, contentType); return { error: null, body: Buffer.from(responseStr), }; } catch (err) { (0, debug_loggers_1.resourceInjectorLogger)('Failed to process request: %s', request.url); return { error: err, body: null, }; } } async processAboutBlankPage(event, userScripts, contextStorage, client) { (0, debug_loggers_1.resourceInjectorLogger)('Handle page as about:blank. Origin url: %s', event.frame.url); const injectableResources = await this._prepareInjectableResources({ isIframe: false, userScripts, contextStorage }); const html = (0, testcafe_hammerhead_1.injectResources)(empty_page_markup_1.default, injectableResources); await client.Page.setDocumentContent({ frameId: event.frame.id, html, }); } async processHTMLPageContent(fulfillRequestInfo, injectableResourcesOptions, client, sessionId, contentType) { const injectableResources = await this._prepareInjectableResources(injectableResourcesOptions); // NOTE: an unhandled exception interrupts the test execution, // and we are force to redirect manually to the idle page. if (!injectableResources) await (0, cdp_1.redirect)(client, fulfillRequestInfo.requestId, this._options.specialServiceRoutes.idlePage); else { const updatedResponseStr = (0, testcafe_hammerhead_1.injectResources)(fulfillRequestInfo.body, injectableResources, this._getPageInjectableResourcesOptions(injectableResourcesOptions)); await this._fulfillRequest(client, fulfillRequestInfo, updatedResponseStr, sessionId, contentType); } } async processNonProxiedContent(fulfillRequestInfo, client, sessionId) { await this._fulfillRequest(client, fulfillRequestInfo, fulfillRequestInfo.body, sessionId); } _getPageInjectableResourcesOptions(injectableResourcesOptions) { const { url, restoringStorages } = injectableResourcesOptions; if (url && restoringStorages) { return { host: new URL(url).host, sessionId: this._testRunBridge.getSessionId(), }; } return void 0; } setOptions(options) { this._options = options; } } exports.default = ResourceInjector; module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb3VyY2UtaW5qZWN0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbmF0aXZlLWF1dG9tYXRpb24vcmVzb3VyY2UtaW5qZWN0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFNQSw2REFRNkI7QUFDN0IsdURBQW9FO0FBQ3BFLDRFQUFvRDtBQUNwRCx5REFBZ0Q7QUFDaEQsaURBQW1EO0FBQ25ELHFDQUFtRDtBQVVuRCwwREFBZ0U7QUFDaEUsMkNBSXdCO0FBQ3hCLDBEQUFpRTtBQUVqRSxxQ0FBZ0Q7QUFFaEQsTUFBTSx3QkFBd0IsR0FBRztJQUM3Qiw4QkFBOEI7SUFDOUIsNEJBQTRCO0lBQzVCLDhCQUE4QjtDQUNqQyxDQUFDO0FBT0YsTUFBTSxpQ0FBaUMsR0FBRztJQUN0QyxvQkFBb0IsRUFBRTtRQUNsQixVQUFVLEVBQVcsRUFBRTtRQUN2QixVQUFVLEVBQVcsRUFBRTtRQUN2QixtQkFBbUIsRUFBRSxFQUFFO1FBQ3ZCLFFBQVEsRUFBYSxFQUFFO0tBQzFCO0lBRUQsZUFBZSxFQUFFLEtBQUs7Q0FDekIsQ0FBQztBQUVGLE1BQXFCLGdCQUFnQjtJQUlqQyxZQUFvQixhQUE0QjtRQUM1QyxJQUFJLENBQUMsUUFBUSxHQUFTLGlDQUFpQyxDQUFDO1FBQ3hELElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDO0lBQ3hDLENBQUM7SUFFTywrQkFBK0IsQ0FBRSxjQUEwQztRQUMvRSxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDL0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBLGNBQWMsYUFBZCxjQUFjLHVCQUFkLGNBQWMsQ0FBRyxjQUFjLENBQUMsRUFBRSxDQUFDLEtBQUksRUFBRSxDQUFDLENBQUM7UUFFeEUsT0FBTyxrR0FBa0csS0FBSyxNQUFNLENBQUM7SUFDekgsQ0FBQztJQUVPLHlCQUF5QixDQUFFLGlCQUFz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LFlBQVksRUFBRTthQUNoRCxDQUFDO1NBQ0w7UUFFRCxPQUFPLEtBQUssQ0FBQyxDQUFDO0lBQ2xCLENBQUM7SUFFTSxVQUFVLENBQUUsT0FBZ0M7UUFDL0MsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7SUFDNUIsQ0FBQztDQUNKO0FBaE1ELG1DQWdNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFByb3RvY29sQXBpIH0gZnJvbSAnY2hyb21lLXJlbW90ZS1pbnRlcmZhY2UnO1xuaW1wb3J0IFByb3RvY29sIGZyb20gJ2RldnRvb2xzLXByb3RvY29sJztcbmltcG9ydCBSZXF1ZXN0UGF1c2VkRXZlbnQgPSBQcm90b2NvbC5GZXRjaC5SZXF1ZXN0UGF1c2VkRXZlbnQ7XG5pbXBvcnQgRnJhbWVOYXZpZ2F0ZWRFdmVudCA9IFByb3RvY29sLlBhZ2UuRnJhbWVOYXZpZ2F0ZWRFdmVudDtcbmltcG9ydCBGdWxmaWxsUmVxdWVzdFJlcXVlc3QgPSBQcm90b2NvbC5GZXRjaC5GdWxmaWxsUmVxdWVzdFJlcXVlc3Q7XG5pbXBvcnQgSGVhZGVyRW50cnkgPSBQcm90b2NvbC5GZXRjaC5IZWFkZXJFbnRyeTtcbmltcG9ydCB7XG4gICAgaW5qZWN0UmVzb3VyY2VzLFxuICAgIFBhZ2VJbmplY3RhYmxlUmVzb3VyY2VzLFxuICAgIElOSkVDVEFCTEVfU0NSSVBUUyBhcyBIQU1NRVJIRUFEX0lOSkVDVEFCTEVfU0NSSVBUUyxcbiAgICBnZXRBc3NldFBhdGgsXG4gICAgUGFnZVJlc3RvcmVTdG9yYWdlc09wdGlvbnMsXG4gICAgU3RvcmFnZXNTbmFwc2hvdCxcbiAgICBQcm94eSxcbn0gZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5pbXBvcnQgeyBTQ1JJUFRTLCBURVNUQ0FGRV9VSV9TVFlMRVMgfSBmcm9tICcuLi9hc3NldHMvaW5qZWN0YWJsZXMnO1xuaW1wb3J0IEVNUFRZX1BBR0VfTUFSS1VQIGZyb20gJy4vZW1wdHktcGFnZS1tYXJrdXAnO1xuaW1wb3J0IHsgU3RhdHVzQ29kZXMgfSBmcm9tICdodHRwLXN0YXR1cy1jb2Rlcyc7XG5pbXBvcnQgeyBQYWdlTG9hZEVycm9yIH0gZnJvbSAnLi4vZXJyb3JzL3Rlc3QtcnVuJztcbmltcG9ydCB7IHJlZGlyZWN0LCBuYXZpZ2F0ZVRvIH0gZnJvbSAnLi91dGlscy9jZHAnO1xuXG5pbXBvcnQge1xuICAgIERvY3VtZW50UmVzb3VyY2VJbmZvLFxuICAgIEluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zLFxuICAgIFNlc3Npb25JZCxcbiAgICBTZXNzaW9uU3RvcmFnZUluZm8sXG4gICAgU3BlY2lhbFNlcnZpY2VSb3V0ZXMsXG59IGZyb20gJy4vdHlwZXMnO1xuXG5pbXBvcnQgeyByZXNvdXJjZUluamVjdG9yTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvZGVidWctbG9nZ2Vycyc7XG5pbXBvcnQge1xuICAgIGdldFJlc3BvbnNlQXNTdHJpbmcsXG4gICAgc3RyaW5naWZ5SGVhZGVyVmFsdWVzLFxuICAgIHRvQmFzZTY0U3RyaW5nLFxufSBmcm9tICcuL3V0aWxzL3N0cmluZyc7XG5pbXBvcnQgeyBzYWZlRnVsZmlsbFJlcXVlc3QgfSBmcm9tICcuL3JlcXVlc3QtcGlwZWxpbmUvc2FmZS1hcGknO1xuaW1wb3J0IFRlc3RSdW5CcmlkZ2UgZnJvbSAnLi9yZXF1ZXN0LXBpcGVsaW5lL3Rlc3QtcnVuLWJyaWRnZSc7XG5pbXBvcnQgeyBmYWlsZWRUb0ZpbmRETlNFcnJvciB9IGZyb20gJy4vZXJyb3JzJztcblxuY29uc3QgUkVTUE9OU0VfUkVNT1ZFRF9IRUFERVJTID0gW1xuICAgICdjcm9zcy1vcmlnaW4tZW1iZWRkZXItcG9saWN5JyxcbiAgICAnY3Jvc3Mtb3JpZ2luLW9wZW5lci1wb2xpY3knLFxuICAgICdjcm9zcy1vcmlnaW4tcmVzb3VyY2UtcG9saWN5Jyxcbl07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb3VyY2VJbmplY3Rvck9wdGlvbnMge1xuICAgIHNwZWNpYWxTZXJ2aWNlUm91dGVzOiBTcGVjaWFsU2VydmljZVJvdXRlcztcbiAgICBkZXZlbG9wbWVudE1vZGU6IGJvb2xlYW47XG59XG5cbmNvbnN0IERFRkFVTFRfUkVTT1VSQ0VfSU5KRUNUT1JfT1BUSU9OUyA9IHtcbiAgICBzcGVjaWFsU2VydmljZVJvdXRlczoge1xuICAgICAgICBlcnJvclBhZ2UxOiAgICAgICAgICAnJyxcbiAgICAgICAgZXJyb3JQYWdlMjogICAgICAgICAgJycsXG4gICAgICAgIG9wZW5GaWxlUHJvdG9jb2xVcmw6ICcnLFxuICAgICAgICBpZGxlUGFnZTogICAgICAgICAgICAnJyxcbiAgICB9LFxuXG4gICAgZGV2ZWxvcG1lbnRNb2RlOiBmYWxzZSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc291cmNlSW5qZWN0b3Ige1xuICAgIHByaXZhdGUgX29wdGlvbnM6IFJlc291cmNlSW5qZWN0b3JPcHRpb25zO1xuICAgIHByaXZhdGUgcmVhZG9ubHkgX3Rlc3RSdW5CcmlkZ2U6IFRlc3RSdW5CcmlkZ2U7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IgKHRlc3RSdW5CcmlkZ2U6IFRlc3RSdW5CcmlkZ2UpIHtcbiAgICAgICAgdGhpcy5fb3B0aW9ucyAgICAgICA9IERFRkFVTFRfUkVTT1VSQ0VfSU5KRUNUT1JfT1BUSU9OUztcbiAgICAgICAgdGhpcy5fdGVzdFJ1bkJyaWRnZSA9IHRlc3RSdW5CcmlkZ2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0UmVzdG9yZUNvbnRleHRTdG9yYWdlU2NyaXB0IChjb250ZXh0U3RvcmFnZT86IFNlc3Npb25TdG9yYWdlSW5mbyB8IG51bGwpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBjdXJyZW50VGVzdFJ1biA9IHRoaXMuX3Rlc3RSdW5CcmlkZ2UuZ2V0Q3VycmVudFRlc3RSdW4oKTtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBKU09OLnN0cmluZ2lmeShjb250ZXh0U3RvcmFnZT8uW2N1cnJlbnRUZXN0UnVuLmlkXSB8fCAnJyk7XG5cbiAgICAgICAgcmV0dXJuIGBPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LCAnJW5hdGl2ZUF1dG9tYXRpb25Db250ZXh0U3RvcmFnZSUnLCB7IGNvbmZpZ3VyYWJsZTogdHJ1ZSwgdmFsdWU6ICR7dmFsdWV9IH0pO2A7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZ2V0UmVzdG9yZVN0b3JhZ2VzU2NyaXB0IChyZXN0b3JpbmdTdG9yYWdlczogU3RvcmFnZXNTbmFwc2hvdCB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICAgICAgICBpZiAoIXJlc3RvcmluZ1N0b3JhZ2VzKVxuICAgICAgICAgICAgcmV0dXJuICcoZnVuY3Rpb24oKSB7fSkoKSc7XG5cbiAgICAgICAgcmV0dXJuIGAoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLmNsZWFyKCk7XG4gICAgICAgICAgICB3aW5kb3cuc2Vzc2lvblN0b3JhZ2UuY2xlYXIoKTtcblxuICAgICAgICAgICAgY29uc3Qgc25hcHNob3QgPSAke0pTT04uc3RyaW5naWZ5KHJlc3RvcmluZ1N0b3JhZ2VzKX07XG4gICAgICAgICAgICBjb25zdCBscyAgICAgICA9IEpTT04ucGFyc2Uoc25hcHNob3QubG9jYWxTdG9yYWdlKTtcbiAgICAgICAgICAgIGNvbnN0IHNzICAgICAgID0gSlNPTi5wYXJzZShzbmFwc2hvdC5zZXNzaW9uU3RvcmFnZSk7XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbHNbMF0ubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKGxzWzBdW2ldLCBsc1sxXVtpXSk7XG5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3NbMF0ubGVuZ3RoOyBpKyspXG4gICAgICAgICAgICAgICAgd2luZG93LnNlc3Npb25TdG9yYWdlLnNldEl0ZW0oc3NbMF1baV0sIHNzWzFdW2ldKTtcbiAgICAgICAgfSkoKTtcbiAgICAgICAgYDtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9yZXNvbHZlUmVsYXRpdmVVcmxzIChwcm94eTogUHJveHksIHJlbGF0aXZlVXJsczogc3RyaW5nW10pOiBzdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiByZWxhdGl2ZVVybHMubWFwKHVybCA9PiBwcm94eS5yZXNvbHZlUmVsYXRpdmVTZXJ2aWNlVXJsKHVybCkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgX3ByZXBhcmVJbmplY3RhYmxlUmVzb3VyY2VzICh7IGlzSWZyYW1lLCByZXN0b3JpbmdTdG9yYWdlcywgY29udGV4dFN0b3JhZ2UsIHVzZXJTY3JpcHRzIH06IEluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zKTogUHJvbWlzZTxQYWdlSW5qZWN0YWJsZVJlc291cmNlcyB8IG51bGw+IHtcbiAgICAgICAgaWYgKCF0aGlzLl90ZXN0UnVuQnJpZGdlLmdldEN1cnJlbnRUZXN0UnVuKCkpXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcblxuICAgICAgICBjb25zdCB0YXNrU2NyaXB0ID0gYXdhaXQgdGhpcy5fdGVzdFJ1bkJyaWRnZS5nZXRUYXNrU2NyaXB0KHsgaXNJZnJhbWUsIHJlc3RvcmluZ1N0b3JhZ2VzLCBjb250ZXh0U3RvcmFnZSwgdXNlclNjcmlwdHMgfSk7XG4gICAgICAgIGNvbnN0IHByb3h5ICAgICAgPSB0aGlzLl90ZXN0UnVuQnJpZGdlLmdldEJyb3dzZXJDb25uZWN0aW9uKCkuYnJvd3NlckNvbm5lY3Rpb25HYXRld2F5LnByb3h5O1xuXG4gICAgICAgIGNvbnN0IGluamVjdGFibGVSZXNvdXJjZXMgPSB7XG4gICAgICAgICAgICBzdHlsZXNoZWV0czogW1xuICAgICAgICAgICAgICAgIFRFU1RDQUZFX1VJX1NUWUxFUyxcbiAgICAgICAgICAgICAgICAuLi50aGlzLl90ZXN0UnVuQnJpZGdlLmdldEluamVjdGFibGVTdHlsZXMoKSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBzY3JpcHRzOiBbXG4gICAgICAgICAgICAgICAgLi4uSEFNTUVSSEVBRF9JTkpFQ1RBQkxFX1NDUklQVFMubWFwKGhzID0+IGdldEFzc2V0UGF0aChocywgdGhpcy5fb3B0aW9ucy5kZXZlbG9wbWVudE1vZGUpKSxcbiAgICAgICAgICAgICAgICAuLi5TQ1JJUFRTLm1hcChzID0+IGdldEFzc2V0UGF0aChzLCB0aGlzLl9vcHRpb25zLmRldmVsb3BtZW50TW9kZSkpLFxuICAgICAgICAgICAgICAgIC4uLnRoaXMuX3Rlc3RSdW5CcmlkZ2UuZ2V0SW5qZWN0YWJsZVNjcmlwdHMoKSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBlbWJlZGRlZFNjcmlwdHM6IFsgdGhpcy5fZ2V0UmVzdG9yZVN0b3JhZ2VzU2NyaXB0KHJlc3RvcmluZ1N0b3JhZ2VzKSwgdGhpcy5fZ2V0UmVzdG9yZUNvbnRleHRTdG9yYWdlU2NyaXB0KGNvbnRleHRTdG9yYWdlKSwgdGFza1NjcmlwdF0sXG4gICAgICAgICAgICB1c2VyU2NyaXB0czogICAgIHVzZXJTY3JpcHRzIHx8IFtdLFxuICAgICAgICB9O1xuXG4gICAgICAgIGluamVjdGFibGVSZXNvdXJjZXMuc2NyaXB0cyAgICAgPSB0aGlzLl9yZXNvbHZlUmVsYXRpdmVVcmxzKHByb3h5LCBpbmplY3RhYmxlUmVzb3VyY2VzLnNjcmlwdHMpO1xuICAgICAgICBpbmplY3RhYmxlUmVzb3VyY2VzLnVzZXJTY3JpcHRzID0gdGhpcy5fcmVzb2x2ZVJlbGF0aXZlVXJscyhwcm94eSwgaW5qZWN0YWJsZVJlc291cmNlcy51c2VyU2NyaXB0cyk7XG4gICAgICAgIGluamVjdGFibGVSZXNvdXJjZXMuc3R5bGVzaGVldHMgPSB0aGlzLl9yZXNvbHZlUmVsYXRpdmVVcmxzKHByb3h5LCBpbmplY3RhYmxlUmVzb3VyY2VzLnN0eWxlc2hlZXRzKTtcblxuICAgICAgICByZXR1cm4gaW5qZWN0YWJsZVJlc291cmNlcztcbiAgICB9XG5cbiAgICBwcml2YXRlIF9wcm9jZXNzUmVzcG9uc2VIZWFkZXJzIChoZWFkZXJzOiBIZWFkZXJFbnRyeVtdIHwgdW5kZWZpbmVkKTogSGVhZGVyRW50cnlbXSB7XG4gICAgICAgIGlmICghaGVhZGVycylcbiAgICAgICAgICAgIHJldHVybiBbXTtcblxuICAgICAgICBoZWFkZXJzID0gaGVhZGVycy5maWx0ZXIoaGVhZGVyID0+ICFSRVNQT05TRV9SRU1PVkVEX0hFQURFUlMuaW5jbHVkZXMoaGVhZGVyLm5hbWUudG9Mb3dlckNhc2UoKSkpO1xuXG4gICAgICAgIHJldHVybiBzdHJpbmdpZnlIZWFkZXJWYWx1ZXMoaGVhZGVycyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBfZnVsZmlsbFJlcXVlc3QgKGNsaWVudDogUHJvdG9jb2xBcGksIGZ1bGZpbGxSZXF1ZXN0SW5mbzogRnVsZmlsbFJlcXVlc3RSZXF1ZXN0LCBib2R5OiBzdHJpbmcsIHNlc3Npb25JZDogU2Vzc2lvbklkLCBjb250ZW50VHlwZT86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCBzYWZlRnVsZmlsbFJlcXVlc3QoY2xpZW50LCB7XG4gICAgICAgICAgICByZXF1ZXN0SWQ6ICAgICAgIGZ1bGZpbGxSZXF1ZXN0SW5mby5yZXF1ZXN0SWQsXG4gICAgICAgICAgICByZXNwb25zZUNvZGU6ICAgIGZ1bGZpbGxSZXF1ZXN0SW5mby5yZXNwb25zZUNvZGUgfHwgU3RhdHVzQ29kZXMuT0ssXG4gICAgICAgICAgICByZXNwb25zZVBocmFzZTogIGZ1bGZpbGxSZXF1ZXN0SW5mby5yZXNwb25zZVBocmFzZSxcbiAgICAgICAgICAgIHJlc3BvbnNlSGVhZGVyczogdGhpcy5fcHJvY2Vzc1Jlc3BvbnNlSGVhZGVycyhmdWxmaWxsUmVxdWVzdEluZm8ucmVzcG9uc2VIZWFkZXJzKSxcbiAgICAgICAgICAgIGJvZHk6ICAgICAgICAgICAgdG9CYXNlNjRTdHJpbmcoYm9keSwgY29udGVudFR5cGUpLFxuICAgICAgICB9LCBzZXNzaW9uSWQpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyByZWRpcmVjdFRvRXJyb3JQYWdlIChjbGllbnQ6IFByb3RvY29sQXBpLCBlcnI6IEVycm9yLCB1cmw6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBjdXJyZW50VGVzdFJ1biA9IHRoaXMuX3Rlc3RSdW5CcmlkZ2UuZ2V0Q3VycmVudFRlc3RSdW4oKTtcblxuICAgICAgICBpZiAoIWN1cnJlbnRUZXN0UnVuKVxuICAgICAgICAgICAgcmV0dXJuO1xuXG4gICAgICAgIGN1cnJlbnRUZXN0UnVuLnBlbmRpbmdQYWdlRXJyb3IgPSBuZXcgUGFnZUxvYWRFcnJvcihlcnIsIHVybCk7XG5cbiAgICAgICAgYXdhaXQgbmF2aWdhdGVUbyhjbGllbnQsIHRoaXMuX29wdGlvbnMuc3BlY2lhbFNlcnZpY2VSb3V0ZXMuZXJyb3JQYWdlMSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGdldERvY3VtZW50UmVzb3VyY2VJbmZvIChldmVudDogUmVxdWVzdFBhdXNlZEV2ZW50LCBjbGllbnQ6IFByb3RvY29sQXBpLCBjb250ZW50VHlwZT86IHN0cmluZyk6IFByb21pc2U8RG9jdW1lbnRSZXNvdXJjZUluZm8+IHtcbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgICAgcmVxdWVzdElkLFxuICAgICAgICAgICAgcmVxdWVzdCxcbiAgICAgICAgICAgIHJlc3BvbnNlRXJyb3JSZWFzb24sXG4gICAgICAgICAgICByZXNvdXJjZVR5cGUsXG4gICAgICAgIH0gPSBldmVudDtcblxuICAgICAgICBpZiAocmVzb3VyY2VUeXBlICE9PSAnRG9jdW1lbnQnKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGVycm9yOiBudWxsLFxuICAgICAgICAgICAgICAgIGJvZHk6ICBudWxsLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAocmVzcG9uc2VFcnJvclJlYXNvbiA9PT0gJ05hbWVOb3RSZXNvbHZlZCcpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBlcnIgPSBmYWlsZWRUb0ZpbmRETlNFcnJvcihyZXF1ZXN0LnVybCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcjogZXJyLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiAgbnVsbCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCByZXNwb25zZU9iaiA9IGF3YWl0IGNsaWVudC5GZXRjaC5nZXRSZXNwb25zZUJvZHkoeyByZXF1ZXN0SWQgfSk7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZVN0ciA9IGdldFJlc3BvbnNlQXNTdHJpbmcocmVzcG9uc2VPYmosIGNvbnRlbnRUeXBlKTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBlcnJvcjogbnVsbCxcbiAgICAgICAgICAgICAgICBib2R5OiAgQnVmZmVyLmZyb20ocmVzcG9uc2VTdHIpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICByZXNvdXJjZUluamVjdG9yTG9nZ2VyKCdGYWlsZWQgdG8gcHJvY2VzcyByZXF1ZXN0OiAlcycsIHJlcXVlc3QudXJsKTtcblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyLFxuICAgICAgICAgICAgICAgIGJvZHk6ICBudWxsLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBwcm9jZXNzQWJvdXRCbGFua1BhZ2UgKGV2ZW50OiBGcmFtZU5hdmlnYXRlZEV2ZW50LCB1c2VyU2NyaXB0czogc3RyaW5nW10sIGNvbnRleHRTdG9yYWdlOiBTZXNzaW9uU3RvcmFnZUluZm8gfCBudWxsLCBjbGllbnQ6IFByb3RvY29sQXBpKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHJlc291cmNlSW5qZWN0b3JMb2dnZXIoJ0hhbmRsZSBwYWdlIGFzIGFib3V0OmJsYW5rLiBPcmlnaW4gdXJsOiAlcycsIGV2ZW50LmZyYW1lLnVybCk7XG5cbiAgICAgICAgY29uc3QgaW5qZWN0YWJsZVJlc291cmNlcyA9IGF3YWl0IHRoaXMuX3ByZXBhcmVJbmplY3RhYmxlUmVzb3VyY2VzKHsgaXNJZnJhbWU6IGZhbHNlLCB1c2VyU2NyaXB0cywgY29udGV4dFN0b3JhZ2UgfSkgYXMgUGFnZUluamVjdGFibGVSZXNvdXJjZXM7XG4gICAgICAgIGNvbnN0IGh0bWwgICAgICAgICAgICAgICAgPSBpbmplY3RSZXNvdXJjZXMoRU1QVFlfUEFHRV9NQVJLVVAsIGluamVjdGFibGVSZXNvdXJjZXMpO1xuXG4gICAgICAgIGF3YWl0IGNsaWVudC5QYWdlLnNldERvY3VtZW50Q29udGVudCh7XG4gICAgICAgICAgICBmcmFtZUlkOiBldmVudC5mcmFtZS5pZCxcbiAgICAgICAgICAgIGh0bWwsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBwcm9jZXNzSFRNTFBhZ2VDb250ZW50IChmdWxmaWxsUmVxdWVzdEluZm86IEZ1bGZpbGxSZXF1ZXN0UmVxdWVzdCwgaW5qZWN0YWJsZVJlc291cmNlc09wdGlvbnM6IEluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zLCBjbGllbnQ6IFByb3RvY29sQXBpLCBzZXNzaW9uSWQ6IFNlc3Npb25JZCwgY29udGVudFR5cGU/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgaW5qZWN0YWJsZVJlc291cmNlcyA9IGF3YWl0IHRoaXMuX3ByZXBhcmVJbmplY3RhYmxlUmVzb3VyY2VzKGluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zKTtcblxuICAgICAgICAvLyBOT1RFOiBhbiB1bmhhbmRsZWQgZXhjZXB0aW9uIGludGVycnVwdHMgdGhlIHRlc3QgZXhlY3V0aW9uLFxuICAgICAgICAvLyBhbmQgd2UgYXJlIGZvcmNlIHRvIHJlZGlyZWN0IG1hbnVhbGx5IHRvIHRoZSBpZGxlIHBhZ2UuXG4gICAgICAgIGlmICghaW5qZWN0YWJsZVJlc291cmNlcylcbiAgICAgICAgICAgIGF3YWl0IHJlZGlyZWN0KGNsaWVudCwgZnVsZmlsbFJlcXVlc3RJbmZvLnJlcXVlc3RJZCwgdGhpcy5fb3B0aW9ucy5zcGVjaWFsU2VydmljZVJvdXRlcy5pZGxlUGFnZSk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgdXBkYXRlZFJlc3BvbnNlU3RyID0gaW5qZWN0UmVzb3VyY2VzKFxuICAgICAgICAgICAgICAgIGZ1bGZpbGxSZXF1ZXN0SW5mby5ib2R5IGFzIHN0cmluZyxcbiAgICAgICAgICAgICAgICBpbmplY3RhYmxlUmVzb3VyY2VzLFxuICAgICAgICAgICAgICAgIHRoaXMuX2dldFBhZ2VJbmplY3RhYmxlUmVzb3VyY2VzT3B0aW9ucyhpbmplY3RhYmxlUmVzb3VyY2VzT3B0aW9ucyksXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9mdWxmaWxsUmVxdWVzdChjbGllbnQsIGZ1bGZpbGxSZXF1ZXN0SW5mbywgdXBkYXRlZFJlc3BvbnNlU3RyLCBzZXNzaW9uSWQsIGNvbnRlbnRUeXBlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBhc3luYyBwcm9jZXNzTm9uUHJveGllZENvbnRlbnQgKGZ1bGZpbGxSZXF1ZXN0SW5mbzogRnVsZmlsbFJlcXVlc3RSZXF1ZXN0LCBjbGllbnQ6IFByb3RvY29sQXBpLCBzZXNzaW9uSWQ6IFNlc3Npb25JZCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLl9mdWxmaWxsUmVxdWVzdChjbGllbnQsIGZ1bGZpbGxSZXF1ZXN0SW5mbywgZnVsZmlsbFJlcXVlc3RJbmZvLmJvZHkgYXMgc3RyaW5nLCBzZXNzaW9uSWQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2dldFBhZ2VJbmplY3RhYmxlUmVzb3VyY2VzT3B0aW9ucyAoaW5qZWN0YWJsZVJlc291cmNlc09wdGlvbnM6IEluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zKTogUGFnZVJlc3RvcmVTdG9yYWdlc09wdGlvbnMgfCB1bmRlZmluZWQge1xuICAgICAgICBjb25zdCB7IHVybCwgcmVzdG9yaW5nU3RvcmFnZXMgfSA9IGluamVjdGFibGVSZXNvdXJjZXNPcHRpb25zO1xuXG4gICAgICAgIGlmICh1cmwgJiYgcmVzdG9yaW5nU3RvcmFnZXMpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgaG9zdDogICAgICBuZXcgVVJMKHVybCkuaG9zdCxcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHRoaXMuX3Rlc3RSdW5CcmlkZ2UuZ2V0U2Vzc2lvbklkKCksXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHZvaWQgMDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0T3B0aW9ucyAob3B0aW9uczogUmVzb3VyY2VJbmplY3Rvck9wdGlvbnMpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5fb3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgfVxufVxuIl19