webdriverio
Version:
Next-gen browser and mobile automation test framework for Node.js
1,059 lines • 45.3 kB
TypeScript
import type { EventEmitter } from 'node:events';
import type { remote, local, SessionFlags, AttachOptions as WebDriverAttachOptions, BidiHandler, EventMap } from 'webdriver';
import type { Capabilities, Options, ThenArg, CustomCommands } from '@wdio/types';
import type { ElementReference, ProtocolCommands, RectReturn } from '@wdio/protocols';
import type { Browser as PuppeteerBrowser } from 'puppeteer-core';
import type { Dialog as DialogImport } from './session/dialog.js';
import type * as BrowserCommands from './commands/browser.js';
import type * as ElementCommands from './commands/element.js';
import type { Button, ButtonNames } from './utils/actions/pointer.js';
import type WebDriverInterception from './utils/interception/index.js';
import type { Response as MockResponse } from './utils/interception/types.js';
/**
* export mock primitives
*/
export * from './utils/interception/types.js';
/**
* re-export action primitives
*/
export * from './utils/actions/index.js';
/**
* re-export command types
*/
export { InitScript } from './commands/browser/addInitScript.js';
type $BrowserCommands = typeof BrowserCommands;
type $ElementCommands = typeof ElementCommands;
type ElementQueryCommands = '$' | 'custom$' | 'shadow$' | 'react$';
type ElementsQueryCommands = '$$' | 'custom$$' | 'shadow$$' | 'react$$';
type ChainablePrototype = {
[K in ElementQueryCommands]: (...args: Parameters<$ElementCommands[K]>) => ChainablePromiseElement;
} & {
[K in ElementsQueryCommands]: (...args: Parameters<$ElementCommands[K]>) => ChainablePromiseArray;
};
type AsyncElementProto = {
[K in keyof Omit<$ElementCommands, keyof ChainablePrototype | 'getSize' | 'getLocation' | 'execute'>]: OmitThisParameter<$ElementCommands[K]>;
} & ChainablePrototype & {
getSize(prop: keyof RectReturn): Promise<number>;
getSize(): Promise<ElementCommands.Size>;
getLocation(prop: keyof ElementCommands.Location): Promise<number>;
getLocation(): Promise<ElementCommands.Location>;
execute<ReturnValue, InnerArguments extends unknown[]>(script: string | ((...innerArgs: TransformElement<[WebdriverIO.Element, ...InnerArguments]>) => ReturnValue | Promise<ReturnValue>), ...args: InnerArguments): Promise<TransformReturn<Awaited<ReturnValue>>>;
};
interface ChainablePromiseBaseElement {
/**
* WebDriver element reference
*/
elementId: Promise<string>;
/**
* parent of the element if fetched via `$(parent).$(child)`
*/
parent: Promise<WebdriverIO.Element | WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser | WebdriverIO.BrowsingContext>;
/**
* selector used to fetch this element, can be
* - undefined if element was created via `$({ 'element-6066-11e4-a52e-4f735466cecf': 'ELEMENT-1' })`
* - a string if `findElement` was used and a reference was found
* - or a function if element was found via e.g. `$(() => document.body)`
*/
selector: Promise<Selector>;
/**
* Error message in case element fetch was not successful
*/
error?: Promise<Error>;
/**
* index of the element if fetched with `$$`
*/
index?: Promise<number>;
/**
* get the `WebdriverIO.Element` reference
*/
getElement(): Promise<WebdriverIO.Element>;
/**
* The chain resolves to the element, so `await $(...)` is a `WebdriverIO.Element`.
*/
then<TResult1 = WebdriverIO.Element, TResult2 = never>(onfulfilled?: ((value: WebdriverIO.Element) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
}
export interface ChainablePromiseElement extends ChainablePromiseBaseElement, AsyncElementProto, Omit<WebdriverIO.Element, keyof ChainablePromiseBaseElement | keyof AsyncElementProto> {
}
/**
* Asynchronous equivalents of the ES5 `Array` iteration methods, available on
* the element list returned by `$$`.
*
* Every method comes in two flavors: the base method runs its callbacks
* **concurrently**, while the `*Series` variant runs **one callback at a time**,
* in order. Prefer a `*Series` variant when the callback interacts with the
* browser and the order of those interactions matters.
*/
interface AsyncIterators<T> {
/**
* Executes the callback once for each element, running the callbacks concurrently.
*/
forEach: (callback: (currentValue: T, index: number, array: T[]) => unknown, thisArg?: unknown) => Promise<void>;
/**
* Same as `forEach`, but runs only one callback at a time.
*/
forEachSeries: (callback: (currentValue: T, index: number, array: T[]) => unknown, thisArg?: unknown) => Promise<void>;
/**
* Creates a new array with the result of the callback for each element, running
* the callbacks concurrently. The result always has the same length as the
* element list.
*/
map: <U>(callback: (currentValue: T, index: number, array: T[]) => U | Promise<U>, thisArg?: unknown) => Promise<U[]>;
/**
* Same as `map`, but runs only one callback at a time.
*/
mapSeries: <U>(callback: (currentValue: T, index: number, array: T[]) => U | Promise<U>, thisArg?: unknown) => Promise<U[]>;
/**
* Returns the first element that satisfies the callback, running the callbacks
* concurrently, or `undefined` if none does. "First" means the first match to
* resolve, which is not necessarily the earliest element in the list, and every
* callback still runs even once a match is found. Use `findSeries` if either
* matters.
*/
find: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<T>;
/**
* Same as `find`, but runs only one callback at a time, so the first match in
* list order is returned.
*/
findSeries: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<T>;
/**
* Returns the index of the first element that satisfies the callback, running
* the callbacks concurrently, or `-1` if none does. "First" means the first
* match to resolve, which is not necessarily the earliest element in the list,
* and every callback still runs even once a match is found. Use
* `findIndexSeries` if either matters.
*/
findIndex: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<number>;
/**
* Same as `findIndex`, but runs only one callback at a time.
*/
findIndexSeries: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<number>;
/**
* Resolves to `true` if at least one element satisfies the callback, running
* the callbacks concurrently.
*/
some: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<boolean>;
/**
* Same as `some`, but runs only one callback at a time.
*/
someSeries: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<boolean>;
/**
* Resolves to `true` if every element satisfies the callback, running the
* callbacks concurrently.
*/
every: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<boolean>;
/**
* Same as `every`, but runs only one callback at a time.
*/
everySeries: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<boolean>;
/**
* Creates a new array with the elements that satisfy the callback, running the
* callbacks concurrently.
*/
filter: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<T[]>;
/**
* Same as `filter`, but runs only one callback at a time.
*/
filterSeries: (callback: (currentValue: T, index: number, array: T[]) => boolean | Promise<boolean>, thisArg?: unknown) => Promise<T[]>;
/**
* Reduces the element list to a single value, awaiting the accumulator between
* elements. Always runs one callback at a time, since each call depends on the
* previous result.
*/
reduce: <U>(callback: (accumulator: U, currentValue: T, currentIndex: number, array: T[]) => U | Promise<U>, initialValue?: U) => Promise<U>;
/**
* Returns an async iterator over `[index, element]` pairs.
*/
entries(): AsyncIterableIterator<[number, T]>;
}
export interface ChainablePromiseArray extends AsyncIterators<WebdriverIO.Element> {
/**
* Awaiting the list yields the resolved `ElementArray`. Until then, `length`
* is a promise and each index is a chainable element.
*/
then<TResult1 = WebdriverIO.ElementArray, TResult2 = never>(onfulfilled?: ((value: WebdriverIO.ElementArray) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | undefined | null): Promise<WebdriverIO.ElementArray | TResult>;
finally(onfinally?: (() => void) | undefined | null): Promise<WebdriverIO.ElementArray>;
[Symbol.asyncIterator](): AsyncIterableIterator<WebdriverIO.Element>;
[Symbol.iterator](): IterableIterator<WebdriverIO.Element>;
/**
* Amount of elements fetched. This is a promise until the query resolves,
* so compare it only after awaiting the list or the property itself.
*/
length: Promise<number>;
/**
* Selector used to fetch this list. It is available immediately, before the
* query resolves. It can be
* - undefined if the list was created via `$$([])`, raw element references, or elements that do not share one selector
* - a string if `findElements` was used and a reference was found
* - or a function if the elements were found via e.g. `$$(() => document.body)`
*/
selector: Selector | undefined;
/**
* Parent of the list if fetched via `$(parent).$$(child)`. Available
* immediately, before the query resolves.
*/
parent: WebdriverIO.Element | WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser | WebdriverIO.BrowsingContext;
/**
* Command name with which this list was found, e.g. `$$`, `react$$`, `custom$$`, `shadow$$`.
* Available immediately, before the query resolves.
*/
foundWith: string;
/**
* Extra arguments of the query that fetched this list. Available immediately.
*/
props: any[];
/**
* allow to access a specific index of the element set
*/
[n: number]: ChainablePromiseElement;
/**
* get the `WebdriverIO.Element[]` list
*/
getElements(): Promise<WebdriverIO.ElementArray>;
/**
* Returns an async iterator of key/value pairs for every index in the array.
*/
entries(): AsyncIterableIterator<[number, WebdriverIO.Element]>;
}
export type BrowserCommandsType = Omit<$BrowserCommands, keyof ChainablePrototype> & ChainablePrototype;
export type ElementCommandsType = Omit<$ElementCommands, keyof ChainablePrototype> & ChainablePrototype;
/**
* Multi-remote command definition
*/
type SingleElementCommandNames = '$' | 'custom$' | 'react$';
type MultiElementCommandNames = '$$' | 'custom$$' | 'react$$';
type ElementCommandNames = SingleElementCommandNames | MultiElementCommandNames;
/**
* `mock` is wrapped into a `MultiRemoteMock` instead of an array of results.
*/
type MultiRemoteArrayCommandNames = ElementCommandNames | 'SESSION_MOCKS' | 'CDP_SESSIONS' | 'mock';
/**
* `shadow$`, `shadow$$` and the sibling and parent queries exist only on an element
*/
type ElementScopeSingleElementCommandNames = SingleElementCommandNames | 'shadow$' | 'nextElement' | 'previousElement' | 'parentElement';
type ElementScopeMultiElementCommandNames = MultiElementCommandNames | 'shadow$$';
type MultiRemoteBrowserQueries = {
[K in keyof Pick<BrowserCommandsType, SingleElementCommandNames>]: (...args: Parameters<BrowserCommandsType[K]>) => ThenArg<WebdriverIO.MultiRemoteElement>;
} & {
[K in keyof Pick<BrowserCommandsType, MultiElementCommandNames>]: (...args: Parameters<BrowserCommandsType[K]>) => ThenArg<WebdriverIO.MultiRemoteElementArray>;
};
type MultiRemoteElementQueries = {
[K in keyof Pick<ElementCommandsType, ElementScopeSingleElementCommandNames>]: (...args: Parameters<ElementCommandsType[K]>) => ThenArg<WebdriverIO.MultiRemoteElement>;
} & {
[K in keyof Pick<ElementCommandsType, ElementScopeMultiElementCommandNames>]: (...args: Parameters<ElementCommandsType[K]>) => ThenArg<WebdriverIO.MultiRemoteElementArray>;
};
export type MultiRemoteBrowserCommandsType = {
[K in keyof Omit<BrowserCommandsType, MultiRemoteArrayCommandNames>]: (...args: Parameters<BrowserCommandsType[K]>) => Promise<ThenArg<ReturnType<BrowserCommandsType[K]>>[]>;
} & MultiRemoteBrowserQueries & {
mock(...args: Parameters<BrowserCommandsType['mock']>): Promise<WebdriverIO.MultiRemoteMock>;
};
export type MultiRemoteElementCommandsType = {
[K in keyof Omit<ElementCommandsType, ElementScopeSingleElementCommandNames | ElementScopeMultiElementCommandNames>]: (...args: Parameters<ElementCommandsType[K]>) => Promise<ThenArg<ReturnType<ElementCommandsType[K]>>[]>;
} & MultiRemoteElementQueries;
export type MultiRemoteProtocolCommandsType = {
[K in keyof ProtocolCommands]: (...args: Parameters<ProtocolCommands[K]>) => Promise<ThenArg<ReturnType<ProtocolCommands[K]>>[]>;
};
interface ElementArrayExport extends Omit<Array<WebdriverIO.Element>, keyof AsyncIterators<WebdriverIO.Element>>, AsyncIterators<WebdriverIO.Element> {
/**
* selector used to fetch this list, can be
* - undefined if the list was created via `$$([])`, raw element references, or elements that do not share one selector
* - a string if `findElements` was used and a reference was found
* - or a function if the elements were found via e.g. `$$(() => document.body)`
*/
selector: Selector | undefined;
/**
* parent of the element if fetched via `$(parent).$(child)`
*/
parent: WebdriverIO.Element | WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser | WebdriverIO.BrowsingContext;
/**
* command name with which this element was found, e.g. `$$`, `react$$`, `custom$$`, `shadow$$`
*/
foundWith: string;
/**
* properties of the fetched elements
*/
props: any[];
/**
* Amount of element fetched.
*/
length: number;
/**
* get the `WebdriverIO.Element[]` list
*/
getElements(): Promise<WebdriverIO.ElementArray>;
/**
* Async iterator so `for await (const el of $$('...'))` yields each element
* whether or not the list has been awaited yet.
*/
[Symbol.asyncIterator](): AsyncIterableIterator<WebdriverIO.Element>;
}
export type ElementArray = ElementArrayExport;
/**
* The array `$$` returns on a multi-remote browser. It carries the same
* information as `ElementArray` — every entry is a `MultiRemoteElement` rather
* than an `Element`, and `isMultiRemote` tells the two apart at runtime.
*/
interface MultiRemoteElementArrayExport extends Omit<Array<WebdriverIO.MultiRemoteElement>, keyof AsyncIterators<WebdriverIO.MultiRemoteElement>>, AsyncIterators<WebdriverIO.MultiRemoteElement> {
/**
* selector used to fetch this element array. Undefined when the entries do not share one selector.
*/
selector: Selector | undefined;
/**
* parent of the element array, i.e. the multi-remote browser or element it was fetched from
*/
parent: WebdriverIO.MultiRemoteBrowser | WebdriverIO.MultiRemoteElement;
/**
* command name with which these elements were found, e.g. `$$`, `react$$`, `custom$$`
*/
foundWith: string;
/**
* properties of the fetched elements
*/
props: any[];
/**
* Amount of elements fetched.
*/
length: number;
/**
* always `true`, so a multi-remote element array can be told apart from a plain one
*/
isMultiRemote: true;
/**
* get the `WebdriverIO.MultiRemoteElement[]` list
*/
getElements(): Promise<WebdriverIO.MultiRemoteElementArray>;
/**
* Async iterator over the multi-remote elements in this list.
*/
[Symbol.asyncIterator](): AsyncIterableIterator<WebdriverIO.MultiRemoteElement>;
}
export type MultiRemoteElementArray = MultiRemoteElementArrayExport;
/**
* What `browser.mock()` returns on a multi-remote browser. Methods such as
* `respond` and `restore` run on every instance. Captured requests stay on
* the mock for one browser: `mock.getInstance(name).calls`. Request ids are
* not shared across sessions, so `getBinaryResponse` stays on that mock too.
*/
interface MultiRemoteMockBase {
/**
* Instance names, in the order the mocks were created. A `select()` that
* reorders browsers is reflected here, so this can differ from
* `browser.instances`.
*/
instances: string[];
/**
* Always `true`, so a multi-remote mock can be told apart from a single `Mock`.
*/
isMultiRemote: true;
/**
* The mock registered on one instance.
* Throws `Multi-remote object has no instance named "<name>"` when `name` is not one of `instances`.
*/
getInstance(name: string): WebdriverIO.Mock;
abort(...args: Parameters<WebdriverIO.Mock['abort']>): this;
abortOnce(...args: Parameters<WebdriverIO.Mock['abortOnce']>): this;
clear(...args: Parameters<WebdriverIO.Mock['clear']>): this;
reset(...args: Parameters<WebdriverIO.Mock['reset']>): this;
redirect(...args: Parameters<WebdriverIO.Mock['redirect']>): this;
redirectOnce(...args: Parameters<WebdriverIO.Mock['redirectOnce']>): this;
request(...args: Parameters<WebdriverIO.Mock['request']>): this;
requestOnce(...args: Parameters<WebdriverIO.Mock['requestOnce']>): this;
respond(...args: Parameters<WebdriverIO.Mock['respond']>): this;
respondOnce(...args: Parameters<WebdriverIO.Mock['respondOnce']>): this;
/**
* Register the same listener on every instance's mock.
*/
on(event: 'request', callback: (request: local.NetworkBeforeRequestSentParameters) => void): this;
on(event: 'match', callback: (match: local.NetworkBeforeRequestSentParameters) => void): this;
on(event: 'continue', callback: (requestId: string) => void): this;
on(event: 'fail', callback: (requestId: string) => void): this;
on(event: 'overwrite', callback: (response: MockResponse) => void): this;
on(event: string, callback: (...args: any[]) => void): this;
/**
* Restore every instance's mock.
*/
restore(...args: Parameters<WebdriverIO.Mock['restore']>): Promise<this>;
/**
* Wait until every instance has received a matching response.
*/
waitForResponse(...args: Parameters<WebdriverIO.Mock['waitForResponse']>): Promise<Awaited<ReturnType<WebdriverIO.Mock['waitForResponse']>>[]>;
}
type AddCommandFnScoped<InstanceType = WebdriverIO.Browser, IsElement extends boolean = false> = (this: IsElement extends true ? WebdriverIO.Element : InstanceType, ...args: any[]) => any;
export type AddCommandFn = (...args: any[]) => any;
type OverwriteCommandFnScoped<ElementKey extends keyof $ElementCommands, BrowserKey extends keyof $BrowserCommands, IsElement extends boolean = false> = (this: IsElement extends true ? WebdriverIO.Element : WebdriverIO.Browser, originalCommand: IsElement extends true ? OmitThisParameter<$ElementCommands[ElementKey]> : OmitThisParameter<$BrowserCommands[BrowserKey]>, ...args: any[]) => Promise<any>;
type OverwriteCommandFn<ElementKey extends keyof $ElementCommands, BrowserKey extends keyof $BrowserCommands, IsElement extends boolean = false> = (this: IsElement extends true ? WebdriverIO.Element : WebdriverIO.Browser, originalCommand: IsElement extends true ? OmitThisParameter<$ElementCommands[ElementKey]> : OmitThisParameter<$BrowserCommands[BrowserKey]>, ...args: any[]) => Promise<any>;
export type CustomLocatorReturnValue = HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>;
export type Instances = CustomCommands.Instances;
export type CustomCommandOptions<IsElement extends boolean> = CustomCommands.CustomCommandOptions<IsElement>;
export type AddCommandFunction<IsElement extends boolean, T = any, Instance = WebdriverIO.Browser> = IsElement extends true ? AddCommandFnScoped<T | Instance, IsElement> : AddCommandFn;
type BrowsingContextCommandOptions = Omit<CustomCommands.CustomCommandOptions<false>, 'attachToElement' | 'attachToBrowsingContext'> & {
attachToElement?: false;
attachToBrowsingContext: true;
};
type BrowsingContextCommand<Key extends keyof WebdriverIO.BrowsingContext> = WebdriverIO.BrowsingContext[Key] extends (...args: any[]) => any ? OmitThisParameter<WebdriverIO.BrowsingContext[Key]> : never;
export interface CustomInstanceCommands<T> {
/**
* add command to every browsing context (tab, window, frame)
*/
addCommand(name: string, func: (this: WebdriverIO.BrowsingContext, ...args: any[]) => any, options: BrowsingContextCommandOptions): void;
/**
* add command to `browser`, or to an element when `options.attachToElement` is true
*/
addCommand<IsElement extends boolean = false, Instance extends Instances = WebdriverIO.Browser>(name: string, func: IsElement extends true ? AddCommandFnScoped<T | Instance, IsElement> : AddCommandFn, options?: CustomCommands.CustomCommandOptions<IsElement>): void;
/**
* overwrite a command of every browsing context (tab, window, frame)
*/
overwriteCommand<Key extends keyof WebdriverIO.BrowsingContext>(name: Key, func: (this: WebdriverIO.BrowsingContext, originalCommand: BrowsingContextCommand<Key>, ...args: any[]) => Promise<any>, options: BrowsingContextCommandOptions): void;
/**
* overwrite a `browser` command, or an element command when `options.attachToElement` is true
*/
overwriteCommand<ElementKey extends keyof $ElementCommands, BrowserKey extends keyof $BrowserCommands, IsElement extends boolean = false>(name: IsElement extends true ? ElementKey : BrowserKey, func: IsElement extends true ? OverwriteCommandFnScoped<ElementKey, BrowserKey, IsElement> : OverwriteCommandFn<ElementKey, BrowserKey, IsElement>, options?: CustomCommands.CustomCommandOptions<IsElement>): void;
/**
* create custom selector
*/
addLocatorStrategy(name: string, func: ((selector: string, root: HTMLElement) => CustomLocatorReturnValue) | ((selector: string) => CustomLocatorReturnValue)): void;
}
interface InstanceBase extends EventEmitter, SessionFlags {
/**
* Session id for the current running session
*/
sessionId: string;
/**
* Applied WebdriverIO options (options that aren't officially part of WebdriverIO are stripped
* out of this object).
*/
options: Options.WebdriverIO | Options.Testrunner;
/**
* Puppeteer instance
*/
puppeteer?: PuppeteerBrowser;
strategies: Map<any, any>;
commandList: string[];
/**
* @private
*/
__propertiesObject__: Record<string, PropertyDescriptor>;
/**
* @private
*/
wdioRetries?: number;
}
/**
* a browser base that has everything besides commands which are defined for sync and async separately
*/
export interface BrowserBase extends InstanceBase, CustomInstanceCommands<WebdriverIO.Browser> {
isMultiRemote: false;
/**
* capabilities of the browser instance
*/
capabilities: WebdriverIO.Capabilities;
}
export type WebdriverIOEventMap = EventMap & {
'dialog': WebdriverIO.Dialog;
};
interface BidiEventHandler {
on<K extends keyof WebdriverIOEventMap>(event: K, listener: (this: WebdriverIO.Browser, param: WebdriverIOEventMap[K]) => unknown): this;
once<K extends keyof WebdriverIOEventMap>(event: K, listener: (this: WebdriverIO.Browser, param: WebdriverIOEventMap[K]) => unknown): this;
}
/**
* @private
*/
export interface Browser extends Omit<BrowserBase, 'on' | 'once'>, BidiEventHandler, BidiHandler, ProtocolCommands, BrowserCommandsType {
}
/**
* export a browser interface that can be used for typing plugins
*/
export interface ElementBase extends InstanceBase, ElementReference, CustomInstanceCommands<WebdriverIO.Element> {
/**
* capabilities of the browser instance
*/
capabilities: WebdriverIO.Capabilities;
/**
* WebDriver element reference
*/
elementId: string;
/**
* selector used to fetch this element, can be
* - undefined if element was created via `$({ 'element-6066-11e4-a52e-4f735466cecf': 'ELEMENT-1' })`
* - a string if `findElement` was used and a reference was found
* - or a functin if element was found via e.g. `$(() => document.body)`
*/
selector: Selector;
/**
* index of the element if fetched with `$$`
*/
index?: number;
/**
* parent of the element if fetched via `$(parent).$(child)`
*/
parent: WebdriverIO.Element | WebdriverIO.Browser | WebdriverIO.BrowsingContext;
/**
* true if element is a React component
*/
isReactElement?: boolean;
/**
* true if element was queried from a shadow root
*/
isShadowElement?: boolean;
/**
* whether the element was queried with strict selector semantics, used to
* keep the same behavior when the element is re-fetched
*/
strict?: boolean;
/**
* error response if element was not found
*/
error?: Error;
/**
* locator of the element
* @requires WebDriver Bidi
*/
locator?: remote.BrowsingContextLocator;
}
interface MultiRemoteBase extends Omit<InstanceBase, 'sessionId'>, CustomInstanceCommands<WebdriverIO.MultiRemoteBrowser> {
/**
* capabilities of the browser instance
*/
capabilities: Capabilities.RequestedMultiRemoteCapabilities;
/**
* Multi-remote browser instance names
*/
instances: string[];
/**
* flag to indicate multi-remote browser session
*/
isMultiRemote: true;
/**
* get a specific instance to run commands on it
*/
getInstance: (browserName: string) => WebdriverIO.Browser;
/**
* select one or multiple browsers always wrapped into a multi-remote to run commands on them.
* Even if only one instance is selected, it will still return a multi-remote browser.
* Use getInstance to have exclusive access to a single instance.
*/
select: (...browserNames: string[]) => WebdriverIO.MultiRemoteBrowser;
}
interface MultiRemoteElementBase {
selector: Selector;
/**
* Multi-remote browser instance names
*/
instances: string[];
commandList: string[];
addCommand: Function;
overwriteCommand: Function;
/**
* flag to indicate multi-remote browser session
*/
isMultiRemote: true;
/**
* get a specific instance to run commands on it
*/
getInstance: (browserName: string) => WebdriverIO.Element;
/**
* select one or multiple browsers always wrapped into a multi-remote to run commands on them.
* Even if only one instance is selected, it will still return a multi-remote element.
* Use getInstance to have exclusive access to a single element.
*/
select: (...browserNames: string[]) => WebdriverIO.MultiRemoteElement;
/**
* @private
*/
__propertiesObject__: never;
}
interface MultiRemoteBrowserType extends MultiRemoteBase, MultiRemoteBrowserCommandsType, MultiRemoteProtocolCommandsType {
}
interface MultiRemoteElementType extends MultiRemoteElementBase, MultiRemoteProtocolCommandsType, Omit<MultiRemoteBrowserCommandsType, keyof MultiRemoteElementCommandsType>, MultiRemoteElementCommandsType {
}
export type ElementFunction = ((elem: HTMLElement) => HTMLElement | undefined) | ((elem: HTMLElement) => (HTMLElement | undefined)[]);
export type CustomStrategyFunction = (...args: any) => ElementReference | ElementReference[];
export type CustomStrategyReference = {
strategy: CustomStrategyFunction;
strategyName: string;
strategyArguments: any[];
};
export type Selector = string | ElementReference | ElementFunction | CustomStrategyReference | HTMLElement;
/**
* options to modify how a single element is queried via `$`
*/
export interface ElementQueryOptions {
/**
* If `true` the query throws a `StrictSelectorError` when the selector resolves
* to more than one element. Defaults to the `strictSelectors` config option
* which itself defaults to `true`.
*/
strict?: boolean;
}
interface CSSValue {
type: string;
string: string;
unit: string;
value: any;
}
interface ParsedColor extends Partial<CSSValue> {
rgb?: string;
rgba?: string;
hex?: string;
}
export interface ParsedCSSValue {
property?: string;
value?: string;
parsed: ParsedColor;
}
interface NoneActionEntity {
type: 'pause';
duration: number;
}
interface PointerActionEntity {
type: 'pointerMove' | 'pointerDown' | 'pointerUp' | 'pointerCancel' | 'pause';
duration?: number;
x?: number;
y?: number;
button?: number;
}
interface KeyActionEntity {
type: 'keyUp' | 'keyDown';
duration?: number;
value?: string;
}
export interface Action {
id: string;
actions: (NoneActionEntity | PointerActionEntity | KeyActionEntity)[];
type?: 'pointer' | 'key';
parameters?: {
pointerType: 'mouse' | 'pen' | 'touch';
};
}
export interface ActionParameter {
actions: Action[];
}
export type Matcher = {
name: string;
args: Array<string | object>;
class?: string;
};
export type ReactSelectorOptions = {
props?: Record<string, unknown>;
state?: Record<string, unknown>;
};
export type MoveToOptions = {
xOffset?: number;
yOffset?: number;
};
export type DragAndDropOptions = {
duration?: number;
};
export type NewWindowOptions = {
type?: 'tab' | 'window';
/**
* Top-level browsing context the new tab or window is opened from.
* A frame is rejected. BiDi only.
*/
referenceContext?: string | WebdriverIO.BrowsingContext;
};
export type TapOptions = MobileScrollIntoViewOptions & {
x?: number;
y?: number;
};
export type LongPressOptions = {
x: number;
y: number;
duration: number;
};
export type ClickOptions = LongPressOptions & {
button: Button | ButtonNames;
skipRelease: boolean;
};
export type PinchAndZoomOptions = {
duration: number;
scale: number;
};
export type WaitForOptions = {
timeout?: number;
interval?: number;
timeoutMsg?: string;
reverse?: boolean;
withinViewport?: boolean;
};
export declare enum MobileScrollDirection {
Down = "down",
Up = "up",
Left = "left",
Right = "right"
}
export type XY = {
x: number;
y: number;
};
export type SwipeOptions = {
direction?: `${MobileScrollDirection}`;
duration?: number;
from?: XY;
percent?: number;
scrollableElement?: WebdriverIO.Element | ChainablePromiseElement;
to?: XY;
};
export type MobileScrollIntoViewOptions = SwipeOptions & {
maxScrolls?: number;
};
export interface CustomScrollIntoViewOptions extends ScrollIntoViewOptions, MobileScrollIntoViewOptions {
}
export type SwitchContextOptions = {
appIdentifier?: string;
title?: string | RegExp;
url?: string | RegExp;
androidWebviewConnectionRetryTime?: number;
androidWebviewConnectTimeout?: number;
};
type AppiumDetailedContextInterface = {
id: string;
title?: string;
url?: string;
};
type IosContextBundleId = {
bundleId?: string;
};
export type IosDetailedContext = AppiumDetailedContextInterface & IosContextBundleId;
export type AndroidDetailedContext = AppiumDetailedContextInterface & {
androidWebviewData?: {
attached: boolean;
empty: boolean;
height: number;
neverAttached: boolean;
screenX: number;
screenY: number;
visible: boolean;
width: number;
};
packageName?: string;
webviewPageId?: string;
};
export type AppiumDetailedCrossPlatformContexts = (IosDetailedContext | AndroidDetailedContext)[];
export type GetContextsOptions = {
androidWebviewConnectionRetryTime?: number;
androidWebviewConnectTimeout?: number;
filterByCurrentAndroidApp?: boolean;
isAndroidWebviewVisible?: boolean;
returnAndroidDescriptionData?: boolean;
returnDetailedContexts?: boolean;
waitForWebviewMs?: number;
};
export type ActiveAppInfo = {
pid: number;
bundleId: string;
name: string;
processArguments: {
args: string[];
env: Record<string, string>;
};
};
export type WaitUntilOptions = {
timeout?: number;
timeoutMsg?: string | (() => string);
interval?: number;
};
export type DragAndDropCoordinate = {
x: number;
y: number;
};
export interface AttachOptions extends Omit<WebDriverAttachOptions, 'capabilities'> {
options?: Options.WebdriverIO;
capabilities?: WebDriverAttachOptions['capabilities'];
requestedCapabilities?: WebDriverAttachOptions['capabilities'];
}
export type ThrottlePreset = 'offline' | 'GPRS' | 'Regular2G' | 'Good2G' | 'Regular3G' | 'Good3G' | 'Regular4G' | 'DSL' | 'WiFi' | 'online';
export interface CustomThrottle {
offline: boolean;
downloadThroughput: number;
uploadThroughput: number;
latency: number;
}
export type ThrottleOptions = ThrottlePreset | CustomThrottle;
export interface ExtendedElementReference {
'element-6066-11e4-a52e-4f735466cecf': string;
locator: remote.BrowsingContextLocator;
}
export type SupportedScopes = 'geolocation' | 'userAgent' | 'colorScheme' | 'media' | 'onLine' | 'locale' | 'timezone' | 'touch' | 'orientation' | 'screen' | 'viewportMeta' | 'textLayout' | 'scripting' | 'scrollbar' | 'forcedColors' | 'clock' | 'device';
export type RestoreMap = Map<SupportedScopes, (() => Promise<any>)[]>;
/**
* Options for `browser.savePDF`. Lengths are centimeters.
*
* Defaults match WebDriver Classic `printPage` and WebDriver BiDi
* `browsingContext.print`: portrait, scale `1`, background `false`,
* shrink-to-fit `true`, page `21.59` × `27.94` cm, margins `1` cm.
* Omitted fields are left to the browser.
*/
export interface PDFPrintOptions {
/**
* Page orientation. Accepted values are `portrait` and `landscape`.
* The property stays a `string` so an existing variable of that type can
* still be passed. Any other value is rejected when `savePDF` runs.
* @default 'portrait'
*/
orientation?: string;
/**
* Page scale. The print protocols accept `0.1`–`2`.
* @default 1
*/
scale?: number;
/**
* Print the page background.
* @default false
*/
background?: boolean;
/**
* Page width in centimeters.
* @default 21.59
*/
width?: number;
/**
* Page height in centimeters.
* @default 27.94
*/
height?: number;
/**
* Top margin in centimeters.
* @default 1
*/
top?: number;
/**
* Bottom margin in centimeters.
* @default 1
*/
bottom?: number;
/**
* Left margin in centimeters.
* @default 1
*/
left?: number;
/**
* Right margin in centimeters.
* @default 1
*/
right?: number;
/**
* Shrink the content to fit the page.
* @default true
*/
shrinkToFit?: boolean;
/**
* Pages to include. Each entry is a page number or a range such as `'1-3'`.
* @default []
*/
pageRanges?: Array<string | number>;
}
/**
* How `context.frame()` finds a frame: by the selector of its frame element
* on the page, by its url (exact string or RegExp), or by its browsing
* context id.
*/
export type FrameQuery = {
selector: string;
url?: never;
id?: never;
} | {
url: string | RegExp;
selector?: never;
id?: never;
} | {
id: string;
selector?: never;
url?: never;
};
export interface SaveScreenshotOptions {
/**
* Whether to take a screenshot of the full page or just the current viewport.
* @default false
*/
fullPage?: boolean;
/**
* The format of the screenshot.
* @default 'png'
*/
format?: 'png' | 'jpeg' | 'jpg';
/**
* The quality of the screenshot in case of JPEG format in range 0-100 percent.
* @default 100
*/
quality?: number;
/**
* Clipping a rectangle of the screenshot.
*/
clip?: {
x: number;
y: number;
width: number;
height: number;
};
}
export type TransformElement<T> = T extends WebdriverIO.Element ? HTMLElement : T extends ChainablePromiseElement ? HTMLElement : T extends WebdriverIO.Element[] ? HTMLElement[] : T extends ChainablePromiseArray ? HTMLElement[] : T extends [infer First, ...infer Rest] ? [TransformElement<First>, ...TransformElement<Rest>] : T extends Array<infer U> ? Array<TransformElement<U>> : T;
export type TransformReturn<T> = T extends HTMLElement ? WebdriverIO.Element : T extends HTMLElement[] ? WebdriverIO.Element[] : T extends [infer First, ...infer Rest] ? [TransformReturn<First>, ...TransformReturn<Rest>] : T extends Array<infer U> ? Array<TransformReturn<U>> : T;
/**
* Additional options outside of the WebDriver spec, exclusively for WebdriverIO, only for runtime, and not sent to Appium
*/
export interface InputOptions {
mask?: boolean;
}
declare global {
namespace WebdriverIO {
/**
* WebdriverIO browser object
* @see https://webdriver.io/docs/api/browser
*/
interface Browser extends Omit<BrowserBase, 'on' | 'once'>, BidiEventHandler, BidiHandler, ProtocolCommands, BrowserCommandsType {
}
/**
* WebdriverIO element object
* @see https://webdriver.io/docs/api/element
*/
interface Element extends ElementBase, ProtocolCommands, ElementCommandsType {
}
/**
* WebdriverIO element array
* When fetching elements via `$$`, `custom$$` or `shadow$$` commands an array of elements
* is returns. This array has extended prototype properties to provide information about
* the parent element, selector and properties of the fetched elements. This is useful to
* e.g. re-fetch the set in case no elements got returned.
*/
interface ElementArray extends ElementArrayExport {
}
/**
* WebdriverIO multi-remote browser object
* A multi-remote browser instance is a property on the global WebdriverIO browser object that
* allows to control multiple browser instances at once. It can be represented as `Record<string, WebdriverIO.Browser>`
* where `string` is the capability name defined in the WebdriverIO options.
*
* @see https://webdriver.io/docs/multiremote/
*/
interface MultiRemoteBrowser extends MultiRemoteBrowserType {
}
/**
* WebdriverIO multi-remote browser object
* A multi-remote browser instance is a property on the global WebdriverIO browser object that
* allows to control multiple browser instances at once. It can be represented as `Record<string, WebdriverIO.Element>`
* where `string` is the capability name defined in the WebdriverIO options.
*
* @see https://webdriver.io/docs/multiremote/
*/
interface MultiRemoteElement extends MultiRemoteElementType {
}
/**
* WebdriverIO multi-remote element array
* What `$$`, `custom$$`, `react$$` and `shadow$$` return on a multi-remote
* browser or element. Like `ElementArray`
* it carries the selector, parent and properties of the fetched set, and
* `isMultiRemote` marks it as the multi-remote variant.
*
* @see https://webdriver.io/docs/multiremote/
*/
interface MultiRemoteElementArray extends MultiRemoteElementArrayExport {
}
/**
* WebdriverIO multi-remote mock
* What `browser.mock()` returns on a multi-remote browser. `instances` names
* each mock, `getInstance(name)` returns that browser's mock, and mock
* methods such as `respond` and `restore` run on every instance.
*
* @see https://webdriver.io/docs/multiremote/
*/
interface MultiRemoteMock extends MultiRemoteMockBase {
}
/**
* WebdriverIO Mock object
* The mock object is an object that represents a network mock and contains information about
* requests that were matching given url and filterOptions. It can be received using the mock command.
*
* @see https://webdriver.io/docs/api/mock
*/
interface Mock extends WebDriverInterception {
}
/**
* 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 {
}
/**
* A tab, a window, or a frame. Commands on this object send the BiDi
* method with `contextId` and do not move the session's current context.
* `parent` is absent on a top-level context. `url` is the document URL.
* Navigate a held context with `navigate()`. `browser.url()` navigates
* the session's initial top-level context and returns it.
*/
/**
* Commands typed with `this: WebdriverIO.Browser` drop that `this`
* here (`OmitThisParameter`), so they can be called on a context.
*/
interface BrowsingContext {
isBidi: boolean;
isMobile: boolean;
capabilities: WebdriverIO.Capabilities;
sessionId: string;
options: Browser['options'];
strategies: Map<string, unknown>;
$(selector: Selector, options?: ElementQueryOptions): ChainablePromiseElement;
$$(selector: Selector): ChainablePromiseArray;
custom$: Browser['custom$'];
custom$$: Browser['custom$$'];
react$: Browser['react$'];
react$$: Browser['react$$'];
execute: Browser['execute'];
action: Browser['action'];
actions: Browser['actions'];
keys: OmitThisParameter<Browser['keys']>;
scroll: OmitThisParameter<Browser['scroll']>;
saveScreenshot: OmitThisParameter<Browser['saveScreenshot']>;
savePDF: OmitThisParameter<Browser['savePDF']>;
getCookies: Browser['getCookies'];
setCookies: Browser['setCookies'];
deleteCookies: Browser['deleteCookies'];
setViewport: Browser['setViewport'];
addInitScript: Browser['addInitScript'];
mock: Browser['mock'];
mockClearAll: Browser['mockClearAll'];
mockRestoreAll: Browser['mockRestoreAll'];
emulate: Browser['emulate'];
restore: OmitThisParameter<Browser['restore']>;
waitUntil: Browser['waitUntil'];
pause: OmitThisParameter<Browser['pause']>;
frame(target: FrameQuery | string | Element | ChainablePromiseElement | ((context: {
context: string;
url: string;
}) => boolean | Promise<boolean>)): Promise<BrowsingContext>;
navigate(url: string, options?: {
wait?: 'none' | 'interactive' | 'networkIdle' | 'complete';
headers?: Record<string, string>;
auth?: {
user: string;
pass: string;
};
timeout?: number;
onBeforeLoad?: Function;
}): Promise<BrowsingContext>;
refresh(): Promise<void>;
closeWindow(): Promise<void>;
activate(): Promise<void>;
getTitle(): Promise<string>;
getUrl(): Promise<string>;
back(): Promise<void>;
forward(): Promise<void>;
acceptAlert(text?: string): Promise<void>;
dismissAlert(): Promise<void>;
getAlertText(): Promise<string>;
on: Browser['on'];
off: Browser['off'];
once: Browser['once'];
emit: Browser['emit'];
removeListener: Browser['removeListener'];
removeAllListeners: Browser['removeAllListeners'];
addCommand(...args: unknown[]): Promise<never>;
overwriteCommand(...args: unknown[]): Promise<never>;
}
}
}
//# sourceMappingURL=types.d.ts.map