Skip to content

LocatorUpdateBuilder

A query’s update(subPath?) and replace(subPath?) return a LocatorUpdateBuilder: the ten locator methods, each of which changes the segment’s locator in that query and returns the query. The registry never changes, and the segment keeps its steps and description.

  • update keeps the registered strategy. Call the method of that strategy with a patch in JSON Merge Patch form: a given first argument replaces the registered one, the options merge key by key, a null key deletes one, a lone null deletes them all, and an omitted value keeps what is registered. Another strategy’s method throws and names replace.
  • replace installs a locator of any strategy, with the arguments of Playwright’s own method: the first argument required, Playwright’s options.

See patching a definition and a new definition.

The examples on this page use this registry, and print each chain without its description:

checkout.locators.ts
import type { LocatorRegistry } from "pomwright";
export type Paths =
| "main"
| "main.button@pay"
| "main.text@total"
| "main.input@email"
| "main.input@search"
| "main.image@card"
| "main.icon@help"
| "main.list@items"
| "main.frame@payment"
| "main.frame@payment.button@confirm"
| "main.rows@cart"
| "main.panel@summary";
export function defineLocators(registry: LocatorRegistry<Paths>) {
registry.add("main").locator("main");
registry.add("main.button@pay").getByRole("button", { name: "Pay", exact: true });
registry.add("main.text@total").getByText("Total", { exact: true });
registry.add("main.input@email").getByLabel("Email");
registry.add("main.input@search").getByPlaceholder("Search");
registry.add("main.image@card").getByAltText("Card logo");
registry.add("main.icon@help").getByTitle("Help");
registry.add("main.list@items").locator("ul", { hasText: "Items" });
registry.add("main.frame@payment").frameLocator("iframe#payment");
registry.add("main.frame@payment.button@confirm").getByRole("button", { name: "Confirm" });
registry.add("main.rows@cart").getByTestId("cart-row");
registry.add("main.panel@summary").getById("summary");
}

Guide: queries.


Every method returns the query, to chain more changes or resolve it. Every method throws, in update mode, for a segment registered with another strategy, and in replace mode, from JavaScript, when the first argument is missing:

update("main.button@pay") cannot change the strategy from "role" to "text"; use replace("main.button@pay").getByText(…) instead.
getByRole requires a role value for "main.button@pay".

An empty string is rejected in both modes where Playwright cannot use one, as at registration: locator requires a non-empty selector for "main.list@items".

Changes the segment to a frame segment: with a selector, the <iframe> element whose descendants resolve inside the frame. In update mode an omitted selector keeps the registered one. In replace mode an omitted selector installs Playwright’s any-frame frameLocator(), which must be the first segment of its chain, so its ancestors are skipped or unregistered.

Usage

registry
.getLocatorSchema("main.frame@payment.button@confirm")
.update("main.frame@payment")
.frameLocator("iframe#card")
.getNestedLocator();
// locator('main').locator('iframe#card').contentFrame().getByRole('button', { name: 'Confirm' })
registry
.getLocatorSchema("main.frame@payment.button@confirm")
.skip("main")
.replace("main.frame@payment")
.frameLocator()
.getNestedLocator();
// frameLocator().getByRole('button', { name: 'Confirm' })

Arguments

  • selector string (optional in update, and in replace for the any-frame form)

Throws

In replace mode without a selector, on the query’s own path or on a segment that has steps in the query:

replace() cannot apply to "main.frame@payment": it is the path this query resolves, and frameLocator() without a selector has no element to resolve to; replace an ancestor instead.
replace() cannot apply to "main.frame@payment": it has filter or nth steps, and frameLocator() without a selector takes none; call clearSteps("main.frame@payment") first.

Changes the segment to Playwright’s getByAltText().

Usage

registry.getLocatorSchema("main.image@card").update().getByAltText(/logo/i).getNestedLocator();
// locator('main').getByAltText(/logo/i)
registry.getLocatorSchema("main.image@card").replace().getByAltText("Visa").getNestedLocator();
// locator('main').getByAltText('Visa')

Arguments

  • text string | RegExp (optional in update)
  • options Object (optional): exact; in update mode a patch, where null deletes.

Changes the segment to an id locator: a string matches the id attribute exactly, a RegExp is tested against each element’s id with its flags. See getById().

Usage

registry.getLocatorSchema("main.panel@summary").update().getById(/^summary/).getNestedLocator();
// selector: internal:attr=[id=/^summary/]
registry.getLocatorSchema("main.panel@summary").replace().getById("order-summary").getNestedLocator();
// selector: [id="order-summary"]

Arguments

  • id string | RegExp (optional in update)

    An empty string is rejected: getById requires a non-empty id for "main.panel@summary".

Changes the segment to Playwright’s getByLabel().

Usage

registry.getLocatorSchema("main.input@email").update().getByLabel("E-mail").getNestedLocator();
// locator('main').getByLabel('E-mail')
registry.getLocatorSchema("main.input@email").replace().getByLabel("Email address").getNestedLocator();
// locator('main').getByLabel('Email address')

Arguments

  • text string | RegExp (optional in update)
  • options Object (optional): exact; in update mode a patch, where null deletes.

Changes the segment to Playwright’s getByPlaceholder().

Usage

registry.getLocatorSchema("main.input@search").update().getByPlaceholder({ exact: true }).getNestedLocator();
// locator('main').getByPlaceholder('Search', { exact: true })
registry.getLocatorSchema("main.input@search").replace().getByPlaceholder("Search products").getNestedLocator();
// locator('main').getByPlaceholder('Search products')

Arguments

  • text string | RegExp (optional in update)
  • options Object (optional): exact; in update mode a patch, where null deletes.

Changes the segment to Playwright’s getByRole().

Usage

registry.getLocatorSchema("main.button@pay").update().getByRole({ name: "Pay now" }).getNestedLocator();
// locator('main').getByRole('button', { name: 'Pay now', exact: true })
registry.getLocatorSchema("main.button@pay").update().getByRole({ exact: null }).getNestedLocator();
// locator('main').getByRole('button', { name: 'Pay' })
registry.getLocatorSchema("main.button@pay").update().getByRole("link", null).getNestedLocator();
// locator('main').getByRole('link')
registry.getLocatorSchema("main.button@pay").replace().getByRole("link", { name: "Pay" }).getNestedLocator();
// locator('main').getByRole('link', { name: 'Pay' })

Arguments

  • role string (optional in update)

    An ARIA role, as Playwright’s type lists them.

  • options Object (optional)

    Playwright’s options, such as name, exact and level; in update mode a patch, where null deletes.

Changes the segment to Playwright’s getByTestId(). An empty string is a value Playwright matches and is kept.

Usage

registry.getLocatorSchema("main.rows@cart").update().getByTestId("cart-item").getNestedLocator();
// locator('main').getByTestId('cart-item')
registry.getLocatorSchema("main.rows@cart").replace().getByTestId(/cart-/).getNestedLocator();
// locator('main').getByTestId(/cart-/)

Arguments

  • testId string | RegExp (optional in update)

Changes the segment to Playwright’s getByText().

Usage

registry.getLocatorSchema("main.text@total").update().getByText({ exact: null }).getNestedLocator();
// locator('main').getByText('Total')
registry.getLocatorSchema("main.button@pay").replace().getByText("Pay", { exact: true }).getNestedLocator();
// locator('main').getByText('Pay', { exact: true })

Arguments

  • text string | RegExp (optional in update)
  • options Object (optional): exact; in update mode a patch, where null deletes.

Changes the segment to Playwright’s getByTitle().

Usage

registry.getLocatorSchema("main.icon@help").update().getByTitle({ exact: true }).getNestedLocator();
// locator('main').getByTitle('Help', { exact: true })
registry.getLocatorSchema("main.icon@help").replace().getByTitle("More help").getNestedLocator();
// locator('main').getByTitle('More help')

Arguments

  • text string | RegExp (optional in update)
  • options Object (optional): exact; in update mode a patch, where null deletes.

Changes the segment to Playwright’s locator().

Usage

registry.getLocatorSchema("main.list@items").update().locator({ hasText: "Cart" }).getNestedLocator();
// locator('main').locator('ul').filter({ hasText: 'Cart' })
registry.getLocatorSchema("main.list@items").update().locator("ol", null).getNestedLocator();
// locator('main').locator('ol')
registry.getLocatorSchema("main.list@items").replace().locator("ol.cart").getNestedLocator();
// locator('main').locator('ol.cart')

Arguments

  • selector string (optional in update)

    An empty selector is rejected in both modes.

  • options Object (optional): Playwright’s options, such as hasText; in update mode a patch, where null deletes.