PRACTICAL GUIDE / Playwright getByRole accessible description locator

Locate Elements by Accessible Description in Playwright

Learn Playwright getByRole accessible description locator with working code, failure cases, debugging steps, and CI evidence for reliable QA automation.

By The Testing AcademyUpdated July 18, 202617 min read
All field guides
In this guide11 sections
  1. Start with the Semantic Identity
  2. Follow the Playwright 1.61.1 Matching Rules
  3. Build the Description through Real Markup
  4. Implement a Locator that Can Fail Clearly
  5. Compare Name, Description, Test ID, and Text
  6. Cover the Boundary and Failure Matrix
  7. Treat Descriptions as Stateful Product Content
  8. Debug a Missing or Ambiguous Description
  9. Govern Accessible Descriptions in CI
  10. Frequently Asked Questions
  11. What does description match in Playwright getByRole?
  12. Is accessible description the same as accessible name?
  13. How does exact affect name and description matching?
  14. Should description be used to resolve every strict-mode collision?
  15. How should accessible-description locators be tested in CI?
  16. Practice the Locator Decision in QABattle

What you will learn

  • Start with the Semantic Identity
  • Follow the Playwright 1.61.1 Matching Rules
  • Build the Description through Real Markup
  • Implement a Locator that Can Fail Clearly

Playwright getByRole accessible description locator support lets a test distinguish controls by the description computed for accessibility APIs. Pass description beside the role and usually name, then assert the description before acting. The first failure boundary is semantic: if the relation breaks, the locator should fail even when identical visible buttons still exist in the DOM.

This is valuable for repeated labels such as Delete, Open, or Learn more, where supporting text gives each control a different consequence. It is not a general text filter. The option asks the accessibility model for a computed description, which makes it expressive but also means the test must understand names, descriptions, matching rules, and product intent.

Start with the Semantic Identity

A role answers what the element is. An accessible name answers how a user identifies it. An accessible description adds supporting information that helps explain purpose, consequences, format, or constraints. A strong locator states only the parts of that identity that the product promises to keep stable.

Imagine two Delete buttons in a draft manager. One is described as Moves this draft to trash for 30 days; the other says Permanently deletes this draft and its comments. The shared name may be deliberate because each button sits in a separately named region, or it may be an accessibility design issue. Before adding description, decide whether users can reliably distinguish the controls in the actual interface.

The Playwright locator guide recommends user-facing attributes such as role and name because they align tests with the rendered experience. Description extends that strategy when extra semantic text truly disambiguates the target. It should not reach into a class name, data attribute, or adjacent paragraph that accessibility APIs do not associate with the element.

Write the locator decision as a sentence: "Choose the button named Delete whose accessible description states that the action is permanent." If the test cannot justify every clause, reduce it. If the sentence reveals that both buttons are indistinguishable to users, fix the interface before making the test cleverer.

Follow the Playwright 1.61.1 Matching Rules

The Playwright release notes identify description as an option added to page.getByRole(), locator.getByRole(), frame.getByRole(), and frameLocator.getByRole(). The installed 1.61.1 type is description?: string | RegExp. It sits beside existing role options such as name, checked, disabled, expanded, and includeHidden.

String description matching is case-insensitive and substring-based by default. With { exact: true }, string name and string description matching become case-sensitive and whole-string, while whitespace is still trimmed. exact is ignored for regular expressions, so case sensitivity and boundaries must be encoded in the expression itself.

That shared exact option is easy to overlook. This locator requires exact matching for both values:

Exact role locator: name and description together

TypeScript
const permanentDelete = page.getByRole('button', {
  name: 'Delete',
  description: 'Permanently deletes this draft and its comments.',
  exact: true,
});

Changing the description to lowercase would stop matching, but so would changing the name to Delete draft. If only one field needs flexible matching, use a deliberate regular expression for that field rather than assuming exact can be configured independently.

Role locators still exclude ARIA-hidden elements by default. A matching description does not make a hidden control eligible unless includeHidden is requested. Likewise, description does not bypass strictness: an action on a locator that resolves to multiple elements fails instead of selecting the first one silently.

Build the Description through Real Markup

The most readable fixture connects a control to explanatory text with an authored semantic relationship. aria-describedby is common for hints, constraints, and consequences. The locator matches the resulting computed description rather than the ID or the source element's CSS location.

Fixture: actions with distinct consequences

HTML
<section aria-labelledby="draft-heading">
  <h2 id="draft-heading">Quarterly report draft</h2>

  <p id="trash-help">Moves this draft to trash for 30 days.</p>
  <button aria-describedby="trash-help">Delete</button>

  <p id="permanent-help">
    Permanently deletes this draft and its comments.
  </p>
  <button aria-describedby="permanent-help">Delete</button>
</section>

This fixture contains two buttons with the same role and name but different descriptions. A test can scope first to the named section, then match the destructive consequence. Scoping remains useful even when description is unique because it documents which draft owns the action and prevents an unrelated dialog from creating a collision.

Do not test only the aria-describedby attribute value. An ID can remain present while pointing to a missing node, stale message, or text from another component. An attribute assertion proves wiring syntax; toHaveAccessibleDescription proves the computed result. The ARIA snapshot accessibility guide provides a wider view when the relationship must be understood within surrounding roles and hierarchy.

The description source may not have the visibility or layout behavior that the product requires. A computed description assertion does not prove that sighted users can see help text, that screen readers announce it at the intended moment, or that the wording is understandable. Add direct visible-text, focus, or user-journey checks when those are separate requirements.

Implement a Locator that Can Fail Clearly

Use a short sequence that exposes semantic problems before the destructive action:

  1. Navigate to deterministic data and scope the scenario to a named landmark or component.
  2. Locate the candidate by role and accessible name without description, then confirm how many controls share that identity.
  3. Add the computed description only when it represents an intentional user-facing distinction.
  4. Assert toHaveAccessibleDescription so failure reports the semantic contract directly.
  5. Perform the action through the final role locator and assert the durable product result.
  6. Retain scoped semantic evidence on failure, with private text removed before external sharing.
  7. Add a negative case that breaks the description relationship and must not reach the destructive outcome.

Playwright example: assert meaning before action

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

test('permanent delete targets the described action', async ({ page }) => {
  await page.goto('/drafts/quarterly-report');

  const draft = page.getByRole('region', {
    name: 'Quarterly report draft',
  });

  const candidate = draft.getByRole('button', {
    name: 'Delete',
    exact: true,
  });

  await expect(candidate).toHaveCount(1);
  await expect(candidate).toHaveAccessibleDescription(
    'Permanently deletes this draft and its comments.',
  );

  const permanentDelete = draft.getByRole('button', {
    name: 'Delete',
    description: 'Permanently deletes this draft and its comments.',
    exact: true,
  });
  await permanentDelete.click();
  await expect(page.getByRole('dialog', { name: 'Delete draft permanently' }))
    .toBeVisible();
});

The candidate locator deliberately does not filter by description. That gives a missing or changed description an expected-versus-received matcher failure instead of reporting that the final locator found nothing. After the semantic assertion passes, a separate description-filtered locator performs the action and proves that the same meaning can be used to select the intended control.

For repeated domain patterns, use a typed locator factory that accepts the intended consequence but returns a locator without clicking it. If the helper also owns assertions or actions, its name should make those effects clear. The custom matcher article shows how to preserve useful matcher diagnostics while centralizing a semantic contract.

Compare Name, Description, Test ID, and Text

Each locator signal answers a different question. Select the one that reflects the user contract, then combine signals only to resolve genuine ambiguity.

Locator approachBest useStrengthFailure risk
getByRole(role, { name })A control has a clear unique identityClosely follows how users identify controlsCollides when names are intentionally repeated
getByRole(role, { name, description })Repeated names have distinct computed explanationsEncodes role, identity, and consequenceCan hide a design problem if descriptions are not usable distinctions
getByText()The text node itself is the target or content assertionDirect and readable for visible copyNearby text is not proof of a control's semantic description
getByTestId()No stable user-facing identity exists for an implementation controlExplicit testing contract independent of wordingDoes not validate accessibility semantics
CSS locatorStructural or styling target cannot be expressed semanticallyPrecise access to authored markupCouples tests to implementation and can survive broken semantics
toHaveAccessibleDescription()The computed description is the requirementProduces a focused semantic assertionDoes not perform the user action or prove visible help

Do not replace all test IDs with description locators. A canvas handle, internal drag surface, or visual swatch may need an explicit testing contract. Conversely, a submit button with a clear role and name should not use a test ID merely to avoid confronting a missing label. The accessibility testing tools overview explains why locator choice offers useful feedback but does not constitute a complete accessibility audit.

Description also differs from an ARIA snapshot. The locator chooses one element based on computed properties. A snapshot records a scoped semantic tree for comparison or diagnosis. Combine them when hierarchy matters, but avoid a large snapshot when a single focused matcher states the requirement more clearly.

Cover the Boundary and Failure Matrix

Description locators fail at semantic, state, language, and ownership boundaries. Plan those cases before a production incident turns a broad substring into the wrong click.

BoundaryConcrete failureExpected observationCI decision
RoleButton is replaced by a clickable generic elementgetByRole('button') cannot find the targetBlock as a semantic and interaction regression
Accessible nameDelete becomes an unnamed iconName-based locator and name assertion failBlock; do not compensate with description alone
Description relationaria-describedby references a removed IDDescription locator and matcher failBlock the owned component change
Description contentHelp text describes the wrong retention periodExact description assertion reports the wording mismatchBlock or route through approved copy change review
Duplicate identityTwo controls share role, name, and descriptionAction fails strict resolutionFix scope or product semantics; never call first() by habit
Matching policySubstring deletes this draft matches temporary and permanent actionsCount or strictness exposes ambiguityUse exact string or anchored expression based on the contract
Dynamic stateDescription changes only after selecting a planPrecondition assertion shows old computed textWait for the owned state transition, not elapsed time
LocalizationEnglish description is used in a French projectLocale-specific semantic assertion failsClassify fixture versus translation defect with locale metadata
FrameTarget action lives in an embedded editorPage scope misses it; frame locator finds itUse frame ownership explicitly and test load failure separately
Hidden stateMatching control is excluded from the ARIA treeDefault role locator does not match itAssert intended visibility instead of forcing hidden inclusion

An effective negative test removes the referenced description node but leaves both Delete buttons rendered. The permanent-action locator must fail, and the draft must remain. This proves the test is using computed semantics rather than DOM order. Another useful case gives both buttons the same description and expects strictness to expose the ambiguity.

The visual accessibility interview scenarios are a helpful reminder that text placement and semantic association can diverge. A paragraph directly under a button may look explanatory while contributing nothing to its accessible description.

Treat Descriptions as Stateful Product Content

Playwright locators are evaluated when they are used, not frozen to the element that matched when the locator variable was created. If a description changes after selection, validation, expansion, or a network response, an earlier locator with the old description can stop resolving. That is often correct: the semantic identity described by the locator no longer exists in the current state.

Model those transitions explicitly. A plan chooser might describe a button as Select Basic, $12 per month before selection and Basic is your current plan afterward. Use one locator and assertion for the pre-action state, trigger the selection, then use a second state-specific assertion. Reusing the old locator and increasing its timeout would obscure the fact that the application moved to a new contract.

Descriptions can be composed from more than one source. An aria-describedby value may reference multiple IDs, and the computed result follows the accessibility description algorithm rather than DOM proximity. Assert the resulting description in the order and wording the product intends. Do not join source nodes in test code and assume that hand-built string proves what the browser exposes.

Keep validation errors separate. aria-errormessage represents an accessible error-message relationship, and Playwright provides toHaveAccessibleErrorMessage for that contract. Do not assume a getByRole({ description }) locator will select a field by its error message. A field can have stable instructions as its description and a changing validation error as a distinct property. Testing each with its matching semantic assertion produces clearer failure ownership.

Localization turns exact description text into a project-specific contract. Seed the locale, avoid machine-dependent formatting, and store approved expectations with the language they represent. A regular expression is suitable only when it describes allowed variability, such as a localized count placeholder. It should not make all translated wording optional. The locator guide remains useful here because narrowing to a named form or region can reduce dependence on repeated translated controls.

Responsive design adds another boundary. Computed descriptions should not change merely because helper text moves visually, but component implementations sometimes swap markup between breakpoints. Run the semantic contract at each supported component variant when the DOM differs. If only clipping, wrapping, or placement changes, diagnose that through the visual snapshot CI guide rather than weakening the description assertion.

Page objects should expose intent, not description-source mechanics. A method such as permanentDeleteButton() can return the role, name, and computed-description locator. It should not accept an aria-describedby ID from the test, because that couples callers to implementation and bypasses the semantic result. Keep the expected consequence readable at the call site or in a domain-named helper.

Finally, classify description text as test data. Help content can contain names, account limits, file titles, or other user-derived details. Use synthetic values and scoped attachments. When a failure artifact must leave CI, sanitize the computed output without changing the local assertion that protected the exact user experience. If sanitization removes the distinction needed by an AI reviewer, keep the case local instead of sending ambiguous evidence.

Debug a Missing or Ambiguous Description

Start with a broad but semantic probe. Locate by role and name, inspect its count, then use toHaveAccessibleDescription with the expected value. If the control exists but the matcher fails, inspect the authored relationship and source text. If the broad locator also fails, investigate role, name, hidden state, frame, or readiness before blaming description matching.

Capture ariaSnapshot() on the smallest parent region to see the roles and names around the target. The snapshot is diagnostic context, not a substitute for the focused description matcher. If a failed locator assertion populates additional ARIA context, Playwright exposes that through TestInfoError.errorContext, documented in the official TestInfoError API. Preserve the original error alongside any extra attachment.

Check matching rules deliberately. Log whether the test passed a string or regular expression and whether exact is true. A case-only change can break exact string matching. A substring can match more controls after new copy is added. An unanchored regular expression can accept suffixes the product did not approve. Do not add i or .* until the allowed variability is written down.

For dynamic descriptions, assert the transition. A password field may change from At least 12 characters to a validation result after blur. Locate and assert the before state, perform the interaction, then assert the new description. This chronology distinguishes a stale relation from a locator that was evaluated too early.

When the action is keyboard-driven, pair the semantic locator with keyboard navigation testing. The existence of a correctly described button does not prove focus order, visible focus, Enter or Space activation, or post-action focus placement.

Govern Accessible Descriptions in CI

Treat names and descriptions as product interfaces. Copy changes can be intentional, but they should not be bulk-approved as selector maintenance. A reviewer should decide whether the meaning changed, whether localization owns the difference, and whether the test should use exact text, a narrower invariant, or a locale-specific expectation.

Run a compact contract suite across ordinary, missing, duplicate, localized, dynamic, hidden, and framed cases. Report the role, expected name, expected description, locale, frame, and locator scope on failure. That metadata is more actionable than a generic timeout and avoids opening traces merely to discover which language project ran.

Do not retry semantic ambiguity. If two controls match, more time will not make the locator's intent clearer. Retries can help a known asynchronous state reach its milestone, but strictness and wrong computed text require a product, fixture, or test-contract change. The guide to reviewing AI-written Playwright tests is particularly relevant because generated locators often add broad text filters to make a scenario pass once.

Retain scoped ARIA evidence for failed semantic contracts, not full pages by default. Redact user-generated descriptions and values before external analysis. Pin Playwright and browser versions during adoption, then run the contract fixtures during upgrades so accessibility mapping changes are reviewed separately from application changes.

Track why description was added. A short code comment is unnecessary when the locator reads clearly, but a helper or test title can state the domain distinction, such as temporary versus permanent deletion. Periodically review description locators with recurring collisions. If the same names need increasingly detailed descriptions, the interface may need clearer labels or stronger component scope.

For the wider semantics program, connect this suite to ARIA snapshot accessibility testing and manual review. Locator success is valuable early feedback, but it does not certify announcement order, clarity, keyboard use, or compliance.

Frequently Asked Questions

What does description match in Playwright getByRole?

The description option matches the element's computed accessible description, not a CSS attribute or any nearby text. That description can be produced by relationships such as aria-describedby. Use it with the role and, when stable, the accessible name so the locator expresses the same semantic identity exposed through accessibility APIs.

Is accessible description the same as accessible name?

No. The accessible name identifies a control, while the accessible description supplies additional explanation. A button might be named Delete and described as Permanently deletes this draft. Tests should normally locate by role and name, adding description when that extra semantic distinction is part of the real interface contract.

How does exact affect name and description matching?

For string values, exact makes both name and description matching case-sensitive and whole-string, although surrounding whitespace is still trimmed. Without exact, string matching is case-insensitive and can match a substring. When either option uses a regular expression, exact does not alter that regular expression's matching behavior.

Should description be used to resolve every strict-mode collision?

No. First decide whether the controls should have distinct accessible names or a narrower semantic scope. Add description only when users genuinely receive that differentiating description and the product intends it as part of the control's identity. A test must not use hidden implementation detail to conceal an accessibility design problem.

How should accessible-description locators be tested in CI?

Cover the ordinary description, a missing relationship, duplicate controls, localization, dynamic help text, and frame boundaries. Assert the description directly before the action, then assert the user outcome. CI should block owned semantic regressions, classify fixture or translation drift separately, and retain scoped ARIA context for diagnosis.

Practice the Locator Decision in QABattle

Start with one repeated action label. Identify its role, name, computed description, component scope, and outcome. Then break the description relationship while leaving the visible layout intact. A trustworthy test should refuse to choose by order and should explain the missing semantic distinction before any destructive action occurs.

Try that review loop in QABattle battles. Select a locator challenge, state what a user can identify before writing the selector, and verify the result after the action. The exercise turns description from a convenient collision filter into a deliberate accessibility contract with a clear CI owner.

// LIVE COURSE / THE TESTING ACADEMY

Playwright Automation Mastery

Go beyond Selenium. Master Playwright with JS/TS in 90 days.

From the instructor behind this guide.

Playwright jobs are growing 8x faster than Selenium. 90 days / 75+ live hrs / Tue-Thu-Sat 7 AM IST.

Code PROMODE / 10% offJoin the batch

The Testing Academy editorial desk

Practical QA guidance built around test evidence, production tradeoffs, and interview-ready explanations.

Published July 18, 2026 / Reviewed July 18, 2026

PRIMARY REFERENCES

Verify the details at the source

QABattle guides are practical explanations. Product behavior, standards, and APIs can change, so use these primary references for the canonical details.

  1. 01
    Official playwright.dev reference

    playwright.dev

    Primary documentation selected and verified for the claims in this guide.

  2. 02
    Official playwright.dev reference

    playwright.dev

    Primary documentation selected and verified for the claims in this guide.

  3. 03
    Official playwright.dev reference

    playwright.dev

    Primary documentation selected and verified for the claims in this guide.

  4. 04
    Official playwright.dev reference

    playwright.dev

    Primary documentation selected and verified for the claims in this guide.

FAQ / QUICK ANSWERS

Questions testers ask

What does description match in Playwright getByRole?

The description option matches the element's computed accessible description, not a CSS attribute or any nearby text. That description can be produced by relationships such as aria-describedby. Use it with the role and, when stable, the accessible name so the locator expresses the same semantic identity exposed through accessibility APIs.

Is accessible description the same as accessible name?

No. The accessible name identifies a control, while the accessible description supplies additional explanation. A button might be named Delete and described as Permanently deletes this draft. Tests should normally locate by role and name, adding description when that extra semantic distinction is part of the real interface contract.

How does exact affect name and description matching?

For string values, exact makes both name and description matching case-sensitive and whole-string, although surrounding whitespace is still trimmed. Without exact, string matching is case-insensitive and can match a substring. When either option uses a regular expression, exact does not alter that regular expression's matching behavior.

Should description be used to resolve every strict-mode collision?

No. First decide whether the controls should have distinct accessible names or a narrower semantic scope. Add description only when users genuinely receive that differentiating description and the product intends it as part of the control's identity. A test must not use hidden implementation detail to conceal an accessibility design problem.

How should accessible-description locators be tested in CI?

Cover the ordinary description, a missing relationship, duplicate controls, localization, dynamic help text, and frame boundaries. Assert the description directly before the action, then assert the user outcome. CI should block owned semantic regressions, classify fixture or translation drift separately, and retain scoped ARIA context for diagnosis.