When Playwright’s Locator Tool Isn’t Enough

Published: (January 19, 2026 at 04:47 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

The Limits of Playwright’s Built‑in Locator

Playwright’s built‑in locator tool works fine most of the time, but when you start dealing with real‑world component libraries it can miss the mark. It often suggests getByText or getByRole against elements that are not truly semantic controls, which makes those locators flaky or unusable in practice.

Custom Checkboxes

In most modern apps, vanilla elements are rarely seen. Instead, you’ll encounter custom components built with, “, hidden inputs, ARIA attributes, and classes that represent state. Because of that, Playwright assertions like toBeChecked or toBeDisabled often cannot be trusted—the checkbox looks checked in the UI, but the underlying HTML does not expose the state in the way those helpers expect.

Owning the Locator

In these cases you need to own the locator yourself. The most reliable starting point is usually some stable text on the screen. Once you anchor to that text, you can walk up and down the DOM to find the real checkbox element.

Playwright provides a small but very useful API for this: locator('..'). It moves one level up in the DOM, and you can chain it as many times as you need. It is much cleaner than xpath=../.. and a lot easier to remember. From there, you can navigate back down into the exact node that represents the state you care about.

Example Locator Chain

const checkboxLocator = page
  .locator('p.user-select-none', { hasText: 'School-Pupil Activity Bus' })
  .locator('..')
  .locator('..')
  .locator('.special-requirement-checkbox')
  .locator('input[type="checkbox"][aria-checked="true"][disabled="disabled"]');

await expect(checkboxLocator).toBeVisible();
  • The anchor is the visible label text.
  • The locator walks up to a shared container, then back down into a wrapper with a class you know is stable enough.
  • Finally it targets the actual input element.
  • Because the checkbox is custom, the test asserts on aria-checked and disabled instead of relying on toBeChecked or toBeDisabled. A simple toBeVisible plus the right attributes ends up being more concrete than the higher‑level assertion API.

Why Human‑crafted Locators Still Matter

All of this is also to say why I am a little skeptical of AI testing tools that promise automatic locators and assertions. Real applications rarely use simple, semantic HTML controls. There is a lot of custom markup, hidden inputs, and framework‑specific structure that you have to understand and navigate. For now, a human who can anchor on the right text, walk the DOM, and assert on real attributes is still the most reliable way to write strong Playwright tests.

Back to Blog

Related posts

Read more »

Prevent flaky tests with Playwright

!Cover image for Prevent flaky tests with Playwrighthttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fd...