UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

972 lines (945 loc) 371 kB
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) { function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var hammerhead__default = /*#__PURE__*/_interopDefaultLegacy(hammerhead); var Promise__default = /*#__PURE__*/_interopDefaultLegacy(Promise$e); var testCafeCore__default = /*#__PURE__*/_interopDefaultLegacy(testCafeCore); var testCafeUI__default = /*#__PURE__*/_interopDefaultLegacy(testCafeUI); var nativeMethods$d = hammerhead__default["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$d['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, SuppressedError, Symbol, Iterator */ 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 __()); } var __assign = function () { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; 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__default["default"]))(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 = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["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 }; } } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; 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); }; } createNativeMethodWrapper('filter'); createNativeMethodWrapper('map'); createNativeMethodWrapper('slice'); createNativeMethodWrapper('splice'); createNativeMethodWrapper('unshift'); createNativeMethodWrapper('forEach'); createNativeMethodWrapper('indexOf'); var some = createNativeMethodWrapper('some'); createNativeMethodWrapper('reverse'); createNativeMethodWrapper('reduce'); createNativeMethodWrapper('concat'); createNativeMethodWrapper('join'); createNativeMethodWrapper('every'); hammerhead__default["default"].utils.browser; var nativeMethods$c = hammerhead__default["default"].nativeMethods; // NOTE: We have to retrieve styleUtils.get from hammerhead // to avoid circular dependencies between domUtils and styleUtils hammerhead__default["default"].utils.style.get; hammerhead__default["default"].utils.dom.getActiveElement; var findDocument = hammerhead__default["default"].utils.dom.findDocument; var find = hammerhead__default["default"].utils.dom.find; hammerhead__default["default"].utils.dom.isElementInDocument; var isElementInIframe = hammerhead__default["default"].utils.dom.isElementInIframe; var getIframeByElement = hammerhead__default["default"].utils.dom.getIframeByElement; hammerhead__default["default"].utils.dom.isCrossDomainWindows; hammerhead__default["default"].utils.dom.getSelectParent; hammerhead__default["default"].utils.dom.getChildVisibleIndex; hammerhead__default["default"].utils.dom.getSelectVisibleChildren; var isElementNode = hammerhead__default["default"].utils.dom.isElementNode; hammerhead__default["default"].utils.dom.isTextNode; hammerhead__default["default"].utils.dom.isRenderedNode; hammerhead__default["default"].utils.dom.isIframeElement; hammerhead__default["default"].utils.dom.isInputElement; hammerhead__default["default"].utils.dom.isButtonElement; hammerhead__default["default"].utils.dom.isFileInput; hammerhead__default["default"].utils.dom.isTextAreaElement; hammerhead__default["default"].utils.dom.isAnchorElement; var isImgElement = hammerhead__default["default"].utils.dom.isImgElement; hammerhead__default["default"].utils.dom.isFormElement; hammerhead__default["default"].utils.dom.isLabelElement; hammerhead__default["default"].utils.dom.isSelectElement; hammerhead__default["default"].utils.dom.isRadioButtonElement; hammerhead__default["default"].utils.dom.isColorInputElement; hammerhead__default["default"].utils.dom.isCheckboxElement; hammerhead__default["default"].utils.dom.isOptionElement; hammerhead__default["default"].utils.dom.isSVGElement; var isMapElement = hammerhead__default["default"].utils.dom.isMapElement; var isBodyElement = hammerhead__default["default"].utils.dom.isBodyElement; var isHtmlElement = hammerhead__default["default"].utils.dom.isHtmlElement; hammerhead__default["default"].utils.dom.isDocument; hammerhead__default["default"].utils.dom.isTextEditableInput; hammerhead__default["default"].utils.dom.isTextEditableElement; hammerhead__default["default"].utils.dom.isTextEditableElementAndEditingAllowed; hammerhead__default["default"].utils.dom.isContentEditableElement; hammerhead__default["default"].utils.dom.isDomElement; hammerhead__default["default"].utils.dom.isShadowUIElement; hammerhead__default["default"].utils.dom.isShadowRoot; hammerhead__default["default"].utils.dom.isElementFocusable; hammerhead__default["default"].utils.dom.isHammerheadAttr; hammerhead__default["default"].utils.dom.isElementReadOnly; var getScrollbarSize = hammerhead__default["default"].utils.dom.getScrollbarSize; var getMapContainer = hammerhead__default["default"].utils.dom.getMapContainer; var getTagName = hammerhead__default["default"].utils.dom.getTagName; var closest = hammerhead__default["default"].utils.dom.closest; var getParents = hammerhead__default["default"].utils.dom.getParents; var findParent = hammerhead__default["default"].utils.dom.findParent; hammerhead__default["default"].utils.dom.getTopSameDomainWindow; hammerhead__default["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$c.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$c.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$6 = hammerhead__default["default"].utils.style; var getBordersWidth = hammerhead__default["default"].utils.style.getBordersWidth; hammerhead__default["default"].utils.style.getComputedStyle; hammerhead__default["default"].utils.style.getElementMargin; var getElementPadding = hammerhead__default["default"].utils.style.getElementPadding; var getElementScroll = hammerhead__default["default"].utils.style.getElementScroll; hammerhead__default["default"].utils.style.getOptionHeight; hammerhead__default["default"].utils.style.getSelectElementSize; hammerhead__default["default"].utils.style.isElementVisible; hammerhead__default["default"].utils.style.isVisibleChild; var getWidth = hammerhead__default["default"].utils.style.getWidth; var getHeight = hammerhead__default["default"].utils.style.getHeight; var getInnerWidth = hammerhead__default["default"].utils.style.getInnerWidth; var getInnerHeight = hammerhead__default["default"].utils.style.getInnerHeight; var getScrollLeft = hammerhead__default["default"].utils.style.getScrollLeft; var getScrollTop = hammerhead__default["default"].utils.style.getScrollTop; var setScrollLeft = hammerhead__default["default"].utils.style.setScrollLeft; var setScrollTop = hammerhead__default["default"].utils.style.setScrollTop; var get = hammerhead__default["default"].utils.style.get; var getBordersWidthFloat = hammerhead__default["default"].utils.style.getBordersWidthFloat; var getElementPaddingFloat = hammerhead__default["default"].utils.style.getElementPaddingFloat; function getWindowDimensions(window) { return new BoundaryValues(0, getWidth(window), getHeight(window), 0); } function isFixedElement(node) { return isElementNode(node) && styleUtils$6.get(node, 'position') === 'fixed'; } function isStickyElement(node) { return isElementNode(node) && styleUtils$6.get(node, 'position') === 'sticky'; } hammerhead__default["default"].shadowUI; hammerhead__default["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$1 = hammerhead__default["default"].utils.html; var nativeMethods$b = hammerhead__default["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$b.cloneNode.call(element); var outerHtml = htmlUtils$1.cleanUpHtml(nativeMethods$b.elementOuterHTMLGetter.call(emptyElement)); var text = truncateString(nativeMethods$b.nodeTextContentGetter.call(element), MAX_TEXT_CONTENT_LENGTH); var children = nativeMethods$b.elementChildrenGetter.call(element); if (nativeMethods$b.htmlCollectionLengthGetter.call(children) > 0) return outerHtml.replace('></', '>...</'); if (text) return outerHtml.replace('></', ">".concat(text, "</")); return outerHtml; } var getElementRectangle = hammerhead__default["default"].utils.position.getElementRectangle; var getOffsetPosition = hammerhead__default["default"].utils.position.getOffsetPosition; var offsetToClientCoords = hammerhead__default["default"].utils.position.offsetToClientCoords; function getClientDimensions(target) { var isHtmlElement$1 = isHtmlElement(target); var body = isHtmlElement$1 ? target.getElementsByTagName('body')[0] : null; var elementRect = target.getBoundingClientRect(); var elBorders = BoundaryValues.create(getBordersWidth(target)); var elScroll = getElementScroll(target); var isElementInIframe$1 = isElementInIframe(target); var isCompatMode = target.ownerDocument.compatMode === 'BackCompat'; var elPosition = isHtmlElement$1 ? new AxisValues(0, 0) : AxisValues.create(elementRect); var elHeight = elementRect.height; var elWidth = elementRect.width; if (isHtmlElement$1) { if (body && isCompatMode) { elHeight = body.clientHeight; elWidth = body.clientWidth; } else { elHeight = target.clientHeight; elWidth = target.clientWidth; } } if (isElementInIframe$1) { var iframeElement = getIframeByElement(target); if (iframeElement) { var iframeOffset = getOffsetPosition(iframeElement); var clientOffset = offsetToClientCoords(AxisValues.create(iframeOffset)); var iframeBorders = getBordersWidth(iframeElement); elPosition.add(clientOffset).add(AxisValues.create(iframeBorders)); if (isHtmlElement$1) elBorders.add(iframeBorders); } } var hasRightScrollbar = !isHtmlElement$1 && getInnerWidth(target) !== target.clientWidth; var hasBottomScrollbar = !isHtmlElement$1 && getInnerHeight(target) !== target.clientHeight; var scrollbar = { right: hasRightScrollbar ? getScrollbarSize() : 0, bottom: hasBottomScrollbar ? getScrollbarSize() : 0, }; return new Dimensions(elWidth, elHeight, elPosition, elBorders, elScroll, scrollbar); } function getElementFromPoint$2(_a) { var x = _a.x, y = _a.y; // @ts-ignore var func = document.elementFromPoint; var el = null; try { // Permission denied to access property 'getElementFromPoint' error in iframe el = func.call(document, x, y); } catch (_b) { return null; } //NOTE: elementFromPoint returns null when is's a border of an iframe if (el === null) el = func.call(document, x - 1, y - 1); while (el && el.shadowRoot && el.shadowRoot.elementFromPoint) { var shadowEl = el.shadowRoot.elementFromPoint(x, y); if (!shadowEl || el === shadowEl) break; el = shadowEl; } return el; } function calcRelativePosition(dimensions, toDimensions) { var pos = BoundaryValues.create({ top: dimensions.top - toDimensions.top, left: dimensions.left - toDimensions.left, right: toDimensions.right - dimensions.right, bottom: toDimensions.bottom - dimensions.bottom, }); return pos.sub(toDimensions.border).sub(toDimensions.scrollbar).round(Math.ceil, Math.floor); } function getIframeClientCoordinates(iframe) { var _a = getOffsetPosition(iframe), left = _a.left, top = _a.top; var clientPosition = offsetToClientCoords({ x: left, y: top }); var iframeBorders = getBordersWidth(iframe); var iframePadding = getElementPadding(iframe); var iframeRectangleLeft = clientPosition.x + iframeBorders.left + iframePadding.left; var iframeRectangleTop = clientPosition.y + iframeBorders.top + iframePadding.top; return new BoundaryValues(iframeRectangleTop, iframeRectangleLeft + getWidth(iframe), iframeRectangleTop + getHeight(iframe), iframeRectangleLeft); } function containsOffset(el, offsetX, offsetY) { var dimensions = getClientDimensions(el); var width = Math.max(el.scrollWidth, dimensions.width); var height = Math.max(el.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 (typeof offsetX === 'undefined' || offsetX >= 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; 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); 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$7 = testCafeCore__default["default"].positionUtils; function getElementFromPoint$1(point, underTopShadowUIElement) { if (underTopShadowUIElement === void 0) { underTopShadowUIElement = false; } return testCafeUI__default["default"].hide(underTopShadowUIElement) .then(function () { var topElement = positionUtils$7.getElementFromPoint(point); return testCafeUI__default["default"].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$2(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 <area> element from document.getElementFromPoint, but // Firefox returns the <img> 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(point, win, expectedEl) { return getElementFromPoint$1(point) .then(function (topElement) { return correctTopElementByExpectedElement(topElement, 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', multipleWindowsModeIsNotSupportedInNativeAutomationError: 'E102', }; // 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 //-------------------------------------------------------------------- /** @class */ ((function (_super) { __extends(ClientFunctionExecutionInterruptionError, _super); function ClientFunctionExecutionInterruptionError(instant