Skip to content

Locators and actions

A locator describes how to find one or more elements inside an attached frame. Locators are chainable and lazy: nothing touches the page until you call an action. If you have used Playwright, you already know this model.

await
const frame: Frame
frame
.
locator: (selector: string) => Locator
locator
('.video-card')
.
first: () => Locator
first
()
.
getByText: (text: string) => Locator
getByText
('Play')
.
click: (options?: (OperationTimeoutOptions & {
position?: {
x?: number | undefined;
y?: number | undefined;
} | undefined;
}) | undefined) => Promise<void>
click
()

Each selector returns a new locator, scoped to the previous step’s matches.

The frame root starts narrow: it offers locator(css), frameLocator(css) and owner(). The full selector set below becomes available on element locators, from the first locator() onward.

SelectorFinds
locator(css)elements matching a CSS selector
getByRole(role)elements by ARIA role
getByText(text)elements containing the given text
getByTestId(id)elements by data-testid
first()the first match of the current set
nth(index)the n-th match of the current set
frameLocator(css)descends into a child iframe matched by the selector
owner()steps back up to the locator’s owning frame

Actions are terminal: they resolve the chain against the live page and perform the operation. Every action is gated by a permission keyed to its capability and the element it targets.

ActionDoesReturns
click()clicks the elementPromise<void>
fill(value)sets an input’s valuePromise<void>
hover()moves a faithful pointer over the elementPromise<void>
textContent()reads the element’s textPromise<string | null>
getAttribute(name)reads an attributePromise<string | null>
isVisible()whether the element is rendered and visiblePromise<boolean>
exists()whether the element is presentPromise<boolean>
count()how many elements matchPromise<number>
videoElement()a remote handle to a <video> element (play, pause, seek, events)Promise<RemoteVideoElement>
addStyleTag(options)injects safety-filtered CSS into the framePromise<void>

All actions accept an options object with:

  • timeout: how long to retry resolving the locator before failing. Waiting for the user’s consent never counts against the timeout.
  • reason: an app-supplied explanation shown on the consent prompt next to the request.
const
const title: string
title
= await
const frame: Frame
frame
.
locator: (selector: string) => Locator
locator
('h1')
.
textContent: (_options?: OperationTimeoutOptions | undefined) => Promise<string>
textContent
({
timeout?: number | undefined
timeout
: 5_000,
reason?: string | undefined
reason
: 'Show the video title in your library' })

Reading the page (textContent, getAttribute, isVisible, exists, count) and acting on it (click, fill, hover) are distinct capabilities with distinct prompts. A user can let an app read a page without letting it click anything, and vice versa.