Skip to contentPlayForge

How does the name option in getByRole match text?

Written by Jatin Thacker, Automation Architect · Updated

By default, name matches the accessible name case-insensitively and as a substring, so { name: 'Export CSV' } also matches 'export csv'. With exact: true it becomes case-sensitive and whole-string, though surrounding whitespace is still trimmed; a regular expression is matched as written.

This answer is one piece of Chapter 9: Locators I: What the User Sees.

  • getByRole and the Accessible Name
  • getByText, getByLabel, getByPlaceholder, getByTestId
  • Strict Mode — One Locator, One Element

The accessible name is what a screen reader announces for an element, usually its visible text or its label. The name option compares against that name, and three rules decide what counts as a match.

The dashboard's case-variants block has four buttons: Export CSV, export csv, Export csv, and Export CSV with spaces on both sides.

  1. Default. Case-insensitive substring. { name: 'Export CSV' } matches all four.
  2. exact: true. Case-sensitive and whole-string, but whitespace at the ends is trimmed. { name: 'Export CSV', exact: true } matches two: the plain one and the padded one. { name: 'export csv', exact: true } matches one.
  3. A regular expression. The exact option is ignored, and the pattern decides. /^Export csv$/ matches only Export csv. Add the i flag to make it case-insensitive again.

The test proves each count with toHaveCount() inside the block, so no other button on the page interferes.

In practice, start with the default. Add exact: true when one name contains another. Use a regular expression when you need a pattern the other two cannot express.

qa-053.spec.js(https://practice.learnplayforge.com)
import { test, expect } from '@playwright/test'; test('how the name option matches four Export buttons', async ({ page }) => { await page.goto('/index.html?mock=static&seed=42&autologin=1'); const section = page.getByTestId('case-section'); // Default: case-insensitive substring, so all four match await expect(section.getByRole('button', { name: 'Export CSV' })).toHaveCount(4); // exact: case-sensitive and whole-string, but whitespace is still trimmed await expect(section.getByRole('button', { name: 'Export CSV', exact: true })).toHaveCount(2); await expect(section.getByRole('button', { name: 'export csv', exact: true })).toHaveCount(1); // A regular expression is matched as written await expect(section.getByRole('button', { name: /^Export csv$/ })).toHaveCount(1); });
Output
1 passed (1.6s)
Test yourself
A button's text is Export CSV with spaces either side. Does getByRole('button', { name: 'Export CSV', exact: true }) match it?

Practised in the full course: the drill Case matters.

See the chapter

AI can write the test now. The job is knowing whether it checks anything. That's what the course teaches, one chapter at a time.

163 lessons · 226 drills · start free

← All questions

Training a team? Talk to us.