Selectors — Finding Elements

Master Playwright's selector strategies. Learn getByRole, getByText, getByLabel, getByTestId, and CSS selectors -- and when to use each one.

Playwright Automation Module 2 Lesson 1
12 min read

What you'll learn

  • Use getByRole, getByText, getByTestId, and getByLabel to locate elements
  • Choose the right selector strategy for each situation
  • Understand why role-based selectors are preferred

Locators: Finding Elements

getByRole1st choice
getByText2nd
getByLabel3rd
getByTestId4th
CSS / XPath5th
  • getByRole:Accessible + resilient
  • getByText:Visible text content
  • getByLabel:Form fields with labels
  • getByTestId:Escape hatch
  • CSS / XPath:Last resort, brittle
Start at the top. Only drop down when the strategy above doesn't work.

The 5 Selector Strategies


Quick Check

Question 1 of 10 correct

Which selector should you reach for FIRST for a '<button>Submit</button>'?


Why getByRole Wins


Avoid CSS/XPath as First Choice


Selector Priority Summary

PriorityStrategyBest ForResilience
1stgetByRoleButtons, links, headings, form elementsHighest — tests accessibility
2ndgetByTextMessages, labels, static textHigh — text rarely changes
3rdgetByLabelForm fields with labelsHigh — labels are user-visible
4thgetByTestIdElements with no semantic hookMedium — stable but not semantic
5thCSS / XPathLegacy code, complex DOM queriesLow — breaks on refactors

Practice: Match HTML to the Best Selector

Match each HTML snippet on the left with the best Playwright selector on the right.


Practice: Fill In the Selectors

Fill in the correct Playwright locator method for each interaction.

import { test, expect } from '@playwright/test';

test('user can log in', async ({ page }) => {
await page.goto('https://app.example.com/login');

// Fill the "Email" input field (has a <label>Email</label>)
await page.('Email').fill('user@test.com');

// Fill the "Password" input field (has a <label>Password</label>)
await page.('Password').fill('secret123');

// Click the "Sign In" button
await page.('button', { name: 'Sign In' }).click();

// Verify the welcome heading appears
await expect(
  page.('heading', { name: 'Welcome' })
).toBeVisible();
});

Try It: Log In with Selectors


Knowledge Check

Question 1 of 30 correct

Why is getByRole considered the 'gold standard' selector in Playwright?