461 lines
80 KiB
JavaScript
461 lines
80 KiB
JavaScript
|
"use strict";
|
||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||
|
};
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
// TODO: Fix https://github.com/DevExpress/testcafe/issues/4139 to get rid of Pinkie
|
||
|
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 add_rendered_warning_1 = __importDefault(require("../../notifications/add-rendered-warning"));
|
||
|
const deprecated_1 = require("../../notifications/deprecated");
|
||
|
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 execution_context_1 = require("./execution-context");
|
||
|
const types_1 = require("../../client-functions/types");
|
||
|
const test_run_proxy_1 = __importDefault(require("../../services/compiler/test-run-proxy"));
|
||
|
const test_run_1 = require("../../errors/test-run");
|
||
|
const assertion_2 = require("../../test-run/commands/assertion");
|
||
|
const callsite_1 = require("../../utils/callsite");
|
||
|
const re_executable_promise_1 = __importDefault(require("../../utils/re-executable-promise"));
|
||
|
const send_1 = require("../../test-run/request/send");
|
||
|
const runtime_1 = require("../../errors/runtime");
|
||
|
const types_2 = require("../../errors/types");
|
||
|
const custom_actions_1 = __importDefault(require("./custom-actions"));
|
||
|
const delegated_api_2 = __importDefault(require("./delegated-api"));
|
||
|
const originalThen = pinkie_1.default.resolve().then;
|
||
|
let inDebug = false;
|
||
|
class TestController {
|
||
|
constructor(testRun) {
|
||
|
var _a;
|
||
|
this._executionContext = null;
|
||
|
this.testRun = testRun;
|
||
|
this.executionChain = pinkie_1.default.resolve();
|
||
|
this.warningLog = testRun.warningLog;
|
||
|
this._customActions = new custom_actions_1.default(this, (_a = testRun === null || testRun === void 0 ? void 0 : testRun.opts) === null || _a === void 0 ? void 0 : _a.customActions);
|
||
|
this._addTestControllerToExecutionChain();
|
||
|
}
|
||
|
_addTestControllerToExecutionChain() {
|
||
|
this.executionChain._testController = this;
|
||
|
}
|
||
|
// NOTE: TestCafe executes actions and assertions asynchronously in the following cases:
|
||
|
// a) The `await` keyword that proceeds the method declaration triggers the `then` function of a Promise.
|
||
|
// b) The action is chained to another `awaited` method.
|
||
|
//
|
||
|
// In order to track missing `await` statements, TestCafe exposes a special Promise to the user.
|
||
|
// When TestCafe detects a missing `await` statement, it compares the method's callsite to the call site of the exposed Promise.
|
||
|
// This workaround is necessary for situations like these:
|
||
|
//
|
||
|
// 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 observedCallsites = this.testRun.observedCallsites;
|
||
|
const markCallsiteAwaited = () => observedCallsites.callsitesWithoutAwait.delete(callsite);
|
||
|
extendedPromise.then = function () {
|
||
|
markCallsiteAwaited();
|
||
|
return originalThen.apply(this, arguments);
|
||
|
};
|
||
|
(0, delegated_api_1.delegateAPI)(extendedPromise, TestController.API_LIST, {
|
||
|
handler: this,
|
||
|
proxyMethod: markCallsiteAwaited,
|
||
|
});
|
||
|
return extendedPromise;
|
||
|
}
|
||
|
_createCommand(CmdCtor, cmdArgs, callsite) {
|
||
|
try {
|
||
|
return new CmdCtor(cmdArgs, this.testRun);
|
||
|
}
|
||
|
catch (err) {
|
||
|
err.callsite = callsite;
|
||
|
throw err;
|
||
|
}
|
||
|
}
|
||
|
_enqueueTask(apiMethodName, createTaskExecutor, callsite) {
|
||
|
const executor = createTaskExecutor();
|
||
|
this.executionChain.then = originalThen;
|
||
|
this.executionChain = this.executionChain.then(executor);
|
||
|
this.testRun.observedCallsites.callsitesWithoutAwait.add(callsite);
|
||
|
this.executionChain = this._createExtendedPromise(this.executionChain, callsite);
|
||
|
this._addTestControllerToExecutionChain();
|
||
|
return this.executionChain;
|
||
|
}
|
||
|
enqueueCommand(CmdCtor, cmdArgs, validateCommandFn, callsite) {
|
||
|
callsite = callsite || (0, get_callsite_1.getCallsiteForMethod)(CmdCtor.methodName);
|
||
|
const command = this._createCommand(CmdCtor, cmdArgs, callsite);
|
||
|
if (typeof validateCommandFn === 'function')
|
||
|
validateCommandFn(this, command, callsite);
|
||
|
return this._enqueueTask(command.methodName, () => {
|
||
|
return () => {
|
||
|
return this.testRun.executeCommand(command, callsite)
|
||
|
.catch(err => {
|
||
|
this.executionChain = pinkie_1.default.resolve();
|
||
|
throw err;
|
||
|
});
|
||
|
};
|
||
|
}, callsite);
|
||
|
}
|
||
|
_validateMultipleWindowCommand(apiMethodName) {
|
||
|
const { disableMultipleWindows, activeWindowId } = this.testRun;
|
||
|
if (disableMultipleWindows)
|
||
|
throw new test_run_1.MultipleWindowsModeIsDisabledError(apiMethodName);
|
||
|
if (!activeWindowId)
|
||
|
throw new test_run_1.MultipleWindowsModeIsNotAvailableInRemoteBrowserError(apiMethodName);
|
||
|
}
|
||
|
getExecutionContext() {
|
||
|
if (!this._executionContext)
|
||
|
this._executionContext = (0, execution_context_1.createExecutionContext)(this.testRun);
|
||
|
return this._executionContext;
|
||
|
}
|
||
|
// 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;
|
||
|
}
|
||
|
_browser$getter() {
|
||
|
return this.testRun.browser;
|
||
|
}
|
||
|
_customActions$getter() {
|
||
|
return this._customActions || new custom_actions_1.default(this, this.testRun.opts.customActions);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.DispatchEventCommand.methodName)](selector, eventName, options = {}) {
|
||
|
return this.enqueueCommand(actions_1.DispatchEventCommand, { selector, eventName, options, relatedTarget: options.relatedTarget });
|
||
|
}
|
||
|
_prepareCookieArguments(args, isSetCommand = false) {
|
||
|
const urlsArg = (0, lodash_1.castArray)(args[1]);
|
||
|
const urls = Array.isArray(urlsArg) && typeof urlsArg[0] === 'string' ? urlsArg : [];
|
||
|
const cookiesArg = urls.length ? args[0] : args;
|
||
|
const cookies = [];
|
||
|
(0, lodash_1.flattenDeep)((0, lodash_1.castArray)(cookiesArg)).forEach(cookie => {
|
||
|
if (isSetCommand && !cookie.name && typeof cookie === 'object')
|
||
|
Object.entries(cookie).forEach(([name, value]) => cookies.push({ name, value }));
|
||
|
else if (!isSetCommand && typeof cookie === 'string')
|
||
|
cookies.push({ name: cookie });
|
||
|
else
|
||
|
cookies.push(cookie);
|
||
|
});
|
||
|
return { urls, cookies };
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.GetCookiesCommand.methodName)](...args) {
|
||
|
return this.enqueueCommand(actions_1.GetCookiesCommand, this._prepareCookieArguments(args));
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SetCookiesCommand.methodName)](...args) {
|
||
|
const { urls, cookies } = this._prepareCookieArguments(args, true);
|
||
|
return this.enqueueCommand(actions_1.SetCookiesCommand, { cookies, url: urls[0] });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.DeleteCookiesCommand.methodName)](...args) {
|
||
|
return this.enqueueCommand(actions_1.DeleteCookiesCommand, this._prepareCookieArguments(args));
|
||
|
}
|
||
|
_prepareRequestArguments(bindOptions, ...args) {
|
||
|
const [url, options] = typeof args[0] === 'object' ? [args[0].url, args[0]] : args;
|
||
|
return {
|
||
|
url,
|
||
|
options: Object.assign({}, options, bindOptions),
|
||
|
};
|
||
|
}
|
||
|
_createRequestFunction(bindOptions = {}) {
|
||
|
const controller = this;
|
||
|
const callsite = (0, get_callsite_1.getCallsiteForMethod)(actions_1.RequestCommand.methodName);
|
||
|
if (!controller.testRun || controller.testRun instanceof test_run_proxy_1.default)
|
||
|
throw new runtime_1.RequestRuntimeError(callsite, types_2.RUNTIME_ERRORS.requestCannotResolveTestRun);
|
||
|
return function (...args) {
|
||
|
const cmdArgs = controller._prepareRequestArguments(bindOptions, ...args);
|
||
|
const command = controller._createCommand(actions_1.RequestCommand, cmdArgs, callsite);
|
||
|
const options = Object.assign(Object.assign({}, command.options), { url: command.url || command.options.url || '' });
|
||
|
const promise = re_executable_promise_1.default.fromFn(async () => {
|
||
|
return (0, send_1.sendRequestThroughAPI)(controller.testRun, options, callsite);
|
||
|
});
|
||
|
actions_1.RequestCommand.resultGetters.forEach(getter => {
|
||
|
Object.defineProperty(promise, getter, {
|
||
|
get: () => re_executable_promise_1.default.fromFn(async () => {
|
||
|
const response = await (0, send_1.sendRequestThroughAPI)(controller.testRun, options, callsite);
|
||
|
return response[getter];
|
||
|
}),
|
||
|
});
|
||
|
});
|
||
|
return promise;
|
||
|
};
|
||
|
}
|
||
|
_decorateRequestFunction(fn) {
|
||
|
actions_1.RequestCommand.extendedMethods.forEach(method => {
|
||
|
Object.defineProperty(fn, method, {
|
||
|
value: this._createRequestFunction({ method }),
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.RequestCommand.methodName, 'getter')]() {
|
||
|
const fn = this._createRequestFunction();
|
||
|
this._decorateRequestFunction(fn);
|
||
|
return fn;
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.ClickCommand.methodName)](selector, options) {
|
||
|
return this.enqueueCommand(actions_1.ClickCommand, { selector, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.RightClickCommand.methodName)](selector, options) {
|
||
|
return this.enqueueCommand(actions_1.RightClickCommand, { selector, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.DoubleClickCommand.methodName)](selector, options) {
|
||
|
return this.enqueueCommand(actions_1.DoubleClickCommand, { selector, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.HoverCommand.methodName)](selector, options) {
|
||
|
return this.enqueueCommand(actions_1.HoverCommand, { selector, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.DragCommand.methodName)](selector, dragOffsetX, dragOffsetY, options) {
|
||
|
return this.enqueueCommand(actions_1.DragCommand, { selector, dragOffsetX, dragOffsetY, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.DragToElementCommand.methodName)](selector, destinationSelector, options) {
|
||
|
return this.enqueueCommand(actions_1.DragToElementCommand, { selector, destinationSelector, options });
|
||
|
}
|
||
|
_getSelectorForScroll(args) {
|
||
|
const selector = typeof args[0] === 'string' || (0, types_1.isSelector)(args[0]) ? args[0] : null;
|
||
|
if (selector)
|
||
|
args.shift();
|
||
|
else
|
||
|
// NOTE: here we use document.scrollingElement for old Safari versions
|
||
|
// document.documentElement does not work as expected on Mojave Safari 12.1/ High Sierra Safari 11.1
|
||
|
// eslint-disable-next-line no-undef
|
||
|
return () => document.scrollingElement || document.documentElement;
|
||
|
return selector;
|
||
|
}
|
||
|
_getPosition(args) {
|
||
|
const position = args.length === 1 && typeof args[0] === 'string' ? args[0] : null;
|
||
|
if (position)
|
||
|
args.shift();
|
||
|
return position;
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.ScrollCommand.methodName)](...args) {
|
||
|
let position = this._getPosition(args);
|
||
|
const selector = this._getSelectorForScroll(args);
|
||
|
let x = void 0;
|
||
|
let y = void 0;
|
||
|
let options = void 0;
|
||
|
if (typeof args[0] === 'string')
|
||
|
[position, options] = args;
|
||
|
if (typeof args[0] === 'number')
|
||
|
[x, y, options] = args;
|
||
|
return this.enqueueCommand(actions_1.ScrollCommand, { selector, x, y, position, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.ScrollByCommand.methodName)](...args) {
|
||
|
const selector = this._getSelectorForScroll(args);
|
||
|
const [byX, byY, options] = args;
|
||
|
return this.enqueueCommand(actions_1.ScrollByCommand, { selector, byX, byY, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.ScrollIntoViewCommand.methodName)](selector, options) {
|
||
|
return this.enqueueCommand(actions_1.ScrollIntoViewCommand, { selector, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.TypeTextCommand.methodName)](selector, text, options) {
|
||
|
return this.enqueueCommand(actions_1.TypeTextCommand, { selector, text, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SelectTextCommand.methodName)](selector, startPos, endPos, options) {
|
||
|
return this.enqueueCommand(actions_1.SelectTextCommand, { selector, startPos, endPos, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SelectTextAreaContentCommand.methodName)](selector, startLine, startPos, endLine, endPos, options) {
|
||
|
return this.enqueueCommand(actions_1.SelectTextAreaContentCommand, {
|
||
|
selector,
|
||
|
startLine,
|
||
|
startPos,
|
||
|
endLine,
|
||
|
endPos,
|
||
|
options,
|
||
|
});
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SelectEditableContentCommand.methodName)](startSelector, endSelector, options) {
|
||
|
return this.enqueueCommand(actions_1.SelectEditableContentCommand, {
|
||
|
startSelector,
|
||
|
endSelector,
|
||
|
options,
|
||
|
});
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.PressKeyCommand.methodName)](keys, options) {
|
||
|
return this.enqueueCommand(actions_1.PressKeyCommand, { keys, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(observation_1.WaitCommand.methodName)](timeout) {
|
||
|
return this.enqueueCommand(observation_1.WaitCommand, { timeout });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.NavigateToCommand.methodName)](url) {
|
||
|
return this.enqueueCommand(actions_1.NavigateToCommand, { url });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SetFilesToUploadCommand.methodName)](selector, filePath) {
|
||
|
return this.enqueueCommand(actions_1.SetFilesToUploadCommand, { selector, filePath });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.ClearUploadCommand.methodName)](selector) {
|
||
|
return this.enqueueCommand(actions_1.ClearUploadCommand, { selector });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(browser_manipulation_1.TakeScreenshotCommand.methodName)](options) {
|
||
|
if (options && typeof options !== 'object')
|
||
|
options = { path: options };
|
||
|
return this.enqueueCommand(browser_manipulation_1.TakeScreenshotCommand, options);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(browser_manipulation_1.TakeElementScreenshotCommand.methodName)](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(browser_manipulation_1.TakeElementScreenshotCommand, commandArgs);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(browser_manipulation_1.ResizeWindowCommand.methodName)](width, height) {
|
||
|
return this.enqueueCommand(browser_manipulation_1.ResizeWindowCommand, { width, height });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(browser_manipulation_1.ResizeWindowToFitDeviceCommand.methodName)](device, options) {
|
||
|
return this.enqueueCommand(browser_manipulation_1.ResizeWindowToFitDeviceCommand, { device, options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(browser_manipulation_1.MaximizeWindowCommand.methodName)]() {
|
||
|
return this.enqueueCommand(browser_manipulation_1.MaximizeWindowCommand);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SwitchToIframeCommand.methodName)](selector) {
|
||
|
return this.enqueueCommand(actions_1.SwitchToIframeCommand, { selector });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SwitchToMainWindowCommand.methodName)]() {
|
||
|
return this.enqueueCommand(actions_1.SwitchToMainWindowCommand);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.OpenWindowCommand.methodName)](url) {
|
||
|
this._validateMultipleWindowCommand(actions_1.OpenWindowCommand.methodName);
|
||
|
return this.enqueueCommand(actions_1.OpenWindowCommand, { url });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.CloseWindowCommand.methodName)](window) {
|
||
|
const windowId = (window === null || window === void 0 ? void 0 : window.id) || null;
|
||
|
this._validateMultipleWindowCommand(actions_1.CloseWindowCommand.methodName);
|
||
|
return this.enqueueCommand(actions_1.CloseWindowCommand, { windowId });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.GetCurrentWindowCommand.methodName)]() {
|
||
|
this._validateMultipleWindowCommand(actions_1.GetCurrentWindowCommand.methodName);
|
||
|
return this.enqueueCommand(actions_1.GetCurrentWindowCommand);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SwitchToWindowCommand.methodName)](windowSelector) {
|
||
|
this._validateMultipleWindowCommand(actions_1.SwitchToWindowCommand.methodName);
|
||
|
let command;
|
||
|
let args;
|
||
|
if (typeof windowSelector === 'function') {
|
||
|
command = actions_1.SwitchToWindowByPredicateCommand;
|
||
|
args = { checkWindow: windowSelector };
|
||
|
}
|
||
|
else {
|
||
|
command = actions_1.SwitchToWindowCommand;
|
||
|
args = { windowId: windowSelector === null || windowSelector === void 0 ? void 0 : windowSelector.id };
|
||
|
}
|
||
|
return this.enqueueCommand(command, args);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SwitchToParentWindowCommand.methodName)]() {
|
||
|
this._validateMultipleWindowCommand(actions_1.SwitchToParentWindowCommand.methodName);
|
||
|
return this.enqueueCommand(actions_1.SwitchToParentWindowCommand);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SwitchToPreviousWindowCommand.methodName)]() {
|
||
|
this._validateMultipleWindowCommand(actions_1.SwitchToPreviousWindowCommand.methodName);
|
||
|
return this.enqueueCommand(actions_1.SwitchToPreviousWindowCommand);
|
||
|
}
|
||
|
_eval$(fn, options) {
|
||
|
if (!(0, lodash_1.isNil)(options))
|
||
|
options = (0, 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();
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SetNativeDialogHandlerCommand.methodName)](fn, options) {
|
||
|
return this.enqueueCommand(actions_1.SetNativeDialogHandlerCommand, {
|
||
|
dialogHandler: { fn, options },
|
||
|
});
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.GetNativeDialogHistoryCommand.methodName)]() {
|
||
|
const callsite = (0, get_callsite_1.getCallsiteForMethod)(actions_1.GetNativeDialogHistoryCommand.methodName);
|
||
|
const command = this._createCommand(actions_1.GetNativeDialogHistoryCommand, {}, callsite);
|
||
|
return this.testRun.executeCommand(command, callsite);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.GetBrowserConsoleMessagesCommand.methodName)]() {
|
||
|
const callsite = (0, get_callsite_1.getCallsiteForMethod)(actions_1.GetBrowserConsoleMessagesCommand.methodName);
|
||
|
const command = this._createCommand(actions_1.GetBrowserConsoleMessagesCommand, {}, callsite);
|
||
|
return this.testRun.executeCommand(command, callsite);
|
||
|
}
|
||
|
checkForExcessiveAwaits(checkedCallsite, { actionId }) {
|
||
|
const snapshotPropertyCallsites = this.testRun.observedCallsites.snapshotPropertyCallsites;
|
||
|
const callsiteId = (0, callsite_1.getCallsiteId)(checkedCallsite);
|
||
|
// NOTE: If there are unasserted callsites, we should add all of them to awaitedSnapshotWarnings.
|
||
|
// The warnings themselves are raised after the test run in wrap-test-function
|
||
|
if (snapshotPropertyCallsites[callsiteId] && !snapshotPropertyCallsites[callsiteId].checked) {
|
||
|
for (const propertyCallsite of snapshotPropertyCallsites[callsiteId].callsites)
|
||
|
this.testRun.observedCallsites.awaitedSnapshotWarnings.set((0, callsite_1.getCallsiteStackFrameString)(propertyCallsite), { callsite: propertyCallsite, actionId });
|
||
|
delete snapshotPropertyCallsites[callsiteId];
|
||
|
}
|
||
|
else
|
||
|
snapshotPropertyCallsites[callsiteId] = { callsites: [], checked: true };
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(assertion_2.AssertionCommand.methodName)](actual) {
|
||
|
const callsite = (0, get_callsite_1.getCallsiteForMethod)(assertion_2.AssertionCommand.methodName);
|
||
|
return new assertion_1.default(actual, this, callsite);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(observation_1.DebugCommand.methodName)]() {
|
||
|
// NOTE: do not need to enqueue the Debug command if we are in debugging mode.
|
||
|
// The Debug command will be executed by CDP.
|
||
|
// Also, we are forced to add empty function to the execution chain to preserve it.
|
||
|
return this.isCompilerServiceMode() ? this._enqueueTask(observation_1.DebugCommand.methodName, lodash_1.noop) : this.enqueueCommand(observation_1.DebugCommand);
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SetTestSpeedCommand.methodName)](speed) {
|
||
|
return this.enqueueCommand(actions_1.SetTestSpeedCommand, { speed });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SetPageLoadTimeoutCommand.methodName)](duration) {
|
||
|
return this.enqueueCommand(actions_1.SetPageLoadTimeoutCommand, { duration }, (testController, command) => {
|
||
|
(0, add_rendered_warning_1.default)(testController.warningLog, { message: (0, deprecated_1.getDeprecationMessage)(deprecated_1.DEPRECATED.setPageLoadTimeout), actionId: command.actionId });
|
||
|
});
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.UseRoleCommand.methodName)](role) {
|
||
|
return this.enqueueCommand(actions_1.UseRoleCommand, { role });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.SkipJsErrorsCommand.methodName)](options) {
|
||
|
return this.enqueueCommand(actions_1.SkipJsErrorsCommand, { options });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.AddRequestHooksCommand.methodName)](...hooks) {
|
||
|
hooks = (0, lodash_1.flattenDeep)(hooks);
|
||
|
return this.enqueueCommand(actions_1.AddRequestHooksCommand, { hooks });
|
||
|
}
|
||
|
[(0, delegated_api_2.default)(actions_1.RemoveRequestHooksCommand.methodName)](...hooks) {
|
||
|
hooks = (0, lodash_1.flattenDeep)(hooks);
|
||
|
return this.enqueueCommand(actions_1.RemoveRequestHooksCommand, { hooks });
|
||
|
}
|
||
|
static enableDebugForNonDebugCommands() {
|
||
|
inDebug = true;
|
||
|
}
|
||
|
static disableDebugForNonDebugCommands() {
|
||
|
inDebug = false;
|
||
|
}
|
||
|
shouldStop(command) {
|
||
|
// NOTE: should never stop in not compliler debugging mode
|
||
|
if (!this.isCompilerServiceMode())
|
||
|
return false;
|
||
|
// NOTE: should always stop on Debug command
|
||
|
if (command === 'debug')
|
||
|
return true;
|
||
|
// NOTE: should stop on other actions after the `Next Action` button is clicked
|
||
|
if (inDebug) {
|
||
|
inDebug = false;
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
isCompilerServiceMode() {
|
||
|
return this.testRun instanceof test_run_proxy_1.default;
|
||
|
}
|
||
|
}
|
||
|
exports.default = TestController;
|
||
|
TestController.API_LIST = (0, delegated_api_1.getDelegatedAPIList)(TestController.prototype);
|
||
|
(0, delegated_api_1.delegateAPI)(TestController.prototype, TestController.API_LIST, { useCurrentCtxAsHandler: true });
|
||
|
module.exports = exports.default;
|
||
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBpL3Rlc3QtY29udHJvbGxlci9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9GQUFvRjtBQUNwRixvREFBNkI7QUFDN0IsbUNBT2dCO0FBRWhCLDREQUFpRTtBQUNqRSw2R0FBbUY7QUFDbkYsNERBQW9DO0FBQ3BDLDZEQUE2RTtBQUM3RSxvR0FBa0U7QUFDbEUsK0RBQW1GO0FBRW5GLDZEQXlDeUM7QUFFekMsdUZBTXNEO0FBRXRELHFFQUFnRjtBQUNoRiwyREFBOEU7QUFDOUUsd0RBQTBEO0FBQzFELDRGQUFrRTtBQUVsRSxvREFHK0I7QUFFL0IsaUVBQXFFO0FBQ3JFLG1EQUFrRjtBQUNsRiw4RkFBb0U7QUFDcEUsc0RBQW1GO0FBQ25GLGtEQUEyRDtBQUMzRCw4Q0FBb0Q7QUFDcEQsc0VBQTZDO0FBQzdDLG9FQUEyQztBQUUzQyxNQUFNLFlBQVksR0FBRyxnQkFBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksQ0FBQztBQUU1QyxJQUFJLE9BQU8sR0FBRyxLQUFLLENBQUM7QUFFcEIsTUFBcUIsY0FBYztJQUMvQixZQUFhLE9BQU87O1FBQ2hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFFOUIsSUFBSSxDQUFDLE9BQU8sR0FBVSxPQUFPLENBQUM7UUFDOUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxnQkFBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxVQUFVLEdBQU8sT0FBTyxDQUFDLFVBQVUsQ0FBQztRQUN6QyxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksd0JBQWEsQ0FBQyxJQUFJLEVBQUUsTUFBQSxPQUFPLGFBQVAsT0FBTyx1QkFBUCxPQUFPLENBQUUsSUFBSSwwQ0FBRSxhQUFhLENBQUMsQ0FBQztRQUU1RSxJQUFJLENBQUMsa0NBQWtDLEVBQUUsQ0FBQztJQUM5QyxDQUFDO0lBRUQs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
|