Skip to main content

Function: findByRole()

findByRole(role, name?, relative?): PartLocator

Defined in: packages/core/src/locators/findByRole.ts:45

Locate an element by its ARIA role plus its COMPUTED accessible name — the accname algorithm: aria-labelledby id-refs, an associated <label>, wrapping/title text, and (unlike byAriaLabel) plain visible text content. This is the common case for a design system that labels controls with visible text rather than a literal aria-label attribute.

Resolution is NOT CSS: the accessible name is computed by a multi-node graph traversal no CSS selector can express (see ADR-008). Each interactor resolves it internally via an engine that already implements accname — @testing-library/dom's getByRole in jsdom, Playwright's Locator.getByRole/Page.getByRole in the browser. name matching is always exact and case-sensitive in both engines (see AccessibleRoleLocator for why there is no exact option). Composing this with a preceding locator scopes the search to that ancestor's subtree (e.g. locatorUtil.append(dialogLocator, findByRole('button', 'Save')) finds "Save" only within the dialog); it must be the LAST segment of a chain — nothing can be appended after it.

Use findByRole when the name comes from visible text/<label>/ aria-labelledby; use byAriaLabel (composed via locatorUtil.and) when the name is a verbatim aria-label attribute — that stays a pure-CSS match with no accname cost.

Parameters​

role​

string

The ARIA role value to match, e.g. 'button', 'link'.

name?​

string

The computed accessible name to match, exact and case-sensitive. Omit to match by role alone (equivalent to byRole but accname-resolved).

relative?​

AccessibleRoleLocatorRelativePosition = 'Descendant'

Relative position of the locator. Only 'Root' (escape to the document root) and 'Descendant' (the default) are accepted: 'Same' (compound onto the same element) and 'Child' (restrict to a direct child) have no accname-search equivalent, so the type excludes them rather than silently falling back to 'Descendant' behavior — see AccessibleRoleLocatorRelativePosition.

Returns​

PartLocator

Example​

const saveButton = findByRole('button', 'Save');
const scopedSaveButton = locatorUtil.append(dialogLocator, findByRole('button', 'Save'));