UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

1,313 lines (961 loc) 95.2 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 initTestCafeUI(window) { 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": { "ui": { "cursor": { "iframe-cursor.js": function (exports, module, require) { exports.__esModule = true; var _hammerhead = require('../deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _testcafeCore = require('../deps/testcafe-core'); var _messages = require('./messages'); var _messages2 = _interopRequireDefault(_messages); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var browserUtils = _hammerhead2.default.utils.browser; // HACK: In most browsers, the iframe's getElementFromPoint function ignores elements // from the parent frame. But in IE it doesn't, and our cursor overlaps the target // element. So, we move the cursor to a position one pixel farther to avoid this. var RECOGNITION_INCREMENT = browserUtils.isIE ? 1 : 0; exports.default = { move: function move(x, y) { var msg = { cmd: _messages2.default.moveRequest, x: x + RECOGNITION_INCREMENT, y: y + RECOGNITION_INCREMENT }; return (0, _testcafeCore.sendRequestToFrame)(msg, _messages2.default.moveResponse, window.parent); }, leftButtonDown: function leftButtonDown() { return (0, _testcafeCore.sendRequestToFrame)({ cmd: _messages2.default.leftButtonDownRequest }, _messages2.default.leftButtonDownResponse, window.parent); }, rightButtonDown: function rightButtonDown() { return (0, _testcafeCore.sendRequestToFrame)({ cmd: _messages2.default.rightButtonDownRequest }, _messages2.default.rightButtonDownResponse, window.parent); }, buttonUp: function buttonUp() { return (0, _testcafeCore.sendRequestToFrame)({ cmd: _messages2.default.buttonUpRequest }, _messages2.default.buttonUpResponse, window.parent); } }; 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 _uiRoot = require('../ui-root'); var _uiRoot2 = _interopRequireDefault(_uiRoot); var _messages = require('./messages'); var _messages2 = _interopRequireDefault(_messages); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var Promise = _hammerhead2.default.Promise; var shadowUI = _hammerhead2.default.shadowUI; var browserUtils = _hammerhead2.default.utils.browser; var featureDetection = _hammerhead2.default.utils.featureDetection; var messageSandbox = _hammerhead2.default.eventSandbox.message; var styleUtils = _testcafeCore2.default.styleUtils; var positionUtils = _testcafeCore2.default.positionUtils; var CURSOR_CLASS = 'cursor'; var TOUCH_CLASS = 'touch'; var L_MOUSE_DOWN_CLASS = 'l-mouse-down'; var R_MOUSE_DOWN_CLASS = 'r-mouse-down'; var STATE_CLASSES = [L_MOUSE_DOWN_CLASS, R_MOUSE_DOWN_CLASS].join(' '); // Setup cross-iframe interaction messageSandbox.on(messageSandbox.SERVICE_MSG_RECEIVED_EVENT, function (e) { var msg = e.message; var position = null; switch (msg.cmd) { case _messages2.default.moveRequest: position = positionUtils.getIframePointRelativeToParentFrame({ x: msg.x, y: msg.y }, e.source); CursorUI.move(position.x, position.y).then(function () { return messageSandbox.sendServiceMsg({ cmd: _messages2.default.moveResponse }, e.source); }); break; case _messages2.default.leftButtonDownRequest: CursorUI.leftButtonDown().then(function () { return messageSandbox.sendServiceMsg({ cmd: _messages2.default.leftButtonDownResponse }, e.source); }); break; case _messages2.default.rightButtonDownRequest: CursorUI.rightButtonDown().then(function () { return messageSandbox.sendServiceMsg({ cmd: _messages2.default.rightButtonDownResponse }, e.source); }); break; case _messages2.default.buttonUpRequest: CursorUI.buttonUp().then(function () { return messageSandbox.sendServiceMsg({ cmd: _messages2.default.buttonUpResponse }, e.source); }); break; } }); var CursorUI = { cursorElement: null, x: 50, y: 50, pointerOffsetX: 0, pointerOffsetY: 0, _createElement: function _createElement() { this.cursorElement = document.createElement('div'); shadowUI.addClass(this.cursorElement, CURSOR_CLASS); // NOTE: For IE, we can't use the touch cursor in a cross-domain iframe // because we won't be able to get an element under the cursor if (featureDetection.isTouchDevice && !browserUtils.isIE) { shadowUI.addClass(this.cursorElement, TOUCH_CLASS); // NOTE: in touch mode, the pointer should be in the center of the cursor this.pointerOffsetX = Math.ceil(styleUtils.getWidth(this.cursorElement) / 2); this.pointerOffsetY = Math.ceil(styleUtils.getHeight(this.cursorElement) / 2); } _uiRoot2.default.element().appendChild(this.cursorElement); }, isVisible: function isVisible() { return this.cursorElement && styleUtils.get(this.cursorElement, 'visibility') !== 'hidden'; }, hide: function hide() { if (!this.cursorElement) this._createElement(); styleUtils.set(this.cursorElement, 'visibility', 'hidden'); }, show: function show() { if (!this.cursorElement) this._createElement(); styleUtils.set(this.cursorElement, 'visibility', ''); }, move: function move(x, y) { this.x = x; this.y = y; if (!this.cursorElement) this._createElement(); styleUtils.set(this.cursorElement, { left: this.x - this.pointerOffsetX + 'px', top: this.y - this.pointerOffsetY + 'px' }); return Promise.resolve(); }, leftButtonDown: function leftButtonDown() { if (!this.cursorElement) this._createElement(); shadowUI.removeClass(this.cursorElement, STATE_CLASSES); shadowUI.addClass(this.cursorElement, L_MOUSE_DOWN_CLASS); return Promise.resolve(); }, rightButtonDown: function rightButtonDown() { if (!this.cursorElement) this._createElement(); shadowUI.removeClass(this.cursorElement, STATE_CLASSES); shadowUI.addClass(this.cursorElement, R_MOUSE_DOWN_CLASS); return Promise.resolve(); }, buttonUp: function buttonUp() { if (!this.cursorElement) this._createElement(); shadowUI.removeClass(this.cursorElement, STATE_CLASSES); return Promise.resolve(); } }; exports.default = CursorUI; module.exports = exports['default']; }, "messages.js": function (exports, module, require) { exports.__esModule = true; exports.default = { moveRequest: 'ui|cursor|move|request', leftButtonDownRequest: 'ui|cursor|leftbuttondown|request', rightButtonDownRequest: 'ui|cursor|rightbuttondown|request', buttonUpRequest: 'ui|cursor|buttonup|request', moveResponse: 'ui|cursor|move|response', leftButtonDownResponse: 'ui|cursor|leftbuttondown|response', rightButtonDownResponse: 'ui|cursor|rightbuttondown|response', buttonUpResponse: 'ui|cursor|buttonup|response' }; 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']; } }, "index.js": function (exports, module, require) { var _hammerhead = require('./deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _testcafeCore = require('./deps/testcafe-core'); var _testcafeCore2 = _interopRequireDefault(_testcafeCore); var _selectElement = require('./select-element'); var selectElement = _interopRequireWildcard(_selectElement); var _modalBackground = require('./modal-background'); var modalBackground = _interopRequireWildcard(_modalBackground); var _progressPanel = require('./progress-panel'); var _progressPanel2 = _interopRequireDefault(_progressPanel); var _statusBar = require('./status-bar'); var _statusBar2 = _interopRequireDefault(_statusBar); var _iframeStatusBar = require('./status-bar/iframe-status-bar'); var _iframeStatusBar2 = _interopRequireDefault(_iframeStatusBar); var _cursor = require('./cursor'); var _cursor2 = _interopRequireDefault(_cursor); var _iframeCursor = require('./cursor/iframe-cursor'); var iframeCursorUI = _interopRequireWildcard(_iframeCursor); var _screenshotMark = require('./screenshot-mark'); var _screenshotMark2 = _interopRequireDefault(_screenshotMark); var _uiRoot = require('./ui-root'); var _uiRoot2 = _interopRequireDefault(_uiRoot); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var Promise = _hammerhead2.default.Promise; var messageSandbox = _hammerhead2.default.eventSandbox.message; var sendRequestToFrame = _testcafeCore2.default.sendRequestToFrame; var HIDE_REQUEST_CMD = 'ui|hide|request'; var HIDE_RESPONSE_CMD = 'ui|hide|response'; var SHOW_REQUEST_CMD = 'ui|show|request'; var SHOW_RESPONSE_CMD = 'ui|show|response'; // Setup cross-iframe interaction messageSandbox.on(messageSandbox.SERVICE_MSG_RECEIVED_EVENT, function (e) { if (e.message.cmd === HIDE_REQUEST_CMD) { _uiRoot2.default.hide(); messageSandbox.sendServiceMsg({ cmd: HIDE_RESPONSE_CMD }, e.source); } else if (e.message.cmd === SHOW_REQUEST_CMD) { _uiRoot2.default.show(); messageSandbox.sendServiceMsg({ cmd: SHOW_RESPONSE_CMD }, e.source); } }); exports.cursorUI = _cursor2.default; exports.iframeCursorUI = iframeCursorUI; exports.selectElement = selectElement; exports.modalBackground = modalBackground; exports.ProgressPanel = _progressPanel2.default; exports.StatusBar = _statusBar2.default; exports.IframeStatusBar = _iframeStatusBar2.default; exports.get = require; exports.hide = function (hideTopRoot) { if (hideTopRoot) return sendRequestToFrame({ cmd: HIDE_REQUEST_CMD }, HIDE_RESPONSE_CMD, window.top); _uiRoot2.default.hide(); return Promise.resolve(); }; exports.show = function (showTopRoot) { if (showTopRoot) return sendRequestToFrame({ cmd: SHOW_REQUEST_CMD }, SHOW_RESPONSE_CMD, window.top); _uiRoot2.default.show(); return Promise.resolve(); }; exports.showScreenshotMark = function (url) { return _screenshotMark2.default.show(url); }; exports.hideScreenshotMark = function () { return _screenshotMark2.default.hide(); }; var nativeMethods = _hammerhead2.default.nativeMethods; var evalIframeScript = _hammerhead2.default.EVENTS.evalIframeScript; nativeMethods.objectDefineProperty(window, '%testCafeUI%', { configurable: true, value: exports }); // eslint-disable-next-line no-undef _hammerhead2.default.on(evalIframeScript, function (e) { return initTestCafeUI(nativeMethods.contentWindowGetter.call(e.iframe), true); }); }, "modal-background.js": function (exports, module, require) { exports.__esModule = true; exports.initAndShowLoadingText = initAndShowLoadingText; exports.show = show; exports.hide = hide; exports.showLoadingIcon = showLoadingIcon; exports.hideLoadingIcon = hideLoadingIcon; var _hammerhead = require('./deps/hammerhead'); var _testcafeCore = require('./deps/testcafe-core'); var _uiRoot = require('./ui-root'); var _uiRoot2 = _interopRequireDefault(_uiRoot); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } //Const var LOADING_TEXT = 'Loading page...'; var BACKGROUND_CLASS = 'modal-background'; var LOADING_TEXT_CLASS = 'loading-text'; var BACKGROUND_OPACITY = 0.7; var BACKGROUND_OPACITY_WITH_LOADING_TEXT = 0.8; var LOADING_ICON_CLASS = 'loading-icon'; //Globals var backgroundDiv = null; var loadingTextDiv = null; var loadingIconDiv = null; var initialized = false; //Markup function createBackground() { var root = _uiRoot2.default.element(); backgroundDiv = document.createElement('div'); root.appendChild(backgroundDiv); _hammerhead.shadowUI.addClass(backgroundDiv, BACKGROUND_CLASS); loadingTextDiv = document.createElement('div'); _hammerhead.nativeMethods.nodeTextContentSetter.call(loadingTextDiv, LOADING_TEXT); root.appendChild(loadingTextDiv); _hammerhead.shadowUI.addClass(loadingTextDiv, LOADING_TEXT_CLASS); loadingIconDiv = document.createElement('div'); _testcafeCore.styleUtils.set(loadingIconDiv, 'visibility', 'hidden'); root.appendChild(loadingIconDiv); _hammerhead.shadowUI.addClass(loadingIconDiv, LOADING_ICON_CLASS); } //Behavior function adjustLoadingTextPos() { var wHeight = _testcafeCore.styleUtils.getHeight(window); var wWidth = _testcafeCore.styleUtils.getWidth(window); var loadingTextHidden = !_testcafeCore.styleUtils.hasDimensions(loadingTextDiv); if (loadingTextHidden) { _testcafeCore.styleUtils.set(loadingTextDiv, 'visibility', 'hidden'); _testcafeCore.styleUtils.set(loadingTextDiv, 'display', 'block'); } _testcafeCore.styleUtils.set(loadingTextDiv, { left: Math.max((wWidth - _testcafeCore.styleUtils.getWidth(loadingTextDiv)) / 2, 0) + 'px', top: Math.max((wHeight - _testcafeCore.styleUtils.getHeight(loadingTextDiv)) / 2, 0) + 'px' }); if (loadingTextHidden) { _testcafeCore.styleUtils.set(loadingTextDiv, 'display', 'none'); _testcafeCore.styleUtils.set(loadingTextDiv, 'visibility', ''); } } function initSizeAdjustments() { var adjust = function adjust() { var wHeight = _testcafeCore.styleUtils.getHeight(window); var wWidth = _testcafeCore.styleUtils.getWidth(window); _testcafeCore.styleUtils.set(backgroundDiv, 'width', wWidth + 'px'); _testcafeCore.styleUtils.set(backgroundDiv, 'height', wHeight + 'px'); _testcafeCore.styleUtils.set(loadingIconDiv, { left: Math.round((wWidth - _testcafeCore.styleUtils.getWidth(loadingIconDiv)) / 2) + 'px', top: Math.round((wHeight - _testcafeCore.styleUtils.getHeight(loadingIconDiv)) / 2) + 'px' }); }; adjust(); _testcafeCore.eventUtils.bind(window, 'resize', adjust); } function init() { createBackground(); initSizeAdjustments(); adjustLoadingTextPos(); initialized = true; } function initAndShowLoadingText() { var shown = false; //NOTE: init and show modal background as soon as possible var initAndShow = function initAndShow() { init(); _testcafeCore.styleUtils.set(backgroundDiv, 'opacity', BACKGROUND_OPACITY_WITH_LOADING_TEXT); _testcafeCore.styleUtils.set(backgroundDiv, 'display', 'block'); _testcafeCore.styleUtils.set(loadingTextDiv, 'display', 'block'); shown = true; }; var tryShowBeforeReady = function tryShowBeforeReady() { if (!shown) { if (document.body) initAndShow();else _hammerhead.nativeMethods.setTimeout.call(window, tryShowBeforeReady, 0); } }; tryShowBeforeReady(); //NOTE: ensure that background was shown on ready _testcafeCore.eventUtils.documentReady().then(function () { if (!shown) initAndShow(); }); } function show(transparent) { if (!initialized) init(); _testcafeCore.styleUtils.set(backgroundDiv, 'opacity', transparent ? 0 : BACKGROUND_OPACITY); _testcafeCore.styleUtils.set(backgroundDiv, 'display', 'block'); } function hide() { if (!initialized) return; _testcafeCore.styleUtils.set(loadingTextDiv, 'display', 'none'); _testcafeCore.styleUtils.set(backgroundDiv, 'display', 'none'); } function showLoadingIcon() { _testcafeCore.styleUtils.set(loadingIconDiv, 'visibility', 'visible'); } function hideLoadingIcon() { _testcafeCore.styleUtils.set(loadingIconDiv, 'visibility', 'hidden'); } }, "progress-panel": { "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 _progressBar = require('./progress-bar'); var _progressBar2 = _interopRequireDefault(_progressBar); var _uiRoot = require('../ui-root'); var _uiRoot2 = _interopRequireDefault(_uiRoot); 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 shadowUI = _hammerhead2.default.shadowUI; var nativeMethods = _hammerhead2.default.nativeMethods; var eventUtils = _testcafeCore2.default.eventUtils; var styleUtils = _testcafeCore2.default.styleUtils; var PANEL_CLASS = 'progress-panel'; var TITLE_CLASS = 'title'; var CONTENT_CLASS = 'content'; var UPDATE_INTERVAL = 100; var ANIMATION_UPDATE_INTERVAL = 10; var OPENING_DELAY = 300; var SHOWING_DELAY = 200; var HIDING_DELAY = 600; var MIN_SHOWING_TIME = 1000; var ProgressPanel = function () { function ProgressPanel() { var _this = this; _classCallCheck(this, ProgressPanel); this.startTime = null; this.openingTimeout = null; this.updateInterval = null; this.animationInterval = null; this.panelDiv = document.createElement('div'); _uiRoot2.default.element().appendChild(this.panelDiv); this.titleDiv = document.createElement('div'); this.panelDiv.appendChild(this.titleDiv); this.contentDiv = document.createElement('div'); this.panelDiv.appendChild(this.contentDiv); shadowUI.addClass(this.panelDiv, PANEL_CLASS); shadowUI.addClass(this.titleDiv, TITLE_CLASS); shadowUI.addClass(this.contentDiv, CONTENT_CLASS); ProgressPanel._showAtWindowCenter(this.panelDiv); this.progressBar = new _progressBar2.default(this.contentDiv); this.disposePanel = function () { return ProgressPanel._showAtWindowCenter(_this.panelDiv); }; } ProgressPanel._getInvisibleElementProperty = function _getInvisibleElementProperty(element, property) { var needShowElement = styleUtils.get(element, 'display') === 'none'; if (needShowElement) styleUtils.set(element, 'display', 'block'); var value = element[property]; if (needShowElement) styleUtils.set(element, 'display', 'none'); return value; }; ProgressPanel._showAtWindowCenter = function _showAtWindowCenter(element) { var elementHeight = ProgressPanel._getInvisibleElementProperty(element, 'offsetHeight'); var elementWidth = ProgressPanel._getInvisibleElementProperty(element, 'offsetWidth'); var top = Math.round(styleUtils.getHeight(window) / 2 - elementHeight / 2); var left = Math.round(styleUtils.getWidth(window) / 2 - elementWidth / 2); styleUtils.set(element, { left: left + 'px', top: top + 'px' }); }; ProgressPanel.prototype._setCurrentProgress = function _setCurrentProgress() { var progress = Math.round((Date.now() - this.startTime) / this.maxTimeout * 100); this.progressBar.setValue(progress); }; ProgressPanel.prototype._setSuccess = function _setSuccess(value) { this.progressBar.setSuccess(value); }; ProgressPanel.prototype._stopAnimation = function _stopAnimation() { nativeMethods.clearInterval.call(window, this.animationInterval); }; ProgressPanel.prototype._animate = function _animate(el, duration, show, complete) { var _this2 = this; var startTime = Date.now(); var startOpacityValue = show ? 0 : 1; var passedTime = 0; var progress = 0; var delta = 0; if (show) { styleUtils.set(el, 'opacity', startOpacityValue); styleUtils.set(el, 'display', 'block'); } this._stopAnimation(); this.animationInterval = nativeMethods.setInterval.call(window, function () { passedTime = Date.now() - startTime; progress = Math.min(passedTime / duration, 1); delta = 0.5 - Math.cos(progress * Math.PI) / 2; styleUtils.set(el, 'opacity', startOpacityValue + (show ? delta : -delta)); if (progress === 1) { _this2._stopAnimation(); if (complete) complete(); } }, ANIMATION_UPDATE_INTERVAL); }; ProgressPanel.prototype._showPanel = function _showPanel() { eventUtils.bind(window, 'resize', this.disposePanel); this._animate(this.panelDiv, SHOWING_DELAY, true); }; ProgressPanel.prototype._hidePanel = function _hidePanel(force) { var _this3 = this; this.startTime = null; eventUtils.unbind(window, 'resize', this.disposePanel); this._animate(this.panelDiv, force ? 0 : HIDING_DELAY, false, function () { return styleUtils.set(_this3.panelDiv, 'display', 'none'); }); }; ProgressPanel.prototype.show = function show(text, timeout) { var _this4 = this; this.startTime = Date.now(); this.maxTimeout = timeout; nativeMethods.nodeTextContentSetter.call(this.titleDiv, text); this._setSuccess(false); this.openingTimeout = nativeMethods.setTimeout.call(window, function () { _this4.openingTimeout = null; _this4._setCurrentProgress(); _this4._showPanel(); _this4.updateInterval = nativeMethods.setInterval.call(window, function () { return _this4._setCurrentProgress(); }, UPDATE_INTERVAL); }, OPENING_DELAY); }; ProgressPanel.prototype.close = function close(success) { var _this5 = this; if (success) this._setSuccess(true); if (this.openingTimeout) { nativeMethods.clearTimeout.call(window, this.openingTimeout); this.openingTimeout = null; } if (this.updateInterval) { nativeMethods.clearInterval.call(window, this.updateInterval); this.updateInterval = null; } if (success) { if (this.startTime && Date.now() - this.startTime < MIN_SHOWING_TIME) { nativeMethods.setTimeout.call(window, function () { nativeMethods.setTimeout.call(window, function () { return _this5._hidePanel(false); }, SHOWING_DELAY); }, UPDATE_INTERVAL); } else nativeMethods.setTimeout.call(window, function () { return _this5._hidePanel(false); }, SHOWING_DELAY); } else this._hidePanel(true); }; return ProgressPanel; }(); exports.default = ProgressPanel; module.exports = exports['default']; }, "progress-bar.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); 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 shadowUI = _hammerhead2.default.shadowUI; var styleUtils = _testcafeCore2.default.styleUtils; var CONTAINER_CLASS = 'progress-bar'; var VALUE_CLASS = 'value'; var SUCCESS_CLASS = 'success'; var ProgressBar = function () { function ProgressBar(containerElement) { _classCallCheck(this, ProgressBar); this.containerElement = document.createElement('div'); this.valueElement = document.createElement('div'); containerElement.appendChild(this.containerElement); this.containerElement.appendChild(this.valueElement); shadowUI.addClass(this.containerElement, CONTAINER_CLASS); shadowUI.addClass(this.valueElement, VALUE_CLASS); } ProgressBar.prototype.setValue = function setValue(value) { value = typeof value !== 'number' ? 0 : Math.min(Math.max(value, 0), 100); styleUtils.set(this.valueElement, 'width', value + '%'); }; ProgressBar.prototype.setSuccess = function setSuccess(value) { if (value) shadowUI.addClass(this.containerElement, SUCCESS_CLASS);else shadowUI.removeClass(this.containerElement, SUCCESS_CLASS); }; return ProgressBar; }(); exports.default = ProgressBar; module.exports = exports['default']; } }, "screenshot-mark.js": function (exports, module, require) { exports.__esModule = true; var _hammerhead = require('./deps/hammerhead'); var _constants = require('../../screenshots/constants'); exports.default = { screenshotMark: null, _createMark: function _createMark() { this.screenshotMark = document.createElement('img'); _hammerhead.shadowUI.addClass(this.screenshotMark, 'screenshot-mark'); this.screenshotMark.style.right = _constants.MARK_RIGHT_MARGIN / window.devicePixelRatio + 'px'; this.screenshotMark.style.width = _constants.MARK_LENGTH / window.devicePixelRatio + 'px'; this.screenshotMark.style.height = _constants.MARK_HEIGHT / window.devicePixelRatio + 'px'; this.hide(); _hammerhead.shadowUI.getRoot().appendChild(this.screenshotMark); }, hide: function hide() { if (!this.screenshotMark) return; this.screenshotMark.style.visibility = 'hidden'; }, show: function show(url) { if (!this.screenshotMark) this._createMark(); _hammerhead.nativeMethods.imageSrcSetter.call(this.screenshotMark, url); this.screenshotMark.style.visibility = ''; } }; module.exports = exports['default']; }, "select-element.js": function (exports, module, require) { exports.__esModule = true; exports.expandOptionList = expandOptionList; exports.collapseOptionList = collapseOptionList; exports.isOptionListExpanded = isOptionListExpanded; exports.getEmulatedChildElement = getEmulatedChildElement; exports.scrollOptionListByChild = scrollOptionListByChild; exports.getSelectChildCenter = getSelectChildCenter; exports.switchOptionsByKeys = switchOptionsByKeys; exports.isOptionElementVisible = isOptionElementVisible; var _hammerhead = require('./deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _testcafeCore = require('./deps/testcafe-core'); var _testcafeCore2 = _interopRequireDefault(_testcafeCore); var _uiRoot = require('./ui-root'); var _uiRoot2 = _interopRequireDefault(_uiRoot); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var shadowUI = _hammerhead2.default.shadowUI; //NOTE: we can't manipulate (open/close option list) with a native select element during test running, so we // draw our custom option list to emulate this. var browserUtils = _hammerhead2.default.utils.browser; var featureDetection = _hammerhead2.default.utils.featureDetection; var nativeMethods = _hammerhead2.default.nativeMethods; var eventSimulator = _hammerhead2.default.eventSandbox.eventSimulator; var listeners = _hammerhead2.default.eventSandbox.listeners; var positionUtils = _testcafeCore2.default.positionUtils; var domUtils = _testcafeCore2.default.domUtils; var styleUtils = _testcafeCore2.default.styleUtils; var eventUtils = _testcafeCore2.default.eventUtils; var arrayUtils = _testcafeCore2.default.arrayUtils; var OPTION_LIST_CLASS = 'tcOptionList'; var OPTION_GROUP_CLASS = 'tcOptionGroup'; var OPTION_CLASS = 'tcOption'; var DISABLED_CLASS = 'disabled'; var MAX_OPTION_LIST_LENGTH = browserUtils.isIE ? 30 : 20; var curSelectEl = null; var optionList = null; var groups = []; var options = []; function onDocumentMouseDown(e) { //NOTE: only in Mozilla 'mousedown' raises for option if ((e.target || e.srcElement) !== curSelectEl && !domUtils.containsElement(curSelectEl, e.target) && !domUtils.containsElement(optionList, e.target)) collapseOptionList(); } function onWindowClick(e, dispatched, preventDefault) { var optionIndex = arrayUtils.indexOf(options, e.target); if (optionIndex < 0) return; preventDefault(); var isDisabled = e.target.className.indexOf(DISABLED_CLASS) > -1; if (isDisabled && browserUtils.isWebKit) return; clickOnOption(optionIndex, isDisabled); } function clickOnOption(optionIndex, isOptionDisabled) { var curSelectIndex = curSelectEl.selectedIndex; var realOption = curSelectEl.getElementsByTagName('option')[optionIndex]; var clickLeadChanges = !isOptionDisabled && optionIndex !== curSelectIndex; if (clickLeadChanges && !browserUtils.isIE) curSelectEl.selectedIndex = optionIndex; if (!browserUtils.isFirefox && !browserUtils.isIE && clickLeadChanges) { eventSimulator.input(curSelectEl); eventSimulator.change(curSelectEl); } if (browserUtils.isFirefox || browserUtils.isIE) eventSimulator.mousedown(browserUtils.isFirefox ? realOption : curSelectEl); if (!featureDetection.isTouchDevice) eventSimulator.mouseup(browserUtils.isFirefox ? realOption : curSelectEl); if ((browserUtils.isFirefox || browserUtils.isIE) && clickLeadChanges) { if (browserUtils.isIE) curSelectEl.selectedIndex = optionIndex; if (!browserUtils.isIE) eventSimulator.input(curSelectEl); eventSimulator.change(curSelectEl); } if (!featureDetection.isTouchDevice) eventSimulator.click(browserUtils.isFirefox || browserUtils.isIE ? realOption : curSelectEl); if (!isOptionDisabled) collapseOptionList(); } function createOption(realOption, parent) { var option = document.createElement('div'); var isOptionDisabled = realOption.disabled || domUtils.getTagName(realOption.parentElement) === 'optgroup' && realOption.parentElement.disabled; // eslint-disable-next-line no-restricted-properties nativeMethods.nodeTextContentSetter.call(option, realOption.text); parent.appendChild(option); shadowUI.addClass(option, OPTION_CLASS); if (isOptionDisabled) { shadowUI.addClass(option, DISABLED_CLASS); styleUtils.set(option, 'color', styleUtils.get(realOption, 'color')); } options.push(option); } function createGroup(realGroup, parent) { var group = document.createElement('div'); nativeMethods.nodeTextContentSetter.call(group, realGroup.label || ' '); parent.appendChild(group); shadowUI.addClass(group, OPTION_GROUP_CLASS); if (group.disabled) { shadowUI.addClass(group, DISABLED_CLASS); styleUtils.set(group, 'color', styleUtils.get(realGroup, 'color')); } createChildren(realGroup.children, group); groups.push(group); } function createChildren(children, parent) { var childrenLength = domUtils.getChildrenLength(children); for (var i = 0; i < childrenLength; i++) { if (domUtils.isOptionElement(children[i])) createOption(children[i], parent);else if (domUtils.getTagName(children[i]) === 'optgroup') createGroup(children[i], parent); } } function expandOptionList(select) { var selectChildren = select.children; if (!selectChildren.length) return; //NOTE: check is option list expanded if (curSelectEl) { var isSelectExpanded = select === curSelectEl; collapseOptionList(); if (isSelectExpanded) return; } curSelectEl = select; optionList = document.createElement('div'); _uiRoot2.default.element().appendChild(optionList); shadowUI.addClass(optionList, OPTION_LIST_CLASS); createChildren(selectChildren, optionList); listeners.addInternalEventListener(window, ['click'], onWindowClick); nativeMethods.setTimeout.call(window, function () { eventUtils.bind(document, 'mousedown', onDocumentMouseDown); }, 0); styleUtils.set(optionList, { position: 'absolute', fontSize: styleUtils.get(curSelectEl, 'fontSize'), fontFamily: styleUtils.get(curSelectEl, 'fontFamily'), minWidth: styleUtils.getWidth(curSelectEl) + 'px', left: positionUtils.getOffsetPosition(curSelectEl).left + 'px', height: domUtils.getSelectVisibleChildren(select).length > MAX_OPTION_LIST_LENGTH ? styleUtils.getOptionHeight(select) * MAX_OPTION_LIST_LENGTH : '' }); var selectTopPosition = positionUtils.getOffsetPosition(curSelectEl).top; var optionListHeight = styleUtils.getHeight(optionList); var optionListTopPosition = selectTopPosition + styleUtils.getHeight(curSelectEl) + 2; if (optionListTopPosition + optionListHeight > styleUtils.getScrollTop(window) + styleUtils.getHeight(window)) { var topPositionAboveSelect = selectTopPosition - 3 - optionListHeight; if (topPositionAboveSelect >= styleUtils.getScrollTop(window)) optionListTopPosition = topPositionAboveSelect; } styleUtils.set(optionList, 'top', optionListTopPosition + 'px'); } function collapseOptionList() { domUtils.remove(optionList); eventUtils.unbind(document, 'mousedown', onDocumentMouseDown); optionList = null; curSelectEl = null; options = []; groups = []; } function isOptionListExpanded(select) { return select ? select === curSelectEl : !!curSelectEl; } function getEmulatedChildElement(element) { var isGroup = domUtils.getTagName(element) === 'optgroup'; var elementIndex = isGroup ? domUtils.getElementIndexInParent(curSelectEl, element) : domUtils.getElementIndexInParent(curSelectEl, element); if (!isGroup) return options[elementIndex]; return groups[elementIndex]; } function scrollOptionListByChild(child) { var select = domUtils.getSelectParent(child); if (!select) return; var realSizeValue = styleUtils.getSelectElementSize(select); var optionHeight = styleUtils.getOptionHeight(select); var scrollIndent = 0; var topVisibleIndex = Math.max(styleUtils.getScrollTop(select) / optionHeight, 0); var bottomVisibleIndex = topVisibleIndex + realSizeValue - 1; var childIndex = domUtils.getChildVisibleIndex(select, child); if (childIndex < topVisibleIndex) { scrollIndent = optionHeight * (topVisibleIndex - childIndex); styleUtils.setScrollTop(select, Math.max(styleUtils.getScrollTop(select) - scrollIndent, 0)); } else if (childIndex > bottomVisibleIndex) { scrollIndent = optionHeight * (childIndex - bottomVisibleIndex); styleUtils.setScrollTop(select, styleUtils.getScrollTop(select) + scrollIndent); } } function getSelectChildCenter(child) { var select = domUtils.getSelectParent(child); if (!select) { return { x: 0, y: 0 }; } var optionHeight = styleUtils.getOptionHeight(select); var childRectangle = positionUtils.getElementRectangle(child); return { x: Math.round(childRectangle.left + childRectangle.width / 2), y: Math.round(childRectangle.top + optionHeight / 2) }; } function switchOptionsByKeys(element, command) { var selectSize = styleUtils.getSelectElementSize(element); var optionListHidden = !styleUtils.hasDimensions(shadowUI.select('.' + OPTION_LIST_CLASS)[0]); if (/down|up/.test(command) || !browserUtils.isIE && (selectSize <= 1 || browserUtils.isFirefox) && (optionListHidden || browserUtils.isFirefox) && /left|right/.test(command)) { var realOptions = element.querySelectorAll('option'); var enabledOptions = []; for (var i = 0; i < realOptions.length; i++) { var parent = realOptions[i].parentElement; if (!realOptions[i].disabled && !(domUtils.getTagName(parent) === 'optgroup' && parent.disabled)) enabledOptions.push(realOptions[i]); } var curSelectedOptionIndex = arrayUtils.indexOf(enabledOptions, realOptions[element.selectedIndex]); var nextIndex = curSelectedOptionIndex + (/down|right/.test(command) ? 1 : -1); if (nextIndex >= 0 && nextIndex < enabledOptions.length) { element.selectedIndex = arrayUtils.indexOf(realOptions, enabledOptions[nextIndex]); if (!browserUtils.isIE) eventSimulator.input(element); eventSimulator.change(element); } } } function isOptionElementVisible(el) { var parentSelect = domUtils.getSelectParent(el); if (!parentSelect) return true; var expanded = isOptionListExpanded(parentSelect); var selectSizeValue = styleUtils.getSelectElementSize(parentSelect); return expanded || selectSizeValue > 1; } }, "status-bar": { "iframe-status-bar.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 _messages = require('./messages'); var _messages2 = _interopRequireDefault(_messages); var _index = require('./index'); var _index2 = _interopRequireDefault(_index); 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 sendRequestToFrame = _testcafeCore2.default.sendRequestToFrame; var messageSandbox = _hammerhead2.default.eventSandbox.message; var IframeStatusBar = function (_StatusBar) { _inherits(IframeStatusBar, _StatusBar); function IframeStatusBar() { _classCallCheck(this, IframeStatusBar); return _possibleConstructorReturn(this, _StatusBar.call(this)); } //API IframeStatusBar.prototype.showWaitingElementStatus = function showWaitingElementStatus(timeout) { messageSandbox.sendServiceMsg({ cmd: _messages2.default.startWaitingElement, timeout: timeout }, window.top); }; IframeStatusBar.prototype.hideWaitingElementStatus = function hideWaitingElementStatus(waitingSuccess) { var msg = { cmd: _messages2.default.endWaitingElementRequest, waitingSuccess: waitingSuccess }; return sendRequestToFrame(msg, _messages2.default.endWaitingElementResponse, window.top); }; IframeStatusBar.prototype.showWaitingAssertionRetriesStatus = function showWaitingAssertionRetriesStatus(timeout) { messageSandbox.sendServiceMsg({ cmd: _messages2.default.startWaitingAssertionRetries, timeout: timeout }, window.top); }; IframeStatusBar.prototype.hideWaitingAssertionRetriesStatus = function hideWaitingAssertionRetriesStatus(waitingSuccess) { var msg = { cmd: _messages2.default.endWaitingAssertionRetriesRequest, waitingSuccess: waitingSuccess }; return sendRequestToFrame(msg, _messages2.default.endWaitingAssertionRetriesResponse, window.top); }; return IframeStatusBar; }(_index2.default); exports.default = IframeStatusBar; module.exports = exports['default']; }, "index.js": function (exports, module, require) { exports.__esModule = true; var _hammerhead = require('./../deps/hammerhea