webdriverio 9.7.1 → 9.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/commands/browser/switchFrame.d.ts.map +1 -1
- package/build/index.js +261 -244
- package/build/node.js +264 -247
- package/build/session/context.d.ts.map +1 -1
- package/build/types.d.ts +5 -0
- package/build/types.d.ts.map +1 -1
- package/package.json +6 -6
package/build/index.js
CHANGED
|
@@ -42,8 +42,8 @@ import logger from "@wdio/logger";
|
|
|
42
42
|
import { getBrowserObject } from "@wdio/utils";
|
|
43
43
|
var log = logger("webdriverio");
|
|
44
44
|
async function implicitWait(currentElement, commandName) {
|
|
45
|
-
const
|
|
46
|
-
const skipForMobileScroll =
|
|
45
|
+
const browser2 = getBrowserObject(currentElement);
|
|
46
|
+
const skipForMobileScroll = browser2.isMobile && await browser2.isNativeContext && (commandName === "scrollIntoView" || commandName === "tap");
|
|
47
47
|
if (!currentElement.elementId && !commandName.match(/(waitUntil|waitFor|isExisting|is?\w+Displayed|is?\w+Clickable)/) && !skipForMobileScroll) {
|
|
48
48
|
log.debug(
|
|
49
49
|
"command ".concat(commandName, ' was called on an element ("').concat(currentElement.selector, '") ') + "that wasn't found, waiting for it..."
|
|
@@ -174,13 +174,13 @@ var WebDriverError = class extends Error {
|
|
|
174
174
|
}
|
|
175
175
|
};
|
|
176
176
|
function getElement(selector, res, props = { isReactElement: false, isShadowElement: false }) {
|
|
177
|
-
const
|
|
177
|
+
const browser2 = getBrowserObject2(this);
|
|
178
178
|
const browserCommandKeys = Object.keys(browser_exports);
|
|
179
179
|
const propertiesObject = {
|
|
180
180
|
/**
|
|
181
181
|
* filter out browser commands from object
|
|
182
182
|
*/
|
|
183
|
-
...Object.entries(clone(
|
|
183
|
+
...Object.entries(clone(browser2.__propertiesObject__)).reduce((commands, [name, descriptor]) => {
|
|
184
184
|
if (!browserCommandKeys.includes(name)) {
|
|
185
185
|
commands[name] = descriptor;
|
|
186
186
|
}
|
|
@@ -212,19 +212,19 @@ function getElement(selector, res, props = { isReactElement: false, isShadowElem
|
|
|
212
212
|
const elementInstance = element(this.sessionId, elementErrorHandler(wrapCommand));
|
|
213
213
|
const origAddCommand = elementInstance.addCommand.bind(elementInstance);
|
|
214
214
|
elementInstance.addCommand = (name, fn) => {
|
|
215
|
-
|
|
215
|
+
browser2.__propertiesObject__[name] = { value: fn };
|
|
216
216
|
origAddCommand(name, fn);
|
|
217
217
|
};
|
|
218
218
|
return elementInstance;
|
|
219
219
|
}
|
|
220
220
|
var getElements = function getElements2(selector, elemResponse, props = { isReactElement: false, isShadowElement: false }) {
|
|
221
|
-
const
|
|
221
|
+
const browser2 = getBrowserObject2(this);
|
|
222
222
|
const browserCommandKeys = Object.keys(browser_exports);
|
|
223
223
|
const propertiesObject = {
|
|
224
224
|
/**
|
|
225
225
|
* filter out browser commands from object
|
|
226
226
|
*/
|
|
227
|
-
...Object.entries(clone(
|
|
227
|
+
...Object.entries(clone(browser2.__propertiesObject__)).reduce((commands, [name, descriptor]) => {
|
|
228
228
|
if (!browserCommandKeys.includes(name)) {
|
|
229
229
|
commands[name] = descriptor;
|
|
230
230
|
}
|
|
@@ -263,7 +263,7 @@ var getElements = function getElements2(selector, elemResponse, props = { isReac
|
|
|
263
263
|
const elementInstance = element(this.sessionId, elementErrorHandler(wrapCommand));
|
|
264
264
|
const origAddCommand = elementInstance.addCommand.bind(elementInstance);
|
|
265
265
|
elementInstance.addCommand = (name, fn) => {
|
|
266
|
-
|
|
266
|
+
browser2.__propertiesObject__[name] = { value: fn };
|
|
267
267
|
origAddCommand(name, fn);
|
|
268
268
|
};
|
|
269
269
|
return elementInstance;
|
|
@@ -1177,11 +1177,11 @@ function uninstallFakeTimers() {
|
|
|
1177
1177
|
var fakerScript = 'function FakeTimers () {\n/*\n * Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no. All rights reserved.\n * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\n/**\n * @typedef {object} IdleDeadline\n * @property {boolean} didTimeout - whether or not the callback was called before reaching the optional timeout\n * @property {function():number} timeRemaining - a floating-point value providing an estimate of the number of milliseconds remaining in the current idle period\n */\n\n/**\n * Queues a function to be called during a browser\'s idle periods\n *\n * @callback RequestIdleCallback\n * @param {function(IdleDeadline)} callback\n * @param {{timeout: number}} options - an options object\n * @returns {number} the id\n */\n\n/**\n * @callback NextTick\n * @param {VoidVarArgsFunc} callback - the callback to run\n * @param {...*} args - optional arguments to call the callback with\n * @returns {void}\n */\n\n/**\n * @callback SetImmediate\n * @param {VoidVarArgsFunc} callback - the callback to run\n * @param {...*} args - optional arguments to call the callback with\n * @returns {NodeImmediate}\n */\n\n/**\n * @callback VoidVarArgsFunc\n * @param {...*} callback - the callback to run\n * @returns {void}\n */\n\n/**\n * @typedef RequestAnimationFrame\n * @property {function(number):void} requestAnimationFrame\n * @returns {number} - the id\n */\n\n/**\n * @typedef Performance\n * @property {function(): number} now\n */\n\n/* eslint-disable jsdoc/require-property-description */\n/**\n * @typedef {object} Clock\n * @property {number} now - the current time\n * @property {Date} Date - the Date constructor\n * @property {number} loopLimit - the maximum number of timers before assuming an infinite loop\n * @property {RequestIdleCallback} requestIdleCallback\n * @property {function(number):void} cancelIdleCallback\n * @property {setTimeout} setTimeout\n * @property {clearTimeout} clearTimeout\n * @property {NextTick} nextTick\n * @property {queueMicrotask} queueMicrotask\n * @property {setInterval} setInterval\n * @property {clearInterval} clearInterval\n * @property {SetImmediate} setImmediate\n * @property {function(NodeImmediate):void} clearImmediate\n * @property {function():number} countTimers\n * @property {RequestAnimationFrame} requestAnimationFrame\n * @property {function(number):void} cancelAnimationFrame\n * @property {function():void} runMicrotasks\n * @property {function(string | number): number} tick\n * @property {function(string | number): Promise<number>} tickAsync\n * @property {function(): number} next\n * @property {function(): Promise<number>} nextAsync\n * @property {function(): number} runAll\n * @property {function(): number} runToFrame\n * @property {function(): Promise<number>} runAllAsync\n * @property {function(): number} runToLast\n * @property {function(): Promise<number>} runToLastAsync\n * @property {function(): void} reset\n * @property {function(number | Date): void} setSystemTime\n * @property {function(number): void} jump\n * @property {Performance} performance\n * @property {function(number[]): number[]} hrtime - process.hrtime (legacy)\n * @property {function(): void} uninstall Uninstall the clock.\n * @property {Function[]} methods - the methods that are faked\n * @property {boolean} [shouldClearNativeTimers] inherited from config\n * @property {{methodName:string, original:any}[] | undefined} timersModuleMethods\n */\n/* eslint-enable jsdoc/require-property-description */\n\n/**\n * Configuration object for the `install` method.\n *\n * @typedef {object} Config\n * @property {number|Date} [now] a number (in milliseconds) or a Date object (default epoch)\n * @property {string[]} [toFake] names of the methods that should be faked.\n * @property {number} [loopLimit] the maximum number of timers that will be run when calling runAll()\n * @property {boolean} [shouldAdvanceTime] tells FakeTimers to increment mocked time automatically (default false)\n * @property {number} [advanceTimeDelta] increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)\n * @property {boolean} [shouldClearNativeTimers] forwards clear timer calls to native functions if they are not fakes (default: false)\n */\n\n/* eslint-disable jsdoc/require-property-description */\n/**\n * The internal structure to describe a scheduled fake timer\n *\n * @typedef {object} Timer\n * @property {Function} func\n * @property {*[]} args\n * @property {number} delay\n * @property {number} callAt\n * @property {number} createdAt\n * @property {boolean} immediate\n * @property {number} id\n * @property {Error} [error]\n */\n\n/**\n * A Node timer\n *\n * @typedef {object} NodeImmediate\n * @property {function(): boolean} hasRef\n * @property {function(): NodeImmediate} ref\n * @property {function(): NodeImmediate} unref\n */\n/* eslint-enable jsdoc/require-property-description */\n\n/**\n * Mocks available features in the specified global namespace.\n *\n * @param {*} _global Namespace to mock (e.g. `window`)\n * @returns {FakeTimers}\n */\nfunction withGlobal(_global) {\n const maxTimeout = Math.pow(2, 31) - 1; //see https://heycam.github.io/webidl/#abstract-opdef-converttoint\n const idCounterStart = 1e12; // arbitrarily large number to avoid collisions with native timer IDs\n const NOOP = function () {\n return undefined;\n };\n const NOOP_ARRAY = function () {\n return [];\n };\n const timeoutResult = _global.setTimeout(NOOP, 0);\n const addTimerReturnsObject = typeof timeoutResult === "object";\n const hrtimePresent =\n _global.process && typeof _global.process.hrtime === "function";\n const hrtimeBigintPresent =\n hrtimePresent && typeof _global.process.hrtime.bigint === "function";\n const nextTickPresent =\n _global.process && typeof _global.process.nextTick === "function";\n const utilPromisify = _global.process && require("util").promisify;\n const performancePresent =\n _global.performance && typeof _global.performance.now === "function";\n const hasPerformancePrototype =\n _global.Performance &&\n (typeof _global.Performance).match(/^(function|object)$/);\n const hasPerformanceConstructorPrototype =\n _global.performance &&\n _global.performance.constructor &&\n _global.performance.constructor.prototype;\n const queueMicrotaskPresent = _global.hasOwnProperty("queueMicrotask");\n const requestAnimationFramePresent =\n _global.requestAnimationFrame &&\n typeof _global.requestAnimationFrame === "function";\n const cancelAnimationFramePresent =\n _global.cancelAnimationFrame &&\n typeof _global.cancelAnimationFrame === "function";\n const requestIdleCallbackPresent =\n _global.requestIdleCallback &&\n typeof _global.requestIdleCallback === "function";\n const cancelIdleCallbackPresent =\n _global.cancelIdleCallback &&\n typeof _global.cancelIdleCallback === "function";\n const setImmediatePresent =\n _global.setImmediate && typeof _global.setImmediate === "function";\n const intlPresent = _global.Intl && typeof _global.Intl === "object";\n\n _global.clearTimeout(timeoutResult);\n\n const NativeDate = _global.Date;\n const NativeIntl = _global.Intl;\n let uniqueTimerId = idCounterStart;\n\n /**\n * @param {number} num\n * @returns {boolean}\n */\n function isNumberFinite(num) {\n if (Number.isFinite) {\n return Number.isFinite(num);\n }\n\n return isFinite(num);\n }\n\n let isNearInfiniteLimit = false;\n\n /**\n * @param {Clock} clock\n * @param {number} i\n */\n function checkIsNearInfiniteLimit(clock, i) {\n if (clock.loopLimit && i === clock.loopLimit - 1) {\n isNearInfiniteLimit = true;\n }\n }\n\n /**\n *\n */\n function resetIsNearInfiniteLimit() {\n isNearInfiniteLimit = false;\n }\n\n /**\n * Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into\n * number of milliseconds. This is used to support human-readable strings passed\n * to clock.tick()\n *\n * @param {string} str\n * @returns {number}\n */\n function parseTime(str) {\n if (!str) {\n return 0;\n }\n\n const strings = str.split(":");\n const l = strings.length;\n let i = l;\n let ms = 0;\n let parsed;\n\n if (l > 3 || !/^(\\d\\d:){0,2}\\d\\d?$/.test(str)) {\n throw new Error(\n "tick only understands numbers, \'m:s\' and \'h:m:s\'. Each part must be two digits",\n );\n }\n\n while (i--) {\n parsed = parseInt(strings[i], 10);\n\n if (parsed >= 60) {\n throw new Error(`Invalid time ${str}`);\n }\n\n ms += parsed * Math.pow(60, l - i - 1);\n }\n\n return ms * 1000;\n }\n\n /**\n * Get the decimal part of the millisecond value as nanoseconds\n *\n * @param {number} msFloat the number of milliseconds\n * @returns {number} an integer number of nanoseconds in the range [0,1e6)\n *\n * Example: nanoRemainer(123.456789) -> 456789\n */\n function nanoRemainder(msFloat) {\n const modulo = 1e6;\n const remainder = (msFloat * 1e6) % modulo;\n const positiveRemainder =\n remainder < 0 ? remainder + modulo : remainder;\n\n return Math.floor(positiveRemainder);\n }\n\n /**\n * Used to grok the `now` parameter to createClock.\n *\n * @param {Date|number} epoch the system time\n * @returns {number}\n */\n function getEpoch(epoch) {\n if (!epoch) {\n return 0;\n }\n if (typeof epoch.getTime === "function") {\n return epoch.getTime();\n }\n if (typeof epoch === "number") {\n return epoch;\n }\n throw new TypeError("now should be milliseconds since UNIX epoch");\n }\n\n /**\n * @param {number} from\n * @param {number} to\n * @param {Timer} timer\n * @returns {boolean}\n */\n function inRange(from, to, timer) {\n return timer && timer.callAt >= from && timer.callAt <= to;\n }\n\n /**\n * @param {Clock} clock\n * @param {Timer} job\n */\n function getInfiniteLoopError(clock, job) {\n const infiniteLoopError = new Error(\n `Aborting after running ${clock.loopLimit} timers, assuming an infinite loop!`,\n );\n\n if (!job.error) {\n return infiniteLoopError;\n }\n\n // pattern never matched in Node\n const computedTargetPattern = /target\\.*[<|(|[].*?[>|\\]|)]\\s*/;\n let clockMethodPattern = new RegExp(\n String(Object.keys(clock).join("|")),\n );\n\n if (addTimerReturnsObject) {\n // node.js environment\n clockMethodPattern = new RegExp(\n `\\\\s+at (Object\\\\.)?(?:${Object.keys(clock).join("|")})\\\\s+`,\n );\n }\n\n let matchedLineIndex = -1;\n job.error.stack.split("\\n").some(function (line, i) {\n // If we\'ve matched a computed target line (e.g. setTimeout) then we\n // don\'t need to look any further. Return true to stop iterating.\n const matchedComputedTarget = line.match(computedTargetPattern);\n /* istanbul ignore if */\n if (matchedComputedTarget) {\n matchedLineIndex = i;\n return true;\n }\n\n // If we\'ve matched a clock method line, then there may still be\n // others further down the trace. Return false to keep iterating.\n const matchedClockMethod = line.match(clockMethodPattern);\n if (matchedClockMethod) {\n matchedLineIndex = i;\n return false;\n }\n\n // If we haven\'t matched anything on this line, but we matched\n // previously and set the matched line index, then we can stop.\n // If we haven\'t matched previously, then we should keep iterating.\n return matchedLineIndex >= 0;\n });\n\n const stack = `${infiniteLoopError}\\n${job.type || "Microtask"} - ${\n job.func.name || "anonymous"\n }\\n${job.error.stack\n .split("\\n")\n .slice(matchedLineIndex + 1)\n .join("\\n")}`;\n\n try {\n Object.defineProperty(infiniteLoopError, "stack", {\n value: stack,\n });\n } catch (e) {\n // noop\n }\n\n return infiniteLoopError;\n }\n\n /**\n * @param {Date} target\n * @param {Date} source\n * @returns {Date} the target after modifications\n */\n function mirrorDateProperties(target, source) {\n let prop;\n for (prop in source) {\n if (source.hasOwnProperty(prop)) {\n target[prop] = source[prop];\n }\n }\n\n // set special now implementation\n if (source.now) {\n target.now = function now() {\n return target.clock.now;\n };\n } else {\n delete target.now;\n }\n\n // set special toSource implementation\n if (source.toSource) {\n target.toSource = function toSource() {\n return source.toSource();\n };\n } else {\n delete target.toSource;\n }\n\n // set special toString implementation\n target.toString = function toString() {\n return source.toString();\n };\n\n target.prototype = source.prototype;\n target.parse = source.parse;\n target.UTC = source.UTC;\n target.prototype.toUTCString = source.prototype.toUTCString;\n target.isFake = true;\n\n return target;\n }\n\n //eslint-disable-next-line jsdoc/require-jsdoc\n function createDate() {\n /**\n * @param {number} year\n * @param {number} month\n * @param {number} date\n * @param {number} hour\n * @param {number} minute\n * @param {number} second\n * @param {number} ms\n * @returns {Date}\n */\n function ClockDate(year, month, date, hour, minute, second, ms) {\n // the Date constructor called as a function, ref Ecma-262 Edition 5.1, section 15.9.2.\n // This remains so in the 10th edition of 2019 as well.\n if (!(this instanceof ClockDate)) {\n return new NativeDate(ClockDate.clock.now).toString();\n }\n\n // if Date is called as a constructor with \'new\' keyword\n // Defensive and verbose to avoid potential harm in passing\n // explicit undefined when user does not pass argument\n switch (arguments.length) {\n case 0:\n return new NativeDate(ClockDate.clock.now);\n case 1:\n return new NativeDate(year);\n case 2:\n return new NativeDate(year, month);\n case 3:\n return new NativeDate(year, month, date);\n case 4:\n return new NativeDate(year, month, date, hour);\n case 5:\n return new NativeDate(year, month, date, hour, minute);\n case 6:\n return new NativeDate(\n year,\n month,\n date,\n hour,\n minute,\n second,\n );\n default:\n return new NativeDate(\n year,\n month,\n date,\n hour,\n minute,\n second,\n ms,\n );\n }\n }\n\n return mirrorDateProperties(ClockDate, NativeDate);\n }\n\n /**\n * Mirror Intl by default on our fake implementation\n *\n * Most of the properties are the original native ones,\n * but we need to take control of those that have a\n * dependency on the current clock.\n *\n * @returns {object} the partly fake Intl implementation\n */\n function createIntl() {\n const ClockIntl = {};\n /*\n * All properties of Intl are non-enumerable, so we need\n * to do a bit of work to get them out.\n */\n Object.getOwnPropertyNames(NativeIntl).forEach(\n (property) => (ClockIntl[property] = NativeIntl[property]),\n );\n\n ClockIntl.DateTimeFormat = function (...args) {\n const realFormatter = new NativeIntl.DateTimeFormat(...args);\n const formatter = {};\n\n ["formatRange", "formatRangeToParts", "resolvedOptions"].forEach(\n (method) => {\n formatter[method] =\n realFormatter[method].bind(realFormatter);\n },\n );\n\n ["format", "formatToParts"].forEach((method) => {\n formatter[method] = function (date) {\n return realFormatter[method](date || ClockIntl.clock.now);\n };\n });\n\n return formatter;\n };\n\n ClockIntl.DateTimeFormat.prototype = Object.create(\n NativeIntl.DateTimeFormat.prototype,\n );\n\n ClockIntl.DateTimeFormat.supportedLocalesOf =\n NativeIntl.DateTimeFormat.supportedLocalesOf;\n\n return ClockIntl;\n }\n\n //eslint-disable-next-line jsdoc/require-jsdoc\n function enqueueJob(clock, job) {\n // enqueues a microtick-deferred task - ecma262/#sec-enqueuejob\n if (!clock.jobs) {\n clock.jobs = [];\n }\n clock.jobs.push(job);\n }\n\n //eslint-disable-next-line jsdoc/require-jsdoc\n function runJobs(clock) {\n // runs all microtick-deferred tasks - ecma262/#sec-runjobs\n if (!clock.jobs) {\n return;\n }\n for (let i = 0; i < clock.jobs.length; i++) {\n const job = clock.jobs[i];\n job.func.apply(null, job.args);\n\n checkIsNearInfiniteLimit(clock, i);\n if (clock.loopLimit && i > clock.loopLimit) {\n throw getInfiniteLoopError(clock, job);\n }\n }\n resetIsNearInfiniteLimit();\n clock.jobs = [];\n }\n\n /**\n * @param {Clock} clock\n * @param {Timer} timer\n * @returns {number} id of the created timer\n */\n function addTimer(clock, timer) {\n if (timer.func === undefined) {\n throw new Error("Callback must be provided to timer calls");\n }\n\n if (addTimerReturnsObject) {\n // Node.js environment\n if (typeof timer.func !== "function") {\n throw new TypeError(\n `[ERR_INVALID_CALLBACK]: Callback must be a function. Received ${\n timer.func\n } of type ${typeof timer.func}`,\n );\n }\n }\n\n if (isNearInfiniteLimit) {\n timer.error = new Error();\n }\n\n timer.type = timer.immediate ? "Immediate" : "Timeout";\n\n if (timer.hasOwnProperty("delay")) {\n if (typeof timer.delay !== "number") {\n timer.delay = parseInt(timer.delay, 10);\n }\n\n if (!isNumberFinite(timer.delay)) {\n timer.delay = 0;\n }\n timer.delay = timer.delay > maxTimeout ? 1 : timer.delay;\n timer.delay = Math.max(0, timer.delay);\n }\n\n if (timer.hasOwnProperty("interval")) {\n timer.type = "Interval";\n timer.interval = timer.interval > maxTimeout ? 1 : timer.interval;\n }\n\n if (timer.hasOwnProperty("animation")) {\n timer.type = "AnimationFrame";\n timer.animation = true;\n }\n\n if (timer.hasOwnProperty("idleCallback")) {\n timer.type = "IdleCallback";\n timer.idleCallback = true;\n }\n\n if (!clock.timers) {\n clock.timers = {};\n }\n\n timer.id = uniqueTimerId++;\n timer.createdAt = clock.now;\n timer.callAt =\n clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));\n\n clock.timers[timer.id] = timer;\n\n if (addTimerReturnsObject) {\n const res = {\n refed: true,\n ref: function () {\n this.refed = true;\n return res;\n },\n unref: function () {\n this.refed = false;\n return res;\n },\n hasRef: function () {\n return this.refed;\n },\n refresh: function () {\n timer.callAt =\n clock.now +\n (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));\n\n // it _might_ have been removed, but if not the assignment is perfectly fine\n clock.timers[timer.id] = timer;\n\n return res;\n },\n [Symbol.toPrimitive]: function () {\n return timer.id;\n },\n };\n return res;\n }\n\n return timer.id;\n }\n\n /* eslint consistent-return: "off" */\n /**\n * Timer comparitor\n *\n * @param {Timer} a\n * @param {Timer} b\n * @returns {number}\n */\n function compareTimers(a, b) {\n // Sort first by absolute timing\n if (a.callAt < b.callAt) {\n return -1;\n }\n if (a.callAt > b.callAt) {\n return 1;\n }\n\n // Sort next by immediate, immediate timers take precedence\n if (a.immediate && !b.immediate) {\n return -1;\n }\n if (!a.immediate && b.immediate) {\n return 1;\n }\n\n // Sort next by creation time, earlier-created timers take precedence\n if (a.createdAt < b.createdAt) {\n return -1;\n }\n if (a.createdAt > b.createdAt) {\n return 1;\n }\n\n // Sort next by id, lower-id timers take precedence\n if (a.id < b.id) {\n return -1;\n }\n if (a.id > b.id) {\n return 1;\n }\n\n // As timer ids are unique, no fallback `0` is necessary\n }\n\n /**\n * @param {Clock} clock\n * @param {number} from\n * @param {number} to\n * @returns {Timer}\n */\n function firstTimerInRange(clock, from, to) {\n const timers = clock.timers;\n let timer = null;\n let id, isInRange;\n\n for (id in timers) {\n if (timers.hasOwnProperty(id)) {\n isInRange = inRange(from, to, timers[id]);\n\n if (\n isInRange &&\n (!timer || compareTimers(timer, timers[id]) === 1)\n ) {\n timer = timers[id];\n }\n }\n }\n\n return timer;\n }\n\n /**\n * @param {Clock} clock\n * @returns {Timer}\n */\n function firstTimer(clock) {\n const timers = clock.timers;\n let timer = null;\n let id;\n\n for (id in timers) {\n if (timers.hasOwnProperty(id)) {\n if (!timer || compareTimers(timer, timers[id]) === 1) {\n timer = timers[id];\n }\n }\n }\n\n return timer;\n }\n\n /**\n * @param {Clock} clock\n * @returns {Timer}\n */\n function lastTimer(clock) {\n const timers = clock.timers;\n let timer = null;\n let id;\n\n for (id in timers) {\n if (timers.hasOwnProperty(id)) {\n if (!timer || compareTimers(timer, timers[id]) === -1) {\n timer = timers[id];\n }\n }\n }\n\n return timer;\n }\n\n /**\n * @param {Clock} clock\n * @param {Timer} timer\n */\n function callTimer(clock, timer) {\n if (typeof timer.interval === "number") {\n clock.timers[timer.id].callAt += timer.interval;\n } else {\n delete clock.timers[timer.id];\n }\n\n if (typeof timer.func === "function") {\n timer.func.apply(null, timer.args);\n } else {\n /* eslint no-eval: "off" */\n const eval2 = eval;\n (function () {\n eval2(timer.func);\n })();\n }\n }\n\n /**\n * Gets clear handler name for a given timer type\n *\n * @param {string} ttype\n */\n function getClearHandler(ttype) {\n if (ttype === "IdleCallback" || ttype === "AnimationFrame") {\n return `cancel${ttype}`;\n }\n return `clear${ttype}`;\n }\n\n /**\n * Gets schedule handler name for a given timer type\n *\n * @param {string} ttype\n */\n function getScheduleHandler(ttype) {\n if (ttype === "IdleCallback" || ttype === "AnimationFrame") {\n return `request${ttype}`;\n }\n return `set${ttype}`;\n }\n\n /**\n * Creates an anonymous function to warn only once\n */\n function createWarnOnce() {\n let calls = 0;\n return function (msg) {\n // eslint-disable-next-line\n !calls++ && console.warn(msg);\n };\n }\n const warnOnce = createWarnOnce();\n\n /**\n * @param {Clock} clock\n * @param {number} timerId\n * @param {string} ttype\n */\n function clearTimer(clock, timerId, ttype) {\n if (!timerId) {\n // null appears to be allowed in most browsers, and appears to be\n // relied upon by some libraries, like Bootstrap carousel\n return;\n }\n\n if (!clock.timers) {\n clock.timers = {};\n }\n\n // in Node, the ID is stored as the primitive value for `Timeout` objects\n // for `Immediate` objects, no ID exists, so it gets coerced to NaN\n const id = Number(timerId);\n\n if (Number.isNaN(id) || id < idCounterStart) {\n const handlerName = getClearHandler(ttype);\n\n if (clock.shouldClearNativeTimers === true) {\n const nativeHandler = clock[`_${handlerName}`];\n return typeof nativeHandler === "function"\n ? nativeHandler(timerId)\n : undefined;\n }\n warnOnce(\n `FakeTimers: ${handlerName} was invoked to clear a native timer instead of one created by this library.` +\n "\\nTo automatically clean-up native timers, use `shouldClearNativeTimers`.",\n );\n }\n\n if (clock.timers.hasOwnProperty(id)) {\n // check that the ID matches a timer of the correct type\n const timer = clock.timers[id];\n if (\n timer.type === ttype ||\n (timer.type === "Timeout" && ttype === "Interval") ||\n (timer.type === "Interval" && ttype === "Timeout")\n ) {\n delete clock.timers[id];\n } else {\n const clear = getClearHandler(ttype);\n const schedule = getScheduleHandler(timer.type);\n throw new Error(\n `Cannot clear timer: timer created with ${schedule}() but cleared with ${clear}()`,\n );\n }\n }\n }\n\n /**\n * @param {Clock} clock\n * @param {Config} config\n * @returns {Timer[]}\n */\n function uninstall(clock, config) {\n let method, i, l;\n const installedHrTime = "_hrtime";\n const installedNextTick = "_nextTick";\n\n for (i = 0, l = clock.methods.length; i < l; i++) {\n method = clock.methods[i];\n if (method === "hrtime" && _global.process) {\n _global.process.hrtime = clock[installedHrTime];\n } else if (method === "nextTick" && _global.process) {\n _global.process.nextTick = clock[installedNextTick];\n } else if (method === "performance") {\n const originalPerfDescriptor = Object.getOwnPropertyDescriptor(\n clock,\n `_${method}`,\n );\n if (\n originalPerfDescriptor &&\n originalPerfDescriptor.get &&\n !originalPerfDescriptor.set\n ) {\n Object.defineProperty(\n _global,\n method,\n originalPerfDescriptor,\n );\n } else if (originalPerfDescriptor.configurable) {\n _global[method] = clock[`_${method}`];\n }\n } else {\n if (_global[method] && _global[method].hadOwnProperty) {\n _global[method] = clock[`_${method}`];\n } else {\n try {\n delete _global[method];\n } catch (ignore) {\n /* eslint no-empty: "off" */\n }\n }\n }\n }\n\n if (config.shouldAdvanceTime === true) {\n _global.clearInterval(clock.attachedInterval);\n }\n\n // Prevent multiple executions which will completely remove these props\n clock.methods = [];\n\n // return pending timers, to enable checking what timers remained on uninstall\n if (!clock.timers) {\n return [];\n }\n return Object.keys(clock.timers).map(function mapper(key) {\n return clock.timers[key];\n });\n }\n\n /**\n * @param {object} target the target containing the method to replace\n * @param {string} method the keyname of the method on the target\n * @param {Clock} clock\n */\n function hijackMethod(target, method, clock) {\n clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(\n target,\n method,\n );\n clock[`_${method}`] = target[method];\n\n if (method === "Date") {\n const date = mirrorDateProperties(clock[method], target[method]);\n target[method] = date;\n } else if (method === "Intl") {\n target[method] = clock[method];\n } else if (method === "performance") {\n const originalPerfDescriptor = Object.getOwnPropertyDescriptor(\n target,\n method,\n );\n // JSDOM has a read only performance field so we have to save/copy it differently\n if (\n originalPerfDescriptor &&\n originalPerfDescriptor.get &&\n !originalPerfDescriptor.set\n ) {\n Object.defineProperty(\n clock,\n `_${method}`,\n originalPerfDescriptor,\n );\n\n const perfDescriptor = Object.getOwnPropertyDescriptor(\n clock,\n method,\n );\n Object.defineProperty(target, method, perfDescriptor);\n } else {\n target[method] = clock[method];\n }\n } else {\n target[method] = function () {\n return clock[method].apply(clock, arguments);\n };\n\n Object.defineProperties(\n target[method],\n Object.getOwnPropertyDescriptors(clock[method]),\n );\n }\n\n target[method].clock = clock;\n }\n\n /**\n * @param {Clock} clock\n * @param {number} advanceTimeDelta\n */\n function doIntervalTick(clock, advanceTimeDelta) {\n clock.tick(advanceTimeDelta);\n }\n\n /**\n * @typedef {object} Timers\n * @property {setTimeout} setTimeout\n * @property {clearTimeout} clearTimeout\n * @property {setInterval} setInterval\n * @property {clearInterval} clearInterval\n * @property {Date} Date\n * @property {Intl} Intl\n * @property {SetImmediate=} setImmediate\n * @property {function(NodeImmediate): void=} clearImmediate\n * @property {function(number[]):number[]=} hrtime\n * @property {NextTick=} nextTick\n * @property {Performance=} performance\n * @property {RequestAnimationFrame=} requestAnimationFrame\n * @property {boolean=} queueMicrotask\n * @property {function(number): void=} cancelAnimationFrame\n * @property {RequestIdleCallback=} requestIdleCallback\n * @property {function(number): void=} cancelIdleCallback\n */\n\n /** @type {Timers} */\n const timers = {\n setTimeout: _global.setTimeout,\n clearTimeout: _global.clearTimeout,\n setInterval: _global.setInterval,\n clearInterval: _global.clearInterval,\n Date: _global.Date,\n };\n\n if (setImmediatePresent) {\n timers.setImmediate = _global.setImmediate;\n timers.clearImmediate = _global.clearImmediate;\n }\n\n if (hrtimePresent) {\n timers.hrtime = _global.process.hrtime;\n }\n\n if (nextTickPresent) {\n timers.nextTick = _global.process.nextTick;\n }\n\n if (performancePresent) {\n timers.performance = _global.performance;\n }\n\n if (requestAnimationFramePresent) {\n timers.requestAnimationFrame = _global.requestAnimationFrame;\n }\n\n if (queueMicrotaskPresent) {\n timers.queueMicrotask = true;\n }\n\n if (cancelAnimationFramePresent) {\n timers.cancelAnimationFrame = _global.cancelAnimationFrame;\n }\n\n if (requestIdleCallbackPresent) {\n timers.requestIdleCallback = _global.requestIdleCallback;\n }\n\n if (cancelIdleCallbackPresent) {\n timers.cancelIdleCallback = _global.cancelIdleCallback;\n }\n\n if (intlPresent) {\n timers.Intl = _global.Intl;\n }\n\n const originalSetTimeout = _global.setImmediate || _global.setTimeout;\n\n /**\n * @param {Date|number} [start] the system time - non-integer values are floored\n * @param {number} [loopLimit] maximum number of timers that will be run when calling runAll()\n * @returns {Clock}\n */\n function createClock(start, loopLimit) {\n // eslint-disable-next-line no-param-reassign\n start = Math.floor(getEpoch(start));\n // eslint-disable-next-line no-param-reassign\n loopLimit = loopLimit || 1000;\n let nanos = 0;\n const adjustedSystemTime = [0, 0]; // [millis, nanoremainder]\n\n if (NativeDate === undefined) {\n throw new Error(\n "The global scope doesn\'t have a `Date` object" +\n " (see https://github.com/sinonjs/sinon/issues/1852#issuecomment-419622780)",\n );\n }\n\n const clock = {\n now: start,\n Date: createDate(),\n loopLimit: loopLimit,\n };\n\n clock.Date.clock = clock;\n\n //eslint-disable-next-line jsdoc/require-jsdoc\n function getTimeToNextFrame() {\n return 16 - ((clock.now - start) % 16);\n }\n\n //eslint-disable-next-line jsdoc/require-jsdoc\n function hrtime(prev) {\n const millisSinceStart = clock.now - adjustedSystemTime[0] - start;\n const secsSinceStart = Math.floor(millisSinceStart / 1000);\n const remainderInNanos =\n (millisSinceStart - secsSinceStart * 1e3) * 1e6 +\n nanos -\n adjustedSystemTime[1];\n\n if (Array.isArray(prev)) {\n if (prev[1] > 1e9) {\n throw new TypeError(\n "Number of nanoseconds can\'t exceed a billion",\n );\n }\n\n const oldSecs = prev[0];\n let nanoDiff = remainderInNanos - prev[1];\n let secDiff = secsSinceStart - oldSecs;\n\n if (nanoDiff < 0) {\n nanoDiff += 1e9;\n secDiff -= 1;\n }\n\n return [secDiff, nanoDiff];\n }\n return [secsSinceStart, remainderInNanos];\n }\n\n /**\n * A high resolution timestamp in milliseconds.\n *\n * @typedef {number} DOMHighResTimeStamp\n */\n\n /**\n * performance.now()\n *\n * @returns {DOMHighResTimeStamp}\n */\n function fakePerformanceNow() {\n const hrt = hrtime();\n const millis = hrt[0] * 1000 + hrt[1] / 1e6;\n return millis;\n }\n\n if (hrtimeBigintPresent) {\n hrtime.bigint = function () {\n const parts = hrtime();\n return BigInt(parts[0]) * BigInt(1e9) + BigInt(parts[1]); // eslint-disable-line\n };\n }\n\n if (intlPresent) {\n clock.Intl = createIntl();\n clock.Intl.clock = clock;\n }\n\n clock.requestIdleCallback = function requestIdleCallback(\n func,\n timeout,\n ) {\n let timeToNextIdlePeriod = 0;\n\n if (clock.countTimers() > 0) {\n timeToNextIdlePeriod = 50; // const for now\n }\n\n const result = addTimer(clock, {\n func: func,\n args: Array.prototype.slice.call(arguments, 2),\n delay:\n typeof timeout === "undefined"\n ? timeToNextIdlePeriod\n : Math.min(timeout, timeToNextIdlePeriod),\n idleCallback: true,\n });\n\n return Number(result);\n };\n\n clock.cancelIdleCallback = function cancelIdleCallback(timerId) {\n return clearTimer(clock, timerId, "IdleCallback");\n };\n\n clock.setTimeout = function setTimeout(func, timeout) {\n return addTimer(clock, {\n func: func,\n args: Array.prototype.slice.call(arguments, 2),\n delay: timeout,\n });\n };\n if (typeof _global.Promise !== "undefined" && utilPromisify) {\n clock.setTimeout[utilPromisify.custom] =\n function promisifiedSetTimeout(timeout, arg) {\n return new _global.Promise(function setTimeoutExecutor(\n resolve,\n ) {\n addTimer(clock, {\n func: resolve,\n args: [arg],\n delay: timeout,\n });\n });\n };\n }\n\n clock.clearTimeout = function clearTimeout(timerId) {\n return clearTimer(clock, timerId, "Timeout");\n };\n\n clock.nextTick = function nextTick(func) {\n return enqueueJob(clock, {\n func: func,\n args: Array.prototype.slice.call(arguments, 1),\n error: isNearInfiniteLimit ? new Error() : null,\n });\n };\n\n clock.queueMicrotask = function queueMicrotask(func) {\n return clock.nextTick(func); // explicitly drop additional arguments\n };\n\n clock.setInterval = function setInterval(func, timeout) {\n // eslint-disable-next-line no-param-reassign\n timeout = parseInt(timeout, 10);\n return addTimer(clock, {\n func: func,\n args: Array.prototype.slice.call(arguments, 2),\n delay: timeout,\n interval: timeout,\n });\n };\n\n clock.clearInterval = function clearInterval(timerId) {\n return clearTimer(clock, timerId, "Interval");\n };\n\n if (setImmediatePresent) {\n clock.setImmediate = function setImmediate(func) {\n return addTimer(clock, {\n func: func,\n args: Array.prototype.slice.call(arguments, 1),\n immediate: true,\n });\n };\n\n if (typeof _global.Promise !== "undefined" && utilPromisify) {\n clock.setImmediate[utilPromisify.custom] =\n function promisifiedSetImmediate(arg) {\n return new _global.Promise(\n function setImmediateExecutor(resolve) {\n addTimer(clock, {\n func: resolve,\n args: [arg],\n immediate: true,\n });\n },\n );\n };\n }\n\n clock.clearImmediate = function clearImmediate(timerId) {\n return clearTimer(clock, timerId, "Immediate");\n };\n }\n\n clock.countTimers = function countTimers() {\n return (\n Object.keys(clock.timers || {}).length +\n (clock.jobs || []).length\n );\n };\n\n clock.requestAnimationFrame = function requestAnimationFrame(func) {\n const result = addTimer(clock, {\n func: func,\n delay: getTimeToNextFrame(),\n get args() {\n return [fakePerformanceNow()];\n },\n animation: true,\n });\n\n return Number(result);\n };\n\n clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) {\n return clearTimer(clock, timerId, "AnimationFrame");\n };\n\n clock.runMicrotasks = function runMicrotasks() {\n runJobs(clock);\n };\n\n /**\n * @param {number|string} tickValue milliseconds or a string parseable by parseTime\n * @param {boolean} isAsync\n * @param {Function} resolve\n * @param {Function} reject\n * @returns {number|undefined} will return the new `now` value or nothing for async\n */\n function doTick(tickValue, isAsync, resolve, reject) {\n const msFloat =\n typeof tickValue === "number"\n ? tickValue\n : parseTime(tickValue);\n const ms = Math.floor(msFloat);\n const remainder = nanoRemainder(msFloat);\n let nanosTotal = nanos + remainder;\n let tickTo = clock.now + ms;\n\n if (msFloat < 0) {\n throw new TypeError("Negative ticks are not supported");\n }\n\n // adjust for positive overflow\n if (nanosTotal >= 1e6) {\n tickTo += 1;\n nanosTotal -= 1e6;\n }\n\n nanos = nanosTotal;\n let tickFrom = clock.now;\n let previous = clock.now;\n // ESLint fails to detect this correctly\n /* eslint-disable prefer-const */\n let timer,\n firstException,\n oldNow,\n nextPromiseTick,\n compensationCheck,\n postTimerCall;\n /* eslint-enable prefer-const */\n\n clock.duringTick = true;\n\n // perform microtasks\n oldNow = clock.now;\n runJobs(clock);\n if (oldNow !== clock.now) {\n // compensate for any setSystemTime() call during microtask callback\n tickFrom += clock.now - oldNow;\n tickTo += clock.now - oldNow;\n }\n\n //eslint-disable-next-line jsdoc/require-jsdoc\n function doTickInner() {\n // perform each timer in the requested range\n timer = firstTimerInRange(clock, tickFrom, tickTo);\n // eslint-disable-next-line no-unmodified-loop-condition\n while (timer && tickFrom <= tickTo) {\n if (clock.timers[timer.id]) {\n tickFrom = timer.callAt;\n clock.now = timer.callAt;\n oldNow = clock.now;\n try {\n runJobs(clock);\n callTimer(clock, timer);\n } catch (e) {\n firstException = firstException || e;\n }\n\n if (isAsync) {\n // finish up after native setImmediate callback to allow\n // all native es6 promises to process their callbacks after\n // each timer fires.\n originalSetTimeout(nextPromiseTick);\n return;\n }\n\n compensationCheck();\n }\n\n postTimerCall();\n }\n\n // perform process.nextTick()s again\n oldNow = clock.now;\n runJobs(clock);\n if (oldNow !== clock.now) {\n // compensate for any setSystemTime() call during process.nextTick() callback\n tickFrom += clock.now - oldNow;\n tickTo += clock.now - oldNow;\n }\n clock.duringTick = false;\n\n // corner case: during runJobs new timers were scheduled which could be in the range [clock.now, tickTo]\n timer = firstTimerInRange(clock, tickFrom, tickTo);\n if (timer) {\n try {\n clock.tick(tickTo - clock.now); // do it all again - for the remainder of the requested range\n } catch (e) {\n firstException = firstException || e;\n }\n } else {\n // no timers remaining in the requested range: move the clock all the way to the end\n clock.now = tickTo;\n\n // update nanos\n nanos = nanosTotal;\n }\n if (firstException) {\n throw firstException;\n }\n\n if (isAsync) {\n resolve(clock.now);\n } else {\n return clock.now;\n }\n }\n\n nextPromiseTick =\n isAsync &&\n function () {\n try {\n compensationCheck();\n postTimerCall();\n doTickInner();\n } catch (e) {\n reject(e);\n }\n };\n\n compensationCheck = function () {\n // compensate for any setSystemTime() call during timer callback\n if (oldNow !== clock.now) {\n tickFrom += clock.now - oldNow;\n tickTo += clock.now - oldNow;\n previous += clock.now - oldNow;\n }\n };\n\n postTimerCall = function () {\n timer = firstTimerInRange(clock, previous, tickTo);\n previous = tickFrom;\n };\n\n return doTickInner();\n }\n\n /**\n * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"\n * @returns {number} will return the new `now` value\n */\n clock.tick = function tick(tickValue) {\n return doTick(tickValue, false);\n };\n\n if (typeof _global.Promise !== "undefined") {\n /**\n * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"\n * @returns {Promise}\n */\n clock.tickAsync = function tickAsync(tickValue) {\n return new _global.Promise(function (resolve, reject) {\n originalSetTimeout(function () {\n try {\n doTick(tickValue, true, resolve, reject);\n } catch (e) {\n reject(e);\n }\n });\n });\n };\n }\n\n clock.next = function next() {\n runJobs(clock);\n const timer = firstTimer(clock);\n if (!timer) {\n return clock.now;\n }\n\n clock.duringTick = true;\n try {\n clock.now = timer.callAt;\n callTimer(clock, timer);\n runJobs(clock);\n return clock.now;\n } finally {\n clock.duringTick = false;\n }\n };\n\n if (typeof _global.Promise !== "undefined") {\n clock.nextAsync = function nextAsync() {\n return new _global.Promise(function (resolve, reject) {\n originalSetTimeout(function () {\n try {\n const timer = firstTimer(clock);\n if (!timer) {\n resolve(clock.now);\n return;\n }\n\n let err;\n clock.duringTick = true;\n clock.now = timer.callAt;\n try {\n callTimer(clock, timer);\n } catch (e) {\n err = e;\n }\n clock.duringTick = false;\n\n originalSetTimeout(function () {\n if (err) {\n reject(err);\n } else {\n resolve(clock.now);\n }\n });\n } catch (e) {\n reject(e);\n }\n });\n });\n };\n }\n\n clock.runAll = function runAll() {\n let numTimers, i;\n runJobs(clock);\n for (i = 0; i < clock.loopLimit; i++) {\n if (!clock.timers) {\n resetIsNearInfiniteLimit();\n return clock.now;\n }\n\n numTimers = Object.keys(clock.timers).length;\n if (numTimers === 0) {\n resetIsNearInfiniteLimit();\n return clock.now;\n }\n\n clock.next();\n checkIsNearInfiniteLimit(clock, i);\n }\n\n const excessJob = firstTimer(clock);\n throw getInfiniteLoopError(clock, excessJob);\n };\n\n clock.runToFrame = function runToFrame() {\n return clock.tick(getTimeToNextFrame());\n };\n\n if (typeof _global.Promise !== "undefined") {\n clock.runAllAsync = function runAllAsync() {\n return new _global.Promise(function (resolve, reject) {\n let i = 0;\n /**\n *\n */\n function doRun() {\n originalSetTimeout(function () {\n try {\n runJobs(clock);\n\n let numTimers;\n if (i < clock.loopLimit) {\n if (!clock.timers) {\n resetIsNearInfiniteLimit();\n resolve(clock.now);\n return;\n }\n\n numTimers = Object.keys(\n clock.timers,\n ).length;\n if (numTimers === 0) {\n resetIsNearInfiniteLimit();\n resolve(clock.now);\n return;\n }\n\n clock.next();\n\n i++;\n\n doRun();\n checkIsNearInfiniteLimit(clock, i);\n return;\n }\n\n const excessJob = firstTimer(clock);\n reject(getInfiniteLoopError(clock, excessJob));\n } catch (e) {\n reject(e);\n }\n });\n }\n doRun();\n });\n };\n }\n\n clock.runToLast = function runToLast() {\n const timer = lastTimer(clock);\n if (!timer) {\n runJobs(clock);\n return clock.now;\n }\n\n return clock.tick(timer.callAt - clock.now);\n };\n\n if (typeof _global.Promise !== "undefined") {\n clock.runToLastAsync = function runToLastAsync() {\n return new _global.Promise(function (resolve, reject) {\n originalSetTimeout(function () {\n try {\n const timer = lastTimer(clock);\n if (!timer) {\n runJobs(clock);\n resolve(clock.now);\n }\n\n resolve(clock.tickAsync(timer.callAt - clock.now));\n } catch (e) {\n reject(e);\n }\n });\n });\n };\n }\n\n clock.reset = function reset() {\n nanos = 0;\n clock.timers = {};\n clock.jobs = [];\n clock.now = start;\n };\n\n clock.setSystemTime = function setSystemTime(systemTime) {\n // determine time difference\n const newNow = getEpoch(systemTime);\n const difference = newNow - clock.now;\n let id, timer;\n\n adjustedSystemTime[0] = adjustedSystemTime[0] + difference;\n adjustedSystemTime[1] = adjustedSystemTime[1] + nanos;\n // update \'system clock\'\n clock.now = newNow;\n nanos = 0;\n\n // update timers and intervals to keep them stable\n for (id in clock.timers) {\n if (clock.timers.hasOwnProperty(id)) {\n timer = clock.timers[id];\n timer.createdAt += difference;\n timer.callAt += difference;\n }\n }\n };\n\n /**\n * @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"\n * @returns {number} will return the new `now` value\n */\n clock.jump = function jump(tickValue) {\n const msFloat =\n typeof tickValue === "number"\n ? tickValue\n : parseTime(tickValue);\n const ms = Math.floor(msFloat);\n\n for (const timer of Object.values(clock.timers)) {\n if (clock.now + ms > timer.callAt) {\n timer.callAt = clock.now + ms;\n }\n }\n clock.tick(ms);\n };\n\n if (performancePresent) {\n clock.performance = Object.create(null);\n clock.performance.now = fakePerformanceNow;\n }\n\n if (hrtimePresent) {\n clock.hrtime = hrtime;\n }\n\n return clock;\n }\n\n /* eslint-disable complexity */\n\n /**\n * @param {Config=} [config] Optional config\n * @returns {Clock}\n */\n function install(config) {\n if (\n arguments.length > 1 ||\n config instanceof Date ||\n Array.isArray(config) ||\n typeof config === "number"\n ) {\n throw new TypeError(\n `FakeTimers.install called with ${String(\n config,\n )} install requires an object parameter`,\n );\n }\n\n if (_global.Date.isFake === true) {\n // Timers are already faked; this is a problem.\n // Make the user reset timers before continuing.\n throw new TypeError(\n "Can\'t install fake timers twice on the same global object.",\n );\n }\n\n // eslint-disable-next-line no-param-reassign\n config = typeof config !== "undefined" ? config : {};\n config.shouldAdvanceTime = config.shouldAdvanceTime || false;\n config.advanceTimeDelta = config.advanceTimeDelta || 20;\n config.shouldClearNativeTimers =\n config.shouldClearNativeTimers || false;\n\n if (config.target) {\n throw new TypeError(\n "config.target is no longer supported. Use `withGlobal(target)` instead.",\n );\n }\n\n let i, l;\n const clock = createClock(config.now, config.loopLimit);\n clock.shouldClearNativeTimers = config.shouldClearNativeTimers;\n\n clock.uninstall = function () {\n return uninstall(clock, config);\n };\n\n clock.methods = config.toFake || [];\n\n if (clock.methods.length === 0) {\n // do not fake nextTick by default - GitHub#126\n clock.methods = Object.keys(timers).filter(function (key) {\n return key !== "nextTick" && key !== "queueMicrotask";\n });\n }\n\n if (config.shouldAdvanceTime === true) {\n const intervalTick = doIntervalTick.bind(\n null,\n clock,\n config.advanceTimeDelta,\n );\n const intervalId = _global.setInterval(\n intervalTick,\n config.advanceTimeDelta,\n );\n clock.attachedInterval = intervalId;\n }\n\n if (clock.methods.includes("performance")) {\n const proto = (() => {\n if (hasPerformanceConstructorPrototype) {\n return _global.performance.constructor.prototype;\n }\n if (hasPerformancePrototype) {\n return _global.Performance.prototype;\n }\n })();\n if (proto) {\n Object.getOwnPropertyNames(proto).forEach(function (name) {\n if (name !== "now") {\n clock.performance[name] =\n name.indexOf("getEntries") === 0\n ? NOOP_ARRAY\n : NOOP;\n }\n });\n } else if ((config.toFake || []).includes("performance")) {\n // user explicitly tried to fake performance when not present\n throw new ReferenceError(\n "non-existent performance object cannot be faked",\n );\n }\n }\n for (i = 0, l = clock.methods.length; i < l; i++) {\n const nameOfMethodToReplace = clock.methods[i];\n if (nameOfMethodToReplace === "hrtime") {\n if (\n _global.process &&\n typeof _global.process.hrtime === "function"\n ) {\n hijackMethod(_global.process, nameOfMethodToReplace, clock);\n }\n } else if (nameOfMethodToReplace === "nextTick") {\n if (\n _global.process &&\n typeof _global.process.nextTick === "function"\n ) {\n hijackMethod(_global.process, nameOfMethodToReplace, clock);\n }\n } else {\n hijackMethod(_global, nameOfMethodToReplace, clock);\n }\n }\n\n return clock;\n }\n\n /* eslint-enable complexity */\n\n return {\n timers: timers,\n createClock: createClock,\n install: install,\n withGlobal: withGlobal,\n };\n}\n\n/**\n * @typedef {object} FakeTimers\n * @property {Timers} timers\n * @property {createClock} createClock\n * @property {Function} install\n * @property {withGlobal} withGlobal\n */\n\n// /** @type {FakeTimers} */\nwindow.__wdio_sinon = withGlobal(globalThis);\n\n// // exports.timers = defaultImplementation.timers;\n// // exports.createClock = defaultImplementation.createClock;\n// // exports.install = defaultImplementation.install;\n// // exports.withGlobal = withGlobal;\n}\n';
|
|
1178
1178
|
var _browser, _resetFn, _isInstalled;
|
|
1179
1179
|
var ClockManager = class {
|
|
1180
|
-
constructor(
|
|
1180
|
+
constructor(browser2) {
|
|
1181
1181
|
__privateAdd(this, _browser);
|
|
1182
1182
|
__privateAdd(this, _resetFn, () => Promise.resolve());
|
|
1183
1183
|
__privateAdd(this, _isInstalled, false);
|
|
1184
|
-
__privateSet(this, _browser,
|
|
1184
|
+
__privateSet(this, _browser, browser2);
|
|
1185
1185
|
}
|
|
1186
1186
|
/**
|
|
1187
1187
|
* Install fake timers on the browser. If you call the `emulate` command, WebdriverIO will automatically install
|
|
@@ -2626,14 +2626,14 @@ var deviceDescriptorsSource = {
|
|
|
2626
2626
|
};
|
|
2627
2627
|
|
|
2628
2628
|
// src/commands/browser/emulate.ts
|
|
2629
|
-
function storeRestoreFunction(
|
|
2629
|
+
function storeRestoreFunction(browser2, scope, fn) {
|
|
2630
2630
|
var _a, _b;
|
|
2631
|
-
if (!restoreFunctions.has(
|
|
2632
|
-
restoreFunctions.set(
|
|
2631
|
+
if (!restoreFunctions.has(browser2)) {
|
|
2632
|
+
restoreFunctions.set(browser2, /* @__PURE__ */ new Map());
|
|
2633
2633
|
}
|
|
2634
|
-
const restoreFunctionsList = (_a = restoreFunctions.get(
|
|
2634
|
+
const restoreFunctionsList = (_a = restoreFunctions.get(browser2)) == null ? void 0 : _a.get(scope);
|
|
2635
2635
|
const updatedList = restoreFunctionsList ? [...restoreFunctionsList, fn] : [fn];
|
|
2636
|
-
(_b = restoreFunctions.get(
|
|
2636
|
+
(_b = restoreFunctions.get(browser2)) == null ? void 0 : _b.set(scope, updatedList);
|
|
2637
2637
|
}
|
|
2638
2638
|
async function emulate(scope, options) {
|
|
2639
2639
|
if (!this.isBidi) {
|
|
@@ -3003,11 +3003,11 @@ var SessionManager = class {
|
|
|
3003
3003
|
* @param browser WebdriverIO.Browser
|
|
3004
3004
|
* @param scope scope of the session manager, e.g. context, network etc.
|
|
3005
3005
|
*/
|
|
3006
|
-
constructor(
|
|
3006
|
+
constructor(browser2, scope) {
|
|
3007
3007
|
__privateAdd(this, _SessionManager_instances);
|
|
3008
3008
|
__privateAdd(this, _browser2);
|
|
3009
3009
|
__privateAdd(this, _scope);
|
|
3010
|
-
__privateSet(this, _browser2,
|
|
3010
|
+
__privateSet(this, _browser2, browser2);
|
|
3011
3011
|
__privateGet(this, _browser2).on("command", __privateMethod(this, _SessionManager_instances, onCommand_fn).bind(this));
|
|
3012
3012
|
__privateSet(this, _scope, scope);
|
|
3013
3013
|
}
|
|
@@ -3027,17 +3027,17 @@ var SessionManager = class {
|
|
|
3027
3027
|
!process.env.WDIO_UNIT_TESTS
|
|
3028
3028
|
);
|
|
3029
3029
|
}
|
|
3030
|
-
static getSessionManager(
|
|
3030
|
+
static getSessionManager(browser2, Manager) {
|
|
3031
3031
|
const scope = Manager.name;
|
|
3032
3032
|
let sessionManagerInstances = sessionManager.get(scope);
|
|
3033
3033
|
if (!sessionManagerInstances) {
|
|
3034
3034
|
sessionManagerInstances = /* @__PURE__ */ new Map();
|
|
3035
3035
|
sessionManager.set(scope, sessionManagerInstances);
|
|
3036
3036
|
}
|
|
3037
|
-
let sessionManagerInstance = sessionManagerInstances.get(
|
|
3037
|
+
let sessionManagerInstance = sessionManagerInstances.get(browser2);
|
|
3038
3038
|
if (!sessionManagerInstance) {
|
|
3039
|
-
sessionManagerInstance = new Manager(
|
|
3040
|
-
sessionManagerInstances.set(
|
|
3039
|
+
sessionManagerInstance = new Manager(browser2);
|
|
3040
|
+
sessionManagerInstances.set(browser2, sessionManagerInstance);
|
|
3041
3041
|
}
|
|
3042
3042
|
return sessionManagerInstance;
|
|
3043
3043
|
}
|
|
@@ -3082,20 +3082,20 @@ function getMobileContext({ capabilities, isAndroid, isNativeContext }) {
|
|
|
3082
3082
|
isAndroid && ((_a = capabilities == null ? void 0 : capabilities.browserName) == null ? void 0 : _a.toLowerCase()) === "chrome" ? "CHROMIUM" : void 0
|
|
3083
3083
|
);
|
|
3084
3084
|
}
|
|
3085
|
-
function calculateAndroidPinchAndZoomSpeed({ browser, duration, scale }) {
|
|
3085
|
+
function calculateAndroidPinchAndZoomSpeed({ browser: browser2, duration, scale }) {
|
|
3086
3086
|
var _a;
|
|
3087
|
-
const deviceScreenSize = (((_a =
|
|
3087
|
+
const deviceScreenSize = (((_a = browser2.capabilities) == null ? void 0 : _a.deviceScreenSize) || "1080x2400").split("x").reduce((a, b) => a * b);
|
|
3088
3088
|
const baseDistance = Math.sqrt(deviceScreenSize);
|
|
3089
3089
|
const gestureDistance = Math.max(baseDistance * Math.abs(scale), baseDistance * 0.1);
|
|
3090
3090
|
const durationSeconds = duration / 1e3;
|
|
3091
3091
|
return Math.floor(gestureDistance / durationSeconds);
|
|
3092
3092
|
}
|
|
3093
|
-
function validatePinchAndZoomOptions({ browser, gesture, options }) {
|
|
3093
|
+
function validatePinchAndZoomOptions({ browser: browser2, gesture, options }) {
|
|
3094
3094
|
if (typeof options !== "undefined" && (typeof options !== "object" || Array.isArray(options))) {
|
|
3095
3095
|
throw new TypeError("Options must be an object");
|
|
3096
3096
|
}
|
|
3097
3097
|
const DEFAULT_SCALE = 0.5;
|
|
3098
|
-
const DEFAULT_DURATION =
|
|
3098
|
+
const DEFAULT_DURATION = browser2.isIOS ? 1.5 : 1500;
|
|
3099
3099
|
const MIN_SCALE = 0;
|
|
3100
3100
|
const MAX_SCALE = 1;
|
|
3101
3101
|
const MIN_DURATION_MS = 500;
|
|
@@ -3104,31 +3104,31 @@ function validatePinchAndZoomOptions({ browser, gesture, options }) {
|
|
|
3104
3104
|
const scale = typeof scaleOption === "number" ? scaleOption >= MIN_SCALE && scaleOption <= MAX_SCALE ? scaleOption : (() => {
|
|
3105
3105
|
throw new Error("The 'scale' option must be a number between ".concat(MIN_SCALE, " and ").concat(MAX_SCALE));
|
|
3106
3106
|
})() : DEFAULT_SCALE;
|
|
3107
|
-
const duration = typeof durationOption === "number" ? durationOption >= MIN_DURATION_MS && durationOption <= MAX_DURATION_MS ?
|
|
3107
|
+
const duration = typeof durationOption === "number" ? durationOption >= MIN_DURATION_MS && durationOption <= MAX_DURATION_MS ? browser2.isIOS ? durationOption / 1e3 : durationOption : (() => {
|
|
3108
3108
|
throw new Error("The 'duration' option must be between ".concat(MIN_DURATION_MS, " and ").concat(MAX_DURATION_MS, " ms (").concat(MIN_DURATION_MS / 1e3, " and ").concat(MAX_DURATION_MS / 1e3, " seconds)"));
|
|
3109
3109
|
})() : DEFAULT_DURATION;
|
|
3110
3110
|
return {
|
|
3111
3111
|
duration,
|
|
3112
|
-
scale:
|
|
3112
|
+
scale: browser2.isIOS && gesture === "zoom" ? scale * 10 : scale
|
|
3113
3113
|
};
|
|
3114
3114
|
}
|
|
3115
3115
|
|
|
3116
3116
|
// src/session/context.ts
|
|
3117
3117
|
var log3 = logger3("webdriverio:context");
|
|
3118
3118
|
var COMMANDS_REQUIRING_RESET = ["deleteSession", "refresh", "switchToParentFrame"];
|
|
3119
|
-
function getContextManager(
|
|
3120
|
-
return SessionManager.getSessionManager(
|
|
3119
|
+
function getContextManager(browser2) {
|
|
3120
|
+
return SessionManager.getSessionManager(browser2, ContextManager);
|
|
3121
3121
|
}
|
|
3122
3122
|
var _browser3, _currentContext, _mobileContext, _isNativeContext, _ContextManager_instances, onCommandResultBidiAndClassic_fn, onCommand_fn2, onCommandResultMobile_fn;
|
|
3123
3123
|
var _ContextManager = class _ContextManager extends SessionManager {
|
|
3124
|
-
constructor(
|
|
3125
|
-
super(
|
|
3124
|
+
constructor(browser2) {
|
|
3125
|
+
super(browser2, _ContextManager.name);
|
|
3126
3126
|
__privateAdd(this, _ContextManager_instances);
|
|
3127
3127
|
__privateAdd(this, _browser3);
|
|
3128
3128
|
__privateAdd(this, _currentContext);
|
|
3129
3129
|
__privateAdd(this, _mobileContext);
|
|
3130
3130
|
__privateAdd(this, _isNativeContext);
|
|
3131
|
-
__privateSet(this, _browser3,
|
|
3131
|
+
__privateSet(this, _browser3, browser2);
|
|
3132
3132
|
const capabilities = __privateGet(this, _browser3).capabilities;
|
|
3133
3133
|
__privateSet(this, _isNativeContext, getNativeContext({ capabilities, isMobile: __privateGet(this, _browser3).isMobile }));
|
|
3134
3134
|
__privateSet(this, _mobileContext, getMobileContext({
|
|
@@ -3141,6 +3141,22 @@ var _ContextManager = class _ContextManager extends SessionManager {
|
|
|
3141
3141
|
return;
|
|
3142
3142
|
}
|
|
3143
3143
|
__privateGet(this, _browser3).on("command", __privateMethod(this, _ContextManager_instances, onCommand_fn2).bind(this));
|
|
3144
|
+
__privateGet(this, _browser3).sessionSubscribe({
|
|
3145
|
+
events: ["browsingContext.navigationStarted"]
|
|
3146
|
+
});
|
|
3147
|
+
__privateGet(this, _browser3).on("browsingContext.navigationStarted", async (nav) => {
|
|
3148
|
+
if (!__privateGet(this, _currentContext) || nav.context === __privateGet(this, _currentContext)) {
|
|
3149
|
+
return;
|
|
3150
|
+
}
|
|
3151
|
+
const { contexts } = await __privateGet(this, _browser3).browsingContextGetTree({});
|
|
3152
|
+
const hasContext = this.findContext(__privateGet(this, _currentContext), contexts, "byContextId");
|
|
3153
|
+
const newContext = contexts.find((context) => context.context === nav.context);
|
|
3154
|
+
if (!hasContext && newContext) {
|
|
3155
|
+
this.setCurrentContext(newContext.context);
|
|
3156
|
+
__privateGet(this, _browser3).switchToWindow(__privateGet(this, _currentContext));
|
|
3157
|
+
return;
|
|
3158
|
+
}
|
|
3159
|
+
});
|
|
3144
3160
|
if (__privateGet(this, _browser3).isMobile) {
|
|
3145
3161
|
__privateGet(this, _browser3).on("result", __privateMethod(this, _ContextManager_instances, onCommandResultMobile_fn).bind(this));
|
|
3146
3162
|
}
|
|
@@ -3316,8 +3332,8 @@ function byContextId(context, contextId) {
|
|
|
3316
3332
|
|
|
3317
3333
|
// src/session/polyfill.ts
|
|
3318
3334
|
import logger4 from "@wdio/logger";
|
|
3319
|
-
function getPolyfillManager(
|
|
3320
|
-
return SessionManager.getSessionManager(
|
|
3335
|
+
function getPolyfillManager(browser2) {
|
|
3336
|
+
return SessionManager.getSessionManager(browser2, PolyfillManager);
|
|
3321
3337
|
}
|
|
3322
3338
|
var log4 = logger4("webdriverio:PolyfillManager");
|
|
3323
3339
|
var polyfillFn = function webdriverioPolyfill() {
|
|
@@ -3330,13 +3346,13 @@ var polyfillFn = function webdriverioPolyfill() {
|
|
|
3330
3346
|
};
|
|
3331
3347
|
var _initialize, _browser4, _scriptsRegisteredInContexts, _PolyfillManager_instances, registerScripts_fn;
|
|
3332
3348
|
var _PolyfillManager = class _PolyfillManager extends SessionManager {
|
|
3333
|
-
constructor(
|
|
3334
|
-
super(
|
|
3349
|
+
constructor(browser2) {
|
|
3350
|
+
super(browser2, _PolyfillManager.name);
|
|
3335
3351
|
__privateAdd(this, _PolyfillManager_instances);
|
|
3336
3352
|
__privateAdd(this, _initialize);
|
|
3337
3353
|
__privateAdd(this, _browser4);
|
|
3338
3354
|
__privateAdd(this, _scriptsRegisteredInContexts, /* @__PURE__ */ new Set());
|
|
3339
|
-
__privateSet(this, _browser4,
|
|
3355
|
+
__privateSet(this, _browser4, browser2);
|
|
3340
3356
|
if (!this.isEnabled()) {
|
|
3341
3357
|
__privateSet(this, _initialize, Promise.resolve(true));
|
|
3342
3358
|
return;
|
|
@@ -3391,8 +3407,8 @@ async function execute(script, ...args) {
|
|
|
3391
3407
|
throw new Error("number or type of arguments don't agree with execute protocol command");
|
|
3392
3408
|
}
|
|
3393
3409
|
if (this.isBidi && !this.isMultiremote) {
|
|
3394
|
-
const
|
|
3395
|
-
const contextManager = getContextManager(
|
|
3410
|
+
const browser2 = getBrowserObject3(this);
|
|
3411
|
+
const contextManager = getContextManager(browser2);
|
|
3396
3412
|
const context = await contextManager.getCurrentContext();
|
|
3397
3413
|
const userScript = typeof script === "string" ? new Function(script) : script;
|
|
3398
3414
|
const functionDeclaration = createFunctionDeclarationFromString(userScript);
|
|
@@ -3404,7 +3420,7 @@ async function execute(script, ...args) {
|
|
|
3404
3420
|
context
|
|
3405
3421
|
}
|
|
3406
3422
|
};
|
|
3407
|
-
const result = await
|
|
3423
|
+
const result = await browser2.scriptCallFunction(params);
|
|
3408
3424
|
return parseScriptResult(params, result);
|
|
3409
3425
|
}
|
|
3410
3426
|
if (typeof script === "function") {
|
|
@@ -3420,8 +3436,8 @@ async function executeAsync(script, ...args) {
|
|
|
3420
3436
|
throw new Error("number or type of arguments don't agree with execute protocol command");
|
|
3421
3437
|
}
|
|
3422
3438
|
if (this.isBidi && !this.isMultiremote) {
|
|
3423
|
-
const
|
|
3424
|
-
const contextManager = getContextManager(
|
|
3439
|
+
const browser2 = getBrowserObject4(this);
|
|
3440
|
+
const contextManager = getContextManager(browser2);
|
|
3425
3441
|
const context = await contextManager.getCurrentContext();
|
|
3426
3442
|
const userScript = typeof script === "string" ? new Function(script) : script;
|
|
3427
3443
|
const functionDeclaration = new Function("\n const args = Array.from(arguments)\n return new Promise(async (resolve, reject) => {\n const cb = (result) => resolve(result)\n try {\n await (".concat(userScript.toString(), ").apply(this, [...args, cb])\n } catch (err) {\n return reject(err)\n }\n })\n ")).toString();
|
|
@@ -3433,7 +3449,7 @@ async function executeAsync(script, ...args) {
|
|
|
3433
3449
|
context
|
|
3434
3450
|
}
|
|
3435
3451
|
};
|
|
3436
|
-
const result = await
|
|
3452
|
+
const result = await browser2.scriptCallFunction(params);
|
|
3437
3453
|
return parseScriptResult(params, result);
|
|
3438
3454
|
}
|
|
3439
3455
|
if (typeof script === "function") {
|
|
@@ -3585,8 +3601,8 @@ async function getPuppeteer() {
|
|
|
3585
3601
|
// src/commands/browser/getWindowSize.ts
|
|
3586
3602
|
import { getBrowserObject as getBrowserObject5 } from "@wdio/utils";
|
|
3587
3603
|
async function getWindowSize() {
|
|
3588
|
-
const
|
|
3589
|
-
const { width, height } = await
|
|
3604
|
+
const browser2 = getBrowserObject5(this);
|
|
3605
|
+
const { width, height } = await browser2.getWindowRect();
|
|
3590
3606
|
return { width, height };
|
|
3591
3607
|
}
|
|
3592
3608
|
|
|
@@ -3801,7 +3817,7 @@ var log7 = logger7("WebDriverInterception");
|
|
|
3801
3817
|
var hasSubscribedToEvents = false;
|
|
3802
3818
|
var _pattern, _mockId, _filterOptions, _browser5, _eventHandler, _restored, _requestOverwrites, _respondOverwrites, _calls, _WebDriverInterception_instances, emit_fn, addEventHandler_fn, handleBeforeRequestSent_fn, handleResponseStarted_fn, handleNetworkProvideResponseError_fn, isRequestMatching_fn, matchesFilterOptions_fn, _setOverwrite, ensureNotRestored_fn;
|
|
3803
3819
|
var _WebDriverInterception = class _WebDriverInterception {
|
|
3804
|
-
constructor(pattern, mockId, filterOptions,
|
|
3820
|
+
constructor(pattern, mockId, filterOptions, browser2) {
|
|
3805
3821
|
__privateAdd(this, _WebDriverInterception_instances);
|
|
3806
3822
|
__privateAdd(this, _pattern);
|
|
3807
3823
|
__privateAdd(this, _mockId);
|
|
@@ -3821,14 +3837,14 @@ var _WebDriverInterception = class _WebDriverInterception {
|
|
|
3821
3837
|
__privateSet(this, _pattern, pattern);
|
|
3822
3838
|
__privateSet(this, _mockId, mockId);
|
|
3823
3839
|
__privateSet(this, _filterOptions, filterOptions);
|
|
3824
|
-
__privateSet(this, _browser5,
|
|
3825
|
-
|
|
3826
|
-
|
|
3840
|
+
__privateSet(this, _browser5, browser2);
|
|
3841
|
+
browser2.on("network.beforeRequestSent", __privateMethod(this, _WebDriverInterception_instances, handleBeforeRequestSent_fn).bind(this));
|
|
3842
|
+
browser2.on("network.responseStarted", __privateMethod(this, _WebDriverInterception_instances, handleResponseStarted_fn).bind(this));
|
|
3827
3843
|
}
|
|
3828
|
-
static async initiate(url2, filterOptions,
|
|
3844
|
+
static async initiate(url2, filterOptions, browser2) {
|
|
3829
3845
|
const pattern = parseUrlPattern(url2);
|
|
3830
3846
|
if (!hasSubscribedToEvents) {
|
|
3831
|
-
await
|
|
3847
|
+
await browser2.sessionSubscribe({
|
|
3832
3848
|
events: [
|
|
3833
3849
|
"network.beforeRequestSent",
|
|
3834
3850
|
"network.responseStarted"
|
|
@@ -3837,7 +3853,7 @@ var _WebDriverInterception = class _WebDriverInterception {
|
|
|
3837
3853
|
log7.info("subscribed to network events");
|
|
3838
3854
|
hasSubscribedToEvents = true;
|
|
3839
3855
|
}
|
|
3840
|
-
const interception = await
|
|
3856
|
+
const interception = await browser2.networkAddIntercept({
|
|
3841
3857
|
phases: ["beforeRequestSent", "responseStarted"],
|
|
3842
3858
|
urlPatterns: [{
|
|
3843
3859
|
type: "pattern",
|
|
@@ -3848,7 +3864,7 @@ var _WebDriverInterception = class _WebDriverInterception {
|
|
|
3848
3864
|
search: getPatternParam(pattern, "search")
|
|
3849
3865
|
}]
|
|
3850
3866
|
});
|
|
3851
|
-
return new _WebDriverInterception(pattern, interception.intercept, filterOptions,
|
|
3867
|
+
return new _WebDriverInterception(pattern, interception.intercept, filterOptions, browser2);
|
|
3852
3868
|
}
|
|
3853
3869
|
/**
|
|
3854
3870
|
* allows access to all requests made with given pattern
|
|
@@ -4146,8 +4162,8 @@ async function mock(url2, filterOptions) {
|
|
|
4146
4162
|
if (!this.isBidi) {
|
|
4147
4163
|
throw new Error("Mocking is only supported when running tests using WebDriver Bidi");
|
|
4148
4164
|
}
|
|
4149
|
-
const
|
|
4150
|
-
const contextManager = getContextManager(
|
|
4165
|
+
const browser2 = getBrowserObject6(this);
|
|
4166
|
+
const contextManager = getContextManager(browser2);
|
|
4151
4167
|
const context = await contextManager.getCurrentContext();
|
|
4152
4168
|
if (!SESSION_MOCKS[context]) {
|
|
4153
4169
|
SESSION_MOCKS[context] = /* @__PURE__ */ new Set();
|
|
@@ -4345,20 +4361,20 @@ function customElementWrapper() {
|
|
|
4345
4361
|
|
|
4346
4362
|
// src/session/shadowRoot.ts
|
|
4347
4363
|
var log11 = logger11("webdriverio:ShadowRootManager");
|
|
4348
|
-
function getShadowRootManager(
|
|
4349
|
-
return SessionManager.getSessionManager(
|
|
4364
|
+
function getShadowRootManager(browser2) {
|
|
4365
|
+
return SessionManager.getSessionManager(browser2, ShadowRootManager);
|
|
4350
4366
|
}
|
|
4351
4367
|
var _browser6, _initialize2, _shadowRoots, _documentElement, _frameDepth, _ShadowRootManager_instances, handleBidiCommand_fn, commandResultHandler_fn;
|
|
4352
4368
|
var _ShadowRootManager = class _ShadowRootManager extends SessionManager {
|
|
4353
|
-
constructor(
|
|
4354
|
-
super(
|
|
4369
|
+
constructor(browser2) {
|
|
4370
|
+
super(browser2, _ShadowRootManager.name);
|
|
4355
4371
|
__privateAdd(this, _ShadowRootManager_instances);
|
|
4356
4372
|
__privateAdd(this, _browser6);
|
|
4357
4373
|
__privateAdd(this, _initialize2);
|
|
4358
4374
|
__privateAdd(this, _shadowRoots, /* @__PURE__ */ new Map());
|
|
4359
4375
|
__privateAdd(this, _documentElement);
|
|
4360
4376
|
__privateAdd(this, _frameDepth, 0);
|
|
4361
|
-
__privateSet(this, _browser6,
|
|
4377
|
+
__privateSet(this, _browser6, browser2);
|
|
4362
4378
|
if (!this.isEnabled()) {
|
|
4363
4379
|
__privateSet(this, _initialize2, Promise.resolve(true));
|
|
4364
4380
|
return;
|
|
@@ -4623,21 +4639,21 @@ var ShadowRootTree = class _ShadowRootTree {
|
|
|
4623
4639
|
};
|
|
4624
4640
|
|
|
4625
4641
|
// src/session/networkManager.ts
|
|
4626
|
-
function getNetworkManager(
|
|
4627
|
-
return SessionManager.getSessionManager(
|
|
4642
|
+
function getNetworkManager(browser2) {
|
|
4643
|
+
return SessionManager.getSessionManager(browser2, NetworkManager);
|
|
4628
4644
|
}
|
|
4629
4645
|
var UNKNOWN_NAVIGATION_ID = "UNKNOWN_NAVIGATION_ID";
|
|
4630
4646
|
var SUPPORTED_NAVIGATION_PROTOCOLS = ["http", "https", "data", "file"];
|
|
4631
4647
|
var _browser7, _initialize3, _requests, _lastNetworkId, _NetworkManager_instances, beforeRequestSent_fn, navigationStarted_fn, fetchError_fn, findRootRequest_fn, responseCompleted_fn;
|
|
4632
4648
|
var _NetworkManager = class _NetworkManager extends SessionManager {
|
|
4633
|
-
constructor(
|
|
4634
|
-
super(
|
|
4649
|
+
constructor(browser2) {
|
|
4650
|
+
super(browser2, _NetworkManager.name);
|
|
4635
4651
|
__privateAdd(this, _NetworkManager_instances);
|
|
4636
4652
|
__privateAdd(this, _browser7);
|
|
4637
4653
|
__privateAdd(this, _initialize3);
|
|
4638
4654
|
__privateAdd(this, _requests, /* @__PURE__ */ new Map());
|
|
4639
4655
|
__privateAdd(this, _lastNetworkId);
|
|
4640
|
-
__privateSet(this, _browser7,
|
|
4656
|
+
__privateSet(this, _browser7, browser2);
|
|
4641
4657
|
if (!this.isEnabled()) {
|
|
4642
4658
|
__privateSet(this, _initialize3, Promise.resolve(true));
|
|
4643
4659
|
return;
|
|
@@ -4821,18 +4837,18 @@ function headerListToObject(headers) {
|
|
|
4821
4837
|
}
|
|
4822
4838
|
|
|
4823
4839
|
// src/session/dialog.ts
|
|
4824
|
-
function getDialogManager(
|
|
4825
|
-
return SessionManager.getSessionManager(
|
|
4840
|
+
function getDialogManager(browser2) {
|
|
4841
|
+
return SessionManager.getSessionManager(browser2, DialogManager);
|
|
4826
4842
|
}
|
|
4827
4843
|
var _browser8, _initialize4, _autoHandleDialog, _DialogManager_instances, handleUserPrompt_fn, switchListenerFlag_fn;
|
|
4828
4844
|
var _DialogManager = class _DialogManager extends SessionManager {
|
|
4829
|
-
constructor(
|
|
4830
|
-
super(
|
|
4845
|
+
constructor(browser2) {
|
|
4846
|
+
super(browser2, _DialogManager.name);
|
|
4831
4847
|
__privateAdd(this, _DialogManager_instances);
|
|
4832
4848
|
__privateAdd(this, _browser8);
|
|
4833
4849
|
__privateAdd(this, _initialize4);
|
|
4834
4850
|
__privateAdd(this, _autoHandleDialog, true);
|
|
4835
|
-
__privateSet(this, _browser8,
|
|
4851
|
+
__privateSet(this, _browser8, browser2);
|
|
4836
4852
|
if (!this.isEnabled()) {
|
|
4837
4853
|
__privateSet(this, _initialize4, Promise.resolve(true));
|
|
4838
4854
|
return;
|
|
@@ -4879,7 +4895,7 @@ switchListenerFlag_fn = function(value) {
|
|
|
4879
4895
|
var DialogManager = _DialogManager;
|
|
4880
4896
|
var _browser9, _context, _message, _defaultValue, _type2;
|
|
4881
4897
|
var Dialog = class {
|
|
4882
|
-
constructor(event,
|
|
4898
|
+
constructor(event, browser2) {
|
|
4883
4899
|
__privateAdd(this, _browser9);
|
|
4884
4900
|
__privateAdd(this, _context);
|
|
4885
4901
|
__privateAdd(this, _message);
|
|
@@ -4889,7 +4905,7 @@ var Dialog = class {
|
|
|
4889
4905
|
__privateSet(this, _defaultValue, event.defaultValue);
|
|
4890
4906
|
__privateSet(this, _type2, event.type);
|
|
4891
4907
|
__privateSet(this, _context, event.context);
|
|
4892
|
-
__privateSet(this, _browser9,
|
|
4908
|
+
__privateSet(this, _browser9, browser2);
|
|
4893
4909
|
}
|
|
4894
4910
|
message() {
|
|
4895
4911
|
return __privateGet(this, _message);
|
|
@@ -5097,8 +5113,8 @@ async function setWindowSize(width, height) {
|
|
|
5097
5113
|
if (width < minWindowSize2 || width > maxWindowSize2 || height < minWindowSize2 || height > maxWindowSize2) {
|
|
5098
5114
|
throw new Error("setWindowSize expects width and height to be a number in the 0 to 2^31 \u2212 1 range");
|
|
5099
5115
|
}
|
|
5100
|
-
const
|
|
5101
|
-
await
|
|
5116
|
+
const browser2 = getBrowserObject7(this);
|
|
5117
|
+
await browser2.setWindowRect(null, null, width, height);
|
|
5102
5118
|
}
|
|
5103
5119
|
|
|
5104
5120
|
// src/commands/browser/switchWindow.ts
|
|
@@ -5293,6 +5309,7 @@ async function switchFrame(context) {
|
|
|
5293
5309
|
if (!result || result.type !== "success" || result.result.type !== "boolean" || !result.result.value) {
|
|
5294
5310
|
continue;
|
|
5295
5311
|
}
|
|
5312
|
+
await browser.switchFrame(null);
|
|
5296
5313
|
await this.switchFrame(contextId);
|
|
5297
5314
|
return contextId;
|
|
5298
5315
|
}
|
|
@@ -5302,23 +5319,23 @@ async function switchFrame(context) {
|
|
|
5302
5319
|
"Invalid type for context parameter: ".concat(typeof context, ", expected one of number, string or null. ") + "Check out our docs: https://webdriver.io/docs/api/browser/switchFrame.html"
|
|
5303
5320
|
);
|
|
5304
5321
|
}
|
|
5305
|
-
function switchToFrameHelper(
|
|
5306
|
-
const sessionContext = getContextManager(
|
|
5322
|
+
function switchToFrameHelper(browser2, context) {
|
|
5323
|
+
const sessionContext = getContextManager(browser2);
|
|
5307
5324
|
sessionContext.setCurrentContext(context);
|
|
5308
5325
|
}
|
|
5309
|
-
async function switchToFrameUsingElement(
|
|
5310
|
-
const frame = await
|
|
5326
|
+
async function switchToFrameUsingElement(browser2, element) {
|
|
5327
|
+
const frame = await browser2.execute(
|
|
5311
5328
|
(iframe) => iframe.contentWindow,
|
|
5312
5329
|
element
|
|
5313
5330
|
);
|
|
5314
|
-
switchToFrameHelper(
|
|
5331
|
+
switchToFrameHelper(browser2, frame.context);
|
|
5315
5332
|
const elementId = element[ELEMENT_KEY8];
|
|
5316
|
-
await switchToFrame(
|
|
5333
|
+
await switchToFrame(browser2, { [ELEMENT_KEY8]: elementId });
|
|
5317
5334
|
return frame.context;
|
|
5318
5335
|
}
|
|
5319
|
-
function switchToFrame(
|
|
5336
|
+
function switchToFrame(browser2, frame) {
|
|
5320
5337
|
process.env.DISABLE_WEBDRIVERIO_DEPRECATION_WARNINGS = "true";
|
|
5321
|
-
return
|
|
5338
|
+
return browser2.switchToFrame(frame).finally(async () => {
|
|
5322
5339
|
delete process.env.DISABLE_WEBDRIVERIO_DEPRECATION_WARNINGS;
|
|
5323
5340
|
});
|
|
5324
5341
|
}
|
|
@@ -5329,8 +5346,8 @@ import { getBrowserObject as getBrowserObject8 } from "@wdio/utils";
|
|
|
5329
5346
|
var log15 = logger15("webdriverio:throttle");
|
|
5330
5347
|
async function throttle(params) {
|
|
5331
5348
|
log15.warn('Command "throttle" is deprecated and will be removed with the next major version release! Use `throttleNetwork` instead.');
|
|
5332
|
-
const
|
|
5333
|
-
await
|
|
5349
|
+
const browser2 = getBrowserObject8(this);
|
|
5350
|
+
await browser2.throttleNetwork(params);
|
|
5334
5351
|
}
|
|
5335
5352
|
|
|
5336
5353
|
// src/commands/browser/throttleCPU.ts
|
|
@@ -5429,8 +5446,8 @@ async function throttleNetwork(params) {
|
|
|
5429
5446
|
throw new Error('Invalid parameter for "throttleNetwork". Expected it to be typeof object or one of the following values: '.concat(NETWORK_PRESET_TYPES.join(", "), ' but found "').concat(params, '"'));
|
|
5430
5447
|
}
|
|
5431
5448
|
if (this.isSauce) {
|
|
5432
|
-
const
|
|
5433
|
-
await
|
|
5449
|
+
const browser2 = getBrowserObject9(this);
|
|
5450
|
+
await browser2.sauceThrottleNetwork(params);
|
|
5434
5451
|
return null;
|
|
5435
5452
|
}
|
|
5436
5453
|
const failedConnectionMessage = "No Puppeteer connection could be established which is required to use this command";
|
|
@@ -5592,8 +5609,8 @@ var SWIPE_DEFAULTS = {
|
|
|
5592
5609
|
PERCENT: 0.95
|
|
5593
5610
|
};
|
|
5594
5611
|
async function swipe(options) {
|
|
5595
|
-
const
|
|
5596
|
-
if (!
|
|
5612
|
+
const browser2 = this;
|
|
5613
|
+
if (!browser2.isNativeContext) {
|
|
5597
5614
|
throw new Error("The swipe command is only available for mobile platforms in the NATIVE context.");
|
|
5598
5615
|
}
|
|
5599
5616
|
let { scrollableElement, from, to } = options || {};
|
|
@@ -5601,18 +5618,18 @@ async function swipe(options) {
|
|
|
5601
5618
|
log16.warn("`scrollableElement` is provided, so `from` and `to` will be ignored.");
|
|
5602
5619
|
}
|
|
5603
5620
|
if (!from || !to) {
|
|
5604
|
-
scrollableElement = scrollableElement || await getScrollableElement(
|
|
5621
|
+
scrollableElement = scrollableElement || await getScrollableElement(browser2);
|
|
5605
5622
|
({ from, to } = await calculateFromTo({
|
|
5606
|
-
browser,
|
|
5623
|
+
browser: browser2,
|
|
5607
5624
|
direction: (options == null ? void 0 : options.direction) || SWIPE_DEFAULTS.DIRECTION,
|
|
5608
5625
|
percentage: options == null ? void 0 : options.percent,
|
|
5609
5626
|
scrollableElement
|
|
5610
5627
|
}));
|
|
5611
5628
|
}
|
|
5612
|
-
return w3cSwipe({ browser, duration: (options == null ? void 0 : options.duration) || SWIPE_DEFAULTS.DURATION, from, to });
|
|
5629
|
+
return w3cSwipe({ browser: browser2, duration: (options == null ? void 0 : options.duration) || SWIPE_DEFAULTS.DURATION, from, to });
|
|
5613
5630
|
}
|
|
5614
5631
|
async function calculateFromTo({
|
|
5615
|
-
browser,
|
|
5632
|
+
browser: browser2,
|
|
5616
5633
|
direction,
|
|
5617
5634
|
percentage,
|
|
5618
5635
|
scrollableElement
|
|
@@ -5627,7 +5644,7 @@ async function calculateFromTo({
|
|
|
5627
5644
|
swipePercentage = percentage;
|
|
5628
5645
|
}
|
|
5629
5646
|
}
|
|
5630
|
-
const { x, y, width, height } = await
|
|
5647
|
+
const { x, y, width, height } = await browser2.getElementRect(await (scrollableElement == null ? void 0 : scrollableElement.elementId));
|
|
5631
5648
|
const scrollRectangles = {
|
|
5632
5649
|
top: { x: Math.round(x + width / 2), y: Math.round(y + height - height * swipePercentage) },
|
|
5633
5650
|
right: { x: Math.round(x + width * swipePercentage), y: Math.round(y + height / 2) },
|
|
@@ -5658,31 +5675,31 @@ async function calculateFromTo({
|
|
|
5658
5675
|
}
|
|
5659
5676
|
return { from, to };
|
|
5660
5677
|
}
|
|
5661
|
-
async function getScrollableElement(
|
|
5678
|
+
async function getScrollableElement(browser2) {
|
|
5662
5679
|
const defaultAndroidSelector = "//android.widget.ScrollView";
|
|
5663
5680
|
const defaultIosSelector = '-ios predicate string:type == "XCUIElementTypeApplication"';
|
|
5664
|
-
const selector =
|
|
5681
|
+
const selector = browser2.isIOS ? (
|
|
5665
5682
|
// For iOS, we need to find the application element, if we can't find it, we should throw an error
|
|
5666
5683
|
defaultIosSelector
|
|
5667
5684
|
) : (
|
|
5668
5685
|
// There is always a scrollview for Android or, if this fails we should throw an error
|
|
5669
5686
|
defaultAndroidSelector
|
|
5670
5687
|
);
|
|
5671
|
-
const scrollableElements = await
|
|
5688
|
+
const scrollableElements = await browser2.$$(
|
|
5672
5689
|
selector
|
|
5673
5690
|
);
|
|
5674
5691
|
if (scrollableElements.length > 0) {
|
|
5675
5692
|
return scrollableElements[0];
|
|
5676
5693
|
}
|
|
5677
5694
|
throw new Error(
|
|
5678
|
-
"Default scrollable element '".concat(
|
|
5695
|
+
"Default scrollable element '".concat(browser2.isIOS ? defaultIosSelector : defaultAndroidSelector, "' was not found. Our advice is to provide a scrollable element like this:\n\nawait browser.swipe({ scrollableElement: $('#scrollable') });\n\n ")
|
|
5679
5696
|
);
|
|
5680
5697
|
}
|
|
5681
|
-
async function w3cSwipe({ browser, duration, from, to }) {
|
|
5682
|
-
await
|
|
5683
|
-
parameters: { pointerType:
|
|
5698
|
+
async function w3cSwipe({ browser: browser2, duration, from, to }) {
|
|
5699
|
+
await browser2.action("pointer", {
|
|
5700
|
+
parameters: { pointerType: browser2.isMobile ? "touch" : "mouse" }
|
|
5684
5701
|
}).move(from.x, from.y).down().pause(10).move({ duration, x: to.x, y: to.y }).up().perform();
|
|
5685
|
-
return
|
|
5702
|
+
return browser2.pause(500);
|
|
5686
5703
|
}
|
|
5687
5704
|
|
|
5688
5705
|
// src/commands/mobile/tap.ts
|
|
@@ -5692,18 +5709,18 @@ var log17 = logger17("webdriver");
|
|
|
5692
5709
|
async function tap(options) {
|
|
5693
5710
|
const isElement2 = this.selector !== void 0;
|
|
5694
5711
|
const element = isElement2 ? this : null;
|
|
5695
|
-
const
|
|
5696
|
-
if (!
|
|
5712
|
+
const browser2 = isElement2 ? getBrowserObject10(this) : this;
|
|
5713
|
+
if (!browser2.isMobile) {
|
|
5697
5714
|
throw new Error("The tap command is only available for mobile platforms.");
|
|
5698
5715
|
}
|
|
5699
5716
|
validateTapOptions(options);
|
|
5700
5717
|
if (element) {
|
|
5701
|
-
return await elementTap(
|
|
5718
|
+
return await elementTap(browser2, element, options);
|
|
5702
5719
|
}
|
|
5703
5720
|
if (!options || options.x === void 0 || options.y === void 0) {
|
|
5704
5721
|
throw new Error("The tap command requires x and y coordinates to be set for screen taps.");
|
|
5705
5722
|
}
|
|
5706
|
-
return await screenTap(
|
|
5723
|
+
return await screenTap(browser2, options);
|
|
5707
5724
|
}
|
|
5708
5725
|
function validateTapOptions(options) {
|
|
5709
5726
|
if (options) {
|
|
@@ -5729,9 +5746,9 @@ function validateTapOptions(options) {
|
|
|
5729
5746
|
}
|
|
5730
5747
|
}
|
|
5731
5748
|
}
|
|
5732
|
-
async function elementTap(
|
|
5733
|
-
if (
|
|
5734
|
-
return await nativeTap(element,
|
|
5749
|
+
async function elementTap(browser2, element, options) {
|
|
5750
|
+
if (browser2.isNativeContext) {
|
|
5751
|
+
return await nativeTap(element, browser2, options);
|
|
5735
5752
|
}
|
|
5736
5753
|
if (options) {
|
|
5737
5754
|
log17.warn("The options object is not supported in Web environments and will be ignored.");
|
|
@@ -5741,18 +5758,18 @@ async function elementTap(browser, element, options) {
|
|
|
5741
5758
|
async function webTap(element) {
|
|
5742
5759
|
return element.click();
|
|
5743
5760
|
}
|
|
5744
|
-
async function executeNativeTap(
|
|
5745
|
-
return await
|
|
5746
|
-
"mobile: ".concat(
|
|
5747
|
-
{ ...
|
|
5761
|
+
async function executeNativeTap(browser2, options) {
|
|
5762
|
+
return await browser2.execute(
|
|
5763
|
+
"mobile: ".concat(browser2.isIOS ? "tap" : "clickGesture"),
|
|
5764
|
+
{ ...browser2.isIOS ? { x: 0, y: 0 } : {}, ...options }
|
|
5748
5765
|
);
|
|
5749
5766
|
}
|
|
5750
|
-
async function nativeTap(element,
|
|
5767
|
+
async function nativeTap(element, browser2, options = {}) {
|
|
5751
5768
|
try {
|
|
5752
5769
|
if (!element.elementId) {
|
|
5753
5770
|
throw new Error("no such element");
|
|
5754
5771
|
}
|
|
5755
|
-
return await executeNativeTap(
|
|
5772
|
+
return await executeNativeTap(browser2, { elementId: element.elementId });
|
|
5756
5773
|
} catch (error) {
|
|
5757
5774
|
let err = error;
|
|
5758
5775
|
if (typeof error === "string") {
|
|
@@ -5770,7 +5787,7 @@ async function nativeTap(element, browser, options = {}) {
|
|
|
5770
5787
|
);
|
|
5771
5788
|
try {
|
|
5772
5789
|
await element.scrollIntoView(scrollIntoViewOptions);
|
|
5773
|
-
return await executeNativeTap(
|
|
5790
|
+
return await executeNativeTap(browser2, { elementId: element.elementId });
|
|
5774
5791
|
} catch (scrollError) {
|
|
5775
5792
|
let err2 = scrollError;
|
|
5776
5793
|
if (typeof scrollError === "string") {
|
|
@@ -5787,12 +5804,12 @@ async function nativeTap(element, browser, options = {}) {
|
|
|
5787
5804
|
}
|
|
5788
5805
|
}
|
|
5789
5806
|
}
|
|
5790
|
-
async function screenTap(
|
|
5807
|
+
async function screenTap(browser2, options) {
|
|
5791
5808
|
const { x, y } = options;
|
|
5792
|
-
if (
|
|
5793
|
-
return await executeNativeTap(
|
|
5809
|
+
if (browser2.isNativeContext) {
|
|
5810
|
+
return await executeNativeTap(browser2, options);
|
|
5794
5811
|
}
|
|
5795
|
-
return await
|
|
5812
|
+
return await browser2.action(
|
|
5796
5813
|
"pointer",
|
|
5797
5814
|
{
|
|
5798
5815
|
parameters: { pointerType: "touch" }
|
|
@@ -5804,19 +5821,19 @@ async function screenTap(browser, options) {
|
|
|
5804
5821
|
import logger18 from "@wdio/logger";
|
|
5805
5822
|
var log18 = logger18("webdriver");
|
|
5806
5823
|
async function getContext(options) {
|
|
5807
|
-
const
|
|
5808
|
-
if (!
|
|
5824
|
+
const browser2 = this;
|
|
5825
|
+
if (!browser2.isMobile) {
|
|
5809
5826
|
throw new Error("The `getContext` command is only available for mobile platforms.");
|
|
5810
5827
|
}
|
|
5811
|
-
const currentAppiumContext = await
|
|
5828
|
+
const currentAppiumContext = await browser2.getAppiumContext();
|
|
5812
5829
|
if (!options || !(options == null ? void 0 : options.returnDetailedContext) || currentAppiumContext === "NATIVE_APP") {
|
|
5813
5830
|
return currentAppiumContext;
|
|
5814
5831
|
}
|
|
5815
5832
|
delete options.returnDetailedContext;
|
|
5816
|
-
return getDetailedContext(
|
|
5833
|
+
return getDetailedContext(browser2, currentAppiumContext, options);
|
|
5817
5834
|
}
|
|
5818
|
-
async function getDetailedContext(
|
|
5819
|
-
const detailedContexts = await
|
|
5835
|
+
async function getDetailedContext(browser2, currentAppiumContext, options) {
|
|
5836
|
+
const detailedContexts = await browser2.getContexts({
|
|
5820
5837
|
...{ options },
|
|
5821
5838
|
// Defaults
|
|
5822
5839
|
returnDetailedContexts: true,
|
|
@@ -5843,13 +5860,13 @@ async function getDetailedContext(browser, currentAppiumContext, options) {
|
|
|
5843
5860
|
import logger19 from "@wdio/logger";
|
|
5844
5861
|
var log19 = logger19("webdriver");
|
|
5845
5862
|
async function getContexts(options) {
|
|
5846
|
-
const
|
|
5847
|
-
if (!
|
|
5863
|
+
const browser2 = this;
|
|
5864
|
+
if (!browser2.isMobile) {
|
|
5848
5865
|
throw new Error("The `getContexts` command is only available for mobile platforms.");
|
|
5849
5866
|
}
|
|
5850
5867
|
if (!options || !options.returnDetailedContexts) {
|
|
5851
5868
|
log19.info("The standard Appium `contexts` method is used. If you want to get more detailed data, you can set `returnDetailedContexts` to `true`.");
|
|
5852
|
-
return
|
|
5869
|
+
return browser2.getAppiumContexts();
|
|
5853
5870
|
}
|
|
5854
5871
|
const defaultOptions = {
|
|
5855
5872
|
androidWebviewConnectionRetryTime: 500,
|
|
@@ -5858,7 +5875,7 @@ async function getContexts(options) {
|
|
|
5858
5875
|
isAndroidWebviewVisible: true,
|
|
5859
5876
|
returnAndroidDescriptionData: false
|
|
5860
5877
|
};
|
|
5861
|
-
return getCurrentContexts({ browser, ...{ ...defaultOptions, ...options } });
|
|
5878
|
+
return getCurrentContexts({ browser: browser2, ...{ ...defaultOptions, ...options } });
|
|
5862
5879
|
}
|
|
5863
5880
|
var CHROME_PACKAGE_NAME = "com.android.chrome";
|
|
5864
5881
|
async function parsedAndroidContexts({
|
|
@@ -5928,7 +5945,7 @@ async function parsedAndroidContexts({
|
|
|
5928
5945
|
return result;
|
|
5929
5946
|
}
|
|
5930
5947
|
async function getCurrentContexts({
|
|
5931
|
-
browser,
|
|
5948
|
+
browser: browser2,
|
|
5932
5949
|
androidWebviewConnectionRetryTime,
|
|
5933
5950
|
androidWebviewConnectTimeout,
|
|
5934
5951
|
filterByCurrentAndroidApp,
|
|
@@ -5936,11 +5953,11 @@ async function getCurrentContexts({
|
|
|
5936
5953
|
returnAndroidDescriptionData
|
|
5937
5954
|
}) {
|
|
5938
5955
|
var _a;
|
|
5939
|
-
const contexts = await
|
|
5940
|
-
if (
|
|
5956
|
+
const contexts = await browser2.execute("mobile: getContexts");
|
|
5957
|
+
if (browser2.isIOS) {
|
|
5941
5958
|
return contexts;
|
|
5942
5959
|
}
|
|
5943
|
-
const packageName = await
|
|
5960
|
+
const packageName = await browser2.getCurrentPackage();
|
|
5944
5961
|
const startTime = Date.now();
|
|
5945
5962
|
const retryInterval = androidWebviewConnectionRetryTime;
|
|
5946
5963
|
let isPackageNameMissing = false;
|
|
@@ -5979,8 +5996,8 @@ async function getCurrentContexts({
|
|
|
5979
5996
|
import logger20 from "@wdio/logger";
|
|
5980
5997
|
var log20 = logger20("webdriver");
|
|
5981
5998
|
async function switchContext(options) {
|
|
5982
|
-
const
|
|
5983
|
-
if (!
|
|
5999
|
+
const browser2 = this;
|
|
6000
|
+
if (!browser2.isMobile) {
|
|
5984
6001
|
throw new Error("The `switchContext` command is only available for mobile platforms.");
|
|
5985
6002
|
}
|
|
5986
6003
|
if (!options) {
|
|
@@ -5988,14 +6005,14 @@ async function switchContext(options) {
|
|
|
5988
6005
|
}
|
|
5989
6006
|
if (typeof options === "string") {
|
|
5990
6007
|
log20.info("The standard Appium `context`-method is used. If you want to switch to a webview with a specific title or url, please provide an object with the `title` or `url` property. See https://webdriver.io/docs/api/mobile/switchContext for more information.");
|
|
5991
|
-
return
|
|
6008
|
+
return browser2.switchAppiumContext(options);
|
|
5992
6009
|
}
|
|
5993
6010
|
if (!options.title && !options.url) {
|
|
5994
6011
|
throw new Error("You need to provide at least a `title` or `url` property to use full potential of the `switchContext` command. See https://webdriver.io/docs/api/mobile/switchContext for more information.");
|
|
5995
6012
|
}
|
|
5996
|
-
return switchToContext({ browser, options });
|
|
6013
|
+
return switchToContext({ browser: browser2, options });
|
|
5997
6014
|
}
|
|
5998
|
-
async function switchToContext({ browser, options }) {
|
|
6015
|
+
async function switchToContext({ browser: browser2, options }) {
|
|
5999
6016
|
var _a;
|
|
6000
6017
|
const getContextsOptions = {
|
|
6001
6018
|
returnDetailedContexts: true,
|
|
@@ -6005,19 +6022,19 @@ async function switchToContext({ browser, options }) {
|
|
|
6005
6022
|
...(options == null ? void 0 : options.androidWebviewConnectionRetryTime) && { androidWebviewConnectionRetryTime: options.androidWebviewConnectionRetryTime },
|
|
6006
6023
|
...(options == null ? void 0 : options.androidWebviewConnectTimeout) && { androidWebviewConnectTimeout: options.androidWebviewConnectTimeout }
|
|
6007
6024
|
};
|
|
6008
|
-
const contexts = await
|
|
6009
|
-
const identifier =
|
|
6010
|
-
const { matchingContext, reasons } = findMatchingContext({ browser, contexts, identifier, ...(options == null ? void 0 : options.title) && { title: options.title }, ...(options == null ? void 0 : options.url) && { url: options.url } });
|
|
6025
|
+
const contexts = await browser2.getContexts(getContextsOptions);
|
|
6026
|
+
const identifier = browser2.isIOS ? (_a = await browser2.execute("mobile: activeAppInfo")) == null ? void 0 : _a.bundleId : await browser2.getCurrentPackage();
|
|
6027
|
+
const { matchingContext, reasons } = findMatchingContext({ browser: browser2, contexts, identifier, ...(options == null ? void 0 : options.title) && { title: options.title }, ...(options == null ? void 0 : options.url) && { url: options.url } });
|
|
6011
6028
|
if (!matchingContext) {
|
|
6012
6029
|
throw new Error(reasons.join("\n"));
|
|
6013
6030
|
}
|
|
6014
6031
|
log20.info("WebdriverIO found a matching context:", JSON.stringify(matchingContext, null, 2));
|
|
6015
|
-
if (!
|
|
6032
|
+
if (!browser2.isIOS) {
|
|
6016
6033
|
const webviewName = "WEBVIEW_".concat(identifier);
|
|
6017
|
-
await
|
|
6034
|
+
await browser2.switchAppiumContext(webviewName);
|
|
6018
6035
|
}
|
|
6019
|
-
const switchFunction =
|
|
6020
|
-
const matchingContextId =
|
|
6036
|
+
const switchFunction = browser2.isIOS ? browser2.switchAppiumContext.bind(browser2) : browser2.switchToWindow.bind(browser2);
|
|
6037
|
+
const matchingContextId = browser2.isIOS ? matchingContext.id : matchingContext.webviewPageId;
|
|
6021
6038
|
return switchFunction(matchingContextId);
|
|
6022
6039
|
}
|
|
6023
6040
|
function findMatchingContext({
|
|
@@ -6186,9 +6203,9 @@ async function actionClick(element, options) {
|
|
|
6186
6203
|
if (!buttonValue.includes(button)) {
|
|
6187
6204
|
throw new Error("Button type not supported.");
|
|
6188
6205
|
}
|
|
6189
|
-
const
|
|
6206
|
+
const browser2 = getBrowserObject11(element);
|
|
6190
6207
|
if (x || y) {
|
|
6191
|
-
const { width, height } = await
|
|
6208
|
+
const { width, height } = await browser2.getElementRect(element.elementId);
|
|
6192
6209
|
if (x && x < -Math.floor(width / 2) || x && x > Math.floor(width / 2)) {
|
|
6193
6210
|
log21.warn("x would cause a out of bounds error as it goes outside of element");
|
|
6194
6211
|
}
|
|
@@ -6197,8 +6214,8 @@ async function actionClick(element, options) {
|
|
|
6197
6214
|
}
|
|
6198
6215
|
}
|
|
6199
6216
|
const clickNested = async () => {
|
|
6200
|
-
await
|
|
6201
|
-
parameters: { pointerType:
|
|
6217
|
+
await browser2.action("pointer", {
|
|
6218
|
+
parameters: { pointerType: browser2.isMobile ? "touch" : "mouse" }
|
|
6202
6219
|
}).move({ origin: element, x, y }).down({ button }).pause(duration).up({ button }).perform(skipRelease);
|
|
6203
6220
|
};
|
|
6204
6221
|
try {
|
|
@@ -6257,8 +6274,8 @@ async function custom$2(strategyName, ...strategyArguments) {
|
|
|
6257
6274
|
// src/commands/element/doubleClick.ts
|
|
6258
6275
|
import { getBrowserObject as getBrowserObject14 } from "@wdio/utils";
|
|
6259
6276
|
async function doubleClick() {
|
|
6260
|
-
const
|
|
6261
|
-
return
|
|
6277
|
+
const browser2 = getBrowserObject14(this);
|
|
6278
|
+
return browser2.action("pointer", { parameters: { pointerType: "mouse" } }).move({ origin: this }).down().up().pause(10).down().up().perform();
|
|
6262
6279
|
}
|
|
6263
6280
|
|
|
6264
6281
|
// src/commands/element/dragAndDrop.ts
|
|
@@ -6282,8 +6299,8 @@ async function dragAndDrop(target, options = {}) {
|
|
|
6282
6299
|
throw new Error('command dragAndDrop requires an WebdriverIO Element or and object with "x" and "y" variables as first parameter');
|
|
6283
6300
|
}
|
|
6284
6301
|
const ACTION_BUTTON = 0;
|
|
6285
|
-
const
|
|
6286
|
-
const defaultOptions = { duration:
|
|
6302
|
+
const browser2 = getBrowserObject15(this);
|
|
6303
|
+
const defaultOptions = { duration: browser2.isMobile ? 250 : 10 };
|
|
6287
6304
|
const { duration } = { ...defaultOptions, ...options };
|
|
6288
6305
|
const isMovingToElement = moveToElement.constructor.name === "Element";
|
|
6289
6306
|
const sourceRef = { [ELEMENT_KEY11]: this[ELEMENT_KEY11] };
|
|
@@ -6292,23 +6309,23 @@ async function dragAndDrop(target, options = {}) {
|
|
|
6292
6309
|
const targetOrigin = isMovingToElement ? targetRef : "pointer";
|
|
6293
6310
|
const targetX = isMovingToElement ? 0 : moveToCoordinates.x;
|
|
6294
6311
|
const targetY = isMovingToElement ? 0 : moveToCoordinates.y;
|
|
6295
|
-
return
|
|
6296
|
-
parameters: { pointerType:
|
|
6312
|
+
return browser2.action("pointer", {
|
|
6313
|
+
parameters: { pointerType: browser2.isMobile ? "touch" : "mouse" }
|
|
6297
6314
|
}).move({ duration: 0, origin, x: 0, y: 0 }).down({ button: ACTION_BUTTON }).pause(10).move({ duration, origin: targetOrigin, x: targetX, y: targetY }).up({ button: ACTION_BUTTON }).perform();
|
|
6298
6315
|
}
|
|
6299
6316
|
|
|
6300
6317
|
// src/commands/element/execute.ts
|
|
6301
6318
|
import { getBrowserObject as getBrowserObject16 } from "@wdio/utils";
|
|
6302
6319
|
async function execute2(script, ...args) {
|
|
6303
|
-
const
|
|
6304
|
-
return
|
|
6320
|
+
const browser2 = getBrowserObject16(this);
|
|
6321
|
+
return browser2.execute(script, this, ...args);
|
|
6305
6322
|
}
|
|
6306
6323
|
|
|
6307
6324
|
// src/commands/element/executeAsync.ts
|
|
6308
6325
|
import { getBrowserObject as getBrowserObject17 } from "@wdio/utils";
|
|
6309
6326
|
async function executeAsync2(script, ...args) {
|
|
6310
|
-
const
|
|
6311
|
-
return
|
|
6327
|
+
const browser2 = getBrowserObject17(this);
|
|
6328
|
+
return browser2.executeAsync(script, this, ...args);
|
|
6312
6329
|
}
|
|
6313
6330
|
|
|
6314
6331
|
// src/commands/element/getAttribute.ts
|
|
@@ -6382,9 +6399,9 @@ function mergeEqualSymmetricalValue(cssValues) {
|
|
|
6382
6399
|
return newCssValues.join(" ");
|
|
6383
6400
|
}
|
|
6384
6401
|
async function getPseudoElementCSSValue(elem, options) {
|
|
6385
|
-
const
|
|
6402
|
+
const browser2 = getBrowserObject18(elem);
|
|
6386
6403
|
const { cssProperty, pseudoElement } = options;
|
|
6387
|
-
const cssValue2 = await
|
|
6404
|
+
const cssValue2 = await browser2.execute(
|
|
6388
6405
|
(elem2, pseudoElement2, cssProperty2) => window.getComputedStyle(elem2, pseudoElement2)[cssProperty2],
|
|
6389
6406
|
elem,
|
|
6390
6407
|
pseudoElement,
|
|
@@ -6445,7 +6462,7 @@ function getHTMLShadow(element, includeSelectorTag, shadowElementIds = []) {
|
|
|
6445
6462
|
var SHADOW_ID_ATTR_NAME = "data-wdio-shadow-id";
|
|
6446
6463
|
var SHADOW_ID_ATTR = "[".concat(SHADOW_ID_ATTR_NAME, "]");
|
|
6447
6464
|
async function getHTML2(options = {}) {
|
|
6448
|
-
const
|
|
6465
|
+
const browser2 = getBrowserObject19(this);
|
|
6449
6466
|
if (typeof options !== "object" && typeof options === "boolean") {
|
|
6450
6467
|
options = { includeSelectorTag: options };
|
|
6451
6468
|
} else if (typeof options !== "object") {
|
|
@@ -6459,7 +6476,7 @@ async function getHTML2(options = {}) {
|
|
|
6459
6476
|
excludeElements: []
|
|
6460
6477
|
}, options);
|
|
6461
6478
|
const basicGetHTML = (elementId, includeSelectorTag2) => {
|
|
6462
|
-
return
|
|
6479
|
+
return browser2.execute(getHTML, {
|
|
6463
6480
|
[ELEMENT_KEY12]: elementId,
|
|
6464
6481
|
// w3c compatible
|
|
6465
6482
|
ELEMENT: elementId
|
|
@@ -6475,12 +6492,12 @@ async function getHTML2(options = {}) {
|
|
|
6475
6492
|
);
|
|
6476
6493
|
}
|
|
6477
6494
|
const { load } = await import("cheerio");
|
|
6478
|
-
const shadowRootManager = getShadowRootManager(
|
|
6479
|
-
const contextManager = getContextManager(
|
|
6495
|
+
const shadowRootManager = getShadowRootManager(browser2);
|
|
6496
|
+
const contextManager = getContextManager(browser2);
|
|
6480
6497
|
const context = await contextManager.getCurrentContext();
|
|
6481
6498
|
const shadowRootElementPairs = shadowRootManager.getShadowElementPairsByContextId(context, this.elementId);
|
|
6482
6499
|
const elementsWithShadowRootAndIdVerified = (await Promise.all(
|
|
6483
|
-
shadowRootElementPairs.map(([elemId, elem]) =>
|
|
6500
|
+
shadowRootElementPairs.map(([elemId, elem]) => browser2.execute((elem2) => elem2.tagName, { [ELEMENT_KEY12]: elemId }).then(
|
|
6484
6501
|
() => [elemId, elem],
|
|
6485
6502
|
() => void 0
|
|
6486
6503
|
))
|
|
@@ -6489,7 +6506,7 @@ async function getHTML2(options = {}) {
|
|
|
6489
6506
|
{ [ELEMENT_KEY12]: elemId },
|
|
6490
6507
|
shadowId ? { [ELEMENT_KEY12]: shadowId } : void 0
|
|
6491
6508
|
]);
|
|
6492
|
-
const { html, shadowElementHTML } = await
|
|
6509
|
+
const { html, shadowElementHTML } = await browser2.execute(
|
|
6493
6510
|
getHTMLShadow,
|
|
6494
6511
|
{ [ELEMENT_KEY12]: this.elementId },
|
|
6495
6512
|
includeSelectorTag,
|
|
@@ -6700,8 +6717,8 @@ async function isClickable() {
|
|
|
6700
6717
|
if (this.isMobile && this.isNativeContext) {
|
|
6701
6718
|
throw new Error("Method not supported in mobile native environment. It is unlikely that you need to use this command.");
|
|
6702
6719
|
}
|
|
6703
|
-
const
|
|
6704
|
-
return
|
|
6720
|
+
const browser2 = getBrowserObject20(this);
|
|
6721
|
+
return browser2.execute(isElementClickable, {
|
|
6705
6722
|
[ELEMENT_KEY13]: this.elementId,
|
|
6706
6723
|
// w3c compatible
|
|
6707
6724
|
ELEMENT: this.elementId
|
|
@@ -6893,12 +6910,12 @@ function isElementInViewport(elem) {
|
|
|
6893
6910
|
|
|
6894
6911
|
// src/commands/element/isDisplayed.ts
|
|
6895
6912
|
async function isDisplayed(commandParams = DEFAULT_PARAMS) {
|
|
6896
|
-
const
|
|
6913
|
+
const browser2 = getBrowserObject21(this);
|
|
6897
6914
|
if (!await hasElementId(this)) {
|
|
6898
6915
|
return false;
|
|
6899
6916
|
}
|
|
6900
|
-
const isNativeApplication = !
|
|
6901
|
-
if (
|
|
6917
|
+
const isNativeApplication = !browser2.capabilities.browserName;
|
|
6918
|
+
if (browser2.isMobile && isNativeApplication) {
|
|
6902
6919
|
if (commandParams == null ? void 0 : commandParams.withinViewport) {
|
|
6903
6920
|
throw new Error(
|
|
6904
6921
|
"Cannot determine element visibility within viewport for native mobile apps as it is not feasible to determine full vertical and horizontal application bounds. In most cases a basic visibility check should suffice."
|
|
@@ -6908,12 +6925,12 @@ async function isDisplayed(commandParams = DEFAULT_PARAMS) {
|
|
|
6908
6925
|
}
|
|
6909
6926
|
let hadToFallback = false;
|
|
6910
6927
|
const [isDisplayed2, displayProperty] = await Promise.all([
|
|
6911
|
-
|
|
6928
|
+
browser2.execute(function checkVisibility(elem, params) {
|
|
6912
6929
|
return elem.checkVisibility(params);
|
|
6913
6930
|
}, this, commandParams).catch((err) => {
|
|
6914
6931
|
if (err.message.includes("checkVisibility is not a function")) {
|
|
6915
6932
|
hadToFallback = true;
|
|
6916
|
-
return
|
|
6933
|
+
return browser2.execute(isElementDisplayed, this);
|
|
6917
6934
|
}
|
|
6918
6935
|
throw err;
|
|
6919
6936
|
}),
|
|
@@ -6924,9 +6941,9 @@ async function isDisplayed(commandParams = DEFAULT_PARAMS) {
|
|
|
6924
6941
|
]);
|
|
6925
6942
|
const hasDisplayContentsCSSProperty = displayProperty.value === "contents";
|
|
6926
6943
|
const shouldRecheckContentVisibility = !hadToFallback && hasDisplayContentsCSSProperty;
|
|
6927
|
-
const finalResponse = shouldRecheckContentVisibility ? await
|
|
6944
|
+
const finalResponse = shouldRecheckContentVisibility ? await browser2.execute(isElementDisplayed, this).catch(() => false) : isDisplayed2;
|
|
6928
6945
|
if (finalResponse && (commandParams == null ? void 0 : commandParams.withinViewport)) {
|
|
6929
|
-
return
|
|
6946
|
+
return browser2.execute(isElementInViewport, this);
|
|
6930
6947
|
}
|
|
6931
6948
|
return finalResponse;
|
|
6932
6949
|
}
|
|
@@ -6952,9 +6969,9 @@ var getWebElement = (el) => ({
|
|
|
6952
6969
|
// jsonwp compatible
|
|
6953
6970
|
});
|
|
6954
6971
|
async function isEqual(el) {
|
|
6955
|
-
const
|
|
6956
|
-
if (
|
|
6957
|
-
const context = await
|
|
6972
|
+
const browser2 = getBrowserObject22(this);
|
|
6973
|
+
if (browser2.isMobile) {
|
|
6974
|
+
const context = await browser2.getContext().catch(() => void 0);
|
|
6958
6975
|
const contextId = typeof context === "string" ? context : context == null ? void 0 : context.id;
|
|
6959
6976
|
if (contextId && contextId.toLowerCase().includes("native")) {
|
|
6960
6977
|
return this.elementId === el.elementId;
|
|
@@ -6962,7 +6979,7 @@ async function isEqual(el) {
|
|
|
6962
6979
|
}
|
|
6963
6980
|
let result;
|
|
6964
6981
|
try {
|
|
6965
|
-
result = await
|
|
6982
|
+
result = await browser2.execute(
|
|
6966
6983
|
/* istanbul ignore next */
|
|
6967
6984
|
function(el1, el2) {
|
|
6968
6985
|
return el1 === el2;
|
|
@@ -6999,8 +7016,8 @@ function isFocused(elem) {
|
|
|
6999
7016
|
|
|
7000
7017
|
// src/commands/element/isFocused.ts
|
|
7001
7018
|
async function isFocused2() {
|
|
7002
|
-
const
|
|
7003
|
-
return
|
|
7019
|
+
const browser2 = await getBrowserObject23(this);
|
|
7020
|
+
return browser2.execute(isFocused, {
|
|
7004
7021
|
[ELEMENT_KEY15]: this.elementId,
|
|
7005
7022
|
// w3c compatible
|
|
7006
7023
|
ELEMENT: this.elementId
|
|
@@ -7042,8 +7059,8 @@ function isElementStable(elem, done) {
|
|
|
7042
7059
|
|
|
7043
7060
|
// src/commands/element/isStable.ts
|
|
7044
7061
|
async function isStable() {
|
|
7045
|
-
const
|
|
7046
|
-
return await
|
|
7062
|
+
const browser2 = getBrowserObject24(this);
|
|
7063
|
+
return await browser2.executeAsync(isElementStable, {
|
|
7047
7064
|
[ELEMENT_KEY16]: this.elementId,
|
|
7048
7065
|
// w3c compatible
|
|
7049
7066
|
ELEMENT: this.elementId
|
|
@@ -7056,9 +7073,9 @@ import logger22 from "@wdio/logger";
|
|
|
7056
7073
|
import { getBrowserObject as getBrowserObject25 } from "@wdio/utils";
|
|
7057
7074
|
var log22 = logger22("webdriver");
|
|
7058
7075
|
async function moveTo({ xOffset, yOffset } = {}) {
|
|
7059
|
-
const
|
|
7076
|
+
const browser2 = getBrowserObject25(this);
|
|
7060
7077
|
if (xOffset || yOffset) {
|
|
7061
|
-
const { width, height } = await
|
|
7078
|
+
const { width, height } = await browser2.getElementRect(this.elementId);
|
|
7062
7079
|
if (xOffset && xOffset < -Math.floor(width / 2) || xOffset && xOffset > Math.floor(width / 2)) {
|
|
7063
7080
|
log22.warn("xOffset would cause a out of bounds error as it goes outside of element");
|
|
7064
7081
|
}
|
|
@@ -7067,7 +7084,7 @@ async function moveTo({ xOffset, yOffset } = {}) {
|
|
|
7067
7084
|
}
|
|
7068
7085
|
}
|
|
7069
7086
|
const moveToNested = async () => {
|
|
7070
|
-
await
|
|
7087
|
+
await browser2.action("pointer", { parameters: { pointerType: "mouse" } }).move({ origin: this, x: xOffset || 0, y: yOffset || 0 }).perform();
|
|
7071
7088
|
};
|
|
7072
7089
|
try {
|
|
7073
7090
|
await moveToNested();
|
|
@@ -7110,10 +7127,10 @@ function previousElement() {
|
|
|
7110
7127
|
// src/commands/element/react$$.ts
|
|
7111
7128
|
import { getBrowserObject as getBrowserObject26 } from "@wdio/utils";
|
|
7112
7129
|
async function react$$4(selector, { props = {}, state = {} } = {}) {
|
|
7113
|
-
const
|
|
7130
|
+
const browser2 = await getBrowserObject26(this);
|
|
7114
7131
|
await this.executeScript(resqScript.toString(), []);
|
|
7115
|
-
await
|
|
7116
|
-
const res = await
|
|
7132
|
+
await browser2.execute(waitToLoadReact);
|
|
7133
|
+
const res = await browser2.execute(
|
|
7117
7134
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7118
7135
|
react$$,
|
|
7119
7136
|
selector,
|
|
@@ -7128,10 +7145,10 @@ async function react$$4(selector, { props = {}, state = {} } = {}) {
|
|
|
7128
7145
|
// src/commands/element/react$.ts
|
|
7129
7146
|
import { getBrowserObject as getBrowserObject27 } from "@wdio/utils";
|
|
7130
7147
|
async function react$4(selector, { props = {}, state = {} } = {}) {
|
|
7131
|
-
const
|
|
7148
|
+
const browser2 = await getBrowserObject27(this);
|
|
7132
7149
|
await this.executeScript(resqScript.toString(), []);
|
|
7133
|
-
await
|
|
7134
|
-
const res = await
|
|
7150
|
+
await browser2.execute(waitToLoadReact);
|
|
7151
|
+
const res = await browser2.execute(
|
|
7135
7152
|
react$,
|
|
7136
7153
|
selector,
|
|
7137
7154
|
props,
|
|
@@ -7152,11 +7169,11 @@ import { ELEMENT_KEY as ELEMENT_KEY17 } from "webdriver";
|
|
|
7152
7169
|
import { getBrowserObject as getBrowserObject28 } from "@wdio/utils";
|
|
7153
7170
|
var log23 = logger23("webdriverio");
|
|
7154
7171
|
async function scrollIntoView(options = { block: "start", inline: "nearest" }) {
|
|
7155
|
-
const
|
|
7156
|
-
if (
|
|
7157
|
-
if (await
|
|
7172
|
+
const browser2 = getBrowserObject28(this);
|
|
7173
|
+
if (browser2.isMobile) {
|
|
7174
|
+
if (await browser2.isNativeContext) {
|
|
7158
7175
|
return nativeMobileScrollIntoView({
|
|
7159
|
-
browser,
|
|
7176
|
+
browser: browser2,
|
|
7160
7177
|
element: this,
|
|
7161
7178
|
options: options || {}
|
|
7162
7179
|
});
|
|
@@ -7164,9 +7181,9 @@ async function scrollIntoView(options = { block: "start", inline: "nearest" }) {
|
|
|
7164
7181
|
return scrollIntoViewWeb.call(this, options);
|
|
7165
7182
|
}
|
|
7166
7183
|
try {
|
|
7167
|
-
const elemRect = await
|
|
7168
|
-
const viewport = await
|
|
7169
|
-
let [scrollX2, scrollY2] = await
|
|
7184
|
+
const elemRect = await browser2.getElementRect(this.elementId);
|
|
7185
|
+
const viewport = await browser2.getWindowSize();
|
|
7186
|
+
let [scrollX2, scrollY2] = await browser2.execute(() => [
|
|
7170
7187
|
window.scrollX,
|
|
7171
7188
|
window.scrollY
|
|
7172
7189
|
]);
|
|
@@ -7201,7 +7218,7 @@ async function scrollIntoView(options = { block: "start", inline: "nearest" }) {
|
|
|
7201
7218
|
}
|
|
7202
7219
|
deltaX = Math.round(deltaX - scrollX2);
|
|
7203
7220
|
deltaY = Math.round(deltaY - scrollY2);
|
|
7204
|
-
await
|
|
7221
|
+
await browser2.action("wheel").scroll({ duration: 0, x: deltaX, y: deltaY, origin: this }).perform();
|
|
7205
7222
|
} catch (err) {
|
|
7206
7223
|
log23.warn(
|
|
7207
7224
|
'Failed to execute "scrollIntoView" using WebDriver Actions API: '.concat(err.message, "!\n") + "Re-attempting using `Element.scrollIntoView` via Web API."
|
|
@@ -7210,7 +7227,7 @@ async function scrollIntoView(options = { block: "start", inline: "nearest" }) {
|
|
|
7210
7227
|
}
|
|
7211
7228
|
}
|
|
7212
7229
|
async function mobileScrollUntilVisible({
|
|
7213
|
-
browser,
|
|
7230
|
+
browser: browser2,
|
|
7214
7231
|
direction,
|
|
7215
7232
|
duration,
|
|
7216
7233
|
element,
|
|
@@ -7230,7 +7247,7 @@ async function mobileScrollUntilVisible({
|
|
|
7230
7247
|
if (isVisible) {
|
|
7231
7248
|
break;
|
|
7232
7249
|
}
|
|
7233
|
-
await
|
|
7250
|
+
await browser2.swipe({
|
|
7234
7251
|
direction,
|
|
7235
7252
|
...duration ? { duration } : {},
|
|
7236
7253
|
...percent ? { percent } : {},
|
|
@@ -7242,7 +7259,7 @@ async function mobileScrollUntilVisible({
|
|
|
7242
7259
|
return { hasScrolled, isVisible };
|
|
7243
7260
|
}
|
|
7244
7261
|
async function nativeMobileScrollIntoView({
|
|
7245
|
-
browser,
|
|
7262
|
+
browser: browser2,
|
|
7246
7263
|
element,
|
|
7247
7264
|
options
|
|
7248
7265
|
}) {
|
|
@@ -7255,7 +7272,7 @@ async function nativeMobileScrollIntoView({
|
|
|
7255
7272
|
...options || {}
|
|
7256
7273
|
};
|
|
7257
7274
|
const { hasScrolled, isVisible } = await mobileScrollUntilVisible({
|
|
7258
|
-
browser,
|
|
7275
|
+
browser: browser2,
|
|
7259
7276
|
element,
|
|
7260
7277
|
maxScrolls: mobileOptions.maxScrolls,
|
|
7261
7278
|
direction: mobileOptions.direction,
|
|
@@ -7264,15 +7281,15 @@ async function nativeMobileScrollIntoView({
|
|
|
7264
7281
|
...(mobileOptions == null ? void 0 : mobileOptions.scrollableElement) ? { scrollableElement: mobileOptions.scrollableElement } : {}
|
|
7265
7282
|
});
|
|
7266
7283
|
if (hasScrolled && isVisible) {
|
|
7267
|
-
return
|
|
7284
|
+
return browser2.pause(1e3);
|
|
7268
7285
|
} else if (isVisible) {
|
|
7269
7286
|
return;
|
|
7270
7287
|
}
|
|
7271
7288
|
throw new Error("Element not found within scroll limit of ".concat(mobileOptions.maxScrolls, ' scrolls by scrolling "').concat(mobileOptions.direction, '". ') + "Are you sure the element is within the scrollable element or the direction is correct? You can change the scrollable element or direction like this:\n\nawait elem.scrollIntoView({\n direction: 'left' // possible options are: 'up|down|left|right'\n scrollableElement: $('#scrollable'),\n});\n\n ");
|
|
7272
7289
|
}
|
|
7273
7290
|
function scrollIntoViewWeb(options = { block: "start", inline: "nearest" }) {
|
|
7274
|
-
const
|
|
7275
|
-
return
|
|
7291
|
+
const browser2 = getBrowserObject28(this);
|
|
7292
|
+
return browser2.execute(
|
|
7276
7293
|
(elem, options2) => elem.scrollIntoView(options2),
|
|
7277
7294
|
{
|
|
7278
7295
|
[ELEMENT_KEY17]: this.elementId,
|
|
@@ -7679,11 +7696,11 @@ var createRoleBaseXpathSelector = (role) => {
|
|
|
7679
7696
|
// src/commands/element/shadow$$.ts
|
|
7680
7697
|
var log24 = logger24("webdriverio");
|
|
7681
7698
|
async function shadow$$(selector) {
|
|
7682
|
-
const
|
|
7699
|
+
const browser2 = getBrowserObject29(this);
|
|
7683
7700
|
try {
|
|
7684
|
-
const shadowRoot = await
|
|
7701
|
+
const shadowRoot = await browser2.getElementShadowRoot(this.elementId);
|
|
7685
7702
|
const { using, value } = findStrategy(selector, this.isW3C, this.isMobile);
|
|
7686
|
-
const res = await
|
|
7703
|
+
const res = await browser2.findElementsFromShadowRoot(shadowRoot[SHADOW_ELEMENT_KEY], using, value);
|
|
7687
7704
|
const elements = await getElements.call(this, selector, res, { isShadowElement: true });
|
|
7688
7705
|
return enhanceElementsArray(elements, this, selector);
|
|
7689
7706
|
} catch (err) {
|
|
@@ -7700,11 +7717,11 @@ import { SHADOW_ELEMENT_KEY as SHADOW_ELEMENT_KEY2 } from "webdriver";
|
|
|
7700
7717
|
import { getBrowserObject as getBrowserObject30 } from "@wdio/utils";
|
|
7701
7718
|
var log25 = logger25("webdriverio");
|
|
7702
7719
|
async function shadow$(selector) {
|
|
7703
|
-
const
|
|
7720
|
+
const browser2 = getBrowserObject30(this);
|
|
7704
7721
|
try {
|
|
7705
|
-
const shadowRoot = await
|
|
7722
|
+
const shadowRoot = await browser2.getElementShadowRoot(this.elementId);
|
|
7706
7723
|
const { using, value } = findStrategy(selector, this.isW3C, this.isMobile);
|
|
7707
|
-
const res = await
|
|
7724
|
+
const res = await browser2.findElementFromShadowRoot(shadowRoot[SHADOW_ELEMENT_KEY2], using, value);
|
|
7708
7725
|
return getElement.call(this, selector, res, { isShadowElement: true });
|
|
7709
7726
|
} catch (err) {
|
|
7710
7727
|
log25.warn(
|
|
@@ -7811,8 +7828,8 @@ var waitUntil2 = waitUntil;
|
|
|
7811
7828
|
// src/commands/mobile/longPress.ts
|
|
7812
7829
|
import { getBrowserObject as getBrowserObject31 } from "@wdio/utils";
|
|
7813
7830
|
function longPress(options) {
|
|
7814
|
-
const
|
|
7815
|
-
if (!
|
|
7831
|
+
const browser2 = getBrowserObject31(this);
|
|
7832
|
+
if (!browser2.isMobile) {
|
|
7816
7833
|
throw new Error("The longPress command is only available for mobile platforms.");
|
|
7817
7834
|
}
|
|
7818
7835
|
if (typeof options !== "undefined" && (typeof options !== "object" || Array.isArray(options))) {
|
|
@@ -7830,12 +7847,12 @@ function longPress(options) {
|
|
|
7830
7847
|
// src/commands/mobile/pinch.ts
|
|
7831
7848
|
import { getBrowserObject as getBrowserObject32 } from "@wdio/utils";
|
|
7832
7849
|
async function pinch(options = {}) {
|
|
7833
|
-
const
|
|
7834
|
-
if (!
|
|
7850
|
+
const browser2 = getBrowserObject32(this);
|
|
7851
|
+
if (!browser2.isMobile) {
|
|
7835
7852
|
throw new Error("The pinch command is only available for mobile platforms.");
|
|
7836
7853
|
}
|
|
7837
|
-
const { duration, scale } = validatePinchAndZoomOptions({ browser, gesture: "pinch", options });
|
|
7838
|
-
const gestureConfig =
|
|
7854
|
+
const { duration, scale } = validatePinchAndZoomOptions({ browser: browser2, gesture: "pinch", options });
|
|
7855
|
+
const gestureConfig = browser2.isIOS ? {
|
|
7839
7856
|
elementId: await this.elementId,
|
|
7840
7857
|
scale,
|
|
7841
7858
|
velocity: -Math.abs(duration)
|
|
@@ -7843,29 +7860,29 @@ async function pinch(options = {}) {
|
|
|
7843
7860
|
} : {
|
|
7844
7861
|
elementId: await this.elementId,
|
|
7845
7862
|
percent: scale,
|
|
7846
|
-
speed: calculateAndroidPinchAndZoomSpeed({ browser, duration, scale })
|
|
7863
|
+
speed: calculateAndroidPinchAndZoomSpeed({ browser: browser2, duration, scale })
|
|
7847
7864
|
};
|
|
7848
|
-
return
|
|
7865
|
+
return browser2.execute(browser2.isIOS ? "mobile: pinch" : "mobile: pinchCloseGesture", gestureConfig);
|
|
7849
7866
|
}
|
|
7850
7867
|
|
|
7851
7868
|
// src/commands/mobile/zoom.ts
|
|
7852
7869
|
import { getBrowserObject as getBrowserObject33 } from "@wdio/utils";
|
|
7853
7870
|
async function zoom(options = {}) {
|
|
7854
|
-
const
|
|
7855
|
-
if (!
|
|
7871
|
+
const browser2 = getBrowserObject33(this);
|
|
7872
|
+
if (!browser2.isMobile) {
|
|
7856
7873
|
throw new Error("The zoom command is only available for mobile platforms.");
|
|
7857
7874
|
}
|
|
7858
|
-
const { duration, scale } = validatePinchAndZoomOptions({ browser, gesture: "zoom", options });
|
|
7859
|
-
const gestureConfig =
|
|
7875
|
+
const { duration, scale } = validatePinchAndZoomOptions({ browser: browser2, gesture: "zoom", options });
|
|
7876
|
+
const gestureConfig = browser2.isIOS ? {
|
|
7860
7877
|
elementId: await this.elementId,
|
|
7861
7878
|
scale,
|
|
7862
7879
|
velocity: duration
|
|
7863
7880
|
} : {
|
|
7864
7881
|
elementId: await this.elementId,
|
|
7865
7882
|
percent: scale,
|
|
7866
|
-
speed: calculateAndroidPinchAndZoomSpeed({ browser, duration, scale })
|
|
7883
|
+
speed: calculateAndroidPinchAndZoomSpeed({ browser: browser2, duration, scale })
|
|
7867
7884
|
};
|
|
7868
|
-
return
|
|
7885
|
+
return browser2.execute(browser2.isIOS ? "mobile: pinch" : "mobile: pinchOpenGesture", gestureConfig);
|
|
7869
7886
|
}
|
|
7870
7887
|
|
|
7871
7888
|
// src/scripts/elementContains.ts
|
|
@@ -8221,9 +8238,9 @@ function transformClassicToBidiSelector(using, value) {
|
|
|
8221
8238
|
throw new Error("Can't transform classic selector ".concat(using, " to Bidi selector"));
|
|
8222
8239
|
}
|
|
8223
8240
|
async function findDeepElement(selector) {
|
|
8224
|
-
const
|
|
8225
|
-
const shadowRootManager = getShadowRootManager(
|
|
8226
|
-
const contextManager = getContextManager(
|
|
8241
|
+
const browser2 = getBrowserObject34(this);
|
|
8242
|
+
const shadowRootManager = getShadowRootManager(browser2);
|
|
8243
|
+
const contextManager = getContextManager(browser2);
|
|
8227
8244
|
const context = await contextManager.getCurrentContext();
|
|
8228
8245
|
const shadowRoots = shadowRootManager.getShadowElementsByContextId(
|
|
8229
8246
|
context,
|
|
@@ -8232,7 +8249,7 @@ async function findDeepElement(selector) {
|
|
|
8232
8249
|
const { using, value } = findStrategy(selector, this.isW3C, this.isMobile);
|
|
8233
8250
|
const locator = transformClassicToBidiSelector(using, value);
|
|
8234
8251
|
const startNodes = shadowRoots.length > 0 ? shadowRoots.map((shadowRootNodeId) => ({ sharedId: shadowRootNodeId })) : this.elementId ? [{ sharedId: this.elementId }] : void 0;
|
|
8235
|
-
const deepElementResult = await
|
|
8252
|
+
const deepElementResult = await browser2.browsingContextLocateNodes({ locator, context, startNodes }).then(async (result) => {
|
|
8236
8253
|
const nodes = result.nodes.filter((node) => Boolean(node.sharedId)).map((node) => ({
|
|
8237
8254
|
[ELEMENT_KEY18]: node.sharedId,
|
|
8238
8255
|
locator
|
|
@@ -8241,7 +8258,7 @@ async function findDeepElement(selector) {
|
|
|
8241
8258
|
return nodes[0];
|
|
8242
8259
|
}
|
|
8243
8260
|
const scopedNodes = await Promise.all(nodes.map(async (node) => {
|
|
8244
|
-
const isIn = await
|
|
8261
|
+
const isIn = await browser2.execute(
|
|
8245
8262
|
elementContains,
|
|
8246
8263
|
{ [ELEMENT_KEY18]: this.elementId },
|
|
8247
8264
|
node
|
|
@@ -8251,7 +8268,7 @@ async function findDeepElement(selector) {
|
|
|
8251
8268
|
return scopedNodes[0];
|
|
8252
8269
|
}, (err) => {
|
|
8253
8270
|
log26.warn("Failed to execute browser.browsingContextLocateNodes({ ... }) due to ".concat(err, ", falling back to regular WebDriver Classic command"));
|
|
8254
|
-
return this && "elementId" in this && this.elementId ? this.findElementFromElement(this.elementId, using, value) :
|
|
8271
|
+
return this && "elementId" in this && this.elementId ? this.findElementFromElement(this.elementId, using, value) : browser2.findElement(using, value);
|
|
8255
8272
|
});
|
|
8256
8273
|
if (!deepElementResult) {
|
|
8257
8274
|
return new Error("Couldn't find element with selector \"".concat(selector, '"'));
|
|
@@ -8259,9 +8276,9 @@ async function findDeepElement(selector) {
|
|
|
8259
8276
|
return deepElementResult;
|
|
8260
8277
|
}
|
|
8261
8278
|
async function findDeepElements(selector) {
|
|
8262
|
-
const
|
|
8263
|
-
const shadowRootManager = getShadowRootManager(
|
|
8264
|
-
const contextManager = getContextManager(
|
|
8279
|
+
const browser2 = getBrowserObject34(this);
|
|
8280
|
+
const shadowRootManager = getShadowRootManager(browser2);
|
|
8281
|
+
const contextManager = getContextManager(browser2);
|
|
8265
8282
|
const context = await contextManager.getCurrentContext();
|
|
8266
8283
|
const shadowRoots = shadowRootManager.getShadowElementsByContextId(
|
|
8267
8284
|
context,
|
|
@@ -8270,7 +8287,7 @@ async function findDeepElements(selector) {
|
|
|
8270
8287
|
const { using, value } = findStrategy(selector, this.isW3C, this.isMobile);
|
|
8271
8288
|
const locator = transformClassicToBidiSelector(using, value);
|
|
8272
8289
|
const startNodes = shadowRoots.length > 0 ? shadowRoots.map((shadowRootNodeId) => ({ sharedId: shadowRootNodeId })) : this.elementId ? [{ sharedId: this.elementId }] : void 0;
|
|
8273
|
-
const deepElementResult = await
|
|
8290
|
+
const deepElementResult = await browser2.browsingContextLocateNodes({ locator, context, startNodes }).then(async (result) => {
|
|
8274
8291
|
const nodes = result.nodes.filter((node) => Boolean(node.sharedId)).map((node) => ({
|
|
8275
8292
|
[ELEMENT_KEY18]: node.sharedId,
|
|
8276
8293
|
locator
|
|
@@ -8279,7 +8296,7 @@ async function findDeepElements(selector) {
|
|
|
8279
8296
|
return nodes;
|
|
8280
8297
|
}
|
|
8281
8298
|
const scopedNodes = await Promise.all(nodes.map(async (node) => {
|
|
8282
|
-
const isIn = await
|
|
8299
|
+
const isIn = await browser2.execute(
|
|
8283
8300
|
elementContains,
|
|
8284
8301
|
{ [ELEMENT_KEY18]: this.elementId },
|
|
8285
8302
|
node
|
|
@@ -8289,7 +8306,7 @@ async function findDeepElements(selector) {
|
|
|
8289
8306
|
return scopedNodes;
|
|
8290
8307
|
}, (err) => {
|
|
8291
8308
|
log26.warn("Failed to execute browser.browsingContextLocateNodes({ ... }) due to ".concat(err, ", falling back to regular WebDriver Classic command"));
|
|
8292
|
-
return this && "elementId" in this && this.elementId ? this.findElementsFromElement(this.elementId, using, value) :
|
|
8309
|
+
return this && "elementId" in this && this.elementId ? this.findElementsFromElement(this.elementId, using, value) : browser2.findElements(using, value);
|
|
8293
8310
|
});
|
|
8294
8311
|
return deepElementResult;
|
|
8295
8312
|
}
|
|
@@ -8791,7 +8808,7 @@ var NOOP2 = () => {
|
|
|
8791
8808
|
var ProtocolStub = class {
|
|
8792
8809
|
static async newSession(options) {
|
|
8793
8810
|
const capabilities = emulateSessionCapabilities(options.capabilities);
|
|
8794
|
-
const
|
|
8811
|
+
const browser2 = {
|
|
8795
8812
|
options,
|
|
8796
8813
|
capabilities,
|
|
8797
8814
|
requestedCapabilities: capabilities,
|
|
@@ -8807,9 +8824,9 @@ var ProtocolStub = class {
|
|
|
8807
8824
|
overwriteCommand: NOOP2,
|
|
8808
8825
|
...capabilitiesEnvironmentDetector(capabilities)
|
|
8809
8826
|
};
|
|
8810
|
-
|
|
8811
|
-
|
|
8812
|
-
return
|
|
8827
|
+
browser2.addCommand = (...args) => browser2.customCommands.push(args);
|
|
8828
|
+
browser2.overwriteCommand = (...args) => browser2.overwrittenCommands.push(args);
|
|
8829
|
+
return browser2;
|
|
8813
8830
|
}
|
|
8814
8831
|
/**
|
|
8815
8832
|
* added just in case user wants to somehow reload webdriver before it was started.
|