API ReferenceTypeScriptLocator
Locator
Every action and query method on Page (click, dblclick, fill, hover, press, focus, highlight, count, textContent, innerText, inputValue, selectedOptions, selectedText, isChecked, getAttribute, boundingBox, waitFor) is also available directly on a Locator, scoped to whatever it resolves to. What's below is what a Locator adds: building one semantically instead of by raw selector, and narrowing it once built.
getByRole
Finds elements by ARIA role, with optional name/exact/checked/disabled/expanded/level/pressed/selected/includeHidden filters.
getByRole(role: string, options?: RoleOptions): LocatorExample
page.getByRole('button', { name: 'Buy', exact: true })getByText / getByLabel / getByPlaceholder / getByAltText / getByTitle
Finds elements by visible text, associated label, placeholder, alt text, or title attribute. TextMatcher is string | RegExp.
getByText(text: TextMatcher, options?: TextOptions): LocatorExample
page.getByLabel('Email', { exact: true }).fill('you@example.com')getByTestId
Finds elements by data-testid attribute.
getByTestId(text: TextMatcher): LocatorLocator.filter
Narrows a locator by a required or forbidden descendant (has/hasNot, same page only), by text (hasText/hasNotText), or by visible.
filter(options?: LocatorFilterOptions): LocatorExample
page.getByRole('listitem').filter({ has: page.getByRole('heading', { name: /^Beta$/ }) })Locator.not
Excludes elements also matched by other (both locators must share the same page).
not(other: Locator): LocatorExample
page.getByRole('button').not(page.getByRole('button', { disabled: true }))Locator.nth / first / last
Selects one match by position — nth accepts negative indices; first/last are sugar for nth(0)/nth(-1).
nth(index: number): Locator
first(): Locator
last(): LocatorLocator.locator
Chains a nested/relative locator off this one.
locator(selector: string, options?: LocatorFilterOptions): LocatorLocator.frame / Frame
Resolves this iframe — nested or cross-origin — to a normal Page, waiting for exactly one match whose document is complete and has gone 200 ms without DOM mutations. timeoutMs (default 10 000) covers the whole resolution; closing the returned page releases its session without closing the parent tab.
frame(options?: CommandOptions): Promise<Page>
Frame(options?: CommandOptions): Promise<Page>Example
const frame = await page.locator("#checkout-frame").frame({ timeoutMs: 10_000 });
await frame.locator("input[name=email]").fill("buyer@example.com");
const nested = await frame.locator("iframe").frame();