PRACTICE FIXTURE — intentionally built for automation practice
Locator quality determines whether a browser test describes product behavior or merely survives today’s markup. Playwright locators retry while the page changes, enforce strictness when an action should target one element, and combine selection with web-first assertions. Those capabilities work best when the DOM exposes the same names and relationships a user perceives.
Begin with accessible roles and names for interactive controls. Labels are the strongest field contract. Visible text, alternative text, titles, and placeholders each fit narrower content types. Test IDs and CSS remain useful when a technical state has no honest user-facing selector, but their presence should be deliberate rather than automatic.
Repeated content needs context. Filter a meaningful collection by a child or visible text, or enter a named region before finding its action. Position helpers communicate order-sensitive behavior; they should not conceal duplicate or missing identity. The paired examples below keep awkward markup visible so you can compare the cost of each choice.
getByRole
Role locators follow the accessibility tree and reflect how people understand controls. Add an accessible name to distinguish similar roles. This is the strongest default for buttons, links, headings, form controls, dialogs, and status regions.
Good DOM
Awkward DOM Intentional
getByText
Text locators suit non-interactive copy and unique visible outcomes. Use exact matching when nearby text overlaps. Avoid using body-wide text as a shortcut for an interactive control that already has a meaningful role.
Good DOM
Payment method updated
Awkward DOM Intentional
getByLabel
A real label creates a durable relationship between field name and control. It improves click targets and accessibility at the same time. Missing or visually nearby text is not an equivalent relationship.
Good DOM
Awkward DOM Intentional
getByPlaceholder
Placeholder locators can be useful when the product genuinely exposes a unique prompt, but placeholders disappear during typing and are not labels. Treat them as a fallback or as a deliberate exercise requirement.
Good DOM
Awkward DOM Intentional
getByAltText
Alternative text identifies meaningful images and image controls. Write alt text for purpose rather than file appearance. Decorative images should use an empty alt and should not be targeted as meaningful content.
Good DOM
Awkward DOM Intentional
getByTitle
Title locators cover elements whose title attribute is part of the observable contract. Since titles are often hidden until hover and unavailable on touch, prefer visible names when you control the markup.
Good DOM
Awkward DOM Intentional
getByTestId
Test IDs are a deliberate escape hatch when user-facing semantics cannot identify a stable technical target. Keep them rare, meaningful, and documented; they should not replace an accessible name that users need.
Good DOM
Awkward DOM Intentional
locator() with CSS
CSS is useful for structural or state assertions that have no user-facing equivalent. Prefer a stable attribute owned by the fixture. Long descendant chains couple tests to styling and incidental wrappers.
Good DOM
Release candidate
Awkward DOM Intentional
filter({ hasText, has })
Filtering starts with a meaningful collection and narrows it by visible text or a descendant locator. It is ideal for repeated cards and rows. Make the outer collection semantic before applying the filter.
Good DOM
Apollo
Gemini
Awkward DOM Intentional
nth()
nth() selects by zero-based position. Use it only when order itself is the behavior under test, such as a ranked list. If an item has an identity, filter by that identity instead.
Good DOM
- Run A
- Run B
- Run C
Awkward DOM Intentional
first()
first() communicates that the first matching item matters. Pair it with a scoped, meaningful list so unrelated matches cannot move ahead of it. Do not use first() merely to silence strict-mode ambiguity.
Good DOM
- Build complete
- Review ready
Awkward DOM Intentional
last()
last() is appropriate when the newest or final item is the contract. Assert the collection context and count when that matters. A locator that happens to be last today can become ambiguous after unrelated content changes.
Good DOM
- Started
- Validated
- Deployed
Awkward DOM Intentional
Locator chaining
Chaining keeps each step readable: locate a region, then a card, then its action. Each link in the chain should express product meaning. Avoid chains made only of implementation classes and child indexes.
Good DOM
Visa ending 1111
Awkward DOM Intentional
Frame-free scoping
Named regions, forms, dialogs, rows, and cards provide scope without iframe complexity. Begin at the smallest stable container and locate within it. This resolves duplicate labels while keeping the exercise in one document.