Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for How To Locate Elements in Playwright
Playwright end to end Testing profile imageDebbie O'Brien
Debbie O'Brien forPlaywright end to end Testing

Posted on • Originally published atdebbie.codes

     

How To Locate Elements in Playwright

In order to write end to end tests we need to first find elements on the webpage and then perform user actions on them. For example, find a link and click on it.

The most convenient way to find an element is to usePlaywright's test generator, which allows you to not only generate tests but also generate a locator for a specific element.

But before we dive into how to use the test generator, first let's understand what a link element is and what exactly locators are.

What is a link?

The HTML<a> element, also known as the anchor element, is an interactive element that creates a hyperlink to another page either within your site or externally to another site. It can also be used to link to specific areas on the same page as well as for emails, file downloads or anything else a URL can address. The<a> element uses thehref attribute to pass in the URL that the hyperlink points to.

So how can we locate a link element so we can click it? We use Locators.

What are locators?

In Playwright we use a term calledLocators. Locators represent a way to find elements on the page complete withauto waiting and retry-ability. Auto waiting means that Playwright performs a range of actionability checks on the elements, such as ensuring the element is visible and enabled before it performs the click.

You can locate elements by:

How to locate a link

The HTML<a> element comes with the implicitly defined role of link, so we don't need to modify the HTML in order to get this role.

<ahref="/about">About</a>
Enter fullscreen modeExit fullscreen mode

That means we can locate an<a> element by using thegetByRole() locator, with the role of link and add the click method to the end of it.

awaitpage.getByRole('link').click();
Enter fullscreen modeExit fullscreen mode

Adding a name

This will work but of course what if you have more than one link on the page? That's where thename option comes in. This is the accessible name for the link used by Assistive Technologies to identify the element. The name is normally taken from the elements content, an attribute, or from an associated element.

awaitpage.getByRole('link',{name:'About'}).click();
Enter fullscreen modeExit fullscreen mode

Using regex

We can also use a regular expression and ignore the case so that the test will pass regardless of if the text it contains has a capital letter or not.

awaitpage.getByRole('link',{name:/about/i}).click();
Enter fullscreen modeExit fullscreen mode

Setting exact to true

You can set exact to true for an exact match. This is helpful if, for example, you have a link that contains the text "About" and another one that contains the text "About the Company". With exact set to true it will only match the link with "About" and not with "About the Company".

awaitpage.getByRole('link',{name:'About',exact:true}).click();
Enter fullscreen modeExit fullscreen mode

Adding an aria-label

If a link contains anaria-label then the value of the aria label will be used instead of the text content.

<ahref="/locators"aria-label="read more about locators">Read more</a>
Enter fullscreen modeExit fullscreen mode

We can then locate the link using thegetByRole() locator of link followed by the value of the aria-label as the name.

awaitpage.getByRole('link',{name:/read more about locators/i}).click();
Enter fullscreen modeExit fullscreen mode

When you are writing your tests it can be quite difficult to know which accessible role to use if using thegetByRole() locator. For a link it is pretty straight forward but there is a vast list of roles that can be used. If your element doesn't have an accessible locator then choosing the best locator to use is not easy especially if you are not familiar with the DOM structure of the site you are testing. So how can you choose the best locator?

Don't spend time trying to figure out which is the best locator to use. Instead use the test generator to generate your locator.


Playwright's test generator

You can generate code right from VS Code when using theVS Code extension by clicking the 'record new' link from the testing sidebar.

test generator in vs code editor

As you click on an element on your website, the generator will look at your page and figure out the best locator for you, prioritizing role, text and test id locators. If the generator finds multiple elements matching the locator, it will improve the locator to make it resilient and uniquely identify the target element, so you don't have to worry about failing tests due to locators. For example, it could chain locators to narrow down the scope, or use thefilter() method to select between multiple elements.

If you are not using the VS Code extension, Playwright comes with a standalone test generator calledCodegen.

npx playwright codegen
Enter fullscreen modeExit fullscreen mode

Codegen

Pick a locator

You can pick a locator by clicking thepick locator button from the testing sidebar when using the VS Code Extension.

pick locator from vs code highlighting the locator in browser window

When you hover over any element in the browser window the locator for that element will be highlighted under your cursor. If you click on the element the locator will appear in the 'pick locator' box. You can then copy it to your clipboard and paste it into your test.

You can also pick a locator when using the standalone test generator by clicking the explore button.

npx playwright open
Enter fullscreen modeExit fullscreen mode

test generator generating a getByRole locator for a link

Chaining locators

If your site contains duplicate links, for example two about links, one in the header and one in the footer, then the test generator will create a unique locator for each one. It does this by looking for an easily-identifiable ancestor of the link and chains the locators.

getByRole('navigation').getByRole('link',{name:'About'})
Enter fullscreen modeExit fullscreen mode

test generator highlighting the about link in the header

For the about link in the footer the test generator again looks for an ancestor and chains the twogetByRole() locators ensuring that there is only one element matching this locator.

getByRole('contentinfo').getByRole('link',{name:'About'})
Enter fullscreen modeExit fullscreen mode

test generator highlighting the footer link

Filtering locators

If the test generator can't give you a unique locator through chaining it will use thefilter() method to ensure the locator is unique. For example, we might have two lists that contain topics for blog posts. The first list is used to filter the blog posts and the second list is used to display the topics for each post. The test generator will use thefilter() method to ensure the locator is unique.

getByRole('list').filter({hasText:'architecturedev reljamstackjavascriptlifestylementoringmotivationnuxtperformance'}).getByRole('link',{name:'architecture'})
Enter fullscreen modeExit fullscreen mode

test generator generating a list locator with filter method

Improving your locators

You may notice that filtering by text can sometimes give you a really ugly locator, like in the example above, and may cause you issues later, especially if you add another topic to the filters.

You can improve this filter by using a regular expression to match certain words in the text, choosing ones that would normally not be seen together in a post such as 'architecture', 'mentoring' and 'testing'.

getByRole('list').filter({hasText:/architecture.*mentoring.*testing/}).getByRole('link',{name:'architecture'})
Enter fullscreen modeExit fullscreen mode

Another option is to add an aria-label to the first<ul> element with the value of topics. This not only helps improve the accessibility of the page but also allows Playwright to locate by role.

<ularia-label="topics">  //...</ul>
Enter fullscreen modeExit fullscreen mode

The test generator will now use this aria-label and locate by the role of list with the name of topics therefore generating a unique locator.

getByRole('list',{name:'topics'}).getByRole('link',{name:'architecture'})
Enter fullscreen modeExit fullscreen mode

test generator generating a list locator with aria-label

Conclusion

There are many other roles and locators that we didn't touch on in this post. The great thing is that you don't have to know which ones are available to you because thanks to the test generator you don't have to worry about which role or locator to choose when writing your tests. This makes for a much better developer experience and ensures you have resilient locators whether you are new to testing or not.

And of course if the test generator generates a locator that you are not happy with then it might be worth investigating the DOM to see if you can improve your code to be more accessible, and in that way the test generator can generate more accessible locators. This gives you better tests and improved code at the same time.

I encourage you to give the test generator a try either using theVS Code extension or opening it from the terminal withnpx playwright codegen. Happy testing.

Top comments(3)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
haikyuu_js profile image
Abdellah Alaoui
Head of the ideas department at Scrimba. Thrives in unexplored lands ... Imba & EdgeDB
  • Joined

Great post. I always thought the locators API was restrictive.

But it turned out I didn't know much about accessibility. Now I can use locators to write better tests and at the same time improve accessibility of our web app.

CollapseExpand
 
afzalyusuf413 profile image
AfzalYusuf413
  • Joined

I'm new to playwright. When I use the GetByRole locator method, I get the following error " 'IPage' does not contain a definition for 'GetByRole' and no accessible extension method 'GetByRole' accepting a first argument of type 'IPage' could be found (are you missing a using directive or an assembly reference?)CS1061"

Please help me solve this as I really want to use the GetBy methods to identify locators

Thanks!!

CollapseExpand
 
nrcvs profile image
nr
  • Joined

Hello, I tried await page.getByRole('link').click() and all other options but still giving Error: locator.clie. Test timeout of xxxxxms exceeded. waiting for getByRole...

can someone please help here?

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Reliable end-to-end testing for modern web apps

Get started by installing Playwright using npm, yarn or pnpm. Alternatively you can also get started and run your tests using the VS Code Extension.

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp