Filters and indices
Introduction
Section titled “Introduction”Playwright narrows a locator with locator.filter() and
picks one of several matches with first(), last() and nth().
POMWright records the same steps with a registration and applies them every time the path is resolved, right after
the segment’s locator and in the order they were chained. One addition: has and hasNot also take a registered path.
The examples on this page use this page:
<main> <section> <h2>Orders</h2> <ul><li>Open #1</li><li>Shipped #2</li></ul> </section> <section> <h2>Wishlist</h2> <ul><li>Lamp</li></ul> </section></main>Filters: filter
Section titled “Filters: filter”filter takes Playwright’s filter options, hasText, hasNotText, has, hasNot and visible, and adds a
locator.filter() step:
registry.add("section@orders").locator("section").filter({ hasText: "Orders" });registry.add("section@orders.item@open").getByRole("listitem").filter({ hasText: "Open" });// locator('section').filter({ hasText: 'Orders' }).getByRole('listitem').filter({ hasText: 'Open' })has and hasNot take a Playwright Locator, as in Playwright, or a registered path:
registry.add("main").locator("main");registry.add("main.section@orders").locator("section").filter({ has: "main.section@orders.heading" });registry.add("main.section@orders.heading").getByRole("heading", { name: "Orders" });registry.add("main.section@orders.item@open").getByRole("listitem").filter({ hasText: "Open" });
registry.getNestedLocator("main.section@orders.item@open");// locator('main').locator('section').filter({ has: getByRole('heading', { name: 'Orders' }) })// .getByRole('listitem').filter({ hasText: 'Open' })A path given to has or hasNot resolves to that path’s own locator with its own steps, without its ancestors,
because Playwright evaluates has inside the element being filtered: the heading is looked for inside each section,
not from the top of the page. A misspelt path is a compile error. The path may be registered after the filter that
names it; the registry’s verification reports a name that is never registered.
Filters that refer to each other in a loop cannot be resolved, and verification reports every path in the loop:
Locator registry verification failed for 2 of 2 paths: "main.list@orders": Detected cyclic filter reference while resolving "main.list@orders": "main.list@archive". "main.list@archive": Detected cyclic filter reference while resolving "main.list@archive": "main.list@orders".A reference that is neither a Locator nor a path, from JavaScript, fails the same way:
Unsupported filter reference while resolving "main.list@orders". Filter has/hasNot supports Playwright Locator instances or registry path strings.
Indices: nth
Section titled “Indices: nth”nth picks one element: "first" and "last" become Playwright’s
first() and
last(), and a number goes to
nth() as given, so -1 is the last element:
registry.add("list").locator("ul");registry.add("list.item@first").getByRole("listitem").nth("first");registry.add("list.item@third").getByRole("listitem").nth(2);registry.add("list.item@last").getByRole("listitem").nth(-1);As in Playwright, an index belongs at the end of a chain that cannot be made unique otherwise; a filter on what identifies the element survives changes to the page that an index does not.
Steps in order
Section titled “Steps in order”Steps apply in the order they are chained, so a filter after an index filters the one element the index picked:
registry.add("list.item").locator("li").filter({ hasText: "Open" }).nth(0).filter({ hasNotText: "#9" });// locator('li').filter({ hasText: 'Open' }).first().filter({ hasNotText: '#9' })When a path resolves to a chain, each segment’s steps apply right after that segment’s locator, before the next segment.
Steps for one use
Section titled “Steps for one use”A step registered with the path applies to every use. A step for one test, such as the row with a given order number, goes on a query instead, which leaves the registry as it is:
const order = registry.getLocatorSchema("list.items").filter({ hasText: "#1042" }).getNestedLocator();See Queries. A step on a frame segment applies to the
<iframe> element, before the frame is entered.
Reference
Section titled “Reference”filter()andnth()on the registration builder;FilterDefinition- Playwright: Filtering locators,
locator.filter(),locator.nth()