Locators and actions
You read and drive the site inside an attached frame through a locator chain, a Locator built by chaining selectors on the Frame that attachFrame() returns. This page covers the chain model, every selector and action, the consent each one raises, area grants, the video handle, addStyleTag() and the error names.
Every read and every action takes the same shape:
const const frame: Frame
frame = await function attachFrame(options: AttachFrameOptions): Promise<Frame>
attachFrame({ iframe: HTMLIFrameElement
iframe: var document: Document
window.document returns a reference to the document contained in the window.
document.ParentNode.querySelector<"iframe">(selectors: "iframe"): HTMLIFrameElement | null (+4 overloads)
Returns the first element that is a descendant of node that matches selectors.
querySelector('iframe')! })const const play: Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
play = const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('.controls').locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('#play') // nothing has happened yet
await const play: Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
play.click: (options?: PositionOptions | undefined) => Promise<void>
click() // one consent check, then the click, retried until the deadlineawait const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('#title').textContent: (_options?: LocatorOptions | undefined) => Promise<string>
textContent() // 'Big Buck Bunny'Nothing touches the page until you call an action on the chain. Each action is one consent check and one deadline. The executor, the code that resolves the chain inside the framed document, is retried inside that deadline.
The consent sheet is the prompt the extension, the FKN browser extension, shows before an action that needs the user’s approval. A chain renders as text, .controls #play above, and the sheet asks the user to allow that text.
An action runs inside the framed document on either of the two backends, the extension and the cloud. A backend is where a call runs. Every action hands you back a plain value, apart from videoElement(), which hands back a live handle on the extension backend, see video. fetch() has refusals of its own on the cloud, see fetching as the frame.
The chain
Section titled “The chain”Each selector call records one part and returns a new chain, so building one costs nothing. When an action runs, the executor walks the parts from the framed document’s root, each narrowing the set the previous one produced, and the action applies to what is left.
The Frame carries only the frame members: locator(), frameLocator(), owner(), addStyleTag(), fetch(), ensure(), goto() and url(). click(), getByRole(), first() and the other element members appear only after a locator(), and calling one on the Frame is a compile error.
frameLocator() is a hop: the executor resolves the parts up to it, takes the first <iframe> it matched, and hands the rest of the chain to that document. owner() hops back up to the parent document:
const const widget: FrameLocator<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
widget = const frame: Frame
frame.frameLocator: (selector: string) => FrameLocator<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; ...
frameLocator('#widget') // the first <iframe> matching #widget
await const widget: FrameLocator<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
widget.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('button').first: () => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
first().click: (options?: PositionOptions | undefined) => Promise<void>
click() // runs inside the child documentawait const widget: FrameLocator<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
widget.owner: () => FrameLocator<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
owner().locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('h1').textContent: (_options?: LocatorOptions | undefined) => Promise<string>
textContent() // back in the framed documentThe click runs in the widget’s document and the read back in the framed document. A hop crosses a realm, one JavaScript execution context, so the chain past it runs with the child’s document and window. A nested frame that navigates mid-call fails that attempt with the frame this call was routed to went away mid-call, retrying, and the loop retries it.
owner() on the Frame itself climbs to the document above the attached iframe, your own page. The extension backend checks every document a chain lands in against the origins you declared. An iframe attached with a src of its own never declares your page, so the climb is refused with frame: this frame no longer holds the document the app attached it to. An iframe attached blank declares your page, and keeps it after a goto(), so the climb reaches it.
owner: already at the top frame is raised only for a document with no parent frame at all, which an attached iframe never is. On the cloud backend the render proxy, the cloud frame backend, refuses a climb out of the site it serves with owner: the parent frame is outside this bridge boundary.
Selectors
Section titled “Selectors”Eight selectors build a chain. Six narrow the current set, frameLocator() narrows and then hops into a child document, and owner() hops up:
| Selector | What it matches |
|---|---|
locator(css) | querySelectorAll(css) under each current element. |
frameLocator(css) | The same, then a hop into the first <iframe> matched, where the rest of the chain runs. |
owner() | Frame only. A hop up to the parent document. |
getByRole(role) | Descendants with an explicit role="<role>" attribute. An implicit ARIA role does not match. |
getByText(text) | Each current element, and every descendant, whose textContent includes text. Substring, case-sensitive. |
getByTestId(id) | Descendants with data-testid="<id>". |
first() | The first of the current set. |
nth(index) | elements.at(index), so nth(-1) is the last. |
Two differ from the Playwright selectors of the same name. getByRole('button') does not find a <button>, only an element carrying role="button", so target native controls by tag or id. getByText() keeps ancestors too, so locator('.controls').getByText('Play') resolves to the .controls box and the button both. first() keeps document order and picks the box, so the fix is to target the button by tag:
await const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('.controls').locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('button').first: () => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
first().click: (options?: PositionOptions | undefined) => Promise<void>
click() // the first button in the box, Playawait const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('li').nth: (index: number) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
nth(-1).textContent: (_options?: LocatorOptions | undefined) => Promise<string>
textContent() // the last itemawait const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('.controls').getByText: (text: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
getByText('Play').click: (options?: PositionOptions | undefined) => Promise<void>
click() // rejects with Strict mode violation: locator resolved to 2 elements, after 30 s of retriesThe last line costs the whole deadline before it fails, because the executor retries a strict mode violation like a missing element.
Actions
Section titled “Actions”Every action is async and takes a trailing options object:
| Action | Returns | What it does |
|---|---|---|
click(options?) | Promise<void> | Synthetic pointerdown, mousedown, pointerup, mouseup and click at the element’s centre, or at position. No scrolling, no focus, isTrusted is false. |
hover(options?) | Promise<void> | One burst of pointerover, pointerenter, mouseenter, mouseover, pointermove and mousemove, then nothing. |
fill(value, options?) | Promise<void> | Writes an <input> or <textarea> through the native setter and dispatches input then change. A contenteditable element gets its textContent set and an input event. |
textContent(options?) | Promise<string> | The element’s textContent. |
getAttribute(name, options?) | Promise<string | null> | element.getAttribute(name). |
isVisible(options?) | Promise<boolean> | display, visibility and a non-zero box, never opacity, clipping, scroll position or occlusion. Anything that is not an HTMLElement, such as an SVG icon, always reports visible. |
count(options?) | Promise<number> | How many elements match. |
exists(options?) | Promise<boolean> | Whether at least one element matches. |
videoElement(options?) | Promise<RemoteVideoElement> | A handle on the single matching <video>, see video. |
addStyleTag(options) | Promise<void> | Frame only. A <style> in the framed document, see styling the page. |
fetch(url, init?) | Promise of an unexported result type | Frame only. A request from inside the framed document, see frames. Its result type is Awaited<ReturnType<Frame['fetch']>>, see TypeScript. |
ensure(operation, options?) | Promise<void> | The consent check for operation, without running it, see ensure() and subtree. |
click(), hover(), fill(), textContent(), getAttribute(), isVisible() and videoElement() are strict: they need exactly one match, and otherwise fail with No elements found or, for example, Strict mode violation: locator resolved to 2 elements, with the number the chain matched. count() and exists() accept any number, so they are the way to probe:
const const search: Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
search = const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('#search')
await const search: Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
search.fill: (value: string, options?: LocatorOptions | undefined) => Promise<void>
fill('hello') // dispatches input, then changeawait const search: Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
search.getAttribute: (name: string, _options?: LocatorOptions | undefined) => Promise<string | null>
getAttribute('placeholder') // 'Search (a fill() target)', null without oneawait const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('.result').count: (_options?: LocatorOptions | undefined) => Promise<number>
count() // 0 when nothing matches, no errorawait const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('.result').first: () => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
first().isVisible: (_options?: LocatorOptions | undefined) => Promise<boolean>
isVisible() // rejects with No elements found after the deadlineThe two probes answer without a sheet or an error. fill() resets React’s value tracker before it writes, so a React-controlled field sees the change, and drives a type="range" input with a pointer down and up around the write. Any other element rejects with fill: element <tag> is not fillable, a plain Error retried to the deadline.
Options
Section titled “Options”The trailing object on every action carries timeout and reason, and on click() and hover() a position too:
await const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('#play').click: (options?: PositionOptions | undefined) => Promise<void>
click({ timeout?: number | undefined
timeout: 5_000, // 30_000 by default reason?: string | undefined
reason: 'Start playback from this app', // shown on the consent sheet position?: { x?: number; y?: number;} | undefined
position: { x?: number | undefined
x: 0.5, y?: number | undefined
y: 0.5 }, // fractions of the element's box, the centre by default})timeout is the deadline for the action, 30,000 ms by default. The consent check runs first and does not count against it. Then the executor is retried every 50 ms until it succeeds, throws a terminal error, or the deadline passes, see limits and timeouts.
A timeout rarely says timeout: the loop throws the last attempt’s error, No elements found for a missing element. Locator timeout (30000ms): click appears only when no attempt failed before the deadline, see what a timeout says.
reason is a sentence for the user on the consent sheet, see giving a reason.
Reading versus acting
Section titled “Reading versus acting”Every action maps to one permission key, an entry such as read.text, and the key’s severity decides whether the user is asked. isVisible(), count(), exists(), videoElement() and addStyleTag() are severity 0 and run without a sheet. textContent() and getAttribute() read at severity 1, fill() and hover() act at severity 1, and click() acts at severity 3:
await const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('#title').exists: (_options?: LocatorOptions | undefined) => Promise<boolean>
exists() // true, no sheet, one 'auto' row in the activity logawait const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('#title').textContent: (_options?: LocatorOptions | undefined) => Promise<string>
textContent() // 'Big Buck Bunny', after a sheet for read.textawait const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('input[value^="a"]').count: (_options?: LocatorOptions | undefined) => Promise<number>
count() // rejects with count: selectors matching the value attribute need a consent-gated operationProbe freely, and ask only when about to read or change something, see permission keys for the full table.
A severity-0 action refuses a chain whose CSS probes the value attribute with count: selectors matching the value attribute need a consent-gated operation, a plain Error, not retried. input[value^="a"] reads a field one character at a time, so that read needs a key the user is asked for.
On the cloud backend only fetch() is gated, and every other action runs without a prompt or an activity log, see consent on the cloud backend.
ensure() and subtree
Section titled “ensure() and subtree”ensure(operation, options?) runs the consent check for operation and nothing else: the sheet is raised or a stored grant found, and no element is touched. With subtree: true the scope widens from the chain to everything under it, an area grant, and one answer then covers every later action inside the area:
try { await const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('.controls').ensure: (operation: "click" | "fill" | "hover" | "textContent" | "getAttribute" | "isVisible" | "count" | "exists" | "videoElement", options?: EnsureOptions) => Promise<void>
ensure('click', { subtree: boolean
subtree: true, reason: string
reason: 'Control the player from this app' }) // one sheet, act.click on '.controls *'} catch (var error: unknown
error) { if ((var error: unknown
error as interface Error
Error).Error.name: string
name === 'PermissionDeniedError') var console: Console
console.Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.
log('the user said no') else throw var error: unknown
error}
await const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('.controls').locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('#play').click: (options?: PositionOptions | undefined) => Promise<void>
click() // covered by the area grant, no sheetawait const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('.controls').locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('#mute').click: (options?: PositionOptions | undefined) => Promise<void>
click() // covered tooThe two clicks under the grant raise no sheet, and each writes one covered row per page load to the activity log, the on-device record of what an app did.
The operation names an element action after a locator(), and 'addStyleTag' or 'fetch' on the Frame itself. At the root, ensure('fetch') asks for frame.fetchRead on the scope this frame. What a grant covers is on asking before acting.
videoElement() hands you a RemoteVideoElement, an EventTarget backed by the real <video> inside the frame. It mirrors only the subset of HTMLVideoElement listed below, so videoWidth and the rest are absent. The single match must be a <video>, otherwise the call rejects with Strict mode violation: expected HTMLVideoElement, got <tag>:
const const video: RemoteVideoElement
video = await const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('video').videoElement: (_options?: LocatorOptions | undefined) => Promise<RemoteVideoElement>
videoElement() // media.video, severity 0, no sheet
const video: RemoteVideoElement
video.EventTarget.addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: AddEventListenerOptions | boolean): void
The addEventListener() method of the EventTarget interface sets up a function that will be called whenever the specified event is delivered to the target.
addEventListener('timeupdate', () => { var console: Console
console.Console.log(...data: any[]): void
The console.log() static method outputs a message to the console.
log(`${const video: RemoteVideoElement
video.currentTime: number
currentTime.Number.toFixed(fractionDigits?: number): string
Returns a string representing a number in fixed-point notation.
toFixed(1)} / ${const video: RemoteVideoElement
video.duration: number
duration.Number.toFixed(fractionDigits?: number): string
Returns a string representing a number in fixed-point notation.
toFixed(1)}`) // refreshed by the event that just arrived})const video: RemoteVideoElement
video.muted: boolean
muted = true // written locally at once, then reconciled from the frameawait const video: RemoteVideoElement
video.function play(): Promise<void>
play() // the frame's own play() promiseif (const video: RemoteVideoElement
video.readyState: number
readyState >= const video: RemoteVideoElement
video.type HAVE_FUTURE_DATA: 3
HAVE_FUTURE_DATA) const video: RemoteVideoElement
video.currentTime: number
currentTime = 30Ten properties are writable: currentTime, volume, muted, playbackRate, src, loop, autoplay, preload, poster and disableRemotePlayback. A write lands in a local snapshot at once and goes to the frame, which answers with a fresh snapshot that overwrites it. Nine are read-only: duration, paused, ended, seeking, readyState, currentSrc, buffered, seekable and error. They come from that snapshot, refreshed only by a setter round trip or by an event you listen for.
Forwarding for an event type starts with your first listener for it, and every forwarded event merges its snapshot in before the listener runs, so a timeupdate listener keeps currentTime and duration current.
play() returns the frame’s own promise, so its rejection reaches you. pause() and load() are fire-and-forget and swallow failures. requestPictureInPicture() and exitPictureInPicture() reject with requestPictureInPicture is not supported in this environment and its exitPictureInPicture twin where the frame’s browser lacks them, so observe the switch through the handle’s enterpictureinpicture event.
Styling the page
Section titled “Styling the page”addStyleTag({ content }) appends a <style> to the framed document’s <head>, or to its root element when there is none, and re-appends it whenever HTML still arriving sweeps it away. It is a frame operation, so after frameLocator() it styles the child document:
await const frame: Frame
frame.addStyleTag: (options: AddStyleTagOptions) => Promise<void>
addStyleTag({ content: string
content: '#sidebar { display: none } body { background: #111 }' }) // media.appear, severity 0
await const frame: Frame
frame.frameLocator: (selector: string) => FrameLocator<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; ...
frameLocator('#widget').addStyleTag: (options: AddStyleTagOptions) => Promise<void>
addStyleTag({ content: string
content: '.promo { display: none }' }) // in the child documentThe first stylesheet lands in the framed document and the second in the widget’s, and the executor filters the CSS first. It removes every declaration whose value contains url(, image(, image-set(, cross-fade(, paint(, element( or expression(, after decoding CSS escapes. It also removes every @import, @font-face, @namespace, @charset and @document rule and every comment, inside nested rules and keyframes too.
The parser drops a rule with a typo and keeps the rest, and only CSS with nothing parseable lands as an empty sheet. Neither raises an error, so a sheet that does less than you expect is worth checking for a typo.
Passing noSanitize: true skips the filter and switches the key from media.appear (severity 0) to media.appearU (severity 2), so the user is asked.
Errors
Section titled “Errors”Only name, message, stack and cause cross the hop out of the frame, so errors are told apart by name, see what crosses a realm. Four names come from the locator machinery, a consent refusal is a fifth, and a plain Error completes the set:
try { await const frame: Frame
frame.locator: (selector: string) => Locator$1<Extended<{ readonly element: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly getByRole: { readonly to: "element"; readonly resolve: (context: LocatorContext, role: string) => Element[]; readonly render: (role: unknown) => { fragment: string; }; }; readonly getByText: { readonly to: "element"; readonly resolve: (context: LocatorContext, text: string) => Element[]; readonly render: (text: unknown) => { fragment: string; }; }; readonly getByTestId: { readonly to: "element"; readonly resolve: (context: LocatorContext, testId: string) => Element[]; readonly render: (testId: unknown) => { fragment: string; }; }; readonly first: { readonly to: "element"; readonly resolve: (context: LocatorContext) => Element[]; readonly render: () => { fragment: string; }; }; readonly nth: { readonly to: "element"; readonly resolve: (context: LocatorContext, index: number) => Element[]; readonly render: (index: unknown) => { fragment: string; }; }; }; readonly operations: { readonly click: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly fill: { readonly resolve: (context: LocatorContext, value: string, _options?: OperationOptions) => void; }; readonly hover: { readonly resolve: (context: LocatorContext, options?: PositionOptions$1) => void; }; readonly textContent: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => string; }; readonly getAttribute: { readonly resolve: (context: LocatorContext, name: string, _options?: OperationOptions) => string | null; }; readonly isVisible: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; readonly count: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => number; }; readonly exists: { readonly resolve: (context: LocatorContext, _options?: OperationOptions) => boolean; }; }; }; readonly frame: { readonly selectors: { readonly locator: { readonly to: "element"; readonly css: true; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "descend"; }; }; readonly frameLocator: { readonly to: "frame"; readonly css: true; readonly barrier: "down"; readonly resolve: (context: LocatorContext, selector: string) => Element[]; readonly render: (selector: unknown) => { fragment: string; separator: "down"; }; }; readonly owner: { readonly to: "frame"; readonly barrier: "up"; readonly resolve: (_context: LocatorContext) => Element[]; readonly render: () => { fragment: string; separator: "up"; }; }; }; readonly operations: { readonly addStyleTag: { readonly resolve: (context: LocatorContext, options: AddStyleTagOptions$1) => void; }; readonly fetch: { readonly kind: ChainKind; readonly ...
locator('#play').click: (options?: PositionOptions | undefined) => Promise<void>
click({ timeout?: number | undefined
timeout: 5_000 })} catch (var error: unknown
error) { const { const name: string
name, const message: string
message } = var error: unknown
error as interface Error
Error if (const name: string
name === 'PermissionDeniedError') const message: string
message // Permission denied: act.click (#play) else if (function isLocatorDenied(error: unknown): boolean
isLocatorDenied(var error: unknown
error)) const message: string
message // refused by a gate, not retried else if (function isTerminalError(error: unknown): boolean
isTerminalError(var error: unknown
error)) const message: string
message // cannot run here, not retried else if (const name: string
name === const LOCATOR_ERROR: "LocatorError"
LOCATOR_ERROR) const message: string
message // No elements found, after 5 s of retries else const message: string
message // a plain Error, such as Locator timeout (5000ms): click}LocatorError is the ordinary failure of one attempt, a missing element or a strict mode violation, and the deadline loop retries it. It has a constant, LOCATOR_ERROR, and no guard.
LocatorDeniedError and LocatorUnsupportedError are terminal: thrown once, never retried, with the guards isLocatorDenied() and isLocatorUnsupported(). isTerminalError() matches both, plus the name LocatorInvalidError that a malformed argument raises, whose constant and guard are not exported, see the name with no constant.
The fifth name is the extension’s consent refusal, PermissionDeniedError, with the message Permission denied: <key> (<scope>). The gate raises it before the retry loop and no exported guard matches it, so compare error.name yourself, see a refusal neither guard matches.
The deadline message, the value attribute refusal and the fill refusal arrive as a plain Error and fall through every guard, so a matcher needs the final else above.
The messages you are most likely to meet:
| Message | What happened |
|---|---|
No elements found | The chain matched nothing on the last attempt. A timeout arrives as this. |
Strict mode violation: locator resolved to 2 elements | An action that needs one element got several. Narrow with first(), nth() or a tighter selector. |
Locator timeout (30000ms): click | No attempt failed before the deadline, so a single attempt hung. Name Error. |
frameLocator: no <iframe> matched | The frameLocator() selector matched nothing. Retried. |
Locator operation not supported on the render proxy backend: <operation> | A backend refused the operation, named after the colon, with operation and backend on the error. The render proxy refuses fetch() with fetch on the shared render proxy session and the two other refusals on that row. Terminal. |
count: selectors matching the value attribute need a consent-gated operation | A severity-0 action with a chain that probes value. Name Error, not retried. |
Every other message, the frame.fetch() refusals included, has a row on every error, and the Permission denied refusal under permissions.
Try it
Section titled “Try it”The demo below is the one from frames, driven from the locator side: a same-origin mock player on the extension backend. Its six buttons click play, read the title, fill the search box, approve the whole .controls area with ensure('click', { subtree: true }), click twice under that grant, and click outside it so the sheet returns.
Revoke a grant from the extension’s popup or dashboard and press a button again to bring the sheet back. From here, permissions and consent explains the sheet and what one grant covers.