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 initTestCafeAutomation(window, isIFrameWithoutSrc) { var document = window.document; (function (hammerhead, Promise$e, testCafeCore, testCafeUI) { var hammerhead__default = 'default' in hammerhead ? hammerhead['default'] : hammerhead; Promise$e = Promise$e && Object.prototype.hasOwnProperty.call(Promise$e, 'default') ? Promise$e['default'] : Promise$e; var testCafeCore__default = 'default' in testCafeCore ? testCafeCore['default'] : testCafeCore; testCafeUI = testCafeUI && Object.prototype.hasOwnProperty.call(testCafeUI, 'default') ? testCafeUI['default'] : testCafeUI; var nativeMethods = hammerhead__default.nativeMethods; var MOUSE_EVENT_NAME_RE = /^((mouse\w+)|((dbl)?click)|(contextmenu))$/; var DRAG_EVENT_NAME_RE = /^((drag\w*)|(drop))$/; var KEY_EVENT_NAME_RE = /^key\w+$/; var INPUT_EVENT_NAME_RE = /^(before)?input$/; var FOCUS_EVENT_NAME_RE = /^(blur|(focus(in|out)?))$/; var POINTER_EVENT_NAME_RE = /^pointer\w+/; var DEFAULT_MOUSE_EVENT_DETAIL_PROP_VALUE = { click: 1, dblclick: 2, mousedown: 1, mouseup: 1, }; // NOTE: default e.buttons for left button pressed var DEFAULT_BUTTONS_PARAMETER = 1; var EVENT_CTORS = { MouseEvent: 'MouseEvent', PointerEvent: 'PointerEvent', KeyboardEvent: 'KeyboardEvent', InputEvent: 'InputEvent', FocusEvent: 'FocusEvent', }; var DispatchEventAutomation = /** @class */ (function () { function DispatchEventAutomation(element, eventName, options) { this.element = element; this.eventName = eventName; this.options = options; } DispatchEventAutomation.prototype.run = function () { var _a = this.options, bubbles = _a.bubbles, cancelable = _a.cancelable, detail = _a.detail, view = _a.view, buttons = _a.buttons; bubbles = bubbles !== false; cancelable = cancelable !== false; detail = detail || DEFAULT_MOUSE_EVENT_DETAIL_PROP_VALUE[this.eventName]; view = window; buttons = buttons === void 0 ? DEFAULT_BUTTONS_PARAMETER : buttons; // eslint-disable-next-line no-restricted-globals Object.assign(this.options, { bubbles: bubbles, cancelable: cancelable, detail: detail, view: view, buttons: buttons }); var Ctor = DispatchEventAutomation._getEventCtorByEventType(this.eventName, this.options.eventConstructor); if (Ctor) { var event_1 = new Ctor(this.eventName, this.options); this.element.dispatchEvent(event_1); } }; DispatchEventAutomation._getEventCtorByEventType = function (eventName, eventConstructor) { if (eventConstructor && typeof DispatchEventAutomation._getEventCtorFromWindow(eventConstructor) === 'function') { var Ctor = DispatchEventAutomation._getEventCtorFromNativeMethods(eventConstructor); if (Ctor && typeof Ctor === 'function') return Ctor; } if (MOUSE_EVENT_NAME_RE.test(eventName)) return DispatchEventAutomation._getEventCtorFromNativeMethods(EVENT_CTORS.MouseEvent); if (DRAG_EVENT_NAME_RE.test(eventName)) return DispatchEventAutomation._getEventCtorFromNativeMethods(EVENT_CTORS.MouseEvent); if (POINTER_EVENT_NAME_RE.test(eventName)) return DispatchEventAutomation._getEventCtorFromNativeMethods(EVENT_CTORS.PointerEvent); if (KEY_EVENT_NAME_RE.test(eventName)) return DispatchEventAutomation._getEventCtorFromNativeMethods(EVENT_CTORS.KeyboardEvent); if (INPUT_EVENT_NAME_RE.test(eventName)) return DispatchEventAutomation._getEventCtorFromNativeMethods(EVENT_CTORS.InputEvent); if (FOCUS_EVENT_NAME_RE.test(eventName)) return DispatchEventAutomation._getEventCtorFromNativeMethods(EVENT_CTORS.FocusEvent); return DispatchEventAutomation._getEventCtorFromNativeMethods('CustomEvent'); }; DispatchEventAutomation._getEventCtorFromNativeMethods = function (eventCtor) { var ctor = nativeMethods['Window' + eventCtor] || DispatchEventAutomation._getEventCtorFromWindow(eventCtor); return ctor; }; DispatchEventAutomation._getEventCtorFromWindow = function (eventCtor) { // @ts-ignore return window[eventCtor]; }; return DispatchEventAutomation; }()); /****************************************************************************** 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$e))(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 }; } } 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 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$1 = 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; function containsElement(elements, element) { if (elements.contains) return elements.contains(element); return some(elements, function (parent) { return parent.contains(element); }); } function findIframeByWindow(iframeWindow) { var iframes = []; find(document, '*', function (elem) { if (elem.tagName === 'IFRAME') iframes.push(elem); if (elem.shadowRoot) find(elem.shadowRoot, 'iframe', function (iframe) { return iframes.push(iframe); }); }); for (var i = 0; i < iframes.length; i++) { if (nativeMethods$1.contentWindowGetter.call(iframes[i]) === iframeWindow) return iframes[i]; } return null; } function isShadowElement(element) { return element && element.getRootNode && findDocument(element) !== element.getRootNode(); } function isNodeEqual(el1, el2) { return el1 === el2; } function getNodeText(el) { return nativeMethods$1.nodeTextContentGetter.call(el); } function getImgMapName(img) { return img.useMap.substring(1); } function getDocumentElement(win) { return win.document.documentElement; } function isDocumentElement(el) { return el === document.documentElement; } 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 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; function getWindowDimensions(window) { return new BoundaryValues(0, getWidth(window), getHeight(window), 0); } function isFixedElement(node) { return isElementNode(node) && styleUtils.get(node, 'position') === 'fixed'; } var shadowUI = hammerhead__default.shadowUI; var nativeMethods$2 = hammerhead__default.nativeMethods; 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 hiddenReasons = { notElementOrTextNode: function (targetType) { return "\n The ".concat(targetType, " is neither a DOM element nor a text node.\n "); }, elOutsideBounds: function (target, targetType) { return "\n The ".concat(targetType, " (").concat(target, ") is located outside the the layout viewport.\n "); }, elHasWidthOrHeightZero: function (target, targetType, width, height) { return "\n The ".concat(targetType, " (").concat(target, ") is too small to be visible: ").concat(width, "px x ").concat(height, "px.\n "); }, elHasDisplayNone: function (target, targetType) { return "\n The ".concat(targetType, " (").concat(target, ") is invisible. \n The value of its 'display' property is 'none'.\n "); }, parentHasDisplayNone: function (target, targetType, parent) { return "\n The ".concat(targetType, " (").concat(target, ") is invisible. \n It descends from an element that has the 'display: none' property (").concat(parent, ").\n "); }, elHasVisibilityHidden: function (target, targetType) { return "\n The ".concat(targetType, " (").concat(target, ") is invisible.\n The value of its 'visibility' property is 'hidden'.\n "); }, parentHasVisibilityHidden: function (target, targetType, parent) { return "\n The ".concat(targetType, " (").concat(target, ") is invisible.\n It descends from an element that has the 'visibility: hidden' property (").concat(parent, ").\n "); }, elHasVisibilityCollapse: function (target, targetType) { return "\n The ".concat(targetType, " (").concat(target, ") is invisible.\n The value of its 'visibility' property is 'collapse'.\n "); }, parentHasVisibilityCollapse: function (target, targetType, parent) { return "\n The ".concat(targetType, " (").concat(target, ") is invisible.\n It descends from an element that has the 'visibility: collapse' property (").concat(parent, ").\n "); }, elNotRendered: function (target, targetType) { return "\n The ".concat(targetType, " (").concat(target, ") has not been rendered.\n "); }, optionNotVisible: function (target, targetType, parent) { return "\n The ".concat(targetType, " (").concat(target, ") is invisible. \n The parent element (").concat(parent, ") is collapsed, and its length is shorter than 2.\n "); }, mapContainerNotVisible: function (target, containerHiddenReason) { return "\n The action target (".concat(target, ") is invisible because ").concat(containerHiddenReason, "\n "); }, }; var htmlUtils = hammerhead__default.utils.html; var nativeMethods$3 = hammerhead__default.nativeMethods; var MAX_TEXT_CONTENT_LENGTH = 10; function truncateString(str, length, omission) { if (omission === void 0) { omission = '...'; } if (str.length < length) return str; return str.substring(0, length - omission.length) + omission; } function stringifyElement(element) { if (!element) return ''; var emptyElement = nativeMethods$3.cloneNode.call(element); var outerHtml = htmlUtils.cleanUpHtml(nativeMethods$3.elementOuterHTMLGetter.call(emptyElement)); var text = truncateString(nativeMethods$3.nodeTextContentGetter.call(element), MAX_TEXT_CONTENT_LENGTH); var children = nativeMethods$3.elementChildrenGetter.call(element); if (nativeMethods$3.htmlCollectionLengthGetter.call(children) > 0) return outerHtml.replace('>...".concat(text, "= 0 && maxX >= offsetX) && (typeof offsetY === 'undefined' || offsetY >= 0 && maxY >= offsetY); } function getClientPosition(el) { var _a = getOffsetPosition(el), left = _a.left, top = _a.top; var clientCoords = offsetToClientCoords({ x: left, y: top }); clientCoords.x = Math.round(clientCoords.x); clientCoords.y = Math.round(clientCoords.y); return clientCoords; } function getWindowPosition() { var x = window.screenLeft || window.screenX; var y = window.screenTop || window.screenY; return new AxisValues(x, y); } function getSubHiddenReason(reason) { return reason.replace(/.*The/, 'its'); } function getElOutsideBoundsReason(el, targetType) { if (targetType === void 0) { targetType = 'action target'; } var strEl = stringifyElement(el); if (isMapElement(el)) { var mapContainer = getMapContainer(closest(el, 'map')); var containerHiddenReason = getElOutsideBoundsReason(mapContainer, 'container') || ''; var containerError = getSubHiddenReason(containerHiddenReason); return hiddenReasons.mapContainerNotVisible(strEl, containerError); } return hiddenReasons.elOutsideBounds(strEl, targetType); } function getAutomationPoint(element, offset) { return hammerhead.Promise.resolve(isDocumentElement(element)) .then(function (isDocEl) { if (isDocEl) return new AxisValues(0, 0); var roundFn = hammerhead.utils.browser.isFirefox ? Math.ceil : Math.round; return hammerhead.Promise.resolve(getOffsetPosition(element, roundFn)) .then(function (elementOffset) { return AxisValues.create(elementOffset); }); }) .then(function (point) { return point.add(offset); }); } var SCROLLABLE_OVERFLOW_STYLE_RE = /auto|scroll|hidden/i; var DEFAULT_IE_SCROLLABLE_OVERFLOW_STYLE_VALUE = 'visible'; function getScrollable(el) { var overflowX = get(el, 'overflowX'); var overflowY = get(el, 'overflowY'); var scrollableHorizontally = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowX); var scrollableVertically = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowY); // IE11 and MS Edge bug: There are two properties: overflow-x and overflow-y. // If one property is set so that the browser may show scrollbars (`auto` or `scroll`) and the second one is set to 'visible', // then the second one will work as if it had the 'auto' value. if (hammerhead.utils.browser.isIE) { scrollableHorizontally = scrollableHorizontally || scrollableVertically && overflowX === DEFAULT_IE_SCROLLABLE_OVERFLOW_STYLE_VALUE; scrollableVertically = scrollableVertically || scrollableHorizontally && overflowY === DEFAULT_IE_SCROLLABLE_OVERFLOW_STYLE_VALUE; } return new AxisValues(scrollableHorizontally, scrollableVertically); } function hasBodyScroll(el) { var overflowX = get(el, 'overflowX'); var overflowY = get(el, 'overflowY'); var scrollableHorizontally = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowX); var scrollableVertically = SCROLLABLE_OVERFLOW_STYLE_RE.test(overflowY); var documentElement = findDocument(el).documentElement; var bodyScrollHeight = el.scrollHeight; if (hammerhead.utils.browser.isChrome || hammerhead.utils.browser.isFirefox || hammerhead.utils.browser.isSafari) { var bodyTop = el.getBoundingClientRect().top; var documentTop = documentElement.getBoundingClientRect().top; bodyScrollHeight = bodyScrollHeight - documentTop + bodyTop; } return (scrollableHorizontally || scrollableVertically) && bodyScrollHeight > documentElement.scrollHeight; } function hasHTMLElementScroll(el) { var overflowX = get(el, 'overflowX'); var overflowY = get(el, 'overflowY'); //T303226 if (overflowX === 'hidden' && overflowY === 'hidden') return false; var hasHorizontalScroll = el.scrollHeight > el.clientHeight; var hasVerticalScroll = el.scrollWidth > el.clientWidth; if (hasHorizontalScroll || hasVerticalScroll) return true; //T174562 - wrong scrolling in iframes without src and others iframes var body = el.getElementsByTagName('body')[0]; if (!body) return false; if (hasBodyScroll(body)) return false; var clientWidth = Math.min(el.clientWidth, body.clientWidth); var clientHeight = Math.min(el.clientHeight, body.clientHeight); return body.scrollHeight > clientHeight || body.scrollWidth > clientWidth; } function hasScroll(el) { if (isBodyElement(el)) return hasBodyScroll(el); if (isHtmlElement(el)) return hasHTMLElementScroll(el); var scrollable = getScrollable(el); if (!scrollable.x && !scrollable.y) return false; var hasVerticalScroll = scrollable.y && el.scrollHeight > el.clientHeight; var hasHorizontalScroll = scrollable.x && el.scrollWidth > el.clientWidth; return hasHorizontalScroll || hasVerticalScroll; } function getScrollableParents(element) { var parentsArray = getParents(element); if (isElementInIframe(element)) { var iframe = getIframeByElement(element); if (iframe) { var iFrameParents = getParents(iframe); parentsArray.concat(iFrameParents); } } return hammerhead.nativeMethods.arrayFilter.call(parentsArray, hasScroll); } function convertToClient(element, point) { return __awaiter(this, void 0, void 0, function () { var elementScroll, hasScroll$1; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, getElementScroll(element)]; case 1: elementScroll = _a.sent(); hasScroll$1 = hasScroll(element); if (!/html/i.test(element.tagName) && hasScroll$1) { point.x -= elementScroll.left; point.y -= elementScroll.top; } return [2 /*return*/, offsetToClientCoords(point)]; } }); }); } function getDevicePoint(clientPoint) { if (!clientPoint) return null; var windowPosition = getWindowPosition(); var screenLeft = windowPosition.x; var screenTop = windowPosition.y; var x = screenLeft + clientPoint.x; var y = screenTop + clientPoint.y; return new AxisValues(x, y); } 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 positionUtils = testCafeCore__default.positionUtils; function getElementFromPoint$1(point, underTopShadowUIElement) { if (underTopShadowUIElement === void 0) { underTopShadowUIElement = false; } return testCafeUI.hide(underTopShadowUIElement) .then(function () { var topElement = positionUtils.getElementFromPoint(point); return testCafeUI.show(underTopShadowUIElement) .then(function () { return topElement; }); }); } // @ts-ignore function ensureImageMap(imgElement, areaElement) { return hammerhead.Promise.resolve(closest(areaElement, 'map')) .then(function (mapElement) { return mapElement && mapElement.name === getImgMapName(imgElement) ? areaElement : imgElement; }); } function findElementOrNonEmptyChildFromPoint(point, element) { return hammerhead.Promise.resolve(getElementFromPoint(point)) .then(function (topElement) { return hammerhead.Promise.resolve(containsElement(element, topElement)) .then(function (containsEl) { return containsEl && getNodeText(topElement); }) .then(function (isNonEmptyChild) { return isNonEmptyChild || topElement && isNodeEqual(topElement, element) ? topElement : null; }); }); } function correctTopElementByExpectedElement(topElement, expectedElement) { if (!expectedElement || !topElement || isNodeEqual(topElement, expectedElement)) return topElement; var isTREFElement = getTagName(expectedElement) === 'tref'; // NOTE: 'document.elementFromPoint' can't find these types of elements if (isTREFElement) return expectedElement; // NOTE: T299665 - Incorrect click automation for images with an associated map element in Firefox // All browsers return the element from document.getElementFromPoint, but // Firefox returns the element. We should accomplish this for Firefox as well. var isImageMapArea = getTagName(expectedElement) === 'area' && isImgElement(topElement); if (hammerhead.utils.browser.isFirefox && isImageMapArea) return ensureImageMap(topElement, expectedElement); // NOTE: try to find a multi-line link by its rectangle (T163678) return hammerhead.Promise.resolve(closest(expectedElement, 'a')) .then(function (anchor) { return !!anchor; }) .then(function (isLinkOrChildExpected) { if (!isLinkOrChildExpected) return false; return hammerhead.Promise.resolve(containsElement(expectedElement, topElement)) .then(function (containsElement) { return containsElement && getNodeText(topElement); }) .then(function (isTopElementChildOfLink) { return !isTopElementChildOfLink && getNodeText(expectedElement); }); }) .then(function (shouldSearchForMultilineLink) { if (!shouldSearchForMultilineLink) return topElement; return hammerhead.Promise.resolve(getClientDimensions(expectedElement)) .then(function (linkRect) { return findElementOrNonEmptyChildFromPoint({ x: linkRect.right - 1, y: linkRect.top + 1 }, expectedElement) .then(function (el) { return el || findElementOrNonEmptyChildFromPoint({ x: linkRect.left + 1, y: linkRect.bottom - 1 }, expectedElement); }) .then(function (el) { return el || topElement; }); }); }); } function getElementFromPoint$2(point, win, expectedEl) { return getElementFromPoint$1(point) .then(function (topElement) { // NOTE: when trying to get an element by elementFromPoint in iframe and the target // element is under any of shadow-ui elements, you will get null (only in IE). // In this case, you should hide a top window's shadow-ui root to obtain an element. var resChain = hammerhead.Promise.resolve(topElement); if (!topElement && hammerhead.utils.dom.isIframeWindow(win || window) && point.x > 0 && point.y > 0) resChain = resChain.then(function () { return getElementFromPoint$1(point, true); }); return resChain.then(function (element) { return correctTopElementByExpectedElement(element, expectedEl); }); }); } // ------------------------------------------------------------- // 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 ACTION_STEP_DELAY_DEFAULT = 10; var MAX_MOUSE_ACTION_STEP_DELAY = 400; var MAX_KEY_ACTION_STEP_DELAY = 200; // We use an exponential function to calculate the cursor // speed according to general test speed // cursorSpeed = (maxSpeed * k) ^ speed / k var MAX_CURSOR_SPEED = 100; // pixels/ms var MAX_DRAGGING_SPEED = 4; // pixels/ms var CURSOR_FACTOR = 4; var AutomationSettings = /** @class */ (function () { function AutomationSettings(speed) { this._speedFactor = speed || 1; } Object.defineProperty(AutomationSettings.prototype, "mouseActionStepDelay", { get: function () { return this._speedFactor === 1 ? ACTION_STEP_DELAY_DEFAULT : (1 - this._speedFactor) * MAX_MOUSE_ACTION_STEP_DELAY; }, enumerable: false, configurable: true }); Object.defineProperty(AutomationSettings.prototype, "keyActionStepDelay", { get: function () { return this._speedFactor === 1 ? ACTION_STEP_DELAY_DEFAULT : (1 - this._speedFactor) * MAX_KEY_ACTION_STEP_DELAY; }, enumerable: false, configurable: true }); Object.defineProperty(AutomationSettings.prototype, "cursorSpeed", { get: function () { return Math.pow(MAX_CURSOR_SPEED * CURSOR_FACTOR, this._speedFactor) / CURSOR_FACTOR; }, enumerable: false, configurable: true }); Object.defineProperty(AutomationSettings.prototype, "draggingSpeed", { get: function () { return Math.pow(MAX_DRAGGING_SPEED * CURSOR_FACTOR, this._speedFactor) / CURSOR_FACTOR; }, enumerable: false, configurable: true }); return AutomationSettings; }()); var Promise = hammerhead__default.Promise; var nativeMethods$4 = hammerhead__default.nativeMethods; function delay (ms) { return new Promise(function (resolve) { return nativeMethods$4.setTimeout.call(window, resolve, ms); }); } function nextTick() { return delay(0); } // ------------------------------------------------------------- // 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; }()); // ------------------------------------------------------------- // 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); } var lastHoveredElement = null; var lastHoveredElementHolder = { get: function () { return lastHoveredElement; }, set: function (element) { lastHoveredElement = element; }, }; var Promise$1 = hammerhead__default.Promise; var nativeMethods$5 = hammerhead__default.nativeMethods; var listeners = hammerhead__default.eventSandbox.listeners; var browserUtils$1 = hammerhead__default.utils.browser; // Imported form the hammerhead var BUTTON = hammerhead__default.utils.event.BUTTON; var BUTTONS_PARAMETER = hammerhead__default.utils.event.BUTTONS_PARAMETER; var DOM_EVENTS = hammerhead__default.utils.event.DOM_EVENTS; var WHICH_PARAMETER = hammerhead__default.utils.event.WHICH_PARAMETER; var preventDefault = hammerhead__default.utils.event.preventDefault; 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*/]; } }); }); } function times(n, iterator) { return __awaiter(this, void 0, void 0, function () { var i; return __generator(this, function (_a) { switch (_a.label) { case 0: i = 0; _a.label = 1; case 1: if (!(i < n)) return [3 /*break*/, 4]; return [4 /*yield*/, iterator(i)]; case 2: _a.sent(); _a.label = 3; case 3: i++; return [3 /*break*/, 1]; case 4: return [2 /*return*/]; } }); }); } function isIframeWindow(window) { return window.top !== window; } var Promise$2 = hammerhead__default.Promise; var messageSandbox = hammerhead__default.eventSandbox.message; function sendRequestToFrame(msg, responseCmd, receiverWindow) { return new Promise$2(function (resolve) { function onMessage(e) { if (e.message.cmd === responseCmd) { messageSandbox.off(messageSandbox.SERVICE_MSG_RECEIVED_EVENT, onMessage); resolve(e.message); } } messageSandbox.on(messageSandbox.SERVICE_MSG_RECEIVED_EVENT, onMessage); messageSandbox.sendServiceMsg(msg, receiverWindow); }); } // @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 EventEmitter$1 = EventEmitter; var listeners$1 = hammerhead.eventSandbox.listeners; var ScrollController = /** @class */ (function () { function ScrollController() { this.initialized = false; this.stopPropagationFlag = false; this.events = new EventEmitter$1(); } ScrollController.prototype._internalListener = function (event, dispatched, preventEvent, cancelHandlers, stopPropagation) { this.events.emit('scroll', event); if (this.stopPropagationFlag) { cancelHandlers(); stopPropagation(); } }; ScrollController.prototype.init = function () { var _this = this; if (this.initialized) return; this.initialized = true; listeners$1.initElementListening(window, ['scroll']); listeners$1.addFirstInternalEventBeforeListener(window, ['scroll'], function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } return _this._internalListener.apply(_this, args); }); }; ScrollController.prototype.waitForScroll = function (scrollElement) { var _this = this; var promiseResolver = null; var promise = new hammerhead.Promise(function (resolve) { promiseResolver = resolve; }); promise.cancel = function () { return _this.events.off('scroll', promiseResolver); }; if (this.initialized) this.handleScrollEvents(scrollElement, promiseResolver); else promiseResolver(); return promise; }; ScrollController.prototype.handleScrollEvents = function (el, handler) { var _this = this; this.events.once('scroll', handler); if (isShadowElement(el)) { listeners$1.initElementListening(el, ['scroll']); listeners$1.addFirstInternalEventBeforeListener(el, ['scroll'], function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } _this._internalListener.apply(_this, args); listeners$1.cancelElementListening(el); }); } }; ScrollController.prototype.stopPropagation = function () { this.stopPropagationFlag = true; }; ScrollController.prototype.enablePropagation = function () { this.stopPropagationFlag = false; }; return ScrollController; }()); var scrollController = new ScrollController(); var DEFAULT_MAX_SCROLL_MARGIN = 50; var SCROLL_MARGIN_INCREASE_STEP = 20; var ScrollAutomation = /** @class */ (function () { function ScrollAutomation(element, scrollOptions, maxScrollMargin) { this._element = element; this._offsets = new AxisValues(scrollOptions.offsetX, scrollOptions.offsetY); this._scrollToCenter = !!scrollOptions.scrollToCenter; this._skipParentFrames = !!scrollOptions.skipParentFrames; this._maxScrollMargin = maxScrollMargin || { left: DEFAULT_MAX_SCROLL_MARGIN, top: DEFAULT_MAX_SCROLL_MARGIN }; this._scrollWasPerformed = false; } ScrollAutomation._isScrollValuesChanged = function (scrollElement, originalScroll) { return getScrollLeft(scrollElement) !== originalScroll.left || getScrollTop(scrollElement) !== originalScroll.top; }; ScrollAutomation.prototype._setScroll = function (element, _a) { var _this = this; var left = _a.left, top = _a.top; var scrollElement = isHtmlElement(element) ? findDocument(element) : element; var originalScroll = { left: getScrollLeft(scrollElement), top: getScrollTop(scrollElement), }; left = Math.max(left, 0); top = Math.max(top, 0); var scrollPromise = scrollController.waitForScroll(scrollElement); setScrollLeft(scrollElement, left); setScrollTop(scrollElement, top); if (!ScrollAutomation._isScrollValuesChanged(scrollElement, originalScroll)) { // @ts-ignore scrollPromise.cancel(); return hammerhead.Promise.resolve(); } scrollPromise = scrollPromise.then(function () { if (!_this._scrollWasPerformed) _this._scrollWasPerformed = ScrollAutomation._isScrollValuesChanged(scrollElement, originalScroll); }); return scrollPromise; }; ScrollAutomation.prototype._getScrollToPoint = function (dimensions, point, maxScrollMargin) { var horizontalCenter = Math.floor(dimensions.width / 2); var verticalCenter = Math.floor(dimensions.height / 2); var leftScrollMargin = this._scrollToCenter ? horizontalCenter : Math.min(maxScrollMargin.left, horizontalCenter); var topScrollMargin = this._scrollToCenter ? verticalCenter : Math.min(maxScrollMargin.top, verticalCenter); var _a = dimensions.scroll, left = _a.left, top = _a.top; var needForwardScrollLeft = point.x >= left + dimensions.width - leftScrollMargin; var needBackwardScrollLeft = point.x <= left + leftScrollMargin; var needForwardScrollTop = point.y >= top + dimensions.height - topScrollMargin; var needBackwardScrollTop = point.y <= top + topScrollMargin; if (needForwardScrollLeft) left = point.x - dimensions.width + leftScrollMargin; else if (needBackwardScrollLeft) left = point.x - leftScrollMargin; if (needForwardScrollTop) top = point.y - dimensions.height + topScrollMargin; else if (needBackwardScrollTop) top = point.y - topScrollMargin; return { left: left, top: top }; }; ScrollAutomation.prototype._getScrollToFullChildView = function (parentDimensions, childDimensions, maxScrollMargin) { var fullViewScroll = { left: null, top: null }; var canShowFullElementWidth = parentDimensions.width >= childDimensions.width; var canShowFullElementHeight = parentDimensions.height >= childDimensions.height; var relativePosition = calcRelativePosition(childDimensions, parentDimensions); if (canShowFullElementWidth) { var availableLeftScrollMargin = parentDimensions.width - childDimensions.width; var leftScrollMargin = Math.min(maxScrollMargin.left, availableLeftScrollMargin); if (this._scrollToCenter) leftScrollMargin = availableLeftScrollMargin / 2; if (relativePosition.left < leftScrollMargin) fullViewScroll.left = Math.round(parentDimensions.scroll.left + relativePosition.left - leftScrollMargin); else if (relativePosition.right < leftScrollMargin) { fullViewScroll.left = Math.round(parentDimensions.scroll.left + Math.min(relativePosition.left, -relativePosition.right) + leftScrollMargin); } } if (canShowFullElementHeight) { var availableTopScrollMargin = parentDimensions.height - childDimensions.height; var topScrollMargin = Math.min(maxScrollMargin.top, availableTopScrollMargin); if (this._scrollToCenter) topScrollMargin = availableTopScrollMargin / 2; if (relativePosition.top < topScrollMargin) fullViewScroll.top = Math.round(parentDimensions.scroll.top + relativePosition.top - topScrollMargin); else if (relativePosition.bottom < topScrollMargin) { fullViewScroll.top = Math.round(parentDimensions.scroll.top + Math.min(relativePosition.top, -relativePosition.bottom) + topScrollMargin); } } return fullViewScroll; }; ScrollAutomation._getChildPoint = function (parentDimensions, childDimensions, offsets) { return AxisValues.create(childDimensions) .sub(AxisValues.create(parentDimensions)) .add(AxisValues.create(parentDimensions.scroll)) .add(AxisValues.create(childDimensions.border)) .add(offsets); }; ScrollAutomation.prototype._getScrollPosition = function (parentDimensions, childDimensions, offsets, maxScrollMargin) { var childPoint = ScrollAutomation._getChildPoint(parentDimensions, childDimensions, offsets); var scrollToPoint = this._getScrollToPoint(parentDimensions, childPoint, maxScrollMargin); var scrollToFullView = this._getScrollToFullChildView(parentDimensions, childDimensions, maxScrollMargin); return { left: Math.max(scrollToFullView.left === null ? scrollToPoint.left : scrollToFullView.left, 0), top: Math.max(scrollToFullView.top === null ? scrollToPoint.top : scrollToFullView.top, 0), }; }; ScrollAutomation._getChildPointAfterScroll = function (parentDimensions, childDimensions, currentScroll, offsets) { return AxisValues.create(childDimensions) .add(AxisValues.create(parentDimensions.scroll)) .sub(AxisValues.create(currentScroll)) .add(offsets); }; ScrollAutomation.prototype._isChildFullyVisible = function (parentDimensions, childDimensions, offsets) { var childPoint = ScrollAutomation._getChildPointAfterScroll(parentDimensions, childDimensions, parentDimensions.scroll, offsets); var zeroMargin = { left: 0, top: 0 }; var _a = this._getScrollPosition(parentDimensions, childDimensions, offsets, zeroMargin), left = _a.left, top = _a.top; return !this._isTargetElementObscuredInPoint(childPoint) && left === parentDimensions.scroll.left && top === parentDimensions.scroll.top; }; ScrollAutomation.prototype._scrollToChild = function (parent, child, offsets) { var parentDimensions = getClientDimensions(parent); var childDimensions = getClientDimensions(child); var windowWidth = getInnerWidth(window); var windowHeight = getInnerHeight(window); var scrollPos = parentDimensions.scroll; var needScroll = !this._isChildFullyVisible(parentDimensions, childDimensions, offsets); while (needScroll) { scrollPos = this._getScrollPosition(parentDimensions, childDimensions, offsets, this._maxScrollMargin); var childPoint = ScrollAutomation._getChildPointAfterScroll(parentDimensions, childDimensions, scrollPos, offsets); var isTargetObscured = this._isTargetElementObscuredInPoint(childPoint); this._maxScrollMargin.left += SCROLL_MARGIN_INCREASE_STEP; if (this._maxScrollMargin.left >= windowWidth) { this._maxScrollMargin.left = DEFAULT_MAX_SCROLL_MARGIN; this._maxScrollMargin.top += SCROLL_MARGIN_INCREASE_STEP; } needScroll = isTargetObscured && this._maxScrollMargin.top < windowHeight; } this._maxScrollMargin = { left: DEFAULT_MAX_SCROLL_MARGIN, top: DEFAULT_MAX_SCROLL_MARGIN }; return this._setScroll(parent, scrollPos); }; ScrollAutomation.prototype._scrollElement = function () { if (!hasScroll(this._element)) return hammerhead.Promise.resolve(); var elementDimensions = getClientDimensions(this._element); var scroll = this._getScrollToPoint(elementDimensions, this._offsets, this._maxScrollMargin); return this._setScroll(this._element, scroll); }; ScrollAutomation.prototype._scrollParents = function () { var _this = this; var parents = getScrollableParents(this._element); var currentChild = this._element; var scrollLeft = getScrollLeft(currentChild); var scrollTop = getScrollTop(currentChild); var currentOffset = AxisValues.create(this._offsets).sub(new AxisValues(scrollLeft, scrollTop).round()); var childDimensions = null; var parentDimensions = null; var scrollParentsPromise = times(parents.length, function (i) { return _this._scrollToChild(parents[i], currentChild, currentOffset) .then(function () { childDimensions = getClientDimensions(currentChild); parentDimensions = getClientDimensions(parents[i]); currentOffset.add(AxisValues.create(childDimensions)) .sub(AxisValues.create(parentDimensions)) .add(AxisValues.create(parentDimensions.border)); currentChild = parents[i]; }); }); var state = { scrollWasPerformed: this._scrollWasPerformed, offsetX: currentOffset.x, offsetY: currentOffset.y, maxScrollMargin: this._maxScrollMargin, }; if (!sendRequestToFrame) return scrollParentsPromise.then(function () { return state; }); return scrollParentsPromise .then(function () { if (_this._skipParentFrames || !isIframeWindow(window)) return; state.cmd = ScrollAutomation.SCROLL_REQUEST_CMD; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, consistent-return return sendRequestToFrame(state, ScrollAutomation.SCROLL_RESPONSE_CMD, window.parent); }) .then(function () { return _this._scrollWasPerformed; }); }; ScrollAutomation._getFixedAncestorOrSelf = function (element) { return findParent(element, true, isFixedElement); }; ScrollAutomation.prototype._isTargetElementObscuredInPoint = function (point) { var elementInPoint = getElementFromPoint(point); if (!elementInPoint) return false; var fixedElement = ScrollAutomation._getFixedAncestorOrSelf(elementInPoint); return !!fixedElement && !fixedElement.contains(this._element); }; ScrollAutomation.prototype.run = function () { var _this = this; return this._scrollElement() .then(function () { return _this._scrollParents(); }); }; ScrollAutomation.SCROLL_REQUEST_CMD = 'automation|scroll|request'; ScrollAutomation.SCROLL_RESPONSE_CMD = 'automation|scroll|response'; return ScrollAutomation; }()); var browserUtils$2 = hammerhead__default.utils.browser; var MoveEventSequenceBase = /** @class */ (function () { function MoveEventSequenceBase(_a) { var moveEvent = _a.moveEvent; this.dragAndDropMode = false; this.dropAllowed = false; this.moveEvent = moveEvent; } MoveEventSequenceBase.prototype.setup = function () { this.dragAndDropMode = false; this.dropAllowed = false; }; MoveEventSequenceBase.prototype.leaveElement = function ( /* currentElement, prevElement, commonAncestor, options */) { }; MoveEventSequenceBase.prototype.move = function ( /* element, options */) { }; MoveEventSequenceBase.prototype.enterElement = function ( /* currentElement, prevElement, commonAncestor, options */) { }; MoveEventSequenceBase.prototype.dragAndDrop = function ( /* dragElement, currentElement, prevElement, options, dragDataStore */) { }; MoveEventSequenceBase.prototype.teardown = function ( /* currentElement, eventOptions, prevElement */) { }; MoveEventSequenceBase.prototype.run = function (currentElement, prevElement, options, dragElement, dragDataStore) { // NOTE: if last hovered element was in an iframe that has been removed, IE // raises an exception when we try to compare it with the current element var prevElementInDocument = prevElement && testCafeCore.domUtils.isElementInDocument(prevElement); var prevElementInRemovedIframe = prevElement && testCafeCore.domUtils.isElementInIframe(prevElement) && !testCafeCore.domUtils.getIframeByElement(prevElement); if (!prevElementInDocument || prevElementInRemovedIframe) prevElement = null; var elementChanged = currentElement !== prevElement; var commonAncestor = elementChanged ? testCafeCore.domUtils.getCommonAncestor(currentElement, prevElement) : null; this.setup(); if (elementChanged && !!prevElement) this.leaveElement(currentElement, prevElement, commonAncestor, options); if (browserUtils$2.isIE) this.move(currentElement, options); if (elementChanged && testCafeCore.domUtils.isElementInDocument(currentElement)) this.enterElement(currentElement, prevElement, commonAncestor, options); if (!browserUtils$2.isIE) this.move(currentElement, options); this.dragAndDrop(dragElement, currentElement, prevElement, options, dragDataStore); this.teardown(currentElement, options, prevElement); var dragAndDropMode = this.dragAndDropMode; var dropAllowed = this.dropAllowed; this.dragAndDropMode = false; this.dropAllowed = false; return { dragAndDropMode: dragAndDropMode, dropAllowed: dropAllowed }; }; return MoveEventSequenceBase; }()); var eventSimulator = hammerhead__default.eventSandbox.eventSimulator; var extend = hammerhead__default.utils.extend; var nativeMethods$6 = hammerhead__default.nativeMethods; var MoveBehaviour = /** @class */ (function () { function MoveBehaviour() { } MoveBehaviour.leaveElement = function (currentElement, prevElement, commonAncestor, options) { eventSimulator.mouseout(prevElement, extend({ relatedTarget: currentElement }, options)); var currentParent = prevElement; while (currentParent && currentParent !== commonAncestor) { eventSimulator.mouseleave(currentParent, extend({ relatedTarget: currentElement }, options)); currentParent = nativeMethods$6.nodeParentNodeGetter.call(currentParent); } }; MoveBehaviour.enterElement = function (currentElement, prevElement, commonAncestor, options) { eventSimulator.mouseover(currentElement, extend({ relatedTarget: prevElement }, options)); var currentParent = currentElement; var mouseenterElements = []; while (currentParent && currentParent !== commonAncestor) { mouseenterElements.push(currentParent); currentParent = testCafeCore.domUtils.getParentExceptShadowRoot(currentParent); } for (var i = mouseenterElements.length - 1; i > -1; i--) eventSimulator.mouseenter(mouseenterElements[i], extend({ relatedTarget: prevElement }, options)); }; MoveBehaviour.move = function (moveEvent, element, options) { eventSimulator[moveEvent](element, options); }; return MoveBehaviour; }()); var DragAndDropBehavior = /** @class */ (function () { function DragAndDropBehavior() { } DragAndDropBehavior.dragAndDrop = function (dragElement, currentElement, prevElement, options) { eventSimulator.drag(dragElement, options); var currentElementChanged = currentElement !== prevElement; if (currentElementChanged) { if (testCafeCore.domUtils.isElementInDocument(currentElement)) { options.relatedTarget = prevElement; eventSimulator.dragenter(currentElement, options); } if (prevElement) { options.relatedTarget = currentElement; eventSimulator.dragleave(prevElement, options); } } return !eventSimulator.dragover(currentElement, options); }; return DragAndDropBehavior; }()); var eventSimulator$1 = hammerhead__default.eventSandbox.eventSimulator; var TOUCH_MOVE_EVENT_NAME = 'touchmove'; var MoveEventSequence = /** @class */ (function (_super) { __extends(MoveEventSequence, _super); function MoveEventSequence(options) { var _this = _super.call(this, options) || this; _this.holdLeftButton = options.holdLeftButton; return _this; } MoveEventSequence.prototype.leaveElement = function (currentElement, prevElement, commonAncestor, options) { MoveBehaviour.leaveElement(currentElement, prevElement, commonAncestor, options); }; MoveEventSequence.prototype.enterElement = function (currentElement, prevElement, commonAncestor, options) { MoveBehaviour.enterElement(currentElement, prevElement, commonAncestor, options); }; MoveEventSequence.prototype.move = function (element, options) { if (this._needEmulateMoveEvent()) MoveBehaviour.move(this.moveEvent, element, options); }; MoveEventSequence.prototype.teardown = function (currentElement, eventOptions, prevElement) { // NOTE: we need to add an extra 'mousemove' if the element was changed because sometimes // the client script requires several 'mousemove' events for an element (T246904) if (this._needEmulateMoveEvent() && testCafeCore.domUtils.isElementInDocument(currentElement) && currentElement !== prevElement) eventSimulator$1[this.moveEvent](currentElement, eventOptions); }; MoveEventSequence.prototype._needEmulateMoveEvent = function () { return this.moveEvent !== TOUCH_MOVE_EVENT_NAME || this.holdLeftButton; }; return MoveEventSequence; }(MoveEventSequenceBase)); var DragAndDropMoveEventSequence = /** @class */ (function (_super) { __extends(DragAndDropMoveEventSequence, _super); function DragAndDropMoveEventSequence() { return _super !== null && _super.apply(this, arguments) || this; } DragAndDropMoveEventSequence.prototype.setup = function () { _super.prototype.setup.call(this); this.dragAndDropMode = true; }; DragAndDropMoveEventSequence.prototype.dragAndDrop = function (dragElement, currentElement, prevElement, options) { this.dropAllowed = DragAndDropBehavior.dragAndDrop(dragElement, currentElement, prevElement, options); }; return DragAndDropMoveEventSequence; }(MoveEventSequenceBase)); var eventSimulator$2 = hammerhead__default.eventSandbox.eventSimulator; var DragAndDropFirstMoveEventSequence = /** @class */ (function (_super) { __extends(DragAndDropFirstMoveEventSequence, _super); function DragAndDropFirstMoveEventSequence() { return _super !== null && _super.apply(this, arguments) || this; } DragAndDropFirstMoveEventSequence.prototype.setup = function () { _super.prototype.setup.call(this); this.dragAndDropMode = true; }; DragAndDropFirstMoveEventSequence.prototype.leaveElement = function (currentElement, prevElement, commonAncestor, options) { MoveBehaviour.leaveElement(currentElement, prevElement, commonAncestor, options); }; DragAndDropFirstMoveEventSequence.prototype.move = function (element, option) { MoveBehaviour.move(this.moveEvent, element, option); }; DragAndDropFirstMoveEventSequence.prototype.enterElement = function (currentElement, prevElement, commonAncestor, options) { MoveBehaviour.enterElement(currentElement, prevElement, commonAncestor, options); }; DragAndDropFirstMoveEventSequence.prototype.dragAndDrop = function (dragElement, currentElement, prevElement, options, dragDataStore) { var dragAllowed = eventSimulator$2.dragstart(dragElement, options); dragDataStore.setReadOnlyMode(); if (!dragAllowed) { this.dragAndDropMode = false; return; } this.dropAllowed = DragAndDropBehavior.dragAndDrop(dragElement, currentElement, prevElement, options); }; DragAndDropFirstMoveEventSequence.prototype.run = function (currentElement, prevElement, options, dragElement, dragDataStore) { return _super.prototype.run.call(this, currentElement, null, options, dragElement, dragDataStore); }; return DragAndDropFirstMoveEventSequence; }(MoveEventSequenceBase)); function createEventSequence(dragAndDropEnabled, firstMovingStepOccured, options) { if (!dragAndDropEnabled) return new MoveEventSequence(options); if (firstMovingStepOccured) return new DragAndDropMoveEventSequence(options); return new DragAndDropFirstMoveEventSequence(options); } var MOVE_REQUEST_CMD = 'automation|move|request'; var MOVE_RESPONSE_CMD = 'automation|move|response'; var MoveAutomation = /** @class */ (function () { function MoveAutomation(el, offset, moveOptions, win, cursor) { this.touchMode = hammerhead.utils.featureDetection.isTouchDevice; this.moveEvent = this.touchMode ? 'touchmove' : 'mousemove'; this.automationSettings = new AutomationSettings(moveOptions.speed); this.cursorSpeed = this._getCursorSpeed(); this.element = el; this.window = win; this.offset = offset; this.cursor = cursor; this.minMovingTime = moveOptions.minMovingTime || 0; this.modifiers = moveOptions.modifiers || {}; this.skipScrolling = moveOptions.skipScrolling; this.skipDefaultDragBehavior = moveOptions.skipDefaultDragBehavior; this.speed = moveOptions.speed; this.firstMovingStepOccured = false; } MoveAutomation.create = function (el, moveOptions, win, cursor) { return __awaiter(this, void 0, hammerhead.Promise, function () { var _a, element, offset; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, MoveAutomation.getTarget(el, win, new AxisValues(moveOptions.offsetX, moveOptions.offsetY))]; case 1: _a = _b.sent(), element = _a.element, offset = _a.offset; return [2 /*return*/, new MoveAutomation(element, offset, moveOptions, win, cursor)]; } }); }); }; MoveAutomation.getTarget = function (element, window, offset) { // NOTE: if the target point (considering offsets) is out of // the element change the target element to the document element return hammerhead.Promise.resolve(containsOffset(element, offset.x, offset.y)) .then(function (containsOffset) { if (!containsOffset) { return hammerhead.Promise.all([ getAutomationPoint(element, offset), getDocumentElement(window), ]) .then(function (_a) { var point = _a[0], docEl = _a[1]; return ({ element: docEl, offset: point }); }); } return { element: element, offset: offset }; }); }; MoveAutomation.prototype._getCursorSpeed = function () { return this.automationSettings.cursorSpeed; }; MoveAutomation.prototype._getTargetClientPoint = function () { var _this = this; return hammerhead.Promise.resolve(getElementScroll(this.element)) .then(function (scroll) { if (isHtmlElement(_this.element)) { return AxisValues.create(_this.offset) .sub(AxisValues.create(scroll)) .round(Math.round); } return hammerhead.Promise.resolve(getClientPosition(_this.element)) .then(function (clientPosition) { var isDocumentBody = isBodyElement(_this.element); // @ts-ignore var clientPoint = AxisValues.create(clientPosition).add(_this.offset); if (!isDocumentBody) clientPoint.sub(AxisValues.create(scroll)); return clientPoint.round(Math.floor); }); }); }; MoveAutomation.prototype._getEventSequenceOptions = function (currPosition) { var button = BUTTONS_PARAMETER.noButton; var devicePoint = getDevicePoint(currPosition); var eventOptions = { clientX: currPosition.x, clientY: currPosition.y, screenX: devicePoint === null || devicePoint === void 0 ? void 0 : devicePoint.x, screenY: devicePoint === null || devicePoint === void 0 ? void 0 : devicePoint.y, buttons: button, ctrl: this.modifiers.ctrl, alt: this.modifiers.alt, shift: this.modifiers.shift, meta: this.modifiers.meta, }; return { eventOptions: eventOptions, eventSequenceOptions: { moveEvent: this.moveEvent } }; }; MoveAutomation.prototype._runEventSequence = function (currentElement, _a) { var eventOptions = _a.eventOptions, eventSequenceOptions = _a.eventSequenceOptions; var eventSequence = createEventSequence(false, this.firstMovingStepOccured, eventSequenceOptions); return eventSequence.run(currentElement, lastHoveredElementHolder.get(), eventOptions, null, null); }; MoveAutomation.prototype._emulateEvents = function (currentElement, currPosition) { var options = this._getEventSequenceOptions(currPosition); this._runEventSequence(currentElement, options); this.firstMovingStepOccured = true; lastHoveredElementHolder.set(currentElement); }; MoveAutomation.prototype._movingStep = function (currPosition) { var _this = this; return this.cursor.move(currPosition) .then(function () { return getElementFromPoint$1(_this.cursor.getPosition()); }) // NOTE: in touch mode, events are simulated for the element for which mousedown was simulated (GH-372) .then(function (topElement) { var currentElement = _this._getCorrectedTopElement(topElement); // NOTE: it can be null in IE if (!currentElement) return null; return _this._emulateEvents(currentElement, currPosition); }) .then(nextTick); }; MoveAutomation.prototype._getCorrectedTopElement = function (topElement) { return topElement; }; MoveAutomation.prototype._move = function (endPoint) { var _this = this; var startPoint = this.cursor.getPosition(); var distance = AxisValues.create(endPoint).sub(startPoint); var startTime = hammerhead.nativeMethods.dateNow(); var movingTime = Math.max(Math.max(Math.abs(distance.x), Math.abs(distance.y)) / this.cursorSpeed, this.minMovingTime); var currPosition = AxisValues.create(startPoint); var isFirstStep = true; return whilst(function () { return !currPosition.eql(endPoint); }, function () { if (_this._needMoveCursorImmediately()) currPosition = AxisValues.create(endPoint); else if (isFirstStep) { isFirstStep = false; // NOTE: the mousemove event can't be simulated at the point where the cursor // was located at the start. Therefore, we add a minimal distance 1 px. currPosition.add({ x: distance.x > 0 ? 1 : -1, y: distance.y > 0 ? 1 : -1, }); } else { var progress = Math.min((hammerhead.nativeMethods.dateNow() - startTime) / movingTime, 1); currPosition = AxisValues.create(distance).mul(progress).add(startPoint).round(Math.floor); } return _this._movingStep(currPosition); }); }; // MoveAutomation.prototype._needMoveCursorImmediately = function () { return this.touchMode; }; MoveAutomation.prototype._scroll = function () { if (this.skipScrolling) return hammerhead.Promise.resolve(false); var scrollOptions = new ScrollOptions({ offsetX: this.offset.x, offsetY: this.offset.y }, false); var scrollAutomation = new ScrollAutomation(this.element, scrollOptions); return scrollAutomation.run(); }; MoveAutomation.prototype._moveToCurrentFrame = function (endPoint) { var _this = this; if (this.cursor.isActive(this.window)) return hammerhead.Promise.resolve(); var _a = this.cursor.getPosition(), x = _a.x, y = _a.y; var activeWindow = this.cursor.getActiveWindow(this.window); var iframe = null; var iframeUnderCursor = null; var msg = { cmd: MOVE_REQUEST_CMD, startX: x, startY: y, endX: endPoint.x, endY: endPoint.y, modifiers: this.modifiers, speed: this.speed, shouldRender: this.cursor.shouldRender, }; return hammerhead.Promise.resolve() .then(function () { if (activeWindow.parent === _this.window) { return hammerhead.Promise.resolve(findIframeByWindow(activeWindow)) .then(function (frame) { iframe = frame; return hammerhead.Promise.resolve(getIframeClientCoordinates(frame)) .then(function (rect) { msg.left = rect.left; msg.top = rect.top; msg.right = rect.right; msg.bottom = rect.bottom; }); }); } return void 0; }) .then(function () { return getElementFromPoint$1(_this.cursor.getPosition()); }) .then(function (topElement) { iframeUnderCursor = topElement === iframe; if (activeWindow.parent === _this.window) msg.iframeUnderCursor = iframeUnderCursor; return sendRequestToFrame(msg, MOVE_RESPONSE_CMD, activeWindow); }) .then(function (message) { _this.cursor.setActiveWindow(_this.window); if (iframeUnderCursor || hammerhead.utils.dom.isIframeWindow(_this.window)) return _this.cursor.move(message); return void 0; }); }; MoveAutomation.prototype.run = function () { var _this = this; return this._scroll() .then(function () { return hammerhead.Promise.all([ _this._getTargetClientPoint(), getWindowDimensions(_this.window), ]); }) .then(function (_a) { var endPoint = _a[0], boundary = _a[1]; if (!boundary.contains(endPoint)) return void 0; return _this._moveToCurrentFrame(endPoint) .then(function () { return _this._move(endPoint); }); }); }; return MoveAutomation; }()); var Cursor = /** @class */ (function () { function Cursor(activeWin, ui) { this._ui = ui; // NOTE: the default position should be outside the page (GH-794) this._x = -1; this._y = -1; this._activeWindow = activeWin; } Cursor.prototype._ensureActiveWindow = function (win) { if (this._activeWindow === win || this._activeWindow === win.parent) return; if (this._activeWindow.parent !== win) this._activeWindow = win; }; Cursor.prototype.isActive = function (currWin) { this._ensureActiveWindow(currWin); return this._activeWindow === currWin; }; Cursor.prototype.setActiveWindow = function (win) { this._activeWindow = win; }; Cursor.prototype.getActiveWindow = function (currWin) { this._ensureActiveWindow(currWin); return this._activeWindow; }; Cursor.prototype.getPosition = function () { return new AxisValues(this._x, this._y); }; Object.defineProperty(Cursor.prototype, "shouldRender", { get: function () { return this._ui.shouldRender; }, set: function (val) { this._ui.shouldRender = val; }, enumerable: false, configurable: true }); Cursor.prototype.move = function (point) { this._x = point.x; this._y = point.y; return this._ui.move(point); }; Cursor.prototype.hide = function () { if (this._ui.hide) return this._ui.hide(); return hammerhead.Promise.resolve(); }; Cursor.prototype.show = function () { if (this._ui.show) return this._ui.show(); return hammerhead.Promise.resolve(); }; Cursor.prototype.leftButtonDown = function () { return this._ui.leftButtonDown(); }; Cursor.prototype.rightButtonDown = function () { return this._ui.rightButtonDown(); }; Cursor.prototype.buttonUp = function () { return this._ui.buttonUp(); }; return Cursor; }()); var cursorUI = !isIframeWindow(window) ? testCafeUI.cursorUI : testCafeUI.iframeCursorUI; var cursor = new Cursor(window.top, cursorUI); var positionUtils$1 = testCafeCore__default.positionUtils, domUtils = testCafeCore__default.domUtils, eventUtils = testCafeCore__default.eventUtils; function ensureMouseEventAfterScroll(currentElement, element, wasScrolled) { return __awaiter(this, void 0, hammerhead__default.Promise, function () { var elementUnderCursorContainsTarget, prevElement, commonAncestor, clientPosition, devicePoint, options; return __generator(this, function (_a) { switch (_a.label) { case 0: elementUnderCursorContainsTarget = !!currentElement && domUtils.contains(element, currentElement); if (!elementUnderCursorContainsTarget || !wasScrolled) return [2 /*return*/]; prevElement = lastHoveredElementHolder.get(); commonAncestor = domUtils.getCommonAncestor(currentElement, prevElement); return [4 /*yield*/, positionUtils$1.getClientPosition(currentElement)]; case 1: clientPosition = _a.sent(); return [4 /*yield*/, getDevicePoint(clientPosition)]; case 2: devicePoint = _a.sent(); if (!devicePoint) return [2 /*return*/]; options = { clientX: clientPosition.x, clientY: clientPosition.y, screenX: devicePoint.x, screenY: devicePoint.y, ctrl: false, alt: false, shift: false, meta: false, buttons: eventUtils.BUTTONS_PARAMETER.leftButton, }; MoveBehaviour.leaveElement(currentElement, prevElement, commonAncestor, options); MoveBehaviour.enterElement(currentElement, prevElement, commonAncestor, options); lastHoveredElementHolder.set(currentElement); return [2 /*return*/]; } }); }); } var WARNING_TYPES = { elementOverlapped: 'elementOverlapped', }; var EventType; (function (EventType) { EventType[EventType["Mouse"] = 0] = "Mouse"; EventType[EventType["Key"] = 1] = "Key"; EventType[EventType["Touch"] = 2] = "Touch"; })(EventType || (EventType = {})); var KeyModifierValues; (function (KeyModifierValues) { KeyModifierValues[KeyModifierValues["alt"] = 1] = "alt"; KeyModifierValues[KeyModifierValues["ctrl"] = 2] = "ctrl"; KeyModifierValues[KeyModifierValues["meta"] = 4] = "meta"; KeyModifierValues[KeyModifierValues["shift"] = 8] = "shift"; })(KeyModifierValues || (KeyModifierValues = {})); function calculateKeyModifiersValue(modifiers) { var result = 0; if (modifiers.ctrl) result |= KeyModifierValues.ctrl; if (modifiers.alt) result |= KeyModifierValues.alt; if (modifiers.shift) result |= KeyModifierValues.shift; if (modifiers.meta) result |= KeyModifierValues.meta; return result; } function calculateMouseButtonValue(options) { if (!options.button) return 'left'; return 'right'; } var MOUSE_EVENT_OPTIONS = { clickCount: 1, button: 'left', }; var ProxylessEventSimulator = /** @class */ (function () { function ProxylessEventSimulator(dispatchEventFn, leftTopPoint) { this._dispatchEventFn = dispatchEventFn; this._leftTopPoint = leftTopPoint || new AxisValues(0, 0); } ProxylessEventSimulator.prototype._createMouseEventOptions = function (type, options) { return hammerhead.utils.extend({ x: options.options.clientX + this._leftTopPoint.x, y: options.options.clientY + this._leftTopPoint.y, modifiers: calculateKeyModifiersValue(options.options), button: calculateMouseButtonValue(options.options), type: type, }, MOUSE_EVENT_OPTIONS); }; ProxylessEventSimulator.prototype.mouseDown = function (options) { var eventOptions = this._createMouseEventOptions('mousePressed', options); return this._dispatchEventFn(EventType.Mouse, eventOptions); }; ProxylessEventSimulator.prototype.mouseUp = function (options) { var eventOptions = this._createMouseEventOptions('mouseReleased', options); return this._dispatchEventFn(EventType.Mouse, eventOptions); }; return ProxylessEventSimulator; }()); var AVAILABLE_OFFSET_DEEP = 2; var ElementState = /** @class */ (function () { function ElementState(_a) { var _b = _a.element, element = _b === void 0 ? null : _b, _c = _a.clientPoint, clientPoint = _c === void 0 ? null : _c, _d = _a.screenPoint, screenPoint = _d === void 0 ? null : _d, _e = _a.isTarget, isTarget = _e === void 0 ? false : _e, _f = _a.inMoving, inMoving = _f === void 0 ? false : _f, _g = _a.devicePoint, devicePoint = _g === void 0 ? null : _g; this.element = element; this.clientPoint = clientPoint; this.screenPoint = screenPoint; this.devicePoint = devicePoint; this.isTarget = isTarget; this.inMoving = inMoving; } ElementState.create = function (_a) { var element = _a.element, clientPoint = _a.clientPoint, screenPoint = _a.screenPoint, isTarget = _a.isTarget, inMoving = _a.inMoving; return __awaiter(this, void 0, void 0, function () { var devicePoint, state; return __generator(this, function (_b) { switch (_b.label) { case 0: devicePoint = null; if (!clientPoint) return [3 /*break*/, 2]; return [4 /*yield*/, getDevicePoint(clientPoint)]; case 1: devicePoint = _b.sent(); _b.label = 2; case 2: state = new ElementState({ element: element, clientPoint: clientPoint, screenPoint: screenPoint, isTarget: isTarget, inMoving: inMoving, devicePoint: devicePoint }); return [2 /*return*/, state]; } }); }); }; return ElementState; }()); var VisibleElementAutomation = /** @class */ (function (_super) { __extends(VisibleElementAutomation, _super); function VisibleElementAutomation(element, offsetOptions, win, cursor, dispatchProxylessEventFn, topLeftPoint) { var _this = _super.call(this) || this; _this.TARGET_ELEMENT_FOUND_EVENT = 'automation|target-element-found-event'; _this.WARNING_EVENT = 'automation|warning-event'; _this.element = element; _this.options = offsetOptions; _this.automationSettings = new AutomationSettings(offsetOptions.speed || 1); _this.window = win; _this.cursor = cursor; _this.proxylessEventSimulator = dispatchProxylessEventFn ? new ProxylessEventSimulator(dispatchProxylessEventFn, topLeftPoint) : null; // NOTE: only for legacy API _this._ensureWindowAndCursorForLegacyTests(_this); return _this; } VisibleElementAutomation.prototype._ensureWindowAndCursorForLegacyTests = function (automation) { automation.window = automation.window || window; // eslint-disable-line no-undef automation.cursor = cursor; }; VisibleElementAutomation.prototype.canUseProxylessEventSimulator = function (element) { return !!this.proxylessEventSimulator && !!element && getTagName(element) !== 'select'; }; VisibleElementAutomation.prototype._getElementForEvent = function (eventArgs) { return __awaiter(this, void 0, void 0, function () { var expectedElement; return __generator(this, function (_a) { expectedElement = containsOffset(this.element, this.options.offsetX, this.options.offsetY) ? this.element : null; return [2 /*return*/, getElementFromPoint$2(eventArgs.point, this.window, expectedElement)]; }); }); }; VisibleElementAutomation.prototype._moveToElement = function () { return __awaiter(this, void 0, void 0, function () { var moveOptions, moveAutomation; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: moveOptions = new MoveOptions(hammerhead.utils.extend({ skipScrolling: true }, this.options), false); return [4 /*yield*/, MoveAutomation.create(this.element, moveOptions, this.window, this.cursor)]; case 1: moveAutomation = _a.sent(); return [2 /*return*/, moveAutomation // eslint-disable-line consistent-return .run() .then(function () { return delay(_this.automationSettings.mouseActionStepDelay); })]; } }); }); }; VisibleElementAutomation.prototype._scrollToElement = function () { var _this = this; var wasScrolled = false; var scrollOptions = new ScrollOptions(this.options, false); var scrollAutomation = new ScrollAutomation(this.element, scrollOptions); return scrollAutomation.run() .then(function (scrollWasPerformed) { wasScrolled = !!scrollWasPerformed; return delay(_this.automationSettings.mouseActionStepDelay); }) .then(function () { return getElementFromPoint$2(_this.cursor.getPosition(), _this.window); }) .then(function (currentElement) { return ensureMouseEventAfterScroll(currentElement, _this.element, wasScrolled); }) .then(function () { return wasScrolled; }); }; VisibleElementAutomation.prototype._getElementOffset = function () { var defaultOffsets = getOffsetOptions(this.element); var _a = this.options, offsetX = _a.offsetX, offsetY = _a.offsetY; var y = offsetY || offsetY === 0 ? offsetY : defaultOffsets.offsetY; var x = offsetX || offsetX === 0 ? offsetX : defaultOffsets.offsetX; return AxisValues.create({ x: x, y: y }); }; VisibleElementAutomation.prototype._isTargetElement = function (element, expectedElement) { return __awaiter(this, void 0, void 0, function () { var isTarget; return __generator(this, function (_a) { switch (_a.label) { case 0: isTarget = !expectedElement || element === expectedElement || element === this.element; if (!(!isTarget && element)) return [3 /*break*/, 2]; return [4 /*yield*/, this._contains(this.element, element)]; case 1: // NOTE: perform an operation with searching in dom only if necessary isTarget = _a.sent(); _a.label = 2; case 2: return [2 /*return*/, isTarget]; } }); }); }; VisibleElementAutomation.prototype._getCheckedPoints = function (centerPoint) { var points = [centerPoint]; var stepX = centerPoint.x / AVAILABLE_OFFSET_DEEP; var stepY = centerPoint.y / AVAILABLE_OFFSET_DEEP; var maxX = centerPoint.x * 2; var maxY = centerPoint.y * 2; for (var y = stepY; y < maxY; y += stepY) { for (var x = stepX; x < maxX; x += stepX) points.push(AxisValues.create({ x: x, y: y })); } return points; }; VisibleElementAutomation.prototype._getAvailableOffset = function (expectedElement, centerPoint) { return __awaiter(this, void 0, void 0, function () { var checkedPoints, screenPoint, clientPoint, element, i; return __generator(this, function (_a) { switch (_a.label) { case 0: checkedPoints = this._getCheckedPoints(centerPoint); screenPoint = null; clientPoint = null; element = null; i = 0; _a.label = 1; case 1: if (!(i < checkedPoints.length)) return [3 /*break*/, 7]; return [4 /*yield*/, getAutomationPoint(this.element, checkedPoints[i])]; case 2: screenPoint = _a.sent(); return [4 /*yield*/, convertToClient(this.element, screenPoint)]; case 3: clientPoint = _a.sent(); return [4 /*yield*/, getElementFromPoint$2(clientPoint, this.window, expectedElement)]; case 4: element = _a.sent(); return [4 /*yield*/, this._isTargetElement(element, expectedElement)]; case 5: if (_a.sent()) return [2 /*return*/, checkedPoints[i]]; _a.label = 6; case 6: i++; return [3 /*break*/, 1]; case 7: return [2 /*return*/, null]; } }); }); }; VisibleElementAutomation.prototype._wrapAction = function (action) { return __awaiter(this, void 0, void 0, function () { var elementOffset, expectedElement, screenPointBeforeAction, clientPositionBeforeAction, availableOffset, screenPointAfterAction, clientPositionAfterAction, clientPoint, element, isTarget, offsetPositionChanged, clientPositionChanged, targetElementIsMoving; return __generator(this, function (_a) { switch (_a.label) { case 0: elementOffset = this._getElementOffset(); return [4 /*yield*/, containsOffset(this.element, elementOffset.x, elementOffset.y)]; case 1: expectedElement = (_a.sent()) ? this.element : null; return [4 /*yield*/, getAutomationPoint(this.element, elementOffset)]; case 2: screenPointBeforeAction = _a.sent(); return [4 /*yield*/, getClientPosition(this.element)]; case 3: clientPositionBeforeAction = _a.sent(); return [4 /*yield*/, action()]; case 4: _a.sent(); if (!this.options.isDefaultOffset) return [3 /*break*/, 6]; return [4 /*yield*/, this._getAvailableOffset(expectedElement, elementOffset)]; case 5: availableOffset = _a.sent(); elementOffset.x = (availableOffset === null || availableOffset === void 0 ? void 0 : availableOffset.x) || elementOffset.x; elementOffset.y = (availableOffset === null || availableOffset === void 0 ? void 0 : availableOffset.y) || elementOffset.y; this.options.offsetX = elementOffset.x; this.options.offsetY = elementOffset.y; _a.label = 6; case 6: return [4 /*yield*/, getAutomationPoint(this.element, elementOffset)]; case 7: screenPointAfterAction = _a.sent(); return [4 /*yield*/, getClientPosition(this.element)]; case 8: clientPositionAfterAction = _a.sent(); return [4 /*yield*/, convertToClient(this.element, screenPointAfterAction)]; case 9: clientPoint = _a.sent(); return [4 /*yield*/, getElementFromPoint$2(clientPoint, this.window, expectedElement)]; case 10: element = _a.sent(); if (!element) { return [2 /*return*/, ElementState.create({ element: null, clientPoint: null, screenPoint: null, isTarget: false, inMoving: false, })]; } return [4 /*yield*/, this._isTargetElement(element, expectedElement)]; case 11: isTarget = _a.sent(); offsetPositionChanged = screenPointBeforeAction.x !== screenPointAfterAction.x || screenPointBeforeAction.y !== screenPointAfterAction.y; clientPositionChanged = clientPositionBeforeAction.x !== clientPositionAfterAction.x || clientPositionBeforeAction.y !== clientPositionAfterAction.y; targetElementIsMoving = offsetPositionChanged && clientPositionChanged; return [2 /*return*/, ElementState.create({ element: element, clientPoint: clientPoint, screenPoint: screenPointAfterAction, isTarget: isTarget, inMoving: targetElementIsMoving, })]; } }); }); }; VisibleElementAutomation.prototype._checkElementState = function (state, useStrictElementCheck) { if (!state.element) { throw new ActionElementIsInvisibleError(null, { reason: getElOutsideBoundsReason(this.element), }); } if (useStrictElementCheck && (!state.isTarget || state.inMoving)) throw new ActionElementIsNotTargetError(); return state; }; VisibleElementAutomation.prototype._ensureElement = function (useStrictElementCheck, skipCheckAfterMoving, skipMoving) { var _this = this; if (skipCheckAfterMoving === void 0) { skipCheckAfterMoving = false; } if (skipMoving === void 0) { skipMoving = false; } return this ._wrapAction(function () { return _this._scrollToElement(); }) .then(function (state) { return _this._checkElementState(state, useStrictElementCheck); }) .then(function (state) { return skipMoving ? state : _this._wrapAction(function () { return _this._moveToElement(); }); }) .then(function (state) { if (!skipCheckAfterMoving) _this._checkElementState(state, useStrictElementCheck); return state; }) .then(function (state) { var element = state === null || state === void 0 ? void 0 : state.element; _this.emit(_this.TARGET_ELEMENT_FOUND_EVENT, { element: element || null }); if (!useStrictElementCheck && element && !state.isTarget) { var expectedElementStr = stringifyElement(_this.element); var actualElementStr = stringifyElement(element); _this.emit(_this.WARNING_EVENT, { type: WARNING_TYPES.elementOverlapped, args: [expectedElementStr, actualElementStr], }); } return { element: (state === null || state === void 0 ? void 0 : state.element) || null, clientPoint: (state === null || state === void 0 ? void 0 : state.clientPoint) || null, screenPoint: (state === null || state === void 0 ? void 0 : state.screenPoint) || null, devicePoint: (state === null || state === void 0 ? void 0 : state.devicePoint) || null, }; }); }; VisibleElementAutomation.prototype._contains = function (parent, child) { return __awaiter(this, void 0, void 0, function () { var parents, _i, parents_1, el; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, getParents(child)]; case 1: parents = _a.sent(); for (_i = 0, parents_1 = parents; _i < parents_1.length; _i++) { el = parents_1[_i]; if (el === parent) return [2 /*return*/, true]; } return [2 /*return*/, false]; } }); }); }; return VisibleElementAutomation; }(EventEmitter)); var Promise$3 = hammerhead__default.Promise; function calculatePosition(el, position) { var centerX = Math.floor(el.scrollWidth / 2 - el.clientWidth / 2); var centerY = Math.floor(el.scrollHeight / 2 - el.clientHeight / 2); var positions = { 'top': [centerX, 0], 'right': [el.scrollWidth, centerY], 'bottom': [centerX, el.scrollHeight], 'left': [0, centerY], 'topRight': [el.scrollWidth, 0], 'topLeft': [0, 0], 'bottomRight': [el.scrollWidth, el.scrollHeight], 'bottomLeft': [0, el.scrollHeight], 'center': [centerX, centerY], }; return positions[position]; } var SetScrollAutomation = /** @class */ (function (_super) { __extends(SetScrollAutomation, _super); function SetScrollAutomation(element, _a, offsetOptions) { var _b; var x = _a.x, y = _a.y, position = _a.position, byX = _a.byX, byY = _a.byY; var _this = _super.call(this, element, offsetOptions, window, cursor) || this; if (position) _b = calculatePosition(element, position), x = _b[0], y = _b[1]; _this.scrollLeft = typeof x === 'number' ? x : element.scrollLeft; _this.scrollTop = typeof y === 'number' ? y : element.scrollTop; if (byX) _this.scrollLeft += byX; if (byY) _this.scrollTop += byY; return _this; } SetScrollAutomation.prototype.run = function (useStrictElementCheck) { var _this = this; var promise = Promise$3.resolve(); if (this.element !== document.scrollingElement && this.element !== document.documentElement) promise = this._ensureElement(useStrictElementCheck, true, true); return promise .then(function () { _this.element.scrollLeft = _this.scrollLeft; _this.element.scrollTop = _this.scrollTop; }); }; return SetScrollAutomation; }(VisibleElementAutomation)); var ScrollIntoViewAutomation = /** @class */ (function (_super) { __extends(ScrollIntoViewAutomation, _super); function ScrollIntoViewAutomation(element, offsetOptions) { return _super.call(this, element, offsetOptions, window, cursor) || this; } ScrollIntoViewAutomation.prototype.run = function (useStrictElementCheck) { return this._ensureElement(useStrictElementCheck, true, true); }; return ScrollIntoViewAutomation; }(VisibleElementAutomation)); var Promise$4 = hammerhead__default.Promise; var nativeMethods$7 = hammerhead__default.nativeMethods; var browserUtils$3 = hammerhead__default.utils.browser; var focusBlurSandbox = hammerhead__default.eventSandbox.focusBlur; var contentEditable = testCafeCore__default.contentEditable; var textSelection = testCafeCore__default.textSelection; var domUtils$1 = testCafeCore__default.domUtils; var styleUtils$1 = testCafeCore__default.styleUtils; var messageSandbox$1 = hammerhead__default.eventSandbox.message; var GET_IFRAME_REQUEST_CMD = 'automation|iframe|request'; var GET_IFRAME_RESPONSE_CMD = 'automation|iframe|response'; messageSandbox$1.on(messageSandbox$1.SERVICE_MSG_RECEIVED_EVENT, function (e) { if (e.message.cmd === GET_IFRAME_REQUEST_CMD) { var iframeElement = domUtils$1.findIframeByWindow(e.source); focusBlurSandbox.focus(iframeElement, function () { messageSandbox$1.sendServiceMsg({ cmd: GET_IFRAME_RESPONSE_CMD }, e.source); }, false); } }); function setCaretPosition(element, caretPos) { var isTextEditable = domUtils$1.isTextEditableElement(element); var isContentEditable = domUtils$1.isContentEditableElement(element); if (isTextEditable || isContentEditable) { if (isContentEditable && isNaN(parseInt(caretPos, 10))) textSelection.setCursorToLastVisiblePosition(element); else { var position = isNaN(parseInt(caretPos, 10)) ? domUtils$1.getElementValue(element).length : caretPos; textSelection.select(element, position, position); } } else { // NOTE: if focus is called for a non-contentEditable element (like 'img' or 'button') inside // a contentEditable parent, we should try to set the right window selection. Generally, we can't // set the right window selection object because after the selection setup, the window.getSelection // method returns a different object, which depends on the browser. var contentEditableParent = contentEditable.findContentEditableParent(element); if (contentEditableParent) textSelection.setCursorToLastVisiblePosition(contentEditable.findContentEditableParent(contentEditableParent)); } } function focusAndSetSelection(element, simulateFocus, caretPos) { var _this = this; return new Promise$4(function (resolve) { return __awaiter(_this, void 0, void 0, function () { var activeElement, isTextEditable, labelWithForAttr, isElementFocusable, shouldFocusByRelatedElement, isContentEditable, elementForFocus, focusWithSilentMode, focusForMouseEvent, preventScrolling, curDocument, curActiveElement, isActiveElementBody, focusableParent, elementChildOfActiveElement; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!isIframeWindow(window)) return [3 /*break*/, 2]; return [4 /*yield*/, sendRequestToFrame({ cmd: GET_IFRAME_REQUEST_CMD }, GET_IFRAME_RESPONSE_CMD, window.parent)]; case 1: _a.sent(); _a.label = 2; case 2: activeElement = domUtils$1.getActiveElement(); isTextEditable = domUtils$1.isTextEditableElement(element); labelWithForAttr = domUtils$1.closest(element, 'label[for]'); isElementFocusable = domUtils$1.isElementFocusable(element); shouldFocusByRelatedElement = !isElementFocusable && labelWithForAttr; isContentEditable = domUtils$1.isContentEditableElement(element); elementForFocus = isContentEditable ? contentEditable.findContentEditableParent(element) : element; // NOTE: in WebKit, if selection was never set in an input element, the focus method selects all the // text in this element. So, we should call select before focus to set the caret to the first symbol. if (simulateFocus && browserUtils$3.isWebKit && isTextEditable) textSelection.select(element, 0, 0); // NOTE: we should call focus for the element related with a 'label' that has the 'for' attribute if (shouldFocusByRelatedElement) { if (simulateFocus) focusByLabel(labelWithForAttr); resolve(); return [2 /*return*/]; } focusWithSilentMode = !simulateFocus; focusForMouseEvent = true; preventScrolling = false; if (!isElementFocusable && !isContentEditable) { curDocument = domUtils$1.findDocument(elementForFocus); curActiveElement = nativeMethods$7.documentActiveElementGetter.call(curDocument); isActiveElementBody = domUtils$1.isBodyElement(curActiveElement); focusableParent = domUtils$1.isBodyElement(elementForFocus) ? elementForFocus : domUtils$1.getFocusableParent(elementForFocus); elementChildOfActiveElement = curActiveElement && !isActiveElementBody && domUtils$1.containsElement(curActiveElement, elementForFocus); if (elementChildOfActiveElement || isActiveElementBody && domUtils$1.isBodyElement(focusableParent)) { resolve(); return [2 /*return*/]; } elementForFocus = focusableParent || curDocument.body; preventScrolling = true; } focusBlurSandbox.focus(elementForFocus, function () { // NOTE: if a different element was focused in the focus event handler, we should not set selection if (simulateFocus && !isContentEditable && element !== domUtils$1.getActiveElement()) { resolve(); return; } setCaretPosition(element, caretPos); // NOTE: we can't avoid the element being focused because the setSelection method leads to focusing. // So, we just focus the previous active element without handlers if we don't need focus here if (!simulateFocus && domUtils$1.getActiveElement() !== activeElement) focusBlurSandbox.focus(activeElement, resolve, true, true); else resolve(); }, focusWithSilentMode, focusForMouseEvent, false, preventScrolling); return [2 /*return*/]; } }); }); }); } function getElementBoundToLabel(element) { var labelWithForAttr = domUtils$1.closest(element, 'label[for]'); var control = labelWithForAttr && (labelWithForAttr.control || document.getElementById(labelWithForAttr.htmlFor)); var isControlVisible = control && styleUtils$1.isElementVisible(control); return isControlVisible ? control : null; } function focusByLabel(label) { if (domUtils$1.isElementFocusable(label)) focusBlurSandbox.focus(label, testCafeCore__default.noop, false, true); else focusByRelatedElement(label); } function focusByRelatedElement(element) { var elementForFocus = getElementBoundToLabel(element); if (!elementForFocus || domUtils$1.getActiveElement() === elementForFocus) return; focusBlurSandbox.focus(elementForFocus, testCafeCore__default.noop, false, true); } var browserUtils$4 = hammerhead__default.utils.browser; var eventSimulator$3 = hammerhead__default.eventSandbox.eventSimulator; var listeners$2 = hammerhead__default.eventSandbox.listeners; var nativeMethods$8 = hammerhead__default.nativeMethods; var domUtils$2 = testCafeCore__default.domUtils; var styleUtils$2 = testCafeCore__default.styleUtils; var selectController = testCafeCore__default.selectController; var selectElementUI = testCafeUI.selectElement; var ElementClickCommand = /** @class */ (function () { function ElementClickCommand(eventState, eventArgs) { this.eventState = eventState; this.eventArgs = eventArgs; } ElementClickCommand.prototype.run = function () { if (this.eventState.clickElement) eventSimulator$3.click(this.eventState.clickElement, this.eventArgs.options); if (!domUtils$2.isElementFocusable(this.eventArgs.element)) focusByRelatedElement(this.eventArgs.element); }; return ElementClickCommand; }()); var LabelElementClickCommand = /** @class */ (function (_super) { __extends(LabelElementClickCommand, _super); function LabelElementClickCommand(eventState, eventArgs) { var _this = _super.call(this, eventState, eventArgs) || this; _this.targetElement = _this.eventArgs.element; _this.input = getElementBoundToLabel(_this.eventArgs.element); return _this; } LabelElementClickCommand.prototype.run = function () { var _this = this; var focusRaised = false; var ensureFocusRaised = function (e) { focusRaised = nativeMethods$8.eventTargetGetter.call(e) === _this.input; }; listeners$2.addInternalEventBeforeListener(window, ['focus'], ensureFocusRaised); _super.prototype.run.call(this); listeners$2.removeInternalEventBeforeListener(window, ['focus'], ensureFocusRaised); if (domUtils$2.isElementFocusable(this.targetElement) && !focusRaised) this._ensureBoundElementFocusRaised(); }; LabelElementClickCommand.prototype._ensureBoundElementFocusRaised = function () { eventSimulator$3.focus(this.input); }; return LabelElementClickCommand; }(ElementClickCommand)); var SelectElementClickCommand = /** @class */ (function (_super) { __extends(SelectElementClickCommand, _super); function SelectElementClickCommand(eventState, eventArgs) { return _super.call(this, eventState, eventArgs) || this; } SelectElementClickCommand.prototype.run = function () { _super.prototype.run.call(this); this._toggleSelectOptionList(); }; SelectElementClickCommand.prototype._toggleSelectOptionList = function () { // NOTE: Emulating the click event on the 'select' element doesn't expand the // dropdown with options (except chrome), therefore we should emulate it. var element = this.eventArgs.element; var isSelectWithDropDown = styleUtils$2.getSelectElementSize(element) === 1; if (isSelectWithDropDown && this.eventState.simulateDefaultBehavior !== false) { if (selectController.isOptionListExpanded(element)) selectElementUI.collapseOptionList(); else selectElementUI.expandOptionList(element); } }; return SelectElementClickCommand; }(ElementClickCommand)); var OptionElementClickCommand = /** @class */ (function (_super) { __extends(OptionElementClickCommand, _super); function OptionElementClickCommand(eventState, eventArgs) { return _super.call(this, eventState, eventArgs) || this; } OptionElementClickCommand.prototype.run = function () { return this.eventArgs.element; }; return OptionElementClickCommand; }(ElementClickCommand)); var LabelledCheckboxElementClickCommand = /** @class */ (function (_super) { __extends(LabelledCheckboxElementClickCommand, _super); function LabelledCheckboxElementClickCommand(eventState, eventArgs) { var _this = _super.call(this, eventState, eventArgs) || this; _this.checkbox = _this.input; return _this; } LabelledCheckboxElementClickCommand.prototype.run = function () { var changed = false; var onChange = function () { changed = true; }; listeners$2.addInternalEventBeforeListener(window, ['change'], onChange); _super.prototype.run.call(this); listeners$2.removeInternalEventBeforeListener(window, ['change'], onChange); // NOTE: Two overlapping issues: https://github.com/DevExpress/testcafe/issues/3348 and https://github.com/DevExpress/testcafe/issues/6949 // When label contains or