GetByRole in Playwright — Most of us regularly use page.getByRole
in Playwright, but I doubt many are not fully aware of its benefits for accessibility testing. Additionally, the examples on the Playwright official website don’t provide detailed explanations on when to use this method and when to avoid it.
This powerful method not only helps us to locate elements on a page but also ensures that accessibility standards are being met.
Surprised? It’s a two-in-one utility in PlayWright that finds elements while simultaneously validating the use of correct ARIA roles. It is the Swiss Army knife of Playwright Locator strategy, helping QAs to both in selecting elements and checking for accessible web design, something that can enhance both usability and compliance with accessibility guidelines.
What is WAI-ARIA roles?
WAI-ARIA (Web Accessibility Initiative – Accessible Rich Internet Applications) 1.2 is a technical specification that provides guidelines for making web content and applications more accessible to people with special abilities. It helps assistive technologies like screen readers to function effectively. HTML alone doesn’t always provide sufficient information for assistive technologies, so WAI-ARIA suggests to add roles, properties, and states to make dynamic content understandable to screen readers.
Interesting, right?
So when you write a locator as below, it not only locates the Buy With Credit Card
button, but it also ensures that screen readers will be able to understand this as button, and will read it correctly.
await page.getByRole('button', { name: 'Buy With Credit Card' });
Through this article, I will highlight the advance usage of the Playwright GetByRole locator strategy. As the PlayWright official document only captures the basic examples, which does not provide comprehensive information on usage of GetByRole
.
Additionally, I’ll help you to identify situations where GetByRole
should be avoided.
I promise, this article will serve as a one-stop solution for understanding the Playwright GetByRole locator strategy using effectively.
[Are you facing error while installing PlayWright executable in MacOS? Discover the solution here.]
[Do you want to print all the attributes of an element in PlayWright? Discover the solution here.]
The ARIA Roles in HTML
As per the WAI-ARIA Roles guidelines, it is recommended to developers to use native HTML elements like <button>
, <input>
, <select>
, etc., because they inherently support accessibility features.
For PlayWright users, the native HTML elements will work as per their role suggested by WAI-ARIA guidelines.
For native HTML elements, the getByRole works even if their HTML representation does not contain role attribute.
With the help of following table, you would be able to clearly understand what are the native elements in HTML and their corresponding role as per the WAI-ARIA Role guidelines.
PlayWright’s getByRole Implementation
PlayWright Implementation of GetByRole
method.
The roles are specified as “alert”|”alertdialog”|”application”|”article”| ..etc.
The attribute which getByRole
supports are checked?: boolean;
disabled?: boolean;
exact?: boolean;
expanded?: boolean;
includeHidden?: boolean;
level?: number;
name?: string|RegExp;
pressed?: boolean;
selected?: boolean;
getByRole(role: "alert"|"alertdialog"|"application"|"article"|"banner"|"blockquote"|"button"|"caption"|"cell"|"checkbox"|"code"|"columnheader"|"combobox"|"complementary"|"contentinfo"|"definition"|"deletion"|"dialog"|"directory"|"document"|"emphasis"|"feed"|"figure"|"form"|"generic"|"grid"|"gridcell"|"group"|"heading"|"img"|"insertion"|"link"|"list"|"listbox"|"listitem"|"log"|"main"|"marquee"|"math"|"meter"|"menu"|"menubar"|"menuitem"|"menuitemcheckbox"|"menuitemradio"|"navigation"|"none"|"note"|"option"|"paragraph"|"presentation"|"progressbar"|"radio"|"radiogroup"|"region"|"row"|"rowgroup"|"rowheader"|"scrollbar"|"search"|"searchbox"|"separator"|"slider"|"spinbutton"|"status"|"strong"|"subscript"|"superscript"|"switch"|"tab"|"table"|"tablist"|"tabpanel"|"term"|"textbox"|"time"|"timer"|"toolbar"|"tooltip"|"tree"|"treegrid"|"treeitem", options?: {
checked?: boolean;
disabled?: boolean;
exact?: boolean;
expanded?: boolean;
includeHidden?: boolean;
level?: number;
name?: string|RegExp;
pressed?: boolean;
selected?: boolean;
}): Locator;
,
getByRole in PlayWright for Native HTML Elements
A button with does not have attribute role
but still it can’t identified by getByRole
in PlayWright as button
is an example of native html element.
<div className="mb-6">
<label className="block mb-2 text-sm font-medium text-gray-700">
Button:
</label>
<button className="px-4 py-2 bg-blue-500 text-white rounded">Click Here</button>
</div>
await page.getByRole('button', {name: 'Click Here'}).click();
await expect(page.getByRole('button', {name: 'Clicked'})).toBeVisible();
An input check which is having an attribute as aria-checked="true"
can also be identified in PlayWright getByRole as
await expect(page.getByRole('checkbox', {selected: true })).toBeVisible();
Another example of list:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
const item1 = await page.getByRole('listitem', { name: 'Item 1' });
const item2 = await page.getByRole('listitem', { name: 'Item 2' });
const item3 = await page.getByRole('listitem', { name: 'Item 3' });
GetByRole in PlayWright for Non-Native Elements
Often, developers use non-native elements to design user interface.
One of the common example of usage of non-native element is div
. A button can also be designed as div
by having something like:
<div onclick="toggleButton(this)">Click Me</div>
This creates a confusion for PlayWright users to understand whether getByRole
will work in this case or not.
The answer is NO, the div is designed to work as button but it is not a native element as suggested by WAI-ARIA. For this div, if we write page.getByRole('button', {name: 'Click Me'})
will result in failure.
As per the guidelines of WAI-ARIA, developer should specify the role of the div. The screen readers will be able to identify is as button only if specifies role
as <div onclick="toggleButton(this)" role="button">Click Me</div>
Playwright can locate elements using the getByRole function if a role is defined.
How to understand when to use getByRole?
To make it easier for Playwright users to understand when to use the getByRole function, consider this:
- For native elements, getByRole will work regardless of whether the role attribute is present.
- For non-native elements, getByRole will only work if a role attribute is specified.
Isn’t it easy now to understand when to use getByRole?
When to avoid getByRole?
getByRole should be avoided only if a non-native element without role is present in HTML. As explained above, the non-native elements won’t be located by getByRole. In this case, it is recommended to use other method like page.locator
() , page.getByText()
, etc.
Additionally, GetByRole should be avoided when you are planning to run tests against different languages.
Other benefits of GetByRole
Thought it can’t be completely replaced for accessibility testing, but having locator finding strategy using getByRole at least ensures that screen-readers will work for the given html element. So it is recommended for PlayWright users to prefer getByRole
and in case it does not work for any element, a suggestion can be made to developers to fix the HTML to have attributes like role
and others as per WAI-ARIA guidelines.
Impact on Test Execution Speed by usage of GetByRole in PlayWright
The following screenshot shows my basic test execution using both getByRole and CSS locator by ID. If you look at the execution time on the right-hand side of each line, you’ll see there’s no significant difference between the two methods: getByRole took 145 ms, while the locator by ID took around 147 ms. Both methods perform equally well, so I don’t see any slowness introduced by the getByRole method, as some have claimed.
However, a more detailed comparison is needed to understand how these methods behave on a complex, dynamic page.
Thank you for reading this post, don’t forget to subscribe!