Role, Text and Test ID Selectors

Role, text, and test ID selectors are three of the most powerful patterns in Playwright. They let you express user intent clearly, whether you are selecting a button by its accessible name or a component by a stable data attribute.

Using Role and Text Selectors

Role-based selectors use the ARIA role and accessible name of elements. Text selectors match visible text nodes. These are ideal when the UI has clear labels and headings.

// role-text-testid.spec.ts
import { test, expect } from '@playwright/test';

test('checkout button using role and text', async ({ page }) => {
  await page.goto('https://demo.myshop.com/cart');

  // Role + name for the primary checkout button.
  await page.getByRole('button', { name: 'Proceed to checkout' }).click();

  // Verify we navigated to the checkout page.
  await expect(page.getByRole('heading', { name: 'Checkout' })).toBeVisible();
});
Note: Text selectors like page.getByText('Welcome back') work best when the text is unique and stable; avoid ambiguous phrases that appear many times.
Tip: Prefer role selectors for interactive controls (buttons, links, checkboxes) and text selectors for status messages or headings.
Warning: If designers frequently change wording, text selectors may need more maintenance; consider test IDs for critical flows.

Using Data Test IDs

When you need a selector that is stable regardless of visual changes, data-testid attributes are a good option. They are ignored by end users but exposed in the DOM for tests.

// Example HTML
// <button data-testid="primary-checkout">Proceed to checkout</button>

// Playwright test
await page.getByTestId('primary-checkout').click();

Agreeing on a naming convention for test IDs helps keep them consistent across the app, such as entity-action or page-element-purpose.

Common Mistakes

Mistake 1 โ€” Overusing text selectors for everything

This can be fragile.

โŒ Wrong: Selecting form fields only by their placeholder text, which UX may change.

โœ… Correct: Combine labels, roles, or test IDs for critical elements.

Mistake 2 โ€” Adding test IDs without any convention

This becomes messy.

โŒ Wrong: Using random, inconsistent values like data-testid="x1" and "btn123".

โœ… Correct: Define a clear naming pattern and document it for the team.

🧠 Test Yourself

When should you use data-testid selectors in Playwright?