Playwright · Reliable end-to-end tests

What is a locator and why is it better than a raw selector?

Easylocatorsselectorsauto-waitingUpdated Oct 2026
Quiz this track

Short answer

A locator is a lazy, retryable description of an element. Playwright re-resolves it on every action and assertion, so tests survive re-renders without manual waits or stale element handles.

A locator does not hold a DOM element. It holds a query. When you click or assert, Playwright runs the query again, waits for a match, and checks that the element is actionable. That is why a locator keeps working after React or Vue replaces the underlying node.

ts
const row = page.getByRole("row", { name: "Asha" });

await row.getByRole("button", { name: "Edit" }).click();
await expect(row.getByRole("cell", { name: "Active" })).toBeVisible();

const firstInvoice = page
  .getByRole("listitem")
  .filter({ hasText: "Invoice" })
  .first();

await expect(firstInvoice).toContainText("Due");
Locators chain and filter, and each step is resolved when the action runs.

Why prefer a locator

  • It is re-resolved on each use, so it does not become stale
  • It participates in actionability checks and auto-waiting
  • It composes: chain, filter, and pick by index or text
  • It produces a readable call log that names the locator when it fails
  • It avoids the need for ElementHandle in almost every case

Filtering is usually better than a long CSS path. If a list has several similar items, filter by visible text or by a nested role rather than relying on nth(3), which breaks as soon as the order changes. Use .first() and .last() only when the position is genuinely part of the requirement.

locator.count() returns a number immediately and does not wait for elements to appear. If the list is rendered asynchronously, assert on the expected element or use expect(locator).toHaveCount(n) instead.

Follow-ups you should expect

Interviewers use these to check whether the first answer was understanding or memorisation.

  1. 1Why is a locator not a DOM element?
  2. 2What is the difference between `locator.count()` and `toHaveCount()`?
  3. 3When would you use `filter` instead of `nth`?
  4. 4Why should you avoid long CSS selector chains?

Say it in the interview

A locator is a lazy query, not a reference to a DOM node. Playwright re-runs the query on every action, waits for the element to be ready, and reports the locator in failures. That is why it survives re-renders and avoids stale element errors. I prefer chaining and filtering by role or text over positional selectors, because those break when the page structure or order changes.

Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.

Related questions

Reading is step one

Now say it out loud.

Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Playwright mock interview and get scored feedback on depth, clarity and confidence.