Lesson 5 / 25
Locators and Auto-Waiting
getByRole first, CSS last.
User-facing locators
A locator describes how to find an element; it is evaluated lazily each time you act on it, so it survives re-renders. Prefer locators that reflect what users and assistive technology see: page.getByRole('button', { name: 'Save' }), getByLabel('Email'), getByPlaceholder, getByText, and getByTestId('checkout') for elements without a good accessible name (it matches data-testid by default, configurable with testIdAttribute). Locators can be chained and filtered, for example page.getByRole('listitem').filter({ hasText: 'Milk' }). Before an action such as click() or fill(), Playwright auto-waits for actionability checks: the element must be attached, visible, stable, enabled and able to receive events.
Locating and acting
Role, label, test id, chaining and filtering.
import { test, expect } from '@playwright/test';
test('checks out a product', async ({ page }) => {
await page.goto('/products');
const card = page.getByRole('article').filter({ hasText: 'Blue Mug' });
await card.getByRole('button', { name: 'Add to cart' }).click();
await page.getByRole('link', { name: 'Cart' }).click();
await page.getByLabel('Email').fill('asha@example.com');
await page.getByTestId('checkout-submit').click();
await expect(page.getByRole('heading', { name: 'Order confirmed' })).toBeVisible();
});Let codegen suggest locators
npx playwright codegen <url> opens a browser and records your actions as code, choosing role-based locators where it can. Treat the result as a starting point and tidy it.
Quick check: What does Playwright do before clicking a locator?
- Clicks immediately and fails if the element is missing
- Waits for the element to be visible, stable, enabled and able to receive events
- Sleeps for a fixed one second
- Reloads the page
Answer
Waits for the element to be visible, stable, enabled and able to receive events — Actionability checks remove most manual waits.