UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

225 lines 34.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 pinkie_1 = __importDefault(require("pinkie")); const lodash_1 = require("lodash"); const get_callsite_1 = require("../../errors/get-callsite"); const client_function_builder_1 = __importDefault(require("../../client-functions/client-function-builder")); const assertion_1 = __importDefault(require("./assertion")); const delegated_api_1 = require("../../utils/delegated-api"); const actions_1 = require("../../test-run/commands/actions"); const browser_manipulation_1 = require("../../test-run/commands/browser-manipulation"); const observation_1 = require("../../test-run/commands/observation"); const assert_type_1 = __importDefault(require("../request-hooks/assert-type")); const originalThen = pinkie_1.default.resolve().then; class TestController { constructor(testRun) { this.testRun = testRun; this.executionChain = pinkie_1.default.resolve(); this.callsitesWithoutAwait = new Set(); } // NOTE: we track missing `awaits` by exposing a special custom Promise to user code. // Action or assertion is awaited if: // a)someone used `await` so Promise's `then` function executed // b)Promise chained by using one of the mixed-in controller methods // // In both scenarios, we check that callsite that produced Promise is equal to the one // that is currently missing await. This is required to workaround scenarios like this: // // var t2 = t.click('#btn1'); // <-- stores new callsiteWithoutAwait // await t2; // <-- callsiteWithoutAwait = null // t.click('#btn2'); // <-- stores new callsiteWithoutAwait // await t2.click('#btn3'); // <-- without check it will set callsiteWithoutAwait = null, so we will lost tracking _createExtendedPromise(promise, callsite) { const extendedPromise = promise.then(lodash_1.identity); const markCallsiteAwaited = () => this.callsitesWithoutAwait.delete(callsite); extendedPromise.then = function () { markCallsiteAwaited(); return originalThen.apply(this, arguments); }; delegated_api_1.delegateAPI(extendedPromise, TestController.API_LIST, { handler: this, proxyMethod: markCallsiteAwaited }); return extendedPromise; } _enqueueTask(apiMethodName, createTaskExecutor) { const callsite = get_callsite_1.getCallsiteForMethod(apiMethodName); const executor = createTaskExecutor(callsite); this.executionChain.then = originalThen; this.executionChain = this.executionChain.then(executor); this.callsitesWithoutAwait.add(callsite); this.executionChain = this._createExtendedPromise(this.executionChain, callsite); return this.executionChain; } _enqueueCommand(apiMethodName, CmdCtor, cmdArgs) { return this._enqueueTask(apiMethodName, callsite => { let command = null; try { command = new CmdCtor(cmdArgs, this.testRun); } catch (err) { err.callsite = callsite; throw err; } return () => this.testRun.executeCommand(command, callsite); }); } // API implementation // We need implementation methods to obtain correct callsites. If we use plain API // methods in chained wrappers then we will have callsite for the wrapped method // in this file instead of chained method callsite in user code. _ctx$getter() { return this.testRun.ctx; } _ctx$setter(val) { this.testRun.ctx = val; return this.testRun.ctx; } _fixtureCtx$getter() { return this.testRun.fixtureCtx; } _click$(selector, options) { return this._enqueueCommand('click', actions_1.ClickCommand, { selector, options }); } _rightClick$(selector, options) { return this._enqueueCommand('rightClick', actions_1.RightClickCommand, { selector, options }); } _doubleClick$(selector, options) { return this._enqueueCommand('doubleClick', actions_1.DoubleClickCommand, { selector, options }); } _hover$(selector, options) { return this._enqueueCommand('hover', actions_1.HoverCommand, { selector, options }); } _drag$(selector, dragOffsetX, dragOffsetY, options) { return this._enqueueCommand('drag', actions_1.DragCommand, { selector, dragOffsetX, dragOffsetY, options }); } _dragToElement$(selector, destinationSelector, options) { return this._enqueueCommand('dragToElement', actions_1.DragToElementCommand, { selector, destinationSelector, options }); } _typeText$(selector, text, options) { return this._enqueueCommand('typeText', actions_1.TypeTextCommand, { selector, text, options }); } _selectText$(selector, startPos, endPos, options) { return this._enqueueCommand('selectText', actions_1.SelectTextCommand, { selector, startPos, endPos, options }); } _selectTextAreaContent$(selector, startLine, startPos, endLine, endPos, options) { return this._enqueueCommand('selectTextAreaContent', actions_1.SelectTextAreaContentCommand, { selector, startLine, startPos, endLine, endPos, options }); } _selectEditableContent$(startSelector, endSelector, options) { return this._enqueueCommand('selectEditableContent', actions_1.SelectEditableContentCommand, { startSelector, endSelector, options }); } _pressKey$(keys, options) { return this._enqueueCommand('pressKey', actions_1.PressKeyCommand, { keys, options }); } _wait$(timeout) { return this._enqueueCommand('wait', observation_1.WaitCommand, { timeout }); } _navigateTo$(url) { return this._enqueueCommand('navigateTo', actions_1.NavigateToCommand, { url }); } _setFilesToUpload$(selector, filePath) { return this._enqueueCommand('setFilesToUpload', actions_1.SetFilesToUploadCommand, { selector, filePath }); } _clearUpload$(selector) { return this._enqueueCommand('clearUpload', actions_1.ClearUploadCommand, { selector }); } _takeScreenshot$(path) { return this._enqueueCommand('takeScreenshot', browser_manipulation_1.TakeScreenshotCommand, { path }); } _takeElementScreenshot$(selector, ...args) { const commandArgs = { selector }; if (args[1]) { commandArgs.path = args[0]; commandArgs.options = args[1]; } else if (typeof args[0] === 'object') commandArgs.options = args[0]; else commandArgs.path = args[0]; return this._enqueueCommand('takeElementScreenshot', browser_manipulation_1.TakeElementScreenshotCommand, commandArgs); } _resizeWindow$(width, height) { return this._enqueueCommand('resizeWindow', browser_manipulation_1.ResizeWindowCommand, { width, height }); } _resizeWindowToFitDevice$(device, options) { return this._enqueueCommand('resizeWindowToFitDevice', browser_manipulation_1.ResizeWindowToFitDeviceCommand, { device, options }); } _maximizeWindow$() { return this._enqueueCommand('maximizeWindow', browser_manipulation_1.MaximizeWindowCommand); } _switchToIframe$(selector) { return this._enqueueCommand('switchToIframe', actions_1.SwitchToIframeCommand, { selector }); } _switchToMainWindow$() { return this._enqueueCommand('switchToMainWindow', actions_1.SwitchToMainWindowCommand); } _eval$(fn, options) { if (!lodash_1.isNil(options)) options = lodash_1.assign({}, options, { boundTestRun: this }); const builder = new client_function_builder_1.default(fn, options, { instantiation: 'eval', execution: 'eval' }); const clientFn = builder.getFunction(); return clientFn(); } _setNativeDialogHandler$(fn, options) { return this._enqueueCommand('setNativeDialogHandler', actions_1.SetNativeDialogHandlerCommand, { dialogHandler: { fn, options } }); } _getNativeDialogHistory$() { const callsite = get_callsite_1.getCallsiteForMethod('getNativeDialogHistory'); return this.testRun.executeCommand(new actions_1.GetNativeDialogHistoryCommand(), callsite); } _getBrowserConsoleMessages$() { const callsite = get_callsite_1.getCallsiteForMethod('getBrowserConsoleMessages'); return this.testRun.executeCommand(new actions_1.GetBrowserConsoleMessagesCommand(), callsite); } _expect$(actual) { const callsite = get_callsite_1.getCallsiteForMethod('expect'); return new assertion_1.default(actual, this, callsite); } _debug$() { return this._enqueueCommand('debug', observation_1.DebugCommand); } _setTestSpeed$(speed) { return this._enqueueCommand('setTestSpeed', actions_1.SetTestSpeedCommand, { speed }); } _setPageLoadTimeout$(duration) { return this._enqueueCommand('setPageLoadTimeout', actions_1.SetPageLoadTimeoutCommand, { duration }); } _useRole$(role) { return this._enqueueCommand('useRole', actions_1.UseRoleCommand, { role }); } _addRequestHooks$(...hooks) { return this._enqueueTask('addRequestHooks', () => { hooks = lodash_1.flattenDeep(hooks); assert_type_1.default(hooks); hooks.forEach(hook => this.testRun.addRequestHook(hook)); }); } _removeRequestHooks$(...hooks) { return this._enqueueTask('removeRequestHooks', () => { hooks = lodash_1.flattenDeep(hooks); assert_type_1.default(hooks); hooks.forEach(hook => this.testRun.removeRequestHook(hook)); }); } } exports.default = TestController; TestController.API_LIST = delegated_api_1.getDelegatedAPIList(TestController.prototype); delegated_api_1.delegateAPI(TestController.prototype, TestController.API_LIST, { useCurrentCtxAsHandler: true }); module.exports = exports.default; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBpL3Rlc3QtY29udHJvbGxlci9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9EQUE2QjtBQUM3QixtQ0FBOEY7QUFDOUYsNERBQWlFO0FBQ2pFLDZHQUFtRjtBQUNuRiw0REFBb0M7QUFDcEMsNkRBQTZFO0FBRTdFLDZEQXVCeUM7QUFFekMsdUZBTXNEO0FBRXRELHFFQUFnRjtBQUNoRiwrRUFBaUU7QUFFakUsTUFBTSxZQUFZLEdBQUcsZ0JBQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUM7QUFFNUMsTUFBcUIsY0FBYztJQUMvQixZQUFhLE9BQU87UUFDaEIsSUFBSSxDQUFDLE9BQU8sR0FBaUIsT0FBTyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxjQUFjLEdBQVUsZ0JBQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMvQyxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBRUQscUZBQXFGO0lBQ3JGLHFDQUFxQztJQUNyQywrREFBK0Q7SUFDL0Qsb0VBQW9FO0lBQ3BFLEVBQUU7SUFDRixzRkFBc0Y7SUFDdEYsdUZBQXVGO0lBQ3ZGLEVBQUU7SUFDRixvRUFBb0U7SUFDcEUsZ0VBQWdFO0lBQ2hFLG9FQUFvRTtJQUNwRSxvSEFBb0g7SUFDcEgsc0JBQXNCLENBQUUsT0FBTyxFQUFFLFFBQVE7UUFDckMsTUFBTSxlQUFlLEdBQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBUSxDQUFDLENBQUM7UUFDbkQsTUFBTSxtQkFBbUIsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRTlFLGVBQWUsQ0FBQyxJQUFJLEdBQUc7WUFDbkIsbUJBQW1CLEVBQUUsQ0FBQztZQUV0QixPQUFPLFlBQVksQ0FBQyxLQUFLLENB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Q0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0NBQ0o7QUF4UUQsaUNBd1FDO0FBRUQsY0FBYyxDQUFDLFFBQVEsR0FBRyxtQ0FBbUIsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUM7QUFFeEUsMkJBQVcsQ0FBQyxjQUFjLENBQUMsU0FBUyxFQUFFLGNBQWMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxzQkFBc0IsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFByb21pc2UgZnJvbSAncGlua2llJztcbmltcG9ydCB7IGlkZW50aXR5LCBhc3NpZ24sIGlzTmlsIGFzIGlzTnVsbE9yVW5kZWZpbmVkLCBmbGF0dGVuRGVlcCBhcyBmbGF0dGVuIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IGdldENhbGxzaXRlRm9yTWV0aG9kIH0gZnJvbSAnLi4vLi4vZXJyb3JzL2dldC1jYWxsc2l0ZSc7XG5pbXBvcnQgQ2xpZW50RnVuY3Rpb25CdWlsZGVyIGZyb20gJy4uLy4uL2NsaWVudC1mdW5jdGlvbnMvY2xpZW50LWZ1bmN0aW9uLWJ1aWxkZXInO1xuaW1wb3J0IEFzc2VydGlvbiBmcm9tICcuL2Fzc2VydGlvbic7XG5pbXBvcnQgeyBnZXREZWxlZ2F0ZWRBUElMaXN0LCBkZWxlZ2F0ZUFQSSB9IGZyb20gJy4uLy4uL3V0aWxzL2RlbGVnYXRlZC1hcGknO1xuXG5pbXBvcnQge1xuICAgIENsaWNrQ29tbWFuZCxcbiAgICBSaWdodENsaWNrQ29tbWFuZCxcbiAgICBEb3VibGVDbGlja0NvbW1hbmQsXG4gICAgSG92ZXJDb21tYW5kLFxuICAgIERyYWdDb21tYW5kLFxuICAgIERyYWdUb0VsZW1lbnRDb21tYW5kLFxuICAgIFR5cGVUZXh0Q29tbWFuZCxcbiAgICBTZWxlY3RUZXh0Q29tbWFuZCxcbiAgICBTZWxlY3RUZXh0QXJlYUNvbnRlbnRDb21tYW5kLFxuICAgIFNlbGVjdEVkaXRhYmxlQ29udGVudENvbW1hbmQsXG4gICAgUHJlc3NLZXlDb21tYW5kLFxuICAgIE5hdmlnYXRlVG9Db21tYW5kLFxuICAgIFNldEZpbGVzVG9VcGxvYWRDb21tYW5kLFxuICAgIENsZWFyVXBsb2FkQ29tbWFuZCxcbiAgICBTd2l0Y2hUb0lmcmFtZUNvbW1hbmQsXG4gICAgU3dpdGNoVG9NYWluV2luZG93Q29tbWFuZCxcbiAgICBTZXROYXRpdmVEaWFsb2dIYW5kbGVyQ29tbWFuZCxcbiAgICBHZXROYXRpdmVEaWFsb2dIaXN0b3J5Q29tbWFuZCxcbiAgICBHZXRCcm93c2VyQ29uc29sZU1lc3NhZ2VzQ29tbWFuZCxcbiAgICBTZXRUZXN0U3BlZWRDb21tYW5kLFxuICAgIFNldFBhZ2VMb2FkVGltZW91dENvbW1hbmQsXG4gICAgVXNlUm9sZUNvbW1hbmRcbn0gZnJvbSAnLi4vLi4vdGVzdC1ydW4vY29tbWFuZHMvYWN0aW9ucyc7XG5cbmltcG9ydCB7XG4gICAgVGFrZVNjcmVlbnNob3RDb21tYW5kLFxuICAgIFRha2VFbGVtZW50U2NyZWVuc2hvdENvbW1hbmQsXG4gICAgUmVzaXplV2luZG93Q29tbWFuZCxcbiAgICBSZXNpemVXaW5kb3dUb0ZpdERldmljZUNvbW1hbmQsXG4gICAgTWF4aW1pemVXaW5kb3dDb21tYW5kXG59IGZyb20gJy4uLy4uL3Rlc3QtcnVuL2NvbW1hbmRzL2Jyb3dzZXItbWFuaXB1bGF0aW9uJztcblxuaW1wb3J0IHsgV2FpdENvbW1hbmQsIERlYnVnQ29tbWFuZCB9IGZyb20gJy4uLy4uL3Rlc3QtcnVuL2NvbW1hbmRzL29ic2VydmF0aW9uJztcbmltcG9ydCBhc3NlcnRSZXF1ZXN0SG9va1R5cGUgZnJvbSAnLi4vcmVxdWVzdC1ob29rcy9hc3NlcnQtdHlwZSc7XG5cbmNvbnN0IG9yaWdpbmFsVGhlbiA9IFByb21pc2UucmVzb2x2ZSgpLnRoZW47XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFRlc3RDb250cm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvciAodGVzdFJ1bikge1xuICAgICAgICB0aGlzLnRlc3RSdW4gICAgICAgICAgICAgICA9IHRlc3RSdW47XG4gICAgICAgIHRoaXMuZXhlY3V0aW9uQ2hhaW4gICAgICAgID0gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgICAgIHRoaXMuY2FsbHNpdGVzV2l0aG91dEF3YWl0ID0gbmV3IFNldCgpO1xuICAgIH1cblxuICAgIC8vIE5PVEU6IHdlIHRyYWNrIG1pc3NpbmcgYGF3YWl0c2AgYnkgZXhwb3NpbmcgYSBzcGVjaWFsIGN1c3RvbSBQcm9taXNlIHRvIHVzZXIgY29kZS5cbiAgICAvLyBBY3Rpb24gb3IgYXNzZXJ0aW9uIGlzIGF3YWl0ZWQgaWY6XG4gICAgLy8gYSlzb21lb25lIHVzZWQgYGF3YWl0YCBzbyBQcm9taXNlJ3MgYHRoZW5gIGZ1bmN0aW9uIGV4ZWN1dGVkXG4gICAgLy8gYilQcm9taXNlIGNoYWluZWQgYnkgdXNpbmcgb25lIG9mIHRoZSBtaXhlZC1pbiBjb250cm9sbGVyIG1ldGhvZHNcbiAgICAvL1xuICAgIC8vIEluIGJvdGggc2NlbmFyaW9zLCB3ZSBjaGVjayB0aGF0IGNhbGxzaXRlIHRoYXQgcHJvZHVjZWQgUHJvbWlzZSBpcyBlcXVhbCB0byB0aGUgb25lXG4gICAgLy8gdGhhdCBpcyBjdXJyZW50bHkgbWlzc2luZyBhd2FpdC4gVGhpcyBpcyByZXF1aXJlZCB0byB3b3JrYXJvdW5kIHNjZW5hcmlvcyBsaWtlIHRoaXM6XG4gICAgLy9cbiAgICAvLyB2YXIgdDIgPSB0LmNsaWNrKCcjYnRuMScpOyAvLyA8LS0gc3RvcmVzIG5ldyBjYWxsc2l0ZVdpdGhvdXRBd2FpdFxuICAgIC8vIGF3YWl0IHQyOyAgICAgICAgICAgICAgICAgIC8vIDwtLSBjYWxsc2l0ZVdpdGhvdXRBd2FpdCA9IG51bGxcbiAgICAvLyB0LmNsaWNrKCcjYnRuMicpOyAgICAgICAgICAvLyA8LS0gc3RvcmVzIG5ldyBjYWxsc2l0ZVdpdGhvdXRBd2FpdFxuICAgIC8vIGF3YWl0IHQyLmNsaWNrKCcjYnRuMycpOyAgIC8vIDwtLSB3aXRob3V0IGNoZWNrIGl0IHdpbGwgc2V0IGNhbGxzaXRlV2l0aG91dEF3YWl0ID0gbnVsbCwgc28gd2Ugd2lsbCBsb3N0IHRyYWNraW5nXG4gICAgX2NyZWF0ZUV4dGVuZGVkUHJvbWlzZSAocHJvbWlzZSwgY2FsbHNpdGUpIHtcbiAgICAgICAgY29uc3QgZXh0ZW5kZWRQcm9taXNlICAgICA9IHByb21pc2UudGhlbihpZGVudGl0eSk7XG4gICAgICAgIGNvbnN0IG1hcmtDYWxsc2l0ZUF3YWl0ZWQgPSAoKSA9PiB0aGlzLmNhbGxzaXRlc1dpdGhvdXRBd2FpdC5kZWxldGUoY2FsbHNpdGUpO1xuXG4gICAgICAgIGV4dGVuZGVkUHJvbWlzZS50aGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgbWFya0NhbGxzaXRlQXdhaXRlZCgpO1xuXG4gICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxUaGVuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgZGVsZWdhdGVBUEkoZXh0ZW5kZWRQcm9taXNlLCBUZXN0Q29udHJvbGxlci5BUElfTElTVCwge1xuICAgICAgICAgICAgaGFuZGxlcjogICAgIHRoaXMsXG4gICAgICAgICAgICBwcm94eU1ldGhvZDogbWFya0NhbGxzaXRlQXdhaXRlZFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gZXh0ZW5kZWRQcm9taXNlO1xuICAgIH1cblxuICAgIF9lbnF1ZXVlVGFzayAoYXBpTWV0aG9kTmFtZSwgY3JlYXRlVGFza0V4ZWN1dG9yKSB7XG4gICAgICAgIGNvbnN0IGNhbGxzaXRlID0gZ2V0Q2FsbHNpdGVGb3JNZXRob2QoYXBpTWV0aG9kTmFtZSk7XG4gICAgICAgIGNvbnN0IGV4ZWN1dG9yID0gY3JlYXRlVGFza0V4ZWN1dG9yKGNhbGxzaXRlKTtcblxuICAgICAgICB0aGlzLmV4ZWN1dGlvbkNoYWluLnRoZW4gPSBvcmlnaW5hbFRoZW47XG4gICAgICAgIHRoaXMuZXhlY3V0aW9uQ2hhaW4gICAgICA9IHRoaXMuZXhlY3V0aW9uQ2hhaW4udGhlbihleGVjdXRvcik7XG5cbiAgICAgICAgdGhpcy5jYWxsc2l0ZXNXaXRob3V0QXdhaXQuYWRkKGNhbGxzaXRlKTtcblxuICAgICAgICB0aGlzLmV4ZWN1dGlvbkNoYWluID0gdGhpcy5fY3JlYXRlRXh0ZW5kZWRQcm9taXNlKHRoaXMuZXhlY3V0aW9uQ2hhaW4sIGNhbGxzaXRlKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5leGVjdXRpb25DaGFpbjtcbiAgICB9XG5cbiAgICBfZW5xdWV1ZUNvbW1hbmQgKGFwaU1ldGhvZE5hbWUsIENtZEN0b3IsIGNtZEFyZ3MpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVUYXNrKGFwaU1ldGhvZE5hbWUsIGNhbGxzaXRlID0+IHtcbiAgICAgICAgICAgIGxldCBjb21tYW5kID0gbnVsbDtcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb21tYW5kID0gbmV3IENtZEN0b3IoY21kQXJncywgdGhpcy50ZXN0UnVuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBlcnIuY2FsbHNpdGUgPSBjYWxsc2l0ZTtcbiAgICAgICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiAoKSA9PiB0aGlzLnRlc3RSdW4uZXhlY3V0ZUNvbW1hbmQoY29tbWFuZCwgY2FsbHNpdGUpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBBUEkgaW1wbGVtZW50YXRpb25cbiAgICAvLyBXZSBuZWVkIGltcGxlbWVudGF0aW9uIG1ldGhvZHMgdG8gb2J0YWluIGNvcnJlY3QgY2FsbHNpdGVzLiBJZiB3ZSB1c2UgcGxhaW4gQVBJXG4gICAgLy8gbWV0aG9kcyBpbiBjaGFpbmVkIHdyYXBwZXJzIHRoZW4gd2Ugd2lsbCBoYXZlIGNhbGxzaXRlIGZvciB0aGUgd3JhcHBlZCBtZXRob2RcbiAgICAvLyBpbiB0aGlzIGZpbGUgaW5zdGVhZCBvZiBjaGFpbmVkIG1ldGhvZCBjYWxsc2l0ZSBpbiB1c2VyIGNvZGUuXG4gICAgX2N0eCRnZXR0ZXIgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50ZXN0UnVuLmN0eDtcbiAgICB9XG5cbiAgICBfY3R4JHNldHRlciAodmFsKSB7XG4gICAgICAgIHRoaXMudGVzdFJ1bi5jdHggPSB2YWw7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdFJ1bi5jdHg7XG4gICAgfVxuXG4gICAgX2ZpeHR1cmVDdHgkZ2V0dGVyICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdFJ1bi5maXh0dXJlQ3R4O1xuICAgIH1cblxuICAgIF9jbGljayQgKHNlbGVjdG9yLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnY2xpY2snLCBDbGlja0NvbW1hbmQsIHsgc2VsZWN0b3IsIG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgX3JpZ2h0Q2xpY2skIChzZWxlY3Rvciwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3JpZ2h0Q2xpY2snLCBSaWdodENsaWNrQ29tbWFuZCwgeyBzZWxlY3Rvciwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBfZG91YmxlQ2xpY2skIChzZWxlY3Rvciwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ2RvdWJsZUNsaWNrJywgRG91YmxlQ2xpY2tDb21tYW5kLCB7IHNlbGVjdG9yLCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIF9ob3ZlciQgKHNlbGVjdG9yLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnaG92ZXInLCBIb3ZlckNvbW1hbmQsIHsgc2VsZWN0b3IsIG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgX2RyYWckIChzZWxlY3RvciwgZHJhZ09mZnNldFgsIGRyYWdPZmZzZXRZLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnZHJhZycsIERyYWdDb21tYW5kLCB7IHNlbGVjdG9yLCBkcmFnT2Zmc2V0WCwgZHJhZ09mZnNldFksIG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgX2RyYWdUb0VsZW1lbnQkIChzZWxlY3RvciwgZGVzdGluYXRpb25TZWxlY3Rvciwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ2RyYWdUb0VsZW1lbnQnLCBEcmFnVG9FbGVtZW50Q29tbWFuZCwgeyBzZWxlY3RvciwgZGVzdGluYXRpb25TZWxlY3Rvciwgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBfdHlwZVRleHQkIChzZWxlY3RvciwgdGV4dCwgb3B0aW9ucykge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3R5cGVUZXh0JywgVHlwZVRleHRDb21tYW5kLCB7IHNlbGVjdG9yLCB0ZXh0LCBvcHRpb25zIH0pO1xuICAgIH1cblxuICAgIF9zZWxlY3RUZXh0JCAoc2VsZWN0b3IsIHN0YXJ0UG9zLCBlbmRQb3MsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdzZWxlY3RUZXh0JywgU2VsZWN0VGV4dENvbW1hbmQsIHsgc2VsZWN0b3IsIHN0YXJ0UG9zLCBlbmRQb3MsIG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgX3NlbGVjdFRleHRBcmVhQ29udGVudCQgKHNlbGVjdG9yLCBzdGFydExpbmUsIHN0YXJ0UG9zLCBlbmRMaW5lLCBlbmRQb3MsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdzZWxlY3RUZXh0QXJlYUNvbnRlbnQnLCBTZWxlY3RUZXh0QXJlYUNvbnRlbnRDb21tYW5kLCB7XG4gICAgICAgICAgICBzZWxlY3RvcixcbiAgICAgICAgICAgIHN0YXJ0TGluZSxcbiAgICAgICAgICAgIHN0YXJ0UG9zLFxuICAgICAgICAgICAgZW5kTGluZSxcbiAgICAgICAgICAgIGVuZFBvcyxcbiAgICAgICAgICAgIG9wdGlvbnNcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX3NlbGVjdEVkaXRhYmxlQ29udGVudCQgKHN0YXJ0U2VsZWN0b3IsIGVuZFNlbGVjdG9yLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnc2VsZWN0RWRpdGFibGVDb250ZW50JywgU2VsZWN0RWRpdGFibGVDb250ZW50Q29tbWFuZCwge1xuICAgICAgICAgICAgc3RhcnRTZWxlY3RvcixcbiAgICAgICAgICAgIGVuZFNlbGVjdG9yLFxuICAgICAgICAgICAgb3B0aW9uc1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfcHJlc3NLZXkkIChrZXlzLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgncHJlc3NLZXknLCBQcmVzc0tleUNvbW1hbmQsIHsga2V5cywgb3B0aW9ucyB9KTtcbiAgICB9XG5cbiAgICBfd2FpdCQgKHRpbWVvdXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCd3YWl0JywgV2FpdENvbW1hbmQsIHsgdGltZW91dCB9KTtcbiAgICB9XG5cbiAgICBfbmF2aWdhdGVUbyQgKHVybCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ25hdmlnYXRlVG8nLCBOYXZpZ2F0ZVRvQ29tbWFuZCwgeyB1cmwgfSk7XG4gICAgfVxuXG4gICAgX3NldEZpbGVzVG9VcGxvYWQkIChzZWxlY3RvciwgZmlsZVBhdGgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdzZXRGaWxlc1RvVXBsb2FkJywgU2V0RmlsZXNUb1VwbG9hZENvbW1hbmQsIHsgc2VsZWN0b3IsIGZpbGVQYXRoIH0pO1xuICAgIH1cblxuICAgIF9jbGVhclVwbG9hZCQgKHNlbGVjdG9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnY2xlYXJVcGxvYWQnLCBDbGVhclVwbG9hZENvbW1hbmQsIHsgc2VsZWN0b3IgfSk7XG4gICAgfVxuXG4gICAgX3Rha2VTY3JlZW5zaG90JCAocGF0aCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3Rha2VTY3JlZW5zaG90JywgVGFrZVNjcmVlbnNob3RDb21tYW5kLCB7IHBhdGggfSk7XG4gICAgfVxuXG4gICAgX3Rha2VFbGVtZW50U2NyZWVuc2hvdCQgKHNlbGVjdG9yLCAuLi5hcmdzKSB7XG4gICAgICAgIGNvbnN0IGNvbW1hbmRBcmdzID0geyBzZWxlY3RvciB9O1xuXG4gICAgICAgIGlmIChhcmdzWzFdKSB7XG4gICAgICAgICAgICBjb21tYW5kQXJncy5wYXRoICAgID0gYXJnc1swXTtcbiAgICAgICAgICAgIGNvbW1hbmRBcmdzLm9wdGlvbnMgPSBhcmdzWzFdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiBhcmdzWzBdID09PSAnb2JqZWN0JylcbiAgICAgICAgICAgIGNvbW1hbmRBcmdzLm9wdGlvbnMgPSBhcmdzWzBdO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgICBjb21tYW5kQXJncy5wYXRoID0gYXJnc1swXTtcblxuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3Rha2VFbGVtZW50U2NyZWVuc2hvdCcsIFRha2VFbGVtZW50U2NyZWVuc2hvdENvbW1hbmQsIGNvbW1hbmRBcmdzKTtcbiAgICB9XG5cbiAgICBfcmVzaXplV2luZG93JCAod2lkdGgsIGhlaWdodCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3Jlc2l6ZVdpbmRvdycsIFJlc2l6ZVdpbmRvd0NvbW1hbmQsIHsgd2lkdGgsIGhlaWdodCB9KTtcbiAgICB9XG5cbiAgICBfcmVzaXplV2luZG93VG9GaXREZXZpY2UkIChkZXZpY2UsIG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCdyZXNpemVXaW5kb3dUb0ZpdERldmljZScsIFJlc2l6ZVdpbmRvd1RvRml0RGV2aWNlQ29tbWFuZCwgeyBkZXZpY2UsIG9wdGlvbnMgfSk7XG4gICAgfVxuXG4gICAgX21heGltaXplV2luZG93JCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnbWF4aW1pemVXaW5kb3cnLCBNYXhpbWl6ZVdpbmRvd0NvbW1hbmQpO1xuICAgIH1cblxuICAgIF9zd2l0Y2hUb0lmcmFtZSQgKHNlbGVjdG9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnc3dpdGNoVG9JZnJhbWUnLCBTd2l0Y2hUb0lmcmFtZUNvbW1hbmQsIHsgc2VsZWN0b3IgfSk7XG4gICAgfVxuXG4gICAgX3N3aXRjaFRvTWFpbldpbmRvdyQgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3N3aXRjaFRvTWFpbldpbmRvdycsIFN3aXRjaFRvTWFpbldpbmRvd0NvbW1hbmQpO1xuICAgIH1cblxuICAgIF9ldmFsJCAoZm4sIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCFpc051bGxPclVuZGVmaW5lZChvcHRpb25zKSlcbiAgICAgICAgICAgIG9wdGlvbnMgPSBhc3NpZ24oe30sIG9wdGlvbnMsIHsgYm91bmRUZXN0UnVuOiB0aGlzIH0pO1xuXG4gICAgICAgIGNvbnN0IGJ1aWxkZXIgID0gbmV3IENsaWVudEZ1bmN0aW9uQnVpbGRlcihmbiwgb3B0aW9ucywgeyBpbnN0YW50aWF0aW9uOiAnZXZhbCcsIGV4ZWN1dGlvbjogJ2V2YWwnIH0pO1xuICAgICAgICBjb25zdCBjbGllbnRGbiA9IGJ1aWxkZXIuZ2V0RnVuY3Rpb24oKTtcblxuICAgICAgICByZXR1cm4gY2xpZW50Rm4oKTtcbiAgICB9XG5cbiAgICBfc2V0TmF0aXZlRGlhbG9nSGFuZGxlciQgKGZuLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnc2V0TmF0aXZlRGlhbG9nSGFuZGxlcicsIFNldE5hdGl2ZURpYWxvZ0hhbmRsZXJDb21tYW5kLCB7XG4gICAgICAgICAgICBkaWFsb2dIYW5kbGVyOiB7IGZuLCBvcHRpb25zIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX2dldE5hdGl2ZURpYWxvZ0hpc3RvcnkkICgpIHtcbiAgICAgICAgY29uc3QgY2FsbHNpdGUgPSBnZXRDYWxsc2l0ZUZvck1ldGhvZCgnZ2V0TmF0aXZlRGlhbG9nSGlzdG9yeScpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLnRlc3RSdW4uZXhlY3V0ZUNvbW1hbmQobmV3IEdldE5hdGl2ZURpYWxvZ0hpc3RvcnlDb21tYW5kKCksIGNhbGxzaXRlKTtcbiAgICB9XG5cbiAgICBfZ2V0QnJvd3NlckNvbnNvbGVNZXNzYWdlcyQgKCkge1xuICAgICAgICBjb25zdCBjYWxsc2l0ZSA9IGdldENhbGxzaXRlRm9yTWV0aG9kKCdnZXRCcm93c2VyQ29uc29sZU1lc3NhZ2VzJyk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMudGVzdFJ1bi5leGVjdXRlQ29tbWFuZChuZXcgR2V0QnJvd3NlckNvbnNvbGVNZXNzYWdlc0NvbW1hbmQoKSwgY2FsbHNpdGUpO1xuICAgIH1cblxuICAgIF9leHBlY3QkIChhY3R1YWwpIHtcbiAgICAgICAgY29uc3QgY2FsbHNpdGUgPSBnZXRDYWxsc2l0ZUZvck1ldGhvZCgnZXhwZWN0Jyk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBBc3NlcnRpb24oYWN0dWFsLCB0aGlzLCBjYWxsc2l0ZSk7XG4gICAgfVxuXG4gICAgX2RlYnVnJCAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnZGVidWcnLCBEZWJ1Z0NvbW1hbmQpO1xuICAgIH1cblxuICAgIF9zZXRUZXN0U3BlZWQkIChzcGVlZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZW5xdWV1ZUNvbW1hbmQoJ3NldFRlc3RTcGVlZCcsIFNldFRlc3RTcGVlZENvbW1hbmQsIHsgc3BlZWQgfSk7XG4gICAgfVxuXG4gICAgX3NldFBhZ2VMb2FkVGltZW91dCQgKGR1cmF0aW9uKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlQ29tbWFuZCgnc2V0UGFnZUxvYWRUaW1lb3V0JywgU2V0UGFnZUxvYWRUaW1lb3V0Q29tbWFuZCwgeyBkdXJhdGlvbiB9KTtcbiAgICB9XG5cbiAgICBfdXNlUm9sZSQgKHJvbGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVDb21tYW5kKCd1c2VSb2xlJywgVXNlUm9sZUNvbW1hbmQsIHsgcm9sZSB9KTtcbiAgICB9XG5cbiAgICBfYWRkUmVxdWVzdEhvb2tzJCAoLi4uaG9va3MpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2VucXVldWVUYXNrKCdhZGRSZXF1ZXN0SG9va3MnLCAoKSA9PiB7XG4gICAgICAgICAgICBob29rcyA9IGZsYXR0ZW4oaG9va3MpO1xuXG4gICAgICAgICAgICBhc3NlcnRSZXF1ZXN0SG9va1R5cGUoaG9va3MpO1xuXG4gICAgICAgICAgICBob29rcy5mb3JFYWNoKGhvb2sgPT4gdGhpcy50ZXN0UnVuLmFkZFJlcXVlc3RIb29rKGhvb2spKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgX3JlbW92ZVJlcXVlc3RIb29rcyQgKC4uLmhvb2tzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbnF1ZXVlVGFzaygncmVtb3ZlUmVxdWVzdEhvb2tzJywgKCkgPT4ge1xuICAgICAgICAgICAgaG9va3MgPSBmbGF0dGVuKGhvb2tzKTtcblxuICAgICAgICAgICAgYXNzZXJ0UmVxdWVzdEhvb2tUeXBlKGhvb2tzKTtcblxuICAgICAgICAgICAgaG9va3MuZm9yRWFjaChob29rID0+IHRoaXMudGVzdFJ1bi5yZW1vdmVSZXF1ZXN0SG9vayhob29rKSk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cblxuVGVzdENvbnRyb2xsZXIuQVBJX0xJU1QgPSBnZXREZWxlZ2F0ZWRBUElMaXN0KFRlc3RDb250cm9sbGVyLnByb3RvdHlwZSk7XG5cbmRlbGVnYXRlQVBJKFRlc3RDb250cm9sbGVyLnByb3RvdHlwZSwgVGVzdENvbnRyb2xsZXIuQVBJX0xJU1QsIHsgdXNlQ3VycmVudEN0eEFzSGFuZGxlcjogdHJ1ZSB9KTtcbiJdfQ==