webdriverio 9.2.1 → 9.2.4
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/keys.d.ts +1 -1
- package/build/commands/browser/mock.d.ts +1 -1
- package/build/commands/browser/newWindow.d.ts +37 -9
- package/build/commands/browser/newWindow.d.ts.map +1 -1
- package/build/commands/browser/switchFrame.d.ts +22 -7
- package/build/commands/browser/switchFrame.d.ts.map +1 -1
- package/build/commands/browser/switchWindow.d.ts.map +1 -1
- package/build/commands/browser/url.d.ts.map +1 -1
- package/build/context.d.ts +4 -1
- package/build/context.d.ts.map +1 -1
- package/build/index.js +348 -223
- package/build/networkManager.d.ts +2 -4
- package/build/networkManager.d.ts.map +1 -1
- package/build/protocol-stub.d.ts.map +1 -1
- package/build/protocol-stub.js +5 -0
- package/build/shadowRoot.d.ts.map +1 -1
- package/build/types.d.ts +1 -0
- package/build/types.d.ts.map +1 -1
- package/build/utils/index.d.ts.map +1 -1
- package/package.json +7 -7
package/build/index.js
CHANGED
|
@@ -5,7 +5,7 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/index.ts
|
|
8
|
-
import
|
|
8
|
+
import logger22 from "@wdio/logger";
|
|
9
9
|
import WebDriver, { DEFAULTS } from "webdriver";
|
|
10
10
|
import { validateConfig } from "@wdio/config";
|
|
11
11
|
import { enableFileLogging, wrapCommand as wrapCommand3 } from "@wdio/utils";
|
|
@@ -16,7 +16,7 @@ import clone2 from "lodash.clonedeep";
|
|
|
16
16
|
import { webdriverMonad as webdriverMonad2, wrapCommand as wrapCommand2 } from "@wdio/utils";
|
|
17
17
|
|
|
18
18
|
// src/middlewares.ts
|
|
19
|
-
import { ELEMENT_KEY as
|
|
19
|
+
import { ELEMENT_KEY as ELEMENT_KEY19 } from "webdriver";
|
|
20
20
|
import { getBrowserObject as getBrowserObject31 } from "@wdio/utils";
|
|
21
21
|
|
|
22
22
|
// src/utils/implicitWait.ts
|
|
@@ -78,9 +78,9 @@ import { URL as URL2 } from "node:url";
|
|
|
78
78
|
import cssValue from "css-value";
|
|
79
79
|
import rgb2hex from "rgb2hex";
|
|
80
80
|
import GraphemeSplitter from "grapheme-splitter";
|
|
81
|
-
import
|
|
81
|
+
import logger21 from "@wdio/logger";
|
|
82
82
|
import isPlainObject from "is-plain-obj";
|
|
83
|
-
import { ELEMENT_KEY as
|
|
83
|
+
import { ELEMENT_KEY as ELEMENT_KEY18 } from "webdriver";
|
|
84
84
|
import { UNICODE_CHARACTERS as UNICODE_CHARACTERS2, asyncIterators, getBrowserObject as getBrowserObject30 } from "@wdio/utils";
|
|
85
85
|
|
|
86
86
|
// src/commands/browser.ts
|
|
@@ -2974,9 +2974,7 @@ var ReferenceValue = class {
|
|
|
2974
2974
|
};
|
|
2975
2975
|
|
|
2976
2976
|
// src/context.ts
|
|
2977
|
-
import logger4 from "@wdio/logger";
|
|
2978
2977
|
var contextManager = /* @__PURE__ */ new Map();
|
|
2979
|
-
var log4 = logger4("webdriverio:ContextManager");
|
|
2980
2978
|
function getContextManager(browser) {
|
|
2981
2979
|
const existingContextManager = contextManager.get(browser);
|
|
2982
2980
|
if (existingContextManager) {
|
|
@@ -2988,53 +2986,47 @@ function getContextManager(browser) {
|
|
|
2988
2986
|
}
|
|
2989
2987
|
var ContextManager = class {
|
|
2990
2988
|
#browser;
|
|
2991
|
-
#initialize;
|
|
2992
2989
|
#currentContext;
|
|
2993
2990
|
constructor(browser) {
|
|
2994
2991
|
this.#browser = browser;
|
|
2995
|
-
if (
|
|
2996
|
-
this.#initialize = Promise.resolve(true);
|
|
2992
|
+
if (process.env.WDIO_UNIT_TESTS) {
|
|
2997
2993
|
return;
|
|
2998
2994
|
}
|
|
2999
|
-
this.#
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
2995
|
+
this.#browser.on("command", (event) => {
|
|
2996
|
+
if (event.command === "switchToWindow") {
|
|
2997
|
+
this.setCurrentContext(event.body.handle);
|
|
2998
|
+
}
|
|
2999
|
+
if (event.command === "switchToParentFrame") {
|
|
3000
|
+
this.#currentContext = void 0;
|
|
3001
|
+
}
|
|
3002
|
+
});
|
|
3006
3003
|
}
|
|
3007
3004
|
/**
|
|
3008
|
-
*
|
|
3009
|
-
* This is most likely the context that the user is using. However if a frame was loaded on the page
|
|
3010
|
-
* then this handler is triggered with the context of the frame. To find out which context we are in
|
|
3011
|
-
* we use the `getWindowHandle` method to validate our assumption before setting the `#currentContext`
|
|
3012
|
-
* value.
|
|
3013
|
-
*
|
|
3014
|
-
* @param {local.BrowsingContextNavigationInfo} context browsing context used to navigate
|
|
3005
|
+
* set context at the start of the session
|
|
3015
3006
|
*/
|
|
3016
|
-
async
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
log4.info(`Update current context: ${context.context}`);
|
|
3020
|
-
this.#currentContext = context.context;
|
|
3007
|
+
async initialize() {
|
|
3008
|
+
if (process.env.WDIO_UNIT_TESTS) {
|
|
3009
|
+
return "fake-context";
|
|
3021
3010
|
}
|
|
3011
|
+
const windowHandle = await this.#browser.getWindowHandle();
|
|
3012
|
+
this.#currentContext = windowHandle;
|
|
3013
|
+
return windowHandle;
|
|
3022
3014
|
}
|
|
3023
3015
|
setCurrentContext(context) {
|
|
3024
3016
|
this.#currentContext = context;
|
|
3025
3017
|
}
|
|
3026
3018
|
async getCurrentContext() {
|
|
3027
3019
|
if (!this.#currentContext) {
|
|
3028
|
-
|
|
3020
|
+
return this.initialize();
|
|
3029
3021
|
}
|
|
3030
3022
|
return this.#currentContext;
|
|
3031
3023
|
}
|
|
3032
3024
|
};
|
|
3033
3025
|
|
|
3034
3026
|
// src/polyfill.ts
|
|
3035
|
-
import
|
|
3027
|
+
import logger4 from "@wdio/logger";
|
|
3036
3028
|
var polyfillManager = /* @__PURE__ */ new Map();
|
|
3037
|
-
var
|
|
3029
|
+
var log4 = logger4("webdriverio:PolyfillManager");
|
|
3038
3030
|
var NAME_POLYFILL = "var __defProp = Object.defineProperty;var __name = function (target, value) { return __defProp(target, 'name', { value: value, configurable: true }); };var __globalThis = (typeof globalThis === 'object' && globalThis) || (typeof window === 'object' && window);__globalThis.__name = __name;";
|
|
3039
3031
|
function getPolyfillManager(browser) {
|
|
3040
3032
|
const existingPolyfillManager = polyfillManager.get(browser);
|
|
@@ -3048,7 +3040,7 @@ function getPolyfillManager(browser) {
|
|
|
3048
3040
|
var PolyfillManager = class {
|
|
3049
3041
|
#initialize;
|
|
3050
3042
|
constructor(browser) {
|
|
3051
|
-
if (!browser.isBidi || process.env.
|
|
3043
|
+
if (!browser.isBidi || process.env.WDIO_UNIT_TESTS || browser.options?.automationProtocol !== "webdriver") {
|
|
3052
3044
|
this.#initialize = Promise.resolve(true);
|
|
3053
3045
|
return;
|
|
3054
3046
|
}
|
|
@@ -3060,7 +3052,7 @@ var PolyfillManager = class {
|
|
|
3060
3052
|
browser.addInitScript(polyfill, NAME_POLYFILL),
|
|
3061
3053
|
browser.execute(polyfill, NAME_POLYFILL)
|
|
3062
3054
|
]).then(() => {
|
|
3063
|
-
|
|
3055
|
+
log4.info("polyfill script added");
|
|
3064
3056
|
return true;
|
|
3065
3057
|
}, () => false);
|
|
3066
3058
|
}
|
|
@@ -3145,8 +3137,8 @@ async function executeAsync(script, ...args) {
|
|
|
3145
3137
|
}
|
|
3146
3138
|
|
|
3147
3139
|
// src/commands/browser/getCookies.ts
|
|
3148
|
-
import
|
|
3149
|
-
var
|
|
3140
|
+
import logger5 from "@wdio/logger";
|
|
3141
|
+
var log5 = logger5("webdriverio");
|
|
3150
3142
|
async function getCookies(filter) {
|
|
3151
3143
|
const usesMultipleFilter = Array.isArray(filter) && filter.length > 1;
|
|
3152
3144
|
if (!this.isBidi || usesMultipleFilter) {
|
|
@@ -3165,7 +3157,7 @@ async function getCookiesClassic(names) {
|
|
|
3165
3157
|
}
|
|
3166
3158
|
const usesMultipleFilter = Array.isArray(names) && names.length > 1;
|
|
3167
3159
|
if (usesMultipleFilter) {
|
|
3168
|
-
|
|
3160
|
+
log5.warn(
|
|
3169
3161
|
"Passing a string array as filter for `getCookies` is deprecated and its support will be removed in an upcoming version of WebdriverIO!"
|
|
3170
3162
|
);
|
|
3171
3163
|
const allCookies2 = await this.getAllCookies();
|
|
@@ -3184,7 +3176,7 @@ function getCookieFilter(names) {
|
|
|
3184
3176
|
}
|
|
3185
3177
|
return (Array.isArray(names) ? names : [names]).map((filter) => {
|
|
3186
3178
|
if (typeof filter === "string") {
|
|
3187
|
-
|
|
3179
|
+
log5.warn("Passing string values into `getCookie` is deprecated and its support will be removed in an upcoming version of WebdriverIO!");
|
|
3188
3180
|
return { name: filter };
|
|
3189
3181
|
}
|
|
3190
3182
|
return filter;
|
|
@@ -3192,9 +3184,9 @@ function getCookieFilter(names) {
|
|
|
3192
3184
|
}
|
|
3193
3185
|
|
|
3194
3186
|
// src/commands/browser/getPuppeteer.ts
|
|
3195
|
-
import
|
|
3187
|
+
import logger6 from "@wdio/logger";
|
|
3196
3188
|
import { userImport } from "@wdio/utils";
|
|
3197
|
-
var
|
|
3189
|
+
var log6 = logger6("webdriverio");
|
|
3198
3190
|
var DEBUG_PIPE_FLAG = "remote-debugging-pipe";
|
|
3199
3191
|
async function getPuppeteer() {
|
|
3200
3192
|
const puppeteer = await userImport("puppeteer-core");
|
|
@@ -3204,7 +3196,7 @@ async function getPuppeteer() {
|
|
|
3204
3196
|
);
|
|
3205
3197
|
}
|
|
3206
3198
|
if (this.puppeteer?.connected) {
|
|
3207
|
-
|
|
3199
|
+
log6.debug("Reusing existing puppeteer session");
|
|
3208
3200
|
return this.puppeteer;
|
|
3209
3201
|
}
|
|
3210
3202
|
const { headers } = this.options;
|
|
@@ -3315,7 +3307,7 @@ import { getBrowserObject as getBrowserObject5 } from "@wdio/utils";
|
|
|
3315
3307
|
|
|
3316
3308
|
// src/utils/interception/index.ts
|
|
3317
3309
|
import EventEmitter2 from "node:events";
|
|
3318
|
-
import
|
|
3310
|
+
import logger7 from "@wdio/logger";
|
|
3319
3311
|
import { URLPattern } from "urlpattern-polyfill";
|
|
3320
3312
|
|
|
3321
3313
|
// src/utils/Timer.ts
|
|
@@ -3372,10 +3364,10 @@ var Timer = class {
|
|
|
3372
3364
|
}
|
|
3373
3365
|
_tick() {
|
|
3374
3366
|
const result = this._fn();
|
|
3367
|
+
if (!result) {
|
|
3368
|
+
return this._checkCondition(new Error(TIMEOUT_ERROR));
|
|
3369
|
+
}
|
|
3375
3370
|
if (typeof result.then !== "function") {
|
|
3376
|
-
if (!result) {
|
|
3377
|
-
return this._checkCondition(new Error(TIMEOUT_ERROR));
|
|
3378
|
-
}
|
|
3379
3371
|
return this._checkCondition(void 0, result);
|
|
3380
3372
|
}
|
|
3381
3373
|
result.then(
|
|
@@ -3481,7 +3473,7 @@ function getPatternParam(pattern, key) {
|
|
|
3481
3473
|
}
|
|
3482
3474
|
|
|
3483
3475
|
// src/utils/interception/index.ts
|
|
3484
|
-
var
|
|
3476
|
+
var log7 = logger7("WebDriverInterception");
|
|
3485
3477
|
var hasSubscribedToEvents = false;
|
|
3486
3478
|
var WebDriverInterception = class _WebDriverInterception {
|
|
3487
3479
|
#pattern;
|
|
@@ -3510,7 +3502,7 @@ var WebDriverInterception = class _WebDriverInterception {
|
|
|
3510
3502
|
"network.responseStarted"
|
|
3511
3503
|
]
|
|
3512
3504
|
});
|
|
3513
|
-
|
|
3505
|
+
log7.info("subscribed to network events");
|
|
3514
3506
|
hasSubscribedToEvents = true;
|
|
3515
3507
|
}
|
|
3516
3508
|
const interception = await browser.networkAddIntercept({
|
|
@@ -3672,7 +3664,7 @@ var WebDriverInterception = class _WebDriverInterception {
|
|
|
3672
3664
|
this.#respondOverwrites = [];
|
|
3673
3665
|
this.#restored = true;
|
|
3674
3666
|
const handle = await this.#browser.getWindowHandle();
|
|
3675
|
-
|
|
3667
|
+
log7.trace(`Restoring mock for ${handle}`);
|
|
3676
3668
|
SESSION_MOCKS[handle].delete(this);
|
|
3677
3669
|
if (this.#mockId) {
|
|
3678
3670
|
await this.#browser.networkRemoveIntercept({ intercept: this.#mockId });
|
|
@@ -3812,11 +3804,11 @@ async function mock(url6, filterOptions) {
|
|
|
3812
3804
|
}
|
|
3813
3805
|
|
|
3814
3806
|
// src/commands/browser/mockClearAll.ts
|
|
3815
|
-
import
|
|
3816
|
-
var
|
|
3807
|
+
import logger8 from "@wdio/logger";
|
|
3808
|
+
var log8 = logger8("webdriverio:mockClearAll");
|
|
3817
3809
|
async function mockClearAll() {
|
|
3818
3810
|
for (const [handle, mocks] of Object.entries(SESSION_MOCKS)) {
|
|
3819
|
-
|
|
3811
|
+
log8.trace(`Clearing mocks for ${handle}`);
|
|
3820
3812
|
for (const mock2 of mocks) {
|
|
3821
3813
|
mock2.clear();
|
|
3822
3814
|
}
|
|
@@ -3824,11 +3816,11 @@ async function mockClearAll() {
|
|
|
3824
3816
|
}
|
|
3825
3817
|
|
|
3826
3818
|
// src/commands/browser/mockRestoreAll.ts
|
|
3827
|
-
import
|
|
3828
|
-
var
|
|
3819
|
+
import logger9 from "@wdio/logger";
|
|
3820
|
+
var log9 = logger9("webdriverio:mockRestoreAll");
|
|
3829
3821
|
async function mockRestoreAll() {
|
|
3830
3822
|
for (const [handle, mocks] of Object.entries(SESSION_MOCKS)) {
|
|
3831
|
-
|
|
3823
|
+
log9.trace(`Clearing mocks for ${handle}`);
|
|
3832
3824
|
for (const mock2 of mocks) {
|
|
3833
3825
|
await mock2.restore();
|
|
3834
3826
|
}
|
|
@@ -3838,18 +3830,26 @@ async function mockRestoreAll() {
|
|
|
3838
3830
|
// src/commands/browser/newWindow.ts
|
|
3839
3831
|
import { sleep } from "@wdio/utils";
|
|
3840
3832
|
import newWindowHelper from "./scripts/newWindow.js";
|
|
3833
|
+
import logger10 from "@wdio/logger";
|
|
3834
|
+
var log10 = logger10("webdriverio:newWindow");
|
|
3841
3835
|
var WAIT_FOR_NEW_HANDLE_TIMEOUT = 3e3;
|
|
3842
|
-
async function newWindow(url6, { windowName = "", windowFeatures = "" } = {}) {
|
|
3836
|
+
async function newWindow(url6, { type = "window", windowName = "", windowFeatures = "" } = {}) {
|
|
3843
3837
|
if (typeof url6 !== "string") {
|
|
3844
3838
|
throw new Error("number or type of arguments don't agree with newWindow command");
|
|
3845
3839
|
}
|
|
3840
|
+
if (!["tab", "window"].includes(type)) {
|
|
3841
|
+
throw new Error(`Invalid type '${type}' provided to newWindow command. Use either 'tab' or 'window'`);
|
|
3842
|
+
}
|
|
3843
|
+
if (windowName || windowFeatures) {
|
|
3844
|
+
log10.warn('The "windowName" and "windowFeatures" options are deprecated and only supported in WebDriver Classic sessions.');
|
|
3845
|
+
}
|
|
3846
3846
|
if (this.isMobile) {
|
|
3847
3847
|
throw new Error("newWindow command is not supported on mobile platforms");
|
|
3848
3848
|
}
|
|
3849
3849
|
const tabsBefore = await this.getWindowHandles();
|
|
3850
3850
|
if (this.isBidi) {
|
|
3851
3851
|
const contextManager2 = getContextManager(this);
|
|
3852
|
-
const { context } = await this.browsingContextCreate({ type
|
|
3852
|
+
const { context } = await this.browsingContextCreate({ type });
|
|
3853
3853
|
contextManager2.setCurrentContext(context);
|
|
3854
3854
|
await this.browsingContextNavigate({ context, url: url6 });
|
|
3855
3855
|
} else {
|
|
@@ -3869,7 +3869,7 @@ async function newWindow(url6, { windowName = "", windowFeatures = "" } = {}) {
|
|
|
3869
3869
|
throw new Error("No window handle was found to switch to");
|
|
3870
3870
|
}
|
|
3871
3871
|
await this.switchToWindow(newTab);
|
|
3872
|
-
return newTab;
|
|
3872
|
+
return { handle: newTab, type };
|
|
3873
3873
|
}
|
|
3874
3874
|
|
|
3875
3875
|
// src/commands/browser/pause.ts
|
|
@@ -4135,6 +4135,7 @@ async function switchWindow(matcher) {
|
|
|
4135
4135
|
if (typeof matcher !== "string" && !(matcher instanceof RegExp)) {
|
|
4136
4136
|
throw new Error('Unsupported parameter for switchWindow, required is "string" or an RegExp');
|
|
4137
4137
|
}
|
|
4138
|
+
const currentWindow = await this.getWindowHandle();
|
|
4138
4139
|
const tabs = await this.getWindowHandles();
|
|
4139
4140
|
const matchesTarget = (target) => {
|
|
4140
4141
|
if (typeof matcher === "string") {
|
|
@@ -4162,60 +4163,150 @@ async function switchWindow(matcher) {
|
|
|
4162
4163
|
return tab;
|
|
4163
4164
|
}
|
|
4164
4165
|
}
|
|
4166
|
+
await this.switchToWindow(currentWindow);
|
|
4165
4167
|
throw new Error(`No window found with title, url or name matching "${matcher}"`);
|
|
4166
4168
|
}
|
|
4167
4169
|
|
|
4168
4170
|
// src/commands/browser/switchFrame.ts
|
|
4171
|
+
import logger13 from "@wdio/logger";
|
|
4172
|
+
import { ELEMENT_KEY as ELEMENT_KEY8 } from "webdriver";
|
|
4173
|
+
var log13 = logger13("webdriverio:switchFrame");
|
|
4169
4174
|
async function switchFrame(context) {
|
|
4175
|
+
if (!this.isBidi) {
|
|
4176
|
+
if (typeof context === "function") {
|
|
4177
|
+
throw new Error("Cannot use a function to fetch a context in WebDriver Classic");
|
|
4178
|
+
}
|
|
4179
|
+
if (typeof context === "string") {
|
|
4180
|
+
throw new Error("Cannot use a string to fetch a context in WebDriver Classic");
|
|
4181
|
+
}
|
|
4182
|
+
return switchToFrame(this, context);
|
|
4183
|
+
}
|
|
4170
4184
|
if (context === null) {
|
|
4171
4185
|
const handle = await this.getWindowHandle();
|
|
4172
|
-
|
|
4186
|
+
switchToFrameHelper(this, handle);
|
|
4187
|
+
await switchToFrame(this, context);
|
|
4173
4188
|
return handle;
|
|
4174
4189
|
}
|
|
4175
4190
|
if (typeof context === "string") {
|
|
4176
4191
|
const tree = await this.browsingContextGetTree({});
|
|
4177
|
-
|
|
4192
|
+
let newContextId;
|
|
4193
|
+
const urlContext = findContext(context, tree.contexts, byUrl) || /**
|
|
4194
|
+
* In case the user provides an url without `/` at the end, e.g. `https://example.com`,
|
|
4195
|
+
* the `browsingContextGetTree` command may return a context with the url `https://example.com/`.
|
|
4196
|
+
*/
|
|
4197
|
+
findContext(`${context}/`, tree.contexts, byUrl);
|
|
4198
|
+
const urlContextContaining = findContext(context, tree.contexts, byUrlContaining);
|
|
4199
|
+
const contextIdContext = findContext(context, tree.contexts, byContextId);
|
|
4178
4200
|
if (urlContext) {
|
|
4179
|
-
|
|
4180
|
-
|
|
4201
|
+
log13.info(`Found context by url "${urlContext.url}" with context id "${urlContext.context}"`);
|
|
4202
|
+
newContextId = urlContext.context;
|
|
4203
|
+
} else if (urlContextContaining) {
|
|
4204
|
+
log13.info(`Found context by url containing "${urlContextContaining.url}" with context id "${urlContextContaining.context}"`);
|
|
4205
|
+
newContextId = urlContextContaining.context;
|
|
4206
|
+
} else if (contextIdContext) {
|
|
4207
|
+
log13.info(`Found context by id "${contextIdContext}" with url "${contextIdContext.url}"`);
|
|
4208
|
+
newContextId = contextIdContext.context;
|
|
4209
|
+
}
|
|
4210
|
+
if (!newContextId) {
|
|
4211
|
+
throw new Error(`No frame with url or id "${context}" found!`);
|
|
4181
4212
|
}
|
|
4182
|
-
const
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
|
|
4213
|
+
const sessionContext = getContextManager(this);
|
|
4214
|
+
const currentContext = await sessionContext.getCurrentContext();
|
|
4215
|
+
const allContexts = await getFlatContextTree(this);
|
|
4216
|
+
const allFrames = (await Promise.all(Object.keys(allContexts).map(async (id) => {
|
|
4217
|
+
const { nodes } = await this.browsingContextLocateNodes({
|
|
4218
|
+
locator: { type: "css", value: "iframe, frame" },
|
|
4219
|
+
context: id
|
|
4220
|
+
}).catch(() => ({ nodes: [] }));
|
|
4221
|
+
return Promise.all(nodes.map(async (node) => {
|
|
4222
|
+
const html = `<iframe${Object.entries(node.value?.attributes || {}).reduce((acc, [key, value]) => `${acc} ${key}="${value}"`, " ")}></iframe>`;
|
|
4223
|
+
const args = [{ [ELEMENT_KEY8]: node.sharedId }];
|
|
4224
|
+
const userScript = (iframe) => iframe.contentWindow;
|
|
4225
|
+
const functionDeclaration = new Function(`
|
|
4226
|
+
return (${SCRIPT_PREFIX}${userScript.toString()}${SCRIPT_SUFFIX}).apply(this, arguments);
|
|
4227
|
+
`).toString();
|
|
4228
|
+
const params = {
|
|
4229
|
+
functionDeclaration,
|
|
4230
|
+
awaitPromise: false,
|
|
4231
|
+
arguments: args.map((arg) => LocalValue.getArgument(arg)),
|
|
4232
|
+
target: { context: id }
|
|
4233
|
+
};
|
|
4234
|
+
const result = await this.scriptCallFunction(params).catch((err) => log13.warn(`Failed to identify frame context id: ${err.message}`));
|
|
4235
|
+
if (!result) {
|
|
4236
|
+
return [];
|
|
4237
|
+
}
|
|
4238
|
+
const { context: context2 } = parseScriptResult(params, result);
|
|
4239
|
+
return {
|
|
4240
|
+
/**
|
|
4241
|
+
* the actual frame context we need to switch WebDriver Bidi commands to
|
|
4242
|
+
*/
|
|
4243
|
+
context: context2,
|
|
4244
|
+
/**
|
|
4245
|
+
* the element reference of the iframe so we can call `switchToFrame` to
|
|
4246
|
+
* switch context for WebDriver Classic commands
|
|
4247
|
+
*/
|
|
4248
|
+
frameElement: { [ELEMENT_KEY8]: node.sharedId },
|
|
4249
|
+
/**
|
|
4250
|
+
* the context id in which the iframe was found
|
|
4251
|
+
*/
|
|
4252
|
+
parentContext: id,
|
|
4253
|
+
/**
|
|
4254
|
+
* an HTML representation of the iframe for a good error message in case
|
|
4255
|
+
* we can't find the desired frame from this list
|
|
4256
|
+
*/
|
|
4257
|
+
html
|
|
4258
|
+
};
|
|
4259
|
+
}));
|
|
4260
|
+
}))).flat(Infinity);
|
|
4261
|
+
let desiredFrame;
|
|
4262
|
+
let desiredContext = newContextId;
|
|
4263
|
+
const contextQueue = [];
|
|
4264
|
+
log13.info(`Available frames to switch to: ${allFrames.length}, desired context to switch: ${desiredContext}`);
|
|
4265
|
+
while (desiredContext !== currentContext) {
|
|
4266
|
+
desiredFrame = allFrames.find(({ context: context2 }) => context2 === desiredContext);
|
|
4267
|
+
if (!desiredFrame) {
|
|
4268
|
+
break;
|
|
4269
|
+
}
|
|
4270
|
+
log13.info(
|
|
4271
|
+
contextQueue.length === 0 ? `Found desired frame with element id ${desiredFrame.frameElement[ELEMENT_KEY8]}` : `to switch to desired frame, we need to switch to ${desiredFrame.context} first`
|
|
4272
|
+
);
|
|
4273
|
+
contextQueue.unshift(desiredFrame);
|
|
4274
|
+
desiredContext = desiredFrame.parentContext;
|
|
4275
|
+
}
|
|
4276
|
+
if (contextQueue.length === 0) {
|
|
4277
|
+
throw new Error(`Frame with url or context id "${context}" not found, available frames to switch to:
|
|
4278
|
+
- ${allFrames.map(({ html }) => html).join("\n - ")}`);
|
|
4186
4279
|
}
|
|
4187
|
-
const
|
|
4188
|
-
|
|
4189
|
-
await
|
|
4190
|
-
return contextIdContext;
|
|
4280
|
+
for (const contextToSwitch of contextQueue) {
|
|
4281
|
+
switchToFrameHelper(this, contextToSwitch.context);
|
|
4282
|
+
await switchToFrame(this, contextToSwitch.frameElement);
|
|
4191
4283
|
}
|
|
4192
|
-
|
|
4284
|
+
return newContextId;
|
|
4193
4285
|
}
|
|
4194
4286
|
if (typeof context === "object" && typeof context.getElement === "function") {
|
|
4195
4287
|
const element = await context.getElement();
|
|
4196
4288
|
return switchToFrameUsingElement(this, element);
|
|
4197
4289
|
}
|
|
4198
4290
|
if (typeof context === "function") {
|
|
4199
|
-
const
|
|
4200
|
-
const
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
if (isDesiredFrame) {
|
|
4215
|
-
return context;
|
|
4291
|
+
const allContexts = await getFlatContextTree(this);
|
|
4292
|
+
const allContextIds = Object.keys(allContexts);
|
|
4293
|
+
for (const contextId of allContextIds) {
|
|
4294
|
+
const functionDeclaration = new Function(`
|
|
4295
|
+
return (${SCRIPT_PREFIX}${context.toString()}${SCRIPT_SUFFIX}).apply(this, arguments);
|
|
4296
|
+
`).toString();
|
|
4297
|
+
const params = {
|
|
4298
|
+
functionDeclaration,
|
|
4299
|
+
awaitPromise: false,
|
|
4300
|
+
arguments: [],
|
|
4301
|
+
target: { context: contextId }
|
|
4302
|
+
};
|
|
4303
|
+
const result = await this.scriptCallFunction(params).catch((err) => log13.warn(`switchFrame context callback threw error: ${err.message}`));
|
|
4304
|
+
if (!result || result.type !== "success" || result.result.type !== "boolean" || !result.result.value) {
|
|
4305
|
+
continue;
|
|
4216
4306
|
}
|
|
4307
|
+
await this.switchFrame(contextId);
|
|
4308
|
+
return contextId;
|
|
4217
4309
|
}
|
|
4218
|
-
sessionContext.setCurrentContext(currentContext);
|
|
4219
4310
|
throw new Error("Could not find the desired frame");
|
|
4220
4311
|
}
|
|
4221
4312
|
throw new Error(
|
|
@@ -4227,25 +4318,14 @@ function switchToFrameHelper(browser, context) {
|
|
|
4227
4318
|
sessionContext.setCurrentContext(context);
|
|
4228
4319
|
}
|
|
4229
4320
|
async function switchToFrameUsingElement(browser, element) {
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
}
|
|
4237
|
-
|
|
4238
|
-
frameSrc = await browser.execute((urlPath) => URL.parse(urlPath, window.location.href)?.href, frameSrc) || frameSrc;
|
|
4239
|
-
}
|
|
4240
|
-
const tree = await browser.browsingContextGetTree({});
|
|
4241
|
-
const urlContext = findContext(frameSrc, tree.contexts, byUrl)?.context;
|
|
4242
|
-
if (!urlContext) {
|
|
4243
|
-
throw new Error(
|
|
4244
|
-
`Frame with url "${frameSrc}" not found! Please try a different method to select the frame. For more information checkout our docs: https://webdriver.io/docs/api/browser/switchFrame.html`
|
|
4245
|
-
);
|
|
4246
|
-
}
|
|
4247
|
-
await switchToFrameHelper(browser, urlContext);
|
|
4248
|
-
return urlContext;
|
|
4321
|
+
const frame = await browser.execute(
|
|
4322
|
+
(iframe) => iframe.contentWindow,
|
|
4323
|
+
element
|
|
4324
|
+
);
|
|
4325
|
+
switchToFrameHelper(browser, frame.context);
|
|
4326
|
+
const elementId = element[ELEMENT_KEY8];
|
|
4327
|
+
await switchToFrame(browser, { [ELEMENT_KEY8]: elementId });
|
|
4328
|
+
return frame.context;
|
|
4249
4329
|
}
|
|
4250
4330
|
function byUrl(context, url6) {
|
|
4251
4331
|
return context.url === url6;
|
|
@@ -4256,13 +4336,13 @@ function byUrlContaining(context, url6) {
|
|
|
4256
4336
|
function byContextId(context, contextId) {
|
|
4257
4337
|
return context.context === contextId;
|
|
4258
4338
|
}
|
|
4259
|
-
function findContext(
|
|
4339
|
+
function findContext(urlOrId, contexts, matcher) {
|
|
4260
4340
|
for (const context of contexts || []) {
|
|
4261
|
-
if (matcher(context,
|
|
4341
|
+
if (matcher(context, urlOrId)) {
|
|
4262
4342
|
return context;
|
|
4263
4343
|
}
|
|
4264
4344
|
if (Array.isArray(context.children) && context.children.length > 0) {
|
|
4265
|
-
const result = findContext(
|
|
4345
|
+
const result = findContext(urlOrId, context.children, matcher);
|
|
4266
4346
|
if (result) {
|
|
4267
4347
|
return result;
|
|
4268
4348
|
}
|
|
@@ -4270,13 +4350,32 @@ function findContext(url6, contexts, matcher) {
|
|
|
4270
4350
|
}
|
|
4271
4351
|
return void 0;
|
|
4272
4352
|
}
|
|
4353
|
+
async function getFlatContextTree(browser) {
|
|
4354
|
+
const tree = await browser.browsingContextGetTree({});
|
|
4355
|
+
const mapContext = (context) => [
|
|
4356
|
+
context.context,
|
|
4357
|
+
...(context.children || []).map(mapContext)
|
|
4358
|
+
];
|
|
4359
|
+
const allContexts = tree.contexts.map(mapContext).flat(Infinity).reduce((acc, ctx) => {
|
|
4360
|
+
const context = findContext(ctx, tree.contexts, byContextId);
|
|
4361
|
+
acc[ctx] = context;
|
|
4362
|
+
return acc;
|
|
4363
|
+
}, {});
|
|
4364
|
+
return allContexts;
|
|
4365
|
+
}
|
|
4366
|
+
function switchToFrame(browser, frame) {
|
|
4367
|
+
process.env.DISABLE_WEBDRIVERIO_DEPRECATION_WARNINGS = "true";
|
|
4368
|
+
return browser.switchToFrame(frame).finally(() => {
|
|
4369
|
+
delete process.env.DISABLE_WEBDRIVERIO_DEPRECATION_WARNINGS;
|
|
4370
|
+
});
|
|
4371
|
+
}
|
|
4273
4372
|
|
|
4274
4373
|
// src/commands/browser/throttle.ts
|
|
4275
|
-
import
|
|
4374
|
+
import logger14 from "@wdio/logger";
|
|
4276
4375
|
import { getBrowserObject as getBrowserObject8 } from "@wdio/utils";
|
|
4277
|
-
var
|
|
4376
|
+
var log14 = logger14("webdriverio:throttle");
|
|
4278
4377
|
async function throttle(params) {
|
|
4279
|
-
|
|
4378
|
+
log14.warn('Command "throttle" is deprecated and will be removed with the next major version release! Use `throttleNetwork` instead.');
|
|
4280
4379
|
const browser = getBrowserObject8(this);
|
|
4281
4380
|
await browser.throttleNetwork(params);
|
|
4282
4381
|
}
|
|
@@ -4432,13 +4531,15 @@ function getNetworkManager(browser) {
|
|
|
4432
4531
|
networkManager.set(browser, newContext);
|
|
4433
4532
|
return newContext;
|
|
4434
4533
|
}
|
|
4534
|
+
var UNKNOWN_NAVIGATION_ID = "UNKNOWN_NAVIGATION_ID";
|
|
4435
4535
|
var NetworkManager = class {
|
|
4436
4536
|
#browser;
|
|
4437
4537
|
#initialize;
|
|
4438
4538
|
#requests = /* @__PURE__ */ new Map();
|
|
4539
|
+
#lastNetworkId;
|
|
4439
4540
|
constructor(browser) {
|
|
4440
4541
|
this.#browser = browser;
|
|
4441
|
-
if (!browser.isBidi || process.env.
|
|
4542
|
+
if (!browser.isBidi || process.env.WDIO_UNIT_TESTS || browser.options?.automationProtocol !== "webdriver") {
|
|
4442
4543
|
this.#initialize = Promise.resolve(true);
|
|
4443
4544
|
return;
|
|
4444
4545
|
}
|
|
@@ -4458,15 +4559,15 @@ var NetworkManager = class {
|
|
|
4458
4559
|
async initialize() {
|
|
4459
4560
|
return this.#initialize;
|
|
4460
4561
|
}
|
|
4461
|
-
#beforeRequestSent(
|
|
4462
|
-
if (
|
|
4562
|
+
#beforeRequestSent(log22) {
|
|
4563
|
+
if (log22.navigation) {
|
|
4463
4564
|
return;
|
|
4464
4565
|
}
|
|
4465
|
-
const request =
|
|
4566
|
+
const request = this.#findRootRequest(log22.navigation);
|
|
4466
4567
|
if (!request) {
|
|
4467
4568
|
return;
|
|
4468
4569
|
}
|
|
4469
|
-
const { request: id, headers, cookies, url: url6 } =
|
|
4570
|
+
const { request: id, headers, cookies, url: url6 } = log22.request;
|
|
4470
4571
|
request.children?.push({
|
|
4471
4572
|
id,
|
|
4472
4573
|
url: url6,
|
|
@@ -4482,66 +4583,76 @@ var NetworkManager = class {
|
|
|
4482
4583
|
sameSite: cookie.sameSite,
|
|
4483
4584
|
expiry: cookie.expiry
|
|
4484
4585
|
})),
|
|
4485
|
-
timestamp:
|
|
4586
|
+
timestamp: log22.timestamp
|
|
4486
4587
|
});
|
|
4487
4588
|
}
|
|
4488
|
-
#navigationStarted(
|
|
4589
|
+
#navigationStarted(log22) {
|
|
4489
4590
|
if (
|
|
4490
4591
|
/**
|
|
4491
4592
|
* we need a navigation id to identify the request
|
|
4492
4593
|
*/
|
|
4493
|
-
!
|
|
4594
|
+
!log22.navigation || /**
|
|
4494
4595
|
* ignore urls that do not start with http
|
|
4495
4596
|
*/
|
|
4496
|
-
!
|
|
4597
|
+
!log22.url.startsWith("http")
|
|
4497
4598
|
) {
|
|
4498
|
-
if (
|
|
4499
|
-
|
|
4599
|
+
if (log22.navigation === null && log22.url === "") {
|
|
4600
|
+
this.#lastNetworkId = UNKNOWN_NAVIGATION_ID;
|
|
4601
|
+
return this.#requests.set(UNKNOWN_NAVIGATION_ID, {
|
|
4500
4602
|
url: "",
|
|
4501
4603
|
headers: {},
|
|
4502
|
-
timestamp:
|
|
4604
|
+
timestamp: log22.timestamp,
|
|
4503
4605
|
redirectChain: [],
|
|
4504
4606
|
children: []
|
|
4505
4607
|
});
|
|
4506
4608
|
}
|
|
4507
4609
|
return;
|
|
4508
4610
|
}
|
|
4509
|
-
this.#
|
|
4510
|
-
|
|
4611
|
+
this.#lastNetworkId = log22.navigation;
|
|
4612
|
+
this.#requests.set(log22.navigation, {
|
|
4613
|
+
url: log22.url,
|
|
4511
4614
|
headers: {},
|
|
4512
|
-
timestamp:
|
|
4513
|
-
navigation:
|
|
4615
|
+
timestamp: log22.timestamp,
|
|
4616
|
+
navigation: log22.navigation,
|
|
4514
4617
|
redirectChain: [],
|
|
4515
4618
|
children: []
|
|
4516
4619
|
});
|
|
4517
4620
|
}
|
|
4518
|
-
#fetchError(
|
|
4519
|
-
const response =
|
|
4621
|
+
#fetchError(log22) {
|
|
4622
|
+
const response = this.#findRootRequest(log22.navigation);
|
|
4520
4623
|
if (!response) {
|
|
4521
4624
|
return;
|
|
4522
4625
|
}
|
|
4523
|
-
const request = response.children?.find((child) => child.id ===
|
|
4626
|
+
const request = response.children?.find((child) => child.id === log22.request.request);
|
|
4524
4627
|
if (!request) {
|
|
4525
4628
|
return;
|
|
4526
4629
|
}
|
|
4527
|
-
request.error =
|
|
4630
|
+
request.error = log22.errorText;
|
|
4631
|
+
}
|
|
4632
|
+
#findRootRequest(navigationId) {
|
|
4633
|
+
const response = this.#requests.get(navigationId || UNKNOWN_NAVIGATION_ID);
|
|
4634
|
+
if (response) {
|
|
4635
|
+
return response;
|
|
4636
|
+
}
|
|
4637
|
+
const firstRequest = this.#requests.values().next().value;
|
|
4638
|
+
return this.#lastNetworkId ? this.#requests.get(this.#lastNetworkId) || firstRequest : firstRequest;
|
|
4528
4639
|
}
|
|
4529
|
-
#responseCompleted(
|
|
4530
|
-
const response =
|
|
4640
|
+
#responseCompleted(log22) {
|
|
4641
|
+
const response = this.#findRootRequest(log22.navigation);
|
|
4531
4642
|
if (!response) {
|
|
4532
4643
|
return;
|
|
4533
4644
|
}
|
|
4534
4645
|
if (!response.navigation && response.url === "") {
|
|
4535
|
-
response.url =
|
|
4536
|
-
response.navigation =
|
|
4646
|
+
response.url = log22.request.url;
|
|
4647
|
+
response.navigation = log22.navigation;
|
|
4537
4648
|
}
|
|
4538
|
-
if (
|
|
4539
|
-
if (response.url !==
|
|
4649
|
+
if (log22.navigation === response.navigation) {
|
|
4650
|
+
if (response.url !== log22.response.url) {
|
|
4540
4651
|
response.redirectChain?.push(response.url);
|
|
4541
4652
|
}
|
|
4542
|
-
response.url =
|
|
4543
|
-
const { headers: requestHeaders } =
|
|
4544
|
-
const { fromCache, headers: responseHeaders, mimeType, status } =
|
|
4653
|
+
response.url = log22.response.url;
|
|
4654
|
+
const { headers: requestHeaders } = log22.request;
|
|
4655
|
+
const { fromCache, headers: responseHeaders, mimeType, status } = log22.response;
|
|
4545
4656
|
response.headers = headerListToObject(requestHeaders), response.response = {
|
|
4546
4657
|
fromCache,
|
|
4547
4658
|
headers: headerListToObject(responseHeaders),
|
|
@@ -4550,30 +4661,30 @@ var NetworkManager = class {
|
|
|
4550
4661
|
};
|
|
4551
4662
|
return;
|
|
4552
4663
|
}
|
|
4553
|
-
const request = response.children?.find((child) => child.id ===
|
|
4664
|
+
const request = response.children?.find((child) => child.id === log22.request.request);
|
|
4554
4665
|
if (!request) {
|
|
4555
4666
|
return;
|
|
4556
4667
|
}
|
|
4557
4668
|
request.response = {
|
|
4558
|
-
fromCache:
|
|
4559
|
-
headers: headerListToObject(
|
|
4560
|
-
mimeType:
|
|
4561
|
-
status:
|
|
4669
|
+
fromCache: log22.response.fromCache,
|
|
4670
|
+
headers: headerListToObject(log22.response.headers),
|
|
4671
|
+
mimeType: log22.response.mimeType,
|
|
4672
|
+
status: log22.response.status
|
|
4562
4673
|
};
|
|
4563
4674
|
response.children?.push(request);
|
|
4564
4675
|
}
|
|
4565
|
-
getRequestResponseData(
|
|
4566
|
-
return this.#requests.get(
|
|
4676
|
+
getRequestResponseData(navigationId) {
|
|
4677
|
+
return this.#requests.get(navigationId);
|
|
4567
4678
|
}
|
|
4568
4679
|
/**
|
|
4569
4680
|
* Returns the number of requests that are currently pending.
|
|
4570
4681
|
* @param context browsing context id
|
|
4571
4682
|
* @returns the number of requests that are currently pending
|
|
4572
4683
|
*/
|
|
4573
|
-
getPendingRequests(
|
|
4574
|
-
const request = this.#requests.get(
|
|
4684
|
+
getPendingRequests(navigationId) {
|
|
4685
|
+
const request = this.#requests.get(navigationId);
|
|
4575
4686
|
if (!request) {
|
|
4576
|
-
throw new Error(`Couldn't find request for
|
|
4687
|
+
throw new Error(`Couldn't find request for navigation with id ${navigationId}`);
|
|
4577
4688
|
}
|
|
4578
4689
|
const subRequests = request.children || [];
|
|
4579
4690
|
return subRequests.filter((child) => (
|
|
@@ -4627,17 +4738,16 @@ async function url3(path4, options = {}) {
|
|
|
4627
4738
|
}
|
|
4628
4739
|
const classicPageLoadStrategy = this.capabilities.pageLoadStrategy === "none" ? "none" : this.capabilities.pageLoadStrategy === "normal" ? "complete" : this.capabilities.pageLoadStrategy === "eager" ? "interactive" : void 0;
|
|
4629
4740
|
const wait = options.wait === "networkIdle" ? "complete" : options.wait || classicPageLoadStrategy || DEFAULT_WAIT_STATE;
|
|
4630
|
-
await this.browsingContextNavigate({
|
|
4741
|
+
const navigation = await this.browsingContextNavigate({
|
|
4631
4742
|
context,
|
|
4632
4743
|
url: path4,
|
|
4633
4744
|
wait
|
|
4634
4745
|
});
|
|
4635
|
-
const network = networkManager.get(this);
|
|
4636
|
-
const request = network?.getRequestResponseData(context);
|
|
4637
4746
|
if (mock2) {
|
|
4638
4747
|
await mock2.restore();
|
|
4639
4748
|
}
|
|
4640
|
-
|
|
4749
|
+
const network = getNetworkManager(this);
|
|
4750
|
+
if (options.wait === "networkIdle") {
|
|
4641
4751
|
const timeout = options.timeout || DEFAULT_NETWORK_IDLE_TIMEOUT;
|
|
4642
4752
|
await this.waitUntil(async () => {
|
|
4643
4753
|
return network.getPendingRequests(context).length === 0;
|
|
@@ -4649,6 +4759,15 @@ async function url3(path4, options = {}) {
|
|
|
4649
4759
|
if (resetPreloadScript) {
|
|
4650
4760
|
await resetPreloadScript.remove();
|
|
4651
4761
|
}
|
|
4762
|
+
const request = await this.waitUntil(
|
|
4763
|
+
() => network.getRequestResponseData(navigation.navigation),
|
|
4764
|
+
/**
|
|
4765
|
+
* set a short interval to immediately return once the first request payload comes in
|
|
4766
|
+
*/
|
|
4767
|
+
{
|
|
4768
|
+
interval: 1
|
|
4769
|
+
}
|
|
4770
|
+
);
|
|
4652
4771
|
return request;
|
|
4653
4772
|
}
|
|
4654
4773
|
if (Object.keys(options).length > 0) {
|
|
@@ -4765,9 +4884,9 @@ function clearValue() {
|
|
|
4765
4884
|
}
|
|
4766
4885
|
|
|
4767
4886
|
// src/commands/element/click.ts
|
|
4768
|
-
import
|
|
4887
|
+
import logger15 from "@wdio/logger";
|
|
4769
4888
|
import { getBrowserObject as getBrowserObject10 } from "@wdio/utils";
|
|
4770
|
-
var
|
|
4889
|
+
var log15 = logger15("webdriver");
|
|
4771
4890
|
function click(options) {
|
|
4772
4891
|
if (typeof options !== "undefined") {
|
|
4773
4892
|
if (typeof options !== "object" || Array.isArray(options)) {
|
|
@@ -4813,10 +4932,10 @@ async function actionClick(element, options) {
|
|
|
4813
4932
|
if (x || y) {
|
|
4814
4933
|
const { width, height } = await browser.getElementRect(element.elementId);
|
|
4815
4934
|
if (x && x < -Math.floor(width / 2) || x && x > Math.floor(width / 2)) {
|
|
4816
|
-
|
|
4935
|
+
log15.warn("x would cause a out of bounds error as it goes outside of element");
|
|
4817
4936
|
}
|
|
4818
4937
|
if (y && y < -Math.floor(height / 2) || y && y > Math.floor(height / 2)) {
|
|
4819
|
-
|
|
4938
|
+
log15.warn("y would cause a out of bounds error as it goes outside of element");
|
|
4820
4939
|
}
|
|
4821
4940
|
}
|
|
4822
4941
|
const clickNested = async () => {
|
|
@@ -4833,7 +4952,7 @@ async function actionClick(element, options) {
|
|
|
4833
4952
|
}
|
|
4834
4953
|
|
|
4835
4954
|
// src/commands/element/custom$$.ts
|
|
4836
|
-
import { ELEMENT_KEY as
|
|
4955
|
+
import { ELEMENT_KEY as ELEMENT_KEY9 } from "webdriver";
|
|
4837
4956
|
import { getBrowserObject as getBrowserObject11 } from "@wdio/utils";
|
|
4838
4957
|
async function custom$$2(strategyName, ...strategyArguments) {
|
|
4839
4958
|
const browserObject = getBrowserObject11(this);
|
|
@@ -4849,13 +4968,13 @@ async function custom$$2(strategyName, ...strategyArguments) {
|
|
|
4849
4968
|
if (!Array.isArray(res)) {
|
|
4850
4969
|
res = [res];
|
|
4851
4970
|
}
|
|
4852
|
-
res = res.filter((el) => !!el && typeof el[
|
|
4971
|
+
res = res.filter((el) => !!el && typeof el[ELEMENT_KEY9] === "string");
|
|
4853
4972
|
const elements = res.length ? await getElements.call(this, strategyRef, res) : [];
|
|
4854
4973
|
return enhanceElementsArray(elements, this, strategyName, "custom$$", strategyArguments);
|
|
4855
4974
|
}
|
|
4856
4975
|
|
|
4857
4976
|
// src/commands/element/custom$.ts
|
|
4858
|
-
import { ELEMENT_KEY as
|
|
4977
|
+
import { ELEMENT_KEY as ELEMENT_KEY10 } from "webdriver";
|
|
4859
4978
|
import { getBrowserObject as getBrowserObject12 } from "@wdio/utils";
|
|
4860
4979
|
async function custom$2(strategyName, ...strategyArguments) {
|
|
4861
4980
|
const browserObject = getBrowserObject12(this);
|
|
@@ -4871,7 +4990,7 @@ async function custom$2(strategyName, ...strategyArguments) {
|
|
|
4871
4990
|
if (Array.isArray(res)) {
|
|
4872
4991
|
res = res[0];
|
|
4873
4992
|
}
|
|
4874
|
-
if (res && typeof res[
|
|
4993
|
+
if (res && typeof res[ELEMENT_KEY10] === "string") {
|
|
4875
4994
|
return await getElement.call(this, strategyRef, res);
|
|
4876
4995
|
}
|
|
4877
4996
|
return await getElement.call(this, strategyRef, new Error("no such element"));
|
|
@@ -4885,7 +5004,7 @@ async function doubleClick() {
|
|
|
4885
5004
|
}
|
|
4886
5005
|
|
|
4887
5006
|
// src/commands/element/dragAndDrop.ts
|
|
4888
|
-
import { ELEMENT_KEY as
|
|
5007
|
+
import { ELEMENT_KEY as ELEMENT_KEY11 } from "webdriver";
|
|
4889
5008
|
import { getBrowserObject as getBrowserObject14 } from "@wdio/utils";
|
|
4890
5009
|
var ACTION_BUTTON = 0;
|
|
4891
5010
|
async function dragAndDrop(target, { duration = 10 } = {}) {
|
|
@@ -4906,8 +5025,8 @@ async function dragAndDrop(target, { duration = 10 } = {}) {
|
|
|
4906
5025
|
throw new Error('command dragAndDrop requires an WebdriverIO Element or and object with "x" and "y" variables as first parameter');
|
|
4907
5026
|
}
|
|
4908
5027
|
const isMovingToElement = target.constructor.name === "Element";
|
|
4909
|
-
const sourceRef = { [
|
|
4910
|
-
const targetRef = { [
|
|
5028
|
+
const sourceRef = { [ELEMENT_KEY11]: this[ELEMENT_KEY11] };
|
|
5029
|
+
const targetRef = { [ELEMENT_KEY11]: moveToElement[ELEMENT_KEY11] };
|
|
4911
5030
|
const origin = sourceRef;
|
|
4912
5031
|
const targetOrigin = isMovingToElement ? targetRef : "pointer";
|
|
4913
5032
|
const targetX = isMovingToElement ? 0 : moveToCoordinates.x;
|
|
@@ -5028,15 +5147,15 @@ async function getElement2() {
|
|
|
5028
5147
|
}
|
|
5029
5148
|
|
|
5030
5149
|
// src/commands/element/getHTML.ts
|
|
5031
|
-
import { ELEMENT_KEY as
|
|
5150
|
+
import { ELEMENT_KEY as ELEMENT_KEY12 } from "webdriver";
|
|
5032
5151
|
import { prettify as prettifyFn } from "htmlfy";
|
|
5033
5152
|
import { getBrowserObject as getBrowserObject18 } from "@wdio/utils";
|
|
5034
5153
|
|
|
5035
5154
|
// src/shadowRoot.ts
|
|
5036
|
-
import
|
|
5155
|
+
import logger16 from "@wdio/logger";
|
|
5037
5156
|
import customElementWrapper from "./scripts/customElement.js";
|
|
5038
5157
|
var shadowRootManager = /* @__PURE__ */ new Map();
|
|
5039
|
-
var
|
|
5158
|
+
var log16 = logger16("webdriverio:ShadowRootManager");
|
|
5040
5159
|
function getShadowRootManager(browser) {
|
|
5041
5160
|
const existingShadowRootManager = shadowRootManager.get(browser);
|
|
5042
5161
|
if (existingShadowRootManager) {
|
|
@@ -5053,7 +5172,7 @@ var ShadowRootManager = class {
|
|
|
5053
5172
|
#frameDepth = 0;
|
|
5054
5173
|
constructor(browser) {
|
|
5055
5174
|
this.#browser = browser;
|
|
5056
|
-
if (!browser.isBidi || process.env.
|
|
5175
|
+
if (!browser.isBidi || process.env.WDIO_UNIT_TESTS || browser.options?.automationProtocol !== "webdriver") {
|
|
5057
5176
|
this.#initialize = Promise.resolve(true);
|
|
5058
5177
|
return;
|
|
5059
5178
|
}
|
|
@@ -5144,9 +5263,9 @@ var ShadowRootManager = class {
|
|
|
5144
5263
|
!shadowElem.value?.shadowRoot?.sharedId || // we expect the shadow root to have a proper type
|
|
5145
5264
|
shadowElem.value.shadowRoot.value?.nodeType !== 11
|
|
5146
5265
|
) {
|
|
5147
|
-
return
|
|
5266
|
+
return log16.warn(`Expected element with shadow root but found <${shadowElem.value?.localName} />`);
|
|
5148
5267
|
}
|
|
5149
|
-
|
|
5268
|
+
log16.info(`Registered new shadow root for element <${shadowElem.value.localName} /> with id ${shadowElem.value.shadowRoot.sharedId}`);
|
|
5150
5269
|
const newTree = new ShadowRootTree(
|
|
5151
5270
|
shadowElem.sharedId,
|
|
5152
5271
|
shadowElem.value.shadowRoot.sharedId,
|
|
@@ -5273,11 +5392,12 @@ var ShadowRootTree = class _ShadowRootTree {
|
|
|
5273
5392
|
return [this, ...Array.from(this.children).map((tree) => tree.flat())].flat();
|
|
5274
5393
|
}
|
|
5275
5394
|
remove(element) {
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5395
|
+
const childArray = Array.from(this.children);
|
|
5396
|
+
for (let i = childArray.length - 1; i >= 0; i--) {
|
|
5397
|
+
if (childArray[i].element === element) {
|
|
5398
|
+
return this.children.delete(childArray[i]);
|
|
5279
5399
|
}
|
|
5280
|
-
const wasFound =
|
|
5400
|
+
const wasFound = childArray[i].remove(element);
|
|
5281
5401
|
if (wasFound) {
|
|
5282
5402
|
return true;
|
|
5283
5403
|
}
|
|
@@ -5307,7 +5427,7 @@ async function getHTML(options = {}) {
|
|
|
5307
5427
|
}, options);
|
|
5308
5428
|
const basicGetHTML = (elementId, includeSelectorTag2) => {
|
|
5309
5429
|
return browser.execute(getHTMLScript, {
|
|
5310
|
-
[
|
|
5430
|
+
[ELEMENT_KEY12]: elementId,
|
|
5311
5431
|
// w3c compatible
|
|
5312
5432
|
ELEMENT: elementId
|
|
5313
5433
|
// jsonwp compatible
|
|
@@ -5327,18 +5447,18 @@ async function getHTML(options = {}) {
|
|
|
5327
5447
|
const context = await contextManager2.getCurrentContext();
|
|
5328
5448
|
const shadowRootElementPairs = shadowRootManager2.getShadowElementPairsByContextId(context, this.elementId);
|
|
5329
5449
|
const elementsWithShadowRootAndIdVerified = (await Promise.all(
|
|
5330
|
-
shadowRootElementPairs.map(([elemId, elem]) => browser.execute((elem2) => elem2.tagName, { [
|
|
5450
|
+
shadowRootElementPairs.map(([elemId, elem]) => browser.execute((elem2) => elem2.tagName, { [ELEMENT_KEY12]: elemId }).then(
|
|
5331
5451
|
() => [elemId, elem],
|
|
5332
5452
|
() => void 0
|
|
5333
5453
|
))
|
|
5334
5454
|
)).filter(Boolean).map(([elemId, shadowId]) => [
|
|
5335
5455
|
elemId,
|
|
5336
|
-
{ [
|
|
5337
|
-
shadowId ? { [
|
|
5456
|
+
{ [ELEMENT_KEY12]: elemId },
|
|
5457
|
+
shadowId ? { [ELEMENT_KEY12]: shadowId } : void 0
|
|
5338
5458
|
]);
|
|
5339
5459
|
const { html, shadowElementHTML } = await browser.execute(
|
|
5340
5460
|
getHTMLShadowScript,
|
|
5341
|
-
{ [
|
|
5461
|
+
{ [ELEMENT_KEY12]: this.elementId },
|
|
5342
5462
|
includeSelectorTag,
|
|
5343
5463
|
elementsWithShadowRootAndIdVerified
|
|
5344
5464
|
);
|
|
@@ -5436,7 +5556,7 @@ function getValue() {
|
|
|
5436
5556
|
}
|
|
5437
5557
|
|
|
5438
5558
|
// src/commands/element/isClickable.ts
|
|
5439
|
-
import { ELEMENT_KEY as
|
|
5559
|
+
import { ELEMENT_KEY as ELEMENT_KEY13 } from "webdriver";
|
|
5440
5560
|
import { getBrowserObject as getBrowserObject19 } from "@wdio/utils";
|
|
5441
5561
|
import isElementClickableScript from "./scripts/isElementClickable.js";
|
|
5442
5562
|
async function isClickable() {
|
|
@@ -5448,7 +5568,7 @@ async function isClickable() {
|
|
|
5448
5568
|
}
|
|
5449
5569
|
const browser = getBrowserObject19(this);
|
|
5450
5570
|
return browser.execute(isElementClickableScript, {
|
|
5451
|
-
[
|
|
5571
|
+
[ELEMENT_KEY13]: this.elementId,
|
|
5452
5572
|
// w3c compatible
|
|
5453
5573
|
ELEMENT: this.elementId
|
|
5454
5574
|
// jsonwp compatible
|
|
@@ -5486,10 +5606,10 @@ function isEnabled() {
|
|
|
5486
5606
|
}
|
|
5487
5607
|
|
|
5488
5608
|
// src/commands/element/isEqual.ts
|
|
5489
|
-
import { ELEMENT_KEY as
|
|
5609
|
+
import { ELEMENT_KEY as ELEMENT_KEY14 } from "webdriver";
|
|
5490
5610
|
import { getBrowserObject as getBrowserObject21 } from "@wdio/utils";
|
|
5491
5611
|
var getWebElement = (el) => ({
|
|
5492
|
-
[
|
|
5612
|
+
[ELEMENT_KEY14]: el.elementId,
|
|
5493
5613
|
// w3c compatible
|
|
5494
5614
|
ELEMENT: el.elementId
|
|
5495
5615
|
// jsonwp compatible
|
|
@@ -5532,13 +5652,13 @@ async function isExisting() {
|
|
|
5532
5652
|
}
|
|
5533
5653
|
|
|
5534
5654
|
// src/commands/element/isFocused.ts
|
|
5535
|
-
import { ELEMENT_KEY as
|
|
5655
|
+
import { ELEMENT_KEY as ELEMENT_KEY15 } from "webdriver";
|
|
5536
5656
|
import { getBrowserObject as getBrowserObject22 } from "@wdio/utils";
|
|
5537
5657
|
import isFocusedScript from "./scripts/isFocused.js";
|
|
5538
5658
|
async function isFocused() {
|
|
5539
5659
|
const browser = await getBrowserObject22(this);
|
|
5540
5660
|
return browser.execute(isFocusedScript, {
|
|
5541
|
-
[
|
|
5661
|
+
[ELEMENT_KEY15]: this.elementId,
|
|
5542
5662
|
// w3c compatible
|
|
5543
5663
|
ELEMENT: this.elementId
|
|
5544
5664
|
// jsonwp compatible
|
|
@@ -5551,13 +5671,13 @@ function isSelected() {
|
|
|
5551
5671
|
}
|
|
5552
5672
|
|
|
5553
5673
|
// src/commands/element/isStable.ts
|
|
5554
|
-
import { ELEMENT_KEY as
|
|
5674
|
+
import { ELEMENT_KEY as ELEMENT_KEY16 } from "webdriver";
|
|
5555
5675
|
import { getBrowserObject as getBrowserObject23 } from "@wdio/utils";
|
|
5556
5676
|
import isElementStable from "./scripts/isElementStable.js";
|
|
5557
5677
|
async function isStable() {
|
|
5558
5678
|
const browser = getBrowserObject23(this);
|
|
5559
5679
|
return await browser.executeAsync(isElementStable, {
|
|
5560
|
-
[
|
|
5680
|
+
[ELEMENT_KEY16]: this.elementId,
|
|
5561
5681
|
// w3c compatible
|
|
5562
5682
|
ELEMENT: this.elementId
|
|
5563
5683
|
// jsonwp compatible
|
|
@@ -5565,18 +5685,18 @@ async function isStable() {
|
|
|
5565
5685
|
}
|
|
5566
5686
|
|
|
5567
5687
|
// src/commands/element/moveTo.ts
|
|
5568
|
-
import
|
|
5688
|
+
import logger17 from "@wdio/logger";
|
|
5569
5689
|
import { getBrowserObject as getBrowserObject24 } from "@wdio/utils";
|
|
5570
|
-
var
|
|
5690
|
+
var log17 = logger17("webdriver");
|
|
5571
5691
|
async function moveTo({ xOffset, yOffset } = {}) {
|
|
5572
5692
|
const browser = getBrowserObject24(this);
|
|
5573
5693
|
if (xOffset || yOffset) {
|
|
5574
5694
|
const { width, height } = await browser.getElementRect(this.elementId);
|
|
5575
5695
|
if (xOffset && xOffset < -Math.floor(width / 2) || xOffset && xOffset > Math.floor(width / 2)) {
|
|
5576
|
-
|
|
5696
|
+
log17.warn("xOffset would cause a out of bounds error as it goes outside of element");
|
|
5577
5697
|
}
|
|
5578
5698
|
if (yOffset && yOffset < -Math.floor(height / 2) || yOffset && yOffset > Math.floor(height / 2)) {
|
|
5579
|
-
|
|
5699
|
+
log17.warn("yOffset would cause a out of bounds error as it goes outside of element");
|
|
5580
5700
|
}
|
|
5581
5701
|
}
|
|
5582
5702
|
const moveToNested = async () => {
|
|
@@ -5686,16 +5806,16 @@ async function saveScreenshot2(filepath) {
|
|
|
5686
5806
|
}
|
|
5687
5807
|
|
|
5688
5808
|
// src/commands/element/scrollIntoView.ts
|
|
5689
|
-
import
|
|
5690
|
-
import { ELEMENT_KEY as
|
|
5809
|
+
import logger18 from "@wdio/logger";
|
|
5810
|
+
import { ELEMENT_KEY as ELEMENT_KEY17 } from "webdriver";
|
|
5691
5811
|
import { getBrowserObject as getBrowserObject27 } from "@wdio/utils";
|
|
5692
|
-
var
|
|
5812
|
+
var log18 = logger18("webdriverio");
|
|
5693
5813
|
function scrollIntoViewWeb(options = { block: "start", inline: "nearest" }) {
|
|
5694
5814
|
const browser = getBrowserObject27(this);
|
|
5695
5815
|
return browser.execute(
|
|
5696
5816
|
(elem, options2) => elem.scrollIntoView(options2),
|
|
5697
5817
|
{
|
|
5698
|
-
[
|
|
5818
|
+
[ELEMENT_KEY17]: this.elementId,
|
|
5699
5819
|
// w3c compatible
|
|
5700
5820
|
ELEMENT: this.elementId
|
|
5701
5821
|
// jsonwp compatible
|
|
@@ -5748,7 +5868,7 @@ async function scrollIntoView(options = { block: "start", inline: "nearest" }) {
|
|
|
5748
5868
|
deltaY = Math.round(deltaY - scrollY);
|
|
5749
5869
|
await browser.action("wheel").scroll({ duration: 0, x: deltaX, y: deltaY, origin: this }).perform();
|
|
5750
5870
|
} catch (err) {
|
|
5751
|
-
|
|
5871
|
+
log18.warn(
|
|
5752
5872
|
`Failed to execute "scrollIntoView" using WebDriver Actions API: ${err.message}!
|
|
5753
5873
|
Re-attempting using \`Element.scrollIntoView\` via Web API.`
|
|
5754
5874
|
);
|
|
@@ -5813,7 +5933,7 @@ async function setValue(value) {
|
|
|
5813
5933
|
}
|
|
5814
5934
|
|
|
5815
5935
|
// src/commands/element/shadow$$.ts
|
|
5816
|
-
import
|
|
5936
|
+
import logger19 from "@wdio/logger";
|
|
5817
5937
|
import { getBrowserObject as getBrowserObject28 } from "@wdio/utils";
|
|
5818
5938
|
import { SHADOW_ELEMENT_KEY } from "webdriver";
|
|
5819
5939
|
import { shadowFnFactory } from "./scripts/shadowFnFactory.js";
|
|
@@ -6141,7 +6261,7 @@ var createRoleBaseXpathSelector = (role) => {
|
|
|
6141
6261
|
};
|
|
6142
6262
|
|
|
6143
6263
|
// src/commands/element/shadow$$.ts
|
|
6144
|
-
var
|
|
6264
|
+
var log19 = logger19("webdriverio");
|
|
6145
6265
|
async function shadow$$(selector) {
|
|
6146
6266
|
const browser = getBrowserObject28(this);
|
|
6147
6267
|
try {
|
|
@@ -6151,7 +6271,7 @@ async function shadow$$(selector) {
|
|
|
6151
6271
|
const elements = await getElements.call(this, selector, res, { isShadowElement: true });
|
|
6152
6272
|
return enhanceElementsArray(elements, this, selector);
|
|
6153
6273
|
} catch (err) {
|
|
6154
|
-
|
|
6274
|
+
log19.warn(
|
|
6155
6275
|
`Failed to fetch element within shadow DOM using WebDriver command: ${err.message}!
|
|
6156
6276
|
Falling back to JavaScript shim.`
|
|
6157
6277
|
);
|
|
@@ -6160,11 +6280,11 @@ Falling back to JavaScript shim.`
|
|
|
6160
6280
|
}
|
|
6161
6281
|
|
|
6162
6282
|
// src/commands/element/shadow$.ts
|
|
6163
|
-
import
|
|
6283
|
+
import logger20 from "@wdio/logger";
|
|
6164
6284
|
import { SHADOW_ELEMENT_KEY as SHADOW_ELEMENT_KEY2 } from "webdriver";
|
|
6165
6285
|
import { shadowFnFactory as shadowFnFactory2 } from "./scripts/shadowFnFactory.js";
|
|
6166
6286
|
import { getBrowserObject as getBrowserObject29 } from "@wdio/utils";
|
|
6167
|
-
var
|
|
6287
|
+
var log20 = logger20("webdriverio");
|
|
6168
6288
|
async function shadow$(selector) {
|
|
6169
6289
|
const browser = getBrowserObject29(this);
|
|
6170
6290
|
try {
|
|
@@ -6173,7 +6293,7 @@ async function shadow$(selector) {
|
|
|
6173
6293
|
const res = await browser.findElementFromShadowRoot(shadowRoot[SHADOW_ELEMENT_KEY2], using, value);
|
|
6174
6294
|
return getElement.call(this, selector, res, { isShadowElement: true });
|
|
6175
6295
|
} catch (err) {
|
|
6176
|
-
|
|
6296
|
+
log20.warn(
|
|
6177
6297
|
`Failed to fetch element within shadow DOM using WebDriver command: ${err.message}!
|
|
6178
6298
|
Falling back to JavaScript shim.`
|
|
6179
6299
|
);
|
|
@@ -6472,7 +6592,7 @@ function querySelectorAllDeep(findMany, s, r) {
|
|
|
6472
6592
|
}
|
|
6473
6593
|
|
|
6474
6594
|
// src/utils/index.ts
|
|
6475
|
-
var
|
|
6595
|
+
var log21 = logger21("webdriverio");
|
|
6476
6596
|
var INVALID_SELECTOR_ERROR = "selector needs to be typeof `string` or `function`";
|
|
6477
6597
|
var IGNORED_COMMAND_FILE_EXPORTS = ["SESSION_MOCKS", "CDP_SESSIONS"];
|
|
6478
6598
|
var scopes = {
|
|
@@ -6502,8 +6622,8 @@ var getElementFromResponse = (res) => {
|
|
|
6502
6622
|
if (res.ELEMENT) {
|
|
6503
6623
|
return res.ELEMENT;
|
|
6504
6624
|
}
|
|
6505
|
-
if (res[
|
|
6506
|
-
return res[
|
|
6625
|
+
if (res[ELEMENT_KEY18]) {
|
|
6626
|
+
return res[ELEMENT_KEY18];
|
|
6507
6627
|
}
|
|
6508
6628
|
return null;
|
|
6509
6629
|
};
|
|
@@ -6610,7 +6730,7 @@ async function findDeepElement(selector) {
|
|
|
6610
6730
|
const startNodes = shadowRoots.length > 0 ? shadowRoots.map((shadowRootNodeId) => ({ sharedId: shadowRootNodeId })) : this.elementId ? [{ sharedId: this.elementId }] : void 0;
|
|
6611
6731
|
const deepElementResult = await browser.browsingContextLocateNodes({ locator, context, startNodes }).then(async (result) => {
|
|
6612
6732
|
const nodes = result.nodes.filter((node) => Boolean(node.sharedId)).map((node) => ({
|
|
6613
|
-
[
|
|
6733
|
+
[ELEMENT_KEY18]: node.sharedId,
|
|
6614
6734
|
locator
|
|
6615
6735
|
}));
|
|
6616
6736
|
if (!this.elementId) {
|
|
@@ -6619,15 +6739,15 @@ async function findDeepElement(selector) {
|
|
|
6619
6739
|
const scopedNodes = await Promise.all(nodes.map(async (node) => {
|
|
6620
6740
|
const isIn = await browser.execute(
|
|
6621
6741
|
elementContains,
|
|
6622
|
-
{ [
|
|
6742
|
+
{ [ELEMENT_KEY18]: this.elementId },
|
|
6623
6743
|
node
|
|
6624
6744
|
);
|
|
6625
6745
|
return [isIn, node];
|
|
6626
6746
|
})).then((elems) => elems.filter(([isIn]) => isIn).map(([, elem]) => elem));
|
|
6627
6747
|
return scopedNodes[0];
|
|
6628
6748
|
}, (err) => {
|
|
6629
|
-
|
|
6630
|
-
return browser.findElement(using, value);
|
|
6749
|
+
log21.warn(`Failed to execute browser.browsingContextLocateNodes({ ... }) due to ${err}, falling back to regular WebDriver Classic command`);
|
|
6750
|
+
return this && "elementId" in this && this.elementId ? this.findElementFromElement(this.elementId, using, value) : browser.findElement(using, value);
|
|
6631
6751
|
});
|
|
6632
6752
|
if (!deepElementResult) {
|
|
6633
6753
|
return new Error(`Couldn't find element with selector "${selector}"`);
|
|
@@ -6648,7 +6768,7 @@ async function findDeepElements(selector) {
|
|
|
6648
6768
|
const startNodes = shadowRoots.length > 0 ? shadowRoots.map((shadowRootNodeId) => ({ sharedId: shadowRootNodeId })) : this.elementId ? [{ sharedId: this.elementId }] : void 0;
|
|
6649
6769
|
const deepElementResult = await browser.browsingContextLocateNodes({ locator, context, startNodes }).then(async (result) => {
|
|
6650
6770
|
const nodes = result.nodes.filter((node) => Boolean(node.sharedId)).map((node) => ({
|
|
6651
|
-
[
|
|
6771
|
+
[ELEMENT_KEY18]: node.sharedId,
|
|
6652
6772
|
locator
|
|
6653
6773
|
}));
|
|
6654
6774
|
if (!this.elementId) {
|
|
@@ -6657,15 +6777,15 @@ async function findDeepElements(selector) {
|
|
|
6657
6777
|
const scopedNodes = await Promise.all(nodes.map(async (node) => {
|
|
6658
6778
|
const isIn = await browser.execute(
|
|
6659
6779
|
elementContains,
|
|
6660
|
-
{ [
|
|
6780
|
+
{ [ELEMENT_KEY18]: this.elementId },
|
|
6661
6781
|
node
|
|
6662
6782
|
);
|
|
6663
6783
|
return [isIn, node];
|
|
6664
6784
|
})).then((elems) => elems.filter(([isIn]) => isIn).map(([, elem]) => elem));
|
|
6665
6785
|
return scopedNodes;
|
|
6666
6786
|
}, (err) => {
|
|
6667
|
-
|
|
6668
|
-
return browser.findElements(using, value);
|
|
6787
|
+
log21.warn(`Failed to execute browser.browsingContextLocateNodes({ ... }) due to ${err}, falling back to regular WebDriver Classic command`);
|
|
6788
|
+
return this && "elementId" in this && this.elementId ? this.findElementsFromElement(this.elementId, using, value) : browser.findElements(using, value);
|
|
6669
6789
|
});
|
|
6670
6790
|
return deepElementResult;
|
|
6671
6791
|
}
|
|
@@ -6761,7 +6881,7 @@ function verifyArgsAndStripIfElement(args) {
|
|
|
6761
6881
|
throw new Error(`The element with selector "${elem.selector}" you are trying to pass into the execute method wasn't found`);
|
|
6762
6882
|
}
|
|
6763
6883
|
return {
|
|
6764
|
-
[
|
|
6884
|
+
[ELEMENT_KEY18]: elem.elementId,
|
|
6765
6885
|
ELEMENT: elem.elementId
|
|
6766
6886
|
};
|
|
6767
6887
|
}
|
|
@@ -6792,7 +6912,7 @@ async function getElementRect(scope) {
|
|
|
6792
6912
|
if (rectJs && typeof rectJs[key] === "number") {
|
|
6793
6913
|
rect[key] = Math.floor(rectJs[key]);
|
|
6794
6914
|
} else {
|
|
6795
|
-
|
|
6915
|
+
log21.error("getElementRect", { rect, rectJs, key });
|
|
6796
6916
|
throw new Error("Failed to receive element rects via execute command");
|
|
6797
6917
|
}
|
|
6798
6918
|
});
|
|
@@ -6867,7 +6987,7 @@ var elementErrorHandler = (fn) => (commandName, commandFn) => {
|
|
|
6867
6987
|
}
|
|
6868
6988
|
const element = await implicitWait(this, commandName);
|
|
6869
6989
|
this.elementId = element.elementId;
|
|
6870
|
-
this[
|
|
6990
|
+
this[ELEMENT_KEY19] = element.elementId;
|
|
6871
6991
|
try {
|
|
6872
6992
|
const result = await fn(commandName, commandFn).apply(this, args);
|
|
6873
6993
|
const caps = getBrowserObject31(this).capabilities;
|
|
@@ -7160,6 +7280,8 @@ function detectBackend(options = {}) {
|
|
|
7160
7280
|
|
|
7161
7281
|
// src/protocol-stub.ts
|
|
7162
7282
|
import { capabilitiesEnvironmentDetector } from "@wdio/utils";
|
|
7283
|
+
var NOOP2 = () => {
|
|
7284
|
+
};
|
|
7163
7285
|
var ProtocolStub = class {
|
|
7164
7286
|
static async newSession(options) {
|
|
7165
7287
|
const capabilities = emulateSessionCapabilities(options.capabilities);
|
|
@@ -7172,6 +7294,9 @@ var ProtocolStub = class {
|
|
|
7172
7294
|
overwrittenCommands: [],
|
|
7173
7295
|
// internally used to transfer overwritten commands to the actual protocol instance
|
|
7174
7296
|
commandList: [],
|
|
7297
|
+
getWindowHandle: NOOP2,
|
|
7298
|
+
on: NOOP2,
|
|
7299
|
+
off: NOOP2,
|
|
7175
7300
|
...capabilitiesEnvironmentDetector(capabilities)
|
|
7176
7301
|
};
|
|
7177
7302
|
browser.addCommand = (...args) => browser.customCommands.push(args);
|
|
@@ -7239,7 +7364,7 @@ var DialogManager = class {
|
|
|
7239
7364
|
#autoHandleDialog = true;
|
|
7240
7365
|
constructor(browser) {
|
|
7241
7366
|
this.#browser = browser;
|
|
7242
|
-
if (!browser.isBidi || process.env.
|
|
7367
|
+
if (!browser.isBidi || process.env.WDIO_UNIT_TESTS || browser.options?.automationProtocol !== "webdriver") {
|
|
7243
7368
|
this.#initialize = Promise.resolve(true);
|
|
7244
7369
|
return;
|
|
7245
7370
|
}
|
|
@@ -7256,14 +7381,14 @@ var DialogManager = class {
|
|
|
7256
7381
|
/**
|
|
7257
7382
|
* capture shadow root elements propagated through console.debug
|
|
7258
7383
|
*/
|
|
7259
|
-
async #handleUserPrompt(
|
|
7384
|
+
async #handleUserPrompt(log22) {
|
|
7260
7385
|
if (this.#autoHandleDialog) {
|
|
7261
7386
|
return this.#browser.browsingContextHandleUserPrompt({
|
|
7262
7387
|
accept: false,
|
|
7263
|
-
context:
|
|
7388
|
+
context: log22.context
|
|
7264
7389
|
});
|
|
7265
7390
|
}
|
|
7266
|
-
const dialog = new Dialog(
|
|
7391
|
+
const dialog = new Dialog(log22, this.#browser);
|
|
7267
7392
|
this.#browser.emit("dialog", dialog);
|
|
7268
7393
|
}
|
|
7269
7394
|
/**
|
|
@@ -7326,7 +7451,7 @@ var remote = async function(params, remoteModifier) {
|
|
|
7326
7451
|
const keysToKeep = Object.keys(process.env.WDIO_WORKER_ID ? params : DEFAULTS);
|
|
7327
7452
|
const config = validateConfig(WDIO_DEFAULTS, params, keysToKeep);
|
|
7328
7453
|
await enableFileLogging(config.outputDir);
|
|
7329
|
-
|
|
7454
|
+
logger22.setLogLevelsConfig(config.logLevels, config.logLevel);
|
|
7330
7455
|
const modifier = (client, options2) => {
|
|
7331
7456
|
Object.assign(options2, Object.entries(config).reduce((a, [k, v]) => typeof v === "undefined" ? a : { ...a, [k]: v }, {}));
|
|
7332
7457
|
if (typeof remoteModifier === "function") {
|