All posts

Playwright and stable selectors - the data-testid attribute
Playwright and stable selectors - the data-testid attribute

Polski

Playwright and stable selectors - the data-testid attribute

Write tests that survive UI refactors by giving important elements stable hooks instead of long, fragile CSS selectors. The post follows Playwright’s recommended test id style and relates it to the familiar Cypress idea of dedicated data attributes.

Playwright

Introduction

Long :nth-child selectors break the first time someone tweaks the layout. Cypress best practices tell you to target dedicated data-* attributes (their examples and the parallel blog post often use data-cy). In the Playwright snippets below I stick to data-testid only: that is the attribute getByTestId queries by default, so you stay aligned with Playwright docs while following the same stability idea Cypress recommends.

Previous post: URLs and configuration.

The data-testid attribute

getByTestId resolves to [data-testid=...] out of the box; you do not need extra config to match Playwright’s documented style.

React example (same refactor as the Cypress series, with Playwright’s attribute name):

<input
  className="form-control form-control-lg"
  type="email"
  data-testid="email-input"
  ...
/>
<input
  type="password"
  data-testid="password-input"
  ...
/>
<button type="submit" data-testid="sign-in-button">
  Sign in
</button>

Spec code

import { test, expect } from "@playwright/test"

test("logs in", async ({ page }) => {
  await page.goto("/login")
  await page.getByTestId("email-input").fill("test@test.com")
  await page.getByTestId("password-input").fill("test")
  await page.getByTestId("sign-in-button").click()
  await expect(page).toHaveURL(/localhost:4100\/$/)
})

getByTestId participates in the same auto-waiting and composition rules as other locators.

Reference videos

Selector playground (mp4)

Email field (mp4)

Git references

https://github.com/12masta/react-redux-realworld-example-app/tree/5-cypress

https://github.com/12masta/react-redux-realworld-example-app/pull/6/files

Next: Cross-browser runs with Playwright.