webdriverio 9.16.0 → 9.17.0
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/debug.d.ts.map +1 -1
- package/build/commands/browser/switchFrame.d.ts.map +1 -1
- package/build/commands/browser/url.d.ts +6 -0
- package/build/commands/browser/url.d.ts.map +1 -1
- package/build/commands/constant.d.ts.map +1 -1
- package/build/environment.d.ts +6 -0
- package/build/environment.d.ts.map +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +332 -316
- package/build/middlewares.d.ts.map +1 -1
- package/build/node.d.ts.map +1 -1
- package/build/node.js +371 -353
- package/build/scripts/resq.d.ts.map +1 -1
- package/build/scripts/shadowFnFactory.d.ts.map +1 -1
- package/build/session/context.d.ts.map +1 -1
- package/build/session/session.d.ts.map +1 -1
- package/build/utils/findStrategy.d.ts.map +1 -1
- package/build/utils/getElementObject.d.ts.map +1 -1
- package/build/utils/index.d.ts.map +1 -1
- package/package.json +10 -10
package/build/node.js
CHANGED
|
@@ -7,6 +7,7 @@ var __export = (target, all) => {
|
|
|
7
7
|
// src/node.ts
|
|
8
8
|
import os from "node:os";
|
|
9
9
|
import fs8 from "node:fs";
|
|
10
|
+
import process2 from "node:process";
|
|
10
11
|
|
|
11
12
|
// src/node/downloadFile.ts
|
|
12
13
|
import fs from "node:fs";
|
|
@@ -132,6 +133,40 @@ import { getBrowserObject } from "@wdio/utils";
|
|
|
132
133
|
// src/session/context.ts
|
|
133
134
|
import logger2 from "@wdio/logger";
|
|
134
135
|
|
|
136
|
+
// src/environment.ts
|
|
137
|
+
var isNode = !!(typeof process !== "undefined" && process.version);
|
|
138
|
+
var environment = {
|
|
139
|
+
value: {
|
|
140
|
+
get readFileSync() {
|
|
141
|
+
throw new Error("Can't read files form file system in this environment");
|
|
142
|
+
},
|
|
143
|
+
get downloadFile() {
|
|
144
|
+
throw new Error("The `downloadFile` command is not available in this environment");
|
|
145
|
+
},
|
|
146
|
+
get savePDF() {
|
|
147
|
+
throw new Error("The `savePDF` command is not available in this environment");
|
|
148
|
+
},
|
|
149
|
+
get saveRecordingScreen() {
|
|
150
|
+
throw new Error("The `saveRecordingScreen` command is not available in this environment");
|
|
151
|
+
},
|
|
152
|
+
get uploadFile() {
|
|
153
|
+
throw new Error("The `uploadFile` command is not available in this environment");
|
|
154
|
+
},
|
|
155
|
+
get saveScreenshot() {
|
|
156
|
+
throw new Error("The `saveScreenshot` command for WebdriverIO.Browser is not available in this environment");
|
|
157
|
+
},
|
|
158
|
+
get saveElementScreenshot() {
|
|
159
|
+
throw new Error("The `saveScreenshot` command for WebdriverIO.Element is not available in this environment");
|
|
160
|
+
},
|
|
161
|
+
get osType() {
|
|
162
|
+
return () => "browser";
|
|
163
|
+
},
|
|
164
|
+
get variables() {
|
|
165
|
+
return isNode ? process.env : {};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
135
170
|
// src/session/session.ts
|
|
136
171
|
var sessionManager = /* @__PURE__ */ new Map();
|
|
137
172
|
var listenerRegisteredSession = /* @__PURE__ */ new Set();
|
|
@@ -145,8 +180,8 @@ var SessionManager = class {
|
|
|
145
180
|
* @param browser WebdriverIO.Browser
|
|
146
181
|
* @param scope scope of the session manager, e.g. context, network etc.
|
|
147
182
|
*/
|
|
148
|
-
constructor(
|
|
149
|
-
this.#browser =
|
|
183
|
+
constructor(browser, scope) {
|
|
184
|
+
this.#browser = browser;
|
|
150
185
|
this.#scope = scope;
|
|
151
186
|
const registrationId = `${this.#browser.sessionId}-${this.#scope}`;
|
|
152
187
|
if (!listenerRegisteredSession.has(registrationId)) {
|
|
@@ -177,20 +212,20 @@ var SessionManager = class {
|
|
|
177
212
|
return (
|
|
178
213
|
// we are in a Bidi session
|
|
179
214
|
this.#browser.isBidi && // we are not running unit tests
|
|
180
|
-
!
|
|
215
|
+
!environment.value.variables.WDIO_UNIT_TESTS
|
|
181
216
|
);
|
|
182
217
|
}
|
|
183
|
-
static getSessionManager(
|
|
218
|
+
static getSessionManager(browser, Manager) {
|
|
184
219
|
const scope = Manager.name;
|
|
185
220
|
let sessionManagerInstances = sessionManager.get(scope);
|
|
186
221
|
if (!sessionManagerInstances) {
|
|
187
222
|
sessionManagerInstances = /* @__PURE__ */ new Map();
|
|
188
223
|
sessionManager.set(scope, sessionManagerInstances);
|
|
189
224
|
}
|
|
190
|
-
let sessionManagerInstance = sessionManagerInstances.get(
|
|
225
|
+
let sessionManagerInstance = sessionManagerInstances.get(browser);
|
|
191
226
|
if (!sessionManagerInstance) {
|
|
192
|
-
sessionManagerInstance = new Manager(
|
|
193
|
-
sessionManagerInstances.set(
|
|
227
|
+
sessionManagerInstance = new Manager(browser);
|
|
228
|
+
sessionManagerInstances.set(browser, sessionManagerInstance);
|
|
194
229
|
}
|
|
195
230
|
return sessionManagerInstance;
|
|
196
231
|
}
|
|
@@ -217,19 +252,19 @@ function getMobileContext({ capabilities, isAndroid, isNativeContext }) {
|
|
|
217
252
|
isAndroid && capabilities?.browserName?.toLowerCase() === "chrome" ? "CHROMIUM" : void 0
|
|
218
253
|
);
|
|
219
254
|
}
|
|
220
|
-
function calculateAndroidPinchAndZoomSpeed({ browser
|
|
221
|
-
const deviceScreenSize = (
|
|
255
|
+
function calculateAndroidPinchAndZoomSpeed({ browser, duration, scale }) {
|
|
256
|
+
const deviceScreenSize = (browser.capabilities?.deviceScreenSize || "1080x2400").split("x").reduce((a, b) => a * b);
|
|
222
257
|
const baseDistance = Math.sqrt(deviceScreenSize);
|
|
223
258
|
const gestureDistance = Math.max(baseDistance * Math.abs(scale), baseDistance * 0.1);
|
|
224
259
|
const durationSeconds = duration / 1e3;
|
|
225
260
|
return Math.floor(gestureDistance / durationSeconds);
|
|
226
261
|
}
|
|
227
|
-
function validatePinchAndZoomOptions({ browser
|
|
262
|
+
function validatePinchAndZoomOptions({ browser, gesture, options }) {
|
|
228
263
|
if (typeof options !== "undefined" && (typeof options !== "object" || Array.isArray(options))) {
|
|
229
264
|
throw new TypeError("Options must be an object");
|
|
230
265
|
}
|
|
231
266
|
const DEFAULT_SCALE = 0.5;
|
|
232
|
-
const DEFAULT_DURATION =
|
|
267
|
+
const DEFAULT_DURATION = browser.isIOS ? 1.5 : 1500;
|
|
233
268
|
const MIN_SCALE = 0;
|
|
234
269
|
const MAX_SCALE = 1;
|
|
235
270
|
const MIN_DURATION_MS = 500;
|
|
@@ -238,20 +273,20 @@ function validatePinchAndZoomOptions({ browser: browser2, gesture, options }) {
|
|
|
238
273
|
const scale = typeof scaleOption === "number" ? scaleOption >= MIN_SCALE && scaleOption <= MAX_SCALE ? scaleOption : (() => {
|
|
239
274
|
throw new Error(`The 'scale' option must be a number between ${MIN_SCALE} and ${MAX_SCALE}`);
|
|
240
275
|
})() : DEFAULT_SCALE;
|
|
241
|
-
const duration = typeof durationOption === "number" ? durationOption >= MIN_DURATION_MS && durationOption <= MAX_DURATION_MS ?
|
|
276
|
+
const duration = typeof durationOption === "number" ? durationOption >= MIN_DURATION_MS && durationOption <= MAX_DURATION_MS ? browser.isIOS ? durationOption / 1e3 : durationOption : (() => {
|
|
242
277
|
throw new Error(`The 'duration' option must be between ${MIN_DURATION_MS} and ${MAX_DURATION_MS} ms (${MIN_DURATION_MS / 1e3} and ${MAX_DURATION_MS / 1e3} seconds)`);
|
|
243
278
|
})() : DEFAULT_DURATION;
|
|
244
279
|
return {
|
|
245
280
|
duration,
|
|
246
|
-
scale:
|
|
281
|
+
scale: browser.isIOS && gesture === "zoom" ? scale * 10 : scale
|
|
247
282
|
};
|
|
248
283
|
}
|
|
249
284
|
|
|
250
285
|
// src/session/context.ts
|
|
251
286
|
var log2 = logger2("webdriverio:context");
|
|
252
287
|
var COMMANDS_REQUIRING_RESET = ["deleteSession", "refresh", "switchToParentFrame"];
|
|
253
|
-
function getContextManager(
|
|
254
|
-
return SessionManager.getSessionManager(
|
|
288
|
+
function getContextManager(browser) {
|
|
289
|
+
return SessionManager.getSessionManager(browser, ContextManager);
|
|
255
290
|
}
|
|
256
291
|
var ContextManager = class _ContextManager extends SessionManager {
|
|
257
292
|
#browser;
|
|
@@ -259,9 +294,9 @@ var ContextManager = class _ContextManager extends SessionManager {
|
|
|
259
294
|
#mobileContext;
|
|
260
295
|
#isNativeContext;
|
|
261
296
|
#getContextSupport = true;
|
|
262
|
-
constructor(
|
|
263
|
-
super(
|
|
264
|
-
this.#browser =
|
|
297
|
+
constructor(browser) {
|
|
298
|
+
super(browser, _ContextManager.name);
|
|
299
|
+
this.#browser = browser;
|
|
265
300
|
const capabilities = this.#browser.capabilities;
|
|
266
301
|
this.#isNativeContext = getNativeContext({ capabilities, isMobile: this.#browser.isMobile });
|
|
267
302
|
this.#mobileContext = getMobileContext({
|
|
@@ -348,7 +383,7 @@ var ContextManager = class _ContextManager extends SessionManager {
|
|
|
348
383
|
* set context at the start of the session
|
|
349
384
|
*/
|
|
350
385
|
async initialize() {
|
|
351
|
-
if (
|
|
386
|
+
if (environment.value.variables.WDIO_UNIT_TESTS) {
|
|
352
387
|
return "";
|
|
353
388
|
}
|
|
354
389
|
if (this.#browser.isMobile && !this.#isNativeContext && !this.#mobileContext && this.#getContextSupport) {
|
|
@@ -486,8 +521,8 @@ function takeScreenshotClassic(filepath, options) {
|
|
|
486
521
|
return this.takeScreenshot();
|
|
487
522
|
}
|
|
488
523
|
async function takeScreenshotBidi(filepath, options) {
|
|
489
|
-
const
|
|
490
|
-
const contextManager = getContextManager(
|
|
524
|
+
const browser = getBrowserObject(this);
|
|
525
|
+
const contextManager = getContextManager(browser);
|
|
491
526
|
const context = await contextManager.getCurrentContext();
|
|
492
527
|
const tree = await this.browsingContextGetTree({});
|
|
493
528
|
const origin = options?.fullPage ? "document" : "viewport";
|
|
@@ -524,7 +559,7 @@ async function takeScreenshotBidi(filepath, options) {
|
|
|
524
559
|
throw new Error("Invalid clip, use an object with x, y, width and height properties");
|
|
525
560
|
}
|
|
526
561
|
}
|
|
527
|
-
const { data } = contextManager.findParentContext(context, tree.contexts) ? await
|
|
562
|
+
const { data } = contextManager.findParentContext(context, tree.contexts) ? await browser.$("html").getElement().then(
|
|
528
563
|
(el) => this.takeElementScreenshot(el.elementId).then((data2) => ({ data: data2 }))
|
|
529
564
|
) : await this.browsingContextCaptureScreenshot({ context, origin, format, clip });
|
|
530
565
|
return data;
|
|
@@ -564,8 +599,8 @@ import logger3 from "@wdio/logger";
|
|
|
564
599
|
import { getBrowserObject as getBrowserObject2 } from "@wdio/utils";
|
|
565
600
|
var log3 = logger3("webdriverio");
|
|
566
601
|
async function implicitWait(currentElement, commandName) {
|
|
567
|
-
const
|
|
568
|
-
const skipForMobileScroll =
|
|
602
|
+
const browser = getBrowserObject2(currentElement);
|
|
603
|
+
const skipForMobileScroll = browser.isMobile && await browser.isNativeContext && (commandName === "scrollIntoView" || commandName === "tap");
|
|
569
604
|
if (!currentElement.elementId && !/(waitUntil|waitFor|isExisting|is?\w+Displayed|is?\w+Clickable)/.test(commandName) && !skipForMobileScroll) {
|
|
570
605
|
log3.debug(
|
|
571
606
|
`command ${commandName} was called on an element ("${currentElement.selector}") that wasn't found, waiting for it...`
|
|
@@ -697,13 +732,13 @@ var WebDriverError = class extends Error {
|
|
|
697
732
|
}
|
|
698
733
|
};
|
|
699
734
|
function getElement(selector, res, props = { isReactElement: false, isShadowElement: false }) {
|
|
700
|
-
const
|
|
735
|
+
const browser = getBrowserObject3(this);
|
|
701
736
|
const browserCommandKeys = Object.keys(browser_exports);
|
|
702
737
|
const propertiesObject = {
|
|
703
738
|
/**
|
|
704
739
|
* filter out browser commands from object
|
|
705
740
|
*/
|
|
706
|
-
...Object.entries(clone(
|
|
741
|
+
...Object.entries(clone(browser.__propertiesObject__)).reduce((commands, [name, descriptor]) => {
|
|
707
742
|
if (!browserCommandKeys.includes(name)) {
|
|
708
743
|
commands[name] = descriptor;
|
|
709
744
|
}
|
|
@@ -735,19 +770,19 @@ function getElement(selector, res, props = { isReactElement: false, isShadowElem
|
|
|
735
770
|
const elementInstance = element(this.sessionId, elementErrorHandler(wrapCommand));
|
|
736
771
|
const origAddCommand = elementInstance.addCommand.bind(elementInstance);
|
|
737
772
|
elementInstance.addCommand = (name, fn) => {
|
|
738
|
-
|
|
773
|
+
browser.__propertiesObject__[name] = { value: fn };
|
|
739
774
|
origAddCommand(name, fn);
|
|
740
775
|
};
|
|
741
776
|
return elementInstance;
|
|
742
777
|
}
|
|
743
778
|
var getElements = function getElements2(selector, elemResponse, props = { isReactElement: false, isShadowElement: false }) {
|
|
744
|
-
const
|
|
779
|
+
const browser = getBrowserObject3(this);
|
|
745
780
|
const browserCommandKeys = Object.keys(browser_exports);
|
|
746
781
|
const propertiesObject = {
|
|
747
782
|
/**
|
|
748
783
|
* filter out browser commands from object
|
|
749
784
|
*/
|
|
750
|
-
...Object.entries(clone(
|
|
785
|
+
...Object.entries(clone(browser.__propertiesObject__)).reduce((commands, [name, descriptor]) => {
|
|
751
786
|
if (!browserCommandKeys.includes(name)) {
|
|
752
787
|
commands[name] = descriptor;
|
|
753
788
|
}
|
|
@@ -786,7 +821,7 @@ var getElements = function getElements2(selector, elemResponse, props = { isReac
|
|
|
786
821
|
const elementInstance = element(this.sessionId, elementErrorHandler(wrapCommand));
|
|
787
822
|
const origAddCommand = elementInstance.addCommand.bind(elementInstance);
|
|
788
823
|
elementInstance.addCommand = (name, fn) => {
|
|
789
|
-
|
|
824
|
+
browser.__propertiesObject__[name] = { value: fn };
|
|
790
825
|
origAddCommand(name, fn);
|
|
791
826
|
};
|
|
792
827
|
return elementInstance;
|
|
@@ -1034,37 +1069,6 @@ var BaseAction = class {
|
|
|
1034
1069
|
}
|
|
1035
1070
|
};
|
|
1036
1071
|
|
|
1037
|
-
// src/environment.ts
|
|
1038
|
-
var isNode = !!(typeof process !== "undefined" && process.version);
|
|
1039
|
-
var environment = {
|
|
1040
|
-
value: {
|
|
1041
|
-
get readFileSync() {
|
|
1042
|
-
throw new Error("Can't read files form file system in this environment");
|
|
1043
|
-
},
|
|
1044
|
-
get downloadFile() {
|
|
1045
|
-
throw new Error("The `downloadFile` command is not available in this environment");
|
|
1046
|
-
},
|
|
1047
|
-
get savePDF() {
|
|
1048
|
-
throw new Error("The `savePDF` command is not available in this environment");
|
|
1049
|
-
},
|
|
1050
|
-
get saveRecordingScreen() {
|
|
1051
|
-
throw new Error("The `saveRecordingScreen` command is not available in this environment");
|
|
1052
|
-
},
|
|
1053
|
-
get uploadFile() {
|
|
1054
|
-
throw new Error("The `uploadFile` command is not available in this environment");
|
|
1055
|
-
},
|
|
1056
|
-
get saveScreenshot() {
|
|
1057
|
-
throw new Error("The `saveScreenshot` command for WebdriverIO.Browser is not available in this environment");
|
|
1058
|
-
},
|
|
1059
|
-
get saveElementScreenshot() {
|
|
1060
|
-
throw new Error("The `saveScreenshot` command for WebdriverIO.Element is not available in this environment");
|
|
1061
|
-
},
|
|
1062
|
-
get osType() {
|
|
1063
|
-
return () => "browser";
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
};
|
|
1067
|
-
|
|
1068
1072
|
// src/utils/actions/key.ts
|
|
1069
1073
|
var KeyAction = class extends BaseAction {
|
|
1070
1074
|
constructor(instance, params) {
|
|
@@ -1566,7 +1570,8 @@ import WDIORepl from "@wdio/repl";
|
|
|
1566
1570
|
function debug(commandTimeout = 5e3) {
|
|
1567
1571
|
const repl = new WDIORepl();
|
|
1568
1572
|
const { introMessage } = WDIORepl;
|
|
1569
|
-
|
|
1573
|
+
const process3 = globalThis.process;
|
|
1574
|
+
if (!environment.value.variables.WDIO_WORKER_ID || typeof process3.send !== "function") {
|
|
1570
1575
|
console.log(WDIORepl.introMessage);
|
|
1571
1576
|
const context = {
|
|
1572
1577
|
browser: this,
|
|
@@ -1576,8 +1581,8 @@ function debug(commandTimeout = 5e3) {
|
|
|
1576
1581
|
};
|
|
1577
1582
|
return repl.start(context);
|
|
1578
1583
|
}
|
|
1579
|
-
|
|
1580
|
-
|
|
1584
|
+
process3._debugProcess(process3.pid);
|
|
1585
|
+
process3.send({
|
|
1581
1586
|
origin: "debugger",
|
|
1582
1587
|
name: "start",
|
|
1583
1588
|
params: { commandTimeout, introMessage }
|
|
@@ -1587,21 +1592,21 @@ function debug(commandTimeout = 5e3) {
|
|
|
1587
1592
|
() => {
|
|
1588
1593
|
}
|
|
1589
1594
|
);
|
|
1590
|
-
|
|
1595
|
+
process3.on("message", (m) => {
|
|
1591
1596
|
if (m.origin !== "debugger") {
|
|
1592
1597
|
return;
|
|
1593
1598
|
}
|
|
1594
1599
|
if (m.name === "stop") {
|
|
1595
|
-
|
|
1600
|
+
process3._debugEnd(process3.pid);
|
|
1596
1601
|
return commandResolve();
|
|
1597
1602
|
}
|
|
1598
1603
|
if (m.name === "eval") {
|
|
1599
1604
|
repl.eval(m.content.cmd, global, void 0, (err, result) => {
|
|
1600
|
-
if (typeof
|
|
1605
|
+
if (typeof process3.send !== "function") {
|
|
1601
1606
|
return;
|
|
1602
1607
|
}
|
|
1603
1608
|
if (err) {
|
|
1604
|
-
|
|
1609
|
+
process3.send({
|
|
1605
1610
|
origin: "debugger",
|
|
1606
1611
|
name: "result",
|
|
1607
1612
|
params: {
|
|
@@ -1613,7 +1618,7 @@ function debug(commandTimeout = 5e3) {
|
|
|
1613
1618
|
if (typeof result === "function") {
|
|
1614
1619
|
result = `[Function: ${result.name}]`;
|
|
1615
1620
|
}
|
|
1616
|
-
|
|
1621
|
+
process3.send({
|
|
1617
1622
|
origin: "debugger",
|
|
1618
1623
|
name: "result",
|
|
1619
1624
|
params: { result }
|
|
@@ -1690,8 +1695,8 @@ var ClockManager = class {
|
|
|
1690
1695
|
#browser;
|
|
1691
1696
|
#resetFn = () => Promise.resolve();
|
|
1692
1697
|
#isInstalled = false;
|
|
1693
|
-
constructor(
|
|
1694
|
-
this.#browser =
|
|
1698
|
+
constructor(browser) {
|
|
1699
|
+
this.#browser = browser;
|
|
1695
1700
|
}
|
|
1696
1701
|
/**
|
|
1697
1702
|
* Install fake timers on the browser. If you call the `emulate` command, WebdriverIO will automatically install
|
|
@@ -3133,13 +3138,13 @@ var deviceDescriptorsSource = {
|
|
|
3133
3138
|
};
|
|
3134
3139
|
|
|
3135
3140
|
// src/commands/browser/emulate.ts
|
|
3136
|
-
function storeRestoreFunction(
|
|
3137
|
-
if (!restoreFunctions.has(
|
|
3138
|
-
restoreFunctions.set(
|
|
3141
|
+
function storeRestoreFunction(browser, scope, fn) {
|
|
3142
|
+
if (!restoreFunctions.has(browser)) {
|
|
3143
|
+
restoreFunctions.set(browser, /* @__PURE__ */ new Map());
|
|
3139
3144
|
}
|
|
3140
|
-
const restoreFunctionsList = restoreFunctions.get(
|
|
3145
|
+
const restoreFunctionsList = restoreFunctions.get(browser)?.get(scope);
|
|
3141
3146
|
const updatedList = restoreFunctionsList ? [...restoreFunctionsList, fn] : [fn];
|
|
3142
|
-
restoreFunctions.get(
|
|
3147
|
+
restoreFunctions.get(browser)?.set(scope, updatedList);
|
|
3143
3148
|
}
|
|
3144
3149
|
async function emulate(scope, options) {
|
|
3145
3150
|
if (!this.isBidi) {
|
|
@@ -3535,8 +3540,8 @@ async function execute(script, ...args) {
|
|
|
3535
3540
|
throw new Error("number or type of arguments don't agree with execute protocol command");
|
|
3536
3541
|
}
|
|
3537
3542
|
if (this.isBidi && !this.isMultiremote) {
|
|
3538
|
-
const
|
|
3539
|
-
const contextManager = getContextManager(
|
|
3543
|
+
const browser = getBrowserObject4(this);
|
|
3544
|
+
const contextManager = getContextManager(browser);
|
|
3540
3545
|
const context = await contextManager.getCurrentContext();
|
|
3541
3546
|
const userScript = typeof script === "string" ? new Function(script) : script;
|
|
3542
3547
|
const functionDeclaration = createFunctionDeclarationFromString(userScript);
|
|
@@ -3548,7 +3553,7 @@ async function execute(script, ...args) {
|
|
|
3548
3553
|
context
|
|
3549
3554
|
}
|
|
3550
3555
|
};
|
|
3551
|
-
const result = await
|
|
3556
|
+
const result = await browser.scriptCallFunction(params);
|
|
3552
3557
|
return parseScriptResult(params, result);
|
|
3553
3558
|
}
|
|
3554
3559
|
if (typeof script === "function") {
|
|
@@ -3569,8 +3574,8 @@ async function executeAsync(script, ...args) {
|
|
|
3569
3574
|
throw new Error("number or type of arguments don't agree with execute protocol command");
|
|
3570
3575
|
}
|
|
3571
3576
|
if (this.isBidi && !this.isMultiremote) {
|
|
3572
|
-
const
|
|
3573
|
-
const contextManager = getContextManager(
|
|
3577
|
+
const browser = getBrowserObject5(this);
|
|
3578
|
+
const contextManager = getContextManager(browser);
|
|
3574
3579
|
const context = await contextManager.getCurrentContext();
|
|
3575
3580
|
const userScript = typeof script === "string" ? new Function(script) : script;
|
|
3576
3581
|
const functionDeclaration = new Function(`
|
|
@@ -3592,7 +3597,7 @@ async function executeAsync(script, ...args) {
|
|
|
3592
3597
|
context
|
|
3593
3598
|
}
|
|
3594
3599
|
};
|
|
3595
|
-
const result = await
|
|
3600
|
+
const result = await browser.scriptCallFunction(params);
|
|
3596
3601
|
return parseScriptResult(params, result);
|
|
3597
3602
|
}
|
|
3598
3603
|
if (typeof script === "function") {
|
|
@@ -3747,8 +3752,8 @@ async function getPuppeteer() {
|
|
|
3747
3752
|
// src/commands/browser/getWindowSize.ts
|
|
3748
3753
|
import { getBrowserObject as getBrowserObject6 } from "@wdio/utils";
|
|
3749
3754
|
async function getWindowSize() {
|
|
3750
|
-
const
|
|
3751
|
-
const { width, height } = await
|
|
3755
|
+
const browser = getBrowserObject6(this);
|
|
3756
|
+
const { width, height } = await browser.getWindowRect();
|
|
3752
3757
|
return { width, height };
|
|
3753
3758
|
}
|
|
3754
3759
|
|
|
@@ -3897,7 +3902,7 @@ function parseOverwrite(overwrite, request) {
|
|
|
3897
3902
|
const result = {};
|
|
3898
3903
|
if ("body" in overwrite && overwrite.body) {
|
|
3899
3904
|
const bodyOverwrite = typeof overwrite.body === "function" ? overwrite.body(request) : overwrite.body;
|
|
3900
|
-
result.body = bodyOverwrite?.type === "string" || bodyOverwrite?.type === "base64" ? bodyOverwrite : typeof bodyOverwrite === "string" ? { type: "string", value: bodyOverwrite } : { type: "base64", value:
|
|
3905
|
+
result.body = bodyOverwrite?.type === "string" || bodyOverwrite?.type === "base64" ? bodyOverwrite : typeof bodyOverwrite === "string" ? { type: "string", value: bodyOverwrite } : { type: "base64", value: btoa(JSON.stringify(bodyOverwrite || "")) };
|
|
3901
3906
|
}
|
|
3902
3907
|
if ("headers" in overwrite) {
|
|
3903
3908
|
const headersOverwrite = typeof overwrite.headers === "function" ? overwrite.headers(request) : overwrite.headers;
|
|
@@ -3958,18 +3963,18 @@ var WebDriverInterception = class _WebDriverInterception {
|
|
|
3958
3963
|
#respondOverwrites = [];
|
|
3959
3964
|
#calls = [];
|
|
3960
3965
|
#responseBodies = /* @__PURE__ */ new Map();
|
|
3961
|
-
constructor(pattern, mockId, filterOptions,
|
|
3966
|
+
constructor(pattern, mockId, filterOptions, browser) {
|
|
3962
3967
|
this.#pattern = pattern;
|
|
3963
3968
|
this.#mockId = mockId;
|
|
3964
3969
|
this.#filterOptions = filterOptions;
|
|
3965
|
-
this.#browser =
|
|
3966
|
-
|
|
3967
|
-
|
|
3970
|
+
this.#browser = browser;
|
|
3971
|
+
browser.on("network.beforeRequestSent", this.#handleBeforeRequestSent.bind(this));
|
|
3972
|
+
browser.on("network.responseStarted", this.#handleResponseStarted.bind(this));
|
|
3968
3973
|
}
|
|
3969
|
-
static async initiate(url2, filterOptions,
|
|
3974
|
+
static async initiate(url2, filterOptions, browser) {
|
|
3970
3975
|
const pattern = parseUrlPattern(url2);
|
|
3971
3976
|
if (!hasSubscribedToEvents) {
|
|
3972
|
-
await
|
|
3977
|
+
await browser.sessionSubscribe({
|
|
3973
3978
|
events: [
|
|
3974
3979
|
"network.beforeRequestSent",
|
|
3975
3980
|
"network.responseStarted"
|
|
@@ -3978,7 +3983,7 @@ var WebDriverInterception = class _WebDriverInterception {
|
|
|
3978
3983
|
log7.info("subscribed to network events");
|
|
3979
3984
|
hasSubscribedToEvents = true;
|
|
3980
3985
|
}
|
|
3981
|
-
const interception = await
|
|
3986
|
+
const interception = await browser.networkAddIntercept({
|
|
3982
3987
|
phases: ["beforeRequestSent", "responseStarted"],
|
|
3983
3988
|
urlPatterns: [{
|
|
3984
3989
|
type: "pattern",
|
|
@@ -3989,7 +3994,7 @@ var WebDriverInterception = class _WebDriverInterception {
|
|
|
3989
3994
|
search: getPatternParam(pattern, "search")
|
|
3990
3995
|
}]
|
|
3991
3996
|
});
|
|
3992
|
-
return new _WebDriverInterception(pattern, interception.intercept, filterOptions,
|
|
3997
|
+
return new _WebDriverInterception(pattern, interception.intercept, filterOptions, browser);
|
|
3993
3998
|
}
|
|
3994
3999
|
#emit(event, args) {
|
|
3995
4000
|
if (!this.#eventHandler.has(event)) {
|
|
@@ -4318,8 +4323,8 @@ async function mock(url2, filterOptions) {
|
|
|
4318
4323
|
if (!this.isBidi) {
|
|
4319
4324
|
throw new Error("Mocking is only supported when running tests using WebDriver Bidi");
|
|
4320
4325
|
}
|
|
4321
|
-
const
|
|
4322
|
-
const contextManager = getContextManager(
|
|
4326
|
+
const browser = getBrowserObject7(this);
|
|
4327
|
+
const contextManager = getContextManager(browser);
|
|
4323
4328
|
const context = await contextManager.getCurrentContext();
|
|
4324
4329
|
if (!SESSION_MOCKS[context]) {
|
|
4325
4330
|
SESSION_MOCKS[context] = /* @__PURE__ */ new Set();
|
|
@@ -4438,17 +4443,17 @@ import logger13 from "@wdio/logger";
|
|
|
4438
4443
|
// src/session/polyfill.ts
|
|
4439
4444
|
import logger11 from "@wdio/logger";
|
|
4440
4445
|
import { polyfillFn as polyfillFn3 } from "./scripts/polyfill.js";
|
|
4441
|
-
function getPolyfillManager(
|
|
4442
|
-
return SessionManager.getSessionManager(
|
|
4446
|
+
function getPolyfillManager(browser) {
|
|
4447
|
+
return SessionManager.getSessionManager(browser, PolyfillManager);
|
|
4443
4448
|
}
|
|
4444
4449
|
var log11 = logger11("webdriverio:PolyfillManager");
|
|
4445
4450
|
var PolyfillManager = class _PolyfillManager extends SessionManager {
|
|
4446
4451
|
#initialize;
|
|
4447
4452
|
#browser;
|
|
4448
4453
|
#scriptsRegisteredInContexts = /* @__PURE__ */ new Set();
|
|
4449
|
-
constructor(
|
|
4450
|
-
super(
|
|
4451
|
-
this.#browser =
|
|
4454
|
+
constructor(browser) {
|
|
4455
|
+
super(browser, _PolyfillManager.name);
|
|
4456
|
+
this.#browser = browser;
|
|
4452
4457
|
if (!this.isEnabled()) {
|
|
4453
4458
|
this.#initialize = Promise.resolve(true);
|
|
4454
4459
|
return;
|
|
@@ -4497,8 +4502,8 @@ var PolyfillManager = class _PolyfillManager extends SessionManager {
|
|
|
4497
4502
|
import logger12 from "@wdio/logger";
|
|
4498
4503
|
import customElementWrapper from "./scripts/customElement.js";
|
|
4499
4504
|
var log12 = logger12("webdriverio:ShadowRootManager");
|
|
4500
|
-
function getShadowRootManager(
|
|
4501
|
-
return SessionManager.getSessionManager(
|
|
4505
|
+
function getShadowRootManager(browser) {
|
|
4506
|
+
return SessionManager.getSessionManager(browser, ShadowRootManager);
|
|
4502
4507
|
}
|
|
4503
4508
|
var ShadowRootManager = class _ShadowRootManager extends SessionManager {
|
|
4504
4509
|
#browser;
|
|
@@ -4506,9 +4511,9 @@ var ShadowRootManager = class _ShadowRootManager extends SessionManager {
|
|
|
4506
4511
|
#shadowRoots = /* @__PURE__ */ new Map();
|
|
4507
4512
|
#documentElement;
|
|
4508
4513
|
#frameDepth = 0;
|
|
4509
|
-
constructor(
|
|
4510
|
-
super(
|
|
4511
|
-
this.#browser =
|
|
4514
|
+
constructor(browser) {
|
|
4515
|
+
super(browser, _ShadowRootManager.name);
|
|
4516
|
+
this.#browser = browser;
|
|
4512
4517
|
if (!this.isEnabled()) {
|
|
4513
4518
|
this.#initialize = Promise.resolve(true);
|
|
4514
4519
|
return;
|
|
@@ -4763,8 +4768,8 @@ var ShadowRootTree = class _ShadowRootTree {
|
|
|
4763
4768
|
};
|
|
4764
4769
|
|
|
4765
4770
|
// src/session/networkManager.ts
|
|
4766
|
-
function getNetworkManager(
|
|
4767
|
-
return SessionManager.getSessionManager(
|
|
4771
|
+
function getNetworkManager(browser) {
|
|
4772
|
+
return SessionManager.getSessionManager(browser, NetworkManager);
|
|
4768
4773
|
}
|
|
4769
4774
|
var UNKNOWN_NAVIGATION_ID = "UNKNOWN_NAVIGATION_ID";
|
|
4770
4775
|
var SUPPORTED_NAVIGATION_PROTOCOLS = ["http", "https", "data", "file"];
|
|
@@ -4773,9 +4778,9 @@ var NetworkManager = class _NetworkManager extends SessionManager {
|
|
|
4773
4778
|
#initialize;
|
|
4774
4779
|
#requests = /* @__PURE__ */ new Map();
|
|
4775
4780
|
#lastNetworkId;
|
|
4776
|
-
constructor(
|
|
4777
|
-
super(
|
|
4778
|
-
this.#browser =
|
|
4781
|
+
constructor(browser) {
|
|
4782
|
+
super(browser, _NetworkManager.name);
|
|
4783
|
+
this.#browser = browser;
|
|
4779
4784
|
if (!this.isEnabled()) {
|
|
4780
4785
|
this.#initialize = Promise.resolve(true);
|
|
4781
4786
|
return;
|
|
@@ -4953,16 +4958,16 @@ function headerListToObject(headers) {
|
|
|
4953
4958
|
}
|
|
4954
4959
|
|
|
4955
4960
|
// src/session/dialog.ts
|
|
4956
|
-
function getDialogManager(
|
|
4957
|
-
return SessionManager.getSessionManager(
|
|
4961
|
+
function getDialogManager(browser) {
|
|
4962
|
+
return SessionManager.getSessionManager(browser, DialogManager);
|
|
4958
4963
|
}
|
|
4959
4964
|
var DialogManager = class _DialogManager extends SessionManager {
|
|
4960
4965
|
#browser;
|
|
4961
4966
|
#initialize;
|
|
4962
4967
|
#autoHandleDialog = true;
|
|
4963
|
-
constructor(
|
|
4964
|
-
super(
|
|
4965
|
-
this.#browser =
|
|
4968
|
+
constructor(browser) {
|
|
4969
|
+
super(browser, _DialogManager.name);
|
|
4970
|
+
this.#browser = browser;
|
|
4966
4971
|
if (!this.isEnabled()) {
|
|
4967
4972
|
this.#initialize = Promise.resolve(true);
|
|
4968
4973
|
return;
|
|
@@ -5011,12 +5016,12 @@ var Dialog = class {
|
|
|
5011
5016
|
#message;
|
|
5012
5017
|
#defaultValue;
|
|
5013
5018
|
#type;
|
|
5014
|
-
constructor(event,
|
|
5019
|
+
constructor(event, browser) {
|
|
5015
5020
|
this.#message = event.message;
|
|
5016
5021
|
this.#defaultValue = event.defaultValue;
|
|
5017
5022
|
this.#type = event.type;
|
|
5018
5023
|
this.#context = event.context;
|
|
5019
|
-
this.#browser =
|
|
5024
|
+
this.#browser = browser;
|
|
5020
5025
|
}
|
|
5021
5026
|
message() {
|
|
5022
5027
|
return this.#message;
|
|
@@ -5227,8 +5232,8 @@ async function setWindowSize(width, height) {
|
|
|
5227
5232
|
if (width < minWindowSize2 || width > maxWindowSize2 || height < minWindowSize2 || height > maxWindowSize2) {
|
|
5228
5233
|
throw new Error("setWindowSize expects width and height to be a number in the 0 to 2^31 \u2212 1 range");
|
|
5229
5234
|
}
|
|
5230
|
-
const
|
|
5231
|
-
await
|
|
5235
|
+
const browser = getBrowserObject8(this);
|
|
5236
|
+
await browser.setWindowRect(null, null, width, height);
|
|
5232
5237
|
}
|
|
5233
5238
|
|
|
5234
5239
|
// src/commands/browser/switchWindow.ts
|
|
@@ -5307,28 +5312,31 @@ async function switchFrame(context) {
|
|
|
5307
5312
|
return handle;
|
|
5308
5313
|
}
|
|
5309
5314
|
if (typeof context === "string") {
|
|
5310
|
-
const
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5315
|
+
const newContextId = await this.waitUntil(async () => {
|
|
5316
|
+
const tree = await this.browsingContextGetTree({});
|
|
5317
|
+
const urlContext = sessionContext.findContext(context, tree.contexts, "byUrl") || /**
|
|
5318
|
+
* In case the user provides an url without `/` at the end, e.g. `https://example.com`,
|
|
5319
|
+
* the `browsingContextGetTree` command may return a context with the url `https://example.com/`.
|
|
5320
|
+
*/
|
|
5321
|
+
sessionContext.findContext(`${context}/`, tree.contexts, "byUrl");
|
|
5322
|
+
const urlContextContaining = sessionContext.findContext(context, tree.contexts, "byUrlContaining");
|
|
5323
|
+
const contextIdContext = sessionContext.findContext(context, tree.contexts, "byContextId");
|
|
5324
|
+
if (urlContext) {
|
|
5325
|
+
log15.info(`Found context by url "${urlContext.url}" with context id "${urlContext.context}"`);
|
|
5326
|
+
return urlContext.context;
|
|
5327
|
+
} else if (urlContextContaining) {
|
|
5328
|
+
log15.info(`Found context by url containing "${urlContextContaining.url}" with context id "${urlContextContaining.context}"`);
|
|
5329
|
+
return urlContextContaining.context;
|
|
5330
|
+
} else if (contextIdContext) {
|
|
5331
|
+
log15.info(`Found context by id "${contextIdContext}" with url "${contextIdContext.url}"`);
|
|
5332
|
+
return contextIdContext.context;
|
|
5333
|
+
}
|
|
5334
|
+
return false;
|
|
5335
|
+
}, {
|
|
5336
|
+
timeout: this.options.waitforTimeout,
|
|
5337
|
+
interval: this.options.waitforInterval,
|
|
5338
|
+
timeoutMsg: `No frame with url or id "${context}" found within the timeout`
|
|
5339
|
+
});
|
|
5332
5340
|
const currentContext = await sessionContext.getCurrentContext();
|
|
5333
5341
|
const allContexts = await sessionContext.getFlatContextTree();
|
|
5334
5342
|
const allFrames = (await Promise.all(Object.keys(allContexts).map(async (id) => {
|
|
@@ -5410,50 +5418,59 @@ async function switchFrame(context) {
|
|
|
5410
5418
|
return switchToFrameUsingElement(this, element);
|
|
5411
5419
|
}
|
|
5412
5420
|
if (typeof context === "function") {
|
|
5413
|
-
const
|
|
5414
|
-
|
|
5415
|
-
|
|
5416
|
-
const
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
|
|
5420
|
-
|
|
5421
|
-
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5421
|
+
const foundContextId = await this.waitUntil(async () => {
|
|
5422
|
+
const allContexts = await sessionContext.getFlatContextTree();
|
|
5423
|
+
const allContextIds = Object.keys(allContexts);
|
|
5424
|
+
for (const contextId of allContextIds) {
|
|
5425
|
+
const functionDeclaration = new Function(`
|
|
5426
|
+
return (${SCRIPT_PREFIX}${context.toString()}${SCRIPT_SUFFIX}).apply(this, arguments);
|
|
5427
|
+
`).toString();
|
|
5428
|
+
const params = {
|
|
5429
|
+
functionDeclaration,
|
|
5430
|
+
awaitPromise: false,
|
|
5431
|
+
arguments: [],
|
|
5432
|
+
target: { context: contextId }
|
|
5433
|
+
};
|
|
5434
|
+
const result = await this.scriptCallFunction(params).catch((err) => {
|
|
5435
|
+
log15.warn(`switchFrame context callback threw error: ${err.message}`);
|
|
5436
|
+
return void 0;
|
|
5437
|
+
});
|
|
5438
|
+
if (result && result.type === "success" && result.result.type === "boolean" && result.result.value) {
|
|
5439
|
+
return contextId;
|
|
5440
|
+
}
|
|
5428
5441
|
}
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5442
|
+
return false;
|
|
5443
|
+
}, {
|
|
5444
|
+
timeout: this.options.waitforTimeout,
|
|
5445
|
+
interval: this.options.waitforInterval,
|
|
5446
|
+
timeoutMsg: "Could not find the desired frame within the timeout"
|
|
5447
|
+
});
|
|
5448
|
+
await this.switchFrame(null);
|
|
5449
|
+
await this.switchFrame(foundContextId);
|
|
5450
|
+
return foundContextId;
|
|
5434
5451
|
}
|
|
5435
5452
|
throw new Error(
|
|
5436
5453
|
`Invalid type for context parameter: ${typeof context}, expected one of number, string or null. Check out our docs: https://webdriver.io/docs/api/browser/switchFrame.html`
|
|
5437
5454
|
);
|
|
5438
5455
|
}
|
|
5439
|
-
function switchToFrameHelper(
|
|
5440
|
-
const sessionContext = getContextManager(
|
|
5456
|
+
function switchToFrameHelper(browser, context) {
|
|
5457
|
+
const sessionContext = getContextManager(browser);
|
|
5441
5458
|
sessionContext.setCurrentContext(context);
|
|
5442
5459
|
}
|
|
5443
|
-
async function switchToFrameUsingElement(
|
|
5444
|
-
const frame = await
|
|
5460
|
+
async function switchToFrameUsingElement(browser, element) {
|
|
5461
|
+
const frame = await browser.execute(
|
|
5445
5462
|
(iframe) => iframe.contentWindow,
|
|
5446
5463
|
element
|
|
5447
5464
|
);
|
|
5448
|
-
switchToFrameHelper(
|
|
5465
|
+
switchToFrameHelper(browser, frame.context);
|
|
5449
5466
|
const elementId = element[ELEMENT_KEY8];
|
|
5450
|
-
await switchToFrame(
|
|
5467
|
+
await switchToFrame(browser, { [ELEMENT_KEY8]: elementId });
|
|
5451
5468
|
return frame.context;
|
|
5452
5469
|
}
|
|
5453
|
-
function switchToFrame(
|
|
5454
|
-
|
|
5455
|
-
return
|
|
5456
|
-
delete
|
|
5470
|
+
function switchToFrame(browser, frame) {
|
|
5471
|
+
environment.value.variables.DISABLE_WEBDRIVERIO_DEPRECATION_WARNINGS = "true";
|
|
5472
|
+
return browser.switchToFrame(frame).finally(async () => {
|
|
5473
|
+
delete environment.value.variables.DISABLE_WEBDRIVERIO_DEPRECATION_WARNINGS;
|
|
5457
5474
|
});
|
|
5458
5475
|
}
|
|
5459
5476
|
|
|
@@ -5463,8 +5480,8 @@ import { getBrowserObject as getBrowserObject9 } from "@wdio/utils";
|
|
|
5463
5480
|
var log16 = logger16("webdriverio:throttle");
|
|
5464
5481
|
async function throttle(params) {
|
|
5465
5482
|
log16.warn('Command "throttle" is deprecated and will be removed with the next major version release! Use `throttleNetwork` instead.');
|
|
5466
|
-
const
|
|
5467
|
-
await
|
|
5483
|
+
const browser = getBrowserObject9(this);
|
|
5484
|
+
await browser.throttleNetwork(params);
|
|
5468
5485
|
}
|
|
5469
5486
|
|
|
5470
5487
|
// src/commands/browser/throttleCPU.ts
|
|
@@ -5563,8 +5580,8 @@ async function throttleNetwork(params) {
|
|
|
5563
5580
|
throw new Error(`Invalid parameter for "throttleNetwork". Expected it to be typeof object or one of the following values: ${NETWORK_PRESET_TYPES.join(", ")} but found "${params}"`);
|
|
5564
5581
|
}
|
|
5565
5582
|
if (this.isSauce) {
|
|
5566
|
-
const
|
|
5567
|
-
await
|
|
5583
|
+
const browser = getBrowserObject10(this);
|
|
5584
|
+
await browser.sauceThrottleNetwork(params);
|
|
5568
5585
|
return;
|
|
5569
5586
|
}
|
|
5570
5587
|
const failedConnectionMessage = "No Puppeteer connection could be established which is required to use this command";
|
|
@@ -5694,14 +5711,14 @@ function waitUntil(condition, {
|
|
|
5694
5711
|
if (typeof interval !== "number") {
|
|
5695
5712
|
interval = this.options.waitforInterval;
|
|
5696
5713
|
}
|
|
5697
|
-
const
|
|
5714
|
+
const browser = getBrowserObject11(this);
|
|
5698
5715
|
const abort = new AbortController();
|
|
5699
5716
|
const abortOnSessionEnd = (result) => {
|
|
5700
5717
|
if (result.command === "deleteSession") {
|
|
5701
5718
|
abort.abort();
|
|
5702
5719
|
}
|
|
5703
5720
|
};
|
|
5704
|
-
|
|
5721
|
+
browser.on("result", abortOnSessionEnd);
|
|
5705
5722
|
const fn = condition.bind(this);
|
|
5706
5723
|
const timer = new Timer_default(interval, timeout, fn, true, abort.signal);
|
|
5707
5724
|
return timer.catch((e) => {
|
|
@@ -5725,7 +5742,7 @@ function waitUntil(condition, {
|
|
|
5725
5742
|
].filter((errorLine) => !errorLine.includes("/node_modules/webdriverio/") && !errorLine.includes("/node_modules/@wdio/")).join("\n");
|
|
5726
5743
|
throw err;
|
|
5727
5744
|
}).finally(() => {
|
|
5728
|
-
|
|
5745
|
+
browser.off("result", abortOnSessionEnd);
|
|
5729
5746
|
});
|
|
5730
5747
|
}
|
|
5731
5748
|
|
|
@@ -5749,8 +5766,8 @@ var SWIPE_DEFAULTS = {
|
|
|
5749
5766
|
PERCENT: 0.95
|
|
5750
5767
|
};
|
|
5751
5768
|
async function swipe(options) {
|
|
5752
|
-
const
|
|
5753
|
-
if (!
|
|
5769
|
+
const browser = this;
|
|
5770
|
+
if (!browser.isNativeContext) {
|
|
5754
5771
|
throw new Error("The swipe command is only available for mobile platforms in the NATIVE context.");
|
|
5755
5772
|
}
|
|
5756
5773
|
let { scrollableElement, from, to } = options || {};
|
|
@@ -5758,18 +5775,18 @@ async function swipe(options) {
|
|
|
5758
5775
|
log17.warn("`scrollableElement` is provided, so `from` and `to` will be ignored.");
|
|
5759
5776
|
}
|
|
5760
5777
|
if (!from || !to) {
|
|
5761
|
-
scrollableElement = scrollableElement || await getScrollableElement(
|
|
5778
|
+
scrollableElement = scrollableElement || await getScrollableElement(browser);
|
|
5762
5779
|
({ from, to } = await calculateFromTo({
|
|
5763
|
-
browser
|
|
5780
|
+
browser,
|
|
5764
5781
|
direction: options?.direction || SWIPE_DEFAULTS.DIRECTION,
|
|
5765
5782
|
percentage: options?.percent,
|
|
5766
5783
|
scrollableElement
|
|
5767
5784
|
}));
|
|
5768
5785
|
}
|
|
5769
|
-
return w3cSwipe({ browser
|
|
5786
|
+
return w3cSwipe({ browser, duration: options?.duration || SWIPE_DEFAULTS.DURATION, from, to });
|
|
5770
5787
|
}
|
|
5771
5788
|
async function calculateFromTo({
|
|
5772
|
-
browser
|
|
5789
|
+
browser,
|
|
5773
5790
|
direction,
|
|
5774
5791
|
percentage,
|
|
5775
5792
|
scrollableElement
|
|
@@ -5784,7 +5801,7 @@ async function calculateFromTo({
|
|
|
5784
5801
|
swipePercentage = percentage;
|
|
5785
5802
|
}
|
|
5786
5803
|
}
|
|
5787
|
-
const { x, y, width, height } = await
|
|
5804
|
+
const { x, y, width, height } = await browser.getElementRect(await scrollableElement?.elementId);
|
|
5788
5805
|
const verticalOffset = height - height * swipePercentage;
|
|
5789
5806
|
const horizontalOffset = width - width * swipePercentage;
|
|
5790
5807
|
const scrollRectangles = {
|
|
@@ -5817,35 +5834,35 @@ async function calculateFromTo({
|
|
|
5817
5834
|
}
|
|
5818
5835
|
return { from, to };
|
|
5819
5836
|
}
|
|
5820
|
-
async function getScrollableElement(
|
|
5837
|
+
async function getScrollableElement(browser) {
|
|
5821
5838
|
const defaultAndroidSelector = "//android.widget.ScrollView";
|
|
5822
5839
|
const defaultIosSelector = '-ios predicate string:type == "XCUIElementTypeApplication"';
|
|
5823
|
-
const selector =
|
|
5840
|
+
const selector = browser.isIOS ? (
|
|
5824
5841
|
// For iOS, we need to find the application element, if we can't find it, we should throw an error
|
|
5825
5842
|
defaultIosSelector
|
|
5826
5843
|
) : (
|
|
5827
5844
|
// There is always a scrollview for Android or, if this fails we should throw an error
|
|
5828
5845
|
defaultAndroidSelector
|
|
5829
5846
|
);
|
|
5830
|
-
const scrollableElements = await
|
|
5847
|
+
const scrollableElements = await browser.$$(
|
|
5831
5848
|
selector
|
|
5832
5849
|
);
|
|
5833
5850
|
if (scrollableElements.length > 0) {
|
|
5834
5851
|
return scrollableElements[0];
|
|
5835
5852
|
}
|
|
5836
5853
|
throw new Error(
|
|
5837
|
-
`Default scrollable element '${
|
|
5854
|
+
`Default scrollable element '${browser.isIOS ? defaultIosSelector : defaultAndroidSelector}' was not found. Our advice is to provide a scrollable element like this:
|
|
5838
5855
|
|
|
5839
5856
|
await browser.swipe({ scrollableElement: $('#scrollable') });
|
|
5840
5857
|
|
|
5841
5858
|
`
|
|
5842
5859
|
);
|
|
5843
5860
|
}
|
|
5844
|
-
async function w3cSwipe({ browser
|
|
5845
|
-
await
|
|
5846
|
-
parameters: { pointerType:
|
|
5861
|
+
async function w3cSwipe({ browser, duration, from, to }) {
|
|
5862
|
+
await browser.action("pointer", {
|
|
5863
|
+
parameters: { pointerType: browser.isMobile ? "touch" : "mouse" }
|
|
5847
5864
|
}).move(from.x, from.y).down().pause(10).move({ duration, x: to.x, y: to.y }).up().perform();
|
|
5848
|
-
return
|
|
5865
|
+
return browser.pause(500);
|
|
5849
5866
|
}
|
|
5850
5867
|
|
|
5851
5868
|
// src/commands/mobile/tap.ts
|
|
@@ -5855,18 +5872,18 @@ var log18 = logger18("webdriver");
|
|
|
5855
5872
|
async function tap(options) {
|
|
5856
5873
|
const isElement2 = this.selector !== void 0;
|
|
5857
5874
|
const element = isElement2 ? this : null;
|
|
5858
|
-
const
|
|
5859
|
-
if (!
|
|
5875
|
+
const browser = isElement2 ? getBrowserObject12(this) : this;
|
|
5876
|
+
if (!browser.isMobile) {
|
|
5860
5877
|
throw new Error("The tap command is only available for mobile platforms.");
|
|
5861
5878
|
}
|
|
5862
5879
|
validateTapOptions(options);
|
|
5863
5880
|
if (element) {
|
|
5864
|
-
return await elementTap(
|
|
5881
|
+
return await elementTap(browser, element, options);
|
|
5865
5882
|
}
|
|
5866
5883
|
if (!options || options.x === void 0 || options.y === void 0) {
|
|
5867
5884
|
throw new Error("The tap command requires x and y coordinates to be set for screen taps.");
|
|
5868
5885
|
}
|
|
5869
|
-
return await screenTap(
|
|
5886
|
+
return await screenTap(browser, options);
|
|
5870
5887
|
}
|
|
5871
5888
|
function validateTapOptions(options) {
|
|
5872
5889
|
if (options) {
|
|
@@ -5892,9 +5909,9 @@ function validateTapOptions(options) {
|
|
|
5892
5909
|
}
|
|
5893
5910
|
}
|
|
5894
5911
|
}
|
|
5895
|
-
async function elementTap(
|
|
5896
|
-
if (
|
|
5897
|
-
return await nativeTap(element,
|
|
5912
|
+
async function elementTap(browser, element, options) {
|
|
5913
|
+
if (browser.isNativeContext) {
|
|
5914
|
+
return await nativeTap(element, browser, options);
|
|
5898
5915
|
}
|
|
5899
5916
|
if (options) {
|
|
5900
5917
|
log18.warn("The options object is not supported in Web environments and will be ignored.");
|
|
@@ -5904,18 +5921,18 @@ async function elementTap(browser2, element, options) {
|
|
|
5904
5921
|
async function webTap(element) {
|
|
5905
5922
|
return element.click();
|
|
5906
5923
|
}
|
|
5907
|
-
async function executeNativeTap(
|
|
5908
|
-
return await
|
|
5909
|
-
`mobile: ${
|
|
5910
|
-
{ ...
|
|
5924
|
+
async function executeNativeTap(browser, options) {
|
|
5925
|
+
return await browser.execute(
|
|
5926
|
+
`mobile: ${browser.isIOS ? "tap" : "clickGesture"}`,
|
|
5927
|
+
{ ...browser.isIOS ? { x: 0, y: 0 } : {}, ...options }
|
|
5911
5928
|
);
|
|
5912
5929
|
}
|
|
5913
|
-
async function nativeTap(element,
|
|
5930
|
+
async function nativeTap(element, browser, options = {}) {
|
|
5914
5931
|
try {
|
|
5915
5932
|
if (!element.elementId) {
|
|
5916
5933
|
throw new Error("no such element");
|
|
5917
5934
|
}
|
|
5918
|
-
return await executeNativeTap(
|
|
5935
|
+
return await executeNativeTap(browser, { elementId: element.elementId });
|
|
5919
5936
|
} catch (error) {
|
|
5920
5937
|
let err = error;
|
|
5921
5938
|
if (typeof error === "string") {
|
|
@@ -5933,7 +5950,7 @@ async function nativeTap(element, browser2, options = {}) {
|
|
|
5933
5950
|
);
|
|
5934
5951
|
try {
|
|
5935
5952
|
await element.scrollIntoView(scrollIntoViewOptions);
|
|
5936
|
-
return await executeNativeTap(
|
|
5953
|
+
return await executeNativeTap(browser, { elementId: element.elementId });
|
|
5937
5954
|
} catch (scrollError) {
|
|
5938
5955
|
let err2 = scrollError;
|
|
5939
5956
|
if (typeof scrollError === "string") {
|
|
@@ -5964,12 +5981,12 @@ await elem.tap({
|
|
|
5964
5981
|
}
|
|
5965
5982
|
}
|
|
5966
5983
|
}
|
|
5967
|
-
async function screenTap(
|
|
5984
|
+
async function screenTap(browser, options) {
|
|
5968
5985
|
const { x, y } = options;
|
|
5969
|
-
if (
|
|
5970
|
-
return await executeNativeTap(
|
|
5986
|
+
if (browser.isNativeContext) {
|
|
5987
|
+
return await executeNativeTap(browser, options);
|
|
5971
5988
|
}
|
|
5972
|
-
return await
|
|
5989
|
+
return await browser.action(
|
|
5973
5990
|
"pointer",
|
|
5974
5991
|
{
|
|
5975
5992
|
parameters: { pointerType: "touch" }
|
|
@@ -5981,19 +5998,19 @@ async function screenTap(browser2, options) {
|
|
|
5981
5998
|
import logger19 from "@wdio/logger";
|
|
5982
5999
|
var log19 = logger19("webdriver");
|
|
5983
6000
|
async function getContext(options) {
|
|
5984
|
-
const
|
|
5985
|
-
if (!
|
|
6001
|
+
const browser = this;
|
|
6002
|
+
if (!browser.isMobile) {
|
|
5986
6003
|
throw new Error("The `getContext` command is only available for mobile platforms.");
|
|
5987
6004
|
}
|
|
5988
|
-
const currentAppiumContext = await
|
|
6005
|
+
const currentAppiumContext = await browser.getAppiumContext();
|
|
5989
6006
|
if (!options || !options?.returnDetailedContext || currentAppiumContext === "NATIVE_APP") {
|
|
5990
6007
|
return currentAppiumContext;
|
|
5991
6008
|
}
|
|
5992
6009
|
delete options.returnDetailedContext;
|
|
5993
|
-
return getDetailedContext(
|
|
6010
|
+
return getDetailedContext(browser, currentAppiumContext, options);
|
|
5994
6011
|
}
|
|
5995
|
-
async function getDetailedContext(
|
|
5996
|
-
const detailedContexts = await
|
|
6012
|
+
async function getDetailedContext(browser, currentAppiumContext, options) {
|
|
6013
|
+
const detailedContexts = await browser.getContexts({
|
|
5997
6014
|
...{ options },
|
|
5998
6015
|
// Defaults
|
|
5999
6016
|
returnDetailedContexts: true,
|
|
@@ -6020,13 +6037,13 @@ async function getDetailedContext(browser2, currentAppiumContext, options) {
|
|
|
6020
6037
|
import logger20 from "@wdio/logger";
|
|
6021
6038
|
var log20 = logger20("webdriver");
|
|
6022
6039
|
async function getContexts(options) {
|
|
6023
|
-
const
|
|
6024
|
-
if (!
|
|
6040
|
+
const browser = this;
|
|
6041
|
+
if (!browser.isMobile) {
|
|
6025
6042
|
throw new Error("The `getContexts` command is only available for mobile platforms.");
|
|
6026
6043
|
}
|
|
6027
6044
|
if (!options || !options.returnDetailedContexts) {
|
|
6028
6045
|
log20.info("The standard Appium `contexts` method is used. If you want to get more detailed data, you can set `returnDetailedContexts` to `true`.");
|
|
6029
|
-
return
|
|
6046
|
+
return browser.getAppiumContexts();
|
|
6030
6047
|
}
|
|
6031
6048
|
const defaultOptions = {
|
|
6032
6049
|
androidWebviewConnectionRetryTime: 500,
|
|
@@ -6035,7 +6052,7 @@ async function getContexts(options) {
|
|
|
6035
6052
|
isAndroidWebviewVisible: true,
|
|
6036
6053
|
returnAndroidDescriptionData: false
|
|
6037
6054
|
};
|
|
6038
|
-
return getCurrentContexts({ browser
|
|
6055
|
+
return getCurrentContexts({ browser, ...{ ...defaultOptions, ...options } });
|
|
6039
6056
|
}
|
|
6040
6057
|
var CHROME_PACKAGE_NAME = "com.android.chrome";
|
|
6041
6058
|
async function parsedAndroidContexts({
|
|
@@ -6102,18 +6119,18 @@ async function parsedAndroidContexts({
|
|
|
6102
6119
|
return result;
|
|
6103
6120
|
}
|
|
6104
6121
|
async function getCurrentContexts({
|
|
6105
|
-
browser
|
|
6122
|
+
browser,
|
|
6106
6123
|
androidWebviewConnectionRetryTime,
|
|
6107
6124
|
androidWebviewConnectTimeout,
|
|
6108
6125
|
filterByCurrentAndroidApp,
|
|
6109
6126
|
isAndroidWebviewVisible,
|
|
6110
6127
|
returnAndroidDescriptionData
|
|
6111
6128
|
}) {
|
|
6112
|
-
const contexts = await
|
|
6113
|
-
if (
|
|
6129
|
+
const contexts = await browser.execute("mobile: getContexts");
|
|
6130
|
+
if (browser.isIOS) {
|
|
6114
6131
|
return contexts;
|
|
6115
6132
|
}
|
|
6116
|
-
const packageName = await
|
|
6133
|
+
const packageName = await browser.getCurrentPackage();
|
|
6117
6134
|
const startTime = Date.now();
|
|
6118
6135
|
const retryInterval = androidWebviewConnectionRetryTime;
|
|
6119
6136
|
let isPackageNameMissing = false;
|
|
@@ -6152,8 +6169,8 @@ async function getCurrentContexts({
|
|
|
6152
6169
|
import logger21 from "@wdio/logger";
|
|
6153
6170
|
var log21 = logger21("webdriver");
|
|
6154
6171
|
async function switchContext(options) {
|
|
6155
|
-
const
|
|
6156
|
-
if (!
|
|
6172
|
+
const browser = this;
|
|
6173
|
+
if (!browser.isMobile) {
|
|
6157
6174
|
throw new Error("The `switchContext` command is only available for mobile platforms.");
|
|
6158
6175
|
}
|
|
6159
6176
|
if (!options) {
|
|
@@ -6161,14 +6178,14 @@ async function switchContext(options) {
|
|
|
6161
6178
|
}
|
|
6162
6179
|
if (typeof options === "string") {
|
|
6163
6180
|
log21.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.");
|
|
6164
|
-
return
|
|
6181
|
+
return browser.switchAppiumContext(options);
|
|
6165
6182
|
}
|
|
6166
6183
|
if (!options.title && !options.url) {
|
|
6167
6184
|
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.");
|
|
6168
6185
|
}
|
|
6169
|
-
return switchToContext({ browser
|
|
6186
|
+
return switchToContext({ browser, options });
|
|
6170
6187
|
}
|
|
6171
|
-
async function switchToContext({ browser
|
|
6188
|
+
async function switchToContext({ browser, options }) {
|
|
6172
6189
|
const getContextsOptions = {
|
|
6173
6190
|
returnDetailedContexts: true,
|
|
6174
6191
|
filterByCurrentAndroidApp: false,
|
|
@@ -6177,19 +6194,19 @@ async function switchToContext({ browser: browser2, options }) {
|
|
|
6177
6194
|
...options?.androidWebviewConnectionRetryTime && { androidWebviewConnectionRetryTime: options.androidWebviewConnectionRetryTime },
|
|
6178
6195
|
...options?.androidWebviewConnectTimeout && { androidWebviewConnectTimeout: options.androidWebviewConnectTimeout }
|
|
6179
6196
|
};
|
|
6180
|
-
const contexts = await
|
|
6181
|
-
const identifier =
|
|
6182
|
-
const { matchingContext, reasons } = findMatchingContext({ browser
|
|
6197
|
+
const contexts = await browser.getContexts(getContextsOptions);
|
|
6198
|
+
const identifier = browser.isIOS ? (await browser.execute("mobile: activeAppInfo"))?.bundleId : await browser.getCurrentPackage();
|
|
6199
|
+
const { matchingContext, reasons } = findMatchingContext({ browser, contexts, identifier, ...options?.title && { title: options.title }, ...options?.url && { url: options.url } });
|
|
6183
6200
|
if (!matchingContext) {
|
|
6184
6201
|
throw new Error(reasons.join("\n"));
|
|
6185
6202
|
}
|
|
6186
6203
|
log21.info("WebdriverIO found a matching context:", JSON.stringify(matchingContext, null, 2));
|
|
6187
|
-
if (!
|
|
6204
|
+
if (!browser.isIOS) {
|
|
6188
6205
|
const webviewName = `WEBVIEW_${identifier}`;
|
|
6189
|
-
await
|
|
6206
|
+
await browser.switchAppiumContext(webviewName);
|
|
6190
6207
|
}
|
|
6191
|
-
const switchFunction =
|
|
6192
|
-
const matchingContextId =
|
|
6208
|
+
const switchFunction = browser.isIOS ? browser.switchAppiumContext.bind(browser) : browser.switchToWindow.bind(browser);
|
|
6209
|
+
const matchingContextId = browser.isIOS ? matchingContext.id : matchingContext.webviewPageId;
|
|
6193
6210
|
return switchFunction(matchingContextId);
|
|
6194
6211
|
}
|
|
6195
6212
|
function findMatchingContext({
|
|
@@ -6230,42 +6247,42 @@ function findMatchingContext({
|
|
|
6230
6247
|
|
|
6231
6248
|
// src/commands/mobile/relaunchActiveApp.ts
|
|
6232
6249
|
async function relaunchActiveApp() {
|
|
6233
|
-
const
|
|
6234
|
-
if (!
|
|
6250
|
+
const browser = this;
|
|
6251
|
+
if (!browser.isMobile) {
|
|
6235
6252
|
throw new Error("The `relaunchActiveApp` command is only available for mobile platforms.");
|
|
6236
6253
|
}
|
|
6237
|
-
if (
|
|
6238
|
-
const { bundleId, processArguments: { args, env } } = await
|
|
6254
|
+
if (browser.isIOS) {
|
|
6255
|
+
const { bundleId, processArguments: { args, env } } = await browser.execute("mobile: activeAppInfo");
|
|
6239
6256
|
const iOSLaunchOptions = {
|
|
6240
6257
|
bundleId,
|
|
6241
6258
|
...args.length > 0 && { arguments: args },
|
|
6242
6259
|
...Object.keys(env).length > 0 && { environment: env }
|
|
6243
6260
|
};
|
|
6244
|
-
await
|
|
6245
|
-
return
|
|
6261
|
+
await browser.execute("mobile: terminateApp", { bundleId });
|
|
6262
|
+
return browser.execute("mobile:launchApp", iOSLaunchOptions);
|
|
6246
6263
|
}
|
|
6247
|
-
const packageName = await
|
|
6248
|
-
await
|
|
6249
|
-
return
|
|
6264
|
+
const packageName = await browser.getCurrentPackage();
|
|
6265
|
+
await browser.execute("mobile: terminateApp", { appId: packageName });
|
|
6266
|
+
return browser.execute("mobile: activateApp", { appId: packageName });
|
|
6250
6267
|
}
|
|
6251
6268
|
|
|
6252
6269
|
// src/commands/mobile/deepLink.ts
|
|
6253
6270
|
async function deepLink(link, appIdentifier) {
|
|
6254
|
-
const
|
|
6255
|
-
if (!
|
|
6271
|
+
const browser = this;
|
|
6272
|
+
if (!browser.isMobile) {
|
|
6256
6273
|
throw new Error("The `deepLink` command is only available for mobile platforms.");
|
|
6257
6274
|
}
|
|
6258
6275
|
if (!isDeepLinkUrl(link)) {
|
|
6259
|
-
throw new Error(`The provided link is not a valid deep link URL.${
|
|
6276
|
+
throw new Error(`The provided link is not a valid deep link URL.${browser.isIOS ? " If your url is a `universal deep link` then use the `url` command instead." : ""}`);
|
|
6260
6277
|
}
|
|
6261
6278
|
if (!appIdentifier) {
|
|
6262
|
-
const mobileOS =
|
|
6263
|
-
const identifierValue =
|
|
6279
|
+
const mobileOS = browser.isIOS ? "iOS" : "Android";
|
|
6280
|
+
const identifierValue = browser.isIOS ? "bundleId" : "package";
|
|
6264
6281
|
throw new Error(`When using a deep link URL for ${mobileOS}, you need to provide the \`${identifierValue}\` of the app that the deep link should open.`);
|
|
6265
6282
|
}
|
|
6266
|
-
return
|
|
6283
|
+
return browser.execute("mobile:deepLink", {
|
|
6267
6284
|
url: link,
|
|
6268
|
-
[
|
|
6285
|
+
[browser.isIOS ? "bundleId" : "package"]: appIdentifier
|
|
6269
6286
|
});
|
|
6270
6287
|
}
|
|
6271
6288
|
function isDeepLinkUrl(link) {
|
|
@@ -6406,9 +6423,9 @@ async function actionClick(element, options) {
|
|
|
6406
6423
|
if (!buttonValue.includes(button)) {
|
|
6407
6424
|
throw new Error("Button type not supported.");
|
|
6408
6425
|
}
|
|
6409
|
-
const
|
|
6426
|
+
const browser = getBrowserObject13(element);
|
|
6410
6427
|
if (x || y) {
|
|
6411
|
-
const { width, height } = await
|
|
6428
|
+
const { width, height } = await browser.getElementRect(element.elementId);
|
|
6412
6429
|
if (x && x < -Math.floor(width / 2) || x && x > Math.floor(width / 2)) {
|
|
6413
6430
|
log22.warn("x would cause a out of bounds error as it goes outside of element");
|
|
6414
6431
|
}
|
|
@@ -6417,8 +6434,8 @@ async function actionClick(element, options) {
|
|
|
6417
6434
|
}
|
|
6418
6435
|
}
|
|
6419
6436
|
const clickNested = async () => {
|
|
6420
|
-
await
|
|
6421
|
-
parameters: { pointerType:
|
|
6437
|
+
await browser.action("pointer", {
|
|
6438
|
+
parameters: { pointerType: browser.isMobile ? "touch" : "mouse" }
|
|
6422
6439
|
}).move({ origin: element, x, y }).down({ button }).pause(duration).up({ button }).perform(skipRelease);
|
|
6423
6440
|
};
|
|
6424
6441
|
try {
|
|
@@ -6477,8 +6494,8 @@ async function custom$2(strategyName, ...strategyArguments) {
|
|
|
6477
6494
|
// src/commands/element/doubleClick.ts
|
|
6478
6495
|
import { getBrowserObject as getBrowserObject16 } from "@wdio/utils";
|
|
6479
6496
|
async function doubleClick() {
|
|
6480
|
-
const
|
|
6481
|
-
return
|
|
6497
|
+
const browser = getBrowserObject16(this);
|
|
6498
|
+
return browser.action("pointer", { parameters: { pointerType: "mouse" } }).move({ origin: this }).down().up().pause(10).down().up().perform();
|
|
6482
6499
|
}
|
|
6483
6500
|
|
|
6484
6501
|
// src/commands/element/dragAndDrop.ts
|
|
@@ -6502,8 +6519,8 @@ async function dragAndDrop(target, options = {}) {
|
|
|
6502
6519
|
throw new Error('command dragAndDrop requires an WebdriverIO Element or and object with "x" and "y" variables as first parameter');
|
|
6503
6520
|
}
|
|
6504
6521
|
const ACTION_BUTTON = 0;
|
|
6505
|
-
const
|
|
6506
|
-
const defaultOptions = { duration:
|
|
6522
|
+
const browser = getBrowserObject17(this);
|
|
6523
|
+
const defaultOptions = { duration: browser.isMobile ? 250 : 10 };
|
|
6507
6524
|
const { duration } = { ...defaultOptions, ...options };
|
|
6508
6525
|
const isMovingToElement = moveToElement.constructor.name === "Element";
|
|
6509
6526
|
const sourceRef = { [ELEMENT_KEY11]: this[ELEMENT_KEY11] };
|
|
@@ -6512,8 +6529,8 @@ async function dragAndDrop(target, options = {}) {
|
|
|
6512
6529
|
const targetOrigin = isMovingToElement ? targetRef : "pointer";
|
|
6513
6530
|
const targetX = isMovingToElement ? 0 : moveToCoordinates.x;
|
|
6514
6531
|
const targetY = isMovingToElement ? 0 : moveToCoordinates.y;
|
|
6515
|
-
return
|
|
6516
|
-
parameters: { pointerType:
|
|
6532
|
+
return browser.action("pointer", {
|
|
6533
|
+
parameters: { pointerType: browser.isMobile ? "touch" : "mouse" }
|
|
6517
6534
|
}).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();
|
|
6518
6535
|
}
|
|
6519
6536
|
|
|
@@ -6521,17 +6538,17 @@ async function dragAndDrop(target, options = {}) {
|
|
|
6521
6538
|
import { getBrowserObject as getBrowserObject18 } from "@wdio/utils";
|
|
6522
6539
|
async function execute2(script, ...args) {
|
|
6523
6540
|
const scope = this;
|
|
6524
|
-
const
|
|
6541
|
+
const browser = getBrowserObject18(scope);
|
|
6525
6542
|
await scope.waitForExist();
|
|
6526
|
-
return
|
|
6543
|
+
return browser.execute(script, scope, ...args);
|
|
6527
6544
|
}
|
|
6528
6545
|
|
|
6529
6546
|
// src/commands/element/executeAsync.ts
|
|
6530
6547
|
import { getBrowserObject as getBrowserObject19 } from "@wdio/utils";
|
|
6531
6548
|
async function executeAsync2(script, ...args) {
|
|
6532
6549
|
const scope = this;
|
|
6533
|
-
const
|
|
6534
|
-
return
|
|
6550
|
+
const browser = getBrowserObject19(scope);
|
|
6551
|
+
return browser.executeAsync(script, scope, ...args);
|
|
6535
6552
|
}
|
|
6536
6553
|
|
|
6537
6554
|
// src/commands/element/getAttribute.ts
|
|
@@ -6605,9 +6622,9 @@ function mergeEqualSymmetricalValue(cssValues) {
|
|
|
6605
6622
|
return newCssValues.join(" ");
|
|
6606
6623
|
}
|
|
6607
6624
|
async function getPseudoElementCSSValue(elem, options) {
|
|
6608
|
-
const
|
|
6625
|
+
const browser = getBrowserObject20(elem);
|
|
6609
6626
|
const { cssProperty, pseudoElement } = options;
|
|
6610
|
-
const cssValue2 = await
|
|
6627
|
+
const cssValue2 = await browser.execute(
|
|
6611
6628
|
(elem2, pseudoElement2, cssProperty2) => window.getComputedStyle(elem2, pseudoElement2)[cssProperty2],
|
|
6612
6629
|
elem,
|
|
6613
6630
|
pseudoElement,
|
|
@@ -6640,7 +6657,7 @@ import getHTMLShadowScript from "./scripts/getHTMLShadow.js";
|
|
|
6640
6657
|
var SHADOW_ID_ATTR_NAME = "data-wdio-shadow-id";
|
|
6641
6658
|
var SHADOW_ID_ATTR = `[${SHADOW_ID_ATTR_NAME}]`;
|
|
6642
6659
|
async function getHTML(options = {}) {
|
|
6643
|
-
const
|
|
6660
|
+
const browser = getBrowserObject21(this);
|
|
6644
6661
|
if (typeof options !== "object" && typeof options === "boolean") {
|
|
6645
6662
|
options = { includeSelectorTag: options };
|
|
6646
6663
|
} else if (typeof options !== "object") {
|
|
@@ -6654,7 +6671,7 @@ async function getHTML(options = {}) {
|
|
|
6654
6671
|
excludeElements: []
|
|
6655
6672
|
}, options);
|
|
6656
6673
|
const basicGetHTML = (elementId, includeSelectorTag2) => {
|
|
6657
|
-
return
|
|
6674
|
+
return browser.execute(getHTMLScript, {
|
|
6658
6675
|
[ELEMENT_KEY12]: elementId,
|
|
6659
6676
|
// w3c compatible
|
|
6660
6677
|
ELEMENT: elementId
|
|
@@ -6670,12 +6687,12 @@ async function getHTML(options = {}) {
|
|
|
6670
6687
|
);
|
|
6671
6688
|
}
|
|
6672
6689
|
const { load } = await import("cheerio");
|
|
6673
|
-
const shadowRootManager = getShadowRootManager(
|
|
6674
|
-
const contextManager = getContextManager(
|
|
6690
|
+
const shadowRootManager = getShadowRootManager(browser);
|
|
6691
|
+
const contextManager = getContextManager(browser);
|
|
6675
6692
|
const context = await contextManager.getCurrentContext();
|
|
6676
6693
|
const shadowRootElementPairs = shadowRootManager.getShadowElementPairsByContextId(context, this.elementId);
|
|
6677
6694
|
const elementsWithShadowRootAndIdVerified = (await Promise.all(
|
|
6678
|
-
shadowRootElementPairs.map(([elemId, elem]) =>
|
|
6695
|
+
shadowRootElementPairs.map(([elemId, elem]) => browser.execute((elem2) => elem2.tagName, { [ELEMENT_KEY12]: elemId }).then(
|
|
6679
6696
|
() => [elemId, elem],
|
|
6680
6697
|
() => void 0
|
|
6681
6698
|
))
|
|
@@ -6793,8 +6810,8 @@ async function isClickable() {
|
|
|
6793
6810
|
if (this.isMobile && this.isNativeContext) {
|
|
6794
6811
|
throw new Error("Method not supported in mobile native environment. It is unlikely that you need to use this command.");
|
|
6795
6812
|
}
|
|
6796
|
-
const
|
|
6797
|
-
return
|
|
6813
|
+
const browser = getBrowserObject22(this);
|
|
6814
|
+
return browser.execute(isElementClickableScript, {
|
|
6798
6815
|
[ELEMENT_KEY13]: this.elementId,
|
|
6799
6816
|
// w3c compatible
|
|
6800
6817
|
ELEMENT: this.elementId
|
|
@@ -6807,11 +6824,11 @@ import { getBrowserObject as getBrowserObject23 } from "@wdio/utils";
|
|
|
6807
6824
|
import isElementDisplayedLegacyScript from "./scripts/isElementDisplayed.js";
|
|
6808
6825
|
import isElementInViewportScript from "./scripts/isElementInViewport.js";
|
|
6809
6826
|
async function isDisplayed(commandParams = DEFAULT_PARAMS) {
|
|
6810
|
-
const
|
|
6827
|
+
const browser = getBrowserObject23(this);
|
|
6811
6828
|
if (!await hasElementId(this)) {
|
|
6812
6829
|
return false;
|
|
6813
6830
|
}
|
|
6814
|
-
if (
|
|
6831
|
+
if (browser.isMobile && (browser.isNativeContext || browser.isWindowsApp || browser.isMacApp)) {
|
|
6815
6832
|
if (commandParams?.withinViewport) {
|
|
6816
6833
|
throw new Error(
|
|
6817
6834
|
"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."
|
|
@@ -6821,7 +6838,7 @@ async function isDisplayed(commandParams = DEFAULT_PARAMS) {
|
|
|
6821
6838
|
}
|
|
6822
6839
|
let hadToFallback = false;
|
|
6823
6840
|
const [isDisplayed2, displayProperty] = await Promise.all([
|
|
6824
|
-
|
|
6841
|
+
browser.execute(function checkVisibility(elem, params) {
|
|
6825
6842
|
if (typeof elem.checkVisibility === "function") {
|
|
6826
6843
|
return elem.checkVisibility(params);
|
|
6827
6844
|
}
|
|
@@ -6832,7 +6849,7 @@ async function isDisplayed(commandParams = DEFAULT_PARAMS) {
|
|
|
6832
6849
|
}).then((result) => {
|
|
6833
6850
|
if (result === null) {
|
|
6834
6851
|
hadToFallback = true;
|
|
6835
|
-
return
|
|
6852
|
+
return browser.execute(isElementDisplayedLegacyScript, this);
|
|
6836
6853
|
}
|
|
6837
6854
|
return result;
|
|
6838
6855
|
}),
|
|
@@ -6843,9 +6860,9 @@ async function isDisplayed(commandParams = DEFAULT_PARAMS) {
|
|
|
6843
6860
|
]);
|
|
6844
6861
|
const hasDisplayContentsCSSProperty = displayProperty.value === "contents";
|
|
6845
6862
|
const shouldRecheckContentVisibility = !hadToFallback && hasDisplayContentsCSSProperty;
|
|
6846
|
-
const finalResponse = shouldRecheckContentVisibility ? await
|
|
6863
|
+
const finalResponse = shouldRecheckContentVisibility ? await browser.execute(isElementDisplayedLegacyScript, this).catch(() => false) : isDisplayed2;
|
|
6847
6864
|
if (finalResponse && commandParams?.withinViewport) {
|
|
6848
|
-
return
|
|
6865
|
+
return browser.execute(isElementInViewportScript, this);
|
|
6849
6866
|
}
|
|
6850
6867
|
return finalResponse;
|
|
6851
6868
|
}
|
|
@@ -6871,9 +6888,9 @@ var getWebElement = (el) => ({
|
|
|
6871
6888
|
// jsonwp compatible
|
|
6872
6889
|
});
|
|
6873
6890
|
async function isEqual(el) {
|
|
6874
|
-
const
|
|
6875
|
-
if (
|
|
6876
|
-
const context = await
|
|
6891
|
+
const browser = getBrowserObject24(this);
|
|
6892
|
+
if (browser.isMobile) {
|
|
6893
|
+
const context = await browser.getContext().catch(() => void 0);
|
|
6877
6894
|
const contextId = typeof context === "string" ? context : context?.id;
|
|
6878
6895
|
if (contextId && contextId.toLowerCase().includes("native")) {
|
|
6879
6896
|
return this.elementId === el.elementId;
|
|
@@ -6881,7 +6898,7 @@ async function isEqual(el) {
|
|
|
6881
6898
|
}
|
|
6882
6899
|
let result;
|
|
6883
6900
|
try {
|
|
6884
|
-
result = await
|
|
6901
|
+
result = await browser.execute(
|
|
6885
6902
|
/* istanbul ignore next */
|
|
6886
6903
|
function(el1, el2) {
|
|
6887
6904
|
return el1 === el2;
|
|
@@ -6912,8 +6929,8 @@ import { ELEMENT_KEY as ELEMENT_KEY15 } from "webdriver";
|
|
|
6912
6929
|
import { getBrowserObject as getBrowserObject25 } from "@wdio/utils";
|
|
6913
6930
|
import isFocusedScript from "./scripts/isFocused.js";
|
|
6914
6931
|
async function isFocused() {
|
|
6915
|
-
const
|
|
6916
|
-
return
|
|
6932
|
+
const browser = await getBrowserObject25(this);
|
|
6933
|
+
return browser.execute(isFocusedScript, {
|
|
6917
6934
|
[ELEMENT_KEY15]: this.elementId,
|
|
6918
6935
|
// w3c compatible
|
|
6919
6936
|
ELEMENT: this.elementId
|
|
@@ -6931,8 +6948,8 @@ import { ELEMENT_KEY as ELEMENT_KEY16 } from "webdriver";
|
|
|
6931
6948
|
import { getBrowserObject as getBrowserObject26 } from "@wdio/utils";
|
|
6932
6949
|
import isElementStable from "./scripts/isElementStable.js";
|
|
6933
6950
|
async function isStable() {
|
|
6934
|
-
const
|
|
6935
|
-
return await
|
|
6951
|
+
const browser = getBrowserObject26(this);
|
|
6952
|
+
return await browser.executeAsync(isElementStable, {
|
|
6936
6953
|
[ELEMENT_KEY16]: this.elementId,
|
|
6937
6954
|
// w3c compatible
|
|
6938
6955
|
ELEMENT: this.elementId
|
|
@@ -6945,9 +6962,9 @@ import logger23 from "@wdio/logger";
|
|
|
6945
6962
|
import { getBrowserObject as getBrowserObject27 } from "@wdio/utils";
|
|
6946
6963
|
var log23 = logger23("webdriver");
|
|
6947
6964
|
async function moveTo({ xOffset, yOffset } = {}) {
|
|
6948
|
-
const
|
|
6965
|
+
const browser = getBrowserObject27(this);
|
|
6949
6966
|
if (xOffset || yOffset) {
|
|
6950
|
-
const { width, height } = await
|
|
6967
|
+
const { width, height } = await browser.getElementRect(this.elementId);
|
|
6951
6968
|
if (xOffset && xOffset < -Math.floor(width / 2) || xOffset && xOffset > Math.floor(width / 2)) {
|
|
6952
6969
|
log23.warn("xOffset would cause a out of bounds error as it goes outside of element");
|
|
6953
6970
|
}
|
|
@@ -6956,7 +6973,7 @@ async function moveTo({ xOffset, yOffset } = {}) {
|
|
|
6956
6973
|
}
|
|
6957
6974
|
}
|
|
6958
6975
|
const moveToNested = async () => {
|
|
6959
|
-
await
|
|
6976
|
+
await browser.action("pointer", { parameters: { pointerType: "mouse" } }).move({ origin: this, x: xOffset || 0, y: yOffset || 0 }).perform();
|
|
6960
6977
|
};
|
|
6961
6978
|
try {
|
|
6962
6979
|
await moveToNested();
|
|
@@ -7000,10 +7017,10 @@ function previousElement() {
|
|
|
7000
7017
|
import { getBrowserObject as getBrowserObject28 } from "@wdio/utils";
|
|
7001
7018
|
import { waitToLoadReact as waitToLoadReact3, react$$ as react$$Script2 } from "./scripts/resq.js";
|
|
7002
7019
|
async function react$$2(selector, { props = {}, state = {} } = {}) {
|
|
7003
|
-
const
|
|
7020
|
+
const browser = await getBrowserObject28(this);
|
|
7004
7021
|
await this.executeScript(resqScript.toString(), []);
|
|
7005
|
-
await
|
|
7006
|
-
const res = await
|
|
7022
|
+
await browser.execute(waitToLoadReact3);
|
|
7023
|
+
const res = await browser.execute(
|
|
7007
7024
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
7008
7025
|
react$$Script2,
|
|
7009
7026
|
selector,
|
|
@@ -7019,10 +7036,10 @@ async function react$$2(selector, { props = {}, state = {} } = {}) {
|
|
|
7019
7036
|
import { getBrowserObject as getBrowserObject29 } from "@wdio/utils";
|
|
7020
7037
|
import { waitToLoadReact as waitToLoadReact4, react$ as react$Script2 } from "./scripts/resq.js";
|
|
7021
7038
|
async function react$2(selector, { props = {}, state = {} } = {}) {
|
|
7022
|
-
const
|
|
7039
|
+
const browser = await getBrowserObject29(this);
|
|
7023
7040
|
await this.executeScript(resqScript.toString(), []);
|
|
7024
|
-
await
|
|
7025
|
-
const res = await
|
|
7041
|
+
await browser.execute(waitToLoadReact4);
|
|
7042
|
+
const res = await browser.execute(
|
|
7026
7043
|
react$Script2,
|
|
7027
7044
|
selector,
|
|
7028
7045
|
props,
|
|
@@ -7043,11 +7060,11 @@ import { ELEMENT_KEY as ELEMENT_KEY17 } from "webdriver";
|
|
|
7043
7060
|
import { getBrowserObject as getBrowserObject30 } from "@wdio/utils";
|
|
7044
7061
|
var log24 = logger24("webdriverio");
|
|
7045
7062
|
async function scrollIntoView(options = { block: "start", inline: "nearest" }) {
|
|
7046
|
-
const
|
|
7047
|
-
if (
|
|
7048
|
-
if (await
|
|
7063
|
+
const browser = getBrowserObject30(this);
|
|
7064
|
+
if (browser.isMobile) {
|
|
7065
|
+
if (await browser.isNativeContext) {
|
|
7049
7066
|
return nativeMobileScrollIntoView({
|
|
7050
|
-
browser
|
|
7067
|
+
browser,
|
|
7051
7068
|
element: this,
|
|
7052
7069
|
options: options || {}
|
|
7053
7070
|
});
|
|
@@ -7055,9 +7072,9 @@ async function scrollIntoView(options = { block: "start", inline: "nearest" }) {
|
|
|
7055
7072
|
return scrollIntoViewWeb.call(this, options);
|
|
7056
7073
|
}
|
|
7057
7074
|
try {
|
|
7058
|
-
const elemRect = await
|
|
7059
|
-
const viewport = await
|
|
7060
|
-
let [scrollX, scrollY] = await
|
|
7075
|
+
const elemRect = await browser.getElementRect(this.elementId);
|
|
7076
|
+
const viewport = await browser.getWindowSize();
|
|
7077
|
+
let [scrollX, scrollY] = await browser.execute(() => [
|
|
7061
7078
|
window.scrollX,
|
|
7062
7079
|
window.scrollY
|
|
7063
7080
|
]);
|
|
@@ -7092,7 +7109,7 @@ async function scrollIntoView(options = { block: "start", inline: "nearest" }) {
|
|
|
7092
7109
|
}
|
|
7093
7110
|
deltaX = Math.round(deltaX - scrollX);
|
|
7094
7111
|
deltaY = Math.round(deltaY - scrollY);
|
|
7095
|
-
await
|
|
7112
|
+
await browser.action("wheel").scroll({ duration: 0, x: deltaX, y: deltaY, origin: this }).perform();
|
|
7096
7113
|
} catch (err) {
|
|
7097
7114
|
log24.warn(
|
|
7098
7115
|
`Failed to execute "scrollIntoView" using WebDriver Actions API: ${err.message}!
|
|
@@ -7102,7 +7119,7 @@ Re-attempting using \`Element.scrollIntoView\` via Web API.`
|
|
|
7102
7119
|
}
|
|
7103
7120
|
}
|
|
7104
7121
|
async function mobileScrollUntilVisible({
|
|
7105
|
-
browser
|
|
7122
|
+
browser,
|
|
7106
7123
|
direction,
|
|
7107
7124
|
duration,
|
|
7108
7125
|
element,
|
|
@@ -7122,7 +7139,7 @@ async function mobileScrollUntilVisible({
|
|
|
7122
7139
|
if (isVisible) {
|
|
7123
7140
|
break;
|
|
7124
7141
|
}
|
|
7125
|
-
await
|
|
7142
|
+
await browser.swipe({
|
|
7126
7143
|
direction,
|
|
7127
7144
|
...duration ? { duration } : {},
|
|
7128
7145
|
...percent ? { percent } : {},
|
|
@@ -7134,7 +7151,7 @@ async function mobileScrollUntilVisible({
|
|
|
7134
7151
|
return { hasScrolled, isVisible };
|
|
7135
7152
|
}
|
|
7136
7153
|
async function nativeMobileScrollIntoView({
|
|
7137
|
-
browser
|
|
7154
|
+
browser,
|
|
7138
7155
|
element,
|
|
7139
7156
|
options
|
|
7140
7157
|
}) {
|
|
@@ -7147,7 +7164,7 @@ async function nativeMobileScrollIntoView({
|
|
|
7147
7164
|
...options || {}
|
|
7148
7165
|
};
|
|
7149
7166
|
const { hasScrolled, isVisible } = await mobileScrollUntilVisible({
|
|
7150
|
-
browser
|
|
7167
|
+
browser,
|
|
7151
7168
|
element,
|
|
7152
7169
|
maxScrolls: mobileOptions.maxScrolls,
|
|
7153
7170
|
direction: mobileOptions.direction,
|
|
@@ -7156,7 +7173,7 @@ async function nativeMobileScrollIntoView({
|
|
|
7156
7173
|
...mobileOptions?.scrollableElement ? { scrollableElement: mobileOptions.scrollableElement } : {}
|
|
7157
7174
|
});
|
|
7158
7175
|
if (hasScrolled && isVisible) {
|
|
7159
|
-
return
|
|
7176
|
+
return browser.pause(1e3);
|
|
7160
7177
|
} else if (isVisible) {
|
|
7161
7178
|
return;
|
|
7162
7179
|
}
|
|
@@ -7170,8 +7187,8 @@ await elem.scrollIntoView({
|
|
|
7170
7187
|
`);
|
|
7171
7188
|
}
|
|
7172
7189
|
function scrollIntoViewWeb(options = { block: "start", inline: "nearest" }) {
|
|
7173
|
-
const
|
|
7174
|
-
return
|
|
7190
|
+
const browser = getBrowserObject30(this);
|
|
7191
|
+
return browser.execute(
|
|
7175
7192
|
(elem, options2) => elem.scrollIntoView(options2),
|
|
7176
7193
|
{
|
|
7177
7194
|
[ELEMENT_KEY17]: this.elementId,
|
|
@@ -7582,11 +7599,11 @@ var createRoleBaseXpathSelector = (role) => {
|
|
|
7582
7599
|
// src/commands/element/shadow$$.ts
|
|
7583
7600
|
var log25 = logger25("webdriverio");
|
|
7584
7601
|
async function shadow$$(selector) {
|
|
7585
|
-
const
|
|
7602
|
+
const browser = getBrowserObject31(this);
|
|
7586
7603
|
try {
|
|
7587
|
-
const shadowRoot = await
|
|
7604
|
+
const shadowRoot = await browser.getElementShadowRoot(this.elementId);
|
|
7588
7605
|
const { using, value } = findStrategy(selector, this.isW3C, this.isMobile);
|
|
7589
|
-
const res = await
|
|
7606
|
+
const res = await browser.findElementsFromShadowRoot(shadowRoot[SHADOW_ELEMENT_KEY], using, value);
|
|
7590
7607
|
const elements = await getElements.call(this, selector, res, { isShadowElement: true });
|
|
7591
7608
|
return enhanceElementsArray(elements, this, selector);
|
|
7592
7609
|
} catch (err) {
|
|
@@ -7605,11 +7622,11 @@ import { shadowFnFactory as shadowFnFactory2 } from "./scripts/shadowFnFactory.j
|
|
|
7605
7622
|
import { getBrowserObject as getBrowserObject32 } from "@wdio/utils";
|
|
7606
7623
|
var log26 = logger26("webdriverio");
|
|
7607
7624
|
async function shadow$(selector) {
|
|
7608
|
-
const
|
|
7625
|
+
const browser = getBrowserObject32(this);
|
|
7609
7626
|
try {
|
|
7610
|
-
const shadowRoot = await
|
|
7627
|
+
const shadowRoot = await browser.getElementShadowRoot(this.elementId);
|
|
7611
7628
|
const { using, value } = findStrategy(selector, this.isW3C, this.isMobile);
|
|
7612
|
-
const res = await
|
|
7629
|
+
const res = await browser.findElementFromShadowRoot(shadowRoot[SHADOW_ELEMENT_KEY2], using, value);
|
|
7613
7630
|
return getElement.call(this, selector, res, { isShadowElement: true });
|
|
7614
7631
|
} catch (err) {
|
|
7615
7632
|
log26.warn(
|
|
@@ -7724,8 +7741,8 @@ var waitUntil2 = waitUntil;
|
|
|
7724
7741
|
// src/commands/mobile/longPress.ts
|
|
7725
7742
|
import { getBrowserObject as getBrowserObject33 } from "@wdio/utils";
|
|
7726
7743
|
function longPress(options) {
|
|
7727
|
-
const
|
|
7728
|
-
if (!
|
|
7744
|
+
const browser = getBrowserObject33(this);
|
|
7745
|
+
if (!browser.isMobile) {
|
|
7729
7746
|
throw new Error("The longPress command is only available for mobile platforms.");
|
|
7730
7747
|
}
|
|
7731
7748
|
if (typeof options !== "undefined" && (typeof options !== "object" || Array.isArray(options))) {
|
|
@@ -7743,12 +7760,12 @@ function longPress(options) {
|
|
|
7743
7760
|
// src/commands/mobile/pinch.ts
|
|
7744
7761
|
import { getBrowserObject as getBrowserObject34 } from "@wdio/utils";
|
|
7745
7762
|
async function pinch(options = {}) {
|
|
7746
|
-
const
|
|
7747
|
-
if (!
|
|
7763
|
+
const browser = getBrowserObject34(this);
|
|
7764
|
+
if (!browser.isMobile) {
|
|
7748
7765
|
throw new Error("The pinch command is only available for mobile platforms.");
|
|
7749
7766
|
}
|
|
7750
|
-
const { duration, scale } = validatePinchAndZoomOptions({ browser
|
|
7751
|
-
const gestureConfig =
|
|
7767
|
+
const { duration, scale } = validatePinchAndZoomOptions({ browser, gesture: "pinch", options });
|
|
7768
|
+
const gestureConfig = browser.isIOS ? {
|
|
7752
7769
|
elementId: await this.elementId,
|
|
7753
7770
|
scale,
|
|
7754
7771
|
velocity: -Math.abs(duration)
|
|
@@ -7756,29 +7773,29 @@ async function pinch(options = {}) {
|
|
|
7756
7773
|
} : {
|
|
7757
7774
|
elementId: await this.elementId,
|
|
7758
7775
|
percent: scale,
|
|
7759
|
-
speed: calculateAndroidPinchAndZoomSpeed({ browser
|
|
7776
|
+
speed: calculateAndroidPinchAndZoomSpeed({ browser, duration, scale })
|
|
7760
7777
|
};
|
|
7761
|
-
return
|
|
7778
|
+
return browser.execute(browser.isIOS ? "mobile: pinch" : "mobile: pinchCloseGesture", gestureConfig);
|
|
7762
7779
|
}
|
|
7763
7780
|
|
|
7764
7781
|
// src/commands/mobile/zoom.ts
|
|
7765
7782
|
import { getBrowserObject as getBrowserObject35 } from "@wdio/utils";
|
|
7766
7783
|
async function zoom(options = {}) {
|
|
7767
|
-
const
|
|
7768
|
-
if (!
|
|
7784
|
+
const browser = getBrowserObject35(this);
|
|
7785
|
+
if (!browser.isMobile) {
|
|
7769
7786
|
throw new Error("The zoom command is only available for mobile platforms.");
|
|
7770
7787
|
}
|
|
7771
|
-
const { duration, scale } = validatePinchAndZoomOptions({ browser
|
|
7772
|
-
const gestureConfig =
|
|
7788
|
+
const { duration, scale } = validatePinchAndZoomOptions({ browser, gesture: "zoom", options });
|
|
7789
|
+
const gestureConfig = browser.isIOS ? {
|
|
7773
7790
|
elementId: await this.elementId,
|
|
7774
7791
|
scale,
|
|
7775
7792
|
velocity: duration
|
|
7776
7793
|
} : {
|
|
7777
7794
|
elementId: await this.elementId,
|
|
7778
7795
|
percent: scale,
|
|
7779
|
-
speed: calculateAndroidPinchAndZoomSpeed({ browser
|
|
7796
|
+
speed: calculateAndroidPinchAndZoomSpeed({ browser, duration, scale })
|
|
7780
7797
|
};
|
|
7781
|
-
return
|
|
7798
|
+
return browser.execute(browser.isIOS ? "mobile: pinch" : "mobile: pinchOpenGesture", gestureConfig);
|
|
7782
7799
|
}
|
|
7783
7800
|
|
|
7784
7801
|
// src/utils/index.ts
|
|
@@ -8118,9 +8135,9 @@ function transformClassicToBidiSelector(using, value) {
|
|
|
8118
8135
|
throw new Error(`Can't transform classic selector ${using} to Bidi selector`);
|
|
8119
8136
|
}
|
|
8120
8137
|
async function findDeepElement(selector) {
|
|
8121
|
-
const
|
|
8122
|
-
const shadowRootManager = getShadowRootManager(
|
|
8123
|
-
const contextManager = getContextManager(
|
|
8138
|
+
const browser = getBrowserObject36(this);
|
|
8139
|
+
const shadowRootManager = getShadowRootManager(browser);
|
|
8140
|
+
const contextManager = getContextManager(browser);
|
|
8124
8141
|
const context = await contextManager.getCurrentContext();
|
|
8125
8142
|
const shadowRoots = shadowRootManager.getShadowElementsByContextId(
|
|
8126
8143
|
context,
|
|
@@ -8129,7 +8146,7 @@ async function findDeepElement(selector) {
|
|
|
8129
8146
|
const { using, value } = findStrategy(selector, this.isW3C, this.isMobile);
|
|
8130
8147
|
const locator = transformClassicToBidiSelector(using, value);
|
|
8131
8148
|
const startNodes = shadowRoots.length > 0 ? shadowRoots.map((shadowRootNodeId) => ({ sharedId: shadowRootNodeId })) : this.elementId ? [{ sharedId: this.elementId }] : void 0;
|
|
8132
|
-
const deepElementResult = await
|
|
8149
|
+
const deepElementResult = await browser.browsingContextLocateNodes({ locator, context, startNodes }).then(async (result) => {
|
|
8133
8150
|
let nodes = result.nodes.filter((node) => Boolean(node.sharedId)).map((node) => ({
|
|
8134
8151
|
[ELEMENT_KEY20]: node.sharedId,
|
|
8135
8152
|
locator
|
|
@@ -8139,7 +8156,7 @@ async function findDeepElement(selector) {
|
|
|
8139
8156
|
return nodes[0];
|
|
8140
8157
|
}
|
|
8141
8158
|
const scopedNodes = await Promise.all(nodes.map(async (node) => {
|
|
8142
|
-
const isIn = await
|
|
8159
|
+
const isIn = await browser.execute(
|
|
8143
8160
|
elementContains,
|
|
8144
8161
|
{ [ELEMENT_KEY20]: this.elementId },
|
|
8145
8162
|
node
|
|
@@ -8149,7 +8166,7 @@ async function findDeepElement(selector) {
|
|
|
8149
8166
|
return scopedNodes[0];
|
|
8150
8167
|
}, (err) => {
|
|
8151
8168
|
log27.warn(`Failed to execute browser.browsingContextLocateNodes({ ... }) due to ${err}, falling back to regular WebDriver Classic command`);
|
|
8152
|
-
return this && "elementId" in this && this.elementId ? this.findElementFromElement(this.elementId, using, value) :
|
|
8169
|
+
return this && "elementId" in this && this.elementId ? this.findElementFromElement(this.elementId, using, value) : browser.findElement(using, value);
|
|
8153
8170
|
});
|
|
8154
8171
|
if (!deepElementResult) {
|
|
8155
8172
|
return new Error(`Couldn't find element with selector "${selector}"`);
|
|
@@ -8157,9 +8174,9 @@ async function findDeepElement(selector) {
|
|
|
8157
8174
|
return deepElementResult;
|
|
8158
8175
|
}
|
|
8159
8176
|
async function findDeepElements(selector) {
|
|
8160
|
-
const
|
|
8161
|
-
const shadowRootManager = getShadowRootManager(
|
|
8162
|
-
const contextManager = getContextManager(
|
|
8177
|
+
const browser = getBrowserObject36(this);
|
|
8178
|
+
const shadowRootManager = getShadowRootManager(browser);
|
|
8179
|
+
const contextManager = getContextManager(browser);
|
|
8163
8180
|
const context = await contextManager.getCurrentContext();
|
|
8164
8181
|
const shadowRoots = shadowRootManager.getShadowElementsByContextId(
|
|
8165
8182
|
context,
|
|
@@ -8168,7 +8185,7 @@ async function findDeepElements(selector) {
|
|
|
8168
8185
|
const { using, value } = findStrategy(selector, this.isW3C, this.isMobile);
|
|
8169
8186
|
const locator = transformClassicToBidiSelector(using, value);
|
|
8170
8187
|
const startNodes = shadowRoots.length > 0 ? shadowRoots.map((shadowRootNodeId) => ({ sharedId: shadowRootNodeId })) : this.elementId ? [{ sharedId: this.elementId }] : void 0;
|
|
8171
|
-
const deepElementResult = await
|
|
8188
|
+
const deepElementResult = await browser.browsingContextLocateNodes({ locator, context, startNodes }).then(async (result) => {
|
|
8172
8189
|
let nodes = result.nodes.filter((node) => Boolean(node.sharedId)).map((node) => ({
|
|
8173
8190
|
[ELEMENT_KEY20]: node.sharedId,
|
|
8174
8191
|
locator
|
|
@@ -8178,7 +8195,7 @@ async function findDeepElements(selector) {
|
|
|
8178
8195
|
return nodes;
|
|
8179
8196
|
}
|
|
8180
8197
|
const scopedNodes = await Promise.all(nodes.map(async (node) => {
|
|
8181
|
-
const isIn = await
|
|
8198
|
+
const isIn = await browser.execute(
|
|
8182
8199
|
elementContains,
|
|
8183
8200
|
{ [ELEMENT_KEY20]: this.elementId },
|
|
8184
8201
|
node
|
|
@@ -8188,7 +8205,7 @@ async function findDeepElements(selector) {
|
|
|
8188
8205
|
return scopedNodes;
|
|
8189
8206
|
}, (err) => {
|
|
8190
8207
|
log27.warn(`Failed to execute browser.browsingContextLocateNodes({ ... }) due to ${err}, falling back to regular WebDriver Classic command`);
|
|
8191
|
-
return this && "elementId" in this && this.elementId ? this.findElementsFromElement(this.elementId, using, value) :
|
|
8208
|
+
return this && "elementId" in this && this.elementId ? this.findElementsFromElement(this.elementId, using, value) : browser.findElements(using, value);
|
|
8192
8209
|
});
|
|
8193
8210
|
return deepElementResult;
|
|
8194
8211
|
}
|
|
@@ -8384,7 +8401,7 @@ ${userScript.toString()}
|
|
|
8384
8401
|
}
|
|
8385
8402
|
|
|
8386
8403
|
// src/middlewares.ts
|
|
8387
|
-
var COMMANDS_TO_SKIP = ["getElement", "getElements"];
|
|
8404
|
+
var COMMANDS_TO_SKIP = ["getElement", "getElements", "emit"];
|
|
8388
8405
|
var elementErrorHandler = (fn) => (commandName, commandFn) => {
|
|
8389
8406
|
return function elementErrorHandlerCallback(...args) {
|
|
8390
8407
|
return fn(commandName, async function elementErrorHandlerCallbackFn() {
|
|
@@ -8692,7 +8709,7 @@ var NOOP2 = () => {
|
|
|
8692
8709
|
var ProtocolStub = class {
|
|
8693
8710
|
static async newSession(options) {
|
|
8694
8711
|
const capabilities = emulateSessionCapabilities(options.capabilities);
|
|
8695
|
-
const
|
|
8712
|
+
const browser = {
|
|
8696
8713
|
options,
|
|
8697
8714
|
capabilities,
|
|
8698
8715
|
requestedCapabilities: capabilities,
|
|
@@ -8708,9 +8725,9 @@ var ProtocolStub = class {
|
|
|
8708
8725
|
overwriteCommand: NOOP2,
|
|
8709
8726
|
...capabilitiesEnvironmentDetector(capabilities)
|
|
8710
8727
|
};
|
|
8711
|
-
|
|
8712
|
-
|
|
8713
|
-
return
|
|
8728
|
+
browser.addCommand = (...args) => browser.customCommands.push(args);
|
|
8729
|
+
browser.overwriteCommand = (...args) => browser.overwrittenCommands.push(args);
|
|
8730
|
+
return browser;
|
|
8714
8731
|
}
|
|
8715
8732
|
/**
|
|
8716
8733
|
* added just in case user wants to somehow reload webdriver before it was started.
|
|
@@ -8760,7 +8777,7 @@ async function getProtocolDriver(options) {
|
|
|
8760
8777
|
var Key2 = Key;
|
|
8761
8778
|
var SevereServiceError2 = SevereServiceError;
|
|
8762
8779
|
var remote = async function(params, remoteModifier) {
|
|
8763
|
-
const keysToKeep = Object.keys(
|
|
8780
|
+
const keysToKeep = Object.keys(environment.value.variables.WDIO_WORKER_ID ? params : DEFAULTS);
|
|
8764
8781
|
const config = validateConfig(WDIO_DEFAULTS, params, keysToKeep);
|
|
8765
8782
|
await enableFileLogging(config.outputDir);
|
|
8766
8783
|
logger28.setLogLevelsConfig(config.logLevels, config.logLevel);
|
|
@@ -8868,7 +8885,8 @@ environment.value = {
|
|
|
8868
8885
|
saveRecordingScreen,
|
|
8869
8886
|
uploadFile,
|
|
8870
8887
|
saveScreenshot,
|
|
8871
|
-
saveElementScreenshot
|
|
8888
|
+
saveElementScreenshot,
|
|
8889
|
+
variables: process2.env
|
|
8872
8890
|
};
|
|
8873
8891
|
export {
|
|
8874
8892
|
Key2 as Key,
|