6463 lines
318 KiB
JavaScript
6463 lines
318 KiB
JavaScript
window['%hammerhead%'].utils.removeInjectedScript();
|
|
|
|
// NOTE: We should have the capability to initialize scripts with different contexts.
|
|
// This is required for iframes without the src attribute because Hammerhead does not
|
|
// inject scripts into such iframes. So, we wrap all scripts in initialization functions.
|
|
(function () {
|
|
function initTestCafeClientDrivers(window, isIFrameWithoutSrc) {
|
|
var document = window.document;
|
|
|
|
(function (hammerhead, Promise$3, testcafeCore, testcafeAutomation, testCafeUI) {
|
|
var hammerhead__default = 'default' in hammerhead ? hammerhead['default'] : hammerhead;
|
|
Promise$3 = Promise$3 && Object.prototype.hasOwnProperty.call(Promise$3, 'default') ? Promise$3['default'] : Promise$3;
|
|
var testCafeUI__default = 'default' in testCafeUI ? testCafeUI['default'] : testCafeUI;
|
|
|
|
/******************************************************************************
|
|
Copyright (c) Microsoft Corporation.
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
purpose with or without fee is hereby granted.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
PERFORMANCE OF THIS SOFTWARE.
|
|
***************************************************************************** */
|
|
/* global Reflect, Promise */
|
|
var extendStatics = function (d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b)
|
|
if (Object.prototype.hasOwnProperty.call(b, p))
|
|
d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
};
|
|
function __extends(d, b) {
|
|
if (typeof b !== "function" && b !== null)
|
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
}
|
|
function __awaiter(thisArg, _arguments, P, generator) {
|
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
return new (P || (P = Promise$3))(function (resolve, reject) {
|
|
function fulfilled(value) { try {
|
|
step(generator.next(value));
|
|
}
|
|
catch (e) {
|
|
reject(e);
|
|
} }
|
|
function rejected(value) { try {
|
|
step(generator["throw"](value));
|
|
}
|
|
catch (e) {
|
|
reject(e);
|
|
} }
|
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
});
|
|
}
|
|
function __generator(thisArg, body) {
|
|
var _ = { label: 0, sent: function () { if (t[0] & 1)
|
|
throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
|
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
function step(op) {
|
|
if (f)
|
|
throw new TypeError("Generator is already executing.");
|
|
while (g && (g = 0, op[0] && (_ = 0)), _)
|
|
try {
|
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
|
|
return t;
|
|
if (y = 0, t)
|
|
op = [op[0] & 2, t.value];
|
|
switch (op[0]) {
|
|
case 0:
|
|
case 1:
|
|
t = op;
|
|
break;
|
|
case 4:
|
|
_.label++;
|
|
return { value: op[1], done: false };
|
|
case 5:
|
|
_.label++;
|
|
y = op[1];
|
|
op = [0];
|
|
continue;
|
|
case 7:
|
|
op = _.ops.pop();
|
|
_.trys.pop();
|
|
continue;
|
|
default:
|
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
_ = 0;
|
|
continue;
|
|
}
|
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
|
|
_.label = op[1];
|
|
break;
|
|
}
|
|
if (op[0] === 6 && _.label < t[1]) {
|
|
_.label = t[1];
|
|
t = op;
|
|
break;
|
|
}
|
|
if (t && _.label < t[2]) {
|
|
_.label = t[2];
|
|
_.ops.push(op);
|
|
break;
|
|
}
|
|
if (t[2])
|
|
_.ops.pop();
|
|
_.trys.pop();
|
|
continue;
|
|
}
|
|
op = body.call(thisArg, _);
|
|
}
|
|
catch (e) {
|
|
op = [6, e];
|
|
y = 0;
|
|
}
|
|
finally {
|
|
f = t = 0;
|
|
}
|
|
if (op[0] & 5)
|
|
throw op[1];
|
|
return { value: op[0] ? op[1] : void 0, done: true };
|
|
}
|
|
}
|
|
function __spreadArray(to, from, pack) {
|
|
if (pack || arguments.length === 2)
|
|
for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
if (ar || !(i in from)) {
|
|
if (!ar)
|
|
ar = Array.prototype.slice.call(from, 0, i);
|
|
ar[i] = from[i];
|
|
}
|
|
}
|
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// WARNING: this file is used by both the client and the server.
|
|
// Do not use any browser or node-specific API!
|
|
// -------------------------------------------------------------
|
|
var HEARTBEAT_TIMEOUT = 2 * 60 * 1000;
|
|
var CHECK_IFRAME_DRIVER_LINK_DELAY = 500;
|
|
var CHECK_CHILD_WINDOW_DRIVER_LINK_DELAY = 500;
|
|
var SEND_STATUS_REQUEST_TIME_LIMIT = 5000;
|
|
var SEND_STATUS_REQUEST_RETRY_DELAY = 300;
|
|
var SEND_STATUS_REQUEST_RETRY_COUNT = Math.floor(HEARTBEAT_TIMEOUT / SEND_STATUS_REQUEST_RETRY_DELAY - 1);
|
|
var CHECK_STATUS_RETRY_DELAY = 1000;
|
|
|
|
var ClientMessages;
|
|
(function (ClientMessages) {
|
|
ClientMessages["ready"] = "ready";
|
|
ClientMessages["readyForBrowserManipulation"] = "ready-for-browser-manipulation";
|
|
ClientMessages["waitForFileDownload"] = "wait-for-file-download";
|
|
})(ClientMessages || (ClientMessages = {}));
|
|
var TEST_RUN_MESSAGES = ClientMessages;
|
|
|
|
// -------------------------------------------------------------
|
|
// WARNING: this file is used by both the client and the server.
|
|
// Do not use any browser or node-specific API!
|
|
// -------------------------------------------------------------
|
|
var COMMAND_TYPE = {
|
|
dispatchEvent: 'dispatch-event',
|
|
click: 'click',
|
|
rightClick: 'right-click',
|
|
doubleClick: 'double-click',
|
|
drag: 'drag',
|
|
dragToElement: 'drag-to-element',
|
|
hover: 'hover',
|
|
scroll: 'scroll',
|
|
scrollBy: 'scroll-by',
|
|
scrollIntoView: 'scroll-into-view',
|
|
typeText: 'type-text',
|
|
selectText: 'select-text',
|
|
selectTextAreaContent: 'select-text-area-content',
|
|
selectEditableContent: 'select-editable-content',
|
|
pressKey: 'press-key',
|
|
wait: 'wait',
|
|
navigateTo: 'navigate-to',
|
|
setFilesToUpload: 'set-files-to-upload',
|
|
clearUpload: 'clear-upload',
|
|
executeClientFunction: 'execute-client-function',
|
|
executeSelector: 'execute-selector',
|
|
takeScreenshot: 'take-screenshot',
|
|
takeElementScreenshot: 'take-element-screenshot',
|
|
takeScreenshotOnFail: 'take-screenshot-on-fail',
|
|
prepareBrowserManipulation: 'prepare-browser-manipulation',
|
|
showAssertionRetriesStatus: 'show-assertion-retries-status',
|
|
hideAssertionRetriesStatus: 'hide-assertion-retries-status',
|
|
setBreakpoint: 'set-breakpoint',
|
|
resizeWindow: 'resize-window',
|
|
resizeWindowToFitDevice: 'resize-window-to-fit-device',
|
|
maximizeWindow: 'maximize-window',
|
|
switchToIframe: 'switch-to-iframe',
|
|
switchToMainWindow: 'switch-to-main-window',
|
|
openWindow: 'open-window',
|
|
closeWindow: 'close-window',
|
|
getCurrentWindow: 'get-current-window',
|
|
getCurrentWindows: 'get-current-windows',
|
|
switchToWindow: 'switch-to-window',
|
|
switchToWindowByPredicate: 'switch-to-window-by-predicate',
|
|
switchToParentWindow: 'switch-to-parent-window',
|
|
switchToPreviousWindow: 'switch-to-previous-window',
|
|
setNativeDialogHandler: 'set-native-dialog-handler',
|
|
getNativeDialogHistory: 'get-native-dialog-history',
|
|
getBrowserConsoleMessages: 'get-browser-console-messages',
|
|
getActiveElement: 'get-active-element',
|
|
setTestSpeed: 'set-test-speed',
|
|
setPageLoadTimeout: 'set-page-load-timeout',
|
|
debug: 'debug',
|
|
disableDebug: 'disable-debug',
|
|
assertion: 'assertion',
|
|
useRole: 'useRole',
|
|
testDone: 'test-done',
|
|
backupStorages: 'backup-storages',
|
|
executeExpression: 'execute-expression',
|
|
executeAsyncExpression: 'execute-async-expression',
|
|
unlockPage: 'unlock-page',
|
|
closeChildWindowOnFileDownloading: 'close-child-window-on-file-downloading',
|
|
recorder: 'recorder',
|
|
prepareClientEnvironmentInDebugMode: 'prepare-client-environment-in-debug-mode',
|
|
getCookies: 'get-cookies',
|
|
setCookies: 'set-cookies',
|
|
deleteCookies: 'delete-cookies',
|
|
getProxyUrl: 'get-proxy-url',
|
|
request: 'request',
|
|
skipJsErrors: 'skip-js-errors',
|
|
addRequestHooks: 'add-request-hooks',
|
|
removeRequestHooks: 'remove-request-hooks',
|
|
runCustomAction: 'run-custom-action',
|
|
};
|
|
|
|
// -------------------------------------------------------------
|
|
function isCommandRejectableByPageError(command) {
|
|
return !isObservationCommand(command) && !isBrowserManipulationCommand(command) && !isServiceCommand(command) ||
|
|
isResizeWindowCommand(command)
|
|
&& !isWindowSwitchingCommand(command);
|
|
}
|
|
function isClientFunctionCommand(command) {
|
|
return command.type === COMMAND_TYPE.executeClientFunction ||
|
|
command.type === COMMAND_TYPE.executeSelector;
|
|
}
|
|
function isObservationCommand(command) {
|
|
return isClientFunctionCommand(command) ||
|
|
command.type === COMMAND_TYPE.wait ||
|
|
command.type === COMMAND_TYPE.assertion ||
|
|
command.type === COMMAND_TYPE.executeExpression;
|
|
}
|
|
function isWindowSwitchingCommand(command) {
|
|
return command.type === COMMAND_TYPE.switchToIframe || command.type === COMMAND_TYPE.switchToMainWindow;
|
|
}
|
|
function isScreenshotCommand(command) {
|
|
return command.type === COMMAND_TYPE.takeScreenshot ||
|
|
command.type === COMMAND_TYPE.takeElementScreenshot ||
|
|
command.type === COMMAND_TYPE.takeScreenshotOnFail;
|
|
}
|
|
function isResizeWindowCommand(command) {
|
|
return command.type === COMMAND_TYPE.resizeWindow ||
|
|
command.type === COMMAND_TYPE.resizeWindowToFitDevice ||
|
|
command.type === COMMAND_TYPE.maximizeWindow;
|
|
}
|
|
function isBrowserManipulationCommand(command) {
|
|
return isScreenshotCommand(command) || isResizeWindowCommand(command);
|
|
}
|
|
function isServiceCommand(command) {
|
|
return command.type === COMMAND_TYPE.testDone ||
|
|
command.type === COMMAND_TYPE.showAssertionRetriesStatus ||
|
|
command.type === COMMAND_TYPE.hideAssertionRetriesStatus ||
|
|
command.type === COMMAND_TYPE.setBreakpoint ||
|
|
command.type === COMMAND_TYPE.takeScreenshotOnFail ||
|
|
command.type === COMMAND_TYPE.recorder ||
|
|
command.type === COMMAND_TYPE.getProxyUrl;
|
|
}
|
|
function isExecutableInTopWindowOnly(command) {
|
|
return command.type === COMMAND_TYPE.testDone ||
|
|
command.type === COMMAND_TYPE.switchToMainWindow ||
|
|
command.type === COMMAND_TYPE.setNativeDialogHandler ||
|
|
command.type === COMMAND_TYPE.getNativeDialogHistory ||
|
|
command.type === COMMAND_TYPE.setTestSpeed ||
|
|
command.type === COMMAND_TYPE.showAssertionRetriesStatus ||
|
|
command.type === COMMAND_TYPE.hideAssertionRetriesStatus ||
|
|
command.type === COMMAND_TYPE.setBreakpoint ||
|
|
isBrowserManipulationCommand(command) && command.type !== COMMAND_TYPE.takeElementScreenshot;
|
|
}
|
|
|
|
var STATUS_BAR_DEBUG_ACTION = {
|
|
step: 'step',
|
|
resume: 'resume',
|
|
};
|
|
|
|
// -------------------------------------------------------------
|
|
// WARNING: this file is used by both the client and the server.
|
|
// Do not use any browser or node-specific API!
|
|
// -------------------------------------------------------------
|
|
var TEST_RUN_ERRORS = {
|
|
uncaughtErrorOnPage: 'E1',
|
|
uncaughtErrorInTestCode: 'E2',
|
|
uncaughtNonErrorObjectInTestCode: 'E3',
|
|
uncaughtErrorInClientFunctionCode: 'E4',
|
|
uncaughtErrorInCustomDOMPropertyCode: 'E5',
|
|
unhandledPromiseRejection: 'E6',
|
|
uncaughtException: 'E7',
|
|
missingAwaitError: 'E8',
|
|
actionIntegerOptionError: 'E9',
|
|
actionPositiveIntegerOptionError: 'E10',
|
|
actionBooleanOptionError: 'E11',
|
|
actionSpeedOptionError: 'E12',
|
|
actionOptionsTypeError: 'E14',
|
|
actionBooleanArgumentError: 'E15',
|
|
actionStringArgumentError: 'E16',
|
|
actionNullableStringArgumentError: 'E17',
|
|
actionStringOrStringArrayArgumentError: 'E18',
|
|
actionStringArrayElementError: 'E19',
|
|
actionIntegerArgumentError: 'E20',
|
|
actionRoleArgumentError: 'E21',
|
|
actionPositiveIntegerArgumentError: 'E22',
|
|
actionSelectorError: 'E23',
|
|
actionElementNotFoundError: 'E24',
|
|
actionElementIsInvisibleError: 'E26',
|
|
actionSelectorMatchesWrongNodeTypeError: 'E27',
|
|
actionAdditionalElementNotFoundError: 'E28',
|
|
actionAdditionalElementIsInvisibleError: 'E29',
|
|
actionAdditionalSelectorMatchesWrongNodeTypeError: 'E30',
|
|
actionElementNonEditableError: 'E31',
|
|
actionElementNotTextAreaError: 'E32',
|
|
actionElementNonContentEditableError: 'E33',
|
|
actionElementIsNotFileInputError: 'E34',
|
|
actionRootContainerNotFoundError: 'E35',
|
|
actionIncorrectKeysError: 'E36',
|
|
actionCannotFindFileToUploadError: 'E37',
|
|
actionUnsupportedDeviceTypeError: 'E38',
|
|
actionIframeIsNotLoadedError: 'E39',
|
|
actionElementNotIframeError: 'E40',
|
|
actionInvalidScrollTargetError: 'E41',
|
|
currentIframeIsNotLoadedError: 'E42',
|
|
currentIframeNotFoundError: 'E43',
|
|
currentIframeIsInvisibleError: 'E44',
|
|
nativeDialogNotHandledError: 'E45',
|
|
uncaughtErrorInNativeDialogHandler: 'E46',
|
|
setTestSpeedArgumentError: 'E47',
|
|
setNativeDialogHandlerCodeWrongTypeError: 'E48',
|
|
clientFunctionExecutionInterruptionError: 'E49',
|
|
domNodeClientFunctionResultError: 'E50',
|
|
invalidSelectorResultError: 'E51',
|
|
cannotObtainInfoForElementSpecifiedBySelectorError: 'E52',
|
|
externalAssertionLibraryError: 'E53',
|
|
pageLoadError: 'E54',
|
|
windowDimensionsOverflowError: 'E55',
|
|
forbiddenCharactersInScreenshotPathError: 'E56',
|
|
invalidElementScreenshotDimensionsError: 'E57',
|
|
roleSwitchInRoleInitializerError: 'E58',
|
|
assertionExecutableArgumentError: 'E59',
|
|
assertionWithoutMethodCallError: 'E60',
|
|
assertionUnawaitedPromiseError: 'E61',
|
|
requestHookNotImplementedError: 'E62',
|
|
requestHookUnhandledError: 'E63',
|
|
uncaughtErrorInCustomClientScriptCode: 'E64',
|
|
uncaughtErrorInCustomClientScriptCodeLoadedFromModule: 'E65',
|
|
uncaughtErrorInCustomScript: 'E66',
|
|
uncaughtTestCafeErrorInCustomScript: 'E67',
|
|
childWindowIsNotLoadedError: 'E68',
|
|
childWindowNotFoundError: 'E69',
|
|
cannotSwitchToWindowError: 'E70',
|
|
closeChildWindowError: 'E71',
|
|
childWindowClosedBeforeSwitchingError: 'E72',
|
|
cannotCloseWindowWithChildrenError: 'E73',
|
|
targetWindowNotFoundError: 'E74',
|
|
parentWindowNotFoundError: 'E76',
|
|
previousWindowNotFoundError: 'E77',
|
|
switchToWindowPredicateError: 'E78',
|
|
actionFunctionArgumentError: 'E79',
|
|
multipleWindowsModeIsDisabledError: 'E80',
|
|
multipleWindowsModeIsNotSupportedInRemoteBrowserError: 'E81',
|
|
cannotCloseWindowWithoutParent: 'E82',
|
|
cannotRestoreChildWindowError: 'E83',
|
|
executionTimeoutExceeded: 'E84',
|
|
actionRequiredCookieArguments: 'E85',
|
|
actionCookieArgumentError: 'E86',
|
|
actionCookieArgumentsError: 'E87',
|
|
actionUrlCookieArgumentError: 'E88',
|
|
actionUrlsCookieArgumentError: 'E89',
|
|
actionStringOptionError: 'E90',
|
|
actionDateOptionError: 'E91',
|
|
actionNumberOptionError: 'E92',
|
|
actionUrlOptionError: 'E93',
|
|
actionUrlSearchParamsOptionError: 'E94',
|
|
actionObjectOptionError: 'E95',
|
|
actionUrlArgumentError: 'E96',
|
|
actionStringOrRegexOptionError: 'E97',
|
|
actionSkipJsErrorsArgumentError: 'E98',
|
|
actionFunctionOptionError: 'E99',
|
|
actionInvalidObjectPropertyError: 'E100',
|
|
actionElementIsNotTargetError: 'E101',
|
|
};
|
|
|
|
// Base
|
|
//--------------------------------------------------------------------
|
|
var TestRunErrorBase = /** @class */ (function () {
|
|
function TestRunErrorBase(code, callsite) {
|
|
this.code = code;
|
|
this.isTestCafeError = true;
|
|
this.callsite = callsite || null;
|
|
}
|
|
return TestRunErrorBase;
|
|
}());
|
|
var ActionOptionErrorBase = /** @class */ (function (_super) {
|
|
__extends(ActionOptionErrorBase, _super);
|
|
function ActionOptionErrorBase(code, optionName, actualValue) {
|
|
var _this = _super.call(this, code) || this;
|
|
_this.optionName = optionName;
|
|
_this.actualValue = actualValue;
|
|
return _this;
|
|
}
|
|
return ActionOptionErrorBase;
|
|
}(TestRunErrorBase));
|
|
// Client function errors
|
|
//--------------------------------------------------------------------
|
|
var ClientFunctionExecutionInterruptionError = /** @class */ (function (_super) {
|
|
__extends(ClientFunctionExecutionInterruptionError, _super);
|
|
function ClientFunctionExecutionInterruptionError(instantiationCallsiteName, callsite) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.clientFunctionExecutionInterruptionError, callsite) || this;
|
|
_this.instantiationCallsiteName = instantiationCallsiteName;
|
|
return _this;
|
|
}
|
|
return ClientFunctionExecutionInterruptionError;
|
|
}(TestRunErrorBase));
|
|
var DomNodeClientFunctionResultError = /** @class */ (function (_super) {
|
|
__extends(DomNodeClientFunctionResultError, _super);
|
|
function DomNodeClientFunctionResultError(instantiationCallsiteName, callsite) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.domNodeClientFunctionResultError, callsite) || this;
|
|
_this.instantiationCallsiteName = instantiationCallsiteName;
|
|
return _this;
|
|
}
|
|
return DomNodeClientFunctionResultError;
|
|
}(TestRunErrorBase));
|
|
// Selector errors
|
|
//--------------------------------------------------------------------
|
|
var SelectorErrorBase = /** @class */ (function (_super) {
|
|
__extends(SelectorErrorBase, _super);
|
|
function SelectorErrorBase(code, _a, callsite) {
|
|
var _b = _a === void 0 ? {} : _a, apiFnChain = _b.apiFnChain, apiFnIndex = _b.apiFnIndex, reason = _b.reason;
|
|
var _this = _super.call(this, code, callsite) || this;
|
|
_this.apiFnChain = apiFnChain;
|
|
_this.apiFnIndex = apiFnIndex;
|
|
_this.reason = reason;
|
|
return _this;
|
|
}
|
|
return SelectorErrorBase;
|
|
}(TestRunErrorBase));
|
|
var InvalidSelectorResultError = /** @class */ (function (_super) {
|
|
__extends(InvalidSelectorResultError, _super);
|
|
function InvalidSelectorResultError(callsite) {
|
|
return _super.call(this, TEST_RUN_ERRORS.invalidSelectorResultError, callsite) || this;
|
|
}
|
|
return InvalidSelectorResultError;
|
|
}(TestRunErrorBase));
|
|
var CannotObtainInfoForElementSpecifiedBySelectorError = /** @class */ (function (_super) {
|
|
__extends(CannotObtainInfoForElementSpecifiedBySelectorError, _super);
|
|
function CannotObtainInfoForElementSpecifiedBySelectorError(callsite, apiFnArgs) {
|
|
return _super.call(this, TEST_RUN_ERRORS.cannotObtainInfoForElementSpecifiedBySelectorError, apiFnArgs, callsite) || this;
|
|
}
|
|
return CannotObtainInfoForElementSpecifiedBySelectorError;
|
|
}(SelectorErrorBase));
|
|
// Uncaught errors
|
|
//--------------------------------------------------------------------
|
|
var UncaughtErrorOnPage = /** @class */ (function (_super) {
|
|
__extends(UncaughtErrorOnPage, _super);
|
|
function UncaughtErrorOnPage(errStack, pageDestUrl) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.uncaughtErrorOnPage) || this;
|
|
_this.errStack = errStack;
|
|
_this.pageDestUrl = pageDestUrl;
|
|
return _this;
|
|
}
|
|
return UncaughtErrorOnPage;
|
|
}(TestRunErrorBase));
|
|
var UncaughtErrorInClientFunctionCode = /** @class */ (function (_super) {
|
|
__extends(UncaughtErrorInClientFunctionCode, _super);
|
|
function UncaughtErrorInClientFunctionCode(instantiationCallsiteName, err, callsite) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.uncaughtErrorInClientFunctionCode, callsite) || this;
|
|
_this.errMsg = String(err);
|
|
_this.instantiationCallsiteName = instantiationCallsiteName;
|
|
return _this;
|
|
}
|
|
return UncaughtErrorInClientFunctionCode;
|
|
}(TestRunErrorBase));
|
|
var UncaughtErrorInCustomDOMPropertyCode = /** @class */ (function (_super) {
|
|
__extends(UncaughtErrorInCustomDOMPropertyCode, _super);
|
|
function UncaughtErrorInCustomDOMPropertyCode(instantiationCallsiteName, err, prop, callsite) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.uncaughtErrorInCustomDOMPropertyCode, callsite) || this;
|
|
_this.errMsg = String(err);
|
|
_this.property = prop;
|
|
_this.instantiationCallsiteName = instantiationCallsiteName;
|
|
return _this;
|
|
}
|
|
return UncaughtErrorInCustomDOMPropertyCode;
|
|
}(TestRunErrorBase));
|
|
var UncaughtErrorInCustomClientScriptCode = /** @class */ (function (_super) {
|
|
__extends(UncaughtErrorInCustomClientScriptCode, _super);
|
|
function UncaughtErrorInCustomClientScriptCode(err) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.uncaughtErrorInCustomClientScriptCode) || this;
|
|
_this.errMsg = String(err);
|
|
return _this;
|
|
}
|
|
return UncaughtErrorInCustomClientScriptCode;
|
|
}(TestRunErrorBase));
|
|
var UncaughtErrorInCustomClientScriptLoadedFromModule = /** @class */ (function (_super) {
|
|
__extends(UncaughtErrorInCustomClientScriptLoadedFromModule, _super);
|
|
function UncaughtErrorInCustomClientScriptLoadedFromModule(err, moduleName) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.uncaughtErrorInCustomClientScriptCodeLoadedFromModule) || this;
|
|
_this.errMsg = String(err);
|
|
_this.moduleName = moduleName;
|
|
return _this;
|
|
}
|
|
return UncaughtErrorInCustomClientScriptLoadedFromModule;
|
|
}(TestRunErrorBase));
|
|
// Action parameters errors
|
|
//--------------------------------------------------------------------
|
|
// Options errors
|
|
//--------------------------------------------------------------------
|
|
var ActionIntegerOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionIntegerOptionError, _super);
|
|
function ActionIntegerOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionIntegerOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionIntegerOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionPositiveIntegerOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionPositiveIntegerOptionError, _super);
|
|
function ActionPositiveIntegerOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionPositiveIntegerOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionPositiveIntegerOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionBooleanOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionBooleanOptionError, _super);
|
|
function ActionBooleanOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionBooleanOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionBooleanOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionSpeedOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionSpeedOptionError, _super);
|
|
function ActionSpeedOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionSpeedOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionSpeedOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionStringOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionStringOptionError, _super);
|
|
function ActionStringOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionStringOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionStringOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionStringOrRegexOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionStringOrRegexOptionError, _super);
|
|
function ActionStringOrRegexOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionStringOrRegexOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionStringOrRegexOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionDateOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionDateOptionError, _super);
|
|
function ActionDateOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionDateOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionDateOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionNumberOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionNumberOptionError, _super);
|
|
function ActionNumberOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionNumberOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionNumberOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionUrlOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionUrlOptionError, _super);
|
|
function ActionUrlOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionUrlOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionUrlOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionUrlSearchParamsOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionUrlSearchParamsOptionError, _super);
|
|
function ActionUrlSearchParamsOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionUrlSearchParamsOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionUrlSearchParamsOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionObjectOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionObjectOptionError, _super);
|
|
function ActionObjectOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionObjectOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionObjectOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionFunctionOptionError = /** @class */ (function (_super) {
|
|
__extends(ActionFunctionOptionError, _super);
|
|
function ActionFunctionOptionError(optionName, actualValue) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionFunctionOptionError, optionName, actualValue) || this;
|
|
}
|
|
return ActionFunctionOptionError;
|
|
}(ActionOptionErrorBase));
|
|
var ActionInvalidObjectPropertyError = /** @class */ (function (_super) {
|
|
__extends(ActionInvalidObjectPropertyError, _super);
|
|
function ActionInvalidObjectPropertyError(objectName, propertyName, availableProperties) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.actionInvalidObjectPropertyError) || this;
|
|
_this.objectName = objectName;
|
|
_this.propertyName = propertyName;
|
|
_this.availableProperties = availableProperties;
|
|
return _this;
|
|
}
|
|
return ActionInvalidObjectPropertyError;
|
|
}(TestRunErrorBase));
|
|
// Action execution errors
|
|
//--------------------------------------------------------------------
|
|
var ActionElementNotFoundError = /** @class */ (function (_super) {
|
|
__extends(ActionElementNotFoundError, _super);
|
|
function ActionElementNotFoundError(callsite, apiFnArgs) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionElementNotFoundError, apiFnArgs, callsite) || this;
|
|
}
|
|
return ActionElementNotFoundError;
|
|
}(SelectorErrorBase));
|
|
var ActionElementIsInvisibleError = /** @class */ (function (_super) {
|
|
__extends(ActionElementIsInvisibleError, _super);
|
|
function ActionElementIsInvisibleError(callsite, apiFnArgs) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionElementIsInvisibleError, apiFnArgs, callsite) || this;
|
|
}
|
|
return ActionElementIsInvisibleError;
|
|
}(SelectorErrorBase));
|
|
var ActionSelectorMatchesWrongNodeTypeError = /** @class */ (function (_super) {
|
|
__extends(ActionSelectorMatchesWrongNodeTypeError, _super);
|
|
function ActionSelectorMatchesWrongNodeTypeError(nodeDescription) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.actionSelectorMatchesWrongNodeTypeError) || this;
|
|
_this.nodeDescription = nodeDescription;
|
|
return _this;
|
|
}
|
|
return ActionSelectorMatchesWrongNodeTypeError;
|
|
}(TestRunErrorBase));
|
|
var ActionAdditionalElementNotFoundError = /** @class */ (function (_super) {
|
|
__extends(ActionAdditionalElementNotFoundError, _super);
|
|
function ActionAdditionalElementNotFoundError(argumentName, apiFnArgs) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.actionAdditionalElementNotFoundError, apiFnArgs) || this;
|
|
_this.argumentName = argumentName;
|
|
return _this;
|
|
}
|
|
return ActionAdditionalElementNotFoundError;
|
|
}(SelectorErrorBase));
|
|
var ActionElementIsNotTargetError = /** @class */ (function (_super) {
|
|
__extends(ActionElementIsNotTargetError, _super);
|
|
function ActionElementIsNotTargetError(callsite) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionElementIsNotTargetError, callsite) || this;
|
|
}
|
|
return ActionElementIsNotTargetError;
|
|
}(TestRunErrorBase));
|
|
var ActionAdditionalElementIsInvisibleError = /** @class */ (function (_super) {
|
|
__extends(ActionAdditionalElementIsInvisibleError, _super);
|
|
function ActionAdditionalElementIsInvisibleError(argumentName, apiFnArgs) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.actionAdditionalElementIsInvisibleError, apiFnArgs) || this;
|
|
_this.argumentName = argumentName;
|
|
return _this;
|
|
}
|
|
return ActionAdditionalElementIsInvisibleError;
|
|
}(SelectorErrorBase));
|
|
var ActionAdditionalSelectorMatchesWrongNodeTypeError = /** @class */ (function (_super) {
|
|
__extends(ActionAdditionalSelectorMatchesWrongNodeTypeError, _super);
|
|
function ActionAdditionalSelectorMatchesWrongNodeTypeError(argumentName, nodeDescription) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.actionAdditionalSelectorMatchesWrongNodeTypeError) || this;
|
|
_this.argumentName = argumentName;
|
|
_this.nodeDescription = nodeDescription;
|
|
return _this;
|
|
}
|
|
return ActionAdditionalSelectorMatchesWrongNodeTypeError;
|
|
}(TestRunErrorBase));
|
|
var ActionElementNonEditableError = /** @class */ (function (_super) {
|
|
__extends(ActionElementNonEditableError, _super);
|
|
function ActionElementNonEditableError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionElementNonEditableError) || this;
|
|
}
|
|
return ActionElementNonEditableError;
|
|
}(TestRunErrorBase));
|
|
var ActionElementNotTextAreaError = /** @class */ (function (_super) {
|
|
__extends(ActionElementNotTextAreaError, _super);
|
|
function ActionElementNotTextAreaError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionElementNotTextAreaError) || this;
|
|
}
|
|
return ActionElementNotTextAreaError;
|
|
}(TestRunErrorBase));
|
|
var ActionElementNonContentEditableError = /** @class */ (function (_super) {
|
|
__extends(ActionElementNonContentEditableError, _super);
|
|
function ActionElementNonContentEditableError(argumentName) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.actionElementNonContentEditableError) || this;
|
|
_this.argumentName = argumentName;
|
|
return _this;
|
|
}
|
|
return ActionElementNonContentEditableError;
|
|
}(TestRunErrorBase));
|
|
var ActionRootContainerNotFoundError = /** @class */ (function (_super) {
|
|
__extends(ActionRootContainerNotFoundError, _super);
|
|
function ActionRootContainerNotFoundError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionRootContainerNotFoundError) || this;
|
|
}
|
|
return ActionRootContainerNotFoundError;
|
|
}(TestRunErrorBase));
|
|
var ActionIncorrectKeysError = /** @class */ (function (_super) {
|
|
__extends(ActionIncorrectKeysError, _super);
|
|
function ActionIncorrectKeysError(argumentName) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.actionIncorrectKeysError) || this;
|
|
_this.argumentName = argumentName;
|
|
return _this;
|
|
}
|
|
return ActionIncorrectKeysError;
|
|
}(TestRunErrorBase));
|
|
var ActionCannotFindFileToUploadError = /** @class */ (function (_super) {
|
|
__extends(ActionCannotFindFileToUploadError, _super);
|
|
function ActionCannotFindFileToUploadError(filePaths, scannedFilePaths) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.actionCannotFindFileToUploadError) || this;
|
|
_this.filePaths = filePaths;
|
|
_this.scannedFilePaths = scannedFilePaths;
|
|
return _this;
|
|
}
|
|
return ActionCannotFindFileToUploadError;
|
|
}(TestRunErrorBase));
|
|
var ActionElementIsNotFileInputError = /** @class */ (function (_super) {
|
|
__extends(ActionElementIsNotFileInputError, _super);
|
|
function ActionElementIsNotFileInputError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionElementIsNotFileInputError) || this;
|
|
}
|
|
return ActionElementIsNotFileInputError;
|
|
}(TestRunErrorBase));
|
|
var ActionInvalidScrollTargetError = /** @class */ (function (_super) {
|
|
__extends(ActionInvalidScrollTargetError, _super);
|
|
function ActionInvalidScrollTargetError(scrollTargetXValid, scrollTargetYValid) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.actionInvalidScrollTargetError) || this;
|
|
if (!scrollTargetXValid) {
|
|
if (!scrollTargetYValid)
|
|
_this.properties = 'scrollTargetX and scrollTargetY properties';
|
|
else
|
|
_this.properties = 'scrollTargetX property';
|
|
}
|
|
else
|
|
_this.properties = 'scrollTargetY property';
|
|
return _this;
|
|
}
|
|
return ActionInvalidScrollTargetError;
|
|
}(TestRunErrorBase));
|
|
var InvalidElementScreenshotDimensionsError = /** @class */ (function (_super) {
|
|
__extends(InvalidElementScreenshotDimensionsError, _super);
|
|
function InvalidElementScreenshotDimensionsError(width, height) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.invalidElementScreenshotDimensionsError) || this;
|
|
var widthIsInvalid = width <= 0;
|
|
var heightIsInvalid = height <= 0;
|
|
if (widthIsInvalid) {
|
|
if (heightIsInvalid) {
|
|
_this.verb = 'are';
|
|
_this.dimensions = 'width and height';
|
|
}
|
|
else {
|
|
_this.verb = 'is';
|
|
_this.dimensions = 'width';
|
|
}
|
|
}
|
|
else {
|
|
_this.verb = 'is';
|
|
_this.dimensions = 'height';
|
|
}
|
|
return _this;
|
|
}
|
|
return InvalidElementScreenshotDimensionsError;
|
|
}(TestRunErrorBase));
|
|
// Iframe errors
|
|
//--------------------------------------------------------------------
|
|
var ActionElementNotIframeError = /** @class */ (function (_super) {
|
|
__extends(ActionElementNotIframeError, _super);
|
|
function ActionElementNotIframeError(callsite) {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionElementNotIframeError, callsite) || this;
|
|
}
|
|
return ActionElementNotIframeError;
|
|
}(TestRunErrorBase));
|
|
var ActionIframeIsNotLoadedError = /** @class */ (function (_super) {
|
|
__extends(ActionIframeIsNotLoadedError, _super);
|
|
function ActionIframeIsNotLoadedError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.actionIframeIsNotLoadedError) || this;
|
|
}
|
|
return ActionIframeIsNotLoadedError;
|
|
}(TestRunErrorBase));
|
|
var CurrentIframeIsNotLoadedError = /** @class */ (function (_super) {
|
|
__extends(CurrentIframeIsNotLoadedError, _super);
|
|
function CurrentIframeIsNotLoadedError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.currentIframeIsNotLoadedError) || this;
|
|
}
|
|
return CurrentIframeIsNotLoadedError;
|
|
}(TestRunErrorBase));
|
|
var ChildWindowNotFoundError = /** @class */ (function (_super) {
|
|
__extends(ChildWindowNotFoundError, _super);
|
|
function ChildWindowNotFoundError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.childWindowNotFoundError) || this;
|
|
}
|
|
return ChildWindowNotFoundError;
|
|
}(TestRunErrorBase));
|
|
var ChildWindowIsNotLoadedError = /** @class */ (function (_super) {
|
|
__extends(ChildWindowIsNotLoadedError, _super);
|
|
function ChildWindowIsNotLoadedError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.childWindowIsNotLoadedError) || this;
|
|
}
|
|
return ChildWindowIsNotLoadedError;
|
|
}(TestRunErrorBase));
|
|
var CannotSwitchToWindowError = /** @class */ (function (_super) {
|
|
__extends(CannotSwitchToWindowError, _super);
|
|
function CannotSwitchToWindowError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.cannotSwitchToWindowError) || this;
|
|
}
|
|
return CannotSwitchToWindowError;
|
|
}(TestRunErrorBase));
|
|
var CloseChildWindowError = /** @class */ (function (_super) {
|
|
__extends(CloseChildWindowError, _super);
|
|
function CloseChildWindowError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.closeChildWindowError) || this;
|
|
}
|
|
return CloseChildWindowError;
|
|
}(TestRunErrorBase));
|
|
var CannotCloseWindowWithChildrenError = /** @class */ (function (_super) {
|
|
__extends(CannotCloseWindowWithChildrenError, _super);
|
|
function CannotCloseWindowWithChildrenError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.cannotCloseWindowWithChildrenError) || this;
|
|
}
|
|
return CannotCloseWindowWithChildrenError;
|
|
}(TestRunErrorBase));
|
|
var CannotCloseWindowWithoutParentError = /** @class */ (function (_super) {
|
|
__extends(CannotCloseWindowWithoutParentError, _super);
|
|
function CannotCloseWindowWithoutParentError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.cannotCloseWindowWithoutParent) || this;
|
|
}
|
|
return CannotCloseWindowWithoutParentError;
|
|
}(TestRunErrorBase));
|
|
var SwitchToWindowPredicateError = /** @class */ (function (_super) {
|
|
__extends(SwitchToWindowPredicateError, _super);
|
|
function SwitchToWindowPredicateError(errMsg) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.switchToWindowPredicateError) || this;
|
|
_this.errMsg = errMsg;
|
|
return _this;
|
|
}
|
|
return SwitchToWindowPredicateError;
|
|
}(TestRunErrorBase));
|
|
var WindowNotFoundError = /** @class */ (function (_super) {
|
|
__extends(WindowNotFoundError, _super);
|
|
function WindowNotFoundError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.targetWindowNotFoundError) || this;
|
|
}
|
|
return WindowNotFoundError;
|
|
}(TestRunErrorBase));
|
|
var ParentWindowNotFoundError = /** @class */ (function (_super) {
|
|
__extends(ParentWindowNotFoundError, _super);
|
|
function ParentWindowNotFoundError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.parentWindowNotFoundError) || this;
|
|
}
|
|
return ParentWindowNotFoundError;
|
|
}(TestRunErrorBase));
|
|
var PreviousWindowNotFoundError = /** @class */ (function (_super) {
|
|
__extends(PreviousWindowNotFoundError, _super);
|
|
function PreviousWindowNotFoundError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.previousWindowNotFoundError) || this;
|
|
}
|
|
return PreviousWindowNotFoundError;
|
|
}(TestRunErrorBase));
|
|
var ChildWindowClosedBeforeSwitchingError = /** @class */ (function (_super) {
|
|
__extends(ChildWindowClosedBeforeSwitchingError, _super);
|
|
function ChildWindowClosedBeforeSwitchingError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.childWindowClosedBeforeSwitchingError) || this;
|
|
}
|
|
return ChildWindowClosedBeforeSwitchingError;
|
|
}(TestRunErrorBase));
|
|
var CannotRestoreChildWindowError = /** @class */ (function (_super) {
|
|
__extends(CannotRestoreChildWindowError, _super);
|
|
function CannotRestoreChildWindowError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.cannotRestoreChildWindowError) || this;
|
|
}
|
|
return CannotRestoreChildWindowError;
|
|
}(TestRunErrorBase));
|
|
var CurrentIframeNotFoundError = /** @class */ (function (_super) {
|
|
__extends(CurrentIframeNotFoundError, _super);
|
|
function CurrentIframeNotFoundError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.currentIframeNotFoundError) || this;
|
|
}
|
|
return CurrentIframeNotFoundError;
|
|
}(TestRunErrorBase));
|
|
var CurrentIframeIsInvisibleError = /** @class */ (function (_super) {
|
|
__extends(CurrentIframeIsInvisibleError, _super);
|
|
function CurrentIframeIsInvisibleError() {
|
|
return _super.call(this, TEST_RUN_ERRORS.currentIframeIsInvisibleError) || this;
|
|
}
|
|
return CurrentIframeIsInvisibleError;
|
|
}(TestRunErrorBase));
|
|
// Native dialog errors
|
|
//--------------------------------------------------------------------
|
|
var NativeDialogNotHandledError = /** @class */ (function (_super) {
|
|
__extends(NativeDialogNotHandledError, _super);
|
|
function NativeDialogNotHandledError(dialogType, url) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.nativeDialogNotHandledError) || this;
|
|
_this.dialogType = dialogType;
|
|
_this.pageUrl = url;
|
|
return _this;
|
|
}
|
|
return NativeDialogNotHandledError;
|
|
}(TestRunErrorBase));
|
|
var UncaughtErrorInNativeDialogHandler = /** @class */ (function (_super) {
|
|
__extends(UncaughtErrorInNativeDialogHandler, _super);
|
|
function UncaughtErrorInNativeDialogHandler(dialogType, errMsg, url) {
|
|
var _this = _super.call(this, TEST_RUN_ERRORS.uncaughtErrorInNativeDialogHandler) || this;
|
|
_this.dialogType = dialogType;
|
|
_this.errMsg = errMsg;
|
|
_this.pageUrl = url;
|
|
return _this;
|
|
}
|
|
return UncaughtErrorInNativeDialogHandler;
|
|
}(TestRunErrorBase));
|
|
|
|
var Errors = /*#__PURE__*/Object.freeze({
|
|
__proto__: null,
|
|
TestRunErrorBase: TestRunErrorBase,
|
|
ClientFunctionExecutionInterruptionError: ClientFunctionExecutionInterruptionError,
|
|
DomNodeClientFunctionResultError: DomNodeClientFunctionResultError,
|
|
SelectorErrorBase: SelectorErrorBase,
|
|
InvalidSelectorResultError: InvalidSelectorResultError,
|
|
CannotObtainInfoForElementSpecifiedBySelectorError: CannotObtainInfoForElementSpecifiedBySelectorError,
|
|
UncaughtErrorOnPage: UncaughtErrorOnPage,
|
|
UncaughtErrorInClientFunctionCode: UncaughtErrorInClientFunctionCode,
|
|
UncaughtErrorInCustomDOMPropertyCode: UncaughtErrorInCustomDOMPropertyCode,
|
|
UncaughtErrorInCustomClientScriptCode: UncaughtErrorInCustomClientScriptCode,
|
|
UncaughtErrorInCustomClientScriptLoadedFromModule: UncaughtErrorInCustomClientScriptLoadedFromModule,
|
|
ActionIntegerOptionError: ActionIntegerOptionError,
|
|
ActionPositiveIntegerOptionError: ActionPositiveIntegerOptionError,
|
|
ActionBooleanOptionError: ActionBooleanOptionError,
|
|
ActionSpeedOptionError: ActionSpeedOptionError,
|
|
ActionStringOptionError: ActionStringOptionError,
|
|
ActionStringOrRegexOptionError: ActionStringOrRegexOptionError,
|
|
ActionDateOptionError: ActionDateOptionError,
|
|
ActionNumberOptionError: ActionNumberOptionError,
|
|
ActionUrlOptionError: ActionUrlOptionError,
|
|
ActionUrlSearchParamsOptionError: ActionUrlSearchParamsOptionError,
|
|
ActionObjectOptionError: ActionObjectOptionError,
|
|
ActionFunctionOptionError: ActionFunctionOptionError,
|
|
ActionInvalidObjectPropertyError: ActionInvalidObjectPropertyError,
|
|
ActionElementNotFoundError: ActionElementNotFoundError,
|
|
ActionElementIsInvisibleError: ActionElementIsInvisibleError,
|
|
ActionSelectorMatchesWrongNodeTypeError: ActionSelectorMatchesWrongNodeTypeError,
|
|
ActionAdditionalElementNotFoundError: ActionAdditionalElementNotFoundError,
|
|
ActionElementIsNotTargetError: ActionElementIsNotTargetError,
|
|
ActionAdditionalElementIsInvisibleError: ActionAdditionalElementIsInvisibleError,
|
|
ActionAdditionalSelectorMatchesWrongNodeTypeError: ActionAdditionalSelectorMatchesWrongNodeTypeError,
|
|
ActionElementNonEditableError: ActionElementNonEditableError,
|
|
ActionElementNotTextAreaError: ActionElementNotTextAreaError,
|
|
ActionElementNonContentEditableError: ActionElementNonContentEditableError,
|
|
ActionRootContainerNotFoundError: ActionRootContainerNotFoundError,
|
|
ActionIncorrectKeysError: ActionIncorrectKeysError,
|
|
ActionCannotFindFileToUploadError: ActionCannotFindFileToUploadError,
|
|
ActionElementIsNotFileInputError: ActionElementIsNotFileInputError,
|
|
ActionInvalidScrollTargetError: ActionInvalidScrollTargetError,
|
|
InvalidElementScreenshotDimensionsError: InvalidElementScreenshotDimensionsError,
|
|
ActionElementNotIframeError: ActionElementNotIframeError,
|
|
ActionIframeIsNotLoadedError: ActionIframeIsNotLoadedError,
|
|
CurrentIframeIsNotLoadedError: CurrentIframeIsNotLoadedError,
|
|
ChildWindowNotFoundError: ChildWindowNotFoundError,
|
|
ChildWindowIsNotLoadedError: ChildWindowIsNotLoadedError,
|
|
CannotSwitchToWindowError: CannotSwitchToWindowError,
|
|
CloseChildWindowError: CloseChildWindowError,
|
|
CannotCloseWindowWithChildrenError: CannotCloseWindowWithChildrenError,
|
|
CannotCloseWindowWithoutParentError: CannotCloseWindowWithoutParentError,
|
|
SwitchToWindowPredicateError: SwitchToWindowPredicateError,
|
|
WindowNotFoundError: WindowNotFoundError,
|
|
ParentWindowNotFoundError: ParentWindowNotFoundError,
|
|
PreviousWindowNotFoundError: PreviousWindowNotFoundError,
|
|
ChildWindowClosedBeforeSwitchingError: ChildWindowClosedBeforeSwitchingError,
|
|
CannotRestoreChildWindowError: CannotRestoreChildWindowError,
|
|
CurrentIframeNotFoundError: CurrentIframeNotFoundError,
|
|
CurrentIframeIsInvisibleError: CurrentIframeIsInvisibleError,
|
|
NativeDialogNotHandledError: NativeDialogNotHandledError,
|
|
UncaughtErrorInNativeDialogHandler: UncaughtErrorInNativeDialogHandler
|
|
});
|
|
|
|
// -------------------------------------------------------------
|
|
// WARNING: this file is used by both the client and the server.
|
|
// Do not use any browser or node-specific API!
|
|
// -------------------------------------------------------------
|
|
var NATIVE_METHODS_PROPERTY_NAME = '_nativeMethods';
|
|
var BrowserConsoleMessages = /** @class */ (function () {
|
|
function BrowserConsoleMessages(data, nativeMethods) {
|
|
var resultNativeMethods = this._ensureNativeMethods(nativeMethods);
|
|
resultNativeMethods.objectDefineProperty(this, NATIVE_METHODS_PROPERTY_NAME, { value: resultNativeMethods });
|
|
this.concat(data);
|
|
}
|
|
BrowserConsoleMessages.prototype._ensureNativeMethods = function (nativeMethods) {
|
|
return nativeMethods || {
|
|
objectKeys: Object.keys,
|
|
arrayForEach: Array.prototype.forEach,
|
|
arrayConcat: Array.prototype.concat,
|
|
arraySlice: Array.prototype.slice,
|
|
objectDefineProperty: Object.defineProperty,
|
|
};
|
|
};
|
|
BrowserConsoleMessages.prototype._getWindowIds = function (consoleMessages) {
|
|
return this[NATIVE_METHODS_PROPERTY_NAME].objectKeys(consoleMessages);
|
|
};
|
|
BrowserConsoleMessages.prototype._copyArray = function (array) {
|
|
return this[NATIVE_METHODS_PROPERTY_NAME].arraySlice.call(array);
|
|
};
|
|
BrowserConsoleMessages.prototype._concatArrays = function (array, anotherArray) {
|
|
return this[NATIVE_METHODS_PROPERTY_NAME].arrayConcat.call(array, anotherArray);
|
|
};
|
|
BrowserConsoleMessages.prototype.ensureMessageContainer = function (windowId) {
|
|
if (this[windowId])
|
|
return;
|
|
this[windowId] = {
|
|
log: [],
|
|
info: [],
|
|
warn: [],
|
|
error: [],
|
|
};
|
|
};
|
|
BrowserConsoleMessages.prototype.concat = function (consoleMessages) {
|
|
var _this = this;
|
|
if (!consoleMessages)
|
|
return this;
|
|
var windowIds = this._getWindowIds(consoleMessages);
|
|
this[NATIVE_METHODS_PROPERTY_NAME].arrayForEach.call(windowIds, function (windowId) {
|
|
_this.ensureMessageContainer(windowId);
|
|
_this[windowId].log = _this._concatArrays(_this[windowId].log, consoleMessages[windowId].log);
|
|
_this[windowId].info = _this._concatArrays(_this[windowId].info, consoleMessages[windowId].info);
|
|
_this[windowId].warn = _this._concatArrays(_this[windowId].warn, consoleMessages[windowId].warn);
|
|
_this[windowId].error = _this._concatArrays(_this[windowId].error, consoleMessages[windowId].error);
|
|
});
|
|
return this;
|
|
};
|
|
BrowserConsoleMessages.prototype.addMessage = function (type, msg, windowId) {
|
|
this.ensureMessageContainer(windowId);
|
|
this[windowId][type].push(msg);
|
|
};
|
|
BrowserConsoleMessages.prototype.getCopy = function () {
|
|
var _this = this;
|
|
var copy = {};
|
|
var windowIds = this._getWindowIds(this);
|
|
this[NATIVE_METHODS_PROPERTY_NAME].arrayForEach.call(windowIds, function (windowId) {
|
|
copy[windowId] = {
|
|
log: _this._copyArray(_this[windowId].log),
|
|
info: _this._copyArray(_this[windowId].info),
|
|
warn: _this._copyArray(_this[windowId].warn),
|
|
error: _this._copyArray(_this[windowId].error),
|
|
};
|
|
});
|
|
return copy;
|
|
};
|
|
return BrowserConsoleMessages;
|
|
}());
|
|
|
|
var ClientBrowserConsoleMessages = /** @class */ (function (_super) {
|
|
__extends(ClientBrowserConsoleMessages, _super);
|
|
function ClientBrowserConsoleMessages(data) {
|
|
return _super.call(this, data, hammerhead.nativeMethods) || this;
|
|
}
|
|
return ClientBrowserConsoleMessages;
|
|
}(BrowserConsoleMessages));
|
|
|
|
function createCommonjsModule(fn, module) {
|
|
return module = { exports: {} }, fn(module, module.exports), module.exports;
|
|
}
|
|
|
|
var replicator = createCommonjsModule(function (module) {
|
|
// Const
|
|
var TRANSFORMED_TYPE_KEY = '@t';
|
|
var CIRCULAR_REF_KEY = '@r';
|
|
var KEY_REQUIRE_ESCAPING_RE = /^#*@(t|r)$/;
|
|
var GLOBAL = (function getGlobal() {
|
|
// NOTE: see http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performeval step 10
|
|
var savedEval = eval;
|
|
return savedEval('this');
|
|
})();
|
|
var TYPED_ARRAY_CTORS = {
|
|
'Int8Array': typeof Int8Array === 'function' ? Int8Array : void 0,
|
|
'Uint8Array': typeof Uint8Array === 'function' ? Uint8Array : void 0,
|
|
'Uint8ClampedArray': typeof Uint8ClampedArray === 'function' ? Uint8ClampedArray : void 0,
|
|
'Int16Array': typeof Int16Array === 'function' ? Int16Array : void 0,
|
|
'Uint16Array': typeof Uint16Array === 'function' ? Uint16Array : void 0,
|
|
'Int32Array': typeof Int32Array === 'function' ? Int32Array : void 0,
|
|
'Uint32Array': typeof Uint32Array === 'function' ? Uint32Array : void 0,
|
|
'Float32Array': typeof Float32Array === 'function' ? Float32Array : void 0,
|
|
'Float64Array': typeof Float64Array === 'function' ? Float64Array : void 0
|
|
};
|
|
var ARRAY_BUFFER_SUPPORTED = typeof ArrayBuffer === 'function';
|
|
var MAP_SUPPORTED = typeof Map === 'function';
|
|
var SET_SUPPORTED = typeof Set === 'function';
|
|
var BUFFER_FROM_SUPPORTED = typeof Buffer === 'function';
|
|
var TYPED_ARRAY_SUPPORTED = function (typeName) {
|
|
return !!TYPED_ARRAY_CTORS[typeName];
|
|
};
|
|
// Saved proto functions
|
|
var arrSlice = Array.prototype.slice;
|
|
// Default serializer
|
|
var JSONSerializer = {
|
|
serialize: function (val) {
|
|
return JSON.stringify(val);
|
|
},
|
|
deserialize: function (val) {
|
|
return JSON.parse(val);
|
|
}
|
|
};
|
|
// EncodingTransformer
|
|
var EncodingTransformer = function (val, transforms) {
|
|
this.references = val;
|
|
this.transforms = transforms;
|
|
this.circularCandidates = [];
|
|
this.circularCandidatesDescrs = [];
|
|
this.circularRefCount = 0;
|
|
};
|
|
EncodingTransformer._createRefMark = function (idx) {
|
|
var obj = Object.create(null);
|
|
obj[CIRCULAR_REF_KEY] = idx;
|
|
return obj;
|
|
};
|
|
EncodingTransformer.prototype._createCircularCandidate = function (val, parent, key) {
|
|
this.circularCandidates.push(val);
|
|
this.circularCandidatesDescrs.push({ parent: parent, key: key, refIdx: -1 });
|
|
};
|
|
EncodingTransformer.prototype._applyTransform = function (val, parent, key, transform) {
|
|
var result = Object.create(null);
|
|
var serializableVal = transform.toSerializable(val);
|
|
if (typeof serializableVal === 'object')
|
|
this._createCircularCandidate(val, parent, key);
|
|
result[TRANSFORMED_TYPE_KEY] = transform.type;
|
|
result.data = this._handleValue(serializableVal, parent, key);
|
|
return result;
|
|
};
|
|
EncodingTransformer.prototype._handleArray = function (arr) {
|
|
var result = [];
|
|
for (var i = 0; i < arr.length; i++)
|
|
result[i] = this._handleValue(arr[i], result, i);
|
|
return result;
|
|
};
|
|
EncodingTransformer.prototype._handlePlainObject = function (obj) {
|
|
var replicator = this;
|
|
var result = Object.create(null);
|
|
var ownPropertyNames = Object.getOwnPropertyNames(obj);
|
|
ownPropertyNames.forEach(function (key) {
|
|
var resultKey = KEY_REQUIRE_ESCAPING_RE.test(key) ? '#' + key : key;
|
|
result[resultKey] = replicator._handleValue(obj[key], result, resultKey);
|
|
});
|
|
return result;
|
|
};
|
|
EncodingTransformer.prototype._handleObject = function (obj, parent, key) {
|
|
this._createCircularCandidate(obj, parent, key);
|
|
return Array.isArray(obj) ? this._handleArray(obj) : this._handlePlainObject(obj);
|
|
};
|
|
EncodingTransformer.prototype._ensureCircularReference = function (obj) {
|
|
var circularCandidateIdx = this.circularCandidates.indexOf(obj);
|
|
if (circularCandidateIdx > -1) {
|
|
var descr = this.circularCandidatesDescrs[circularCandidateIdx];
|
|
if (descr.refIdx === -1)
|
|
descr.refIdx = descr.parent ? ++this.circularRefCount : 0;
|
|
return EncodingTransformer._createRefMark(descr.refIdx);
|
|
}
|
|
return null;
|
|
};
|
|
EncodingTransformer.prototype._handleValue = function (val, parent, key) {
|
|
var type = typeof val;
|
|
var isObject = type === 'object' && val !== null;
|
|
if (isObject) {
|
|
var refMark = this._ensureCircularReference(val);
|
|
if (refMark)
|
|
return refMark;
|
|
}
|
|
for (var i = 0; i < this.transforms.length; i++) {
|
|
var transform = this.transforms[i];
|
|
if (transform.shouldTransform(type, val))
|
|
return this._applyTransform(val, parent, key, transform);
|
|
}
|
|
if (isObject)
|
|
return this._handleObject(val, parent, key);
|
|
return val;
|
|
};
|
|
EncodingTransformer.prototype.transform = function () {
|
|
var references = [this._handleValue(this.references, null, null)];
|
|
for (var i = 0; i < this.circularCandidatesDescrs.length; i++) {
|
|
var descr = this.circularCandidatesDescrs[i];
|
|
if (descr.refIdx > 0) {
|
|
references[descr.refIdx] = descr.parent[descr.key];
|
|
descr.parent[descr.key] = EncodingTransformer._createRefMark(descr.refIdx);
|
|
}
|
|
}
|
|
return references;
|
|
};
|
|
// DecodingTransform
|
|
var DecodingTransformer = function (references, transformsMap) {
|
|
this.references = references;
|
|
this.transformMap = transformsMap;
|
|
this.activeTransformsStack = [];
|
|
this.visitedRefs = Object.create(null);
|
|
};
|
|
DecodingTransformer.prototype._handlePlainObject = function (obj) {
|
|
var replicator = this;
|
|
var unescaped = Object.create(null);
|
|
var ownPropertyNames = Object.getOwnPropertyNames(obj);
|
|
ownPropertyNames.forEach(function (key) {
|
|
replicator._handleValue(obj[key], obj, key);
|
|
if (KEY_REQUIRE_ESCAPING_RE.test(key)) {
|
|
// NOTE: use intermediate object to avoid unescaped and escaped keys interference
|
|
// E.g. unescaped "##@t" will be "#@t" which can overwrite escaped "#@t".
|
|
unescaped[key.substring(1)] = obj[key];
|
|
delete obj[key];
|
|
}
|
|
});
|
|
for (var unsecapedKey in unescaped)
|
|
obj[unsecapedKey] = unescaped[unsecapedKey];
|
|
};
|
|
DecodingTransformer.prototype._handleTransformedObject = function (obj, parent, key) {
|
|
var transformType = obj[TRANSFORMED_TYPE_KEY];
|
|
var transform = this.transformMap[transformType];
|
|
if (!transform)
|
|
throw new Error('Can\'t find transform for "' + transformType + '" type.');
|
|
this.activeTransformsStack.push(obj);
|
|
this._handleValue(obj.data, obj, 'data');
|
|
this.activeTransformsStack.pop();
|
|
parent[key] = transform.fromSerializable(obj.data);
|
|
};
|
|
DecodingTransformer.prototype._handleCircularSelfRefDuringTransform = function (refIdx, parent, key) {
|
|
// NOTE: we've hit a hard case: object reference itself during transformation.
|
|
// We can't dereference it since we don't have resulting object yet. And we'll
|
|
// not be able to restore reference lately because we will need to traverse
|
|
// transformed object again and reference might be unreachable or new object contain
|
|
// new circular references. As a workaround we create getter, so once transformation
|
|
// complete, dereferenced property will point to correct transformed object.
|
|
var references = this.references;
|
|
var val = void 0;
|
|
Object.defineProperty(parent, key, {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get: function () {
|
|
if (val === void 0)
|
|
val = references[refIdx];
|
|
return val;
|
|
},
|
|
set: function (value) {
|
|
val = value;
|
|
return val;
|
|
}
|
|
});
|
|
};
|
|
DecodingTransformer.prototype._handleCircularRef = function (refIdx, parent, key) {
|
|
if (this.activeTransformsStack.indexOf(this.references[refIdx]) > -1)
|
|
this._handleCircularSelfRefDuringTransform(refIdx, parent, key);
|
|
else {
|
|
if (!this.visitedRefs[refIdx]) {
|
|
this.visitedRefs[refIdx] = true;
|
|
this._handleValue(this.references[refIdx], this.references, refIdx);
|
|
}
|
|
parent[key] = this.references[refIdx];
|
|
}
|
|
};
|
|
DecodingTransformer.prototype._handleValue = function (val, parent, key) {
|
|
if (typeof val !== 'object' || val === null)
|
|
return;
|
|
var refIdx = val[CIRCULAR_REF_KEY];
|
|
if (refIdx !== void 0)
|
|
this._handleCircularRef(refIdx, parent, key);
|
|
else if (val[TRANSFORMED_TYPE_KEY])
|
|
this._handleTransformedObject(val, parent, key);
|
|
else if (Array.isArray(val)) {
|
|
for (var i = 0; i < val.length; i++)
|
|
this._handleValue(val[i], val, i);
|
|
}
|
|
else
|
|
this._handlePlainObject(val);
|
|
};
|
|
DecodingTransformer.prototype.transform = function () {
|
|
this.visitedRefs[0] = true;
|
|
this._handleValue(this.references[0], this.references, 0);
|
|
return this.references[0];
|
|
};
|
|
// Transforms
|
|
var builtInTransforms = [
|
|
{
|
|
type: '[[NaN]]',
|
|
shouldTransform: function (type, val) {
|
|
return type === 'number' && isNaN(val);
|
|
},
|
|
toSerializable: function () {
|
|
return '';
|
|
},
|
|
fromSerializable: function () {
|
|
return NaN;
|
|
}
|
|
},
|
|
{
|
|
type: '[[undefined]]',
|
|
shouldTransform: function (type) {
|
|
return type === 'undefined';
|
|
},
|
|
toSerializable: function () {
|
|
return '';
|
|
},
|
|
fromSerializable: function () {
|
|
return void 0;
|
|
}
|
|
},
|
|
{
|
|
type: '[[Date]]',
|
|
shouldTransform: function (type, val) {
|
|
return val instanceof Date;
|
|
},
|
|
toSerializable: function (date) {
|
|
return date.getTime();
|
|
},
|
|
fromSerializable: function (val) {
|
|
var date = new Date();
|
|
date.setTime(val);
|
|
return date;
|
|
}
|
|
},
|
|
{
|
|
type: '[[RegExp]]',
|
|
shouldTransform: function (type, val) {
|
|
return val instanceof RegExp;
|
|
},
|
|
toSerializable: function (re) {
|
|
var result = {
|
|
src: re.source,
|
|
flags: ''
|
|
};
|
|
if (re.global)
|
|
result.flags += 'g';
|
|
if (re.ignoreCase)
|
|
result.flags += 'i';
|
|
if (re.multiline)
|
|
result.flags += 'm';
|
|
return result;
|
|
},
|
|
fromSerializable: function (val) {
|
|
return new RegExp(val.src, val.flags);
|
|
}
|
|
},
|
|
{
|
|
type: '[[Error]]',
|
|
shouldTransform: function (type, val) {
|
|
return val instanceof Error;
|
|
},
|
|
toSerializable: function (err) {
|
|
return {
|
|
name: err.name,
|
|
message: err.message,
|
|
stack: err.stack
|
|
};
|
|
},
|
|
fromSerializable: function (val) {
|
|
var Ctor = GLOBAL[val.name] || Error;
|
|
var err = new Ctor(val.message);
|
|
err.stack = val.stack;
|
|
return err;
|
|
}
|
|
},
|
|
{
|
|
type: '[[ArrayBuffer]]',
|
|
shouldTransform: function (type, val) {
|
|
return ARRAY_BUFFER_SUPPORTED && val instanceof ArrayBuffer;
|
|
},
|
|
toSerializable: function (buffer) {
|
|
var view = new Int8Array(buffer);
|
|
return arrSlice.call(view);
|
|
},
|
|
fromSerializable: function (val) {
|
|
if (ARRAY_BUFFER_SUPPORTED) {
|
|
var buffer = new ArrayBuffer(val.length);
|
|
var view = new Int8Array(buffer);
|
|
view.set(val);
|
|
return buffer;
|
|
}
|
|
return val;
|
|
}
|
|
},
|
|
{
|
|
type: '[[Buffer]]',
|
|
shouldTransform: function (type, val) {
|
|
return BUFFER_FROM_SUPPORTED && val instanceof Buffer;
|
|
},
|
|
toSerializable: function (buffer) {
|
|
return arrSlice.call(buffer);
|
|
},
|
|
fromSerializable: function (val) {
|
|
if (BUFFER_FROM_SUPPORTED)
|
|
return Buffer.from(val);
|
|
return val;
|
|
}
|
|
},
|
|
{
|
|
type: '[[TypedArray]]',
|
|
shouldTransform: function (type, val) {
|
|
return Object.keys(TYPED_ARRAY_CTORS).some(function (ctorName) {
|
|
return TYPED_ARRAY_SUPPORTED(ctorName) && val instanceof TYPED_ARRAY_CTORS[ctorName];
|
|
});
|
|
},
|
|
toSerializable: function (arr) {
|
|
return {
|
|
ctorName: arr.constructor.name,
|
|
arr: arrSlice.call(arr)
|
|
};
|
|
},
|
|
fromSerializable: function (val) {
|
|
return TYPED_ARRAY_SUPPORTED(val.ctorName) ? new TYPED_ARRAY_CTORS[val.ctorName](val.arr) : val.arr;
|
|
}
|
|
},
|
|
{
|
|
type: '[[Map]]',
|
|
shouldTransform: function (type, val) {
|
|
return MAP_SUPPORTED && val instanceof Map;
|
|
},
|
|
toSerializable: function (map) {
|
|
var flattenedKVArr = [];
|
|
map.forEach(function (val, key) {
|
|
flattenedKVArr.push(key);
|
|
flattenedKVArr.push(val);
|
|
});
|
|
return flattenedKVArr;
|
|
},
|
|
fromSerializable: function (val) {
|
|
if (MAP_SUPPORTED) {
|
|
// NOTE: new Map(iterable) is not supported by all browsers
|
|
var map = new Map();
|
|
for (var i = 0; i < val.length; i += 2)
|
|
map.set(val[i], val[i + 1]);
|
|
return map;
|
|
}
|
|
var kvArr = [];
|
|
for (var j = 0; j < val.length; j += 2)
|
|
kvArr.push([val[i], val[i + 1]]);
|
|
return kvArr;
|
|
}
|
|
},
|
|
{
|
|
type: '[[Set]]',
|
|
shouldTransform: function (type, val) {
|
|
return SET_SUPPORTED && val instanceof Set;
|
|
},
|
|
toSerializable: function (set) {
|
|
var arr = [];
|
|
set.forEach(function (val) {
|
|
arr.push(val);
|
|
});
|
|
return arr;
|
|
},
|
|
fromSerializable: function (val) {
|
|
if (SET_SUPPORTED) {
|
|
// NOTE: new Set(iterable) is not supported by all browsers
|
|
var set = new Set();
|
|
for (var i = 0; i < val.length; i++)
|
|
set.add(val[i]);
|
|
return set;
|
|
}
|
|
return val;
|
|
}
|
|
}
|
|
];
|
|
// Replicator
|
|
var Replicator = module.exports = function (serializer) {
|
|
this.transforms = [];
|
|
this.transformsMap = Object.create(null);
|
|
this.serializer = serializer || JSONSerializer;
|
|
this.addTransforms(builtInTransforms);
|
|
};
|
|
// Manage transforms
|
|
Replicator.prototype.addTransforms = function (transforms) {
|
|
transforms = Array.isArray(transforms) ? transforms : [transforms];
|
|
for (var i = 0; i < transforms.length; i++) {
|
|
var transform = transforms[i];
|
|
if (this.transformsMap[transform.type])
|
|
throw new Error('Transform with type "' + transform.type + '" was already added.');
|
|
this.transforms.push(transform);
|
|
this.transformsMap[transform.type] = transform;
|
|
}
|
|
return this;
|
|
};
|
|
Replicator.prototype.removeTransforms = function (transforms) {
|
|
transforms = Array.isArray(transforms) ? transforms : [transforms];
|
|
for (var i = 0; i < transforms.length; i++) {
|
|
var transform = transforms[i];
|
|
var idx = this.transforms.indexOf(transform);
|
|
if (idx > -1)
|
|
this.transforms.splice(idx, 1);
|
|
delete this.transformsMap[transform.type];
|
|
}
|
|
return this;
|
|
};
|
|
Replicator.prototype.encode = function (val) {
|
|
var transformer = new EncodingTransformer(val, this.transforms);
|
|
var references = transformer.transform();
|
|
return this.serializer.serialize(references);
|
|
};
|
|
Replicator.prototype.decode = function (val) {
|
|
var references = this.serializer.deserialize(val);
|
|
var transformer = new DecodingTransformer(references, this.transformsMap);
|
|
return transformer.transform();
|
|
};
|
|
});
|
|
|
|
var identity = function (val) { return val; };
|
|
function createReplicator(transforms) {
|
|
// NOTE: we will serialize replicator results
|
|
// to JSON with a command or command result.
|
|
// Therefore there is no need to do additional job here,
|
|
// so we use identity functions for serialization.
|
|
var replicator$1 = new replicator({
|
|
serialize: identity,
|
|
deserialize: identity,
|
|
});
|
|
return replicator$1.addTransforms(transforms);
|
|
}
|
|
|
|
// @ts-ignore
|
|
function isNodeCollection(obj) {
|
|
return obj instanceof hammerhead.nativeMethods.HTMLCollection || obj instanceof hammerhead.nativeMethods.NodeList;
|
|
}
|
|
function castToArray(list) {
|
|
var length = list.length;
|
|
var result = [];
|
|
for (var i = 0; i < length; i++)
|
|
result.push(list[i]);
|
|
return result;
|
|
}
|
|
function isArrayOfNodes(obj) {
|
|
if (!hammerhead.nativeMethods.isArray(obj))
|
|
return false;
|
|
for (var i = 0; i < obj.length; i++) {
|
|
// @ts-ignore
|
|
if (!(obj[i] instanceof hammerhead.nativeMethods.Node))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
var _a;
|
|
var SELECTOR_FILTER_ERROR = {
|
|
filterVisible: 1,
|
|
filterHidden: 2,
|
|
nth: 3,
|
|
};
|
|
var FILTER_ERROR_TO_API_RE = (_a = {},
|
|
_a[SELECTOR_FILTER_ERROR.filterVisible] = /^\.filterVisible\(\)$/,
|
|
_a[SELECTOR_FILTER_ERROR.filterHidden] = /^\.filterHidden\(\)$/,
|
|
_a[SELECTOR_FILTER_ERROR.nth] = /^\.nth\(\d+\)$/,
|
|
_a);
|
|
var SelectorFilter = /** @class */ (function () {
|
|
function SelectorFilter() {
|
|
this._err = null;
|
|
}
|
|
Object.defineProperty(SelectorFilter.prototype, "error", {
|
|
get: function () {
|
|
return this._err;
|
|
},
|
|
set: function (message) {
|
|
if (this._err === null)
|
|
this._err = message;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
SelectorFilter.prototype.filter = function (nodes, options, apiInfo) {
|
|
if (options.filterVisible) {
|
|
nodes = nodes.filter(testcafeCore.positionUtils.isElementVisible);
|
|
this._assertFilterError(nodes, apiInfo, SELECTOR_FILTER_ERROR.filterVisible);
|
|
}
|
|
if (options.filterHidden) {
|
|
nodes = nodes.filter(function (n) { return !testcafeCore.positionUtils.isElementVisible(n); });
|
|
this._assertFilterError(nodes, apiInfo, SELECTOR_FILTER_ERROR.filterHidden);
|
|
}
|
|
if (options.counterMode) {
|
|
if (options.index === null)
|
|
return nodes.length;
|
|
return SelectorFilter._getNodeByIndex(nodes, options.index) ? 1 : 0;
|
|
}
|
|
if (options.collectionMode) {
|
|
if (options.index !== null) {
|
|
var nodeOnIndex_1 = SelectorFilter._getNodeByIndex(nodes, options.index);
|
|
nodes = nodeOnIndex_1 ? [nodeOnIndex_1] : [];
|
|
this._assertFilterError(nodes, apiInfo, SELECTOR_FILTER_ERROR.nth);
|
|
}
|
|
return nodes;
|
|
}
|
|
var nodeOnIndex = SelectorFilter._getNodeByIndex(nodes, options.index || 0);
|
|
if (!nodeOnIndex)
|
|
this.error = SelectorFilter._getErrorItem(apiInfo, SELECTOR_FILTER_ERROR.nth);
|
|
return nodeOnIndex;
|
|
};
|
|
SelectorFilter.prototype.cast = function (searchResult) {
|
|
if (searchResult === null || searchResult === void 0)
|
|
return [];
|
|
else if (searchResult instanceof hammerhead.nativeMethods.Node)
|
|
return [searchResult];
|
|
else if (isArrayOfNodes(searchResult))
|
|
return searchResult;
|
|
else if (isNodeCollection(searchResult))
|
|
return castToArray(searchResult);
|
|
throw new InvalidSelectorResultError();
|
|
};
|
|
SelectorFilter.prototype._assertFilterError = function (filtered, apiInfo, filterError) {
|
|
if (filtered.length === 0)
|
|
this.error = SelectorFilter._getErrorItem(apiInfo, filterError);
|
|
};
|
|
SelectorFilter._getErrorItem = function (_a, err) {
|
|
var apiFnChain = _a.apiFnChain, apiFnID = _a.apiFnID;
|
|
if (err) {
|
|
for (var i = apiFnID; i < apiFnChain.length; i++) {
|
|
if (FILTER_ERROR_TO_API_RE[err].test(apiFnChain[i]))
|
|
return i;
|
|
}
|
|
}
|
|
return null;
|
|
};
|
|
SelectorFilter._getNodeByIndex = function (nodes, index) {
|
|
return index < 0 ? nodes[nodes.length + index] : nodes[index];
|
|
};
|
|
return SelectorFilter;
|
|
}());
|
|
var selectorFilter = new SelectorFilter();
|
|
|
|
// @ts-ignore
|
|
// NOTE: evalFunction is isolated into a separate module to
|
|
// restrict access to TestCafe intrinsics for the evaluated code.
|
|
// It also accepts `__dependencies$` argument which may be used by evaluated code.
|
|
function evalFunction(fnCode, __dependencies$) {
|
|
var FunctionCtor = hammerhead.nativeMethods.Function;
|
|
var evaluator = new FunctionCtor('fnCode', '__dependencies$', 'Promise',
|
|
// NOTE: we should pass the original `RegExp`
|
|
// to make the `instanceof RegExp` check successful in different contexts
|
|
'RegExp',
|
|
// NOTE: `eval` in strict mode will not override context variables
|
|
'"use strict"; return eval(fnCode)');
|
|
return evaluator(fnCode, __dependencies$, hammerhead.Promise, RegExp);
|
|
}
|
|
|
|
var FunctionTransform = /** @class */ (function () {
|
|
function FunctionTransform() {
|
|
this.type = 'Function';
|
|
}
|
|
FunctionTransform.prototype.shouldTransform = function (type) {
|
|
return type === 'function';
|
|
};
|
|
FunctionTransform.prototype.toSerializable = function () {
|
|
return '';
|
|
};
|
|
// HACK: UglifyJS + TypeScript + argument destructuring can generate incorrect code.
|
|
// So we have to use plain assignments here.
|
|
FunctionTransform.prototype.fromSerializable = function (opts) {
|
|
var fnCode = opts.fnCode;
|
|
var dependencies = opts.dependencies;
|
|
if ('filterOptions' in dependencies)
|
|
dependencies.selectorFilter = selectorFilter;
|
|
return evalFunction(fnCode, dependencies);
|
|
};
|
|
return FunctionTransform;
|
|
}());
|
|
|
|
var ClientFunctionNodeTransform = /** @class */ (function () {
|
|
function ClientFunctionNodeTransform(instantiationCallsiteName) {
|
|
this.type = 'Node';
|
|
this._instantiationCallsiteName = instantiationCallsiteName;
|
|
}
|
|
ClientFunctionNodeTransform.prototype.shouldTransform = function (type, val) {
|
|
if (val instanceof hammerhead.nativeMethods.Node)
|
|
throw new DomNodeClientFunctionResultError(this._instantiationCallsiteName);
|
|
return false;
|
|
};
|
|
ClientFunctionNodeTransform.prototype.toSerializable = function () {
|
|
};
|
|
ClientFunctionNodeTransform.prototype.fromSerializable = function () {
|
|
};
|
|
return ClientFunctionNodeTransform;
|
|
}());
|
|
|
|
var ClientFunctionExecutor = /** @class */ (function () {
|
|
function ClientFunctionExecutor(command) {
|
|
this.command = command;
|
|
this.replicator = this._createReplicator();
|
|
this.dependencies = this.replicator.decode(command.dependencies);
|
|
this.fn = evalFunction(command.fnCode, this.dependencies);
|
|
}
|
|
ClientFunctionExecutor.prototype.getResult = function () {
|
|
var _this = this;
|
|
return hammerhead.Promise.resolve()
|
|
.then(function () {
|
|
var args = _this.replicator.decode(_this.command.args);
|
|
return _this._executeFn(args);
|
|
})
|
|
.catch(function (err) {
|
|
if (!err.isTestCafeError)
|
|
err = new UncaughtErrorInClientFunctionCode(_this.command.instantiationCallsiteName, err);
|
|
throw err;
|
|
});
|
|
};
|
|
ClientFunctionExecutor.prototype.encodeResult = function (result) {
|
|
return this.replicator.encode(result);
|
|
};
|
|
ClientFunctionExecutor.prototype._createReplicator = function () {
|
|
return createReplicator([
|
|
new ClientFunctionNodeTransform(this.command.instantiationCallsiteName),
|
|
new FunctionTransform(),
|
|
]);
|
|
};
|
|
ClientFunctionExecutor.prototype._executeFn = function (args) {
|
|
return this.fn.apply(window, args);
|
|
};
|
|
return ClientFunctionExecutor;
|
|
}());
|
|
|
|
var MESSAGE_TYPE = {
|
|
appearedDialog: 'appeared-dialog',
|
|
unexpectedDialog: 'unexpected-dialog',
|
|
handlerError: 'handler-error',
|
|
};
|
|
|
|
var messageSandbox = hammerhead__default.eventSandbox.message;
|
|
var processScript = hammerhead__default.processScript;
|
|
var nativeMethods = hammerhead__default.nativeMethods;
|
|
var APPEARED_DIALOGS = 'testcafe|native-dialog-tracker|appeared-dialogs';
|
|
var UNEXPECTED_DIALOG = 'testcafe|native-dialog-tracker|unexpected-dialog';
|
|
var ERROR_IN_HANDLER = 'testcafe|native-dialog-tracker|error-in-handler';
|
|
var GETTING_PAGE_URL_PROCESSED_SCRIPT = processScript('window.location.href');
|
|
var NativeDialogTracker = /** @class */ (function () {
|
|
function NativeDialogTracker(contextStorage, _a) {
|
|
var _b = _a === void 0 ? {} : _a, dialogHandler = _b.dialogHandler;
|
|
this.contextStorage = contextStorage;
|
|
this.dialogHandler = dialogHandler;
|
|
this._init();
|
|
this._initListening();
|
|
if (this.dialogHandler)
|
|
this.setHandler(dialogHandler);
|
|
}
|
|
Object.defineProperty(NativeDialogTracker.prototype, "appearedDialogs", {
|
|
get: function () {
|
|
var dialogs = this.contextStorage.getItem(APPEARED_DIALOGS);
|
|
if (!dialogs) {
|
|
dialogs = [];
|
|
this.appearedDialogs = dialogs;
|
|
}
|
|
return dialogs;
|
|
},
|
|
set: function (dialog) {
|
|
this.contextStorage.setItem(APPEARED_DIALOGS, dialog);
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(NativeDialogTracker.prototype, "unexpectedDialog", {
|
|
get: function () {
|
|
return this.contextStorage.getItem(UNEXPECTED_DIALOG);
|
|
},
|
|
set: function (dialog) {
|
|
this.contextStorage.setItem(UNEXPECTED_DIALOG, dialog);
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(NativeDialogTracker.prototype, "handlerError", {
|
|
get: function () {
|
|
return this.contextStorage.getItem(ERROR_IN_HANDLER);
|
|
},
|
|
set: function (dialog) {
|
|
this.contextStorage.setItem(ERROR_IN_HANDLER, dialog);
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
NativeDialogTracker._getPageUrl = function () {
|
|
return nativeMethods.eval(GETTING_PAGE_URL_PROCESSED_SCRIPT);
|
|
};
|
|
NativeDialogTracker.prototype._initListening = function () {
|
|
var _this = this;
|
|
messageSandbox.on(messageSandbox.SERVICE_MSG_RECEIVED_EVENT, function (e) {
|
|
var msg = e.message;
|
|
if (msg.type === MESSAGE_TYPE.appearedDialog)
|
|
// eslint-disable-next-line no-restricted-properties
|
|
_this._addAppearedDialogs(msg.dialogType, msg.text, msg.url);
|
|
else if (msg.type === MESSAGE_TYPE.unexpectedDialog && !_this.unexpectedDialog)
|
|
_this.unexpectedDialog = { type: msg.dialogType, url: msg.url };
|
|
else if (msg.type === MESSAGE_TYPE.handlerError && !_this.handlerError)
|
|
_this._onHandlerError(msg.dialogType, msg.message, msg.url);
|
|
});
|
|
};
|
|
NativeDialogTracker.prototype._init = function () {
|
|
var _this = this;
|
|
hammerhead__default.on(hammerhead__default.EVENTS.beforeUnload, function (e) {
|
|
if (e.prevented && !e.isFakeIEEvent) {
|
|
if (_this.dialogHandler) {
|
|
var handler = _this._createDialogHandler('beforeunload');
|
|
handler(e.returnValue || '');
|
|
}
|
|
else
|
|
_this._defaultDialogHandler('beforeunload');
|
|
}
|
|
// NOTE: we should save changes that could be made via 'shift' and 'push' methods.
|
|
if (_this.contextStorage)
|
|
_this.contextStorage.save();
|
|
});
|
|
window.alert = function () { return _this._defaultDialogHandler('alert'); };
|
|
window.confirm = function () { return _this._defaultDialogHandler('confirm'); };
|
|
window.prompt = function () { return _this._defaultDialogHandler('prompt'); };
|
|
};
|
|
NativeDialogTracker.prototype._createDialogHandler = function (type) {
|
|
var _this = this;
|
|
return function (text) {
|
|
var url = NativeDialogTracker._getPageUrl();
|
|
_this._addAppearedDialogs(type, text, url);
|
|
var executor = new ClientFunctionExecutor(_this.dialogHandler);
|
|
var result = null;
|
|
try {
|
|
result = executor.fn.apply(window, [type, text, url]);
|
|
}
|
|
catch (err) {
|
|
_this._onHandlerError(type, err.message || String(err), url);
|
|
}
|
|
return result;
|
|
};
|
|
};
|
|
// Overridable methods
|
|
NativeDialogTracker.prototype._defaultDialogHandler = function (type) {
|
|
var url = NativeDialogTracker._getPageUrl();
|
|
this.unexpectedDialog = this.unexpectedDialog || { type: type, url: url };
|
|
};
|
|
NativeDialogTracker.prototype._addAppearedDialogs = function (type, text, url) {
|
|
this.appearedDialogs.splice(0, 0, { type: type, text: text, url: url });
|
|
};
|
|
NativeDialogTracker.prototype._onHandlerError = function (type, message, url) {
|
|
this.handlerError = this.handlerError || { type: type, message: message, url: url };
|
|
};
|
|
// API
|
|
NativeDialogTracker.prototype.setHandler = function (dialogHandler) {
|
|
var _this = this;
|
|
this.dialogHandler = dialogHandler;
|
|
['alert', 'confirm', 'prompt'].forEach(function (dialogType) {
|
|
window[dialogType] = _this.dialogHandler ?
|
|
_this._createDialogHandler(dialogType) :
|
|
function () { return _this._defaultDialogHandler(dialogType); };
|
|
});
|
|
};
|
|
NativeDialogTracker.prototype.getUnexpectedDialogError = function () {
|
|
var unexpectedDialog = this.unexpectedDialog;
|
|
var handlerError = this.handlerError;
|
|
this.unexpectedDialog = null;
|
|
this.handlerError = null;
|
|
if (unexpectedDialog)
|
|
return new NativeDialogNotHandledError(unexpectedDialog.type, unexpectedDialog.url);
|
|
if (handlerError)
|
|
return new UncaughtErrorInNativeDialogHandler(handlerError.type, handlerError.message, handlerError.url);
|
|
return null;
|
|
};
|
|
return NativeDialogTracker;
|
|
}());
|
|
|
|
function generateId () {
|
|
return hammerhead.nativeMethods.performanceNow().toString();
|
|
}
|
|
|
|
var TYPE = {
|
|
establishConnection: 'driver|establish-connection',
|
|
switchToWindow: 'driver|switch-to-window',
|
|
closeWindow: 'driver|close-window',
|
|
closeWindowValidation: 'driver|close-window-validation',
|
|
switchToWindowValidation: 'driver|switch-to-window-validation',
|
|
getWindows: 'driver|get-windows',
|
|
commandExecuted: 'driver|command-executed',
|
|
executeCommand: 'driver|execute-command',
|
|
confirmation: 'driver|confirmation',
|
|
setNativeDialogHandler: 'driver|set-native-dialog-handler',
|
|
setAsMaster: 'driver|set-as-master',
|
|
closeAllChildWindows: 'driver|close-all-child-windows',
|
|
startToRestoreChildLink: 'driver|start-to-restore-child-link',
|
|
restoreChildLink: 'driver|restore-child-link',
|
|
childWindowIsLoadedInIFrame: 'driver|child-window-is-loaded-in-iframe',
|
|
childWindowIsOpenedInIFrame: 'driver|child-window-is-opened-in-iframe',
|
|
stopInternalFromFrame: 'driver|stop-internal-from-iframe',
|
|
hasPendingActionFlags: 'driver|has-pending-action-flags',
|
|
};
|
|
var InterDriverMessage = /** @class */ (function () {
|
|
function InterDriverMessage(type) {
|
|
this.type = type;
|
|
this.id = generateId();
|
|
}
|
|
return InterDriverMessage;
|
|
}());
|
|
var EstablishConnectionMessage = /** @class */ (function (_super) {
|
|
__extends(EstablishConnectionMessage, _super);
|
|
function EstablishConnectionMessage() {
|
|
return _super.call(this, TYPE.establishConnection) || this;
|
|
}
|
|
return EstablishConnectionMessage;
|
|
}(InterDriverMessage));
|
|
var CloseWindowValidationMessage = /** @class */ (function (_super) {
|
|
__extends(CloseWindowValidationMessage, _super);
|
|
function CloseWindowValidationMessage(_a) {
|
|
var windowId = _a.windowId;
|
|
var _this = _super.call(this, TYPE.closeWindowValidation) || this;
|
|
_this.windowId = windowId;
|
|
return _this;
|
|
}
|
|
return CloseWindowValidationMessage;
|
|
}(InterDriverMessage));
|
|
var SwitchToWindowValidationMessage = /** @class */ (function (_super) {
|
|
__extends(SwitchToWindowValidationMessage, _super);
|
|
function SwitchToWindowValidationMessage(_a) {
|
|
var windowId = _a.windowId, fn = _a.fn;
|
|
var _this = _super.call(this, TYPE.switchToWindowValidation) || this;
|
|
_this.windowId = windowId;
|
|
_this.fn = fn;
|
|
return _this;
|
|
}
|
|
return SwitchToWindowValidationMessage;
|
|
}(InterDriverMessage));
|
|
var GetWindowsMessage = /** @class */ (function (_super) {
|
|
__extends(GetWindowsMessage, _super);
|
|
function GetWindowsMessage() {
|
|
return _super.call(this, TYPE.getWindows) || this;
|
|
}
|
|
return GetWindowsMessage;
|
|
}(InterDriverMessage));
|
|
var CloseWindowCommandMessage = /** @class */ (function (_super) {
|
|
__extends(CloseWindowCommandMessage, _super);
|
|
function CloseWindowCommandMessage(_a) {
|
|
var windowId = _a.windowId, isCurrentWindow = _a.isCurrentWindow;
|
|
var _this = _super.call(this, TYPE.closeWindow) || this;
|
|
_this.windowId = windowId;
|
|
_this.isCurrentWindow = isCurrentWindow;
|
|
return _this;
|
|
}
|
|
return CloseWindowCommandMessage;
|
|
}(InterDriverMessage));
|
|
var SwitchToWindowCommandMessage = /** @class */ (function (_super) {
|
|
__extends(SwitchToWindowCommandMessage, _super);
|
|
function SwitchToWindowCommandMessage(_a) {
|
|
var windowId = _a.windowId, fn = _a.fn;
|
|
var _this = _super.call(this, TYPE.switchToWindow) || this;
|
|
_this.windowId = windowId;
|
|
_this.fn = fn;
|
|
return _this;
|
|
}
|
|
return SwitchToWindowCommandMessage;
|
|
}(InterDriverMessage));
|
|
var CommandExecutedMessage = /** @class */ (function (_super) {
|
|
__extends(CommandExecutedMessage, _super);
|
|
function CommandExecutedMessage(driverStatus) {
|
|
var _this = _super.call(this, TYPE.commandExecuted) || this;
|
|
_this.driverStatus = driverStatus;
|
|
return _this;
|
|
}
|
|
return CommandExecutedMessage;
|
|
}(InterDriverMessage));
|
|
var ExecuteCommandMessage = /** @class */ (function (_super) {
|
|
__extends(ExecuteCommandMessage, _super);
|
|
function ExecuteCommandMessage(command, testSpeed, leftTopPoint) {
|
|
var _this = _super.call(this, TYPE.executeCommand) || this;
|
|
_this.command = command;
|
|
_this.testSpeed = testSpeed;
|
|
_this.leftTopPoint = leftTopPoint;
|
|
return _this;
|
|
}
|
|
return ExecuteCommandMessage;
|
|
}(InterDriverMessage));
|
|
var ConfirmationMessage = /** @class */ (function (_super) {
|
|
__extends(ConfirmationMessage, _super);
|
|
function ConfirmationMessage(requestMessageId, result) {
|
|
var _this = _super.call(this, TYPE.confirmation) || this;
|
|
_this.requestMessageId = requestMessageId;
|
|
_this.result = result;
|
|
return _this;
|
|
}
|
|
return ConfirmationMessage;
|
|
}(InterDriverMessage));
|
|
var SetNativeDialogHandlerMessage = /** @class */ (function (_super) {
|
|
__extends(SetNativeDialogHandlerMessage, _super);
|
|
function SetNativeDialogHandlerMessage(dialogHandler) {
|
|
var _this = _super.call(this, TYPE.setNativeDialogHandler) || this;
|
|
_this.dialogHandler = dialogHandler;
|
|
return _this;
|
|
}
|
|
return SetNativeDialogHandlerMessage;
|
|
}(InterDriverMessage));
|
|
var SetAsMasterMessage = /** @class */ (function (_super) {
|
|
__extends(SetAsMasterMessage, _super);
|
|
function SetAsMasterMessage(finalizePendingCommand) {
|
|
var _this = _super.call(this, TYPE.setAsMaster) || this;
|
|
_this.finalizePendingCommand = finalizePendingCommand;
|
|
return _this;
|
|
}
|
|
return SetAsMasterMessage;
|
|
}(InterDriverMessage));
|
|
var CloseAllChildWindowsMessage = /** @class */ (function (_super) {
|
|
__extends(CloseAllChildWindowsMessage, _super);
|
|
function CloseAllChildWindowsMessage() {
|
|
return _super.call(this, TYPE.closeAllChildWindows) || this;
|
|
}
|
|
return CloseAllChildWindowsMessage;
|
|
}(InterDriverMessage));
|
|
var StartToRestoreChildLinkMessage = /** @class */ (function (_super) {
|
|
__extends(StartToRestoreChildLinkMessage, _super);
|
|
function StartToRestoreChildLinkMessage() {
|
|
return _super.call(this, TYPE.startToRestoreChildLink) || this;
|
|
}
|
|
return StartToRestoreChildLinkMessage;
|
|
}(InterDriverMessage));
|
|
var RestoreChildLinkMessage = /** @class */ (function (_super) {
|
|
__extends(RestoreChildLinkMessage, _super);
|
|
function RestoreChildLinkMessage(windowId) {
|
|
var _this = _super.call(this, TYPE.restoreChildLink) || this;
|
|
_this.windowId = windowId;
|
|
return _this;
|
|
}
|
|
return RestoreChildLinkMessage;
|
|
}(InterDriverMessage));
|
|
var ChildWindowIsLoadedInFrameMessage = /** @class */ (function (_super) {
|
|
__extends(ChildWindowIsLoadedInFrameMessage, _super);
|
|
function ChildWindowIsLoadedInFrameMessage(windowId) {
|
|
var _this = _super.call(this, TYPE.childWindowIsLoadedInIFrame) || this;
|
|
_this.windowId = windowId;
|
|
return _this;
|
|
}
|
|
return ChildWindowIsLoadedInFrameMessage;
|
|
}(InterDriverMessage));
|
|
var ChildWindowIsOpenedInFrameMessage = /** @class */ (function (_super) {
|
|
__extends(ChildWindowIsOpenedInFrameMessage, _super);
|
|
function ChildWindowIsOpenedInFrameMessage() {
|
|
return _super.call(this, TYPE.childWindowIsOpenedInIFrame) || this;
|
|
}
|
|
return ChildWindowIsOpenedInFrameMessage;
|
|
}(InterDriverMessage));
|
|
var StopInternalFromFrameMessage = /** @class */ (function (_super) {
|
|
__extends(StopInternalFromFrameMessage, _super);
|
|
function StopInternalFromFrameMessage() {
|
|
return _super.call(this, TYPE.stopInternalFromFrame) || this;
|
|
}
|
|
return StopInternalFromFrameMessage;
|
|
}(InterDriverMessage));
|
|
var HasPendingActionFlagsMessage = /** @class */ (function (_super) {
|
|
__extends(HasPendingActionFlagsMessage, _super);
|
|
function HasPendingActionFlagsMessage() {
|
|
return _super.call(this, TYPE.hasPendingActionFlags) || this;
|
|
}
|
|
return HasPendingActionFlagsMessage;
|
|
}(InterDriverMessage));
|
|
|
|
var JSON$1 = hammerhead__default.json;
|
|
var nativeMethods$1 = hammerhead__default.nativeMethods;
|
|
var STORAGE_KEY_PREFIX = 'testcafe|driver|';
|
|
var PROXYLESS_STORAGE_KEY = '%proxylessContextStorage%';
|
|
var StorageStrategyBase = /** @class */ (function () {
|
|
function StorageStrategyBase() {
|
|
}
|
|
StorageStrategyBase.prototype.loadFromStorage = function () {
|
|
var res = {};
|
|
var savedData = this._getData();
|
|
if (savedData) {
|
|
res = JSON$1.parse(savedData);
|
|
this._deleteData();
|
|
}
|
|
return res;
|
|
};
|
|
StorageStrategyBase.prototype._getData = function () {
|
|
throw new Error('Not implemented');
|
|
};
|
|
StorageStrategyBase.prototype._deleteData = function () {
|
|
throw new Error('Not implemented');
|
|
};
|
|
StorageStrategyBase.prototype.save = function () {
|
|
throw new Error('Not implemented');
|
|
};
|
|
StorageStrategyBase.prototype.sync = function () {
|
|
};
|
|
StorageStrategyBase.prototype.dispose = function () {
|
|
this._deleteData();
|
|
};
|
|
return StorageStrategyBase;
|
|
}());
|
|
var StorageStrategyProxy = /** @class */ (function (_super) {
|
|
__extends(StorageStrategyProxy, _super);
|
|
function StorageStrategyProxy(window, testRunId, windowId) {
|
|
var _this = _super.call(this) || this;
|
|
_this.storage = nativeMethods$1.winSessionStorageGetter.call(window);
|
|
_this.storageKey = _this._createStorageKey(testRunId, windowId);
|
|
return _this;
|
|
}
|
|
StorageStrategyProxy.prototype._createStorageKey = function (testRunId, windowId) {
|
|
var storageKey = STORAGE_KEY_PREFIX + testRunId;
|
|
if (windowId)
|
|
return storageKey + '|' + windowId;
|
|
return storageKey;
|
|
};
|
|
StorageStrategyProxy.prototype._getData = function () {
|
|
return nativeMethods$1.storageGetItem.call(this.storage, this.storageKey);
|
|
};
|
|
StorageStrategyProxy.prototype._deleteData = function () {
|
|
nativeMethods$1.storageRemoveItem.call(this.storage, this.storageKey);
|
|
};
|
|
StorageStrategyProxy.prototype.save = function (data) {
|
|
nativeMethods$1.storageSetItem.call(this.storage, this.storageKey, JSON$1.stringify(data));
|
|
};
|
|
return StorageStrategyProxy;
|
|
}(StorageStrategyBase));
|
|
var StorageStrategyProxyless = /** @class */ (function (_super) {
|
|
__extends(StorageStrategyProxyless, _super);
|
|
function StorageStrategyProxyless(window, testRunId) {
|
|
var _this = _super.call(this) || this;
|
|
var _a = testRunId.split('-'), id = _a[0], frameId = _a[1];
|
|
_this.testRunId = id;
|
|
_this.frameId = frameId || 'main';
|
|
return _this;
|
|
}
|
|
StorageStrategyProxyless.prototype._getData = function () {
|
|
var _a;
|
|
return (_a = window[PROXYLESS_STORAGE_KEY]) === null || _a === void 0 ? void 0 : _a[this.frameId];
|
|
};
|
|
StorageStrategyProxyless.prototype._deleteData = function () {
|
|
window[PROXYLESS_STORAGE_KEY] = null;
|
|
};
|
|
StorageStrategyProxyless.prototype.save = function (data) {
|
|
if (window.PROXYLESS_STORAGE_BINDING) {
|
|
window.PROXYLESS_STORAGE_BINDING(JSON$1.stringify({
|
|
testRunId: this.testRunId,
|
|
frameDriverId: this.frameId,
|
|
data: JSON$1.stringify(data),
|
|
}));
|
|
}
|
|
};
|
|
return StorageStrategyProxyless;
|
|
}(StorageStrategyBase));
|
|
var Storage = /** @class */ (function () {
|
|
function Storage(window, _a) {
|
|
var testRunId = _a.testRunId, windowId = _a.windowId, proxyless = _a.proxyless;
|
|
this.strategy = this._createStorageStrategy(proxyless, window, testRunId, windowId);
|
|
this.data = this.strategy.loadFromStorage();
|
|
this.testRunId = testRunId;
|
|
}
|
|
Storage.prototype._createStorageStrategy = function (proxyless, window, testRunId, windowId) {
|
|
return proxyless ? new StorageStrategyProxyless(window, testRunId, windowId) : new StorageStrategyProxy(window, testRunId, windowId);
|
|
};
|
|
Storage.prototype.save = function () {
|
|
this.strategy.save(this.data);
|
|
};
|
|
Storage.prototype.setItem = function (prop, value) {
|
|
this.data[prop] = value;
|
|
this.save(this.data);
|
|
};
|
|
Storage.prototype.getItem = function (prop) {
|
|
return this.data[prop];
|
|
};
|
|
Storage.prototype.dispose = function () {
|
|
this.strategy.dispose();
|
|
};
|
|
return Storage;
|
|
}());
|
|
|
|
// -------------------------------------------------------------
|
|
// WARNING: this file is used by both the client and the server.
|
|
// Do not use any browser or node-specific API!
|
|
// -------------------------------------------------------------
|
|
var objectToString = Object.prototype.toString;
|
|
var stringIndexOf = String.prototype.indexOf;
|
|
var stringEndsWith = String.prototype.endsWith
|
|
|| function (searchString, position) {
|
|
var subjectString = objectToString.call(this);
|
|
if (position === void 0 || position > subjectString.length)
|
|
position = subjectString.length;
|
|
position -= searchString.length;
|
|
var lastIndex = stringIndexOf.call(subjectString, searchString, position);
|
|
return lastIndex !== -1 && lastIndex === position;
|
|
};
|
|
|
|
// -------------------------------------------------------------
|
|
var arrayIndexOf = Array.prototype.indexOf;
|
|
var arrayMap = Array.prototype.map;
|
|
var arraySort = Array.prototype.sort;
|
|
var arrayFilter = Array.prototype.filter;
|
|
var arrayConcat = Array.prototype.concat;
|
|
var COMMAND_NAME_SUFFIX = 'Command';
|
|
function validateObjectProps(obj, dest) {
|
|
var objectName = dest.constructor.name;
|
|
var validKeys = arrayMap.call(dest.getAllAssignableProperties(), function (p) { return p.name; });
|
|
var reportedProperties = arraySort.call(dest.getReportedProperties());
|
|
for (var key in obj) {
|
|
if (!(arrayIndexOf.call(validKeys, key) > -1 || key in dest))
|
|
throw new ActionInvalidObjectPropertyError(objectName, key, reportedProperties);
|
|
}
|
|
}
|
|
function getDisplayTypeName(constructorName, propName) {
|
|
if (stringEndsWith.call(constructorName, COMMAND_NAME_SUFFIX))
|
|
return propName;
|
|
return "".concat(constructorName, ".").concat(propName);
|
|
}
|
|
var Assignable = /** @class */ (function () {
|
|
function Assignable() {
|
|
}
|
|
Assignable.prototype.getAssignableProperties = function () {
|
|
return [];
|
|
};
|
|
Assignable.prototype.getAllAssignableProperties = function () {
|
|
var parent = Object.getPrototypeOf(this);
|
|
var result = [];
|
|
while (parent && parent.getAssignableProperties) {
|
|
result = arrayConcat.call(result, parent.getAssignableProperties());
|
|
parent = Object.getPrototypeOf(parent);
|
|
}
|
|
return result;
|
|
};
|
|
Assignable.prototype.getNonReportedProperties = function () {
|
|
return [];
|
|
};
|
|
Assignable.prototype.getReportedProperties = function () {
|
|
var props = arrayMap.call(this.getAllAssignableProperties(), function (prop) { return prop.name; });
|
|
var nonReportedProps = this.getNonReportedProperties();
|
|
return arrayFilter.call(props, function (name) { return !(arrayIndexOf.call(nonReportedProps, name) > -1); });
|
|
};
|
|
Assignable.prototype._assignFrom = function (obj, validate, initOptions) {
|
|
if (initOptions === void 0) { initOptions = {}; }
|
|
if (!obj)
|
|
return;
|
|
if (validate)
|
|
validateObjectProps(obj, this);
|
|
var props = this.getAllAssignableProperties();
|
|
for (var i = 0; i < props.length; i++) {
|
|
var _a = props[i], name_1 = _a.name, type = _a.type, required = _a.required, init = _a.init, defaultValue = _a.defaultValue;
|
|
if (defaultValue !== void 0)
|
|
this[name_1] = defaultValue;
|
|
var srcVal = obj[name_1];
|
|
if (srcVal === void 0 && !required)
|
|
continue;
|
|
if (validate && type) {
|
|
var typeName = getDisplayTypeName(this.constructor.name, name_1);
|
|
type(typeName, srcVal);
|
|
}
|
|
this[name_1] = init ? init(name_1, srcVal, initOptions, validate) : srcVal;
|
|
}
|
|
};
|
|
return Assignable;
|
|
}());
|
|
|
|
var DriverStatus = /** @class */ (function (_super) {
|
|
__extends(DriverStatus, _super);
|
|
function DriverStatus(obj) {
|
|
var _this = _super.call(this, obj) || this;
|
|
_this.id = generateId();
|
|
_this.isCommandResult = false;
|
|
_this.executionError = null;
|
|
_this.pageError = null;
|
|
_this.resent = false;
|
|
_this.result = null;
|
|
_this.consoleMessages = null;
|
|
_this.isPendingWindowSwitching = false;
|
|
_this.isObservingFileDownloadingInNewWindow = false;
|
|
_this.isFirstRequestAfterWindowSwitching = false;
|
|
_this.debug = '';
|
|
_this.warnings = null;
|
|
_this._assignFrom(obj, true);
|
|
return _this;
|
|
}
|
|
DriverStatus.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'isCommandResult' },
|
|
{ name: 'executionError' },
|
|
{ name: 'pageError' },
|
|
{ name: 'result' },
|
|
{ name: 'consoleMessages' },
|
|
{ name: 'isPendingWindowSwitching' },
|
|
{ name: 'isObservingFileDownloadingInNewWindow' },
|
|
{ name: 'isFirstRequestAfterWindowSwitching' },
|
|
{ name: 'warnings' },
|
|
];
|
|
};
|
|
return DriverStatus;
|
|
}(Assignable));
|
|
|
|
var MIN_RESPONSE_WAITING_TIMEOUT = 2500;
|
|
var RESEND_MESSAGE_INTERVAL = 1000;
|
|
function sendMessageToDriver(msg, driverWindow, timeout, NotLoadedErrorCtor) {
|
|
var sendMsgInterval = null;
|
|
var sendMsgTimeout = null;
|
|
var onResponse = null;
|
|
timeout = Math.max(timeout || 0, MIN_RESPONSE_WAITING_TIMEOUT);
|
|
var sendAndWaitForResponse = function () {
|
|
return new hammerhead.Promise(function (resolve) {
|
|
onResponse = function (e) {
|
|
if (e.message.type === TYPE.confirmation && e.message.requestMessageId === msg.id)
|
|
resolve(e.message);
|
|
};
|
|
hammerhead.eventSandbox.message.on(hammerhead.eventSandbox.message.SERVICE_MSG_RECEIVED_EVENT, onResponse);
|
|
sendMsgInterval = hammerhead.nativeMethods.setInterval.call(window, function () { return hammerhead.eventSandbox.message.sendServiceMsg(msg, driverWindow); }, RESEND_MESSAGE_INTERVAL);
|
|
hammerhead.eventSandbox.message.sendServiceMsg(msg, driverWindow);
|
|
});
|
|
};
|
|
return hammerhead.Promise.race([testcafeCore.delay(timeout), sendAndWaitForResponse()])
|
|
.then(function (response) {
|
|
hammerhead.nativeMethods.clearInterval.call(window, sendMsgInterval);
|
|
hammerhead.nativeMethods.clearTimeout.call(window, sendMsgTimeout);
|
|
hammerhead.eventSandbox.message.off(hammerhead.eventSandbox.message.SERVICE_MSG_RECEIVED_EVENT, onResponse);
|
|
if (!response)
|
|
throw new NotLoadedErrorCtor();
|
|
return response;
|
|
});
|
|
}
|
|
|
|
var WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT = 20000;
|
|
var WAIT_FOR_IFRAME_DRIVER_RESPONSE_TIMEOUT = 5000;
|
|
var CHECK_IFRAME_EXISTENCE_INTERVAL = 1000;
|
|
var CHECK_IFRAME_VISIBLE_INTERVAL = 200;
|
|
var WAIT_IFRAME_RESPONSE_DELAY = 500;
|
|
var CHECK_CHILD_WINDOW_CLOSED_INTERVAL = 200;
|
|
|
|
function sendConfirmationMessage (_a) {
|
|
var requestMsgId = _a.requestMsgId, result = _a.result, window = _a.window;
|
|
var msg = new ConfirmationMessage(requestMsgId, result);
|
|
hammerhead.eventSandbox.message.sendServiceMsg(msg, window);
|
|
}
|
|
|
|
var BoundaryValues = /** @class */ (function () {
|
|
function BoundaryValues(top, right, bottom, left) {
|
|
if (top === void 0) { top = 0; }
|
|
if (right === void 0) { right = 0; }
|
|
if (bottom === void 0) { bottom = 0; }
|
|
if (left === void 0) { left = 0; }
|
|
this.top = top;
|
|
this.right = right;
|
|
this.bottom = bottom;
|
|
this.left = left;
|
|
}
|
|
BoundaryValues.create = function (v) {
|
|
return new BoundaryValues(v.top, v.right, v.bottom, v.left);
|
|
};
|
|
BoundaryValues.prototype.add = function (d) {
|
|
this.top += d.top;
|
|
this.right += d.right;
|
|
this.bottom += d.bottom;
|
|
this.left += d.left;
|
|
return this;
|
|
};
|
|
BoundaryValues.prototype.sub = function (d) {
|
|
if ('top' in d) {
|
|
this.top -= d.top;
|
|
this.left -= d.left;
|
|
}
|
|
this.bottom -= d.bottom;
|
|
this.right -= d.right;
|
|
return this;
|
|
};
|
|
BoundaryValues.prototype.round = function (leftTopRound, rightBottomRound) {
|
|
if (leftTopRound === void 0) { leftTopRound = Math.round; }
|
|
if (rightBottomRound === void 0) { rightBottomRound = leftTopRound; }
|
|
this.top = leftTopRound(this.top);
|
|
this.right = rightBottomRound(this.right);
|
|
this.bottom = rightBottomRound(this.bottom);
|
|
this.left = leftTopRound(this.left);
|
|
return this;
|
|
};
|
|
BoundaryValues.prototype.contains = function (point) {
|
|
return point.x >= this.left && point.x <= this.right && point.y >= this.top && point.y <= this.bottom;
|
|
};
|
|
return BoundaryValues;
|
|
}());
|
|
|
|
var ARRAY_METHODS_PREFIX = 'array';
|
|
function createNativeMethodWrapper(methodName) {
|
|
var nativeMethodName = ARRAY_METHODS_PREFIX + methodName.charAt(0).toUpperCase() + methodName.slice(1);
|
|
var nativeMethod = hammerhead.nativeMethods[nativeMethodName];
|
|
return function () {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
return nativeMethod.call.apply(nativeMethod, args);
|
|
};
|
|
}
|
|
var filter = createNativeMethodWrapper('filter');
|
|
var map = createNativeMethodWrapper('map');
|
|
var slice = createNativeMethodWrapper('slice');
|
|
var splice = createNativeMethodWrapper('splice');
|
|
var unshift = createNativeMethodWrapper('unshift');
|
|
var forEach = createNativeMethodWrapper('forEach');
|
|
var indexOf = createNativeMethodWrapper('indexOf');
|
|
var some = createNativeMethodWrapper('some');
|
|
var reverse = createNativeMethodWrapper('reverse');
|
|
var reduce = createNativeMethodWrapper('reduce');
|
|
var concat = createNativeMethodWrapper('concat');
|
|
var join = createNativeMethodWrapper('join');
|
|
|
|
var browserUtils = hammerhead__default.utils.browser;
|
|
var nativeMethods$2 = hammerhead__default.nativeMethods;
|
|
// NOTE: We have to retrieve styleUtils.get from hammerhead
|
|
// to avoid circular dependencies between domUtils and styleUtils
|
|
var getElementStyleProperty = hammerhead__default.utils.style.get;
|
|
var getActiveElement = hammerhead__default.utils.dom.getActiveElement;
|
|
var findDocument = hammerhead__default.utils.dom.findDocument;
|
|
var find = hammerhead__default.utils.dom.find;
|
|
var isElementInDocument = hammerhead__default.utils.dom.isElementInDocument;
|
|
var isElementInIframe = hammerhead__default.utils.dom.isElementInIframe;
|
|
var getIframeByElement = hammerhead__default.utils.dom.getIframeByElement;
|
|
var isCrossDomainWindows = hammerhead__default.utils.dom.isCrossDomainWindows;
|
|
var getSelectParent = hammerhead__default.utils.dom.getSelectParent;
|
|
var getChildVisibleIndex = hammerhead__default.utils.dom.getChildVisibleIndex;
|
|
var getSelectVisibleChildren = hammerhead__default.utils.dom.getSelectVisibleChildren;
|
|
var isElementNode = hammerhead__default.utils.dom.isElementNode;
|
|
var isTextNode = hammerhead__default.utils.dom.isTextNode;
|
|
var isRenderedNode = hammerhead__default.utils.dom.isRenderedNode;
|
|
var isIframeElement = hammerhead__default.utils.dom.isIframeElement;
|
|
var isInputElement = hammerhead__default.utils.dom.isInputElement;
|
|
var isButtonElement = hammerhead__default.utils.dom.isButtonElement;
|
|
var isFileInput = hammerhead__default.utils.dom.isFileInput;
|
|
var isTextAreaElement = hammerhead__default.utils.dom.isTextAreaElement;
|
|
var isAnchorElement = hammerhead__default.utils.dom.isAnchorElement;
|
|
var isImgElement = hammerhead__default.utils.dom.isImgElement;
|
|
var isFormElement = hammerhead__default.utils.dom.isFormElement;
|
|
var isLabelElement = hammerhead__default.utils.dom.isLabelElement;
|
|
var isSelectElement = hammerhead__default.utils.dom.isSelectElement;
|
|
var isRadioButtonElement = hammerhead__default.utils.dom.isRadioButtonElement;
|
|
var isColorInputElement = hammerhead__default.utils.dom.isColorInputElement;
|
|
var isCheckboxElement = hammerhead__default.utils.dom.isCheckboxElement;
|
|
var isOptionElement = hammerhead__default.utils.dom.isOptionElement;
|
|
var isSVGElement = hammerhead__default.utils.dom.isSVGElement;
|
|
var isMapElement = hammerhead__default.utils.dom.isMapElement;
|
|
var isBodyElement = hammerhead__default.utils.dom.isBodyElement;
|
|
var isHtmlElement = hammerhead__default.utils.dom.isHtmlElement;
|
|
var isDocument = hammerhead__default.utils.dom.isDocument;
|
|
var isWindow = hammerhead__default.utils.dom.isWindow;
|
|
var isTextEditableInput = hammerhead__default.utils.dom.isTextEditableInput;
|
|
var isTextEditableElement = hammerhead__default.utils.dom.isTextEditableElement;
|
|
var isTextEditableElementAndEditingAllowed = hammerhead__default.utils.dom.isTextEditableElementAndEditingAllowed;
|
|
var isContentEditableElement = hammerhead__default.utils.dom.isContentEditableElement;
|
|
var isDomElement = hammerhead__default.utils.dom.isDomElement;
|
|
var isShadowUIElement = hammerhead__default.utils.dom.isShadowUIElement;
|
|
var isShadowRoot = hammerhead__default.utils.dom.isShadowRoot;
|
|
var isElementFocusable = hammerhead__default.utils.dom.isElementFocusable;
|
|
var isHammerheadAttr = hammerhead__default.utils.dom.isHammerheadAttr;
|
|
var isElementReadOnly = hammerhead__default.utils.dom.isElementReadOnly;
|
|
var getScrollbarSize = hammerhead__default.utils.dom.getScrollbarSize;
|
|
var getMapContainer = hammerhead__default.utils.dom.getMapContainer;
|
|
var getTagName = hammerhead__default.utils.dom.getTagName;
|
|
var closest = hammerhead__default.utils.dom.closest;
|
|
var getParents = hammerhead__default.utils.dom.getParents;
|
|
var findParent = hammerhead__default.utils.dom.findParent;
|
|
var getTopSameDomainWindow = hammerhead__default.utils.dom.getTopSameDomainWindow;
|
|
var getParentExceptShadowRoot = hammerhead__default.utils.dom.getParentExceptShadowRoot;
|
|
|
|
var styleUtils = hammerhead__default.utils.style;
|
|
var getBordersWidth = hammerhead__default.utils.style.getBordersWidth;
|
|
var getComputedStyle = hammerhead__default.utils.style.getComputedStyle;
|
|
var getElementMargin = hammerhead__default.utils.style.getElementMargin;
|
|
var getElementPadding = hammerhead__default.utils.style.getElementPadding;
|
|
var getElementScroll = hammerhead__default.utils.style.getElementScroll;
|
|
var getOptionHeight = hammerhead__default.utils.style.getOptionHeight;
|
|
var getSelectElementSize = hammerhead__default.utils.style.getSelectElementSize;
|
|
var isElementVisible = hammerhead__default.utils.style.isElementVisible;
|
|
var isSelectVisibleChild = hammerhead__default.utils.style.isVisibleChild;
|
|
var getWidth = hammerhead__default.utils.style.getWidth;
|
|
var getHeight = hammerhead__default.utils.style.getHeight;
|
|
var getInnerWidth = hammerhead__default.utils.style.getInnerWidth;
|
|
var getInnerHeight = hammerhead__default.utils.style.getInnerHeight;
|
|
var getScrollLeft = hammerhead__default.utils.style.getScrollLeft;
|
|
var getScrollTop = hammerhead__default.utils.style.getScrollTop;
|
|
var setScrollLeft = hammerhead__default.utils.style.setScrollLeft;
|
|
var setScrollTop = hammerhead__default.utils.style.setScrollTop;
|
|
var get = hammerhead__default.utils.style.get;
|
|
var getBordersWidthFloat = hammerhead__default.utils.style.getBordersWidthFloat;
|
|
var getElementPaddingFloat = hammerhead__default.utils.style.getElementPaddingFloat;
|
|
|
|
var ChildIframeDriverLink = /** @class */ (function () {
|
|
function ChildIframeDriverLink(driverWindow, driverId, dispatchProxylessEventUrl) {
|
|
this.driverWindow = driverWindow;
|
|
this.driverIframe = testcafeCore.domUtils.findIframeByWindow(driverWindow);
|
|
this.driverId = driverId;
|
|
this.iframeAvailabilityTimeout = 0;
|
|
this.dispatchProxylessEventUrl = dispatchProxylessEventUrl;
|
|
}
|
|
Object.defineProperty(ChildIframeDriverLink.prototype, "availabilityTimeout", {
|
|
set: function (val) {
|
|
this.iframeAvailabilityTimeout = val;
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
ChildIframeDriverLink.prototype._ensureIframe = function () {
|
|
var _this = this;
|
|
if (!testcafeCore.domUtils.isElementInDocument(this.driverIframe))
|
|
return hammerhead.Promise.reject(new CurrentIframeNotFoundError());
|
|
return testcafeCore.waitFor(function () { return testcafeCore.positionUtils.isIframeVisible(_this.driverIframe) ? _this.driverIframe : null; }, CHECK_IFRAME_VISIBLE_INTERVAL, this.iframeAvailabilityTimeout)
|
|
.catch(function () {
|
|
throw new CurrentIframeIsInvisibleError();
|
|
});
|
|
};
|
|
ChildIframeDriverLink.prototype._waitForIframeRemovedOrHidden = function () {
|
|
var _this = this;
|
|
// NOTE: If an iframe was removed or became hidden while a
|
|
// command was being executed, we consider this command finished.
|
|
return new hammerhead.Promise(function (resolve) {
|
|
_this.checkIframeInterval = hammerhead.nativeMethods.setInterval.call(window, function () {
|
|
_this._ensureIframe()
|
|
.catch(function () {
|
|
// NOTE: wait for possible delayed iframe message
|
|
return testcafeCore.delay(WAIT_IFRAME_RESPONSE_DELAY)
|
|
.then(function () { return resolve(new DriverStatus({ isCommandResult: true })); });
|
|
});
|
|
}, CHECK_IFRAME_EXISTENCE_INTERVAL);
|
|
});
|
|
};
|
|
ChildIframeDriverLink.prototype._waitForCommandResult = function () {
|
|
var _this = this;
|
|
var onMessage = null;
|
|
var waitForResultMessage = function () { return new hammerhead.Promise(function (resolve) {
|
|
onMessage = function (e) {
|
|
if (e.message.type === TYPE.commandExecuted)
|
|
resolve(e.message.driverStatus);
|
|
};
|
|
hammerhead.eventSandbox.message.on(hammerhead.eventSandbox.message.SERVICE_MSG_RECEIVED_EVENT, onMessage);
|
|
}); };
|
|
return hammerhead.Promise.race([this._waitForIframeRemovedOrHidden(), waitForResultMessage()])
|
|
.then(function (status) {
|
|
hammerhead.eventSandbox.message.off(hammerhead.eventSandbox.message.SERVICE_MSG_RECEIVED_EVENT, onMessage);
|
|
hammerhead.nativeMethods.clearInterval.call(window, _this.checkIframeInterval);
|
|
return status;
|
|
});
|
|
};
|
|
ChildIframeDriverLink.prototype._getLeftTopPoint = function (proxyless) {
|
|
if (!proxyless)
|
|
return null;
|
|
var rect = this.driverIframe.getBoundingClientRect();
|
|
var borders = getBordersWidthFloat(this.driverIframe);
|
|
var paddings = getElementPaddingFloat(this.driverIframe);
|
|
return {
|
|
x: rect.left + borders.left + paddings.left,
|
|
y: rect.top + borders.top + paddings.top,
|
|
};
|
|
};
|
|
ChildIframeDriverLink.prototype.sendConfirmationMessage = function (requestMsgId) {
|
|
sendConfirmationMessage({
|
|
requestMsgId: requestMsgId,
|
|
result: { id: this.driverId, dispatchProxylessEventUrl: this.dispatchProxylessEventUrl },
|
|
window: this.driverWindow,
|
|
});
|
|
};
|
|
ChildIframeDriverLink.prototype.executeCommand = function (command, testSpeed, proxyless, leftTopPoint) {
|
|
var _this = this;
|
|
// NOTE: We should check if the iframe is visible and exists before executing the next
|
|
// command, because the iframe might be hidden or removed since the previous command.
|
|
return this
|
|
._ensureIframe()
|
|
.then(function () {
|
|
var currentLeftTopPoint = _this._getLeftTopPoint(proxyless);
|
|
if (leftTopPoint) {
|
|
currentLeftTopPoint.x += leftTopPoint.x;
|
|
currentLeftTopPoint.y += leftTopPoint.y;
|
|
}
|
|
var msg = new ExecuteCommandMessage(command, testSpeed, currentLeftTopPoint);
|
|
return hammerhead.Promise.all([
|
|
sendMessageToDriver(msg, _this.driverWindow, _this.iframeAvailabilityTimeout, CurrentIframeIsNotLoadedError),
|
|
_this._waitForCommandResult(),
|
|
]);
|
|
})
|
|
.then(function (result) { return result[1]; });
|
|
};
|
|
return ChildIframeDriverLink;
|
|
}());
|
|
|
|
// -------------------------------------------------------------
|
|
// WARNING: this file is used by both the client and the server.
|
|
// Do not use any browser or node-specific API!
|
|
// -------------------------------------------------------------
|
|
var NODE_SNAPSHOT_PROPERTIES = [
|
|
'nodeType',
|
|
'textContent',
|
|
'childNodeCount',
|
|
'hasChildNodes',
|
|
'childElementCount',
|
|
'hasChildElements',
|
|
];
|
|
var ELEMENT_ACTION_SNAPSHOT_PROPERTIES = [
|
|
'tagName',
|
|
'attributes',
|
|
];
|
|
var ELEMENT_SNAPSHOT_PROPERTIES = [
|
|
'tagName',
|
|
'visible',
|
|
'focused',
|
|
'attributes',
|
|
'boundingClientRect',
|
|
'classNames',
|
|
'style',
|
|
'innerText',
|
|
'namespaceURI',
|
|
'id',
|
|
'value',
|
|
'checked',
|
|
'selected',
|
|
'selectedIndex',
|
|
'scrollWidth',
|
|
'scrollHeight',
|
|
'scrollLeft',
|
|
'scrollTop',
|
|
'offsetWidth',
|
|
'offsetHeight',
|
|
'offsetLeft',
|
|
'offsetTop',
|
|
'clientWidth',
|
|
'clientHeight',
|
|
'clientLeft',
|
|
'clientTop',
|
|
];
|
|
|
|
var nodeSnapshotPropertyInitializers = {
|
|
// eslint-disable-next-line no-restricted-properties
|
|
childNodeCount: function (node) { return node.childNodes.length; },
|
|
hasChildNodes: function (node) { return !!nodeSnapshotPropertyInitializers.childNodeCount(node); },
|
|
childElementCount: function (node) {
|
|
var children = node.children;
|
|
if (children)
|
|
// eslint-disable-next-line no-restricted-properties
|
|
return children.length;
|
|
// NOTE: IE doesn't have `children` for non-element nodes =/
|
|
var childElementCount = 0;
|
|
// eslint-disable-next-line no-restricted-properties
|
|
var childNodeCount = node.childNodes.length;
|
|
for (var i = 0; i < childNodeCount; i++) {
|
|
// eslint-disable-next-line no-restricted-properties
|
|
if (node.childNodes[i].nodeType === 1)
|
|
childElementCount++;
|
|
}
|
|
return childElementCount;
|
|
},
|
|
// eslint-disable-next-line no-restricted-properties
|
|
hasChildElements: function (node) { return !!nodeSnapshotPropertyInitializers.childElementCount(node); },
|
|
};
|
|
var BaseSnapshot = /** @class */ (function () {
|
|
function BaseSnapshot() {
|
|
}
|
|
BaseSnapshot.prototype._initializeProperties = function (node, properties, initializers) {
|
|
for (var _i = 0, properties_1 = properties; _i < properties_1.length; _i++) {
|
|
var property = properties_1[_i];
|
|
var initializer = initializers[property];
|
|
this[property] = initializer ? initializer(node) : node[property];
|
|
}
|
|
};
|
|
return BaseSnapshot;
|
|
}());
|
|
var NodeSnapshot = /** @class */ (function (_super) {
|
|
__extends(NodeSnapshot, _super);
|
|
function NodeSnapshot(node) {
|
|
var _this = _super.call(this) || this;
|
|
_this._initializeProperties(node, NODE_SNAPSHOT_PROPERTIES, nodeSnapshotPropertyInitializers);
|
|
return _this;
|
|
}
|
|
return NodeSnapshot;
|
|
}(BaseSnapshot));
|
|
// Element
|
|
var elementSnapshotPropertyInitializers = {
|
|
tagName: function (element) { return element.tagName.toLowerCase(); },
|
|
visible: function (element) { return testcafeCore.positionUtils.isElementVisible(element); },
|
|
focused: function (element) { return hammerhead.utils.dom.getActiveElement() === element; },
|
|
attributes: function (element) {
|
|
// eslint-disable-next-line no-restricted-properties
|
|
var attrs = element.attributes;
|
|
var result = {};
|
|
for (var i = attrs.length - 1; i >= 0; i--)
|
|
// eslint-disable-next-line no-restricted-properties
|
|
result[attrs[i].name] = attrs[i].value;
|
|
return result;
|
|
},
|
|
boundingClientRect: function (element) {
|
|
var rect = element.getBoundingClientRect();
|
|
return {
|
|
left: rect.left,
|
|
right: rect.right,
|
|
top: rect.top,
|
|
bottom: rect.bottom,
|
|
width: rect.width,
|
|
height: rect.height,
|
|
};
|
|
},
|
|
classNames: function (element) {
|
|
var className = element.className;
|
|
if (typeof className.animVal === 'string')
|
|
className = className.animVal;
|
|
return className
|
|
.replace(/^\s+|\s+$/g, '')
|
|
.split(/\s+/g);
|
|
},
|
|
style: function (element) {
|
|
var result = {};
|
|
var computed = window.getComputedStyle(element);
|
|
for (var i = 0; i < computed.length; i++) {
|
|
var prop = computed[i];
|
|
result[prop] = computed[prop];
|
|
}
|
|
return result;
|
|
},
|
|
// eslint-disable-next-line no-restricted-properties
|
|
innerText: function (element) { return element.innerText; },
|
|
};
|
|
var ElementActionSnapshot = /** @class */ (function (_super) {
|
|
__extends(ElementActionSnapshot, _super);
|
|
function ElementActionSnapshot(element) {
|
|
var _this = _super.call(this) || this;
|
|
_this._initializeProperties(element, ELEMENT_ACTION_SNAPSHOT_PROPERTIES, elementSnapshotPropertyInitializers);
|
|
return _this;
|
|
}
|
|
return ElementActionSnapshot;
|
|
}(BaseSnapshot));
|
|
var ElementSnapshot = /** @class */ (function (_super) {
|
|
__extends(ElementSnapshot, _super);
|
|
function ElementSnapshot(element) {
|
|
var _this = _super.call(this, element) || this;
|
|
_this._initializeProperties(element, ELEMENT_SNAPSHOT_PROPERTIES, elementSnapshotPropertyInitializers);
|
|
return _this;
|
|
}
|
|
return ElementSnapshot;
|
|
}(NodeSnapshot));
|
|
|
|
var SelectorNodeTransform = /** @class */ (function () {
|
|
function SelectorNodeTransform(customDOMProperties, instantiationCallsiteName) {
|
|
if (customDOMProperties === void 0) { customDOMProperties = {}; }
|
|
this.type = 'Node';
|
|
this._customDOMProperties = customDOMProperties;
|
|
this._instantiationCallsiteName = instantiationCallsiteName;
|
|
}
|
|
SelectorNodeTransform.prototype._extend = function (snapshot, node) {
|
|
var props = hammerhead.nativeMethods.objectKeys(this._customDOMProperties);
|
|
for (var _i = 0, props_1 = props; _i < props_1.length; _i++) {
|
|
var prop = props_1[_i];
|
|
try {
|
|
snapshot[prop] = this._customDOMProperties[prop](node);
|
|
}
|
|
catch (err) {
|
|
throw new UncaughtErrorInCustomDOMPropertyCode(this._instantiationCallsiteName, err, prop);
|
|
}
|
|
}
|
|
};
|
|
SelectorNodeTransform.prototype.shouldTransform = function (type, val) {
|
|
return val instanceof hammerhead.nativeMethods.Node;
|
|
};
|
|
SelectorNodeTransform.prototype.toSerializable = function (node) {
|
|
var snapshot = node.nodeType === 1 ? new ElementSnapshot(node) : new NodeSnapshot(node);
|
|
this._extend(snapshot, node);
|
|
return snapshot;
|
|
};
|
|
SelectorNodeTransform.prototype.fromSerializable = function () {
|
|
};
|
|
return SelectorNodeTransform;
|
|
}());
|
|
|
|
// @ts-ignore
|
|
var EventEmitter = /** @class */ (function () {
|
|
function EventEmitter() {
|
|
this._eventsListeners = {};
|
|
}
|
|
EventEmitter.prototype.on = function (evt, listener) {
|
|
if (!this._eventsListeners[evt])
|
|
this._eventsListeners[evt] = [];
|
|
this._eventsListeners[evt].push(listener);
|
|
};
|
|
EventEmitter.prototype.once = function (evt, listener) {
|
|
var _this = this;
|
|
this.on(evt, function () {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
_this.off(evt, listener);
|
|
return listener.apply(void 0, args);
|
|
});
|
|
};
|
|
EventEmitter.prototype.off = function (evt, listener) {
|
|
var listeners = this._eventsListeners[evt];
|
|
if (listeners)
|
|
this._eventsListeners[evt] = hammerhead.nativeMethods.arrayFilter.call(listeners, function (item) { return item !== listener; });
|
|
};
|
|
EventEmitter.prototype.offAll = function (evt) {
|
|
if (evt)
|
|
this._eventsListeners[evt] = [];
|
|
else
|
|
this._eventsListeners = {};
|
|
};
|
|
EventEmitter.prototype.emit = function (evt) {
|
|
var args = [];
|
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
args[_i - 1] = arguments[_i];
|
|
}
|
|
var listeners = this._eventsListeners[evt];
|
|
if (!listeners)
|
|
return;
|
|
for (var i = 0; i < listeners.length; i++) {
|
|
try {
|
|
listeners[i].apply(this, args);
|
|
}
|
|
catch (e) {
|
|
// Hack for IE: after document.write calling IFrameSandbox event handlers
|
|
// rises 'Can't execute code from a freed script' exception because document has been
|
|
// recreated
|
|
if (e.message && e.message.indexOf('freed script') > -1)
|
|
this.off(evt, listeners[i]);
|
|
else
|
|
throw e;
|
|
}
|
|
}
|
|
};
|
|
return EventEmitter;
|
|
}());
|
|
|
|
var Promise = hammerhead__default.Promise;
|
|
var nativeMethods$3 = hammerhead__default.nativeMethods;
|
|
function delay (ms) {
|
|
return new Promise(function (resolve) { return nativeMethods$3.setTimeout.call(window, resolve, ms); });
|
|
}
|
|
|
|
function whilst(condition, iterator) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
if (!condition()) return [3 /*break*/, 2];
|
|
return [4 /*yield*/, iterator()];
|
|
case 1:
|
|
_a.sent();
|
|
return [3 /*break*/, 0];
|
|
case 2: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// NOTE: node description by node type
|
|
var NODE_TYPE_DESCRIPTIONS = {
|
|
1: 'element',
|
|
2: 'attribute',
|
|
3: 'text',
|
|
4: 'cdata section',
|
|
5: 'entity reference',
|
|
6: 'entity node',
|
|
7: 'processing instruction',
|
|
8: 'comment',
|
|
9: 'document',
|
|
10: 'document type',
|
|
11: 'document fragment',
|
|
12: 'notation',
|
|
};
|
|
|
|
function getInvisibleErrorCtor(elementName) {
|
|
return !elementName ? 'ActionElementIsInvisibleError' : {
|
|
name: 'ActionAdditionalElementIsInvisibleError',
|
|
firstArg: elementName,
|
|
};
|
|
}
|
|
function getNotFoundErrorCtor(elementName) {
|
|
return !elementName ? 'ActionElementNotFoundError' : {
|
|
name: 'ActionAdditionalElementNotFoundError',
|
|
firstArg: elementName,
|
|
};
|
|
}
|
|
function getCannotObtainInfoErrorCtor() {
|
|
return 'CannotObtainInfoForElementSpecifiedBySelectorError';
|
|
}
|
|
function createErrorCtorCallback(errCtor) {
|
|
// @ts-ignore
|
|
var Error = typeof errCtor === 'string' ? Errors[errCtor] : Errors[errCtor.name];
|
|
var firstArg = typeof errCtor === 'string' ? null : errCtor.firstArg;
|
|
return function (fn) { return new Error(firstArg, fn); };
|
|
}
|
|
|
|
var ElementsRetriever = /** @class */ (function () {
|
|
function ElementsRetriever(globalSelectorTimeout, executeSelectorFn) {
|
|
this._globalSelectorTimeout = globalSelectorTimeout;
|
|
this._ensureElementsStartTime = hammerhead.nativeMethods.dateNow();
|
|
this._ensureElementsPromise = hammerhead.Promise.resolve();
|
|
this._executeSelectorFn = executeSelectorFn;
|
|
this._elements = [];
|
|
}
|
|
ElementsRetriever.prototype.push = function (selector, elementName) {
|
|
var _this = this;
|
|
this._ensureElementsPromise = this._ensureElementsPromise
|
|
.then(function () {
|
|
return _this._executeSelectorFn(selector, {
|
|
invisible: getInvisibleErrorCtor(elementName),
|
|
notFound: getNotFoundErrorCtor(elementName),
|
|
}, _this._ensureElementsStartTime);
|
|
})
|
|
.then(function (el) {
|
|
if (!testcafeCore.domUtils.isDomElement(el)) {
|
|
var nodeType = el.nodeType;
|
|
var nodeTypeStr = NODE_TYPE_DESCRIPTIONS[nodeType];
|
|
if (!elementName)
|
|
throw new ActionSelectorMatchesWrongNodeTypeError(nodeTypeStr);
|
|
else
|
|
throw new ActionAdditionalSelectorMatchesWrongNodeTypeError(elementName, nodeTypeStr);
|
|
}
|
|
_this._elements.push(el);
|
|
});
|
|
};
|
|
ElementsRetriever.prototype.getElements = function () {
|
|
var _this = this;
|
|
return this._ensureElementsPromise.then(function () { return _this._elements; });
|
|
};
|
|
return ElementsRetriever;
|
|
}());
|
|
|
|
var shadowUI = hammerhead__default.shadowUI;
|
|
var nativeMethods$4 = hammerhead__default.nativeMethods;
|
|
|
|
var AxisValues = /** @class */ (function () {
|
|
function AxisValues(x, y) {
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
AxisValues.create = function (a) {
|
|
if ('left' in a)
|
|
return new AxisValues(a.left, a.top);
|
|
else if ('right' in a)
|
|
return new AxisValues(a.right, a.bottom);
|
|
return new AxisValues(a.x, a.y);
|
|
};
|
|
AxisValues.prototype.add = function (p) {
|
|
this.x += p.x;
|
|
this.y += p.y;
|
|
return this;
|
|
};
|
|
AxisValues.prototype.sub = function (p) {
|
|
this.x -= p.x;
|
|
this.y -= p.y;
|
|
return this;
|
|
};
|
|
AxisValues.prototype.round = function (fn) {
|
|
if (fn === void 0) { fn = Math.round; }
|
|
this.x = fn(this.x);
|
|
this.y = fn(this.y);
|
|
return this;
|
|
};
|
|
AxisValues.prototype.eql = function (p) {
|
|
return this.x === p.x && this.y === p.y;
|
|
};
|
|
AxisValues.prototype.mul = function (n) {
|
|
this.x *= n;
|
|
this.y *= n;
|
|
return this;
|
|
};
|
|
AxisValues.prototype.distance = function (p) {
|
|
return Math.sqrt(Math.pow(this.x - p.x, 2) + Math.pow(this.y - p.y, 2));
|
|
};
|
|
return AxisValues;
|
|
}());
|
|
|
|
var Dimensions = /** @class */ (function () {
|
|
function Dimensions(width, height, position, borders, elScroll, scrollbar) {
|
|
this.width = width;
|
|
this.height = height;
|
|
this.left = position.x;
|
|
this.top = position.y;
|
|
this.right = position.x + width;
|
|
this.bottom = position.y + height;
|
|
this.border = borders;
|
|
this.scrollbar = scrollbar;
|
|
this.scroll = elScroll;
|
|
}
|
|
return Dimensions;
|
|
}());
|
|
|
|
var htmlUtils = hammerhead__default.utils.html;
|
|
var nativeMethods$5 = hammerhead__default.nativeMethods;
|
|
|
|
var getElementRectangle = hammerhead__default.utils.position.getElementRectangle;
|
|
var getOffsetPosition = hammerhead__default.utils.position.getOffsetPosition;
|
|
var offsetToClientCoords = hammerhead__default.utils.position.offsetToClientCoords;
|
|
function getClientDimensions(target) {
|
|
var isHtmlElement$1 = isHtmlElement(target);
|
|
var body = isHtmlElement$1 ? target.getElementsByTagName('body')[0] : null;
|
|
var elementRect = target.getBoundingClientRect();
|
|
var elBorders = BoundaryValues.create(getBordersWidth(target));
|
|
var elScroll = getElementScroll(target);
|
|
var isElementInIframe$1 = isElementInIframe(target);
|
|
var isCompatMode = target.ownerDocument.compatMode === 'BackCompat';
|
|
var elPosition = isHtmlElement$1 ? new AxisValues(0, 0) : AxisValues.create(elementRect);
|
|
var elHeight = elementRect.height;
|
|
var elWidth = elementRect.width;
|
|
if (isHtmlElement$1) {
|
|
if (body && isCompatMode) {
|
|
elHeight = body.clientHeight;
|
|
elWidth = body.clientWidth;
|
|
}
|
|
else {
|
|
elHeight = target.clientHeight;
|
|
elWidth = target.clientWidth;
|
|
}
|
|
}
|
|
if (isElementInIframe$1) {
|
|
var iframeElement = getIframeByElement(target);
|
|
if (iframeElement) {
|
|
var iframeOffset = getOffsetPosition(iframeElement);
|
|
var clientOffset = offsetToClientCoords(AxisValues.create(iframeOffset));
|
|
var iframeBorders = getBordersWidth(iframeElement);
|
|
elPosition.add(clientOffset).add(AxisValues.create(iframeBorders));
|
|
if (isHtmlElement$1)
|
|
elBorders.add(iframeBorders);
|
|
}
|
|
}
|
|
var hasRightScrollbar = !isHtmlElement$1 && getInnerWidth(target) !== target.clientWidth;
|
|
var hasBottomScrollbar = !isHtmlElement$1 && getInnerHeight(target) !== target.clientHeight;
|
|
var scrollbar = {
|
|
right: hasRightScrollbar ? getScrollbarSize() : 0,
|
|
bottom: hasBottomScrollbar ? getScrollbarSize() : 0,
|
|
};
|
|
return new Dimensions(elWidth, elHeight, elPosition, elBorders, elScroll, scrollbar);
|
|
}
|
|
|
|
function calcOffset(size) {
|
|
var offset = size / 2;
|
|
return offset < 1 ? 0 : Math.round(offset);
|
|
}
|
|
function getDefaultAutomationOffsets(element) {
|
|
var rect = getElementRectangle(element);
|
|
var offsetX = calcOffset(rect.width);
|
|
var offsetY = calcOffset(rect.height);
|
|
return { offsetX: offsetX, offsetY: offsetY };
|
|
}
|
|
function getOffsetOptions(element, offsetX, offsetY) {
|
|
var defaultOffsets = getDefaultAutomationOffsets(element);
|
|
offsetX = typeof offsetX === 'number' ? Math.round(offsetX) : defaultOffsets.offsetX;
|
|
offsetY = typeof offsetY === 'number' ? Math.round(offsetY) : defaultOffsets.offsetY;
|
|
if (offsetX > 0 && offsetY > 0)
|
|
return { offsetX: offsetX, offsetY: offsetY };
|
|
var dimensions = getClientDimensions(element);
|
|
var width = Math.round(Math.max(element.scrollWidth, dimensions.width));
|
|
var height = Math.round(Math.max(element.scrollHeight, dimensions.height));
|
|
var maxX = dimensions.scrollbar.right + dimensions.border.left + dimensions.border.right + width;
|
|
var maxY = dimensions.scrollbar.bottom + dimensions.border.top + dimensions.border.bottom + height;
|
|
return {
|
|
offsetX: offsetX < 0 ? maxX + offsetX : offsetX,
|
|
offsetY: offsetY < 0 ? maxY + offsetY : offsetY,
|
|
};
|
|
}
|
|
|
|
var MAX_DELAY_AFTER_EXECUTION = 2000;
|
|
var CHECK_ELEMENT_IN_AUTOMATIONS_INTERVAL = 250;
|
|
var ActionExecutor = /** @class */ (function (_super) {
|
|
__extends(ActionExecutor, _super);
|
|
function ActionExecutor(command, options) {
|
|
var _this = _super.call(this) || this;
|
|
_this._command = command;
|
|
_this._targetElement = null;
|
|
_this._elements = [];
|
|
_this._options = options;
|
|
_this._executionStartTime = 0;
|
|
_this._prepareCommand(command, options);
|
|
_this._commandSelectorTimeout = _this._getCommandSelectorTimeout(command, options);
|
|
return _this;
|
|
}
|
|
ActionExecutor.prototype._prepareCommand = function (command, options) {
|
|
// TODO: move it to the server
|
|
// @ts-ignore
|
|
if (command.options && !command.options.speed) // @ts-ignore
|
|
command.options.speed = options.testSpeed;
|
|
};
|
|
ActionExecutor.prototype._getCommandSelectorTimeout = function (command, options) {
|
|
var _a;
|
|
// @ts-ignore
|
|
return typeof ((_a = command.selector) === null || _a === void 0 ? void 0 : _a.timeout) === 'number' ? command.selector.timeout : options.globalSelectorTimeout;
|
|
};
|
|
ActionExecutor.prototype._delayAfterExecution = function () {
|
|
// @ts-ignore TODO
|
|
if (!this._command.options || this._command.options.speed === 1)
|
|
return hammerhead.Promise.resolve();
|
|
// @ts-ignore TODO
|
|
return delay((1 - this._command.options.speed) * MAX_DELAY_AFTER_EXECUTION);
|
|
};
|
|
ActionExecutor.prototype._isExecutionTimeoutExpired = function () {
|
|
return hammerhead.nativeMethods.dateNow() - this._executionStartTime >= this._commandSelectorTimeout;
|
|
};
|
|
ActionExecutor.prototype._ensureCommandArguments = function () {
|
|
var handler = ActionExecutor.ACTIONS_HANDLERS[this._command.type];
|
|
if (!(handler === null || handler === void 0 ? void 0 : handler.ensureCmdArgs))
|
|
return;
|
|
handler.ensureCmdArgs(this._command);
|
|
};
|
|
ActionExecutor.prototype._ensureCommandElements = function () {
|
|
var _this = this;
|
|
var _a;
|
|
var elsRetriever = new ElementsRetriever(this._options.globalSelectorTimeout, this._options.executeSelectorFn);
|
|
if (this._command.selector)
|
|
// @ts-ignore TODO
|
|
elsRetriever.push(this._command.selector);
|
|
var additionalSelectorProps = (_a = ActionExecutor.ACTIONS_HANDLERS[this._command.type]) === null || _a === void 0 ? void 0 : _a.additionalSelectorProps;
|
|
if (additionalSelectorProps) {
|
|
for (var _i = 0, additionalSelectorProps_1 = additionalSelectorProps; _i < additionalSelectorProps_1.length; _i++) {
|
|
var prop = additionalSelectorProps_1[_i];
|
|
if (this._command[prop])
|
|
// @ts-ignore TODO
|
|
elsRetriever.push(this._command[prop], prop);
|
|
}
|
|
}
|
|
return elsRetriever.getElements()
|
|
.then(function (elements) {
|
|
_this._elements = elements;
|
|
});
|
|
};
|
|
ActionExecutor.prototype._ensureCommandElementsProperties = function () {
|
|
var handler = ActionExecutor.ACTIONS_HANDLERS[this._command.type];
|
|
if (!(handler === null || handler === void 0 ? void 0 : handler.ensureElsProps))
|
|
return;
|
|
handler.ensureElsProps(this._elements);
|
|
};
|
|
ActionExecutor.prototype._ensureCommandOptions = function () {
|
|
return __awaiter(this, void 0, hammerhead.Promise, function () {
|
|
var opts, _a, offsetX, offsetY;
|
|
return __generator(this, function (_b) {
|
|
opts = this._command.options;
|
|
// @ts-ignore TODO
|
|
if (this._elements.length && opts && 'offsetX' in opts && 'offsetY' in opts) { // @ts-ignore
|
|
_a = getOffsetOptions(this._elements[0], opts.offsetX, opts.offsetY), offsetX = _a.offsetX, offsetY = _a.offsetY;
|
|
// @ts-ignore TODO
|
|
opts.isDefaultOffset = !opts.offsetX && !opts.offsetY;
|
|
// @ts-ignore TODO
|
|
opts.offsetX = offsetX;
|
|
// @ts-ignore TODO
|
|
opts.offsetY = offsetY;
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
ActionExecutor.prototype._createAutomation = function () {
|
|
var handler = ActionExecutor.ACTIONS_HANDLERS[this._command.type];
|
|
if (!handler)
|
|
throw new Error("There is no handler for the \"".concat(this._command.type, "\" command."));
|
|
return handler.create(this._command, this._elements, this._options.dispatchProxylessEventFn, this._options.leftTopPoint);
|
|
};
|
|
ActionExecutor.prototype._runAction = function (strictElementCheck) {
|
|
var _this = this;
|
|
return this._ensureCommandElements()
|
|
.then(function () { return _this._ensureCommandElementsProperties(); })
|
|
.then(function () { return _this._ensureCommandOptions(); })
|
|
.then(function () {
|
|
var automation = _this._createAutomation();
|
|
if (automation.WARNING_EVENT) {
|
|
automation.on(automation.WARNING_EVENT, function (warning) {
|
|
_this.emit(ActionExecutor.WARNING_EVENT, warning);
|
|
});
|
|
}
|
|
if (automation.TARGET_ELEMENT_FOUND_EVENT) {
|
|
automation.on(automation.TARGET_ELEMENT_FOUND_EVENT, function (e) {
|
|
_this._targetElement = e.element;
|
|
_this.emit(ActionExecutor.EXECUTION_STARTED_EVENT);
|
|
});
|
|
}
|
|
else
|
|
_this.emit(ActionExecutor.EXECUTION_STARTED_EVENT);
|
|
return automation.run(strictElementCheck);
|
|
});
|
|
};
|
|
ActionExecutor.prototype._runRecursively = function () {
|
|
var _this = this;
|
|
var actionFinished = false;
|
|
var strictElementCheck = true;
|
|
return whilst(function () { return !actionFinished; }, function () {
|
|
return _this._runAction(strictElementCheck)
|
|
.then(function () {
|
|
actionFinished = true;
|
|
})
|
|
.catch(function (err) {
|
|
if (!_this._isExecutionTimeoutExpired())
|
|
return delay(CHECK_ELEMENT_IN_AUTOMATIONS_INTERVAL);
|
|
if (err.code === TEST_RUN_ERRORS.actionElementIsNotTargetError) {
|
|
// If we can't get a target element via elementFromPoint but it's
|
|
// visible we click on the point where the element is located.
|
|
strictElementCheck = false;
|
|
return hammerhead.Promise.resolve();
|
|
}
|
|
throw err;
|
|
});
|
|
});
|
|
};
|
|
ActionExecutor.prototype.execute = function (barriers) {
|
|
var _this = this;
|
|
this._executionStartTime = hammerhead.nativeMethods.dateNow();
|
|
try {
|
|
// TODO: I think that this check is unnecessary here. It checks only a key sequence of the pressKey command.
|
|
// This check can be moved to the server.
|
|
this._ensureCommandArguments();
|
|
}
|
|
catch (err) {
|
|
return hammerhead.Promise.reject(err);
|
|
}
|
|
this.emit(ActionExecutor.WAITING_FOR_ELEMENT_EVENT, this._commandSelectorTimeout);
|
|
return this._runRecursively()
|
|
.then(function () { return hammerhead.Promise.all([
|
|
_this._delayAfterExecution(),
|
|
barriers.wait(),
|
|
]); })
|
|
.then(function () {
|
|
var elements = __spreadArray([], _this._elements, true);
|
|
if (_this._targetElement)
|
|
elements[0] = _this._targetElement;
|
|
return elements;
|
|
});
|
|
};
|
|
ActionExecutor.EXECUTION_STARTED_EVENT = 'execution-started';
|
|
ActionExecutor.WAITING_FOR_ELEMENT_EVENT = 'waiting-for-elements';
|
|
ActionExecutor.WARNING_EVENT = 'warning';
|
|
ActionExecutor.ACTIONS_HANDLERS = {};
|
|
return ActionExecutor;
|
|
}(EventEmitter));
|
|
|
|
// -------------------------------------------------------------
|
|
// WARNING: this file is used by both the client and the server.
|
|
// Do not use any browser or node-specific API!
|
|
// -------------------------------------------------------------
|
|
function limitNumber (value, min, max) {
|
|
return Math.min(Math.max(min, value), max);
|
|
}
|
|
|
|
function determineDimensionBounds(bounds, maximum) {
|
|
var hasMin = typeof bounds.min === 'number';
|
|
var hasMax = typeof bounds.max === 'number';
|
|
var hasLength = typeof bounds.length === 'number';
|
|
if (hasLength)
|
|
bounds.length = limitNumber(bounds.length, 0, maximum);
|
|
if (hasMin && bounds.min < 0)
|
|
bounds.min += maximum;
|
|
if (hasMax && bounds.max < 0)
|
|
bounds.max += maximum;
|
|
if (!hasMin)
|
|
bounds.min = hasMax && hasLength ? bounds.max - bounds.length : 0;
|
|
if (!hasMax)
|
|
bounds.max = hasLength ? bounds.min + bounds.length : maximum;
|
|
bounds.min = limitNumber(bounds.min, 0, maximum);
|
|
bounds.max = limitNumber(bounds.max, 0, maximum);
|
|
bounds.length = bounds.max - bounds.min;
|
|
return bounds;
|
|
}
|
|
function determineScrollPoint(cropStart, cropEnd, viewportBound) {
|
|
return Math.round(cropStart + limitNumber(cropEnd - cropStart, 0, viewportBound) / 2);
|
|
}
|
|
function ensureCropOptions(element, options) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var elementRectangle, elementBounds, elementMargin, elementPadding, elementBordersWidth, scrollRight, scrollBottom, horizontalCropBounds, verticalCropBounds, viewportDimensions, hasScrollTargetX, hasScrollTargetY, _a, offsetX, offsetY, isScrollTargetXValid, isScrollTargetYValid;
|
|
return __generator(this, function (_b) {
|
|
elementRectangle = element.getBoundingClientRect();
|
|
elementBounds = {
|
|
left: elementRectangle.left,
|
|
right: elementRectangle.right,
|
|
top: elementRectangle.top,
|
|
bottom: elementRectangle.bottom,
|
|
};
|
|
elementMargin = testcafeCore.styleUtils.getElementMargin(element);
|
|
elementPadding = testcafeCore.styleUtils.getElementPadding(element);
|
|
elementBordersWidth = testcafeCore.styleUtils.getBordersWidth(element);
|
|
options.originOffset = { x: 0, y: 0 };
|
|
scrollRight = elementBounds.left + element.scrollWidth + elementBordersWidth.left + elementBordersWidth.right;
|
|
scrollBottom = elementBounds.top + element.scrollHeight + elementBordersWidth.top + elementBordersWidth.bottom;
|
|
elementBounds.right = Math.max(elementBounds.right, scrollRight);
|
|
elementBounds.bottom = Math.max(elementBounds.bottom, scrollBottom);
|
|
if (!options.includeBorders || !options.includePaddings) {
|
|
options.originOffset.x += elementBordersWidth.left;
|
|
options.originOffset.y += elementBordersWidth.top;
|
|
elementBounds.left += elementBordersWidth.left;
|
|
elementBounds.top += elementBordersWidth.top;
|
|
elementBounds.right -= elementBordersWidth.right;
|
|
elementBounds.bottom -= elementBordersWidth.bottom;
|
|
if (!options.includePaddings) {
|
|
options.originOffset.x += elementPadding.left;
|
|
options.originOffset.y += elementPadding.top;
|
|
elementBounds.left += elementPadding.left;
|
|
elementBounds.top += elementPadding.top;
|
|
elementBounds.right -= elementPadding.right;
|
|
elementBounds.bottom -= elementPadding.bottom;
|
|
}
|
|
}
|
|
else if (options.includeMargins) {
|
|
options.originOffset.x -= elementMargin.left;
|
|
options.originOffset.y -= elementMargin.top;
|
|
elementBounds.left -= elementMargin.left;
|
|
elementBounds.top -= elementMargin.top;
|
|
elementBounds.right += elementMargin.right;
|
|
elementBounds.bottom += elementMargin.bottom;
|
|
}
|
|
elementBounds.width = elementBounds.right - elementBounds.left;
|
|
elementBounds.height = elementBounds.bottom - elementBounds.top;
|
|
horizontalCropBounds = determineDimensionBounds({ min: options.crop.left, max: options.crop.right, length: options.crop.width }, elementBounds.width);
|
|
verticalCropBounds = determineDimensionBounds({ min: options.crop.top, max: options.crop.bottom, length: options.crop.height }, elementBounds.height);
|
|
options.crop.left = horizontalCropBounds.min;
|
|
options.crop.right = horizontalCropBounds.max;
|
|
options.crop.width = horizontalCropBounds.length;
|
|
options.crop.top = verticalCropBounds.min;
|
|
options.crop.bottom = verticalCropBounds.max;
|
|
options.crop.height = verticalCropBounds.length;
|
|
if (options.crop.width <= 0 || options.crop.height <= 0)
|
|
throw new InvalidElementScreenshotDimensionsError(options.crop.width, options.crop.height);
|
|
viewportDimensions = testcafeCore.styleUtils.getViewportDimensions();
|
|
if (elementBounds.width > viewportDimensions.width || elementBounds.height > viewportDimensions.height)
|
|
options.scrollToCenter = true;
|
|
hasScrollTargetX = typeof options.scrollTargetX === 'number';
|
|
hasScrollTargetY = typeof options.scrollTargetY === 'number';
|
|
if (!hasScrollTargetX)
|
|
options.scrollTargetX = determineScrollPoint(options.crop.left, options.crop.right, viewportDimensions.width);
|
|
if (!hasScrollTargetY)
|
|
options.scrollTargetY = determineScrollPoint(options.crop.top, options.crop.bottom, viewportDimensions.height);
|
|
_a = testcafeAutomation.getOffsetOptions(element, options.scrollTargetX, options.scrollTargetY), offsetX = _a.offsetX, offsetY = _a.offsetY;
|
|
options.scrollTargetX = offsetX;
|
|
options.scrollTargetY = offsetY;
|
|
isScrollTargetXValid = !hasScrollTargetX || options.scrollTargetX >= options.crop.left && options.scrollTargetX <= options.crop.right;
|
|
isScrollTargetYValid = !hasScrollTargetY || options.scrollTargetY >= options.crop.top && options.scrollTargetY <= options.crop.bottom;
|
|
if (!isScrollTargetXValid || !isScrollTargetYValid)
|
|
throw new ActionInvalidScrollTargetError(isScrollTargetXValid, isScrollTargetYValid);
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
}
|
|
|
|
var CHECK_ELEMENT_DELAY = 200;
|
|
|
|
var SelectorExecutor = /** @class */ (function (_super) {
|
|
__extends(SelectorExecutor, _super);
|
|
function SelectorExecutor(command, globalTimeout, startTime, createNotFoundError, createIsInvisibleError) {
|
|
var _this = _super.call(this, command) || this;
|
|
_this.createNotFoundError = createNotFoundError;
|
|
_this.createIsInvisibleError = createIsInvisibleError;
|
|
_this.timeout = typeof command.timeout === 'number' ? command.timeout : globalTimeout;
|
|
_this.counterMode = _this.dependencies.filterOptions.counterMode;
|
|
_this.getVisibleValueMode = _this.dependencies.filterOptions.getVisibleValueMode;
|
|
_this.dependencies.selectorFilter = selectorFilter;
|
|
if (startTime) {
|
|
var elapsed = hammerhead.nativeMethods.dateNow() - startTime;
|
|
_this.timeout = Math.max(_this.timeout - elapsed, 0);
|
|
}
|
|
var customDOMProperties = _this.dependencies.customDOMProperties;
|
|
_this.replicator.addTransforms([
|
|
new SelectorNodeTransform(customDOMProperties, command.instantiationCallsiteName),
|
|
]);
|
|
return _this;
|
|
}
|
|
SelectorExecutor.prototype._createReplicator = function () {
|
|
return createReplicator([
|
|
new FunctionTransform(),
|
|
]);
|
|
};
|
|
SelectorExecutor.prototype._getTimeoutErrorParams = function (el) {
|
|
var apiFnIndex = selectorFilter.error;
|
|
var apiFnChain = this.command.apiFnChain;
|
|
var reason = testcafeCore.positionUtils.getHiddenReason(el);
|
|
return { apiFnIndex: apiFnIndex, apiFnChain: apiFnChain, reason: reason };
|
|
};
|
|
SelectorExecutor.prototype._getTimeoutError = function (elementExists) {
|
|
return elementExists ? this.createIsInvisibleError : this.createNotFoundError;
|
|
};
|
|
SelectorExecutor.prototype._validateElement = function (args, startTime) {
|
|
var _this = this;
|
|
return hammerhead.Promise.resolve()
|
|
.then(function () { return _super.prototype._executeFn.call(_this, args); })
|
|
.then(function (el) {
|
|
var element = el;
|
|
var isElementExists = !!element;
|
|
var isElementVisible = !_this.command.visibilityCheck || element && testcafeCore.positionUtils.isElementVisible(element);
|
|
var isTimeout = hammerhead.nativeMethods.dateNow() - startTime >= _this.timeout;
|
|
if (isElementExists && (isElementVisible || hammerhead.utils.dom.isShadowRoot(element)))
|
|
return element;
|
|
if (!isTimeout)
|
|
return testcafeCore.delay(CHECK_ELEMENT_DELAY).then(function () { return _this._validateElement(args, startTime); });
|
|
var createTimeoutError = _this.getVisibleValueMode ? null : _this._getTimeoutError(isElementExists);
|
|
if (createTimeoutError)
|
|
throw createTimeoutError(_this._getTimeoutErrorParams(element));
|
|
return null;
|
|
});
|
|
};
|
|
SelectorExecutor.prototype._executeFn = function (args) {
|
|
if (this.counterMode)
|
|
return _super.prototype._executeFn.call(this, args);
|
|
return this._validateElement(args, hammerhead.nativeMethods.dateNow());
|
|
};
|
|
return SelectorExecutor;
|
|
}(ClientFunctionExecutor));
|
|
|
|
var DateCtor = hammerhead.nativeMethods.date;
|
|
var ElementsRetriever$1 = /** @class */ (function () {
|
|
function ElementsRetriever(elementDescriptors, globalSelectorTimeout) {
|
|
var _this = this;
|
|
this.elements = [];
|
|
this.globalSelectorTimeout = globalSelectorTimeout;
|
|
this.ensureElementsPromise = hammerhead.Promise.resolve();
|
|
this.ensureElementsStartTime = new DateCtor();
|
|
elementDescriptors.forEach(function (descriptor) { return _this._ensureElement(descriptor); });
|
|
}
|
|
ElementsRetriever.prototype._ensureElement = function (_a) {
|
|
var _this = this;
|
|
var selector = _a.selector, createNotFoundError = _a.createNotFoundError, createIsInvisibleError = _a.createIsInvisibleError, createHasWrongNodeTypeError = _a.createHasWrongNodeTypeError;
|
|
this.ensureElementsPromise = this.ensureElementsPromise
|
|
.then(function () {
|
|
var selectorExecutor = new SelectorExecutor(selector, _this.globalSelectorTimeout, _this.ensureElementsStartTime, createNotFoundError, createIsInvisibleError);
|
|
return selectorExecutor.getResult();
|
|
})
|
|
.then(function (el) {
|
|
if (!testcafeCore.domUtils.isDomElement(el))
|
|
throw createHasWrongNodeTypeError(NODE_TYPE_DESCRIPTIONS[el.nodeType]);
|
|
_this.elements.push(el);
|
|
});
|
|
};
|
|
ElementsRetriever.prototype.getElements = function () {
|
|
var _this = this;
|
|
return this.ensureElementsPromise
|
|
.then(function () { return _this.elements; });
|
|
};
|
|
return ElementsRetriever;
|
|
}());
|
|
function ensureElements(elementDescriptors, globalSelectorTimeout) {
|
|
var elementsRetriever = new ElementsRetriever$1(elementDescriptors, globalSelectorTimeout);
|
|
return elementsRetriever.getElements();
|
|
}
|
|
function createElementDescriptor(selector) {
|
|
return {
|
|
selector: selector,
|
|
createNotFoundError: function (fn) { return new ActionElementNotFoundError(null, fn); },
|
|
createIsInvisibleError: function (fn) { return new ActionElementIsInvisibleError(null, fn); },
|
|
createHasWrongNodeTypeError: function (nodeDescription) { return new ActionSelectorMatchesWrongNodeTypeError(nodeDescription); },
|
|
};
|
|
}
|
|
|
|
function runWithBarriers (action) {
|
|
var args = [];
|
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
args[_i - 1] = arguments[_i];
|
|
}
|
|
var requestEmitter = new testcafeCore.ClientRequestEmitter();
|
|
var requestBarrier = new testcafeCore.RequestBarrier(requestEmitter);
|
|
var scriptEmitter = new testcafeCore.ScriptExecutionEmitter();
|
|
var scriptExecutionBarrier = new testcafeCore.ScriptExecutionBarrier(scriptEmitter);
|
|
testcafeCore.pageUnloadBarrier.watchForPageNavigationTriggers();
|
|
var actionResult = null;
|
|
var actionPromise = action.apply(void 0, args);
|
|
var barriersPromise = actionPromise
|
|
.then(function (result) {
|
|
actionResult = result;
|
|
return hammerhead.Promise.all([
|
|
// NOTE: script can be added by xhr-request, so we should run
|
|
// script execution barrier waiting after request barrier resolved
|
|
requestBarrier
|
|
.wait()
|
|
.then(function () { return scriptExecutionBarrier.wait(); }),
|
|
testcafeCore.pageUnloadBarrier.wait(),
|
|
]);
|
|
})
|
|
.then(function () { return actionResult; });
|
|
return { actionPromise: actionPromise, barriersPromise: barriersPromise };
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
// WARNING: this file is used by both the client and the server.
|
|
// Do not use any browser or node-specific API!
|
|
// -------------------------------------------------------------
|
|
function createIntegerValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
var valType = typeof val;
|
|
if (valType !== 'number')
|
|
throw new ErrorCtor(name, valType);
|
|
var isInteger = !isNaN(val) &&
|
|
isFinite(val) &&
|
|
val === Math.floor(val);
|
|
if (!isInteger)
|
|
throw new ErrorCtor(name, val);
|
|
};
|
|
}
|
|
function createPositiveIntegerValidator(ErrorCtor) {
|
|
var integerValidator = createIntegerValidator(ErrorCtor);
|
|
return function (name, val) {
|
|
integerValidator(name, val);
|
|
if (val < 0)
|
|
throw new ErrorCtor(name, val);
|
|
};
|
|
}
|
|
function createBooleanValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
var valType = typeof val;
|
|
if (valType !== 'boolean')
|
|
throw new ErrorCtor(name, valType);
|
|
};
|
|
}
|
|
function createSpeedValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
var valType = typeof val;
|
|
if (valType !== 'number')
|
|
throw new ErrorCtor(name, valType);
|
|
if (isNaN(val) || val < 0.01 || val > 1)
|
|
throw new ErrorCtor(name, val);
|
|
};
|
|
}
|
|
function createStringValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
var valType = typeof val;
|
|
if (valType !== 'string')
|
|
throw new ErrorCtor(name, valType);
|
|
};
|
|
}
|
|
function createStringOrRegexValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
var valType = typeof val;
|
|
if (valType !== 'string' && !(val instanceof RegExp))
|
|
throw new ErrorCtor(name, valType);
|
|
};
|
|
}
|
|
function createDateValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
if (!(val instanceof Date))
|
|
throw new ErrorCtor(name, val);
|
|
};
|
|
}
|
|
function createNumberValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
if (isNaN(Number(val)))
|
|
throw new ErrorCtor(name, typeof val);
|
|
};
|
|
}
|
|
function createUrlValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
var valType = typeof val;
|
|
if (valType !== 'string' && !(val instanceof URL))
|
|
throw new ErrorCtor(name, valType);
|
|
};
|
|
}
|
|
function createUrlSearchParamsValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
var valType = typeof val;
|
|
if (valType !== 'object' && !(val instanceof URLSearchParams))
|
|
throw new ErrorCtor(name, valType);
|
|
};
|
|
}
|
|
function createObjectValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
var valType = typeof val;
|
|
if (valType !== 'object')
|
|
throw new ErrorCtor(name, valType);
|
|
};
|
|
}
|
|
function createFunctionValidator(ErrorCtor) {
|
|
return function (name, val) {
|
|
var valType = typeof val;
|
|
if (valType !== 'function')
|
|
throw new ErrorCtor(name, valType);
|
|
};
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
var integerOption = createIntegerValidator(ActionIntegerOptionError);
|
|
var positiveIntegerOption = createPositiveIntegerValidator(ActionPositiveIntegerOptionError);
|
|
var booleanOption = createBooleanValidator(ActionBooleanOptionError);
|
|
var speedOption = createSpeedValidator(ActionSpeedOptionError);
|
|
var stringOption = createStringValidator(ActionStringOptionError);
|
|
var stringOrRegexOption = createStringOrRegexValidator(ActionStringOrRegexOptionError);
|
|
var dateOption = createDateValidator(ActionDateOptionError);
|
|
var numberOption = createNumberValidator(ActionNumberOptionError);
|
|
var urlOption = createUrlValidator(ActionUrlOptionError);
|
|
var urlSearchParamsOption = createUrlSearchParamsValidator(ActionUrlSearchParamsOptionError);
|
|
var objectOption = createObjectValidator(ActionObjectOptionError);
|
|
var functionOption = createFunctionValidator(ActionFunctionOptionError);
|
|
// Actions
|
|
var ActionOptions = /** @class */ (function (_super) {
|
|
__extends(ActionOptions, _super);
|
|
function ActionOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.speed = null;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
ActionOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'speed', type: speedOption },
|
|
];
|
|
};
|
|
return ActionOptions;
|
|
}(Assignable));
|
|
// Offset
|
|
var OffsetOptions = /** @class */ (function (_super) {
|
|
__extends(OffsetOptions, _super);
|
|
function OffsetOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.offsetX = null;
|
|
_this.offsetY = null;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
OffsetOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'offsetX', type: integerOption },
|
|
{ name: 'offsetY', type: integerOption },
|
|
{ name: 'isDefaultOffset', type: booleanOption },
|
|
];
|
|
};
|
|
return OffsetOptions;
|
|
}(ActionOptions));
|
|
var ScrollOptions = /** @class */ (function (_super) {
|
|
__extends(ScrollOptions, _super);
|
|
function ScrollOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.scrollToCenter = false;
|
|
_this.skipParentFrames = false;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
ScrollOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'scrollToCenter', type: booleanOption },
|
|
{ name: 'skipParentFrames', type: booleanOption },
|
|
];
|
|
};
|
|
return ScrollOptions;
|
|
}(OffsetOptions));
|
|
var CropOptions = /** @class */ (function (_super) {
|
|
__extends(CropOptions, _super);
|
|
function CropOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
CropOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'left', type: integerOption, defaultValue: null },
|
|
{ name: 'right', type: integerOption, defaultValue: null },
|
|
{ name: 'top', type: integerOption, defaultValue: null },
|
|
{ name: 'bottom', type: integerOption, defaultValue: null },
|
|
];
|
|
};
|
|
return CropOptions;
|
|
}(Assignable));
|
|
// Element Screenshot
|
|
var ElementScreenshotOptions = /** @class */ (function (_super) {
|
|
__extends(ElementScreenshotOptions, _super);
|
|
function ElementScreenshotOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.scrollTargetX = null;
|
|
_this.scrollTargetY = null;
|
|
_this.includeMargins = false;
|
|
_this.includeBorders = true;
|
|
_this.includePaddings = true;
|
|
_this.crop = {
|
|
left: null,
|
|
right: null,
|
|
top: null,
|
|
bottom: null,
|
|
};
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
ElementScreenshotOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'scrollTargetX', type: integerOption },
|
|
{ name: 'scrollTargetY', type: integerOption },
|
|
{ name: 'crop', type: objectOption, init: initCropOptions },
|
|
{ name: 'includeMargins', type: booleanOption },
|
|
{ name: 'includeBorders', type: booleanOption },
|
|
{ name: 'includePaddings', type: booleanOption },
|
|
];
|
|
};
|
|
return ElementScreenshotOptions;
|
|
}(ActionOptions));
|
|
var ModifiersOptions = /** @class */ (function (_super) {
|
|
__extends(ModifiersOptions, _super);
|
|
function ModifiersOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
ModifiersOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'ctrl', type: booleanOption, defaultValue: false },
|
|
{ name: 'alt', type: booleanOption, defaultValue: false },
|
|
{ name: 'shift', type: booleanOption, defaultValue: false },
|
|
{ name: 'meta', type: booleanOption, defaultValue: false },
|
|
];
|
|
};
|
|
return ModifiersOptions;
|
|
}(Assignable));
|
|
// Mouse
|
|
var MouseOptions = /** @class */ (function (_super) {
|
|
__extends(MouseOptions, _super);
|
|
function MouseOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.modifiers = {
|
|
ctrl: false,
|
|
alt: false,
|
|
shift: false,
|
|
meta: false,
|
|
};
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
MouseOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'modifiers', type: objectOption, init: initModifiersOptions },
|
|
];
|
|
};
|
|
return MouseOptions;
|
|
}(OffsetOptions));
|
|
// Click
|
|
var ClickOptions = /** @class */ (function (_super) {
|
|
__extends(ClickOptions, _super);
|
|
function ClickOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.caretPos = null;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
ClickOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'caretPos', type: positiveIntegerOption },
|
|
];
|
|
};
|
|
return ClickOptions;
|
|
}(MouseOptions));
|
|
// Move
|
|
var MoveOptions = /** @class */ (function (_super) {
|
|
__extends(MoveOptions, _super);
|
|
function MoveOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.speed = null;
|
|
_this.minMovingTime = null;
|
|
_this.holdLeftButton = false;
|
|
_this.skipScrolling = false;
|
|
_this.skipDefaultDragBehavior = false;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
MoveOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'speed' },
|
|
{ name: 'minMovingTime' },
|
|
{ name: 'holdLeftButton' },
|
|
{ name: 'skipScrolling', type: booleanOption },
|
|
{ name: 'skipDefaultDragBehavior', type: booleanOption },
|
|
];
|
|
};
|
|
return MoveOptions;
|
|
}(MouseOptions));
|
|
// Type
|
|
var TypeOptions = /** @class */ (function (_super) {
|
|
__extends(TypeOptions, _super);
|
|
function TypeOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.replace = false;
|
|
_this.paste = false;
|
|
_this.confidential = void 0;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
TypeOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'replace', type: booleanOption },
|
|
{ name: 'paste', type: booleanOption },
|
|
{ name: 'confidential', type: booleanOption },
|
|
];
|
|
};
|
|
return TypeOptions;
|
|
}(ClickOptions));
|
|
// DragToElement
|
|
var DragToElementOptions = /** @class */ (function (_super) {
|
|
__extends(DragToElementOptions, _super);
|
|
function DragToElementOptions(obj, validate) {
|
|
var _this = _super.call(this, obj, validate) || this;
|
|
_this.destinationOffsetX = null;
|
|
_this.destinationOffsetY = null;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
DragToElementOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'destinationOffsetX', type: integerOption },
|
|
{ name: 'destinationOffsetY', type: integerOption },
|
|
];
|
|
};
|
|
return DragToElementOptions;
|
|
}(MouseOptions));
|
|
//ResizeToFitDevice
|
|
var ResizeToFitDeviceOptions = /** @class */ (function (_super) {
|
|
__extends(ResizeToFitDeviceOptions, _super);
|
|
function ResizeToFitDeviceOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.portraitOrientation = false;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
ResizeToFitDeviceOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'portraitOrientation', type: booleanOption },
|
|
];
|
|
};
|
|
return ResizeToFitDeviceOptions;
|
|
}(Assignable));
|
|
//Assertion
|
|
var AssertionOptions = /** @class */ (function (_super) {
|
|
__extends(AssertionOptions, _super);
|
|
function AssertionOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.timeout = void 0;
|
|
_this.allowUnawaitedPromise = false;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
AssertionOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'timeout', type: positiveIntegerOption },
|
|
{ name: 'allowUnawaitedPromise', type: booleanOption },
|
|
];
|
|
};
|
|
return AssertionOptions;
|
|
}(Assignable));
|
|
// Press
|
|
var PressOptions = /** @class */ (function (_super) {
|
|
__extends(PressOptions, _super);
|
|
function PressOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this.confidential = void 0;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
PressOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'confidential', type: booleanOption },
|
|
];
|
|
};
|
|
return PressOptions;
|
|
}(ActionOptions));
|
|
// Cookie
|
|
var CookieOptions = /** @class */ (function (_super) {
|
|
__extends(CookieOptions, _super);
|
|
function CookieOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
CookieOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'name', type: stringOption },
|
|
{ name: 'value', type: stringOption },
|
|
{ name: 'domain', type: stringOption },
|
|
{ name: 'path', type: stringOption },
|
|
{ name: 'expires', type: dateOption },
|
|
{ name: 'maxAge', type: numberOption },
|
|
{ name: 'secure', type: booleanOption },
|
|
{ name: 'httpOnly', type: booleanOption },
|
|
{ name: 'sameSite', type: stringOption },
|
|
];
|
|
};
|
|
return CookieOptions;
|
|
}(Assignable));
|
|
var RequestAuthOptions = /** @class */ (function (_super) {
|
|
__extends(RequestAuthOptions, _super);
|
|
function RequestAuthOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
RequestAuthOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'username', type: stringOption, required: true },
|
|
{ name: 'password', type: stringOption },
|
|
];
|
|
};
|
|
return RequestAuthOptions;
|
|
}(Assignable));
|
|
var RequestProxyOptions = /** @class */ (function (_super) {
|
|
__extends(RequestProxyOptions, _super);
|
|
function RequestProxyOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
RequestProxyOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'protocol', type: stringOption },
|
|
{ name: 'host', type: stringOption, required: true },
|
|
{ name: 'port', type: numberOption, required: true },
|
|
{ name: 'auth', type: objectOption, init: initRequestAuthOption },
|
|
];
|
|
};
|
|
return RequestProxyOptions;
|
|
}(Assignable));
|
|
var RequestOptions = /** @class */ (function (_super) {
|
|
__extends(RequestOptions, _super);
|
|
function RequestOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
RequestOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'url', type: urlOption },
|
|
{ name: 'method', type: stringOption },
|
|
{ name: 'headers', type: objectOption },
|
|
{ name: 'params', type: urlSearchParamsOption },
|
|
{ name: 'body' },
|
|
{ name: 'timeout', type: numberOption },
|
|
{ name: 'withCredentials', type: booleanOption },
|
|
{ name: 'auth', type: objectOption, init: initRequestAuthOption },
|
|
{ name: 'proxy', type: objectOption, init: initRequestProxyOptions },
|
|
{ name: 'rawResponse', type: booleanOption },
|
|
];
|
|
};
|
|
return RequestOptions;
|
|
}(Assignable));
|
|
var GetProxyUrlOptions = /** @class */ (function (_super) {
|
|
__extends(GetProxyUrlOptions, _super);
|
|
function GetProxyUrlOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
GetProxyUrlOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'credentials', type: numberOption },
|
|
];
|
|
};
|
|
return GetProxyUrlOptions;
|
|
}(Assignable));
|
|
var SkipJsErrorsOptions = /** @class */ (function (_super) {
|
|
__extends(SkipJsErrorsOptions, _super);
|
|
function SkipJsErrorsOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
SkipJsErrorsOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'stack', type: stringOrRegexOption, required: false },
|
|
{ name: 'message', type: stringOrRegexOption, required: false },
|
|
{ name: 'pageUrl', type: stringOrRegexOption, required: false },
|
|
];
|
|
};
|
|
return SkipJsErrorsOptions;
|
|
}(Assignable));
|
|
var SkipJsErrorsCallbackWithOptions = /** @class */ (function (_super) {
|
|
__extends(SkipJsErrorsCallbackWithOptions, _super);
|
|
function SkipJsErrorsCallbackWithOptions(obj, validate) {
|
|
var _this = _super.call(this) || this;
|
|
_this._assignFrom(obj, validate);
|
|
return _this;
|
|
}
|
|
SkipJsErrorsCallbackWithOptions.prototype.getAssignableProperties = function () {
|
|
return [
|
|
{ name: 'fn', type: functionOption, required: true },
|
|
{ name: 'dependencies', type: objectOption, required: false },
|
|
];
|
|
};
|
|
return SkipJsErrorsCallbackWithOptions;
|
|
}(Assignable));
|
|
// Initializers
|
|
function initRequestAuthOption(name, val, initOptions, validate) {
|
|
if (validate === void 0) { validate = true; }
|
|
return new RequestAuthOptions(val, validate);
|
|
}
|
|
function initRequestProxyOptions(name, val, initOptions, validate) {
|
|
if (validate === void 0) { validate = true; }
|
|
return new RequestProxyOptions(val, validate);
|
|
}
|
|
function initCropOptions(name, val, initOptions, validate) {
|
|
if (validate === void 0) { validate = true; }
|
|
return new CropOptions(val, validate);
|
|
}
|
|
function initModifiersOptions(name, val, initOptions, validate) {
|
|
if (validate === void 0) { validate = true; }
|
|
return new ModifiersOptions(val, validate);
|
|
}
|
|
|
|
function isIframeWindow(window) {
|
|
return window.top !== window;
|
|
}
|
|
|
|
var messageSandbox$1 = hammerhead.eventSandbox.message;
|
|
var HIDING_UI_RELAYOUT_DELAY = 500;
|
|
var POSSIBLE_RESIZE_ERROR_DELAY = 200;
|
|
var MANIPULATION_REQUEST_CMD = 'driver|browser-manipulation|request';
|
|
var MANIPULATION_RESPONSE_CMD = 'driver|browser-manipulation|response';
|
|
// Setup cross-iframe interaction
|
|
messageSandbox$1.on(messageSandbox$1.SERVICE_MSG_RECEIVED_EVENT, function (e) {
|
|
if (e.message.cmd === MANIPULATION_REQUEST_CMD) {
|
|
var element = testcafeCore.domUtils.findIframeByWindow(e.source);
|
|
var _a = e.message, command = _a.command, cropDimensions = _a.cropDimensions;
|
|
if (cropDimensions)
|
|
command.options = new ElementScreenshotOptions({ crop: cropDimensions, includePaddings: false });
|
|
var manipulation = new ManipulationExecutor(command);
|
|
manipulation.element = element;
|
|
manipulation
|
|
.execute()
|
|
.then(function (result) { return messageSandbox$1.sendServiceMsg({ cmd: MANIPULATION_RESPONSE_CMD, result: result }, e.source); });
|
|
}
|
|
});
|
|
var ManipulationExecutor = /** @class */ (function () {
|
|
function ManipulationExecutor(command, globalSelectorTimeout, statusBar) {
|
|
this.command = command;
|
|
this.globalSelectorTimeout = globalSelectorTimeout;
|
|
this.statusBar = statusBar;
|
|
this.element = null;
|
|
}
|
|
ManipulationExecutor.prototype._getAbsoluteCropValues = function () {
|
|
var _a = this.element.getBoundingClientRect(), top = _a.top, left = _a.left;
|
|
left += this.command.options.originOffset.x;
|
|
top += this.command.options.originOffset.y;
|
|
var right = left + this.command.options.crop.right;
|
|
var bottom = top + this.command.options.crop.bottom;
|
|
top += this.command.options.crop.top;
|
|
left += this.command.options.crop.left;
|
|
return { top: top, left: left, bottom: bottom, right: right };
|
|
};
|
|
ManipulationExecutor.prototype._createManipulationReadyMessage = function () {
|
|
var dpr = window.devicePixelRatio || 1;
|
|
var message = {
|
|
cmd: TEST_RUN_MESSAGES.readyForBrowserManipulation,
|
|
pageDimensions: {
|
|
dpr: dpr,
|
|
innerWidth: window.innerWidth,
|
|
innerHeight: window.innerHeight,
|
|
documentWidth: document.documentElement.clientWidth,
|
|
documentHeight: document.documentElement.clientHeight,
|
|
bodyWidth: document.body.clientWidth,
|
|
bodyHeight: document.body.clientHeight,
|
|
},
|
|
disableResending: true,
|
|
};
|
|
if (this.command.type === COMMAND_TYPE.takeElementScreenshot)
|
|
message.cropDimensions = this._getAbsoluteCropValues();
|
|
return message;
|
|
};
|
|
ManipulationExecutor.prototype._runScrollBeforeScreenshot = function () {
|
|
var _this = this;
|
|
return hammerhead.Promise
|
|
.resolve()
|
|
.then(function () {
|
|
if (_this.element || !_this.command.selector)
|
|
return hammerhead.Promise.resolve();
|
|
var selectorTimeout = _this.command.selector.timeout;
|
|
var specificSelectorTimeout = typeof selectorTimeout === 'number' ? selectorTimeout : _this.globalSelectorTimeout;
|
|
_this.statusBar.showWaitingElementStatus(specificSelectorTimeout);
|
|
return ensureElements([createElementDescriptor(_this.command.selector)], _this.globalSelectorTimeout)
|
|
.then(function (elements) {
|
|
_this.statusBar.hideWaitingElementStatus();
|
|
_this.element = elements[0];
|
|
})
|
|
.catch(function (error) {
|
|
_this.statusBar.hideWaitingElementStatus();
|
|
throw error;
|
|
});
|
|
})
|
|
.then(function () { return ensureCropOptions(_this.element, _this.command.options); })
|
|
.then(function () {
|
|
var _a = _this.command.options, scrollTargetX = _a.scrollTargetX, scrollTargetY = _a.scrollTargetY, scrollToCenter = _a.scrollToCenter;
|
|
var scrollAutomation = new testcafeCore.ScrollAutomation(_this.element, new ScrollOptions({
|
|
offsetX: scrollTargetX,
|
|
offsetY: scrollTargetY,
|
|
scrollToCenter: scrollToCenter,
|
|
skipParentFrames: true,
|
|
}));
|
|
return scrollAutomation.run();
|
|
});
|
|
};
|
|
ManipulationExecutor.prototype._hideUI = function () {
|
|
testCafeUI.hide();
|
|
if (this.command.markData)
|
|
testCafeUI.showScreenshotMark(this.command.markData);
|
|
return testcafeCore.delay(HIDING_UI_RELAYOUT_DELAY);
|
|
};
|
|
ManipulationExecutor.prototype._showUI = function () {
|
|
if (this.command.markData)
|
|
testCafeUI.hideScreenshotMark();
|
|
testCafeUI.show();
|
|
};
|
|
ManipulationExecutor.prototype._requestManipulation = function () {
|
|
if (!isIframeWindow(window))
|
|
return hammerhead.transport.queuedAsyncServiceMsg(this._createManipulationReadyMessage());
|
|
var cropDimensions = this._getAbsoluteCropValues();
|
|
var iframeRequestPromise = testcafeCore.sendRequestToFrame({
|
|
cmd: MANIPULATION_REQUEST_CMD,
|
|
command: this.command,
|
|
cropDimensions: cropDimensions,
|
|
}, MANIPULATION_RESPONSE_CMD, window.parent);
|
|
return iframeRequestPromise
|
|
.then(function (message) {
|
|
if (!message.result)
|
|
return { result: null };
|
|
var _a = message.result, result = _a.result, executionError = _a.executionError;
|
|
if (executionError)
|
|
throw executionError;
|
|
return { result: result };
|
|
});
|
|
};
|
|
ManipulationExecutor.prototype._runManipulation = function () {
|
|
var _this = this;
|
|
var manipulationResult = null;
|
|
return hammerhead.Promise
|
|
.resolve()
|
|
.then(function () {
|
|
if (_this.command.type !== COMMAND_TYPE.takeElementScreenshot)
|
|
return hammerhead.Promise.resolve();
|
|
testcafeCore.scrollController.stopPropagation();
|
|
return _this._runScrollBeforeScreenshot();
|
|
})
|
|
.then(function () {
|
|
if (!isIframeWindow(window))
|
|
return _this._hideUI();
|
|
return hammerhead.Promise.resolve();
|
|
})
|
|
.then(function () { return _this._requestManipulation(); })
|
|
.then(function (_a) {
|
|
var result = _a.result, error = _a.error;
|
|
if (error)
|
|
throw error;
|
|
testcafeCore.scrollController.enablePropagation();
|
|
manipulationResult = result;
|
|
if (!isIframeWindow(window))
|
|
_this._showUI();
|
|
return testcafeCore.delay(POSSIBLE_RESIZE_ERROR_DELAY);
|
|
})
|
|
.then(function () { return new DriverStatus({ isCommandResult: true, result: manipulationResult }); })
|
|
.catch(function (err) {
|
|
testcafeCore.scrollController.enablePropagation();
|
|
return new DriverStatus({ isCommandResult: true, executionError: err });
|
|
});
|
|
};
|
|
ManipulationExecutor.prototype.execute = function () {
|
|
var _this = this;
|
|
var barriersPromise = runWithBarriers(function () { return _this._runManipulation(); }).barriersPromise;
|
|
return barriersPromise;
|
|
};
|
|
return ManipulationExecutor;
|
|
}());
|
|
function executeManipulationCommand (command, globalSelectorTimeout, statusBar) {
|
|
var manipulationExecutor = new ManipulationExecutor(command, globalSelectorTimeout, statusBar);
|
|
return manipulationExecutor.execute();
|
|
}
|
|
|
|
function executeNavigateTo(command) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var requestEmitter, requestBarrier, error_1;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
_a.trys.push([0, 2, , 3]);
|
|
requestEmitter = new testcafeCore.ClientRequestEmitter();
|
|
requestBarrier = new testcafeCore.RequestBarrier(requestEmitter);
|
|
hammerhead.navigateTo(command.url, command.forceReload);
|
|
return [4 /*yield*/, hammerhead.Promise.all([requestBarrier.wait(), testcafeCore.pageUnloadBarrier.wait()])];
|
|
case 1:
|
|
_a.sent();
|
|
return [2 /*return*/, new DriverStatus({ isCommandResult: true })];
|
|
case 2:
|
|
error_1 = _a.sent();
|
|
return [2 /*return*/, new DriverStatus({ isCommandResult: true, executionError: error_1 })];
|
|
case 3: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function getExecutorResultDriverStatus(executor) {
|
|
return executor
|
|
.getResult()
|
|
.then(function (result) { return new DriverStatus({
|
|
isCommandResult: true,
|
|
result: executor.encodeResult(result),
|
|
}); })
|
|
.catch(function (err) { return new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: err,
|
|
}); });
|
|
}
|
|
|
|
function getResult(command, globalTimeout, startTime, createNotFoundError, createIsInvisibleError, statusBar) {
|
|
var selectorExecutor = new SelectorExecutor(command, globalTimeout, startTime, createNotFoundError, createIsInvisibleError);
|
|
statusBar.showWaitingElementStatus(selectorExecutor.timeout);
|
|
return selectorExecutor.getResult()
|
|
.then(function (el) {
|
|
return statusBar.hideWaitingElementStatus(!!el)
|
|
.then(function () { return el; });
|
|
})
|
|
.catch(function (err) {
|
|
return statusBar.hideWaitingElementStatus(false)
|
|
.then(function () {
|
|
throw err;
|
|
});
|
|
});
|
|
}
|
|
function getResultDriverStatus(command, globalTimeout, startTime, createNotFoundError, createIsInvisibleError, statusBar) {
|
|
var selectorExecutor = new SelectorExecutor(command, globalTimeout, startTime, createNotFoundError, createIsInvisibleError);
|
|
statusBar.showWaitingElementStatus(selectorExecutor.timeout);
|
|
return getExecutorResultDriverStatus(selectorExecutor)
|
|
.then(function (status) {
|
|
return statusBar.hideWaitingElementStatus(!!status.result)
|
|
.then(function () { return status; });
|
|
});
|
|
}
|
|
|
|
var Promise$1 = hammerhead__default.Promise;
|
|
function executeChildWindowDriverLinkSelector(selector, childWindowLinks) {
|
|
if (typeof selector === 'string') {
|
|
var foundChildWindowDriverLink = testcafeCore.arrayUtils.find(childWindowLinks, function (link) { return link.windowId === selector; });
|
|
if (!foundChildWindowDriverLink) {
|
|
var error = new ChildWindowNotFoundError();
|
|
return Promise$1.reject(error);
|
|
}
|
|
// NOTE: We cannot pass the driver window of the found child window driver link
|
|
// because the current Promise implementation checks the type of the value passed to the 'resolve' function.
|
|
// It causes an unhandled JavaScript error on accessing to cross-domain iframe.
|
|
return Promise$1.resolve(foundChildWindowDriverLink);
|
|
}
|
|
// TODO: Query url and title properties of the all driverLinks' windows
|
|
return Promise$1.resolve(null);
|
|
}
|
|
|
|
var ChildWindowDriverLink = /** @class */ (function () {
|
|
function ChildWindowDriverLink(driverWindow, windowId) {
|
|
this._isNonPageWindow = false;
|
|
this.driverWindow = driverWindow;
|
|
this.windowId = windowId;
|
|
}
|
|
ChildWindowDriverLink.prototype.setAsMaster = function (finalizePendingCommand) {
|
|
var _this = this;
|
|
var msg = new SetAsMasterMessage(finalizePendingCommand);
|
|
return sendMessageToDriver(msg, this.driverWindow, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError)
|
|
.catch(function (err) {
|
|
if (_this._isNonPageWindow)
|
|
return;
|
|
throw err;
|
|
});
|
|
};
|
|
ChildWindowDriverLink.prototype.closeAllChildWindows = function () {
|
|
var msg = new CloseAllChildWindowsMessage();
|
|
return sendMessageToDriver(msg, this.driverWindow, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CloseChildWindowError);
|
|
};
|
|
ChildWindowDriverLink.prototype.findChildWindows = function (options, MessageCtor) {
|
|
var msg = new MessageCtor(options);
|
|
return sendMessageToDriver(msg, this.driverWindow, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError);
|
|
};
|
|
ChildWindowDriverLink.prototype.startToRestore = function () {
|
|
var msg = new StartToRestoreChildLinkMessage();
|
|
return sendMessageToDriver(msg, this.driverWindow, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError);
|
|
};
|
|
ChildWindowDriverLink.prototype.closeFileDownloadingWindow = function () {
|
|
this._isNonPageWindow = true;
|
|
this.driverWindow.close();
|
|
};
|
|
return ChildWindowDriverLink;
|
|
}());
|
|
|
|
var ParentWindowDriverLink = /** @class */ (function () {
|
|
function ParentWindowDriverLink(currentDriverWindow) {
|
|
this.currentDriverWindow = currentDriverWindow;
|
|
}
|
|
ParentWindowDriverLink.prototype._getTopOpenedWindow = function (wnd) {
|
|
var topOpened = wnd;
|
|
while (topOpened.opener)
|
|
topOpened = topOpened.opener;
|
|
return topOpened.top;
|
|
};
|
|
ParentWindowDriverLink.prototype._setAsMaster = function (wnd, finalizePendingCommand) {
|
|
var msg = new SetAsMasterMessage(finalizePendingCommand);
|
|
return sendMessageToDriver(msg, wnd, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError);
|
|
};
|
|
ParentWindowDriverLink.prototype.getTopOpenedWindow = function () {
|
|
return this._getTopOpenedWindow(this.currentDriverWindow);
|
|
};
|
|
ParentWindowDriverLink.prototype.setTopOpenedWindowAsMaster = function () {
|
|
var wnd = this._getTopOpenedWindow(this.currentDriverWindow);
|
|
return this._setAsMaster(wnd);
|
|
};
|
|
ParentWindowDriverLink.prototype.setParentWindowAsMaster = function (opts) {
|
|
if (opts === void 0) { opts = {}; }
|
|
var wnd = this.currentDriverWindow.opener;
|
|
return this._setAsMaster(wnd, opts.finalizePendingCommand);
|
|
};
|
|
ParentWindowDriverLink.prototype.restoreChild = function (windowId) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var msg, wnd;
|
|
return __generator(this, function (_a) {
|
|
msg = new RestoreChildLinkMessage(windowId);
|
|
wnd = this.currentDriverWindow.opener;
|
|
sendMessageToDriver(msg, wnd, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError);
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
return ParentWindowDriverLink;
|
|
}());
|
|
|
|
var DriverRole = {
|
|
master: 'master',
|
|
replica: 'replica',
|
|
};
|
|
|
|
var SelectorElementActionTransform = /** @class */ (function () {
|
|
function SelectorElementActionTransform() {
|
|
this.type = 'Node';
|
|
}
|
|
SelectorElementActionTransform.prototype.shouldTransform = function (type, val) {
|
|
return val instanceof hammerhead.nativeMethods.Node;
|
|
};
|
|
SelectorElementActionTransform.prototype.toSerializable = function (node) {
|
|
return new ElementActionSnapshot(node);
|
|
};
|
|
SelectorElementActionTransform.prototype.fromSerializable = function () {
|
|
};
|
|
return SelectorElementActionTransform;
|
|
}());
|
|
|
|
var REQUESTS_COLLECTION_DELAY_DEFAULT = 50;
|
|
var RequestBarrier = /** @class */ (function () {
|
|
function RequestBarrier(emitter, delays) {
|
|
if (delays === void 0) { delays = {}; }
|
|
var _a, _b, _c;
|
|
this._delays = {
|
|
requestsCollection: (_a = delays.requestsCollection) !== null && _a !== void 0 ? _a : REQUESTS_COLLECTION_DELAY_DEFAULT,
|
|
additionalRequestsCollection: (_b = delays.additionalRequestsCollection) !== null && _b !== void 0 ? _b : REQUESTS_COLLECTION_DELAY_DEFAULT,
|
|
pageInitialRequestsCollection: (_c = delays.pageInitialRequestsCollection) !== null && _c !== void 0 ? _c : REQUESTS_COLLECTION_DELAY_DEFAULT,
|
|
};
|
|
this._emitter = emitter;
|
|
this._waitResolve = null;
|
|
this._watchdog = null;
|
|
this._requests = new Set();
|
|
this._collectingReqs = true;
|
|
this._startListening();
|
|
}
|
|
RequestBarrier.prototype._startListening = function () {
|
|
var _this = this;
|
|
this._emitter.onRequestSend(function (req) { return _this._onRequestSend(req); });
|
|
this._emitter.onRequestCompleted(function (req) { return _this._onRequestCompleted(req); });
|
|
this._emitter.onRequestError(function (req) { return _this._onRequestError(req); });
|
|
};
|
|
RequestBarrier.prototype._offListening = function () {
|
|
this._emitter.offAll();
|
|
};
|
|
RequestBarrier.prototype._onRequestSend = function (req) {
|
|
if (this._collectingReqs)
|
|
this._requests.add(req);
|
|
};
|
|
RequestBarrier.prototype._onRequestCompleted = function (req) {
|
|
var _this = this;
|
|
// NOTE: let the last real XHR handler finish its job and try to obtain
|
|
// any additional requests if they were initiated by this handler
|
|
delay(this._delays.additionalRequestsCollection)
|
|
.then(function () { return _this._onRequestFinished(req); });
|
|
};
|
|
RequestBarrier.prototype._onRequestFinished = function (req) {
|
|
if (!this._requests.has(req))
|
|
return;
|
|
this._requests.delete(req);
|
|
if (!this._collectingReqs && !this._requests.size && this._watchdog)
|
|
this._finishWaiting();
|
|
};
|
|
RequestBarrier.prototype._onRequestError = function (req) {
|
|
this._onRequestFinished(req);
|
|
};
|
|
RequestBarrier.prototype._finishWaiting = function () {
|
|
if (this._watchdog) {
|
|
var clearTimeout_1 = hammerhead.nativeMethods.clearTimeout;
|
|
clearTimeout_1(this._watchdog);
|
|
this._watchdog = null;
|
|
}
|
|
this._requests.clear();
|
|
this._offListening();
|
|
this._waitResolve(); // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
|
};
|
|
RequestBarrier.prototype.wait = function (isPageLoad) {
|
|
var _this = this;
|
|
return delay(isPageLoad ? this._delays.pageInitialRequestsCollection : this._delays.requestsCollection)
|
|
.then(function () { return new hammerhead.Promise(function (resolve) {
|
|
_this._collectingReqs = false;
|
|
_this._waitResolve = resolve;
|
|
if (!_this._requests.size) {
|
|
_this._finishWaiting();
|
|
return;
|
|
}
|
|
var setTimeout = hammerhead.nativeMethods.setTimeout;
|
|
_this._watchdog = setTimeout(function () { return _this._finishWaiting(); }, RequestBarrier.TIMEOUT);
|
|
}); });
|
|
};
|
|
RequestBarrier.TIMEOUT = 3000;
|
|
return RequestBarrier;
|
|
}());
|
|
|
|
var WAIT_FOR_NEW_SCRIPTS_DELAY = 25;
|
|
var ScriptExecutionBarrier = /** @class */ (function () {
|
|
function ScriptExecutionBarrier(emitter) {
|
|
this._emitter = emitter;
|
|
this._watchdog = null;
|
|
this._waitResolve = null;
|
|
this._scripts = new Map();
|
|
this._startListening();
|
|
}
|
|
ScriptExecutionBarrier.prototype._startListening = function () {
|
|
var _this = this;
|
|
this._emitter.onScriptAdded(function (script) { return _this._onScriptElementAdded(script); });
|
|
this._emitter.onScriptLoadedOrFailed(function (script) { return _this._onScriptLoadedOrFailed(script); });
|
|
};
|
|
ScriptExecutionBarrier.prototype._offListening = function () {
|
|
this._emitter.offAll();
|
|
};
|
|
ScriptExecutionBarrier.prototype._onScriptElementAdded = function (script) {
|
|
var _this = this;
|
|
var setTimeout = hammerhead.nativeMethods.setTimeout;
|
|
var timeoutFn = function () { return _this._onScriptLoadedOrFailed(script, true); };
|
|
var loadingTimeout = setTimeout(timeoutFn, ScriptExecutionBarrier.LOADING_TIMEOUT);
|
|
this._scripts.set(script, loadingTimeout);
|
|
};
|
|
ScriptExecutionBarrier.prototype._onScriptLoadedOrFailed = function (script, isTimeout) {
|
|
var _this = this;
|
|
if (isTimeout === void 0) { isTimeout = false; }
|
|
if (!this._scripts.has(script))
|
|
return;
|
|
if (!isTimeout) {
|
|
var clearTimeout_1 = hammerhead.nativeMethods.clearTimeout;
|
|
clearTimeout_1(this._scripts.get(script));
|
|
}
|
|
this._scripts.delete(script);
|
|
if (this._scripts.size)
|
|
return;
|
|
delay(WAIT_FOR_NEW_SCRIPTS_DELAY)
|
|
.then(function () {
|
|
if (_this._waitResolve && !_this._scripts.size)
|
|
_this._finishWaiting();
|
|
});
|
|
};
|
|
ScriptExecutionBarrier.prototype._finishWaiting = function () {
|
|
if (this._watchdog) {
|
|
var clearTimeout_2 = hammerhead.nativeMethods.clearTimeout;
|
|
clearTimeout_2(this._watchdog);
|
|
this._watchdog = null;
|
|
}
|
|
this._scripts.clear();
|
|
this._offListening();
|
|
this._waitResolve(); // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
|
this._waitResolve = null;
|
|
};
|
|
ScriptExecutionBarrier.prototype.wait = function () {
|
|
var _this = this;
|
|
return new hammerhead.Promise(function (resolve) {
|
|
_this._waitResolve = resolve;
|
|
if (!_this._scripts.size) {
|
|
_this._finishWaiting();
|
|
return;
|
|
}
|
|
var setTimeout = hammerhead.nativeMethods.setTimeout;
|
|
_this._watchdog = setTimeout(function () { return _this._finishWaiting(); }, ScriptExecutionBarrier.TIMEOUT);
|
|
});
|
|
};
|
|
ScriptExecutionBarrier.TIMEOUT = 3000;
|
|
ScriptExecutionBarrier.LOADING_TIMEOUT = 2000;
|
|
return ScriptExecutionBarrier;
|
|
}());
|
|
|
|
var BarriersComplex = /** @class */ (function () {
|
|
function BarriersComplex(reqEmitter, scriptEmitter, unloadBarrier) {
|
|
this._requestBarrier = new RequestBarrier(reqEmitter);
|
|
this._scriptExecutionBarrier = new ScriptExecutionBarrier(scriptEmitter);
|
|
this._unloadBarrier = unloadBarrier;
|
|
if (unloadBarrier.watchForPageNavigationTriggers)
|
|
unloadBarrier.watchForPageNavigationTriggers();
|
|
}
|
|
BarriersComplex.prototype.wait = function () {
|
|
var _this = this;
|
|
return hammerhead.Promise.all([
|
|
// NOTE: script can be added by xhr-request, so we should run
|
|
// script execution barrier waiting after request barrier resolved
|
|
this._requestBarrier.wait()
|
|
.then(function () { return _this._scriptExecutionBarrier.wait(); }),
|
|
this._unloadBarrier.wait(),
|
|
]).then();
|
|
};
|
|
return BarriersComplex;
|
|
}());
|
|
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.dispatchEvent] = {
|
|
additionalSelectorProps: ['relatedTarget'],
|
|
create: function (command, elements) {
|
|
if (elements[1]) // @ts-ignore
|
|
command.options.relatedTarget = elements[1];
|
|
return new testcafeAutomation.DispatchEvent(elements[0], command.eventName, command.options);
|
|
},
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.pressKey] = {
|
|
create: function (command) { return new testcafeAutomation.Press(testcafeCore.parseKeySequence(command.keys).combinations, command.options); },
|
|
ensureCmdArgs: function (command) {
|
|
var parsedKeySequence = testcafeCore.parseKeySequence(command.keys);
|
|
if (parsedKeySequence.error)
|
|
throw new ActionIncorrectKeysError('keys');
|
|
},
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.click] = {
|
|
create: function (command, elements, dispatchProxylessEventFn, leftTopPoint) {
|
|
if (/option|optgroup/.test(testcafeCore.domUtils.getTagName(elements[0])))
|
|
return new testcafeAutomation.SelectChildClick(elements[0], command.options);
|
|
testcafeAutomation.cursor.shouldRender = !dispatchProxylessEventFn;
|
|
return new testcafeAutomation.Click(elements[0], command.options, window, testcafeAutomation.cursor, dispatchProxylessEventFn, leftTopPoint);
|
|
},
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.rightClick] = {
|
|
create: function (command, elements) { return new testcafeAutomation.RClick(elements[0], command.options); },
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.doubleClick] = {
|
|
create: function (command, elements) { return new testcafeAutomation.DblClick(elements[0], command.options); },
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.hover] = {
|
|
create: function (command, elements) { return new testcafeAutomation.Hover(elements[0], command.options); },
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.drag] = {
|
|
create: function (command, elements) {
|
|
return new testcafeAutomation.DragToOffset(elements[0], command.dragOffsetX, command.dragOffsetY, command.options);
|
|
},
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.dragToElement] = {
|
|
additionalSelectorProps: ['destinationSelector'],
|
|
create: function (command, elements) {
|
|
return new testcafeAutomation.DragToElement(elements[0], elements[1], command.options);
|
|
},
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.scroll] = {
|
|
create: function (command, elements) {
|
|
var x = command.x, y = command.y, position = command.position, options = command.options;
|
|
return new testcafeAutomation.SetScroll(elements[0], { x: x, y: y, position: position }, options);
|
|
},
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.scrollBy] = {
|
|
create: function (command, elements) {
|
|
var byX = command.byX, byY = command.byY, options = command.options;
|
|
return new testcafeAutomation.SetScroll(elements[0], { byX: byX, byY: byY }, options);
|
|
},
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.scrollIntoView] = {
|
|
create: function (command, elements) { return new testcafeAutomation.ScrollIntoView(elements[0], command.options); },
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.typeText] = {
|
|
// eslint-disable-next-line no-restricted-properties
|
|
create: function (command, elements) { return new testcafeAutomation.Type(elements[0], command.text, command.options); },
|
|
};
|
|
function createSelectTextAutomation(command, elements) {
|
|
var selectArgs = testcafeAutomation.calculateSelectTextArguments(elements[0], command);
|
|
return new testcafeAutomation.SelectText(elements[0], selectArgs.startPos, selectArgs.endPos, command.options);
|
|
}
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.selectText] = {
|
|
create: createSelectTextAutomation,
|
|
ensureElsProps: function (elements) {
|
|
if (!testcafeCore.domUtils.isEditableElement(elements[0]))
|
|
throw new ActionElementNonEditableError();
|
|
},
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.selectTextAreaContent] = {
|
|
create: createSelectTextAutomation,
|
|
ensureElsProps: function (elements) {
|
|
if (!testcafeCore.domUtils.isTextAreaElement(elements[0]))
|
|
throw new ActionElementNotTextAreaError();
|
|
},
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.selectEditableContent] = {
|
|
additionalSelectorProps: ['startSelector', 'endSelector'],
|
|
create: function (command, elements) {
|
|
command.endSelector = command.endSelector || command.startSelector;
|
|
return new testcafeAutomation.SelectEditableContent(elements[0], elements[1], command.options);
|
|
},
|
|
ensureElsProps: function (elements) {
|
|
if (!testcafeCore.domUtils.isContentEditableElement(elements[0]))
|
|
throw new ActionElementNonContentEditableError('startSelector');
|
|
if (!testcafeCore.domUtils.isContentEditableElement(elements[1]))
|
|
throw new ActionElementNonContentEditableError('endSelector');
|
|
// NOTE: We should find a common element for the nodes to perform the select action
|
|
if (!testcafeCore.contentEditable.getNearestCommonAncestor(elements[0], elements[1]))
|
|
throw new ActionRootContainerNotFoundError();
|
|
},
|
|
};
|
|
function ensureFileInput(element) {
|
|
if (!testcafeCore.domUtils.isFileInput(element))
|
|
throw new ActionElementIsNotFileInputError();
|
|
}
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.setFilesToUpload] = {
|
|
create: function (command, elements) {
|
|
return new testcafeAutomation.Upload(elements[0], command.filePath, function (filePaths, scannedFilePaths) { return new ActionCannotFindFileToUploadError(filePaths, scannedFilePaths); });
|
|
},
|
|
ensureElsProps: function (elements) { return ensureFileInput(elements[0]); },
|
|
};
|
|
ActionExecutor.ACTIONS_HANDLERS[COMMAND_TYPE.clearUpload] = {
|
|
create: function (command, elements) { return new testcafeAutomation.Upload(elements[0]); },
|
|
ensureElsProps: function (elements) { return ensureFileInput(elements[0]); },
|
|
};
|
|
|
|
function shouldSkipJsError(options, err) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
if (!isClientFunctionCommand(options)) return [3 /*break*/, 2];
|
|
return [4 /*yield*/, processJsErrorsFunction(options, err)];
|
|
case 1: return [2 /*return*/, _a.sent()];
|
|
case 2: return [2 /*return*/, options || false];
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function processJsErrorsFunction(processingFunction, err) {
|
|
var opts = {
|
|
stack: err.stack,
|
|
pageUrl: err.pageUrl,
|
|
message: err.msg,
|
|
};
|
|
processingFunction.args = [[opts]];
|
|
var executor = new ClientFunctionExecutor(processingFunction);
|
|
return executor.getResult();
|
|
}
|
|
|
|
var settings = hammerhead__default.settings;
|
|
var transport = hammerhead__default.transport;
|
|
var Promise$2 = hammerhead__default.Promise;
|
|
var messageSandbox$2 = hammerhead__default.eventSandbox.message;
|
|
var storages = hammerhead__default.storages;
|
|
var nativeMethods$6 = hammerhead__default.nativeMethods;
|
|
var DateCtor$1 = nativeMethods$6.date;
|
|
var listeners = hammerhead__default.eventSandbox.listeners;
|
|
var urlUtils = hammerhead__default.utils.url;
|
|
var TEST_DONE_SENT_FLAG = 'testcafe|driver|test-done-sent-flag';
|
|
var PENDING_STATUS = 'testcafe|driver|pending-status';
|
|
var EXECUTING_CLIENT_FUNCTION_DESCRIPTOR = 'testcafe|driver|executing-client-function-descriptor';
|
|
var EXECUTING_SKIP_JS_ERRORS_FUNCTION_FLAG = 'testcafe|driver|executing-skip-js-errors-function-flag';
|
|
var SELECTOR_EXECUTION_START_TIME = 'testcafe|driver|selector-execution-start-time';
|
|
var PENDING_PAGE_ERROR = 'testcafe|driver|pending-page-error';
|
|
var ACTIVE_IFRAME_SELECTOR = 'testcafe|driver|active-iframe-selector';
|
|
var TEST_SPEED = 'testcafe|driver|test-speed';
|
|
var ASSERTION_RETRIES_TIMEOUT = 'testcafe|driver|assertion-retries-timeout';
|
|
var ASSERTION_RETRIES_START_TIME = 'testcafe|driver|assertion-retries-start-time';
|
|
var CONSOLE_MESSAGES = 'testcafe|driver|console-messages';
|
|
var PENDING_CHILD_WINDOW_COUNT = 'testcafe|driver|pending-child-window-count';
|
|
var ACTION_IFRAME_ERROR_CTORS = {
|
|
NotLoadedError: ActionIframeIsNotLoadedError,
|
|
NotFoundError: ActionElementNotFoundError,
|
|
IsInvisibleError: ActionElementIsInvisibleError,
|
|
};
|
|
var CURRENT_IFRAME_ERROR_CTORS = {
|
|
NotLoadedError: CurrentIframeIsNotLoadedError,
|
|
NotFoundError: CurrentIframeNotFoundError,
|
|
IsInvisibleError: CurrentIframeIsInvisibleError,
|
|
};
|
|
var COMMAND_EXECUTION_MAX_TIMEOUT = Math.pow(2, 31) - 1;
|
|
var EMPTY_COMMAND_EVENT_WAIT_TIMEOUT = 30 * 1000;
|
|
var CHILD_WINDOW_CLOSED_EVENT_TIMEOUT = 2000;
|
|
var RESTORE_CHILD_WINDOWS_TIMEOUT = 30 * 1000;
|
|
var STATUS_WITH_COMMAND_RESULT_EVENT = 'status-with-command-result-event';
|
|
var EMPTY_COMMAND_EVENT = 'empty-command-event';
|
|
var CHILD_WINDOW_CLOSED_EVENT = 'child-window-closed';
|
|
var SKIP_JS_ERRORS_FUNCTION_EXECUTION_COMPLETE_EVENT = 'skip-js-errors-function-execution-complete';
|
|
var Driver = /** @class */ (function (_super) {
|
|
__extends(Driver, _super);
|
|
function Driver(testRunId, communicationUrls, runInfo, options) {
|
|
var _this = _super.call(this) || this;
|
|
_this.COMMAND_EXECUTING_FLAG = 'testcafe|driver|command-executing-flag';
|
|
_this.EXECUTING_IN_IFRAME_FLAG = 'testcafe|driver|executing-in-iframe-flag';
|
|
_this.PENDING_WINDOW_SWITCHING_FLAG = 'testcafe|driver|pending-window-switching-flag';
|
|
_this.WINDOW_COMMAND_API_CALL_FLAG = 'testcafe|driver|window-command-api-flag';
|
|
_this.testRunId = testRunId;
|
|
_this.communicationUrls = communicationUrls;
|
|
_this.runInfo = runInfo;
|
|
_this.options = options;
|
|
_this.isFirstPageLoad = settings.get().isFirstPageLoad;
|
|
_this.customCommandHandlers = {};
|
|
_this.contextStorage = null;
|
|
_this.nativeDialogsTracker = null;
|
|
_this.childIframeDriverLinks = [];
|
|
_this.activeChildIframeDriverLink = null;
|
|
_this.childWindowDriverLinks = [];
|
|
_this.parentWindowDriverLink = null;
|
|
_this.statusBar = null;
|
|
_this.windowId = _this._getCurrentWindowId();
|
|
_this.role = DriverRole.replica;
|
|
_this.setAsMasterInProgress = false;
|
|
_this.checkClosedChildWindowIntervalId = null;
|
|
var requestEmitter = new testcafeCore.ClientRequestEmitter();
|
|
_this.pageInitialRequestBarrier = new testcafeCore.RequestBarrier(requestEmitter);
|
|
_this.readyPromise = _this._getReadyPromise();
|
|
_this._initChildDriverListening();
|
|
testcafeCore.pageUnloadBarrier.init();
|
|
if (!_this.options.proxyless)
|
|
testcafeCore.preventRealEvents();
|
|
hammerhead__default.on(hammerhead__default.EVENTS.uncaughtJsError, function (err) { return _this._onJsError(err); });
|
|
hammerhead__default.on(hammerhead__default.EVENTS.unhandledRejection, function (err) { return _this._onJsError(err); });
|
|
hammerhead__default.on(hammerhead__default.EVENTS.consoleMethCalled, function (e) { return _this._onConsoleMessage(e); });
|
|
hammerhead__default.on(hammerhead__default.EVENTS.beforeFormSubmit, function (e) { return _this._onFormSubmit(e); });
|
|
hammerhead__default.on(hammerhead__default.EVENTS.windowOpened, function (e) { return _this._onChildWindowOpened(e); });
|
|
_this.setCustomCommandHandlers(COMMAND_TYPE.unlockPage, function () { return _this._unlockPageAfterTestIsDone(); });
|
|
_this.setCustomCommandHandlers(COMMAND_TYPE.getActiveElement, function () { return _this._getActiveElement(); });
|
|
// NOTE: initiate the child links restoring process before the window is reloaded
|
|
listeners.addInternalEventBeforeListener(window, ['beforeunload'], function () {
|
|
_this._sendStartToRestoreCommand();
|
|
});
|
|
_this.replicator = createReplicator([new SelectorNodeTransform()]);
|
|
return _this;
|
|
}
|
|
Driver.prototype._isOpenedInIframe = function () {
|
|
var opener = window.opener;
|
|
return opener && opener.top && opener.top !== opener;
|
|
};
|
|
Object.defineProperty(Driver.prototype, "speed", {
|
|
get: function () {
|
|
return this.contextStorage.getItem(TEST_SPEED);
|
|
},
|
|
set: function (val) {
|
|
this.contextStorage.setItem(TEST_SPEED, val);
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(Driver.prototype, "consoleMessages", {
|
|
get: function () {
|
|
return new ClientBrowserConsoleMessages(this.contextStorage.getItem(CONSOLE_MESSAGES));
|
|
},
|
|
set: function (messages) {
|
|
return this.contextStorage.setItem(CONSOLE_MESSAGES, messages ? messages.getCopy() : null);
|
|
},
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
Driver.prototype._getReadyPromise = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0: return [4 /*yield*/, testcafeCore.eventUtils.documentReady(this.options.pageLoadTimeout)];
|
|
case 1:
|
|
_a.sent();
|
|
return [4 /*yield*/, this.pageInitialRequestBarrier.wait(true)];
|
|
case 2:
|
|
_a.sent();
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._hasPendingActionFlags = function (contextStorage) {
|
|
return contextStorage.getItem(this.COMMAND_EXECUTING_FLAG) ||
|
|
contextStorage.getItem(this.EXECUTING_IN_IFRAME_FLAG);
|
|
};
|
|
Driver.prototype._getCurrentWindowId = function () {
|
|
if (this.options.proxyless)
|
|
return this.runInfo.activeWindowId;
|
|
var currentUrl = window.location.toString();
|
|
var parsedProxyUrl = hammerhead__default.utils.url.parseProxyUrl(currentUrl);
|
|
return parsedProxyUrl && parsedProxyUrl.windowId || null;
|
|
};
|
|
// Error handling
|
|
Driver.prototype._onJsError = function (err) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var e_1;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
// NOTE: we should not send any message to the server if we've
|
|
// sent the 'test-done' message but haven't got the response.
|
|
if (this.contextStorage.getItem(TEST_DONE_SENT_FLAG))
|
|
return [2 /*return*/];
|
|
if (!this.options.skipJsErrors) return [3 /*break*/, 6];
|
|
this.contextStorage.setItem(EXECUTING_SKIP_JS_ERRORS_FUNCTION_FLAG, true);
|
|
_a.label = 1;
|
|
case 1:
|
|
_a.trys.push([1, 3, 4, 5]);
|
|
return [4 /*yield*/, shouldSkipJsError(this.options.skipJsErrors, err)];
|
|
case 2:
|
|
if (!(_a.sent()))
|
|
this._setUncaughtErrorOnPage(err);
|
|
return [3 /*break*/, 5];
|
|
case 3:
|
|
e_1 = _a.sent();
|
|
if (!this.contextStorage.getItem(PENDING_PAGE_ERROR))
|
|
this.contextStorage.setItem(PENDING_PAGE_ERROR, e_1);
|
|
return [3 /*break*/, 5];
|
|
case 4:
|
|
this.contextStorage.setItem(EXECUTING_SKIP_JS_ERRORS_FUNCTION_FLAG, false);
|
|
this.emit(SKIP_JS_ERRORS_FUNCTION_EXECUTION_COMPLETE_EVENT);
|
|
return [7 /*endfinally*/];
|
|
case 5: return [2 /*return*/];
|
|
case 6:
|
|
this._setUncaughtErrorOnPage(err);
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._setUncaughtErrorOnPage = function (err) {
|
|
var error = new UncaughtErrorOnPage(err.stack, err.pageUrl);
|
|
if (!this.contextStorage.getItem(PENDING_PAGE_ERROR))
|
|
this.contextStorage.setItem(PENDING_PAGE_ERROR, error);
|
|
};
|
|
Driver.prototype._unlockPageAfterTestIsDone = function () {
|
|
if (!this.options.proxyless)
|
|
testcafeCore.disableRealEventsPreventing();
|
|
return Promise$2.resolve();
|
|
};
|
|
Driver.prototype._getActiveElement = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var activeElement;
|
|
return __generator(this, function (_a) {
|
|
activeElement = testcafeCore.domUtils.getActiveElement();
|
|
return [2 /*return*/, this.replicator.encode(activeElement)];
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._failIfClientCodeExecutionIsInterrupted = function () {
|
|
// NOTE: ClientFunction should be used primarily for observation. We raise
|
|
// an error if the page was reloaded during ClientFunction execution.
|
|
var executingClientFnDescriptor = this.contextStorage.getItem(EXECUTING_CLIENT_FUNCTION_DESCRIPTOR);
|
|
if (executingClientFnDescriptor) {
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: new ClientFunctionExecutionInterruptionError(executingClientFnDescriptor.instantiationCallsiteName),
|
|
}));
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
Driver.prototype.onCustomClientScriptError = function (err, moduleName) {
|
|
var error = moduleName
|
|
? new UncaughtErrorInCustomClientScriptLoadedFromModule(err, moduleName)
|
|
: new UncaughtErrorInCustomClientScriptCode(err);
|
|
if (!this.contextStorage.getItem(PENDING_PAGE_ERROR))
|
|
this.contextStorage.setItem(PENDING_PAGE_ERROR, error);
|
|
};
|
|
Driver.prototype._addChildWindowDriverLink = function (e) {
|
|
var childWindowDriverLink = new ChildWindowDriverLink(e.window, e.windowId);
|
|
this.childWindowDriverLinks.push(childWindowDriverLink);
|
|
this._ensureClosedChildWindowWatcher();
|
|
};
|
|
Driver.prototype._ensureClosedChildWindowWatcher = function () {
|
|
var _this = this;
|
|
if (this.checkClosedChildWindowIntervalId)
|
|
return;
|
|
this.checkClosedChildWindowIntervalId = nativeMethods$6.setInterval.call(window, function () {
|
|
var firstClosedChildWindowDriverLink = testcafeCore.arrayUtils.find(_this.childWindowDriverLinks, function (childWindowDriverLink) { return childWindowDriverLink.driverWindow.closed; });
|
|
if (!firstClosedChildWindowDriverLink)
|
|
return;
|
|
_this.emit(CHILD_WINDOW_CLOSED_EVENT);
|
|
testcafeCore.arrayUtils.remove(_this.childWindowDriverLinks, firstClosedChildWindowDriverLink);
|
|
if (!firstClosedChildWindowDriverLink.ignoreMasterSwitching)
|
|
_this._setCurrentWindowAsMaster();
|
|
if (!_this.childWindowDriverLinks.length) {
|
|
nativeMethods$6.clearInterval.call(window, _this.checkClosedChildWindowIntervalId);
|
|
delete _this.checkClosedChildWindowIntervalId;
|
|
}
|
|
}, CHECK_CHILD_WINDOW_CLOSED_INTERVAL);
|
|
};
|
|
Driver.prototype._setAsMasterInProgressOrCompleted = function () {
|
|
return this.setAsMasterInProgress || this.role === DriverRole.master;
|
|
};
|
|
Driver.prototype._setCurrentWindowAsMaster = function () {
|
|
var _this = this;
|
|
if (this._setAsMasterInProgressOrCompleted())
|
|
return;
|
|
this.setAsMasterInProgress = true;
|
|
this._clearActiveChildIframeInfo();
|
|
Promise$2.resolve()
|
|
.then(function () {
|
|
return testcafeCore.browser.setActiveWindowId(_this.communicationUrls.activeWindowId, hammerhead__default.createNativeXHR, _this.windowId);
|
|
})
|
|
.then(function () {
|
|
_this._startInternal({
|
|
finalizePendingCommand: true,
|
|
isFirstRequestAfterWindowSwitching: true,
|
|
});
|
|
_this.setAsMasterInProgress = false;
|
|
})
|
|
.catch(function () {
|
|
_this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: new CannotSwitchToWindowError(),
|
|
}));
|
|
});
|
|
};
|
|
Driver.prototype._onChildWindowOpened = function (e) {
|
|
this._addChildWindowDriverLink(e);
|
|
this._switchToChildWindow(e.windowId);
|
|
};
|
|
Driver.prototype._sendStartToRestoreCommand = function () {
|
|
if (!this.contextStorage)
|
|
return;
|
|
// NOTE: the situation is possible when the child window responds before the parent window is reloaded,
|
|
// so we should not respond to the child window if the parent window is not reloaded
|
|
this._stopRespondToChildren = true;
|
|
// NOTE: save the child window count that we expect to restore after the parent window is reloaded
|
|
this.contextStorage.setItem(PENDING_CHILD_WINDOW_COUNT, this.childWindowDriverLinks.length);
|
|
for (var _i = 0, _a = this.childWindowDriverLinks; _i < _a.length; _i++) {
|
|
var childLink = _a[_i];
|
|
childLink.startToRestore();
|
|
}
|
|
};
|
|
// HACK: For https://github.com/DevExpress/testcafe/issues/3560
|
|
// We have to cancel every form submit after a test is done
|
|
// to prevent requests to a closed session
|
|
Driver.prototype._onFormSubmit = function (e) {
|
|
// NOTE: We need to refactor this code to avoid the undefined value in contextStorage
|
|
// https://github.com/DevExpress/testcafe/issues/4360
|
|
if (this.contextStorage && this.contextStorage.getItem(TEST_DONE_SENT_FLAG))
|
|
e.preventSubmit = true;
|
|
};
|
|
// Console messages
|
|
Driver.prototype._onConsoleMessage = function (_a) {
|
|
var meth = _a.meth, line = _a.line;
|
|
var messages = this.consoleMessages;
|
|
messages.addMessage(meth, line, this.windowId);
|
|
this.consoleMessages = messages;
|
|
};
|
|
// Status
|
|
Driver.prototype._addPendingErrorToStatus = function (status) {
|
|
var pendingPageError = this.contextStorage.getItem(PENDING_PAGE_ERROR);
|
|
if (pendingPageError) {
|
|
this.contextStorage.setItem(PENDING_PAGE_ERROR, null);
|
|
status.pageError = pendingPageError;
|
|
}
|
|
};
|
|
Driver.prototype._addUnexpectedDialogErrorToStatus = function (status) {
|
|
var dialogError = this.nativeDialogsTracker.getUnexpectedDialogError();
|
|
status.pageError = status.pageError || dialogError;
|
|
};
|
|
Driver.prototype._addConsoleMessagesToStatus = function (status) {
|
|
status.consoleMessages = this.consoleMessages;
|
|
this.consoleMessages = null;
|
|
};
|
|
Driver.prototype._addPendingWindowSwitchingStateToStatus = function (status) {
|
|
status.isPendingWindowSwitching = this._isPendingSwitchingWindow();
|
|
};
|
|
Driver.prototype._sendStatusRequest = function (status) {
|
|
var statusRequestOptions = {
|
|
cmd: TEST_RUN_MESSAGES.ready,
|
|
status: status,
|
|
disableResending: true,
|
|
allowRejecting: true,
|
|
};
|
|
var requestAttempt = function () { return testcafeCore.getTimeLimitedPromise(transport.asyncServiceMsg(statusRequestOptions), SEND_STATUS_REQUEST_TIME_LIMIT); };
|
|
var retryRequest = function () { return testcafeCore.delay(SEND_STATUS_REQUEST_RETRY_DELAY).then(requestAttempt); };
|
|
var statusPromise = requestAttempt();
|
|
for (var i = 0; i < SEND_STATUS_REQUEST_RETRY_COUNT; i++)
|
|
statusPromise = statusPromise.catch(retryRequest);
|
|
return statusPromise;
|
|
};
|
|
Driver.prototype._sendStatus = function (status) {
|
|
var _this = this;
|
|
// NOTE: We should not modify the status if it is resent after
|
|
// the page load because the server has cached the response
|
|
if (!status.resent) {
|
|
this._addPendingErrorToStatus(status);
|
|
this._addUnexpectedDialogErrorToStatus(status);
|
|
this._addConsoleMessagesToStatus(status);
|
|
this._addPendingWindowSwitchingStateToStatus(status);
|
|
}
|
|
this.contextStorage.setItem(PENDING_STATUS, status);
|
|
var readyCommandResponse = null;
|
|
// NOTE: postpone status sending if the page is unloading
|
|
return testcafeCore.pageUnloadBarrier
|
|
.wait(0)
|
|
.then(function () { return _this._sendStatusRequest(status); })
|
|
//NOTE: do not execute the next command if the page is unloading
|
|
.then(function (res) {
|
|
readyCommandResponse = res;
|
|
return testcafeCore.pageUnloadBarrier.wait(0);
|
|
})
|
|
.then(function () {
|
|
_this.contextStorage.setItem(PENDING_STATUS, null);
|
|
return readyCommandResponse;
|
|
});
|
|
};
|
|
// Iframes and child windows interaction
|
|
Driver.prototype._addChildIframeDriverLink = function (id, driverWindow) {
|
|
var childIframeDriverLink = this._getChildIframeDriverLinkByWindow(driverWindow);
|
|
if (!childIframeDriverLink) {
|
|
var driverId = "".concat(this.testRunId, "-").concat(generateId());
|
|
childIframeDriverLink = new ChildIframeDriverLink(driverWindow, driverId, this.communicationUrls.dispatchProxylessEvent);
|
|
this.childIframeDriverLinks.push(childIframeDriverLink);
|
|
}
|
|
childIframeDriverLink.sendConfirmationMessage(id);
|
|
};
|
|
Driver.prototype._getTargetWindowNotFoundResult = function (errCode, errMsg) {
|
|
return Promise$2.resolve({
|
|
success: false,
|
|
errCode: errCode,
|
|
errMsg: errMsg,
|
|
});
|
|
};
|
|
Driver.prototype._getChildWindowValidateResult = function (arr) {
|
|
var success = arr.find(function (item) { return item.result.success; });
|
|
if (success)
|
|
return success.result;
|
|
var errItem = arr.find(function (item) {
|
|
return item.result.errCode === testcafeCore.TEST_RUN_ERRORS.cannotCloseWindowWithChildrenError ||
|
|
item.result.errCode === testcafeCore.TEST_RUN_ERRORS.cannotCloseWindowWithoutParent;
|
|
});
|
|
if (!errItem)
|
|
errItem = arr.find(function (item) { return !!item.result.errCode; });
|
|
return errItem ? { errCode: errItem.result.errCode } : void 0;
|
|
};
|
|
Driver.prototype._handleWindowValidation = function (msg, wnd, getWindowFoundResult, WindowValidationMessageCtor) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var result;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0: return [4 /*yield*/, this._validateWindow(msg, wnd, getWindowFoundResult, WindowValidationMessageCtor)];
|
|
case 1:
|
|
result = _a.sent();
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: wnd,
|
|
result: result,
|
|
});
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._getWindowInfo = function () {
|
|
var parsedUrl = hammerhead__default.utils.url.parseProxyUrl(window.location.toString());
|
|
return {
|
|
id: this.windowId,
|
|
title: document.title,
|
|
url: parsedUrl.destUrl,
|
|
};
|
|
};
|
|
Driver.prototype._isTargetWindow = function (msg) {
|
|
return msg.windowId === this.windowId;
|
|
};
|
|
Driver.prototype._validateWindow = function (msg, wnd, getWindowFoundResult, WindowValidationMessageCtor) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var windowExists, searchQueries, searchResults;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
windowExists = this._isTargetWindow(msg);
|
|
if (windowExists)
|
|
return [2 /*return*/, getWindowFoundResult()];
|
|
if (!this.childWindowDriverLinks.length)
|
|
return [2 /*return*/, this._getTargetWindowNotFoundResult(testcafeCore.TEST_RUN_ERRORS.targetWindowNotFoundError)];
|
|
searchQueries = this.childWindowDriverLinks.map(function (childWindowDriverLink) {
|
|
return childWindowDriverLink.findChildWindows(msg, WindowValidationMessageCtor);
|
|
});
|
|
return [4 /*yield*/, Promise$2.all(searchQueries)];
|
|
case 1:
|
|
searchResults = _a.sent();
|
|
return [2 /*return*/, this._getChildWindowValidateResult(searchResults)];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver._createWindowValidationError = function (_a) {
|
|
var errCode = _a.errCode;
|
|
if (errCode === testcafeCore.TEST_RUN_ERRORS.cannotCloseWindowWithChildrenError)
|
|
return new CannotCloseWindowWithChildrenError();
|
|
if (errCode === testcafeCore.TEST_RUN_ERRORS.cannotCloseWindowWithoutParent)
|
|
return new CannotCloseWindowWithoutParentError();
|
|
return new WindowNotFoundError();
|
|
};
|
|
Driver.prototype._getCloseWindowFoundResult = function () {
|
|
if (!this.parentWindowDriverLink) {
|
|
return Promise$2.resolve({
|
|
success: false,
|
|
errCode: testcafeCore.TEST_RUN_ERRORS.cannotCloseWindowWithoutParent,
|
|
});
|
|
}
|
|
if (this.childWindowDriverLinks.length) {
|
|
return Promise$2.resolve({
|
|
success: false,
|
|
errCode: testcafeCore.TEST_RUN_ERRORS.cannotCloseWindowWithChildrenError,
|
|
});
|
|
}
|
|
return Promise$2.resolve({ success: true });
|
|
};
|
|
Driver.prototype._handleCloseWindowValidation = function (msg, wnd) {
|
|
var _this = this;
|
|
var getWindowFoundResult = function () {
|
|
return _this._getCloseWindowFoundResult();
|
|
};
|
|
return this._handleWindowValidation(msg, wnd, getWindowFoundResult, CloseWindowValidationMessage);
|
|
};
|
|
Driver.prototype._handleSwitchToWindowValidation = function (msg, wnd) {
|
|
var getWindowFoundResult = function () {
|
|
return Promise$2.resolve({ success: true });
|
|
};
|
|
return this._handleWindowValidation(msg, wnd, getWindowFoundResult, SwitchToWindowValidationMessage);
|
|
};
|
|
Driver.prototype._handleCloseWindow = function (msg, wnd) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0: return [4 /*yield*/, this._closeWindow(msg, wnd)];
|
|
case 1:
|
|
_a.sent();
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: wnd,
|
|
});
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._closeWindowAndWait = function (childWindowToClose, msg) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var waitWindowForClose;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
waitWindowForClose = this._createWaitForEventPromise(CHILD_WINDOW_CLOSED_EVENT, CHILD_WINDOW_CLOSED_EVENT_TIMEOUT);
|
|
childWindowToClose.ignoreMasterSwitching = !msg.isCurrentWindow;
|
|
if (!!this.closing) return [3 /*break*/, 2];
|
|
this.closing = true;
|
|
return [4 /*yield*/, testcafeCore.browser.closeWindow(this.communicationUrls.closeWindow, hammerhead__default.createNativeXHR, this.windowId)];
|
|
case 1:
|
|
_a.sent();
|
|
_a.label = 2;
|
|
case 2:
|
|
childWindowToClose.driverWindow.close();
|
|
return [2 /*return*/, waitWindowForClose];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._closeWindow = function (msg) {
|
|
if (!this.childWindowDriverLinks.length)
|
|
return Promise$2.resolve();
|
|
var childWindowToClose = this.childWindowDriverLinks.find(function (link) { return link.windowId === msg.windowId; });
|
|
if (childWindowToClose)
|
|
return this._closeWindowAndWait(childWindowToClose, msg);
|
|
var searchQueries = this.childWindowDriverLinks.map(function (childWindowDriverLink) {
|
|
return childWindowDriverLink.findChildWindows(msg, CloseWindowCommandMessage);
|
|
});
|
|
return Promise$2.all(searchQueries);
|
|
};
|
|
Driver.prototype._getWindows = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var searchQueries, searchResults, result, _i, searchResults_1, item;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
if (!this.childWindowDriverLinks.length)
|
|
return [2 /*return*/, [this._getWindowInfo()]];
|
|
searchQueries = this.childWindowDriverLinks.map(function (childWindowDriverLink) {
|
|
return childWindowDriverLink.findChildWindows({}, GetWindowsMessage);
|
|
});
|
|
return [4 /*yield*/, Promise$2.all(searchQueries)];
|
|
case 1:
|
|
searchResults = _a.sent();
|
|
result = [this._getWindowInfo()];
|
|
for (_i = 0, searchResults_1 = searchResults; _i < searchResults_1.length; _i++) {
|
|
item = searchResults_1[_i];
|
|
if (Array.isArray(item.result))
|
|
result = result.concat(item.result);
|
|
}
|
|
return [2 /*return*/, result];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._handleGetWindows = function (msg, wnd) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var result;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0: return [4 /*yield*/, this._getWindows(msg, wnd)];
|
|
case 1:
|
|
result = _a.sent();
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: wnd,
|
|
result: result,
|
|
});
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._handleSwitchToWindow = function (msg, wnd) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0: return [4 /*yield*/, this._switchToWindow(msg)];
|
|
case 1:
|
|
_a.sent();
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: wnd,
|
|
});
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._switchToWindow = function (msg) {
|
|
var _this = this;
|
|
if (this._isTargetWindow(msg)) {
|
|
return Promise$2.resolve()
|
|
.then(function () {
|
|
_this._setCurrentWindowAsMaster();
|
|
});
|
|
}
|
|
if (!this.childWindowDriverLinks.length)
|
|
return Promise$2.resolve();
|
|
return Promise$2.all(this.childWindowDriverLinks.map(function (childWindowDriverLink) {
|
|
return childWindowDriverLink.findChildWindows(msg, SwitchToWindowCommandMessage);
|
|
}));
|
|
};
|
|
Driver.prototype._handleSetAsMasterMessage = function (msg, wnd) {
|
|
var _this = this;
|
|
// NOTE: The 'setAsMaster' message can be send a few times because
|
|
// the 'sendMessageToDriver' function resend messages if the message confirmation is not received in 1 sec.
|
|
// This message can be send even after driver is started.
|
|
if (this._setAsMasterInProgressOrCompleted())
|
|
return;
|
|
this.setAsMasterInProgress = true;
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: wnd,
|
|
});
|
|
Promise$2.resolve()
|
|
.then(function () {
|
|
return testcafeCore.browser.setActiveWindowId(_this.communicationUrls.activeWindowId, hammerhead__default.createNativeXHR, _this.windowId);
|
|
})
|
|
.then(function () {
|
|
_this._startInternal({
|
|
finalizePendingCommand: msg.finalizePendingCommand,
|
|
result: { id: _this.windowId },
|
|
});
|
|
_this.setAsMasterInProgress = false;
|
|
})
|
|
.catch(function () {
|
|
_this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: new CannotSwitchToWindowError(),
|
|
}));
|
|
});
|
|
};
|
|
Driver.prototype._handleCloseAllWindowsMessage = function (msg, wnd) {
|
|
var _this = this;
|
|
this._closeAllChildWindows()
|
|
.then(function () {
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: wnd,
|
|
});
|
|
})
|
|
.catch(function () {
|
|
_this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: new CloseChildWindowError(),
|
|
}));
|
|
});
|
|
};
|
|
Driver.prototype._handleStartToRestoreChildLinkMessage = function () {
|
|
this.parentWindowDriverLink.restoreChild(this._getCurrentWindowId());
|
|
};
|
|
Driver.prototype._handleHasPendingActionFlags = function (msg, window) {
|
|
var result = this._hasPendingActionFlags(this.contextStorage);
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: window,
|
|
result: result,
|
|
});
|
|
};
|
|
Driver.prototype._handleRestoreChildLink = function (msg, wnd) {
|
|
if (this._stopRespondToChildren)
|
|
return;
|
|
this._addChildWindowDriverLink({ window: wnd, windowId: msg.windowId });
|
|
var allChildWindowLinksRestored = this.childWindowDriverLinks.length === this.contextStorage.getItem(PENDING_CHILD_WINDOW_COUNT);
|
|
if (allChildWindowLinksRestored && this._restoreChildWindowsPromiseResolver) {
|
|
this._restoreChildWindowsPromiseResolver();
|
|
delete this._restoreChildWindowsPromiseResolver;
|
|
this.contextStorage.setItem(PENDING_CHILD_WINDOW_COUNT, 0);
|
|
}
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: wnd,
|
|
});
|
|
};
|
|
Driver.prototype._handleChildWindowIsOpenedInIFrame = function () {
|
|
var _this = this;
|
|
// NOTE: when the child window is opened in iframe we need to wait until the
|
|
// child window is fully loaded
|
|
this._pendingChildWindowInIFrame = new Promise$2(function (resolve) {
|
|
_this._resolvePendingChildWindowInIframe = resolve;
|
|
});
|
|
};
|
|
Driver.prototype._handleChildWindowIsLoadedInIFrame = function (msg, wnd) {
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: wnd,
|
|
});
|
|
this._resolvePendingChildWindowInIframe();
|
|
var childWindowDriverLinkExists = !!this.childWindowDriverLinks.find(function (link) { return link.windowId === msg.windowId; });
|
|
if (!childWindowDriverLinkExists)
|
|
this._onChildWindowOpened({ window: wnd, windowId: msg.windowId });
|
|
};
|
|
Driver.prototype._handleStopInternalFromFrame = function (msg, wnd) {
|
|
sendConfirmationMessage({
|
|
requestMsgId: msg.id,
|
|
window: wnd,
|
|
});
|
|
this.contextStorage.setItem(this.EXECUTING_IN_IFRAME_FLAG, false);
|
|
this._stopInternal();
|
|
};
|
|
Driver.prototype._initChildDriverListening = function () {
|
|
var _this = this;
|
|
messageSandbox$2.on(messageSandbox$2.SERVICE_MSG_RECEIVED_EVENT, function (e) {
|
|
var msg = e.message;
|
|
var window = e.source;
|
|
switch (msg.type) {
|
|
case TYPE.establishConnection:
|
|
_this._addChildIframeDriverLink(msg.id, window);
|
|
break;
|
|
case TYPE.childWindowIsOpenedInIFrame:
|
|
_this._handleChildWindowIsOpenedInIFrame(msg, window);
|
|
break;
|
|
case TYPE.childWindowIsLoadedInIFrame:
|
|
_this._handleChildWindowIsLoadedInIFrame(msg, window);
|
|
break;
|
|
case TYPE.stopInternalFromFrame:
|
|
_this._handleStopInternalFromFrame(msg, window);
|
|
break;
|
|
case TYPE.setAsMaster:
|
|
_this._handleSetAsMasterMessage(msg, window);
|
|
break;
|
|
case TYPE.switchToWindow:
|
|
_this._handleSwitchToWindow(msg, window);
|
|
break;
|
|
case TYPE.closeWindow:
|
|
_this._handleCloseWindow(msg, window);
|
|
break;
|
|
case TYPE.switchToWindowValidation:
|
|
_this._handleSwitchToWindowValidation(msg, window);
|
|
break;
|
|
case TYPE.closeWindowValidation:
|
|
_this._handleCloseWindowValidation(msg, window);
|
|
break;
|
|
case TYPE.getWindows:
|
|
_this._handleGetWindows(msg, window);
|
|
break;
|
|
case TYPE.closeAllChildWindows:
|
|
_this._handleCloseAllWindowsMessage(msg, window);
|
|
break;
|
|
case TYPE.startToRestoreChildLink:
|
|
_this._handleStartToRestoreChildLinkMessage();
|
|
break;
|
|
case TYPE.hasPendingActionFlags:
|
|
_this._handleHasPendingActionFlags(msg, window);
|
|
break;
|
|
case TYPE.restoreChildLink:
|
|
_this._handleRestoreChildLink(msg, window);
|
|
}
|
|
});
|
|
};
|
|
Driver.prototype._getChildIframeDriverLinkByWindow = function (driverWindow) {
|
|
return testcafeCore.arrayUtils.find(this.childIframeDriverLinks, function (link) { return link.driverWindow === driverWindow; });
|
|
};
|
|
Driver.prototype._getChildWindowDriverLinkByWindow = function (childDriverWindow) {
|
|
return testcafeCore.arrayUtils.find(this.childWindowDriverLinks, function (link) { return link.driverWindow === childDriverWindow; });
|
|
};
|
|
Driver.prototype._runInActiveIframe = function (command) {
|
|
var _this = this;
|
|
var runningChain = Promise$2.resolve();
|
|
var activeIframeSelector = this.contextStorage.getItem(ACTIVE_IFRAME_SELECTOR);
|
|
// NOTE: if the page was reloaded we restore the active child driver link via the iframe selector
|
|
if (!this.activeChildIframeDriverLink && activeIframeSelector)
|
|
runningChain = this._switchToIframe(activeIframeSelector, CURRENT_IFRAME_ERROR_CTORS);
|
|
runningChain
|
|
.then(function () {
|
|
_this.contextStorage.setItem(_this.EXECUTING_IN_IFRAME_FLAG, true);
|
|
return _this.activeChildIframeDriverLink.executeCommand(command, _this.speed, _this.options.proxyless, _this.leftTopPoint);
|
|
})
|
|
.then(function (status) { return _this._onCommandExecutedInIframe(status); })
|
|
.catch(function (err) { return _this._onCommandExecutedInIframe(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: err,
|
|
})); });
|
|
};
|
|
Driver.prototype._onCommandExecutedInIframe = function (status) {
|
|
var _this = this;
|
|
this.contextStorage.setItem(this.EXECUTING_IN_IFRAME_FLAG, false);
|
|
var promise = Promise$2.resolve();
|
|
if (this._pendingChildWindowInIFrame)
|
|
promise = this._pendingChildWindowInIFrame;
|
|
promise.then(function () {
|
|
_this._onReady(status);
|
|
});
|
|
};
|
|
Driver.prototype._ensureChildIframeDriverLink = function (iframeWindow, ErrorCtor, selectorTimeout) {
|
|
var _this = this;
|
|
// NOTE: a child iframe driver should establish connection with the parent when it's loaded.
|
|
// Here we are waiting while the appropriate child iframe driver do this if it didn't do yet.
|
|
return testcafeCore.waitFor(function () { return _this._getChildIframeDriverLinkByWindow(iframeWindow); }, CHECK_IFRAME_DRIVER_LINK_DELAY, selectorTimeout)
|
|
.catch(function () {
|
|
throw new ErrorCtor();
|
|
});
|
|
};
|
|
Driver.prototype._ensureChildWindowDriverLink = function (childWindow, ErrorCtor, timeout) {
|
|
var _this = this;
|
|
// NOTE: a child window driver should establish connection with the parent when it's loaded.
|
|
// Here we are waiting while the appropriate child window driver do this if it didn't do yet.
|
|
return testcafeCore.waitFor(function () { return _this._getChildWindowDriverLinkByWindow(childWindow); }, CHECK_CHILD_WINDOW_DRIVER_LINK_DELAY, timeout)
|
|
.catch(function () {
|
|
throw new ErrorCtor();
|
|
});
|
|
};
|
|
Driver.prototype._switchToIframe = function (selector, iframeErrorCtors) {
|
|
var _this = this;
|
|
var hasSpecificTimeout = typeof selector.timeout === 'number';
|
|
var commandSelectorTimeout = hasSpecificTimeout ? selector.timeout : this.options.selectorTimeout;
|
|
return getResult(selector, commandSelectorTimeout, null, function (fn) { return new iframeErrorCtors.NotFoundError(null, fn); }, function () { return new iframeErrorCtors.IsInvisibleError(); }, this.statusBar)
|
|
.then(function (iframe) {
|
|
if (!testcafeCore.domUtils.isIframeElement(iframe))
|
|
throw new ActionElementNotIframeError();
|
|
// NOTE: RG-4558 Previously we waited for iframe become visible when execute selector
|
|
// We need to add a timeout to be sure that iframe driver is initialized
|
|
var childLinkResponseTimeout = hasSpecificTimeout
|
|
? commandSelectorTimeout
|
|
: Math.max(commandSelectorTimeout, WAIT_FOR_IFRAME_DRIVER_RESPONSE_TIMEOUT);
|
|
return _this._ensureChildIframeDriverLink(nativeMethods$6.contentWindowGetter.call(iframe), iframeErrorCtors.NotLoadedError, childLinkResponseTimeout);
|
|
})
|
|
.then(function (childDriverLink) {
|
|
childDriverLink.availabilityTimeout = commandSelectorTimeout;
|
|
_this.activeChildIframeDriverLink = childDriverLink;
|
|
_this.contextStorage.setItem(ACTIVE_IFRAME_SELECTOR, selector);
|
|
});
|
|
};
|
|
Driver.prototype._createWaitForEventPromise = function (eventName, timeout) {
|
|
var _this = this;
|
|
var eventHandler = null;
|
|
var timeoutPromise = new Promise$2(function (resolve) {
|
|
nativeMethods$6.setTimeout.call(window, function () {
|
|
_this.off(eventName, eventHandler);
|
|
resolve();
|
|
}, timeout);
|
|
});
|
|
var resultPromise = new Promise$2(function (resolve) {
|
|
eventHandler = function () {
|
|
this.off(eventName, eventHandler);
|
|
resolve();
|
|
};
|
|
_this.on(eventName, eventHandler);
|
|
});
|
|
return Promise$2.race([timeoutPromise, resultPromise]);
|
|
};
|
|
Driver.prototype._waitForCurrentCommandCompletion = function () {
|
|
if (!this.contextStorage.getItem(this.COMMAND_EXECUTING_FLAG))
|
|
return Promise$2.resolve();
|
|
return this._createWaitForEventPromise(STATUS_WITH_COMMAND_RESULT_EVENT, COMMAND_EXECUTION_MAX_TIMEOUT);
|
|
};
|
|
Driver.prototype._waitForSkipJsErrorFunctionCompletion = function (driverStatus) {
|
|
var _this = this;
|
|
if (!this.contextStorage.getItem(EXECUTING_SKIP_JS_ERRORS_FUNCTION_FLAG))
|
|
return Promise$2.resolve(driverStatus);
|
|
return new Promise$2(function (resolve) {
|
|
var eventHandler = function () {
|
|
_this.off(SKIP_JS_ERRORS_FUNCTION_EXECUTION_COMPLETE_EVENT, eventHandler);
|
|
resolve(driverStatus);
|
|
};
|
|
_this.on(SKIP_JS_ERRORS_FUNCTION_EXECUTION_COMPLETE_EVENT, eventHandler);
|
|
});
|
|
};
|
|
Driver.prototype._waitForEmptyCommand = function () {
|
|
return this._createWaitForEventPromise(EMPTY_COMMAND_EVENT, EMPTY_COMMAND_EVENT_WAIT_TIMEOUT);
|
|
};
|
|
Driver.prototype._abortSwitchingToChildWindowIfItClosed = function () {
|
|
if (!this.activeChildWindowDriverLink.driverWindow.closed)
|
|
return;
|
|
testcafeCore.arrayUtils.remove(this.childWindowDriverLinks, this.activeChildWindowDriverLink);
|
|
this.activeChildWindowDriverLink = null;
|
|
throw new ChildWindowClosedBeforeSwitchingError();
|
|
};
|
|
Driver.prototype._switchToChildWindow = function (selector) {
|
|
var _this = this;
|
|
this.contextStorage.setItem(this.PENDING_WINDOW_SWITCHING_FLAG, true);
|
|
var isWindowOpenedViaAPI = this.contextStorage.getItem(this.WINDOW_COMMAND_API_CALL_FLAG);
|
|
return executeChildWindowDriverLinkSelector(selector, this.childWindowDriverLinks)
|
|
.then(function (childWindowDriverLink) {
|
|
return _this._ensureChildWindowDriverLink(childWindowDriverLink.driverWindow, ChildWindowIsNotLoadedError, _this.options.childWindowReadyTimeout);
|
|
})
|
|
.then(function (childWindowDriverLink) {
|
|
_this.activeChildWindowDriverLink = childWindowDriverLink;
|
|
return _this._waitForCurrentCommandCompletion();
|
|
})
|
|
.then(function () {
|
|
return isWindowOpenedViaAPI ? void 0 : _this._waitForEmptyCommand();
|
|
})
|
|
.then(function () {
|
|
_this._observeFileDownloadingInNewWindow();
|
|
_this._abortSwitchingToChildWindowIfItClosed();
|
|
_this._stopInternal();
|
|
return _this.activeChildWindowDriverLink.setAsMaster(isWindowOpenedViaAPI);
|
|
})
|
|
.then(function () {
|
|
_this.contextStorage.setItem(_this.PENDING_WINDOW_SWITCHING_FLAG, false);
|
|
})
|
|
.catch(function (err) {
|
|
_this.contextStorage.setItem(_this.PENDING_WINDOW_SWITCHING_FLAG, false);
|
|
if (err instanceof ChildWindowClosedBeforeSwitchingError) {
|
|
_this._onReady(new DriverStatus());
|
|
return;
|
|
}
|
|
_this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: new CannotSwitchToWindowError(),
|
|
}));
|
|
});
|
|
};
|
|
Driver.prototype._switchToTopParentWindow = function () {
|
|
var switchFn = this.parentWindowDriverLink.setTopOpenedWindowAsMaster.bind(this.parentWindowDriverLink);
|
|
this._switchToParentWindowInternal(switchFn);
|
|
};
|
|
Driver.prototype._switchToParentWindow = function (opts) {
|
|
if (opts === void 0) { opts = {}; }
|
|
var switchFn = this.parentWindowDriverLink.setParentWindowAsMaster.bind(this.parentWindowDriverLink);
|
|
this._switchToParentWindowInternal(switchFn, opts);
|
|
};
|
|
Driver.prototype._switchToParentWindowInternal = function (parentWindowSwitchFn, opts) {
|
|
var _this = this;
|
|
if (opts === void 0) { opts = {}; }
|
|
this.contextStorage.setItem(this.PENDING_WINDOW_SWITCHING_FLAG, true);
|
|
return Promise$2.resolve()
|
|
.then(function () {
|
|
_this._stopInternal();
|
|
return parentWindowSwitchFn(opts);
|
|
})
|
|
.then(function () {
|
|
_this.contextStorage.setItem(_this.PENDING_WINDOW_SWITCHING_FLAG, false);
|
|
})
|
|
.catch(function () {
|
|
_this.contextStorage.setItem(_this.PENDING_WINDOW_SWITCHING_FLAG, false);
|
|
_this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: new CannotSwitchToWindowError(),
|
|
}));
|
|
});
|
|
};
|
|
Driver.prototype._switchToMainWindow = function (command) {
|
|
if (this.activeChildIframeDriverLink)
|
|
this.activeChildIframeDriverLink.executeCommand(command);
|
|
this._clearActiveChildIframeInfo();
|
|
};
|
|
Driver.prototype._clearActiveChildIframeInfo = function () {
|
|
this.contextStorage.setItem(ACTIVE_IFRAME_SELECTOR, null);
|
|
this.activeChildIframeDriverLink = null;
|
|
};
|
|
Driver.prototype._setNativeDialogHandlerInIframes = function (dialogHandler) {
|
|
var msg = new SetNativeDialogHandlerMessage(dialogHandler);
|
|
for (var i = 0; i < this.childIframeDriverLinks.length; i++)
|
|
messageSandbox$2.sendServiceMsg(msg, this.childIframeDriverLinks[i].driverWindow);
|
|
};
|
|
// Commands handling
|
|
Driver.prototype._onActionCommand = function (command) {
|
|
var _this = this;
|
|
var executeSelectorCb = function (selector /*: ExecuteSelectorCommand*/, errCtors /*: AutomationErrorCtors*/, startTime /*: number*/) {
|
|
var createNotFoundError = createErrorCtorCallback(errCtors.notFound);
|
|
var createIsInvisibleError = createErrorCtorCallback(errCtors.invisible);
|
|
var selectorExecutor = new SelectorExecutor(selector, _this.options.selectorTimeout, startTime, createNotFoundError, createIsInvisibleError);
|
|
return selectorExecutor.getResult();
|
|
};
|
|
var dispatchProxylessEventFn = this.options.proxyless ? nativeMethods$6.functionBind.call(testcafeCore.browser.dispatchProxylessEvent, testcafeCore.browser.dispatchProxylessEvent, this.communicationUrls.dispatchProxylessEvent, testCafeUI__default, hammerhead__default.createNativeXHR) : null;
|
|
var executor = new ActionExecutor(command, {
|
|
globalSelectorTimeout: this.options.selectorTimeout,
|
|
testSpeed: this.speed,
|
|
executeSelectorFn: executeSelectorCb,
|
|
leftTopPoint: this.leftTopPoint,
|
|
dispatchProxylessEventFn: dispatchProxylessEventFn,
|
|
});
|
|
var warnings = [];
|
|
executor.on(ActionExecutor.EXECUTION_STARTED_EVENT, function () {
|
|
_this.statusBar.hideWaitingElementStatus(true);
|
|
_this.contextStorage.setItem(_this.COMMAND_EXECUTING_FLAG, true);
|
|
});
|
|
executor.on(ActionExecutor.WAITING_FOR_ELEMENT_EVENT, function (timeout) {
|
|
_this.statusBar.showWaitingElementStatus(timeout);
|
|
});
|
|
executor.on(ActionExecutor.WARNING_EVENT, function (warning) {
|
|
warnings.push(warning);
|
|
});
|
|
var clientRequestEmitter = new testcafeCore.ClientRequestEmitter();
|
|
var scriptExecutionEmitter = new testcafeCore.ScriptExecutionEmitter();
|
|
var barriers = new BarriersComplex(clientRequestEmitter, scriptExecutionEmitter, testcafeCore.pageUnloadBarrier);
|
|
executor.execute(barriers)
|
|
.then(function (elements) { return new DriverStatus({
|
|
isCommandResult: true,
|
|
result: createReplicator(new SelectorElementActionTransform()).encode(elements),
|
|
warnings: warnings,
|
|
}); })
|
|
.catch(function (err) { return _this.statusBar.hideWaitingElementStatus(false)
|
|
.then(function () { return new DriverStatus({ isCommandResult: true, executionError: err }); }); })
|
|
.then(function (driverStatus) { return _this._waitForSkipJsErrorFunctionCompletion(driverStatus); })
|
|
.then(function (driverStatus) {
|
|
_this.contextStorage.setItem(_this.COMMAND_EXECUTING_FLAG, false);
|
|
_this.contextStorage.setItem(EXECUTING_SKIP_JS_ERRORS_FUNCTION_FLAG, false);
|
|
_this._onReady(driverStatus);
|
|
});
|
|
};
|
|
Driver.prototype._onSetNativeDialogHandlerCommand = function (command) {
|
|
this.nativeDialogsTracker.setHandler(command.dialogHandler);
|
|
this._setNativeDialogHandlerInIframes(command.dialogHandler);
|
|
this._onReady(new DriverStatus({ isCommandResult: true }));
|
|
};
|
|
Driver.prototype._onGetNativeDialogHistoryCommand = function () {
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
result: this.nativeDialogsTracker.appearedDialogs,
|
|
}));
|
|
};
|
|
Driver.prototype._onGetBrowserConsoleMessagesCommand = function () {
|
|
this._onReady(new DriverStatus({ isCommandResult: true }));
|
|
};
|
|
Driver.prototype._onNavigateToCommand = function (command) {
|
|
var _this = this;
|
|
this.contextStorage.setItem(this.COMMAND_EXECUTING_FLAG, true);
|
|
executeNavigateTo(command)
|
|
.then(function (driverStatus) {
|
|
_this.contextStorage.setItem(_this.COMMAND_EXECUTING_FLAG, false);
|
|
return _this._onReady(driverStatus);
|
|
});
|
|
};
|
|
Driver.prototype._onGetProxyUrlCommand = function (command) {
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
result: urlUtils.getProxyUrl(command.url, command.options),
|
|
}));
|
|
};
|
|
Driver.prototype._onSkipJsErrorsCommand = function (_a) {
|
|
var options = _a.options;
|
|
this.options.skipJsErrors = options;
|
|
this._onReady(new DriverStatus({ isCommandResult: true }));
|
|
};
|
|
Driver.prototype._onExecuteClientFunctionCommand = function (command) {
|
|
var _this = this;
|
|
this.contextStorage.setItem(EXECUTING_CLIENT_FUNCTION_DESCRIPTOR, { instantiationCallsiteName: command.instantiationCallsiteName });
|
|
var executor = new ClientFunctionExecutor(command);
|
|
getExecutorResultDriverStatus(executor)
|
|
.then(function (driverStatus) {
|
|
_this.contextStorage.setItem(EXECUTING_CLIENT_FUNCTION_DESCRIPTOR, null);
|
|
_this._onReady(driverStatus);
|
|
});
|
|
};
|
|
Driver.prototype._onExecuteSelectorCommand = function (command) {
|
|
var _this = this;
|
|
var startTime = this.contextStorage.getItem(SELECTOR_EXECUTION_START_TIME) || new DateCtor$1();
|
|
var elementNotFoundOrNotVisible = createErrorCtorCallback(getCannotObtainInfoErrorCtor());
|
|
var elementNotFound = command.strictError ? createErrorCtorCallback(getNotFoundErrorCtor()) : elementNotFoundOrNotVisible;
|
|
var elementIsInvisible = command.strictError ? createErrorCtorCallback(getInvisibleErrorCtor()) : elementNotFoundOrNotVisible;
|
|
getResultDriverStatus(command, this.options.selectorTimeout, startTime, command.needError ? elementNotFound : null, command.needError ? elementIsInvisible : null, this.statusBar)
|
|
.then(function (driverStatus) {
|
|
_this.contextStorage.setItem(SELECTOR_EXECUTION_START_TIME, null);
|
|
_this._onReady(driverStatus);
|
|
});
|
|
};
|
|
Driver.prototype._onSwitchToMainWindowCommand = function (command) {
|
|
this._switchToMainWindow(command);
|
|
this._onReady(new DriverStatus({ isCommandResult: true }));
|
|
};
|
|
Driver.prototype._onSwitchToIframeCommand = function (command) {
|
|
var _this = this;
|
|
this
|
|
._switchToIframe(command.selector, ACTION_IFRAME_ERROR_CTORS)
|
|
.then(function () { return _this._onReady(new DriverStatus({ isCommandResult: true })); })
|
|
.catch(function (err) { return _this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: err,
|
|
})); });
|
|
};
|
|
Driver.prototype._onWindowOpenCommand = function (command) {
|
|
this.contextStorage.setItem(this.WINDOW_COMMAND_API_CALL_FLAG, true);
|
|
window.open(command.url);
|
|
};
|
|
Driver.prototype._onWindowCloseCommand = function (command) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var wnd, windowId, isCurrentWindow, response, result, err_1;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
wnd = this._getTopOpenedWindow();
|
|
windowId = command.windowId || this.windowId;
|
|
isCurrentWindow = windowId === this.windowId;
|
|
_a.label = 1;
|
|
case 1:
|
|
_a.trys.push([1, 4, , 5]);
|
|
return [4 /*yield*/, this._validateChildWindowCloseCommandExists(windowId, wnd)];
|
|
case 2:
|
|
response = _a.sent();
|
|
result = response.result;
|
|
if (!result.success)
|
|
throw Driver._createWindowValidationError(result);
|
|
return [4 /*yield*/, sendMessageToDriver(new CloseWindowCommandMessage({
|
|
windowId: windowId,
|
|
isCurrentWindow: isCurrentWindow,
|
|
}), wnd, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError)];
|
|
case 3:
|
|
_a.sent();
|
|
// NOTE: we do not need to send a new Driver Status if we close the current window
|
|
// in this case the new Driver Status will be sent from the `_setCurrentWindowAsMaster` method
|
|
// in other cases we need to send a new Driver Status from here.
|
|
if (!isCurrentWindow) {
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
}));
|
|
}
|
|
return [3 /*break*/, 5];
|
|
case 4:
|
|
err_1 = _a.sent();
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: err_1,
|
|
}));
|
|
return [3 /*break*/, 5];
|
|
case 5: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._onGetCurrentWindowCommand = function () {
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
result: {
|
|
id: this.windowId,
|
|
},
|
|
}));
|
|
};
|
|
Driver.prototype._onGetWindowsCommand = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var wnd, response;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
wnd = this._getTopOpenedWindow();
|
|
return [4 /*yield*/, sendMessageToDriver(new GetWindowsMessage(), wnd, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError)];
|
|
case 1:
|
|
response = _a.sent();
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
result: response.result,
|
|
}));
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._validateChildWindowCloseCommandExists = function (windowId, wnd) {
|
|
return sendMessageToDriver(new CloseWindowValidationMessage({ windowId: windowId }), wnd, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError);
|
|
};
|
|
Driver.prototype._validateChildWindowSwitchToWindowCommandExists = function (_a, wnd) {
|
|
var windowId = _a.windowId, fn = _a.fn;
|
|
return sendMessageToDriver(new SwitchToWindowValidationMessage({ windowId: windowId, fn: fn }), wnd, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError);
|
|
};
|
|
Driver.prototype._getTopOpenedWindow = function () {
|
|
var _a;
|
|
var wnd = ((_a = this.parentWindowDriverLink) === null || _a === void 0 ? void 0 : _a.getTopOpenedWindow()) || window;
|
|
return wnd.top;
|
|
};
|
|
Driver.prototype._onSwitchToWindow = function (command, err) {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var wnd, response, result;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
wnd = this._getTopOpenedWindow();
|
|
return [4 /*yield*/, this._validateChildWindowSwitchToWindowCommandExists({ windowId: command.windowId, fn: command.checkWindow }, wnd)];
|
|
case 1:
|
|
response = _a.sent();
|
|
result = response.result;
|
|
if (!result.success) {
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: err || Driver._createWindowValidationError(result),
|
|
}));
|
|
}
|
|
else {
|
|
this._stopInternal();
|
|
sendMessageToDriver(new SwitchToWindowCommandMessage({ windowId: command.windowId, fn: command.checkWindow }), wnd, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, CannotSwitchToWindowError);
|
|
}
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._restoreChildWindowLinks = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var restoreChildWindowsPromise, err_2;
|
|
var _this = this;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
if (!this.contextStorage.getItem(PENDING_CHILD_WINDOW_COUNT))
|
|
return [2 /*return*/];
|
|
restoreChildWindowsPromise = new Promise$2(function (resolve) {
|
|
_this._restoreChildWindowsPromiseResolver = resolve;
|
|
});
|
|
_a.label = 1;
|
|
case 1:
|
|
_a.trys.push([1, 3, , 4]);
|
|
return [4 /*yield*/, testcafeCore.getTimeLimitedPromise(restoreChildWindowsPromise, RESTORE_CHILD_WINDOWS_TIMEOUT)];
|
|
case 2:
|
|
_a.sent();
|
|
return [3 /*break*/, 4];
|
|
case 3:
|
|
err_2 = _a.sent();
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: new CannotRestoreChildWindowError(),
|
|
}));
|
|
return [3 /*break*/, 4];
|
|
case 4: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._onSwitchToPreviousWindow = function (command) {
|
|
this._onSwitchToWindow(command, new PreviousWindowNotFoundError());
|
|
};
|
|
Driver.prototype._onSwitchToParentWindow = function () {
|
|
if (this.parentWindowDriverLink)
|
|
this._switchToParentWindow({ finalizePendingCommand: true });
|
|
else {
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: new ParentWindowNotFoundError(),
|
|
}));
|
|
}
|
|
};
|
|
Driver.prototype._onBrowserManipulationCommand = function (command) {
|
|
var _this = this;
|
|
this.contextStorage.setItem(this.COMMAND_EXECUTING_FLAG, true);
|
|
executeManipulationCommand(command, this.options.selectorTimeout, this.statusBar)
|
|
.then(function (driverStatus) {
|
|
_this.contextStorage.setItem(_this.COMMAND_EXECUTING_FLAG, false);
|
|
return _this._onReady(driverStatus);
|
|
});
|
|
};
|
|
Driver.prototype._onSetBreakpointCommand = function (_a) {
|
|
var _this = this;
|
|
var isTestError = _a.isTestError, inCompilerService = _a.inCompilerService;
|
|
var showDebuggingStatusPromise = this.statusBar.showDebuggingStatus(isTestError);
|
|
if (inCompilerService) {
|
|
showDebuggingStatusPromise.then(function (debug) {
|
|
_this.debug = debug;
|
|
});
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
result: true,
|
|
}));
|
|
}
|
|
else {
|
|
showDebuggingStatusPromise.then(function (debug) {
|
|
var stopAfterNextAction = debug === STATUS_BAR_DEBUG_ACTION.step;
|
|
_this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
result: stopAfterNextAction,
|
|
}));
|
|
});
|
|
}
|
|
};
|
|
Driver.prototype._onDisableDebugCommand = function () {
|
|
this.statusBar._resetState();
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
}));
|
|
};
|
|
Driver.prototype._onSetTestSpeedCommand = function (command) {
|
|
this.speed = command.speed;
|
|
this._onReady(new DriverStatus({ isCommandResult: true }));
|
|
};
|
|
Driver.prototype._onShowAssertionRetriesStatusCommand = function (command) {
|
|
this.contextStorage.setItem(ASSERTION_RETRIES_TIMEOUT, command.timeout);
|
|
this.contextStorage.setItem(ASSERTION_RETRIES_START_TIME, nativeMethods$6.dateNow());
|
|
this.statusBar.showWaitingAssertionRetriesStatus(command.timeout);
|
|
this._onReady(new DriverStatus({ isCommandResult: true }));
|
|
};
|
|
Driver.prototype._onHideAssertionRetriesStatusCommand = function (command) {
|
|
var _this = this;
|
|
this.contextStorage.setItem(ASSERTION_RETRIES_TIMEOUT, null);
|
|
this.contextStorage.setItem(ASSERTION_RETRIES_START_TIME, null);
|
|
this.statusBar.hideWaitingAssertionRetriesStatus(command.success)
|
|
.then(function () { return _this._onReady(new DriverStatus({ isCommandResult: true })); });
|
|
};
|
|
Driver.prototype._checkStatus = function () {
|
|
var _this = this;
|
|
var urls = {
|
|
statusUrl: this.communicationUrls.statusDone,
|
|
};
|
|
return testcafeCore.browser
|
|
.checkStatus(urls, hammerhead__default.createNativeXHR, { manualRedirect: true, proxyless: this.options.proxyless })
|
|
.then(function (_a) {
|
|
var command = _a.command;
|
|
var isSessionChange = command.testRunId !== _this.testRunId;
|
|
if (isSessionChange) {
|
|
storages.clear();
|
|
storages.lock();
|
|
testcafeCore.browser.redirect(command, hammerhead__default.createNativeXHR, _this.communicationUrls.openFileProtocolUrl);
|
|
}
|
|
else {
|
|
_this.contextStorage.setItem(TEST_DONE_SENT_FLAG, false);
|
|
_this._onReady({ isCommandResult: false });
|
|
}
|
|
})
|
|
.catch(function () {
|
|
return testcafeCore.delay(CHECK_STATUS_RETRY_DELAY);
|
|
});
|
|
};
|
|
Driver.prototype._onCustomCommand = function (command) {
|
|
var _this = this;
|
|
var handler = this.customCommandHandlers[command.type].handler;
|
|
handler(command).then(function (result) {
|
|
_this._onReady(new DriverStatus({ isCommandResult: true, result: result }));
|
|
});
|
|
};
|
|
Driver.prototype._closeAllChildWindows = function () {
|
|
var _this = this;
|
|
if (!this.childWindowDriverLinks.length)
|
|
return Promise$2.resolve();
|
|
return Promise$2.all(this.childWindowDriverLinks.map(function (childWindowDriverLink) {
|
|
return childWindowDriverLink.closeAllChildWindows();
|
|
}))
|
|
.then(function () {
|
|
nativeMethods$6.arrayForEach.call(_this.childWindowDriverLinks, function (childWindowDriverLink) {
|
|
childWindowDriverLink.driverWindow.close();
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._onTestDone = function (status) {
|
|
var _this = this;
|
|
this.contextStorage.setItem(TEST_DONE_SENT_FLAG, true);
|
|
if (this.parentWindowDriverLink)
|
|
this._switchToTopParentWindow();
|
|
else {
|
|
this._closeAllChildWindows()
|
|
.then(function () {
|
|
return _this._sendStatus(status);
|
|
})
|
|
.then(function () {
|
|
_this._checkStatus();
|
|
})
|
|
.catch(function () {
|
|
_this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
executionError: CloseChildWindowError,
|
|
}));
|
|
});
|
|
}
|
|
};
|
|
Driver.prototype._onBackupStoragesCommand = function () {
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
result: storages.backup(),
|
|
}));
|
|
};
|
|
Driver.prototype._isPendingSwitchingWindow = function () {
|
|
return !!this.contextStorage.getItem(this.PENDING_WINDOW_SWITCHING_FLAG);
|
|
};
|
|
Driver.prototype._onPrepareClientEnvironmentInDebugMode = function (command) {
|
|
// NOTE: repeat the function call wrapping produced by the 'esm' module on the client-side
|
|
// (same as on the server-side).
|
|
nativeMethods$6.objectDefineProperty(window, command.esmRuntime, {
|
|
value: {
|
|
g: window,
|
|
c: window.eval, //eslint-disable-line no-eval
|
|
},
|
|
configurable: true, // NOTE: for the 'disablePageReloads' option
|
|
});
|
|
this._onReady(new DriverStatus({
|
|
isCommandResult: true,
|
|
result: true,
|
|
}));
|
|
};
|
|
Driver.prototype._isStatusWithCommandResultInPendingWindowSwitchingMode = function (status) {
|
|
return status.isCommandResult && this._isPendingSwitchingWindow();
|
|
};
|
|
Driver.prototype._isEmptyCommandInPendingWindowSwitchingMode = function (command) {
|
|
return !command && this._isPendingSwitchingWindow();
|
|
};
|
|
Driver.prototype._observeFileDownloadingInNewWindow = function () {
|
|
var _this = this;
|
|
var status = new DriverStatus({ isObservingFileDownloadingInNewWindow: true });
|
|
if (this._isPendingSwitchingWindow()) {
|
|
this._sendStatus(status)
|
|
.then(function (command) {
|
|
if (command)
|
|
_this._onCommand(command);
|
|
else
|
|
_this._observeFileDownloadingInNewWindow();
|
|
});
|
|
}
|
|
};
|
|
// Routing
|
|
Driver.prototype._onReady = function (status) {
|
|
var _this = this;
|
|
if (this.debug) {
|
|
status.debug = this.debug;
|
|
this.debug = null;
|
|
}
|
|
if (this._isStatusWithCommandResultInPendingWindowSwitchingMode(status))
|
|
this.emit(STATUS_WITH_COMMAND_RESULT_EVENT);
|
|
this._sendStatus(status)
|
|
.then(function (command) {
|
|
if (command)
|
|
_this._onCommand(command);
|
|
else {
|
|
if (_this._isEmptyCommandInPendingWindowSwitchingMode(command)) {
|
|
_this.emit(EMPTY_COMMAND_EVENT);
|
|
return;
|
|
}
|
|
// NOTE: the driver gets an empty response if TestRun doesn't get a new command within 2 minutes
|
|
_this._onReady(new DriverStatus());
|
|
}
|
|
});
|
|
};
|
|
Driver.prototype._executeCommand = function (command) {
|
|
this.contextStorage.setItem(this.WINDOW_COMMAND_API_CALL_FLAG, false);
|
|
if (this.customCommandHandlers[command.type])
|
|
this._onCustomCommand(command);
|
|
else if (command.type === COMMAND_TYPE.testDone)
|
|
this._onTestDone(new DriverStatus({ isCommandResult: true }));
|
|
else if (command.type === COMMAND_TYPE.setBreakpoint)
|
|
this._onSetBreakpointCommand(command);
|
|
else if (command.type === COMMAND_TYPE.disableDebug)
|
|
this._onDisableDebugCommand();
|
|
else if (command.type === COMMAND_TYPE.switchToMainWindow)
|
|
this._onSwitchToMainWindowCommand(command);
|
|
else if (command.type === COMMAND_TYPE.switchToIframe)
|
|
this._onSwitchToIframeCommand(command);
|
|
else if (command.type === COMMAND_TYPE.openWindow)
|
|
this._onWindowOpenCommand(command);
|
|
else if (command.type === COMMAND_TYPE.closeWindow)
|
|
this._onWindowCloseCommand(command);
|
|
else if (command.type === COMMAND_TYPE.getCurrentWindow)
|
|
this._onGetCurrentWindowCommand(command);
|
|
else if (command.type === COMMAND_TYPE.getCurrentWindows)
|
|
this._onGetWindowsCommand();
|
|
else if (command.type === COMMAND_TYPE.switchToWindow)
|
|
this._onSwitchToWindow(command);
|
|
else if (command.type === COMMAND_TYPE.switchToPreviousWindow)
|
|
this._onSwitchToPreviousWindow(command);
|
|
else if (command.type === COMMAND_TYPE.switchToParentWindow)
|
|
this._onSwitchToParentWindow();
|
|
else if (isBrowserManipulationCommand(command))
|
|
this._onBrowserManipulationCommand(command);
|
|
else if (command.type === COMMAND_TYPE.executeClientFunction)
|
|
this._onExecuteClientFunctionCommand(command);
|
|
else if (command.type === COMMAND_TYPE.executeSelector)
|
|
this._onExecuteSelectorCommand(command);
|
|
else if (command.type === COMMAND_TYPE.navigateTo)
|
|
this._onNavigateToCommand(command);
|
|
else if (command.type === COMMAND_TYPE.setNativeDialogHandler)
|
|
this._onSetNativeDialogHandlerCommand(command);
|
|
else if (command.type === COMMAND_TYPE.getNativeDialogHistory)
|
|
this._onGetNativeDialogHistoryCommand(command);
|
|
else if (command.type === COMMAND_TYPE.getBrowserConsoleMessages)
|
|
this._onGetBrowserConsoleMessagesCommand(command);
|
|
else if (command.type === COMMAND_TYPE.setTestSpeed)
|
|
this._onSetTestSpeedCommand(command);
|
|
else if (command.type === COMMAND_TYPE.showAssertionRetriesStatus)
|
|
this._onShowAssertionRetriesStatusCommand(command);
|
|
else if (command.type === COMMAND_TYPE.hideAssertionRetriesStatus)
|
|
this._onHideAssertionRetriesStatusCommand(command);
|
|
else if (command.type === COMMAND_TYPE.backupStorages)
|
|
this._onBackupStoragesCommand();
|
|
else if (command.type === COMMAND_TYPE.closeChildWindowOnFileDownloading)
|
|
this._closeChildWindowOnFileDownloading();
|
|
else if (command.type === COMMAND_TYPE.prepareClientEnvironmentInDebugMode)
|
|
this._onPrepareClientEnvironmentInDebugMode(command);
|
|
else if (command.type === COMMAND_TYPE.getProxyUrl)
|
|
this._onGetProxyUrlCommand(command);
|
|
else if (command.type === COMMAND_TYPE.skipJsErrors)
|
|
this._onSkipJsErrorsCommand(command);
|
|
else
|
|
this._onActionCommand(command);
|
|
};
|
|
Driver.prototype._closeChildWindowOnFileDownloading = function () {
|
|
this.activeChildWindowDriverLink.closeFileDownloadingWindow();
|
|
testcafeCore.arrayUtils.remove(this.childWindowDriverLinks, this.activeChildWindowDriverLink);
|
|
testcafeAutomation.cursor.show();
|
|
this._startInternal();
|
|
};
|
|
Driver.prototype._isExecutableInTopWindowOnly = function (command) {
|
|
if (isExecutableInTopWindowOnly(command))
|
|
return true;
|
|
var customCommandHandler = this.customCommandHandlers[command.type];
|
|
return command.forceExecutionInTopWindowOnly || customCommandHandler && customCommandHandler.isExecutableInTopWindowOnly;
|
|
};
|
|
Driver.prototype._onCommand = function (command) {
|
|
var _this = this;
|
|
// NOTE: the driver sends status to the server as soon as it's created,
|
|
// but it should wait until the page is loaded before executing a command.
|
|
this.readyPromise
|
|
.then(function () {
|
|
// NOTE: we should not execute a command if we already have a pending page error and this command is
|
|
// rejectable by page errors. In this case, we immediately send status with this error to the server.
|
|
var isCommandRejectableByError = isCommandRejectableByPageError(command);
|
|
var pendingPageError = _this.contextStorage.getItem(PENDING_PAGE_ERROR);
|
|
if (pendingPageError && isCommandRejectableByError) {
|
|
_this._onReady(new DriverStatus({ isCommandResult: true }));
|
|
return;
|
|
}
|
|
// NOTE: we should execute a command in an iframe if the current execution context belongs to
|
|
// this iframe and the command is not one of those that can be executed only in the top window.
|
|
var isThereActiveIframe = _this.activeChildIframeDriverLink ||
|
|
_this.contextStorage.getItem(ACTIVE_IFRAME_SELECTOR);
|
|
if (!_this._isExecutableInTopWindowOnly(command) && isThereActiveIframe) {
|
|
_this._runInActiveIframe(command);
|
|
return;
|
|
}
|
|
_this._executeCommand(command);
|
|
});
|
|
};
|
|
// API
|
|
Driver.prototype.setCustomCommandHandlers = function (command, handler, executeInTopWindowOnly) {
|
|
this.customCommandHandlers[command] = {
|
|
isExecutableInTopWindowOnly: executeInTopWindowOnly,
|
|
handler: handler,
|
|
};
|
|
};
|
|
Driver.prototype._startInternal = function (opts) {
|
|
this.role = DriverRole.master;
|
|
testcafeCore.browser.startHeartbeat(this.communicationUrls.heartbeat, hammerhead__default.createNativeXHR);
|
|
this._setupAssertionRetryIndication();
|
|
this._startCommandsProcessing(opts);
|
|
};
|
|
Driver.prototype._stopInternal = function () {
|
|
this.role = DriverRole.replica;
|
|
testcafeCore.browser.stopHeartbeat();
|
|
testcafeAutomation.cursor.hide();
|
|
};
|
|
Driver.prototype._setupAssertionRetryIndication = function () {
|
|
var _this = this;
|
|
this.readyPromise.then(function () {
|
|
_this.statusBar.hidePageLoadingStatus();
|
|
var assertionRetriesTimeout = _this.contextStorage.getItem(ASSERTION_RETRIES_TIMEOUT);
|
|
if (assertionRetriesTimeout) {
|
|
var startTime = _this.contextStorage.getItem(ASSERTION_RETRIES_START_TIME);
|
|
var timeLeft = assertionRetriesTimeout - (new DateCtor$1() - startTime);
|
|
if (timeLeft > 0)
|
|
_this.statusBar.showWaitingAssertionRetriesStatus(assertionRetriesTimeout, startTime);
|
|
}
|
|
});
|
|
};
|
|
Driver.prototype._startCommandsProcessing = function (opts) {
|
|
if (opts === void 0) { opts = { finalizePendingCommand: false, isFirstRequestAfterWindowSwitching: false, result: void 0 }; }
|
|
var pendingStatus = this.contextStorage.getItem(PENDING_STATUS);
|
|
if (pendingStatus)
|
|
pendingStatus.resent = true;
|
|
// NOTE: we should not send any message to the server if we've
|
|
// sent the 'test-done' message but haven't got the response.
|
|
if (this.contextStorage.getItem(TEST_DONE_SENT_FLAG)) {
|
|
if (pendingStatus)
|
|
this._onTestDone(pendingStatus);
|
|
else
|
|
this._checkStatus();
|
|
return;
|
|
}
|
|
if (this._failIfClientCodeExecutionIsInterrupted())
|
|
return;
|
|
var finalizePendingCommand = opts.finalizePendingCommand || this._hasPendingActionFlags(this.contextStorage);
|
|
var status = pendingStatus || new DriverStatus({
|
|
isCommandResult: finalizePendingCommand,
|
|
isFirstRequestAfterWindowSwitching: opts.isFirstRequestAfterWindowSwitching,
|
|
result: opts.result,
|
|
});
|
|
this.contextStorage.setItem(this.COMMAND_EXECUTING_FLAG, false);
|
|
this.contextStorage.setItem(this.EXECUTING_IN_IFRAME_FLAG, false);
|
|
this.contextStorage.setItem(this.PENDING_WINDOW_SWITCHING_FLAG, false);
|
|
this._onReady(status);
|
|
};
|
|
Driver.prototype._initParentWindowLink = function () {
|
|
// NOTE: we need to create parentWindowDriverLinks in the following cases:
|
|
// multiple-windows mode is enabled
|
|
// current window has parent window
|
|
// current window parent is not the same as current window
|
|
// the last case is possible when we have the series of multiple and non-multiple windows tests
|
|
if (window.opener && window.opener !== window && this.windowId)
|
|
this.parentWindowDriverLink = new ParentWindowDriverLink(window);
|
|
};
|
|
Driver.prototype._initConsoleMessages = function () {
|
|
var messages = this.consoleMessages;
|
|
messages.ensureMessageContainer(this.windowId);
|
|
this.consoleMessages = messages;
|
|
};
|
|
Driver.prototype._getDriverRole = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var activeWindowId;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
if (!this.windowId)
|
|
return [2 /*return*/, DriverRole.master];
|
|
return [4 /*yield*/, testcafeCore.browser.getActiveWindowId(this.communicationUrls.activeWindowId, hammerhead__default.createNativeXHR)];
|
|
case 1:
|
|
activeWindowId = (_a.sent()).activeWindowId;
|
|
return [2 /*return*/, activeWindowId === this.windowId ?
|
|
DriverRole.master :
|
|
DriverRole.replica];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype._init = function () {
|
|
var _a = this.options, proxyless = _a.proxyless, dialogHandler = _a.dialogHandler, speed = _a.speed;
|
|
this.contextStorage = new Storage(window, {
|
|
testRunId: this.testRunId,
|
|
windowId: this.windowId,
|
|
proxyless: proxyless,
|
|
});
|
|
this.nativeDialogsTracker = new NativeDialogTracker(this.contextStorage, { proxyless: proxyless, dialogHandler: dialogHandler });
|
|
this.statusBar = new testCafeUI__default.StatusBar(this.runInfo.userAgent, this.runInfo.fixtureName, this.runInfo.testName, this.contextStorage);
|
|
var self = this;
|
|
this.statusBar.on(this.statusBar.UNLOCK_PAGE_BTN_CLICK, function () {
|
|
if (!self.options.proxyless)
|
|
testcafeCore.disableRealEventsPreventing();
|
|
});
|
|
this.speed = speed;
|
|
this._initConsoleMessages();
|
|
this._initParentWindowLink();
|
|
if (this._isOpenedInIframe())
|
|
sendMessageToDriver(new ChildWindowIsLoadedInFrameMessage(this.windowId), window.opener.top, WAIT_FOR_WINDOW_DRIVER_RESPONSE_TIMEOUT, WindowNotFoundError);
|
|
};
|
|
Driver.prototype._doFirstPageLoadSetup = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
return __generator(this, function (_a) {
|
|
if (this.isFirstPageLoad && this.options.canUseDefaultWindowActions) ;
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
Driver.prototype.start = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var role;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
this._init();
|
|
return [4 /*yield*/, this._doFirstPageLoadSetup()];
|
|
case 1:
|
|
_a.sent();
|
|
return [4 /*yield*/, this._restoreChildWindowLinks()];
|
|
case 2:
|
|
_a.sent();
|
|
return [4 /*yield*/, this._getDriverRole()];
|
|
case 3:
|
|
role = _a.sent();
|
|
// NOTE: the child window can become master during the preceding async requests
|
|
// in this case we do not need to call the `_startInternal` method again
|
|
// since it was called during the `_handleSetAsMasterMessage` method.
|
|
if (this.role === DriverRole.master)
|
|
return [2 /*return*/];
|
|
if (role === DriverRole.master)
|
|
this._startInternal();
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
return Driver;
|
|
}(testcafeCore.serviceUtils.EventEmitter));
|
|
|
|
var ParentIframeDriverLink = /** @class */ (function () {
|
|
function ParentIframeDriverLink(parentDriverWindow) {
|
|
this.driverWindow = parentDriverWindow;
|
|
}
|
|
ParentIframeDriverLink.prototype.establishConnection = function () {
|
|
var msg = new EstablishConnectionMessage();
|
|
return sendMessageToDriver(msg, this.driverWindow, WAIT_FOR_IFRAME_DRIVER_RESPONSE_TIMEOUT, CurrentIframeIsNotLoadedError)
|
|
.then(function (response) { return response.result; });
|
|
};
|
|
ParentIframeDriverLink.prototype.sendConfirmationMessage = function (requestMsgId) {
|
|
sendConfirmationMessage({
|
|
requestMsgId: requestMsgId,
|
|
window: this.driverWindow,
|
|
});
|
|
};
|
|
ParentIframeDriverLink.prototype.onCommandExecuted = function (status) {
|
|
var msg = new CommandExecutedMessage(status);
|
|
hammerhead.eventSandbox.message.sendServiceMsg(msg, this.driverWindow);
|
|
};
|
|
ParentIframeDriverLink.prototype.hasPendingActionFlags = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var response;
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0: return [4 /*yield*/, sendMessageToDriver(new HasPendingActionFlagsMessage(), this.driverWindow, WAIT_FOR_IFRAME_DRIVER_RESPONSE_TIMEOUT, CurrentIframeIsNotLoadedError)];
|
|
case 1:
|
|
response = _a.sent();
|
|
return [2 /*return*/, response.result];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
return ParentIframeDriverLink;
|
|
}());
|
|
|
|
var messageSandbox$3 = hammerhead__default.eventSandbox.message;
|
|
var IframeNativeDialogTracker = /** @class */ (function (_super) {
|
|
__extends(IframeNativeDialogTracker, _super);
|
|
function IframeNativeDialogTracker(options) {
|
|
return _super.call(this, null, options) || this;
|
|
}
|
|
IframeNativeDialogTracker.prototype._defaultDialogHandler = function (type) {
|
|
messageSandbox$3.sendServiceMsg({
|
|
type: MESSAGE_TYPE.unexpectedDialog,
|
|
dialogType: type,
|
|
url: NativeDialogTracker._getPageUrl(),
|
|
}, window.top);
|
|
};
|
|
IframeNativeDialogTracker.prototype._addAppearedDialogs = function (type, text) {
|
|
messageSandbox$3.sendServiceMsg({
|
|
type: MESSAGE_TYPE.appearedDialog,
|
|
dialogType: type,
|
|
text: text,
|
|
url: NativeDialogTracker._getPageUrl(),
|
|
}, window.top);
|
|
};
|
|
IframeNativeDialogTracker.prototype._onHandlerError = function (type, message) {
|
|
messageSandbox$3.sendServiceMsg({
|
|
type: MESSAGE_TYPE.handlerError,
|
|
dialogType: type,
|
|
message: message,
|
|
url: NativeDialogTracker._getPageUrl(),
|
|
}, window.top);
|
|
};
|
|
return IframeNativeDialogTracker;
|
|
}(NativeDialogTracker));
|
|
|
|
var messageSandbox$4 = hammerhead.eventSandbox.message;
|
|
var IframeDriver = /** @class */ (function (_super) {
|
|
__extends(IframeDriver, _super);
|
|
function IframeDriver(testRunId, options) {
|
|
var _this = _super.call(this, testRunId, {}, {}, options) || this;
|
|
_this.lastParentDriverMessageId = null;
|
|
_this.parentDriverLink = new ParentIframeDriverLink(window.parent);
|
|
_this._initParentDriverListening();
|
|
_this.leftTopPoint = new AxisValues(0, 0);
|
|
return _this;
|
|
}
|
|
// Errors handling
|
|
IframeDriver.prototype._onJsError = function () {
|
|
// NOTE: do nothing because hammerhead sends js error to the top window directly
|
|
};
|
|
IframeDriver.prototype._onConsoleMessage = function () {
|
|
// NOTE: do nothing because hammerhead sends console messages to the top window directly
|
|
};
|
|
// NOTE: when the new page is opened in the iframe we send a message to the top window
|
|
// to start waiting for the new page is loaded
|
|
IframeDriver.prototype._onChildWindowOpened = function () {
|
|
messageSandbox$4.sendServiceMsg(new ChildWindowIsOpenedInFrameMessage(), window.top);
|
|
};
|
|
IframeDriver.prototype._stopInternal = function () {
|
|
messageSandbox$4.sendServiceMsg(new StopInternalFromFrameMessage(), window.top);
|
|
};
|
|
// Messaging between drivers
|
|
IframeDriver.prototype._initParentDriverListening = function () {
|
|
var _this = this;
|
|
hammerhead.eventSandbox.message.on(hammerhead.eventSandbox.message.SERVICE_MSG_RECEIVED_EVENT, function (e) {
|
|
var msg = e.message;
|
|
testcafeCore.pageUnloadBarrier
|
|
.wait(0)
|
|
.then(function () {
|
|
// NOTE: the parent driver repeats commands sent to a child driver if it doesn't get a confirmation
|
|
// from the child in time. However, confirmations sent by child drivers may be delayed when the browser
|
|
// is heavily loaded. That's why the child driver should ignore repeated messages from its parent.
|
|
if (msg.type === TYPE.executeCommand) {
|
|
if (_this.lastParentDriverMessageId === msg.id)
|
|
return;
|
|
_this.lastParentDriverMessageId = msg.id;
|
|
_this.readyPromise.then(function () {
|
|
_this.speed = msg.testSpeed;
|
|
_this.leftTopPoint = msg.leftTopPoint;
|
|
_this.parentDriverLink.sendConfirmationMessage(msg.id);
|
|
_this._onCommand(msg.command);
|
|
});
|
|
}
|
|
if (msg.type === TYPE.setNativeDialogHandler) {
|
|
_this.nativeDialogsTracker.setHandler(msg.dialogHandler);
|
|
_this._setNativeDialogHandlerInIframes(msg.dialogHandler);
|
|
}
|
|
});
|
|
});
|
|
};
|
|
// Commands handling
|
|
IframeDriver.prototype._onSwitchToMainWindowCommand = function (command) {
|
|
this._switchToMainWindow(command);
|
|
};
|
|
// Routing
|
|
IframeDriver.prototype._onReady = function (status) {
|
|
this.parentDriverLink.onCommandExecuted(status);
|
|
};
|
|
IframeDriver.prototype._isInCommandExecution = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
return __generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
if (!hammerhead.utils.dom.isCrossDomainWindows(window, window.parent)) return [3 /*break*/, 2];
|
|
return [4 /*yield*/, this.parentDriverLink.hasPendingActionFlags()];
|
|
case 1: return [2 /*return*/, _a.sent()];
|
|
case 2: return [2 /*return*/, this._hasPendingActionFlags(this.contextStorage)];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
IframeDriver.prototype._init = function () {
|
|
return __awaiter(this, void 0, void 0, function () {
|
|
var _a, id, dispatchProxylessEventUrl, inCommandExecution;
|
|
return __generator(this, function (_b) {
|
|
switch (_b.label) {
|
|
case 0: return [4 /*yield*/, this.parentDriverLink.establishConnection()];
|
|
case 1:
|
|
_a = _b.sent(), id = _a.id, dispatchProxylessEventUrl = _a.dispatchProxylessEventUrl;
|
|
this.contextStorage = new Storage(window, {
|
|
testRunId: id,
|
|
windowId: this.windowId,
|
|
proxyless: this.options.proxyless,
|
|
});
|
|
this.communicationUrls.dispatchProxylessEvent = dispatchProxylessEventUrl;
|
|
if (this._failIfClientCodeExecutionIsInterrupted())
|
|
return [2 /*return*/];
|
|
return [4 /*yield*/, this._isInCommandExecution()];
|
|
case 2:
|
|
inCommandExecution = _b.sent();
|
|
if (!inCommandExecution)
|
|
return [2 /*return*/];
|
|
this.contextStorage.setItem(this.COMMAND_EXECUTING_FLAG, false);
|
|
this.contextStorage.setItem(this.EXECUTING_IN_IFRAME_FLAG, false);
|
|
this._onReady(new DriverStatus({ isCommandResult: true }));
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
// API
|
|
IframeDriver.prototype.start = function () {
|
|
this.nativeDialogsTracker = new IframeNativeDialogTracker({
|
|
dialogHandler: this.options.dialogHandler,
|
|
proxyless: this.options.proxyless,
|
|
});
|
|
this.statusBar = new testCafeUI.IframeStatusBar();
|
|
var initializePromise = this._init();
|
|
this.readyPromise = hammerhead.Promise.all([this.readyPromise, initializePromise]);
|
|
};
|
|
return IframeDriver;
|
|
}(Driver));
|
|
|
|
var embeddingUtils = {
|
|
NodeSnapshot: NodeSnapshot,
|
|
ElementSnapshot: ElementSnapshot,
|
|
SelectorExecutor: SelectorExecutor,
|
|
};
|
|
|
|
var INTERNAL_PROPERTIES = {
|
|
testCafeDriver: '%testCafeDriver%',
|
|
testCafeIframeDriver: '%testCafeIframeDriver%',
|
|
testCafeEmbeddingUtils: '%testCafeEmbeddingUtils%',
|
|
testCafeDriverInstance: '%testCafeDriverInstance%',
|
|
};
|
|
|
|
var nativeMethods$7 = hammerhead__default.nativeMethods;
|
|
var evalIframeScript = hammerhead__default.EVENTS.evalIframeScript;
|
|
nativeMethods$7.objectDefineProperty(window, INTERNAL_PROPERTIES.testCafeDriver, { configurable: true, value: Driver });
|
|
nativeMethods$7.objectDefineProperty(window, INTERNAL_PROPERTIES.testCafeIframeDriver, { configurable: true, value: IframeDriver });
|
|
nativeMethods$7.objectDefineProperty(window, INTERNAL_PROPERTIES.testCafeEmbeddingUtils, { configurable: true, value: embeddingUtils });
|
|
// eslint-disable-next-line no-undef
|
|
hammerhead__default.on(evalIframeScript, function (e) { return initTestCafeClientDrivers(nativeMethods$7.contentWindowGetter.call(e.iframe), true); });
|
|
|
|
}(window['%hammerhead%'], window['%hammerhead%'].Promise, window['%testCafeCore%'], window['%testCafeAutomation%'], window['%testCafeUI%']));
|
|
|
|
}
|
|
|
|
initTestCafeClientDrivers(window);
|
|
})();
|