PLAYWRIGHT UIBEGINNER

Understanding Playwright Locators: Roles, Text, Test IDs, and CSS

Master every locator strategy Playwright ships with — getByRole, getByText, getByTestId, and CSS/XPath — and learn which one to reach for first.

iff Solution Academy July 6, 2026 10 min read Updated July 6, 2026
Playwright Locators Selectors Beginner

What is a Locator?

A Locator in Playwright is a lazy, re-queryable handle to an element. Instead of grabbing a DOM node once, Playwright resolves it every time you act on it — which is exactly why auto-waiting and retries work so reliably.

ts
const submit = page.getByRole('button', { name: 'Submit' });
await submit.click();

getByRole — the recommended default

Role-based locators mirror how assistive tech sees your page. They're stable and improve accessibility at the same time.

ts
await page.getByRole('link', { name: 'Sign in' }).click();
await page.getByRole('textbox', { name: 'Email' }).fill('a@b.com');
await page.getByRole('checkbox', { name: 'Remember me' }).check();

getByText — visible copy

Use getByText for visible strings the user actually reads. Prefer exact matches when the text is short and unique.

ts
await page.getByText('Welcome back').isVisible();
await page.getByText('Delete', { exact: true }).click();

getByTestId — when semantics are missing

For custom widgets without roles, add data-testid attributes and use them. This is the escape hatch, not the default.

ts
await page.getByTestId('shopping-cart').click();

CSS and XPath (last resort)

CSS is fine for structural queries; XPath is powerful but brittle. Reach for them only when the semantic APIs cannot express what you need.

ts
page.locator('css=nav >> a.active');
page.locator('xpath=//table//tr[td[text()="John"]]');

Chaining and Filtering

Compose locators to scope queries — this eliminates flaky global selectors.

ts
const row = page.getByRole('row', { name: /John/ });
await row.getByRole('button', { name: 'Edit' }).click();

page.getByRole('listitem').filter({ hasText: 'Product 2' });

Best Practices

  • Prefer getByRole > getByLabel > getByPlaceholder > getByText > getByTestId > CSS/XPath.
  • Never assert or act on a raw element handle — use Locators.
  • Use filter() and chaining instead of long CSS selectors.
  • Avoid indexes like nth(3) — they break when the DOM changes.

Get Playwright tutorials in your inbox

Weekly tips, real-world examples, and framework patterns – no spam, unsubscribe anytime.

Recommended Next Articles