UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

1,226 lines (868 loc) 392 kB
// 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; // This file was generated by modules-webmake (modules for web) project. // See: https://github.com/medikoo/modules-webmake (function (modules) { 'use strict'; var resolve, getRequire, wmRequire, notFoundError, findFile , extensions = {".js":[],".json":[],".css":[],".html":[]} , envRequire = typeof require === 'function' ? require : null; notFoundError = function (path) { var error = new Error("Could not find module '" + path + "'"); error.code = 'MODULE_NOT_FOUND'; return error; }; findFile = function (scope, name, extName) { var i, ext; if (typeof scope[name + extName] === 'function') return name + extName; for (i = 0; (ext = extensions[extName][i]); ++i) { if (typeof scope[name + ext] === 'function') return name + ext; } return null; }; resolve = function (scope, tree, path, fullPath, state, id) { var name, dir, exports, module, fn, found, ext; path = path.split(/[\\/]/); name = path.pop(); if ((name === '.') || (name === '..')) { path.push(name); name = ''; } while ((dir = path.shift()) != null) { if (!dir || (dir === '.')) continue; if (dir === '..') { scope = tree.pop(); id = id.slice(0, id.lastIndexOf('/')); } else { tree.push(scope); scope = scope[dir]; id += '/' + dir; } if (!scope) throw notFoundError(fullPath); } if (name && (typeof scope[name] !== 'function')) { found = findFile(scope, name, '.js'); if (!found) found = findFile(scope, name, '.json'); if (!found) found = findFile(scope, name, '.css'); if (!found) found = findFile(scope, name, '.html'); if (found) { name = found; } else if ((state !== 2) && (typeof scope[name] === 'object')) { tree.push(scope); scope = scope[name]; id += '/' + name; name = ''; } } if (!name) { if ((state !== 1) && scope[':mainpath:']) { return resolve(scope, tree, scope[':mainpath:'], fullPath, 1, id); } return resolve(scope, tree, 'index', fullPath, 2, id); } fn = scope[name]; if (!fn) throw notFoundError(fullPath); if (fn.hasOwnProperty('module')) return fn.module.exports; exports = {}; fn.module = module = { exports: exports, id: id + '/' + name }; fn.call(exports, exports, module, getRequire(scope, tree, id)); return module.exports; }; wmRequire = function (scope, tree, fullPath, id) { var name, path = fullPath, t = fullPath.charAt(0), state = 0; if (t === '/') { path = path.slice(1); scope = modules['/']; if (!scope) { if (envRequire) return envRequire(fullPath); throw notFoundError(fullPath); } id = '/'; tree = []; } else if (t !== '.') { name = path.split('/', 1)[0]; scope = modules[name]; if (!scope) { if (envRequire) return envRequire(fullPath); throw notFoundError(fullPath); } id = name; tree = []; path = path.slice(name.length + 1); if (!path) { path = scope[':mainpath:']; if (path) { state = 1; } else { path = 'index'; state = 2; } } } return resolve(scope, tree, path, fullPath, state, id); }; getRequire = function (scope, tree, id) { return function (path) { return wmRequire(scope, [].concat(tree), path, id); }; }; return getRequire(modules, [], ''); })({ "testcafe-release": { "src": { "client": { "automation": { "cursor.js": function (exports, module, require) { exports.__esModule = true; var _testcafeCore = require('./deps/testcafe-core'); var _testcafeCore2 = _interopRequireDefault(_testcafeCore); var _testcafeUi = require('./deps/testcafe-ui'); var _testcafeUi2 = _interopRequireDefault(_testcafeUi); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var domUtils = _testcafeCore2.default.domUtils; var cursorUI = window.top === window ? _testcafeUi2.default.cursorUI : _testcafeUi2.default.iframeCursorUI; // NOTE: the default position should be outside of the page (GH-794) exports.default = { x: -1, y: -1, currentActiveWindow: window.top, _ensureActiveWindow: function _ensureActiveWindow() { if (this.currentActiveWindow === window || this.currentActiveWindow === window.parent) return; var activeFrame = domUtils.findIframeByWindow(this.currentActiveWindow); if (!activeFrame || !domUtils.isElementInDocument(activeFrame)) this.currentActiveWindow = window; }, get active() { this._ensureActiveWindow(); return this.currentActiveWindow === window; }, set activeWindow(win) { this.currentActiveWindow = win; }, get activeWindow() { this._ensureActiveWindow(); return this.currentActiveWindow; }, get position() { return { x: this.x, y: this.y }; }, get visible() { return window.top === window && cursorUI.isVisible(); }, move: function move(newX, newY) { this.x = newX; this.y = newY; return cursorUI.move(this.x, this.y); }, hide: function hide() { if (this.visible) cursorUI.hide(); }, show: function show() { if (window.top === window) cursorUI.show(); }, leftButtonDown: function leftButtonDown() { return cursorUI.leftButtonDown(); }, rightButtonDown: function rightButtonDown() { return cursorUI.rightButtonDown(); }, buttonUp: function buttonUp() { return cursorUI.buttonUp(); } }; module.exports = exports['default']; }, "deps": { "hammerhead.js": function (exports, module, require) { exports.__esModule = true; exports.default = window['%hammerhead%']; module.exports = exports['default']; }, "testcafe-core.js": function (exports, module, require) { exports.__esModule = true; exports.default = window['%testCafeCore%']; module.exports = exports['default']; }, "testcafe-ui.js": function (exports, module, require) { exports.__esModule = true; exports.default = window['%testCafeUI%']; module.exports = exports['default']; } }, "errors.js": function (exports, module, require) { exports.__esModule = true; exports.default = { elementIsInvisibleError: 'elementIsInvisibleError', foundElementIsNotTarget: 'foundElementIsNotTarget' }; module.exports = exports['default']; }, "get-element.js": function (exports, module, require) { exports.__esModule = true; exports.fromPoint = fromPoint; exports.underCursor = underCursor; var _hammerhead = require('./deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _testcafeCore = require('./deps/testcafe-core'); var _testcafeCore2 = _interopRequireDefault(_testcafeCore); var _testcafeUi = require('./deps/testcafe-ui'); var _testcafeUi2 = _interopRequireDefault(_testcafeUi); var _cursor = require('./cursor'); var _cursor2 = _interopRequireDefault(_cursor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var browserUtils = _hammerhead2.default.utils.browser; var Promise = _hammerhead2.default.Promise; var nativeMethods = _hammerhead2.default.nativeMethods; var positionUtils = _testcafeCore2.default.positionUtils; var domUtils = _testcafeCore2.default.domUtils; function getElementFromPoint(x, y, underTopShadowUIElement) { var topElement = null; return _testcafeUi2.default.hide(underTopShadowUIElement).then(function () { topElement = positionUtils.getElementFromPoint(x, y); return _testcafeUi2.default.show(underTopShadowUIElement); }).then(function () { return topElement; }); } function ensureImageMap(imgElement, areaElement) { var mapElement = domUtils.closest(areaElement, 'map'); return mapElement && mapElement.name === imgElement.useMap.substring(1) ? areaElement : imgElement; } function findElementOrNonEmptyChildFromPoint(x, y, element) { var topElement = positionUtils.getElementFromPoint(x, y); var isNonEmptyChild = domUtils.containsElement(element, topElement) && nativeMethods.nodeTextContentGetter.call(topElement).length; if (topElement && topElement === element || isNonEmptyChild) return topElement; return null; } function correctTopElementByExpectedElement(topElement, expectedElement) { var expectedElementDefined = expectedElement && domUtils.isDomElement(expectedElement); if (!expectedElementDefined || !topElement || topElement === expectedElement) return topElement; var isTREFElement = domUtils.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 = domUtils.getTagName(expectedElement) === 'area' && domUtils.isImgElement(topElement); if (browserUtils.isFirefox && isImageMapArea) return ensureImageMap(topElement, expectedElement); // NOTE: try to find a multi-line link by its rectangle (T163678) var isLinkOrChildExpected = domUtils.isAnchorElement(expectedElement) || domUtils.getParents(expectedElement, 'a').length; var isTopElementChildOfLink = isLinkOrChildExpected && domUtils.containsElement(expectedElement, topElement) && nativeMethods.nodeTextContentGetter.call(topElement).length; var shouldSearchForMultilineLink = isLinkOrChildExpected && !isTopElementChildOfLink && nativeMethods.nodeTextContentGetter.call(expectedElement).length; if (!shouldSearchForMultilineLink) return topElement; var linkRect = expectedElement.getBoundingClientRect(); return findElementOrNonEmptyChildFromPoint(linkRect.right - 1, linkRect.top + 1, expectedElement) || findElementOrNonEmptyChildFromPoint(linkRect.left + 1, linkRect.bottom - 1, expectedElement) || topElement; } function fromPoint(x, y, expectedElement) { var isInIframe = window !== window.top; var foundElement = null; return getElementFromPoint(x, y).then(function (topElement) { foundElement = 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 = Promise.resolve(topElement); if (!foundElement && isInIframe && x > 0 && y > 0) { resChain = resChain.then(function () { return getElementFromPoint(x, y, true); }).then(function (element) { foundElement = element; return element; }); } return resChain.then(function (element) { return correctTopElementByExpectedElement(element, expectedElement); }).then(function (correctedElement) { return { element: correctedElement, corrected: correctedElement !== foundElement }; }); }); } function underCursor() { var cursorPosition = _cursor2.default.position; return fromPoint(cursorPosition.x, cursorPosition.y).then(function (_ref) { var element = _ref.element; return element; }); } }, "index.js": function (exports, module, require) { var _hammerhead = require('./deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _scroll = require('./playback/scroll'); var _scroll2 = _interopRequireDefault(_scroll); var _click = require('./playback/click'); var _click2 = _interopRequireDefault(_click); var _selectChild = require('./playback/click/select-child'); var _selectChild2 = _interopRequireDefault(_selectChild); var _dblclick = require('./playback/dblclick'); var _dblclick2 = _interopRequireDefault(_dblclick); var _toOffset = require('./playback/drag/to-offset'); var _toOffset2 = _interopRequireDefault(_toOffset); var _toElement = require('./playback/drag/to-element'); var _toElement2 = _interopRequireDefault(_toElement); var _hover = require('./playback/hover'); var _hover2 = _interopRequireDefault(_hover); var _press = require('./playback/press'); var _press2 = _interopRequireDefault(_press); var _rclick = require('./playback/rclick'); var _rclick2 = _interopRequireDefault(_rclick); var _selectText = require('./playback/select/select-text'); var _selectText2 = _interopRequireDefault(_selectText); var _selectEditableContent = require('./playback/select/select-editable-content'); var _selectEditableContent2 = _interopRequireDefault(_selectEditableContent); var _type = require('./playback/type'); var _type2 = _interopRequireDefault(_type); var _upload = require('./playback/upload'); var _upload2 = _interopRequireDefault(_upload); var _options = require('../../test-run/commands/options'); var _settings = require('./settings'); var _settings2 = _interopRequireDefault(_settings); var _offsets = require('./utils/offsets'); var _utils = require('./playback/press/utils'); var _calculateSelectTextArguments = require('./playback/select/calculate-select-text-arguments'); var _calculateSelectTextArguments2 = _interopRequireDefault(_calculateSelectTextArguments); var _errors = require('./errors'); var _errors2 = _interopRequireDefault(_errors); var _cursor = require('./cursor'); var _cursor2 = _interopRequireDefault(_cursor); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } exports.Scroll = _scroll2.default; exports.Click = _click2.default; exports.SelectChildClick = _selectChild2.default; exports.DblClick = _dblclick2.default; exports.DragToOffset = _toOffset2.default; exports.DragToElement = _toElement2.default; exports.Hover = _hover2.default; exports.Press = _press2.default; exports.RClick = _rclick2.default; exports.SelectText = _selectText2.default; exports.SelectEditableContent = _selectEditableContent2.default; exports.Type = _type2.default; exports.Upload = _upload2.default; exports.MouseOptions = _options.MouseOptions; exports.ClickOptions = _options.ClickOptions; exports.TypeOptions = _options.TypeOptions; exports.ERROR_TYPES = _errors2.default; exports.AutomationSettings = _settings2.default; exports.getOffsetOptions = _offsets.getOffsetOptions; exports.calculateSelectTextArguments = _calculateSelectTextArguments2.default; exports.cursor = _cursor2.default; exports.getNextFocusableElement = _utils.getNextFocusableElement; exports.get = require; var nativeMethods = _hammerhead2.default.nativeMethods; var evalIframeScript = _hammerhead2.default.EVENTS.evalIframeScript; nativeMethods.objectDefineProperty(window, '%testCafeAutomation%', { configurable: true, value: exports }); // eslint-disable-next-line no-undef _hammerhead2.default.on(evalIframeScript, function (e) { return initTestCafeAutomation(nativeMethods.contentWindowGetter.call(e.iframe), true); }); }, "playback": { "click": { "click-command.js": function (exports, module, require) { exports.__esModule = true; exports.default = function (eventState, eventArgs) { var elementBoundToLabel = (0, _utils.getElementBoundToLabel)(eventArgs.element); var isSelectElement = domUtils.isSelectElement(eventArgs.element); var isOptionElement = domUtils.isOptionElement(eventArgs.element); var isLabelElement = domUtils.isLabelElement(eventArgs.element) && elementBoundToLabel; var isLabelledCheckbox = elementBoundToLabel && domUtils.isCheckboxElement(elementBoundToLabel); if (isSelectElement) return new SelectElementClickCommand(eventState, eventArgs); if (isOptionElement) return new OptionElementClickCommand(eventState, eventArgs); if (isLabelledCheckbox) return new LabelledCheckboxElementClickCommand(eventState, eventArgs); if (isLabelElement) return new LabelElementClickCommand(eventState, eventArgs); return new ElementClickCommand(eventState, eventArgs); }; var _hammerhead = require('../../deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _testcafeCore = require('../../deps/testcafe-core'); var _testcafeCore2 = _interopRequireDefault(_testcafeCore); var _testcafeUi = require('../../deps/testcafe-ui'); var _testcafeUi2 = _interopRequireDefault(_testcafeUi); var _utils = require('../../utils/utils'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var browserUtils = _hammerhead2.default.utils.browser; var eventSimulator = _hammerhead2.default.eventSandbox.eventSimulator; var listeners = _hammerhead2.default.eventSandbox.listeners; var domUtils = _testcafeCore2.default.domUtils; var styleUtils = _testcafeCore2.default.styleUtils; var selectElementUI = _testcafeUi2.default.selectElement; var ElementClickCommand = function () { function ElementClickCommand(eventState, eventArgs) { _classCallCheck(this, ElementClickCommand); this.eventState = eventState; this.eventArgs = eventArgs; } ElementClickCommand.prototype.run = function run() { if (this.eventState.clickElement) eventSimulator.click(this.eventState.clickElement, this.eventArgs.options); if (!domUtils.isElementFocusable(this.eventArgs.element)) (0, _utils.focusByRelatedElement)(this.eventArgs.element); }; return ElementClickCommand; }(); var LabelElementClickCommand = function (_ElementClickCommand) { _inherits(LabelElementClickCommand, _ElementClickCommand); function LabelElementClickCommand(eventState, eventArgs) { _classCallCheck(this, LabelElementClickCommand); var _this = _possibleConstructorReturn(this, _ElementClickCommand.call(this, eventState, eventArgs)); _this.label = _this.eventArgs.element; _this.input = (0, _utils.getElementBoundToLabel)(_this.eventArgs.element); return _this; } LabelElementClickCommand.prototype.run = function run() { var _this2 = this; var focusRaised = false; var ensureFocusRaised = function ensureFocusRaised(e) { focusRaised = e.target === _this2.input; }; listeners.addInternalEventListener(window, ['focus'], ensureFocusRaised); _ElementClickCommand.prototype.run.call(this); listeners.removeInternalEventListener(window, ['focus'], ensureFocusRaised); if (domUtils.isElementFocusable(this.label) && !focusRaised) this._ensureBoundElementFocusRaised(); }; LabelElementClickCommand.prototype._ensureBoundElementFocusRaised = function _ensureBoundElementFocusRaised() { eventSimulator.focus(this.input); }; return LabelElementClickCommand; }(ElementClickCommand); var SelectElementClickCommand = function (_ElementClickCommand2) { _inherits(SelectElementClickCommand, _ElementClickCommand2); function SelectElementClickCommand(eventState, eventArgs) { _classCallCheck(this, SelectElementClickCommand); return _possibleConstructorReturn(this, _ElementClickCommand2.call(this, eventState, eventArgs)); } SelectElementClickCommand.prototype.run = function run() { _ElementClickCommand2.prototype.run.call(this); this._toggleSelectOptionList(); }; SelectElementClickCommand.prototype._toggleSelectOptionList = function _toggleSelectOptionList() { // 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.getSelectElementSize(element) === 1; if (isSelectWithDropDown && this.eventState.simulateDefaultBehavior !== false) { if (selectElementUI.isOptionListExpanded(element)) selectElementUI.collapseOptionList();else selectElementUI.expandOptionList(element); } }; return SelectElementClickCommand; }(ElementClickCommand); var OptionElementClickCommand = function (_ElementClickCommand3) { _inherits(OptionElementClickCommand, _ElementClickCommand3); function OptionElementClickCommand(eventState, eventArgs) { _classCallCheck(this, OptionElementClickCommand); return _possibleConstructorReturn(this, _ElementClickCommand3.call(this, eventState, eventArgs)); } OptionElementClickCommand.prototype.run = function run() { return this.eventArgs.element; }; return OptionElementClickCommand; }(ElementClickCommand); var LabelledCheckboxElementClickCommand = function (_LabelElementClickCom) { _inherits(LabelledCheckboxElementClickCommand, _LabelElementClickCom); function LabelledCheckboxElementClickCommand(eventState, eventArgs) { _classCallCheck(this, LabelledCheckboxElementClickCommand); var _this5 = _possibleConstructorReturn(this, _LabelElementClickCom.call(this, eventState, eventArgs)); _this5.checkbox = _this5.input; return _this5; } LabelledCheckboxElementClickCommand.prototype.run = function run() { var changed = false; var onChange = function onChange() { changed = true; }; listeners.addInternalEventListener(window, ['change'], onChange); _LabelElementClickCom.prototype.run.call(this); listeners.removeInternalEventListener(window, ['change'], onChange); if (browserUtils.isChrome && !changed) this._ensureCheckboxStateChanged(); }; LabelledCheckboxElementClickCommand.prototype._ensureCheckboxStateChanged = function _ensureCheckboxStateChanged() { this.checkbox.checked = !this.checkbox.checked; eventSimulator.change(this.checkbox); }; return LabelledCheckboxElementClickCommand; }(LabelElementClickCommand); module.exports = exports['default']; }, "index.js": function (exports, module, require) { exports.__esModule = true; var _hammerhead = require('../../deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _testcafeCore = require('../../deps/testcafe-core'); var _testcafeCore2 = _interopRequireDefault(_testcafeCore); var _visibleElementAutomation = require('../visible-element-automation'); var _visibleElementAutomation2 = _interopRequireDefault(_visibleElementAutomation); var _utils = require('../../utils/utils'); var _cursor = require('../../cursor'); var _cursor2 = _interopRequireDefault(_cursor); var _nextTick = require('../../utils/next-tick'); var _nextTick2 = _interopRequireDefault(_nextTick); var _clickCommand = require('./click-command'); var _clickCommand2 = _interopRequireDefault(_clickCommand); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var Promise = _hammerhead2.default.Promise; var extend = _hammerhead2.default.utils.extend; var browserUtils = _hammerhead2.default.utils.browser; var featureDetection = _hammerhead2.default.utils.featureDetection; var eventSimulator = _hammerhead2.default.eventSandbox.eventSimulator; var listeners = _hammerhead2.default.eventSandbox.listeners; var domUtils = _testcafeCore2.default.domUtils; var eventUtils = _testcafeCore2.default.eventUtils; var arrayUtils = _testcafeCore2.default.arrayUtils; var delay = _testcafeCore2.default.delay; var ClickAutomation = function (_VisibleElementAutoma) { _inherits(ClickAutomation, _VisibleElementAutoma); function ClickAutomation(element, clickOptions) { _classCallCheck(this, ClickAutomation); var _this = _possibleConstructorReturn(this, _VisibleElementAutoma.call(this, element, clickOptions)); _this.modifiers = clickOptions.modifiers; _this.caretPos = clickOptions.caretPos; _this.targetElementParentNodes = []; _this.activeElementBeforeMouseDown = null; _this.mouseDownElement = null; _this.eventState = { mousedownPrevented: false, blurRaised: false, simulateDefaultBehavior: true, clickElement: null }; return _this; } ClickAutomation.prototype._bindMousedownHandler = function _bindMousedownHandler() { var _this2 = this; var onmousedown = function onmousedown(e) { _this2.eventState.mousedownPrevented = e.defaultPrevented; eventUtils.preventDefault(e); eventUtils.unbind(_this2.element, 'mousedown', onmousedown); }; eventUtils.bind(this.element, 'mousedown', onmousedown); }; ClickAutomation.prototype._bindBlurHandler = function _bindBlurHandler(element) { var _this3 = this; var onblur = function onblur() { _this3.eventState.blurRaised = true; eventUtils.unbind(element, 'blur', onblur, true); }; eventUtils.bind(element, 'blur', onblur, true); }; ClickAutomation.prototype._raiseTouchEvents = function _raiseTouchEvents(eventArgs) { if (featureDetection.isTouchDevice) { eventSimulator.touchstart(eventArgs.element, eventArgs.options); eventSimulator.touchend(eventArgs.element, eventArgs.options); } }; ClickAutomation.prototype._mousedown = function _mousedown(eventArgs) { var _this4 = this; this.targetElementParentNodes = domUtils.getParents(eventArgs.element); this.mouseDownElement = eventArgs.element; return _cursor2.default.leftButtonDown().then(function () { _this4._raiseTouchEvents(eventArgs); var activeElement = domUtils.getActiveElement(); _this4.activeElementBeforeMouseDown = activeElement; // NOTE: In WebKit and IE, the mousedown event opens the select element's dropdown; // therefore, we should prevent mousedown and hide the dropdown (B236416). var needCloseSelectDropDown = (browserUtils.isWebKit || browserUtils.isIE) && domUtils.isSelectElement(_this4.mouseDownElement); if (needCloseSelectDropDown) _this4._bindMousedownHandler(); _this4._bindBlurHandler(activeElement); _this4.eventState.simulateDefaultBehavior = eventSimulator.mousedown(eventArgs.element, eventArgs.options); if (_this4.eventState.simulateDefaultBehavior === false) _this4.eventState.simulateDefaultBehavior = needCloseSelectDropDown && !_this4.eventState.mousedownPrevented; return _this4._ensureActiveElementBlur(activeElement); }).then(function () { return _this4._focus(eventArgs); }); }; ClickAutomation.prototype._ensureActiveElementBlur = function _ensureActiveElementBlur(element) { var _this5 = this; // NOTE: In some cases, mousedown may lead to active element change (browsers raise blur). // We simulate the blur event if the active element was changed after the mousedown, and // the blur event does not get raised automatically (B239273, B253520) return new Promise(function (resolve) { var simulateBlur = domUtils.getActiveElement() !== element && !_this5.eventState.blurRaised; if (!simulateBlur) { resolve(); return; } if (browserUtils.isIE && browserUtils.version < 12) { // NOTE: In whatever way an element is blurred from the client script, the // blur event is raised asynchronously in IE (in MSEdge focus/blur is sync) (0, _nextTick2.default)().then(function () { if (!_this5.eventState.blurRaised) eventSimulator.blur(element); resolve(); }); } else { eventSimulator.blur(element); resolve(); } }); }; ClickAutomation.prototype._focus = function _focus(eventArgs) { if (this.eventState.simulateDefaultBehavior === false) return Promise.resolve(); // NOTE: If a target element is a contentEditable element, we need to call focusAndSetSelection directly for // this element. Otherwise, if the element obtained by elementFromPoint is a child of the contentEditable // element, a selection position may be calculated incorrectly (by using the caretPos option). var elementForFocus = domUtils.isContentEditableElement(this.element) ? this.element : eventArgs.element; // NOTE: IE doesn't perform focus if active element has been changed while executing mousedown var simulateFocus = !browserUtils.isIE || this.activeElementBeforeMouseDown === domUtils.getActiveElement(); return (0, _utils.focusAndSetSelection)(elementForFocus, simulateFocus, this.caretPos); }; ClickAutomation._getElementForClick = function _getElementForClick(mouseDownElement, topElement, mouseDownElementParentNodes) { var topElementParentNodes = domUtils.getParents(topElement); var areElementsSame = domUtils.isTheSameNode(topElement, mouseDownElement); // NOTE: Mozilla Firefox always skips click, if an element under cursor has been changed after mousedown. if (browserUtils.isFirefox) return areElementsSame ? mouseDownElement : null; if (!areElementsSame) { if (mouseDownElement.contains(topElement) && !domUtils.isEditableFormElement(topElement)) return mouseDownElement; if (topElement.contains(mouseDownElement)) return topElement; // NOTE: If elements are not in the parent-child relationships, // non-ff browsers raise the `click` event for their common parent. return arrayUtils.getCommonElement(topElementParentNodes, mouseDownElementParentNodes); } // NOTE: In case the target element and the top element are the same, // non-FF browsers are dispatching the `click` event if the target // element hasn't changed its position in the DOM after mousedown. return arrayUtils.equals(mouseDownElementParentNodes, topElementParentNodes) ? mouseDownElement : null; }; ClickAutomation.prototype._mouseup = function _mouseup(eventArgs) { var _this6 = this; return _cursor2.default.buttonUp().then(function () { return _this6._getElementForEvent(eventArgs); }).then(function (element) { eventArgs.element = element; _this6.eventState.clickElement = ClickAutomation._getElementForClick(_this6.mouseDownElement, element, _this6.targetElementParentNodes); var timeStamp = {}; var getTimeStamp = function getTimeStamp(e) { timeStamp = e.timeStamp; listeners.removeInternalEventListener(window, ['mouseup'], getTimeStamp); }; if (!browserUtils.isIE) listeners.addInternalEventListener(window, ['mouseup'], getTimeStamp); eventSimulator.mouseup(element, eventArgs.options); return { timeStamp: timeStamp }; }); }; ClickAutomation.prototype._click = function _click(eventArgs) { var clickCommand = (0, _clickCommand2.default)(this.eventState, eventArgs); clickCommand.run(); return eventArgs; }; ClickAutomation.prototype.run = function run(useStrictElementCheck) { var _this7 = this; var eventArgs = null; return this._ensureElement(useStrictElementCheck).then(function (_ref) { var element = _ref.element, clientPoint = _ref.clientPoint, screenPoint = _ref.screenPoint, devicePoint = _ref.devicePoint; eventArgs = { point: clientPoint, screenPoint: screenPoint, element: element, options: extend({ clientX: clientPoint.x, clientY: clientPoint.y, screenX: devicePoint.x, screenY: devicePoint.y }, _this7.modifiers) }; // NOTE: we should raise mouseup event with 'mouseActionStepDelay' after we trigger // mousedown event regardless of how long mousedown event handlers were executing return Promise.all([delay(_this7.automationSettings.mouseActionStepDelay), _this7._mousedown(eventArgs)]); }).then(function () { return _this7._mouseup(eventArgs); }).then(function (_ref2) { var timeStamp = _ref2.timeStamp; eventArgs.options.timeStamp = timeStamp; return _this7._click(eventArgs); }); }; return ClickAutomation; }(_visibleElementAutomation2.default); exports.default = ClickAutomation; module.exports = exports['default']; }, "select-child.js": function (exports, module, require) { exports.__esModule = true; var _hammerhead = require('../../deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _testcafeCore = require('../../deps/testcafe-core'); var _testcafeCore2 = _interopRequireDefault(_testcafeCore); var _testcafeUi = require('../../deps/testcafe-ui'); var _testcafeUi2 = _interopRequireDefault(_testcafeUi); var _move2 = require('../move'); var _move3 = _interopRequireDefault(_move2); var _options = require('../../../../test-run/commands/options'); var _offsets = require('../../utils/offsets'); var _settings = require('../../settings'); var _settings2 = _interopRequireDefault(_settings); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Promise = _hammerhead2.default.Promise; var browserUtils = _hammerhead2.default.utils.browser; var featureDetection = _hammerhead2.default.utils.featureDetection; var eventSimulator = _hammerhead2.default.eventSandbox.eventSimulator; var focusBlurSandbox = _hammerhead2.default.eventSandbox.focusBlur; var nativeMethods = _hammerhead2.default.nativeMethods; var domUtils = _testcafeCore2.default.domUtils; var styleUtils = _testcafeCore2.default.styleUtils; var delay = _testcafeCore2.default.delay; var selectElementUI = _testcafeUi2.default.selectElement; var FOCUS_DELAY = featureDetection.isTouchDevice ? 0 : 160; var SelectChildClickAutomation = function () { function SelectChildClickAutomation(element, clickOptions) { _classCallCheck(this, SelectChildClickAutomation); this.element = element; this.modifiers = clickOptions.modifiers; this.caretPos = clickOptions.caretPos; this.offsetX = clickOptions.offsetX; this.offsetY = clickOptions.offsetY; this.speed = clickOptions.speed; this.automationSettings = new _settings2.default(clickOptions.speed); this.parentSelect = domUtils.getSelectParent(this.element); this.optionListExpanded = this.parentSelect ? selectElementUI.isOptionListExpanded(this.parentSelect) : false; this.childIndex = null; this.clickCausesChange = false; if (this.parentSelect) { var isOption = domUtils.isOptionElement(this.element); var selectedIndex = this.parentSelect.selectedIndex; this.childIndex = isOption ? domUtils.getElementIndexInParent(this.parentSelect, this.element) : domUtils.getElementIndexInParent(this.parentSelect, this.element); var parent = nativeMethods.nodeParentNodeGetter.call(this.element); var parentOptGroup = domUtils.isOptionGroupElement(parent) ? parent : null; var isDisabled = this.element.disabled || parentOptGroup && parentOptGroup.disabled; this.clickCausesChange = isOption && !isDisabled && this.childIndex !== selectedIndex; } this.eventsArgs = { options: this.modifiers, element: this.element }; } SelectChildClickAutomation.prototype._calculateEventArguments = function _calculateEventArguments() { var childElement = this.optionListExpanded ? selectElementUI.getEmulatedChildElement(this.element) : this.element; var parentSelectSize = styleUtils.getSelectElementSize(this.parentSelect) > 1; return { options: this.modifiers, element: browserUtils.isIE && parentSelectSize ? this.parentSelect : childElement }; }; SelectChildClickAutomation.prototype._getMoveArguments = function _getMoveArguments() { var element = null; var offsetX = null; var offsetY = null; if (this.optionListExpanded) { element = selectElementUI.getEmulatedChildElement(this.element); var moveActionOffsets = (0, _offsets.getDefaultAutomationOffsets)(element); offsetX = moveActionOffsets.offsetX; offsetY = moveActionOffsets.offsetY; } else { element = document.documentElement; var elementCenter = selectElementUI.getSelectChildCenter(this.element); offsetX = elementCenter.x; offsetY = elementCenter.y; } return { element: element, offsetX: offsetX, offsetY: offsetY, speed: this.speed }; }; SelectChildClickAutomation.prototype._move = function _move(_ref) { var _this = this; var element = _ref.element, offsetX = _ref.offsetX, offsetY = _ref.offsetY, speed = _ref.speed; var moveOptions = new _options.MoveOptions({ offsetX: offsetX, offsetY: offsetY, speed: speed, modifiers: this.modifiers }, false); var moveAutomation = new _move3.default(element, moveOptions); return moveAutomation.run().then(function () { return delay(_this.automationSettings.mouseActionStepDelay); }); }; SelectChildClickAutomation.prototype._mousedown = function _mousedown() { var _this2 = this; if (browserUtils.isFirefox) { eventSimulator.mousedown(this.eventsArgs.element, this.eventsArgs.options); if (this.clickCausesChange) this.parentSelect.selectedIndex = this.childIndex; return this._focus(); } if (browserUtils.isIE) { eventSimulator.mousedown(this.eventsArgs.element, this.eventsArgs.options); return this._focus(); } // NOTE: In Chrome, document.activeElement is 'select' after mousedown. But we need to // raise blur and change the event for a previously active element during focus raising. // That's why we should change the event order and raise focus before mousedown. return this._focus().then(function () { return delay(FOCUS_DELAY); }).then(function () { eventSimulator.mousedown(_this2.eventsArgs.element, _this2.eventsArgs.options); if (_this2.clickCausesChange) _this2.parentSelect.selectedIndex = _this2.childIndex; }); }; SelectChildClickAutomation.prototype._focus = function _focus() { var _this3 = this; return new Promise(function (resolve) { focusBlurSandbox.focus(_this3.parentSelect, resolve, false, true); }); }; SelectChildClickAutomation.prototype._mouseup = function _mouseup() { var elementForMouseupEvent = browserUtils.isIE ? this.parentSelect : this.eventsArgs.element; eventSimulator.mouseup(elementForMouseupEvent, this.eventsArgs.options); if (browserUtils.isIE && this.clickCausesChange) this.parentSelect.selectedIndex = this.childIndex; var simulateInputEventOnValueChange = browserUtils.isFirefox || browserUtils.isSafari || browserUtils.isChrome && browserUtils.version >= 53; var simulateChangeEventOnValueChange = simulateInputEventOnValueChange || browserUtils.isIE; if (simulateInputEventOnValueChange && this.clickCausesChange) eventSimulator.input(this.parentSelect); if (simulateChangeEventOnValueChange && this.clickCausesChange) eventSimulator.change(this.parentSelect); return Promise.resolve(); }; SelectChildClickAutomation.prototype._click = function _click() { eventSimulator.click(this.eventsArgs.element, this.eventsArgs.options); }; SelectChildClickAutomation.prototype.run = function run() { var _this4 = this; if (!this.parentSelect) { eventSimulator.click(this.eventsArgs.element, this.eventsArgs.options); return Promise.resolve(); } if (!this.optionListExpanded) selectElementUI.scrollOptionListByChild(this.element); var moveArguments = this._getMoveArguments(); this.eventsArgs = this._calculateEventArguments(); if (styleUtils.getSelectElementSize(this.parentSelect) <= 1) { return this._move(moveArguments).then(function () { return _this4._click(); }); } return this._move(moveArguments).then(function () { return _this4._mousedown(); }).then(function () { return _this4._mouseup(); }).then(function () { return _this4._click(); }); }; return SelectChildClickAutomation; }(); exports.default = SelectChildClickAutomation; module.exports = exports['default']; } }, "dblclick.js": function (exports, module, require) { exports.__esModule = true; var _hammerhead = require('../deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _testcafeCore = require('../deps/testcafe-core'); var _testcafeCore2 = _interopRequireDefault(_testcafeCore); var _options = require('../../../test-run/commands/options'); var _visibleElementAutomation = require('./visible-element-automation'); var _visibleElementAutomation2 = _interopRequireDefault(_visibleElementAutomation); var _click = require('./click'); var _click2 = _interopRequireDefault(_click); var _settings = require('../settings'); var _settings2 = _interopRequireDefault(_settings); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if