UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

1,347 lines (989 loc) 252 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 initTestCafeClientDrivers(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, [], ''); })({ "replicator": { ":mainpath:": "index.js", "index.js": function (exports, module, require) { // Const var TRANSFORMED_TYPE_KEY = '@t'; var CIRCULAR_REF_KEY = '@r'; var KEY_REQUIRE_ESCAPING_RE = /^#*@(t|r)$/; var GLOBAL = function getGlobal() { // NOTE: see http://www.ecma-international.org/ecma-262/6.0/index.html#sec-performeval step 10 var savedEval = eval; return savedEval('this'); }(); var ARRAY_BUFFER_SUPPORTED = typeof ArrayBuffer === 'function'; var MAP_SUPPORTED = typeof Map === 'function'; var SET_SUPPORTED = typeof Set === 'function'; var TYPED_ARRAY_CTORS = ['Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array']; // Saved proto functions var arrSlice = Array.prototype.slice; // Default serializer var JSONSerializer = { serialize: function serialize(val) { return JSON.stringify(val); }, deserialize: function deserialize(val) { return JSON.parse(val); } }; // EncodingTransformer var EncodingTransformer = function EncodingTransformer(val, transforms) { this.references = val; this.transforms = transforms; this.circularCandidates = []; this.circularCandidatesDescrs = []; this.circularRefCount = 0; }; EncodingTransformer._createRefMark = function (idx) { var obj = Object.create(null); obj[CIRCULAR_REF_KEY] = idx; return obj; }; EncodingTransformer.prototype._createCircularCandidate = function (val, parent, key) { this.circularCandidates.push(val); this.circularCandidatesDescrs.push({ parent: parent, key: key, refIdx: -1 }); }; EncodingTransformer.prototype._applyTransform = function (val, parent, key, transform) { var result = Object.create(null); var serializableVal = transform.toSerializable(val); if (typeof serializableVal === 'object') this._createCircularCandidate(val, parent, key); result[TRANSFORMED_TYPE_KEY] = transform.type; result.data = this._handleValue(serializableVal, parent, key); return result; }; EncodingTransformer.prototype._handleArray = function (arr) { var result = []; for (var i = 0; i < arr.length; i++) { result[i] = this._handleValue(arr[i], result, i); }return result; }; EncodingTransformer.prototype._handlePlainObject = function (obj) { var replicator = this; var result = Object.create(null); var ownPropertyNames = Object.getOwnPropertyNames(obj); ownPropertyNames.forEach(function (key) { var resultKey = KEY_REQUIRE_ESCAPING_RE.test(key) ? '#' + key : key; result[resultKey] = replicator._handleValue(obj[key], result, resultKey); }); return result; }; EncodingTransformer.prototype._handleObject = function (obj, parent, key) { this._createCircularCandidate(obj, parent, key); return Array.isArray(obj) ? this._handleArray(obj) : this._handlePlainObject(obj); }; EncodingTransformer.prototype._ensureCircularReference = function (obj) { var circularCandidateIdx = this.circularCandidates.indexOf(obj); if (circularCandidateIdx > -1) { var descr = this.circularCandidatesDescrs[circularCandidateIdx]; if (descr.refIdx === -1) descr.refIdx = descr.parent ? ++this.circularRefCount : 0; return EncodingTransformer._createRefMark(descr.refIdx); } return null; }; EncodingTransformer.prototype._handleValue = function (val, parent, key) { var type = typeof val; var isObject = type === 'object' && val !== null; if (isObject) { var refMark = this._ensureCircularReference(val); if (refMark) return refMark; } for (var i = 0; i < this.transforms.length; i++) { var transform = this.transforms[i]; if (transform.shouldTransform(type, val)) return this._applyTransform(val, parent, key, transform); } if (isObject) return this._handleObject(val, parent, key); return val; }; EncodingTransformer.prototype.transform = function () { var references = [this._handleValue(this.references, null, null)]; for (var i = 0; i < this.circularCandidatesDescrs.length; i++) { var descr = this.circularCandidatesDescrs[i]; if (descr.refIdx > 0) { references[descr.refIdx] = descr.parent[descr.key]; descr.parent[descr.key] = EncodingTransformer._createRefMark(descr.refIdx); } } return references; }; // DecodingTransform var DecodingTransformer = function DecodingTransformer(references, transformsMap) { this.references = references; this.transformMap = transformsMap; this.activeTransformsStack = []; this.visitedRefs = Object.create(null); }; DecodingTransformer.prototype._handlePlainObject = function (obj) { var replicator = this; var unescaped = Object.create(null); var ownPropertyNames = Object.getOwnPropertyNames(obj); ownPropertyNames.forEach(function (key) { replicator._handleValue(obj[key], obj, key); if (KEY_REQUIRE_ESCAPING_RE.test(key)) { // NOTE: use intermediate object to avoid unescaped and escaped keys interference // E.g. unescaped "##@t" will be "#@t" which can overwrite escaped "#@t". unescaped[key.substring(1)] = obj[key]; delete obj[key]; } }); for (var unsecapedKey in unescaped) { obj[unsecapedKey] = unescaped[unsecapedKey]; } }; DecodingTransformer.prototype._handleTransformedObject = function (obj, parent, key) { var transformType = obj[TRANSFORMED_TYPE_KEY]; var transform = this.transformMap[transformType]; if (!transform) throw new Error('Can\'t find transform for "' + transformType + '" type.'); this.activeTransformsStack.push(obj); this._handleValue(obj.data, obj, 'data'); this.activeTransformsStack.pop(); parent[key] = transform.fromSerializable(obj.data); }; DecodingTransformer.prototype._handleCircularSelfRefDuringTransform = function (refIdx, parent, key) { // NOTE: we've hit a hard case: object reference itself during transformation. // We can't dereference it since we don't have resulting object yet. And we'll // not be able to restore reference lately because we will need to traverse // transformed object again and reference might be unreachable or new object contain // new circular references. As a workaround we create getter, so once transformation // complete, dereferenced property will point to correct transformed object. var references = this.references; var val = void 0; Object.defineProperty(parent, key, { configurable: true, enumerable: true, get: function get() { if (val === void 0) val = references[refIdx]; return val; }, set: function set(value) { val = value; return val; } }); }; DecodingTransformer.prototype._handleCircularRef = function (refIdx, parent, key) { if (this.activeTransformsStack.indexOf(this.references[refIdx]) > -1) this._handleCircularSelfRefDuringTransform(refIdx, parent, key);else { if (!this.visitedRefs[refIdx]) { this.visitedRefs[refIdx] = true; this._handleValue(this.references[refIdx], this.references, refIdx); } parent[key] = this.references[refIdx]; } }; DecodingTransformer.prototype._handleValue = function (val, parent, key) { if (typeof val !== 'object' || val === null) return; var refIdx = val[CIRCULAR_REF_KEY]; if (refIdx !== void 0) this._handleCircularRef(refIdx, parent, key);else if (val[TRANSFORMED_TYPE_KEY]) this._handleTransformedObject(val, parent, key);else if (Array.isArray(val)) { for (var i = 0; i < val.length; i++) { this._handleValue(val[i], val, i); } } else this._handlePlainObject(val); }; DecodingTransformer.prototype.transform = function () { this.visitedRefs[0] = true; this._handleValue(this.references[0], this.references, 0); return this.references[0]; }; // Transforms var builtInTransforms = [{ type: '[[NaN]]', shouldTransform: function shouldTransform(type, val) { return type === 'number' && isNaN(val); }, toSerializable: function toSerializable() { return ''; }, fromSerializable: function fromSerializable() { return NaN; } }, { type: '[[undefined]]', shouldTransform: function shouldTransform(type) { return type === 'undefined'; }, toSerializable: function toSerializable() { return ''; }, fromSerializable: function fromSerializable() { return void 0; } }, { type: '[[Date]]', shouldTransform: function shouldTransform(type, val) { return val instanceof Date; }, toSerializable: function toSerializable(date) { return date.getTime(); }, fromSerializable: function fromSerializable(val) { var date = new Date(); date.setTime(val); return date; } }, { type: '[[RegExp]]', shouldTransform: function shouldTransform(type, val) { return val instanceof RegExp; }, toSerializable: function toSerializable(re) { var result = { src: re.source, flags: '' }; if (re.global) result.flags += 'g'; if (re.ignoreCase) result.flags += 'i'; if (re.multiline) result.flags += 'm'; return result; }, fromSerializable: function fromSerializable(val) { return new RegExp(val.src, val.flags); } }, { type: '[[Error]]', shouldTransform: function shouldTransform(type, val) { return val instanceof Error; }, toSerializable: function toSerializable(err) { return { name: err.name, message: err.message, stack: err.stack }; }, fromSerializable: function fromSerializable(val) { var Ctor = GLOBAL[val.name] || Error; var err = new Ctor(val.message); err.stack = val.stack; return err; } }, { type: '[[ArrayBuffer]]', shouldTransform: function shouldTransform(type, val) { return ARRAY_BUFFER_SUPPORTED && val instanceof ArrayBuffer; }, toSerializable: function toSerializable(buffer) { var view = new Int8Array(buffer); return arrSlice.call(view); }, fromSerializable: function fromSerializable(val) { if (ARRAY_BUFFER_SUPPORTED) { var buffer = new ArrayBuffer(val.length); var view = new Int8Array(buffer); view.set(val); return buffer; } return val; } }, { type: '[[TypedArray]]', shouldTransform: function shouldTransform(type, val) { for (var i = 0; i < TYPED_ARRAY_CTORS.length; i++) { var ctorName = TYPED_ARRAY_CTORS[i]; if (typeof GLOBAL[ctorName] === 'function' && val instanceof GLOBAL[ctorName]) return true; } return false; }, toSerializable: function toSerializable(arr) { return { ctorName: arr.constructor.name, arr: arrSlice.call(arr) }; }, fromSerializable: function fromSerializable(val) { return typeof GLOBAL[val.ctorName] === 'function' ? new GLOBAL[val.ctorName](val.arr) : val.arr; } }, { type: '[[Map]]', shouldTransform: function shouldTransform(type, val) { return MAP_SUPPORTED && val instanceof Map; }, toSerializable: function toSerializable(map) { var flattenedKVArr = []; map.forEach(function (val, key) { flattenedKVArr.push(key); flattenedKVArr.push(val); }); return flattenedKVArr; }, fromSerializable: function fromSerializable(val) { if (MAP_SUPPORTED) { // NOTE: new Map(iterable) is not supported by all browsers var map = new Map(); for (var i = 0; i < val.length; i += 2) { map.set(val[i], val[i + 1]); }return map; } var kvArr = []; for (var j = 0; j < val.length; j += 2) { kvArr.push([val[i], val[i + 1]]); }return kvArr; } }, { type: '[[Set]]', shouldTransform: function shouldTransform(type, val) { return SET_SUPPORTED && val instanceof Set; }, toSerializable: function toSerializable(set) { var arr = []; set.forEach(function (val) { arr.push(val); }); return arr; }, fromSerializable: function fromSerializable(val) { if (SET_SUPPORTED) { // NOTE: new Set(iterable) is not supported by all browsers var set = new Set(); for (var i = 0; i < val.length; i++) { set.add(val[i]); }return set; } return val; } }]; // Replicator var Replicator = module.exports = function (serializer) { this.transforms = []; this.transformsMap = Object.create(null); this.serializer = serializer || JSONSerializer; this.addTransforms(builtInTransforms); }; // Manage transforms Replicator.prototype.addTransforms = function (transforms) { transforms = Array.isArray(transforms) ? transforms : [transforms]; for (var i = 0; i < transforms.length; i++) { var transform = transforms[i]; if (this.transformsMap[transform.type]) throw new Error('Transform with type "' + transform.type + '" was already added.'); this.transforms.push(transform); this.transformsMap[transform.type] = transform; } return this; }; Replicator.prototype.removeTransforms = function (transforms) { transforms = Array.isArray(transforms) ? transforms : [transforms]; for (var i = 0; i < transforms.length; i++) { var transform = transforms[i]; var idx = this.transforms.indexOf(transform); if (idx > -1) this.transforms.splice(idx, 1); delete this.transformsMap[transform.type]; } return this; }; Replicator.prototype.encode = function (val) { var transformer = new EncodingTransformer(val, this.transforms); var references = transformer.transform(); return this.serializer.serialize(references); }; Replicator.prototype.decode = function (val) { var references = this.serializer.deserialize(val); var transformer = new DecodingTransformer(references, this.transformsMap); return transformer.transform(); }; } }, "testcafe-release": { "src": { "client": { "driver": { "command-executors": { "browser-manipulation": { "ensure-crop-options.js": function (exports, module, require) { exports.__esModule = true; exports.default = ensureCropOptions; var _testcafeCore = require('../../deps/testcafe-core'); var _testcafeAutomation = require('../../deps/testcafe-automation'); var _limitNumber = require('../../../../utils/limit-number'); var _limitNumber2 = _interopRequireDefault(_limitNumber); var _testRun = require('../../../../errors/test-run'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function determineDimensionBounds(bounds, maximum) { var hasMin = typeof bounds.min === 'number'; var hasMax = typeof bounds.max === 'number'; var hasLength = typeof bounds.length === 'number'; if (hasLength) bounds.length = (0, _limitNumber2.default)(bounds.length, 0, maximum); if (hasMin && bounds.min < 0) bounds.min += maximum; if (hasMax && bounds.max < 0) bounds.max += maximum; if (!hasMin) bounds.min = hasMax && hasLength ? bounds.max - bounds.length : 0; if (!hasMax) bounds.max = hasLength ? bounds.min + bounds.length : maximum; bounds.min = (0, _limitNumber2.default)(bounds.min, 0, maximum); bounds.max = (0, _limitNumber2.default)(bounds.max, 0, maximum); bounds.length = bounds.max - bounds.min; return bounds; } function determineScrollPoint(cropStart, cropEnd, viewportBound) { return Math.round(cropStart + (0, _limitNumber2.default)(cropEnd - cropStart, 0, viewportBound) / 2); } function ensureCropOptions(element, options) { var elementRectangle = element.getBoundingClientRect(); var elementBounds = { left: elementRectangle.left, right: elementRectangle.right, top: elementRectangle.top, bottom: elementRectangle.bottom }; var elementMargin = _testcafeCore.styleUtils.getElementMargin(element); var elementPadding = _testcafeCore.styleUtils.getElementPadding(element); var elementBordersWidth = _testcafeCore.styleUtils.getBordersWidth(element); options.originOffset = { x: 0, y: 0 }; var scrollRight = elementBounds.left + element.scrollWidth + elementBordersWidth.left + elementBordersWidth.right; var scrollBottom = elementBounds.top + element.scrollHeight + elementBordersWidth.top + elementBordersWidth.bottom; elementBounds.right = Math.max(elementBounds.right, scrollRight); elementBounds.bottom = Math.max(elementBounds.bottom, scrollBottom); if (!options.includeBorders || !options.includePaddings) { options.originOffset.x += elementBordersWidth.left; options.originOffset.y += elementBordersWidth.top; elementBounds.left += elementBordersWidth.left; elementBounds.top += elementBordersWidth.top; elementBounds.right -= elementBordersWidth.right; elementBounds.bottom -= elementBordersWidth.bottom; if (!options.includePaddings) { options.originOffset.x += elementPadding.left; options.originOffset.y += elementPadding.top; elementBounds.left += elementPadding.left; elementBounds.top += elementPadding.top; elementBounds.right -= elementPadding.right; elementBounds.bottom -= elementPadding.bottom; } } else if (options.includeMargins) { options.originOffset.x -= elementMargin.left; options.originOffset.y -= elementMargin.top; elementBounds.left -= elementMargin.left; elementBounds.top -= elementMargin.top; elementBounds.right += elementMargin.right; elementBounds.bottom += elementMargin.bottom; } elementBounds.width = elementBounds.right - elementBounds.left; elementBounds.height = elementBounds.bottom - elementBounds.top; var horizontalCropBounds = determineDimensionBounds({ min: options.crop.left, max: options.crop.right, length: options.crop.width }, elementBounds.width); var verticalCropBounds = determineDimensionBounds({ min: options.crop.top, max: options.crop.bottom, length: options.crop.height }, elementBounds.height); options.crop.left = horizontalCropBounds.min; options.crop.right = horizontalCropBounds.max; options.crop.width = horizontalCropBounds.length; options.crop.top = verticalCropBounds.min; options.crop.bottom = verticalCropBounds.max; options.crop.height = verticalCropBounds.length; if (options.crop.width <= 0 || options.crop.height <= 0) throw new _testRun.InvalidElementScreenshotDimensionsError(options.crop.width, options.crop.height); var viewportDimensions = _testcafeCore.styleUtils.getViewportDimensions(); if (elementBounds.width > viewportDimensions.width || elementBounds.height > viewportDimensions.height) options.scrollToCenter = true; var hasScrollTargetX = typeof options.scrollTargetX === 'number'; var hasScrollTargetY = typeof options.scrollTargetY === 'number'; if (!hasScrollTargetX) options.scrollTargetX = determineScrollPoint(options.crop.left, options.crop.right, viewportDimensions.width); if (!hasScrollTargetY) options.scrollTargetY = determineScrollPoint(options.crop.top, options.crop.bottom, viewportDimensions.height); var _getOffsetOptions = (0, _testcafeAutomation.getOffsetOptions)(element, options.scrollTargetX, options.scrollTargetY), offsetX = _getOffsetOptions.offsetX, offsetY = _getOffsetOptions.offsetY; options.scrollTargetX = offsetX; options.scrollTargetY = offsetY; var isScrollTargetXValid = !hasScrollTargetX || options.scrollTargetX >= options.crop.left && options.scrollTargetX <= options.crop.right; var isScrollTargetYValid = !hasScrollTargetY || options.scrollTargetY >= options.crop.top && options.scrollTargetY <= options.crop.bottom; if (!isScrollTargetXValid || !isScrollTargetYValid) throw new _testRun.ActionInvalidScrollTargetError(isScrollTargetXValid, isScrollTargetYValid); } module.exports = exports['default']; }, "index.js": function (exports, module, require) { exports.__esModule = true; exports.default = function (command, globalSelectorTimeout, statusBar) { var manipulationExecutor = new ManipulationExecutor(command, globalSelectorTimeout, statusBar); return manipulationExecutor.execute(); }; var _hammerhead = require('../../deps/hammerhead'); var _testcafeCore = require('../../deps/testcafe-core'); var _testcafeAutomation = require('../../deps/testcafe-automation'); var _testcafeUi = require('../../deps/testcafe-ui'); var _status = require('../../status'); var _status2 = _interopRequireDefault(_status); var _ensureCropOptions = require('./ensure-crop-options'); var _ensureCropOptions2 = _interopRequireDefault(_ensureCropOptions); var _ensureElements = require('../../utils/ensure-elements'); var _runWithBarriers2 = require('../../utils/run-with-barriers'); var _runWithBarriers3 = _interopRequireDefault(_runWithBarriers2); var _clientMessages = require('../../../../test-run/client-messages'); var _clientMessages2 = _interopRequireDefault(_clientMessages); var _type = require('../../../../test-run/commands/type'); var _type2 = _interopRequireDefault(_type); var _options = require('../../../../test-run/commands/options'); 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 messageSandbox = _hammerhead.eventSandbox.message; var HIDING_UI_RELAYOUT_DELAY = 500; var POSSIBLE_RESIZE_ERROR_DELAY = 200; var MANIPULATION_REQUEST_CMD = 'driver|browser-manipulation|request'; var MANIPULATION_RESPONSE_CMD = 'driver|browser-manipulation|response'; // Setup cross-iframe interaction messageSandbox.on(messageSandbox.SERVICE_MSG_RECEIVED_EVENT, function (e) { if (e.message.cmd === MANIPULATION_REQUEST_CMD) { var element = _testcafeCore.domUtils.findIframeByWindow(e.source); var _e$message = e.message, command = _e$message.command, cropDimensions = _e$message.cropDimensions; if (cropDimensions) command.options = new _options.ElementScreenshotOptions({ crop: cropDimensions, includePaddings: false }); var manipulation = new ManipulationExecutor(command); manipulation.element = element; manipulation.execute().then(function (result) { return messageSandbox.sendServiceMsg({ cmd: MANIPULATION_RESPONSE_CMD, result: result }, e.source); }); } }); var ManipulationExecutor = function () { function ManipulationExecutor(command, globalSelectorTimeout, statusBar) { _classCallCheck(this, ManipulationExecutor); this.command = command; this.globalSelectorTimeout = globalSelectorTimeout; this.statusBar = statusBar; this.element = null; } ManipulationExecutor.prototype._getAbsoluteCropValues = function _getAbsoluteCropValues() { var _element$getBoundingC = this.element.getBoundingClientRect(), top = _element$getBoundingC.top, left = _element$getBoundingC.left; left += this.command.options.originOffset.x; top += this.command.options.originOffset.y; var right = left + this.command.options.crop.right; var bottom = top + this.command.options.crop.bottom; top += this.command.options.crop.top; left += this.command.options.crop.left; return { top: top, left: left, bottom: bottom, right: right }; }; ManipulationExecutor.prototype._createManipulationReadyMessage = function _createManipulationReadyMessage() { var dpr = window.devicePixelRatio || 1; var message = { cmd: _clientMessages2.default.readyForBrowserManipulation, pageDimensions: { dpr: dpr, innerWidth: window.innerWidth, innerHeight: window.innerHeight, documentWidth: document.documentElement.clientWidth, documentHeight: document.documentElement.clientHeight, bodyWidth: document.body.clientWidth, bodyHeight: document.body.clientHeight }, disableResending: true }; if (this.command.type === _type2.default.takeElementScreenshot) message.cropDimensions = this._getAbsoluteCropValues(); return message; }; ManipulationExecutor.prototype._runScrollBeforeScreenshot = function _runScrollBeforeScreenshot() { var _this = this; return _hammerhead.Promise.resolve().then(function () { if (_this.element || !_this.command.selector) return _hammerhead.Promise.resolve(); var selectorTimeout = _this.command.selector.timeout; var specificSelectorTimeout = typeof selectorTimeout === 'number' ? selectorTimeout : _this.globalSelectorTimeout; _this.statusBar.showWaitingElementStatus(specificSelectorTimeout); return (0, _ensureElements.ensureElements)([(0, _ensureElements.createElementDescriptor)(_this.command.selector)], _this.globalSelectorTimeout).then(function (elements) { _this.statusBar.hideWaitingElementStatus(); _this.element = elements[0]; }).catch(function (error) { _this.statusBar.hideWaitingElementStatus(); throw error; }); }).then(function () { (0, _ensureCropOptions2.default)(_this.element, _this.command.options); var _command$options = _this.command.options, scrollTargetX = _command$options.scrollTargetX, scrollTargetY = _command$options.scrollTargetY, scrollToCenter = _command$options.scrollToCenter; var scrollAutomation = new _testcafeAutomation.Scroll(_this.element, new _options.ScrollOptions({ offsetX: scrollTargetX, offsetY: scrollTargetY, scrollToCenter: scrollToCenter, skipParentFrames: true })); return scrollAutomation.run(); }); }; ManipulationExecutor.prototype._hideUI = function _hideUI() { (0, _testcafeUi.hide)(); if (this.command.markData) (0, _testcafeUi.showScreenshotMark)(this.command.markData); return (0, _testcafeCore.delay)(HIDING_UI_RELAYOUT_DELAY); }; ManipulationExecutor.prototype._showUI = function _showUI() { if (this.command.markData) (0, _testcafeUi.hideScreenshotMark)(); (0, _testcafeUi.show)(); }; ManipulationExecutor.prototype._requestManipulation = function _requestManipulation() { if (window.top === window) return _hammerhead.transport.queuedAsyncServiceMsg(this._createManipulationReadyMessage()); var cropDimensions = this._getAbsoluteCropValues(); var iframeRequestPromise = (0, _testcafeCore.sendRequestToFrame)({ cmd: MANIPULATION_REQUEST_CMD, command: this.command, cropDimensions: cropDimensions }, MANIPULATION_RESPONSE_CMD, window.parent); return iframeRequestPromise.then(function (message) { if (!message.result) return { result: null }; var _message$result = message.result, result = _message$result.result, executionError = _message$result.executionError; if (executionError) throw executionError; return { result: result }; }); }; ManipulationExecutor.prototype._runManipulation = function _runManipulation() { var _this2 = this; var manipulationResult = null; return _hammerhead.Promise.resolve().then(function () { if (_this2.command.type !== _type2.default.takeElementScreenshot) return _hammerhead.Promise.resolve(); _testcafeCore.scrollController.stopPropagation(); return _this2._runScrollBeforeScreenshot(); }).then(function () { if (window.top === window) return _this2._hideUI(); return _hammerhead.Promise.resolve(); }).then(function () { return _this2._requestManipulation(); }).then(function (_ref) { var result = _ref.result, error = _ref.error; if (error) throw error; _testcafeCore.scrollController.enablePropagation(); manipulationResult = result; if (window.top === window) _this2._showUI(); return (0, _testcafeCore.delay)(POSSIBLE_RESIZE_ERROR_DELAY); }).then(function () { return new _status2.default({ isCommandResult: true, result: manipulationResult }); }).catch(function (err) { _testcafeCore.scrollController.enablePropagation(); return new _status2.default({ isCommandResult: true, executionError: err }); }); }; ManipulationExecutor.prototype.execute = function execute() { var _this3 = this; var _runWithBarriers = (0, _runWithBarriers3.default)(function () { return _this3._runManipulation(); }), barriersPromise = _runWithBarriers.barriersPromise; return barriersPromise; }; return ManipulationExecutor; }(); module.exports = exports['default']; } }, "client-functions": { "client-function-executor.js": function (exports, module, require) { exports.__esModule = true; var _hammerhead = require('../../deps/hammerhead'); var _status = require('../../status'); var _status2 = _interopRequireDefault(_status); var _replicator = require('./replicator'); var _evalFunction = require('./eval-function'); var _evalFunction2 = _interopRequireDefault(_evalFunction); var _testRun = require('../../../../errors/test-run'); 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 ClientFunctionExecutor = function () { function ClientFunctionExecutor(command) { _classCallCheck(this, ClientFunctionExecutor); this.command = command; this.replicator = this._createReplicator(); this.dependencies = this.replicator.decode(this.command.dependencies); this.fn = (0, _evalFunction2.default)(this.command.fnCode, this.dependencies); } ClientFunctionExecutor.prototype.getResult = function getResult() { var _this = this; return _hammerhead.Promise.resolve().then(function () { var args = _this.replicator.decode(_this.command.args); return _this._executeFn(args); }).catch(function (err) { if (!err.isTestCafeError) err = new _testRun.UncaughtErrorInClientFunctionCode(_this.command.instantiationCallsiteName, err); throw err; }); }; ClientFunctionExecutor.prototype.getResultDriverStatus = function getResultDriverStatus() { var _this2 = this; return this.getResult().then(function (result) { return new _status2.default({ isCommandResult: true, result: _this2.replicator.encode(result) }); }).catch(function (err) { return new _status2.default({ isCommandResult: true, executionError: err }); }); }; //Overridable methods ClientFunctionExecutor.prototype._createReplicator = function _createReplicator() { return (0, _replicator.createReplicator)([new _replicator.ClientFunctionNodeTransform(this.command.instantiationCallsiteName), new _replicator.FunctionTransform()]); }; ClientFunctionExecutor.prototype._executeFn = function _executeFn(args) { return this.fn.apply(window, args); }; return ClientFunctionExecutor; }(); exports.default = ClientFunctionExecutor; module.exports = exports['default']; }, "eval-function.js": function (exports, module, require) { exports.__esModule = true; exports.default = evalFunction; var _hammerhead = require('../../deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // NOTE: expose Promise to the function code /* eslint-disable @typescript-eslint/no-unused-vars */ var Promise = _hammerhead2.default.Promise; /* eslint-enable @typescript-eslint/no-unused-vars */ // NOTE: evalFunction is isolated into a separate module to // restrict access to TestCafe intrinsics for the evaluated code. // It also accepts `__dependencies$` argument which may be used by evaluated code. /* eslint-disable @typescript-eslint/no-unused-vars */ function evalFunction(fnCode, __dependencies$) { // NOTE: `eval` in strict mode will not override context variables 'use strict'; /* eslint-disable no-eval */ return eval(fnCode); /* eslint-enable no-eval */ } /* eslint-enable @typescript-eslint/no-unused-vars */ module.exports = exports['default']; }, "replicator.js": function (exports, module, require) { exports.__esModule = true; exports.ClientFunctionNodeTransform = exports.SelectorNodeTransform = exports.FunctionTransform = undefined; exports.createReplicator = createReplicator; var _replicator = require('replicator'); var _replicator2 = _interopRequireDefault(_replicator); var _evalFunction = require('./eval-function'); var _evalFunction2 = _interopRequireDefault(_evalFunction); var _nodeSnapshots = require('./selector-executor/node-snapshots'); var _testRun = require('../../../../errors/test-run'); var _hammerhead = require('../../deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); 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"); } } // NOTE: save original ctors because they may be overwritten by page code var Node = window.Node; var identity = function identity(val) { return val; }; function createReplicator(transforms) { // NOTE: we will serialize replicator results // to JSON with a command or command result. // Therefore there is no need to do additional job here, // so we use identity functions for serialization. var replicator = new _replicator2.default({ serialize: identity, deserialize: identity }); return replicator.addTransforms(transforms); } var FunctionTransform = exports.FunctionTransform = function () { function FunctionTransform() { _classCallCheck(this, FunctionTransform); this.type = 'Function'; } FunctionTransform.prototype.shouldTransform = function shouldTransform(type) { return type === 'function'; }; FunctionTransform.prototype.toSerializable = function toSerializable() { return ''; }; FunctionTransform.prototype.fromSerializable = function fromSerializable(_ref) { var fnCode = _ref.fnCode, dependencies = _ref.dependencies; return (0, _evalFunction2.default)(fnCode, dependencies); }; return FunctionTransform; }(); var SelectorNodeTransform = exports.SelectorNodeTransform = function () { function SelectorNodeTransform(customDOMProperties) { _classCallCheck(this, SelectorNodeTransform); this.type = 'Node'; this.customDOMProperties = customDOMProperties || {}; } SelectorNodeTransform.prototype._extend = function _extend(snapshot, node) { var _this = this; _hammerhead2.default.nativeMethods.objectKeys.call(window.Object, this.customDOMProperties).forEach(function (prop) { try { snapshot[prop] = _this.customDOMProperties[prop](node); } catch (err) { throw new _testRun.UncaughtErrorInCustomDOMPropertyCode(_this.instantiationCallsiteName, err, prop); } }); }; SelectorNodeTransform.prototype.shouldTransform = function shouldTransform(type, val) { return val instanceof Node; }; SelectorNodeTransform.prototype.toSerializable = function toSerializable(node) { var snapshot = node.nodeType === 1 ? new _nodeSnapshots.ElementSnapshot(node) : new _nodeSnapshots.NodeSnapshot(node); this._extend(snapshot, node); return snapshot; }; return SelectorNodeTransform; }(); var ClientFunctionNodeTransform = exports.ClientFunctionNodeTransform = function () { function ClientFunctionNodeTransform(instantiationCallsiteName) { _classCallCheck(this, ClientFunctionNodeTransform); this.type = 'Node'; this.instantiationCallsiteName = instantiationCallsiteName; } ClientFunctionNodeTransform.prototype.shouldTransform = function shouldTransform(type, val) { if (val instanceof Node) throw new _testRun.DomNodeClientFunctionResultError(this.instantiationCallsiteName); }; return ClientFunctionNodeTransform; }(); }, "selector-executor": { "filter.js": function (exports, module, require) { var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _FILTER_ERROR_TO_API_; var _testRun = require('../../../../../errors/test-run'); var _elementUtils = require('../../../utils/element-utils'); var _testcafeCore = require('../../../deps/testcafe-core'); var _testcafeCore2 = _interopRequireDefault(_testcafeCore); var _hammerhead = require('../../../deps/hammerhead'); var _hammerhead2 = _interopRequireDefault(_hammerhead); 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 arrayUtils = _testcafeCore2.default.arrayUtils; var typeUtils = _hammerhead2.default.utils.types; var nativeMethods = _hammerhead2.default.nativeMethods; var SELECTOR_FILTER_ERROR = { filterVisible: 1, filterHidden: 2, nth: 3 }; var FILTER_ERROR_TO_API_RE = (_FILTER_ERROR_TO_API_ = {}, _FILTER_ERROR_TO_API_[SELECTOR_FILTER_ERROR.filterVisible] = /^\.filterVisible\(\)$/, _FILTER_ERROR_TO_API_[SELECTOR_FILTER_ERROR.filterHidden] = /^\.filterHidden\(\)$/, _FILTER_ERROR_TO_API_[SELECTOR_FILTER_ERROR.nth] = /^\.nth\(\d+\)$/, _FILTER_ERROR_TO_API_); var SelectorFilter = function () { function SelectorFilter() { _classCallCheck(this, SelectorFilter); this.err = null; } SelectorFilter.prototype.filter = function filter(node, options, apiInfo) { var filtered = arrayUtils.filter(node, _elementUtils.exists); if (options.filterVisible) { filtered = filtered.filter(_elementUtils.visible); this.assertFilterError(filtered, apiInfo, SELECTOR_FILTER_ERROR.filterVisible); } if (options.filterHidden) { filtered = filtered.filter(function (n) { return !(0, _elementUtils.visible)(n); }); this.assertFilterError(filtered, apiInfo, SELECTOR_FILTER_ERROR.filterHidden); } if (options.counterMode) { if (options.index !== null) filtered = this.getNodeByIndex(filtered, options.index) ? 1 : 0;else filtered = filtered.length; } else { if (options.collectionMode) { if (options.index !== null) { var nodeOnIndex = this.getNodeByIndex(filtered, options.index); filtered = nodeOnIndex ? [nodeOnIndex] : []; } } else filtered = this.getNodeByIndex(filtered, options.index || 0); if (typeof options.index === 'number') this.assertFilterError(filtered, apiInfo, SELECTOR_FILTER_ERROR.nth); } return filtered; }; SelectorFilter.prototype.cast = function cas