Socket
Socket
Sign inDemoInstall

webdriverio

Package Overview
Dependencies
Maintainers
3
Versions
708
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

webdriverio - npm Package Compare versions

Comparing version 9.0.0-alpha.369 to 9.0.0-alpha.426

build/clock.d.ts

2

build/commands/browser.d.ts

@@ -5,2 +5,3 @@ export * from './browser/$$.js';

export * from './browser/actions.js';
export * from './browser/addInitScript.js';
export * from './browser/call.js';

@@ -27,2 +28,3 @@ export * from './browser/custom$$.js';

export * from './browser/reloadSession.js';
export * from './browser/restore.js';
export * from './browser/savePDF.js';

@@ -29,0 +31,0 @@ export * from './browser/saveRecordingScreen.js';

@@ -5,2 +5,3 @@ export * from './browser/$$.js';

export * from './browser/actions.js';
export * from './browser/addInitScript.js';
export * from './browser/call.js';

@@ -27,2 +28,3 @@ export * from './browser/custom$$.js';

export * from './browser/reloadSession.js';
export * from './browser/restore.js';
export * from './browser/savePDF.js';

@@ -29,0 +31,0 @@ export * from './browser/saveRecordingScreen.js';

43

build/commands/browser/emulate.d.ts

@@ -1,36 +0,11 @@

type SupportedScopes = 'geolocation' | 'userAgent' | 'colorScheme' | 'onLine';
interface EmulationOptions {
geolocation: Partial<GeolocationCoordinates>;
userAgent: string;
colorScheme: 'light' | 'dark';
onLine: boolean;
}
/**
* WebdriverIO allows you to emulate Web APIs using the `emulate` command. These Web APIs can then
* behave exactly as you specify it.
*
* Read more on this in the [Emulation](/docs/emulation) guidelines.
*
* :::info
*
* It is not possible to change the emulated value without reloading the page.
*
* :::
*
* :::info
*
* This feature requires WebDriver Bidi support for the browser. While recent versions of Chrome, Edge
* and Firefox have such support, Safari __does not__. For updates follow [wpt.fyi](https://wpt.fyi/results/webdriver/tests/bidi/script/add_preload_script/add_preload_script.py?label=experimental&label=master&aligned).
* Furthermore if you use a cloud vendor for spawning browsers, make sure your vendor also supports WebDriver Bidi.
*
* :::
*
* @param {string} scope feature of the browser you like to emulate, can be either `geolocation`, `userAgent`, `colorScheme` or `onLine`
* @param {EmulationOptions} options emulation option for specific scope
* @example https://github.com/webdriverio/example-recipes/blob/9bff2baf8a0678c6886f8591d9fc8dea201895d3/emulate/example.js#L4-L18
* @example https://github.com/webdriverio/example-recipes/blob/9bff2baf8a0678c6886f8591d9fc8dea201895d3/emulate/example.js#L20-L36
* @returns `void`
*/
export declare function emulate<Scope extends SupportedScopes>(this: WebdriverIO.Browser, scope: Scope, options: EmulationOptions[Scope]): Promise<void>;
import type { FakeTimerInstallOpts } from '@sinonjs/fake-timers';
import { ClockManager } from '../../clock.js';
type RestoreFunction = () => Promise<any>;
type ColorScheme = 'light' | 'dark';
export declare function emulate(scope: 'clock', options?: FakeTimerInstallOpts): Promise<ClockManager>;
export declare function emulate(scope: 'geolocation', geolocation: Partial<GeolocationCoordinates>): Promise<RestoreFunction>;
export declare function emulate(scope: 'userAgent', userAgent: string): Promise<RestoreFunction>;
export declare function emulate(scope: 'colorScheme', colorScheme: ColorScheme): Promise<RestoreFunction>;
export declare function emulate(scope: 'onLine', state: boolean): Promise<RestoreFunction>;
export {};
//# sourceMappingURL=emulate.d.ts.map

@@ -0,5 +1,23 @@

import { restoreFunctions, ClockManager } from '../../clock.js';
function storeRestoreFunction(browser, scope, fn) {
if (!restoreFunctions.has(browser)) {
restoreFunctions.set(browser, new Map());
}
const restoreFunctionsList = restoreFunctions.get(browser)?.get(scope);
const updatedList = restoreFunctionsList ? [...restoreFunctionsList, fn] : [fn];
restoreFunctions.get(browser)?.set(scope, updatedList);
}
/**
* WebdriverIO allows you to emulate Web APIs using the `emulate` command. These Web APIs can then
* behave exactly as you specify it.
* behave exactly as you specify it. The following scopes are supported:
*
* - `geolocation`: Emulate the geolocation API
* - `userAgent`: Emulate the user agent
* - `colorScheme`: Emulate the color scheme
* - `onLine`: Emulate the online status
* - `clock`: Emulate the system clock
*
* The `emulate` command returns a function that can be called to reset the emulation. This is useful
* when you want to reset the emulation after a test or a suite of tests.
*
* Read more on this in the [Emulation](/docs/emulation) guidelines.

@@ -9,3 +27,3 @@ *

*
* It is not possible to change the emulated value without reloading the page.
* Except for the `clock` scope it is not possible to change the emulated value without reloading the page.
*

@@ -22,7 +40,53 @@ * :::

*
* @param {string} scope feature of the browser you like to emulate, can be either `geolocation`, `userAgent`, `colorScheme` or `onLine`
* Based on the scope you can pass different options:
*
* | Scope | Options |
* |---------------|--------------------------------------------------|
* | `geolocation` | `{ latitude: number, longitude: number }` |
* | `userAgent` | `string` |
* | `colorScheme` | `'light' | 'dark'` |
* | `onLine` | `boolean` |
* | `clock` | `FakeTimerInstallOpts` |
*
* The `FakeTimerInstallOpts` object can have the following properties:
*
* ```ts
* interface FakeTimerInstallOpts {
* // Installs fake timers with the specified unix epoch
* // @default: 0
* now?: number | Date | undefined;
* // An array with names of global methods and APIs to fake. By default, WebdriverIO
* // does not replace `nextTick()` and `queueMicrotask()`. For instance,
* // `browser.emulate('clock', { toFake: ['setTimeout', 'nextTick'] })` will fake only
* // `setTimeout()` and `nextTick()`
* toFake?: FakeMethod[] | undefined;
* // The maximum number of timers that will be run when calling runAll() (default: 1000)
* loopLimit?: number | undefined;
* // Tells WebdriverIO to increment mocked time automatically based on the real system
* // time shift (e.g. the mocked time will be incremented by 20ms for every 20ms change
* // in the real system time)
* // @default false
* shouldAdvanceTime?: boolean | undefined;
* // Relevant only when using with shouldAdvanceTime: true. increment mocked time by
* // advanceTimeDelta ms every advanceTimeDelta ms change in the real system time
* // @default: 20
* advanceTimeDelta?: number | undefined;
* // Tells FakeTimers to clear 'native' (i.e. not fake) timers by delegating to their
* // respective handlers. These are not cleared by default, leading to potentially
* // unexpected behavior if timers existed prior to installing FakeTimers.
* // @default: false
* shouldClearNativeTimers?: boolean | undefined;
* }
* ```
*
* @param {string} scope feature of the browser you like to emulate, can be either `clock`, `geolocation`, `userAgent`, `colorScheme` or `onLine`
* @param {EmulationOptions} options emulation option for specific scope
* @example https://github.com/webdriverio/example-recipes/blob/9bff2baf8a0678c6886f8591d9fc8dea201895d3/emulate/example.js#L4-L18
* @example https://github.com/webdriverio/example-recipes/blob/9bff2baf8a0678c6886f8591d9fc8dea201895d3/emulate/example.js#L20-L36
* @returns `void`
* @returns {Function} a function to reset the emulation
*/

@@ -43,3 +107,3 @@ export async function emulate(scope, options) {

})`;
await this.scriptAddPreloadScript({
const res = await this.scriptAddPreloadScript({
functionDeclaration: /*js*/ `() => {

@@ -51,3 +115,5 @@ Object.defineProperty(navigator.geolocation, 'getCurrentPosition', {

});
return;
const resetFn = async () => this.scriptRemovePreloadScript({ script: res.script });
storeRestoreFunction(this, 'geolocation', resetFn);
return resetFn;
}

@@ -58,3 +124,3 @@ if (scope === 'userAgent') {

}
await this.scriptAddPreloadScript({
const res = await this.scriptAddPreloadScript({
functionDeclaration: /*js*/ `() => {

@@ -66,4 +132,14 @@ Object.defineProperty(navigator, 'userAgent', {

});
return;
const resetFn = async () => {
return this.scriptRemovePreloadScript({ script: res.script });
};
storeRestoreFunction(this, 'userAgent', resetFn);
return resetFn;
}
if (scope === 'clock') {
const clock = new ClockManager(this);
await clock.install(options);
storeRestoreFunction(this, 'clock', clock.restore.bind(clock));
return clock;
}
if (scope === 'colorScheme') {

@@ -73,3 +149,3 @@ if (options !== 'light' && options !== 'dark') {

}
await this.scriptAddPreloadScript({
const res = await this.scriptAddPreloadScript({
functionDeclaration: /*js*/ `() => {

@@ -95,3 +171,5 @@ const originalMatchMedia = window.matchMedia

});
return;
const resetFn = async () => this.scriptRemovePreloadScript({ script: res.script });
storeRestoreFunction(this, 'colorScheme', resetFn);
return resetFn;
}

@@ -102,3 +180,3 @@ if (scope === 'onLine') {

}
await this.scriptAddPreloadScript({
const res = await this.scriptAddPreloadScript({
functionDeclaration: /*js*/ `() => {

@@ -110,5 +188,7 @@ Object.defineProperty(navigator, 'onLine', {

});
return;
const resetFn = async () => this.scriptRemovePreloadScript({ script: res.script });
storeRestoreFunction(this, 'onLine', resetFn);
return resetFn;
}
return;
throw new Error(`Invalid scope "${scope}", expected one of "geolocation", "userAgent", "colorScheme", "onLine" or "clock"`);
}

@@ -1,2 +0,1 @@

/// <reference types="node" resolution-mode="require"/>
type PDFPrintOptions = {

@@ -3,0 +2,0 @@ orientation?: string;

@@ -1,2 +0,1 @@

/// <reference types="node" resolution-mode="require"/>
/**

@@ -3,0 +2,0 @@ *

@@ -1,2 +0,1 @@

/// <reference types="node" resolution-mode="require"/>
/**

@@ -3,0 +2,0 @@ *

@@ -0,14 +1,93 @@

type WaitState = 'none' | 'interactive' | 'networkIdle' | 'complete';
interface UrlCommandOptions {
/**
* The desired state the requested resource should be in before finishing the command.
* It supports the following states:
*
* - `none`: no wait after the page request is made and the response is received
* - `interactive`: wait until the page is interactive
* - `complete`: wait until the DOM tree of the page is fully loaded
* - `networkIdle`: wait until there are no pending network requests
*
* @default 'complete'
*/
wait?: WaitState;
/**
* Headers to be sent with the request.
* @default {}
*/
headers?: Record<string, string>;
/**
* Basic authentication credentials
* Note: this will overwrite the existing `Authorization` header if provided in the `headers` option
*/
auth?: {
user: string;
pass: string;
};
/**
* If set to a number, the command will wait for the specified amount of milliseconds for the page to load
* all responses before returning.
*
* Note: for this to have an impact, it requires the `wait` option to be set to `networkIdle`
*
* @default 5000
*/
timeout?: number;
/**
* A function that is being called before your page has loaded all of its resources. It allows you to easily
* mock the environment, e.g. overwrite Web APIs that your application uses.
*
* Note: the provided function is being serialized and executed in the browser context. You can not pass in variables
* from the Node.js context. Furthermore changes to the environment only apply for this specific page load.
* Checkout `browser.addPreloadScript` for a more versatile way to mock the environment.
*/
onBeforeLoad?: () => any;
}
/**
*
* Protocol binding to load the URL of the browser. If a baseUrl is
* specified in the config, it will be prepended to the url parameter using
* node's url.resolve() method. Calling `browser.url('...')` with the same url as last
* time will trigger a page reload.
* The `url` command loads an URL in the browser. If a baseUrl is specified in the config,
* it will be prepended to the url parameter using node's url.resolve() method. Calling
* `browser.url('...')` with the same url as last time will trigger a page reload.
*
* The command returns an `WebdriverIO.Request` object that contains information about the
* request and response data of the page load.
*
* The command supports the following options:
*
* ### wait
* The desired state the requested resource should be in before finishing the command.
* It supports the following states:
*
* - `none`: no wait after the page request is made and the response is received
* - `interactive`: wait until the page is interactive
* - `complete`: wait until the DOM tree of the page is fully loaded
* - `networkIdle`: wait until there are no pending network requests
*
* ### headers
*
* Headers to be sent with the request.
*
* __Default:__ `{}`
*
* ### auth
*
* Basic authentication credentials.
* Note: this will overwrite the existing `Authorization` header if provided in the `headers` option.
*
* ### timeout
*
* If set to a number, the command will wait for the specified amount of milliseconds for the page to load
* all responses before returning.
*
* Note: for this to have an impact, it requires the `wait` option to be set to `networkIdle`.
*
* __Default:__ `5000`
*
* <example>
:url.js
// navigate to a new URL
await browser.url('https://webdriver.io');
// receive url
console.log(await browser.getUrl()); // outputs: "https://webdriver.io"
const request = await browser.url('https://webdriver.io');
// log url
console.log(request.url); // outputs: "https://webdriver.io"

@@ -28,5 +107,36 @@ :baseUrlResolutions.js

await browser.url('/rootRelative');
:basicAuth.js
// navigate to a URL with basic authentication
await browser.url('https://the-internet.herokuapp.com/basic_auth', {
auth: {
user
pass
}
});
await expect($('p=Congratulations! You must have the proper credentials.).toBeDisplayed();
:onBeforeLoad.js
// navigate to a URL and mock the battery API
await browser.url('https://pazguille.github.io/demo-battery-api/', {
onBeforeLoad (win) {
// mock "navigator.battery" property
// returning mock charge object
win.navigator.getBattery = () => Promise.resolve({
level: 0.5,
charging: false,
chargingTime: Infinity,
dischargingTime: 3600, // seconds
})
}
})
// now we can assert actual text - we are charged at 50%
await expect($('.battery-percentage')).toHaveText('50%')
// and has enough juice for 1 hour
await expect($('.battery-remaining')).toHaveText('01:00)
* </example>
*
* @param {String=} url the URL to navigate to
* @param {UrlOptions=} options navigation options
* @returns {WebdriverIO.Request} a request object of the page load with information about the request and response data
*

@@ -38,3 +148,4 @@ * @see https://w3c.github.io/webdriver/webdriver-spec.html#dfn-get

*/
export declare function url(this: WebdriverIO.Browser, path: string): Promise<string>;
export declare function url(this: WebdriverIO.Browser, path: string, options?: UrlCommandOptions): Promise<WebdriverIO.Request | void>;
export {};
//# sourceMappingURL=url.d.ts.map
import { validateUrl } from '../../utils/index.js';
import { networkManager } from '../../networkManager.js';
const DEFAULT_NETWORK_IDLE_TIMEOUT = 5000;
const DEFAULT_WAIT_STATE = 'complete';
/**
*
* Protocol binding to load the URL of the browser. If a baseUrl is
* specified in the config, it will be prepended to the url parameter using
* node's url.resolve() method. Calling `browser.url('...')` with the same url as last
* time will trigger a page reload.
* The `url` command loads an URL in the browser. If a baseUrl is specified in the config,
* it will be prepended to the url parameter using node's url.resolve() method. Calling
* `browser.url('...')` with the same url as last time will trigger a page reload.
*
* The command returns an `WebdriverIO.Request` object that contains information about the
* request and response data of the page load.
*
* The command supports the following options:
*
* ### wait
* The desired state the requested resource should be in before finishing the command.
* It supports the following states:
*
* - `none`: no wait after the page request is made and the response is received
* - `interactive`: wait until the page is interactive
* - `complete`: wait until the DOM tree of the page is fully loaded
* - `networkIdle`: wait until there are no pending network requests
*
* ### headers
*
* Headers to be sent with the request.
*
* __Default:__ `{}`
*
* ### auth
*
* Basic authentication credentials.
* Note: this will overwrite the existing `Authorization` header if provided in the `headers` option.
*
* ### timeout
*
* If set to a number, the command will wait for the specified amount of milliseconds for the page to load
* all responses before returning.
*
* Note: for this to have an impact, it requires the `wait` option to be set to `networkIdle`.
*
* __Default:__ `5000`
*
* <example>
:url.js
// navigate to a new URL
await browser.url('https://webdriver.io');
// receive url
console.log(await browser.getUrl()); // outputs: "https://webdriver.io"
const request = await browser.url('https://webdriver.io');
// log url
console.log(request.url); // outputs: "https://webdriver.io"

@@ -29,5 +65,36 @@ :baseUrlResolutions.js

await browser.url('/rootRelative');
:basicAuth.js
// navigate to a URL with basic authentication
await browser.url('https://the-internet.herokuapp.com/basic_auth', {
auth: {
user
pass
}
});
await expect($('p=Congratulations! You must have the proper credentials.).toBeDisplayed();
:onBeforeLoad.js
// navigate to a URL and mock the battery API
await browser.url('https://pazguille.github.io/demo-battery-api/', {
onBeforeLoad (win) {
// mock "navigator.battery" property
// returning mock charge object
win.navigator.getBattery = () => Promise.resolve({
level: 0.5,
charging: false,
chargingTime: Infinity,
dischargingTime: 3600, // seconds
})
}
})
// now we can assert actual text - we are charged at 50%
await expect($('.battery-percentage')).toHaveText('50%')
// and has enough juice for 1 hour
await expect($('.battery-remaining')).toHaveText('01:00)
* </example>
*
* @param {String=} url the URL to navigate to
* @param {UrlOptions=} options navigation options
* @returns {WebdriverIO.Request} a request object of the page load with information about the request and response data
*

@@ -39,3 +106,3 @@ * @see https://w3c.github.io/webdriver/webdriver-spec.html#dfn-get

*/
export async function url(path) {
export async function url(path, options = {}) {
if (typeof path !== 'string') {

@@ -48,11 +115,58 @@ throw new Error('Parameter for "url" command needs to be type of string');

if (this.isBidi) {
let resetPreloadScript = async () => { };
const context = await this.getWindowHandle();
const res = await this.browsingContextNavigate({
/**
* set up preload script if `onBeforeLoad` option is provided
*/
if (options.onBeforeLoad) {
if (typeof options.onBeforeLoad !== 'function') {
throw new Error(`Option "onBeforeLoad" must be a function, but received: ${typeof options.onBeforeLoad}`);
}
resetPreloadScript = await this.addInitScript(options.onBeforeLoad);
}
if (options.auth) {
options.headers = {
...(options.headers || {}),
Authorization: `Basic ${btoa(`${options.auth.user}:${options.auth.pass}`)}`
};
}
let mock;
if (options.headers) {
mock = await this.mock(path);
mock.requestOnce({ headers: options.headers });
}
const wait = options.wait === 'networkIdle'
? 'complete'
: options.wait || DEFAULT_WAIT_STATE;
await this.browsingContextNavigate({
context,
url: path,
wait: 'interactive'
wait
});
return res.url;
const network = networkManager.get(this);
const request = network?.getRequestResponseData(context);
if (mock) {
await mock.restore();
}
if (network && options.wait === 'networkIdle') {
const timeout = options.timeout || DEFAULT_NETWORK_IDLE_TIMEOUT;
await this.waitUntil(async () => {
return network.getPendingRequests(context).length === 0;
}, {
timeout,
timeoutMsg: `Navigation to '${path}' timed out after ${timeout}ms with ${network.getPendingRequests(context).length} (${network.getPendingRequests(context).map((r) => r.url).join(', ')}) pending requests`
});
}
/**
* clear up preload script
*/
if (resetPreloadScript) {
await resetPreloadScript();
}
return request;
}
return this.navigateTo(validateUrl(path));
if (Object.keys(options).length > 0) {
throw new Error('Setting url options is only supported when automating browser using WebDriver Bidi protocol');
}
await this.navigateTo(validateUrl(path));
}

@@ -1,2 +0,1 @@

/// <reference types="node" resolution-mode="require"/>
/**

@@ -3,0 +2,0 @@ *

@@ -21,3 +21,3 @@ /**

*/
export declare function shadow$$(this: WebdriverIO.Element, selector: string): Promise<WebdriverIO.ElementArray | import("../../types.js").ChainablePromiseArray>;
export declare function shadow$$(this: WebdriverIO.Element, selector: string): Promise<import("../../types.js").ChainablePromiseArray | WebdriverIO.ElementArray>;
//# sourceMappingURL=shadow$$.d.ts.map

@@ -7,5 +7,3 @@ import type { Capabilities } from '@wdio/types';

export declare const Key: {
readonly Ctrl: "WDIO_CONTROL"; /**
* we need to overwrite the original addCommand and overwriteCommand
*/
readonly Ctrl: "WDIO_CONTROL";
readonly NULL: "";

@@ -37,5 +35,2 @@ readonly Cancel: "";

readonly Equals: "";
/**
* copy instances properties into new object
*/
readonly Numpad0: "";

@@ -42,0 +37,0 @@ readonly Numpad1: "";

@@ -12,2 +12,4 @@ import logger from '@wdio/logger';

import { getShadowRootManager } from './shadowRoot.js';
import { getNetworkManager } from './networkManager.js';
import { getDialogManager } from './dialog.js';
export * from './types.js';

@@ -59,3 +61,7 @@ export const Key = KeyConstant;

instance.addLocatorStrategy = addLocatorStrategyHandler(instance);
await getShadowRootManager(instance).initialize();
await Promise.all([
getShadowRootManager(instance).initialize(),
getNetworkManager(instance).initialize(),
getDialogManager(instance).initialize()
]);
return instance;

@@ -79,3 +85,7 @@ };

// @ts-expect-error `bidiHandler` is a private property
await driver._bidiHandler?.connect().then(() => getShadowRootManager(driver).initialize());
await driver._bidiHandler?.connect().then(() => (Promise.all([
getShadowRootManager(driver).initialize(),
getNetworkManager(driver).initialize(),
getDialogManager(driver).initialize()
])));
return driver;

@@ -82,0 +92,0 @@ };

@@ -6,2 +6,3 @@ import { ELEMENT_KEY } from 'webdriver';

import { isStaleElementError } from './utils/index.js';
const COMMANDS_TO_SKIP = ['getElement', 'getElements'];
/**

@@ -16,2 +17,5 @@ * This method is an command wrapper for elements that checks if a command is called

return fn(commandName, async function elementErrorHandlerCallbackFn() {
if (COMMANDS_TO_SKIP.includes(commandName)) {
return fn(commandName, commandFn).apply(this, args);
}
const element = await implicitWait(this, commandName);

@@ -18,0 +22,0 @@ this.elementId = element.elementId;

@@ -42,3 +42,3 @@ import type { Options } from '@wdio/types';

*/
commandWrapper(commandName: keyof (ProtocolCommands & BrowserCommandsType) & 'getInstance'): ((this: Record<string, WebdriverIO.Browser | WebdriverIO.Element>, browserName: string) => WebdriverIO.Element | WebdriverIO.Browser) | ((...args: any) => Promise<unknown>);
commandWrapper(commandName: keyof (ProtocolCommands & BrowserCommandsType) & 'getInstance'): ((this: Record<string, WebdriverIO.Browser | WebdriverIO.Element>, browserName: string) => WebdriverIO.Browser | WebdriverIO.Element) | ((...args: any) => Promise<unknown>);
}

@@ -45,0 +45,0 @@ /**

@@ -13,2 +13,7 @@ import { type local } from 'webdriver';

/**
* check if we are within a frame
* @returns {boolean} true if we are within a frame
*/
isWithinFrame(): boolean;
/**
* capture shadow root elements propagated through console.debug

@@ -15,0 +20,0 @@ */

@@ -21,2 +21,3 @@ import customElementWrapper from './scripts/customElement.js';

#shadowRoots = new Map();
#frameDepth = 0;
constructor(browser) {

@@ -38,2 +39,3 @@ this.#browser = browser;

this.#browser.on('log.entryAdded', this.handleLogEntry.bind(this));
this.#browser.on('result', this.#commandResultHandler.bind(this));
browser.scriptAddPreloadScript({

@@ -47,2 +49,20 @@ functionDeclaration: customElementWrapper.toString()

/**
* keep track of frame depth
*/
#commandResultHandler(result) {
if (result.command === 'switchToFrame' && !result.result.error) {
this.#frameDepth++;
}
if (result.command === 'switchToParentFrame' && !result.result.error) {
this.#frameDepth = Math.max(0, this.#frameDepth - 1);
}
}
/**
* check if we are within a frame
* @returns {boolean} true if we are within a frame
*/
isWithinFrame() {
return this.#frameDepth > 0;
}
/**
* capture shadow root elements propagated through console.debug

@@ -49,0 +69,0 @@ */

@@ -1,7 +0,7 @@

/// <reference types="node" resolution-mode="require"/>
import type { EventEmitter } from 'node:events';
import type { remote, SessionFlags, AttachOptions as WebDriverAttachOptions, BidiHandler, BidiEventHandler } from 'webdriver';
import type { remote, SessionFlags, AttachOptions as WebDriverAttachOptions, BidiHandler, EventMap } from 'webdriver';
import type { Capabilities, Options, ThenArg } from '@wdio/types';
import type { ElementReference, ProtocolCommands } from '@wdio/protocols';
import type { Browser as PuppeteerBrowser } from 'puppeteer-core';
import type { Dialog as DialogImport } from './dialog.js';
import type * as BrowserCommands from './commands/browser.js';

@@ -44,3 +44,3 @@ import type * as ElementCommands from './commands/element.js';

* - a string if `findElement` was used and a reference was found
* - or a functin if element was found via e.g. `$(() => document.body)`
* - or a function if element was found via e.g. `$(() => document.body)`
*/

@@ -215,2 +215,9 @@ selector: Promise<Selector>;

}
type WebdriverIOEventMap = EventMap & {
'dialog': WebdriverIO.Dialog;
};
interface BidiEventHandler {
on<K extends keyof WebdriverIOEventMap>(event: K, listener: (this: WebdriverIO.Browser, param: WebdriverIOEventMap[K]) => void): this;
once<K extends keyof WebdriverIOEventMap>(event: K, listener: (this: WebdriverIO.Browser, param: WebdriverIOEventMap[K]) => void): this;
}
/**

@@ -498,4 +505,14 @@ * @private

}
/**
* WebdriverIO Dialog object
* The dialog object represents a user prompt that was triggered by the browser. It contains
* information about the message, type and default value of the prompt.
* It can be received using the `on('dialog')` event.
*
* @see https://webdriver.io/docs/api/dialog
*/
interface Dialog extends DialogImport {
}
}
}
//# sourceMappingURL=types.d.ts.map

@@ -36,3 +36,3 @@ import type { ElementReference } from '@wdio/protocols';

duration: number;
origin: WebdriverIO.Element | ElementReference | ChainablePromiseElement | Origin;
origin: (Origin | ElementReference | ChainablePromiseElement | WebdriverIO.Element);
};

@@ -39,0 +39,0 @@ type PointerActionParams = Partial<typeof PARAM_DEFAULTS> & Partial<PointerActionUpParams>;

@@ -13,3 +13,3 @@ import { type remote } from 'webdriver';

*/
export declare const getPrototype: (scope: 'browser' | 'element') => Record<string, PropertyDescriptor>;
export declare const getPrototype: (scope: "browser" | "element") => Record<string, PropertyDescriptor>;
/**

@@ -106,3 +106,3 @@ * get element id from WebDriver response

*/
export declare const isStub: (automationProtocol?: string) => boolean;
export declare const isStub: (automationProtocol?: string) => automationProtocol is "./protocol-stub.js";
/**

@@ -109,0 +109,0 @@ * compare if an object (`base`) contains the same values as another object (`match`)

@@ -324,2 +324,3 @@ /// <reference types="@wdio/globals/types" />

const browserObject = getBrowserObject(this);
const shadowRootManager = getShadowRootManager(browserObject);
/**

@@ -330,4 +331,5 @@ * do a deep lookup if

* - that is not a deep selector
* - and we are not in an iframe (because it is currently not supported to locate nodes in an iframe via Bidi)
*/
if (this.isBidi && typeof selector === 'string' && !selector.startsWith(DEEP_SELECTOR)) {
if (this.isBidi && typeof selector === 'string' && !selector.startsWith(DEEP_SELECTOR) && !shadowRootManager.isWithinFrame()) {
return findDeepElement.call(this, selector);

@@ -334,0 +336,0 @@ }

@@ -1,2 +0,1 @@

/// <reference types="node" resolution-mode="require"/>
import { type JsonCompatible } from '@wdio/types';

@@ -3,0 +2,0 @@ import { type local } from 'webdriver';

{
"name": "webdriverio",
"description": "Next-gen browser and mobile automation test framework for Node.js",
"version": "9.0.0-alpha.369+43868ec82",
"version": "9.0.0-alpha.426+d760644c4",
"homepage": "https://webdriver.io",

@@ -63,2 +63,3 @@ "author": "Christian Bromann <mail@bromann.dev>",

"devDependencies": {
"@sinonjs/fake-timers": "^11.2.2",
"@types/archiver": "^6.0.2",

@@ -72,8 +73,9 @@ "@types/aria-query": "^5.0.4",

"@types/node": "^20.11.30",
"@wdio/config": "9.0.0-alpha.369+43868ec82",
"@wdio/logger": "9.0.0-alpha.369+43868ec82",
"@wdio/protocols": "9.0.0-alpha.369+43868ec82",
"@wdio/repl": "9.0.0-alpha.369+43868ec82",
"@wdio/types": "9.0.0-alpha.369+43868ec82",
"@wdio/utils": "9.0.0-alpha.369+43868ec82",
"@types/sinonjs__fake-timers": "^8.1.5",
"@wdio/config": "9.0.0-alpha.426+d760644c4",
"@wdio/logger": "9.0.0-alpha.426+d760644c4",
"@wdio/protocols": "9.0.0-alpha.426+d760644c4",
"@wdio/repl": "9.0.0-alpha.426+d760644c4",
"@wdio/types": "9.0.0-alpha.426+d760644c4",
"@wdio/utils": "9.0.0-alpha.426+d760644c4",
"archiver": "^7.0.1",

@@ -97,3 +99,3 @@ "aria-query": "^5.3.0",

"urlpattern-polyfill": "^10.0.0",
"webdriver": "9.0.0-alpha.369+43868ec82"
"webdriver": "9.0.0-alpha.426+d760644c4"
},

@@ -108,3 +110,3 @@ "peerDependencies": {

},
"gitHead": "43868ec82075db90009f00bb737f6df0f1744ca6"
"gitHead": "d760644c4c6e1ef910c0bee120cb422e25dbbe06"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc