testcafe
Version:
Automated browser testing for the modern web development stack.
177 lines (174 loc) • 29.5 kB
JavaScript
;
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