One of the biggest issues developers face when testing websites is finding the right elements to interact with. Locators fix this by automatically waiting for elements to be ready before interacting with them for you. Whether you’re clicking a button, filling out a form, or checking if a message appears, locators provide a reliable way to point to the exact element on the page. In Playwright especially, locators automatically wait for elements to be ready and provide a host of strategies to locate them, reducing flaky tests and making automation more seamless.
In this tutorial, we’ll go over what locators are and why they matter. We'll focus on Playwright, a leading testing solution, discussing how to use locators in Playwright and the best practices for reliable tests.
At the end of this article, you should have a solid understanding of Playwright locators and how to use them effectively in your test automation. Let’s dive in!
Whether you’re clicking a button, filling out a form, or checking if a message appears, locators provide a reliable way to point to the exact element on the page.
What Are Locators and How Do We Use Them?
Locators are tools used to find, or locate, web elements such as buttons, text boxes, or links. To do this, they may identify attributes of the targeted elements by assessing their position in the Document Object Model (DOM), such as their name or a unique link contained in them. This allows locators to seamlessly interact with the elements.
There are several types of locators. Playwright allows you to find elements based on their role, text content, title ID, or several other criteria. Playwright also supports CSS locators, which allow you to identify web elements based on CSS selectors. For example, you can locate a button with the ID "submit" using page.locator('button#submit'). This approach is fast and widely used among developers.
Another useful option is text-based locators, which let you find elements based on their visible text content. If you need to locate a button labeled Sign In, you can simply use page.locator('text=Sign In'), making the test easier to understand.
For better accessibility, Playwright supports role-based locators, which find elements based on their ARIA roles. This is particularly helpful for testing applications that need to be accessible to all users. For example, to select a checkbox labeled Accept Terms, you can use page.locator('role=checkbox[name="Accept Terms"]').
If you’re working with a complex HTML structure, XPath locators might be a good choice. Although they’re not as readable as CSS selectors, they can be powerful for navigating deeply nested elements. You can find an input field using page.locator('//input[@type="text"]'), but use this sparingly as XPath expressions can become difficult to maintain. Playwright locators should be the first and foremost method of locating elements.
Choosing the right locator type can make your tests more stable and maintainable, leading to more efficient automation.
You could also use attribute-based locators, which rely on custom attributes such as data-test-id. This is particularly useful when elements don’t have unique IDs or classes. For instance, you can locate a login button with page.locator('[data-test-id="login-button"]').
When dealing with nested elements, chained locators help you narrow down your selection. If you need to find a submit button inside a form, you can use page.locator('form').locator('button[type="submit"]'), ensuring that the test only interacts with the correct button.
Each type of locator has its strengths. CSS selectors work well for general cases, text locators are great for buttons and links, and role-based locators enhance accessibility. Only use XPath when necessary. Chained locators help with structured elements. Choosing the right locator type can make your tests more stable and maintainable, leading to more efficient automation.
How to Use Playwright Locators
Now let's talk about using Playwright locators. As explained in their developer guides, Playwright allows you to locate elements through various attributes. In this tutorial, we'll walk through the steps to locate an element by text. Playwright’s guide breaks down the process of using text locators:
Imagine a string of text that reads “Welcome, John”.
To find this element by its exact text, you may use page.get_by_text("Welcome, John")
You may also search for partial matches using page.get_by_text("Welcome") to find any element including the word “welcome” or page.get_by_text("John") to locate any element that contains the text “John”.
Playwright also allows you to use CSS selectors with the locator() method. For example, you could locate a button with the class .submit-button as follows:
const button = page.locator('.submit-button');
If the button is inside a specific container, you could use:
const button = page.locator('form button');
Normally, CSS selectors have limited functionality, making users unable to locate elements by attributes such as the text. However, Playwright-specific CSS extensions circumvent this, allowing you to select elements based on text content or hierarchy.
Using CSS selectors in Playwright, you could locate a button with the text “Submit” as follows:
const button = page.locator('button:has-text("Submit")');
Playwright Locator Best Practices
How to Optimize Locator Performance
Efficient locators are essential for improving the speed and reliability of Playwright tests. Poorly chosen locators can slow down execution and lead to flakiness, making tests harder to maintain. To optimize performance, selecting the right locator strategy is crucial.
In Playwright, one of the most effective ways to improve performance is by leveraging Playwright’s role-based and text locators. These locators, such as getByRole() and getByText(), are optimized for both performance and accessibility. They provide a more intuitive way to select elements while reducing the need for complex queries. Similarly, using .nth() when dealing with multiple matching elements allows Playwright to focus on a specific instance rather than evaluating all matches.
Playwright’s built-in waiting mechanisms should also be utilized to avoid unnecessary waitFor() calls. Since Playwright automatically waits for elements to be ready before interacting with them, excessive manual waiting can slow down tests without adding value. Furthermore, chaining locators for nested elements improves both readability and efficiency. Instead of writing long XPath queries, breaking them down into smaller, structured locators enhances maintainability.
Poorly chosen locators can slow down execution and lead to flakiness, making tests harder to maintain.
Common Challenges with Locators
For all their advantages, working with locators in Playwright can sometimes be challenging, especially when dealing with dynamic elements, multiple matching elements, or unstable selectors. However, these issues can be addressed with the right strategies.
One common challenge is handling dynamic elements that change their attributes or positions. Instead of relying on unstable selectors, using stable attributes like data-test-id or text-based locators can improve reliability. For example, page.getByText("Submit") is more stable than selecting by a dynamic class name.
Slow-loading elements can also cause test failures. Instead of using explicit waits, leveraging Playwright’s built-in waiting mechanisms, such as waitFor(), ensures elements are ready before interaction.
Tests may also fail due to elements not being fully loaded before interaction. While Playwright automatically waits for elements, sometimes additional conditions are needed. Using .waitFor() or assertions like toBeVisible() can help ensure an element is ready before proceeding.
The right locator strategies allow you to handle common challenges and optimize page performance so that your script can run efficiently across dynamic web applications.
Conclusion
Locators can be invaluable tools when designing a web page or app. Mastering them allows you to test web pages efficiently. The right locator strategies allow you to handle common challenges and optimize page performance so that your script can run efficiently across dynamic web applications. However, maintaining and scaling automated tests can still be time-consuming.
Autify Nexus, a low-code AI-powered test automation platform, further streamlines this process by eliminating the need for complex locator code. So whether you're a single developer looking to save time on your page testing, or a large team looking to ensure that your page runs smoothly, consider Autify to enhance your development process.