UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

1,440 lines (1,093 loc) 180 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 initTestCafeCore(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, [], ''); })({ "pinkie": { "index.js": function (exports, module, require) { var PENDING = 'pending'; var SETTLED = 'settled'; var FULFILLED = 'fulfilled'; var REJECTED = 'rejected'; var NOOP = function NOOP() {}; var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function'; var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate; var asyncQueue = []; var asyncTimer; function asyncFlush() { // run promise callbacks for (var i = 0; i < asyncQueue.length; i++) { asyncQueue[i][0](asyncQueue[i][1]); } // reset async asyncQueue asyncQueue = []; asyncTimer = false; } function asyncCall(callback, arg) { asyncQueue.push([callback, arg]); if (!asyncTimer) { asyncTimer = true; asyncSetTimer(asyncFlush, 0); } } function invokeResolver(resolver, promise) { function resolvePromise(value) { resolve(promise, value); } function rejectPromise(reason) { reject(promise, reason); } try { resolver(resolvePromise, rejectPromise); } catch (e) { rejectPromise(e); } } function invokeCallback(subscriber) { var owner = subscriber.owner; var settled = owner._state; var value = owner._data; var callback = subscriber[settled]; var promise = subscriber.then; if (typeof callback === 'function') { settled = FULFILLED; try { value = callback(value); } catch (e) { reject(promise, e); } } if (!handleThenable(promise, value)) { if (settled === FULFILLED) { resolve(promise, value); } if (settled === REJECTED) { reject(promise, value); } } } function handleThenable(promise, value) { var resolved; try { if (promise === value) { throw new TypeError('A promises callback cannot return that same promise.'); } if (value && (typeof value === 'function' || typeof value === 'object')) { // then should be retrieved only once var then = value.then; if (typeof then === 'function') { then.call(value, function (val) { if (!resolved) { resolved = true; if (value === val) { fulfill(promise, val); } else { resolve(promise, val); } } }, function (reason) { if (!resolved) { resolved = true; reject(promise, reason); } }); return true; } } } catch (e) { if (!resolved) { reject(promise, e); } return true; } return false; } function resolve(promise, value) { if (promise === value || !handleThenable(promise, value)) { fulfill(promise, value); } } function fulfill(promise, value) { if (promise._state === PENDING) { promise._state = SETTLED; promise._data = value; asyncCall(publishFulfillment, promise); } } function reject(promise, reason) { if (promise._state === PENDING) { promise._state = SETTLED; promise._data = reason; asyncCall(publishRejection, promise); } } function publish(promise) { promise._then = promise._then.forEach(invokeCallback); } function publishFulfillment(promise) { promise._state = FULFILLED; publish(promise); } function publishRejection(promise) { promise._state = REJECTED; publish(promise); if (!promise._handled && isNode) { global.process.emit('unhandledRejection', promise._data, promise); } } function notifyRejectionHandled(promise) { global.process.emit('rejectionHandled', promise); } /** * @class */ function Promise(resolver) { if (typeof resolver !== 'function') { throw new TypeError('Promise resolver ' + resolver + ' is not a function'); } if (this instanceof Promise === false) { throw new TypeError('Failed to construct \'Promise\': Please use the \'new\' operator, this object constructor cannot be called as a function.'); } this._then = []; invokeResolver(resolver, this); } Promise.prototype = { constructor: Promise, _state: PENDING, _then: null, _data: undefined, _handled: false, then: function then(onFulfillment, onRejection) { var subscriber = { owner: this, then: new this.constructor(NOOP), fulfilled: onFulfillment, rejected: onRejection }; if ((onRejection || onFulfillment) && !this._handled) { this._handled = true; if (this._state === REJECTED && isNode) { asyncCall(notifyRejectionHandled, this); } } if (this._state === FULFILLED || this._state === REJECTED) { // already resolved, call callback async asyncCall(invokeCallback, subscriber); } else { // subscribe this._then.push(subscriber); } return subscriber.then; }, catch: function _catch(onRejection) { return this.then(null, onRejection); } }; Promise.all = function (promises) { if (!Array.isArray(promises)) { throw new TypeError('You must pass an array to Promise.all().'); } return new Promise(function (resolve, reject) { var results = []; var remaining = 0; function resolver(index) { remaining++; return function (value) { results[index] = value; if (! --remaining) { resolve(results); } }; } for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === 'function') { promise.then(resolver(i), reject); } else { results[i] = promise; } } if (!remaining) { resolve(results); } }); }; Promise.race = function (promises) { if (!Array.isArray(promises)) { throw new TypeError('You must pass an array to Promise.race().'); } return new Promise(function (resolve, reject) { for (var i = 0, promise; i < promises.length; i++) { promise = promises[i]; if (promise && typeof promise.then === 'function') { promise.then(resolve, reject); } else { resolve(promise); } } }); }; Promise.resolve = function (value) { if (value && typeof value === 'object' && value.constructor === Promise) { return value; } return new Promise(function (resolve) { resolve(value); }); }; Promise.reject = function (reason) { return new Promise(function (resolve, reject) { reject(reason); }); }; module.exports = Promise; } }, "testcafe-release": { "src": { "browser": { "connection": { "command.js": function (exports, module, require) { exports.__esModule = true; // -------------------------------------------------------- // WARNING: this file is used by both the client and the server. // Do not use any browser or node-specific API! // -------------------------------------------------------- exports.default = { run: 'run', idle: 'idle' }; module.exports = exports['default']; }, "status.js": function (exports, module, require) { exports.__esModule = true; exports.default = { ok: 'ok', closing: 'closing' }; module.exports = exports['default']; }, "unstable-network-mode.js": function (exports, module, require) { exports.__esModule = true; var UNSTABLE_NETWORK_MODE_HEADER = exports.UNSTABLE_NETWORK_MODE_HEADER = 'x-testcafe-cache-page-request'; } } }, "client": { "browser": { "index.js": function (exports, module, require) { exports.__esModule = true; exports.sendXHR = sendXHR; exports.startHeartbeat = startHeartbeat; exports.startInitScriptExecution = startInitScriptExecution; exports.stopInitScriptExecution = stopInitScriptExecution; exports.redirect = redirect; exports.fetchPageToCache = fetchPageToCache; exports.checkStatus = checkStatus; exports.enableRetryingTestPages = enableRetryingTestPages; exports.disableRetryingTestPages = disableRetryingTestPages; exports.isRetryingTestPagesEnabled = isRetryingTestPagesEnabled; var _pinkie = require('pinkie'); var _pinkie2 = _interopRequireDefault(_pinkie); var _command = require('../../browser/connection/command'); var _command2 = _interopRequireDefault(_command); var _status = require('../../browser/connection/status'); var _status2 = _interopRequireDefault(_status); var _unstableNetworkMode = require('../../browser/connection/unstable-network-mode'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // TODO: once we'll have client commons load it from there instead of node modules (currently it's leads to two copies of this packages on client) var HEARTBEAT_INTERVAL = 2 * 1000; var allowInitScriptExecution = false; var retryTestPages = false; var noop = function noop() { return void 0; }; var delay = function delay(ms) { return new _pinkie2.default(function (resolve) { return setTimeout(resolve, ms); }); }; var FETCH_PAGE_TO_CACHE_RETRY_DELAY = 300; var FETCH_PAGE_TO_CACHE_RETRY_COUNT = 5; //Utils // NOTE: the window.XMLHttpRequest may have been wrapped by Hammerhead, while we should send a request to // the original URL. That's why we need the XMLHttpRequest argument to send the request via native methods. function sendXHR(url, createXHR) { var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, _ref$method = _ref.method, method = _ref$method === undefined ? 'GET' : _ref$method, _ref$data = _ref.data, data = _ref$data === undefined ? null : _ref$data, _ref$parseResponse = _ref.parseResponse, parseResponse = _ref$parseResponse === undefined ? true : _ref$parseResponse; return new _pinkie2.default(function (resolve, reject) { var xhr = createXHR(); xhr.open(method, url, true); if (isRetryingTestPagesEnabled()) { xhr.setRequestHeader(_unstableNetworkMode.UNSTABLE_NETWORK_MODE_HEADER, 'true'); xhr.setRequestHeader('accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'); } xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { var responseText = xhr.responseText || ''; if (responseText && parseResponse) responseText = JSON.parse(xhr.responseText); //eslint-disable-line no-restricted-globals resolve(responseText); } else reject('disconnected'); } }; xhr.send(data); }); } function isCurrentLocation(url) { /*eslint-disable no-restricted-properties*/ return document.location.href.toLowerCase() === url.toLowerCase(); /*eslint-enable no-restricted-properties*/ } //API function startHeartbeat(heartbeatUrl, createXHR) { function heartbeat() { sendXHR(heartbeatUrl, createXHR).then(function (status) { if (status.code === _status2.default.closing && !isCurrentLocation(status.url)) { stopInitScriptExecution(); document.location = status.url; } }); } window.setInterval(heartbeat, HEARTBEAT_INTERVAL); heartbeat(); } function executeInitScript(initScriptUrl, createXHR) { if (!allowInitScriptExecution) return; sendXHR(initScriptUrl, createXHR).then(function (res) { if (!res.code) return null; /* eslint-disable no-eval, no-restricted-globals*/ return sendXHR(initScriptUrl, createXHR, { method: 'POST', data: JSON.stringify(eval(res.code)) }); /* eslint-enable no-eval, no-restricted-globals */ }).then(function () { window.setTimeout(function () { return executeInitScript(initScriptUrl, createXHR); }, 1000); }); } function startInitScriptExecution(initScriptUrl, createXHR) { allowInitScriptExecution = true; executeInitScript(initScriptUrl, createXHR); } function stopInitScriptExecution() { allowInitScriptExecution = false; } function redirect(command) { stopInitScriptExecution(); document.location = command.url; } function fetchPageToCache(pageUrl, createXHR) { var requestAttempt = function requestAttempt() { return sendXHR(pageUrl, createXHR, { parseResponse: false }); }; var retryRequest = function retryRequest() { return delay(FETCH_PAGE_TO_CACHE_RETRY_DELAY).then(requestAttempt); }; var fetchPagePromise = requestAttempt(); for (var i = 0; i < FETCH_PAGE_TO_CACHE_RETRY_COUNT; i++) { fetchPagePromise = fetchPagePromise.catch(retryRequest); }return fetchPagePromise.catch(noop); } function checkStatus(statusUrl, createXHR, opts) { var _ref2 = opts || {}, manualRedirect = _ref2.manualRedirect; return sendXHR(statusUrl, createXHR).then(function (result) { var ensurePagePromise = _pinkie2.default.resolve(); if (result.url && isRetryingTestPagesEnabled()) ensurePagePromise = fetchPageToCache(result.url, createXHR); return ensurePagePromise.then(function () { return result; }); }).then(function (result) { var redirecting = (result.cmd === _command2.default.run || result.cmd === _command2.default.idle) && !isCurrentLocation(result.url); if (redirecting && !manualRedirect) redirect(result); return { command: result, redirecting: redirecting }; }); } function enableRetryingTestPages() { retryTestPages = true; } function disableRetryingTestPages() { retryTestPages = false; } function isRetryingTestPagesEnabled() { return retryTestPages; } } }, "core": { "deps": { "hammerhead.js": function (exports, module, require) { exports.__esModule = true; exports.default = window['%hammerhead%']; module.exports = exports['default']; } }, "index.js": function (exports, module, require) { var _hammerhead = require('./deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _keyMaps = require('./utils/key-maps'); var _keyMaps2 = _interopRequireDefault(_keyMaps); var _nodeTypeDescriptions = require('./utils/node-type-descriptions'); var _nodeTypeDescriptions2 = _interopRequireDefault(_nodeTypeDescriptions); var _requestBarrier = require('./request-barrier'); var _requestBarrier2 = _interopRequireDefault(_requestBarrier); var _pageUnloadBarrier = require('./page-unload-barrier'); var pageUnloadBarrier = _interopRequireWildcard(_pageUnloadBarrier); var _preventRealEvents = require('./prevent-real-events'); var _scrollController = require('./scroll-controller'); var _scrollController2 = _interopRequireDefault(_scrollController); var _service = require('./utils/service'); var serviceUtils = _interopRequireWildcard(_service); var _dom = require('./utils/dom'); var domUtils = _interopRequireWildcard(_dom); var _contentEditable = require('./utils/content-editable'); var contentEditable = _interopRequireWildcard(_contentEditable); var _position = require('./utils/position'); var positionUtils = _interopRequireWildcard(_position); var _style = require('./utils/style'); var styleUtils = _interopRequireWildcard(_style); var _event = require('./utils/event'); var eventUtils = _interopRequireWildcard(_event); var _array = require('./utils/array'); var arrayUtils = _interopRequireWildcard(_array); var _promise = require('./utils/promise'); var promiseUtils = _interopRequireWildcard(_promise); var _textSelection = require('./utils/text-selection'); var textSelection = _interopRequireWildcard(_textSelection); var _waitFor = require('./utils/wait-for'); var _waitFor2 = _interopRequireDefault(_waitFor); var _delay = require('./utils/delay'); var _delay2 = _interopRequireDefault(_delay); var _getTimeLimitedPromise = require('./utils/get-time-limited-promise'); var _getTimeLimitedPromise2 = _interopRequireDefault(_getTimeLimitedPromise); var _noop = require('./utils/noop'); var _noop2 = _interopRequireDefault(_noop); var _getKeyArray = require('./utils/get-key-array'); var _getKeyArray2 = _interopRequireDefault(_getKeyArray); var _getSanitizedKey = require('./utils/get-sanitized-key'); var _getSanitizedKey2 = _interopRequireDefault(_getSanitizedKey); var _parseKeySequence = require('./utils/parse-key-sequence'); var _parseKeySequence2 = _interopRequireDefault(_parseKeySequence); var _sendRequestToFrame = require('./utils/send-request-to-frame'); var _sendRequestToFrame2 = _interopRequireDefault(_sendRequestToFrame); var _browser = require('../browser'); var browser = _interopRequireWildcard(_browser); var _selectorTextFilter = require('../../client-functions/selectors/selector-text-filter'); var _selectorTextFilter2 = _interopRequireDefault(_selectorTextFilter); var _selectorAttributeFilter = require('../../client-functions/selectors/selector-attribute-filter'); var _selectorAttributeFilter2 = _interopRequireDefault(_selectorAttributeFilter); 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 }; } exports.RequestBarrier = _requestBarrier2.default; exports.pageUnloadBarrier = pageUnloadBarrier; exports.preventRealEvents = _preventRealEvents.preventRealEvents; exports.disableRealEventsPreventing = _preventRealEvents.disableRealEventsPreventing; exports.scrollController = _scrollController2.default; exports.serviceUtils = serviceUtils; exports.domUtils = domUtils; exports.contentEditable = contentEditable; exports.positionUtils = positionUtils; exports.styleUtils = styleUtils; exports.eventUtils = eventUtils; exports.arrayUtils = arrayUtils; exports.promiseUtils = promiseUtils; exports.textSelection = textSelection; exports.waitFor = _waitFor2.default; exports.delay = _delay2.default; exports.getTimeLimitedPromise = _getTimeLimitedPromise2.default; exports.noop = _noop2.default; exports.getKeyArray = _getKeyArray2.default; exports.getSanitizedKey = _getSanitizedKey2.default; exports.parseKeySequence = _parseKeySequence2.default; exports.sendRequestToFrame = _sendRequestToFrame2.default; exports.KEY_MAPS = _keyMaps2.default; exports.NODE_TYPE_DESCRIPTIONS = _nodeTypeDescriptions2.default; exports.browser = browser; exports.selectorTextFilter = _selectorTextFilter2.default; exports.selectorAttributeFilter = _selectorAttributeFilter2.default; exports.get = require; var nativeMethods = _hammerhead2.default.nativeMethods; var evalIframeScript = _hammerhead2.default.EVENTS.evalIframeScript; nativeMethods.objectDefineProperty(window, '%testCafeCore%', { configurable: true, value: exports }); // NOTE: initTestCafeCore defined in wrapper template /* global initTestCafeCore */ _hammerhead2.default.on(evalIframeScript, function (e) { return initTestCafeCore(nativeMethods.contentWindowGetter.call(e.iframe), true); }); }, "page-unload-barrier.js": function (exports, module, require) { exports.__esModule = true; exports.init = init; exports.watchForPageNavigationTriggers = watchForPageNavigationTriggers; exports.wait = wait; var _hammerhead = require('./deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _event = require('./utils/event'); var eventUtils = _interopRequireWildcard(_event); var _delay = require('./utils/delay'); var _delay2 = _interopRequireDefault(_delay); var _clientMessages = require('../../test-run/client-messages'); var _clientMessages2 = _interopRequireDefault(_clientMessages); var _dom = require('./utils/dom'); 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 browserUtils = _hammerhead2.default.utils.browser; var nativeMethods = _hammerhead2.default.nativeMethods; var transport = _hammerhead2.default.transport; var DEFAULT_BARRIER_TIMEOUT = 400; var SHORT_WAIT_FOR_UNLOAD_TIMEOUT = 30; var FILE_DOWNLOAD_CHECK_DELAY = 500; var MAX_UNLOADING_TIMEOUT = 15 * 1000; var waitingForUnload = false; var waitingForUnloadTimeoutId = null; var waitingPromiseResolvers = []; var unloading = false; var pageNavigationTriggeredListener = null; var pageNavigationTriggered = false; function onBeforeUnload() { if (!browserUtils.isIE) { unloading = true; return; } prolongUnloadWaiting(SHORT_WAIT_FOR_UNLOAD_TIMEOUT); (0, _delay2.default)(0).then(function () { // NOTE: except file downloading if (document.readyState === 'loading') { var activeElement = nativeMethods.documentActiveElementGetter.call(document); if (!activeElement || !(0, _dom.isAnchorElement)(activeElement) || !activeElement.hasAttribute('download')) unloading = true; } }); } function prolongUnloadWaiting(timeout) { if (waitingForUnloadTimeoutId) nativeMethods.clearTimeout.call(window, waitingForUnloadTimeoutId); waitingForUnload = true; waitingForUnloadTimeoutId = nativeMethods.setTimeout.call(window, function () { waitingForUnloadTimeoutId = null; waitingForUnload = false; waitingPromiseResolvers.forEach(function (resolve) { return resolve(); }); waitingPromiseResolvers = []; }, timeout); } function waitForFileDownload() { return new Promise(function (resolve) { nativeMethods.setTimeout.call(window, function () { transport.queuedAsyncServiceMsg({ cmd: _clientMessages2.default.waitForFileDownload }).then(function (fileDownloadingHandled) { // NOTE: we use a flag to confirm file download because if unload // is raised the browser can respond with an empty string if (fileDownloadingHandled) resolve(); }); }, FILE_DOWNLOAD_CHECK_DELAY); }); } // API function init() { _hammerhead2.default.on(_hammerhead2.default.EVENTS.beforeUnload, onBeforeUnload); eventUtils.bind(window, 'unload', function () { unloading = true; }); } function watchForPageNavigationTriggers() { pageNavigationTriggeredListener = function pageNavigationTriggeredListener() { pageNavigationTriggered = true; }; _hammerhead2.default.on(_hammerhead2.default.EVENTS.pageNavigationTriggered, pageNavigationTriggeredListener); } function wait(timeout) { var waitForUnloadingPromise = new Promise(function (resolve) { if (timeout === void 0) timeout = !pageNavigationTriggeredListener || pageNavigationTriggered ? DEFAULT_BARRIER_TIMEOUT : 0; if (pageNavigationTriggeredListener) { _hammerhead2.default.off(_hammerhead2.default.EVENTS.pageNavigationTriggered, pageNavigationTriggeredListener); pageNavigationTriggeredListener = null; } (0, _delay2.default)(timeout).then(function () { if (unloading) { waitForFileDownload().then(function () { unloading = false; resolve(); }); return; } if (!waitingForUnload) resolve();else waitingPromiseResolvers.push(resolve); }); }); // NOTE: sometimes the page isn't actually unloaded after the beforeunload event // fires (see issues #664, #437). To avoid test hanging, we resolve the unload // barrier waiting promise in MAX_UNLOADING_TIMEOUT. We can improve this logic when // the https://github.com/DevExpress/testcafe-hammerhead/issues/667 issue is fixed. var watchdog = (0, _delay2.default)(MAX_UNLOADING_TIMEOUT).then(function () { unloading = false; }); return Promise.race([waitForUnloadingPromise, watchdog]); } }, "prevent-real-events.js": function (exports, module, require) { exports.__esModule = true; exports.preventRealEvents = preventRealEvents; exports.disableRealEventsPreventing = disableRealEventsPreventing; var _hammerhead = require('./deps/hammerhead'); var _scrollController = require('./scroll-controller'); var _scrollController2 = _interopRequireDefault(_scrollController); var _style = require('./utils/style'); var _array = require('./utils/array'); var _dom = require('./utils/dom'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var browserUtils = _hammerhead.utils.browser; var listeners = _hammerhead.eventSandbox.listeners; var eventSimulator = _hammerhead.eventSandbox.eventSimulator; var PREVENTED_EVENTS = ['click', 'mousedown', 'mouseup', 'dblclick', 'contextmenu', 'mousemove', 'mouseover', 'mouseout', 'touchstart', 'touchmove', 'touchend', 'keydown', 'keypress', 'input', 'keyup', 'change', 'focus', 'blur', 'MSPointerDown', 'MSPointerMove', 'MSPointerOver', 'MSPointerOut', 'MSPointerUp', 'pointerdown', 'pointermove', 'pointerover', 'pointerout', 'pointerup']; var F12_KEY_CODE = 123; function checkBrowserHotkey(e) { // NOTE: Opening browser tools with F12, CTRL+SHIFT+<SYMBOL KEY> // on PC or with OPTION(ALT)+CMD+<SYMBOL KEY> on Mac. return e.shiftKey && e.ctrlKey || (e.altKey || e.metaKey) && browserUtils.isMacPlatform || e.keyCode === F12_KEY_CODE; } // NOTE: when tests are running, we should block real events (from mouse // or keyboard), because they may lead to unexpected test result. function preventRealEventHandler(e, dispatched, preventDefault, cancelHandlers, stopEventPropagation) { var target = e.target || e.srcElement; if (!dispatched && !(0, _dom.isShadowUIElement)(target)) { // NOTE: this will allow pressing hotkeys to open developer tools. if (/^key/.test(e.type) && checkBrowserHotkey(e)) { stopEventPropagation(); return; } // NOTE: if an element loses focus because of becoming invisible, the blur event is // raised. We must not prevent this blur event. In IE, an element loses focus only // if the CSS 'display' property is set to 'none', other ways of making an element // invisible don't lead to blurring (in MSEdge, focus/blur are sync). if (e.type === 'blur') { if (browserUtils.isIE && browserUtils.version < 12) { var isWindowInstance = (0, _dom.isWindow)(target); var isElementInvisible = !isWindowInstance && (0, _style.get)(target, 'display') === 'none'; var elementParents = null; var invisibleParents = false; if (!isWindowInstance && !isElementInvisible) { elementParents = (0, _dom.getParents)(target); invisibleParents = (0, _array.filter)(elementParents, function (parent) { return (0, _style.get)(parent, 'display') === 'none'; }); } if (isElementInvisible || invisibleParents.length) { // NOTE: In IE we should prevent the event and raise it on timeout. This is a fix for // the case when a focus event leads to the element disappearing. If we don't prevent // the blur event it will be raised before the previous focus event is raised (see B254768) _hammerhead.eventSandbox.timers.deferFunction(function () { eventSimulator.blur(target); }); } } // NOTE: fix for a jQuery bug. An exception is raised when calling .is(':visible') // for a window or document on page loading (when e.ownerDocument is null). else if (target !== window && target !== window.document && !(0, _style.hasDimensions)(target)) return; } preventDefault(); } } function preventRealEvents() { listeners.initElementListening(window, PREVENTED_EVENTS); listeners.addFirstInternalHandler(window, PREVENTED_EVENTS, preventRealEventHandler); _scrollController2.default.init(); } function disableRealEventsPreventing() { listeners.removeInternalEventListener(window, PREVENTED_EVENTS, preventRealEventHandler); } }, "request-barrier.js": function (exports, module, require) { exports.__esModule = true; var _hammerhead = require('./deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); var _delay = require('./utils/delay'); var _delay2 = _interopRequireDefault(_delay); var _array = require('./utils/array'); var _service = require('./utils/service'); 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 nativeMethods = _hammerhead2.default.nativeMethods; var REQUESTS_COLLECTION_DELAY_DEFAULT = 50; var REQUESTS_FINISHED_EVENT = 'requests-finished'; var GLOBAL_REQUEST_BARRIER_FIELD = 'testcafe|request-barrier'; var RequestBarrier = function (_EventEmitter) { _inherits(RequestBarrier, _EventEmitter); function RequestBarrier() { var delays = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, RequestBarrier); var _this = _possibleConstructorReturn(this, _EventEmitter.call(this)); _this.BARRIER_TIMEOUT = 3000; _this.delays = { requestsCollection: delays.requestsCollection === void 0 ? REQUESTS_COLLECTION_DELAY_DEFAULT : delays.requestsCollection, additionalRequestsCollection: delays.additionalRequestsCollection === void 0 ? REQUESTS_COLLECTION_DELAY_DEFAULT : delays.additionalRequestsCollection, pageInitialRequestsCollection: delays.pageInitialRequestsCollection === void 0 ? REQUESTS_COLLECTION_DELAY_DEFAULT : delays.pageInitialRequestsCollection }; _this.collectingReqs = true; _this.requests = []; _this.watchdog = null; _this._unbindHandlers = null; _this._init(); return _this; } RequestBarrier.prototype._init = function _init() { var _this2 = this; var onXhrSend = function onXhrSend(e) { return _this2._onXhrSend(e.xhr); }; var onXhrCompleted = function onXhrCompleted(e) { return _this2._onRequestCompleted(e.xhr); }; var onXhrError = function onXhrError(e) { return _this2._onRequestError(e.xhr, e.err); }; var onFetchSend = function onFetchSend(e) { return _this2._onFetchSend(e); }; _hammerhead2.default.on(_hammerhead2.default.EVENTS.beforeXhrSend, onXhrSend); _hammerhead2.default.on(_hammerhead2.default.EVENTS.xhrCompleted, onXhrCompleted); _hammerhead2.default.on(_hammerhead2.default.EVENTS.xhrError, onXhrError); _hammerhead2.default.on(_hammerhead2.default.EVENTS.fetchSent, onFetchSend); this._unbindHandlers = function () { _hammerhead2.default.off(_hammerhead2.default.EVENTS.beforeXhrSend, onXhrSend); _hammerhead2.default.off(_hammerhead2.default.EVENTS.xhrCompleted, onXhrCompleted); _hammerhead2.default.off(_hammerhead2.default.EVENTS.xhrError, onXhrError); _hammerhead2.default.off(_hammerhead2.default.EVENTS.fetchSent, onFetchSend); }; }; RequestBarrier.prototype._onXhrSend = function _onXhrSend(request) { if (this.collectingReqs) this.requests.push(request); }; RequestBarrier.prototype._onRequestCompleted = function _onRequestCompleted(request) { var _this3 = this; // NOTE: let the last real XHR handler finish its job and try to obtain // any additional requests if they were initiated by this handler (0, _delay2.default)(this.delays.additionalRequestsCollection).then(function () { return _this3._onRequestFinished(request); }); }; RequestBarrier.prototype._onRequestError = function _onRequestError(request) { this._onRequestFinished(request); }; RequestBarrier.prototype._onRequestFinished = function _onRequestFinished(request) { if ((0, _array.indexOf)(this.requests, request) > -1) { (0, _array.remove)(this.requests, request); if (!this.collectingReqs && !this.requests.length) this.emit(REQUESTS_FINISHED_EVENT); } }; RequestBarrier.prototype._onFetchSend = function _onFetchSend(request) { var _this4 = this; if (this.collectingReqs) { this.requests.push(request); request.then(function () { return _this4._onRequestCompleted(request); }).catch(function () { return _this4._onRequestError(request); }); } }; RequestBarrier.prototype.wait = function wait(isPageLoad) { var _this5 = this; return new Promise(function (resolve) { (0, _delay2.default)(isPageLoad ? _this5.delays.pageInitialRequestsCollection : _this5.delays.requestsCollection).then(function () { _this5.collectingReqs = false; var onRequestsFinished = function onRequestsFinished() { if (_this5.watchdog) nativeMethods.clearTimeout.call(window, _this5.watchdog); _this5._unbindHandlers(); resolve(); }; if (_this5.requests.length) { _this5.watchdog = nativeMethods.setTimeout.call(window, onRequestsFinished, _this5.BARRIER_TIMEOUT); _this5.on(REQUESTS_FINISHED_EVENT, onRequestsFinished); } else onRequestsFinished(); }); }); }; return RequestBarrier; }(_service.EventEmitter); exports.default = RequestBarrier; RequestBarrier.GLOBAL_REQUEST_BARRIER_FIELD = GLOBAL_REQUEST_BARRIER_FIELD; window[RequestBarrier.GLOBAL_REQUEST_BARRIER_FIELD] = RequestBarrier; module.exports = exports['default']; }, "scroll-controller.js": function (exports, module, require) { exports.__esModule = true; var _hammerhead = require('./deps/hammerhead'); var _service = require('./utils/service'); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var listeners = _hammerhead.eventSandbox.listeners; var ScrollController = function () { function ScrollController() { _classCallCheck(this, ScrollController); this.initialized = false; this.stopPropagationFlag = false; this.events = new _service.EventEmitter(); } ScrollController.prototype._internalListener = function _internalListener(event, dispatched, preventEvent, cancelHandlers, stopPropagation) { this.events.emit('scroll', event); if (this.stopPropagationFlag) { cancelHandlers(); stopPropagation(); } }; ScrollController.prototype.init = function init() { var _this = this; if (this.initialized) return; this.initialized = true; listeners.initElementListening(window, ['scroll']); listeners.addFirstInternalHandler(window, ['scroll'], function () { return _this._internalListener.apply(_this, arguments); }); }; ScrollController.prototype.waitForScroll = function waitForScroll() { var _this2 = this; var promiseResolver = null; var promise = new _hammerhead.Promise(function (resolve) { promiseResolver = resolve; }); promise.cancel = function () { return _this2.events.off('scroll', promiseResolver); }; if (this.initialized) this.events.once('scroll', promiseResolver);else promiseResolver(); return promise; }; ScrollController.prototype.stopPropagation = function stopPropagation() { this.stopPropagationFlag = true; }; ScrollController.prototype.enablePropagation = function enablePropagation() { this.stopPropagationFlag = false; }; return ScrollController; }(); exports.default = new ScrollController(); module.exports = exports['default']; }, "utils": { "array.js": function (exports, module, require) { exports.__esModule = true; exports.toArray = toArray; exports.reverse = reverse; exports.isArray = isArray; exports.find = find; exports.indexOf = indexOf; exports.forEach = forEach; exports.some = some; exports.map = map; exports.filter = filter; exports.reduce = reduce; exports.remove = remove; exports.equals = equals; exports.getCommonElement = getCommonElement; var _hammerhead = require('../deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var nativeIndexOf = Array.prototype.indexOf; var nativeForEach = Array.prototype.forEach; var nativeSome = Array.prototype.some; var nativeMap = Array.prototype.map; var nativeFilter = Array.prototype.filter; var nativeReverse = Array.prototype.reverse; var nativeReduce = Array.prototype.reduce; var nativeSplice = Array.prototype.splice; function toArray(arg) { var arr = []; var length = arg.length; for (var i = 0; i < length; i++) { arr.push(arg[i]); }return arr; } function reverse(arr) { return nativeReverse.call(arr); } function isArray(arg) { return _hammerhead2.default.nativeMethods.objectToString.call(arg) === '[object Array]'; } function find(arr, callback) { var length = arr.length; for (var i = 0; i < length; i++) { if (callback(arr[i], i, arr)) return arr[i]; } return null; } function indexOf(arr, arg) { return nativeIndexOf.call(arr, arg); } function forEach(arr, callback) { nativeForEach.call(arr, callback); } function some(arr, callback) { return nativeSome.call(arr, callback); } function map(arr, callback) { return nativeMap.call(arr, callback); } function filter(arr, callback) { return nativeFilter.call(arr, callback); } function reduce(arr, callback, initialValue) { return nativeReduce.call(arr, callback, initialValue); } function remove(arr, item) { var index = indexOf(arr, item); if (index > -1) nativeSplice.call(arr, index, 1); } function equals(arr1, arr2) { if (arr1.length !== arr2.length) return false; for (var i = 0, l = arr1.length; i < l; i++) { if (arr1[i] !== arr2[i]) return false; } return true; } function getCommonElement(arr1, arr2) { for (var i = 0; i < arr1.length; i++) { for (var t = 0; t < arr2.length; t++) { if (arr1[i] === arr2[t]) return arr1[i]; } } return null; } }, "content-editable.js": function (exports, module, require) { exports.__esModule = true; exports.getFirstVisibleTextNode = getFirstVisibleTextNode; exports.getLastTextNode = getLastTextNode; exports.getFirstNonWhitespaceSymbolIndex = getFirstNonWhitespaceSymbolIndex; exports.getLastNonWhitespaceSymbolIndex = getLastNonWhitespaceSymbolIndex; exports.isInvisibleTextNode = isInvisibleTextNode; exports.findContentEditableParent = findContentEditableParent; exports.getNearestCommonAncestor = getNearestCommonAncestor; exports.getSelection = getSelection; exports.getSelectionStartPosition = getSelectionStartPosition; exports.getSelectionEndPosition = getSelectionEndPosition; exports.calculateNodeAndOffsetByPosition = calculateNodeAndOffsetByPosition; exports.calculatePositionByNodeAndOffset = calculatePositionByNodeAndOffset; exports.getElementBySelection = getElementBySelection; exports.getFirstVisiblePosition = getFirstVisiblePosition; exports.getLastVisiblePosition = getLastVisiblePosition; exports.getContentEditableValue = getContentEditableValue; var _dom = require('./dom'); var domUtils = _interopRequireWildcard(_dom); var _array = require('./array'); var arrayUtils = _interopRequireWildcard(_array); var _style = require('./style'); var styleUtils = _interopRequireWildcard(_style); var _hammerhead = require('../../driver/deps/hammerhead'); 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; } } //nodes utils function getOwnFirstVisibleTextNode(el) { var children