- Understanding Playwright Locators
- Types of Playwright Selectors
- Best Practices for Using Playwright Selectors
- 1. Prefer User-facing Attributes
- 2. Use Data Attributes for Stability
- 3. Avoid Brittle Selectors
- 4. Use CSS and Text Selectors
- 5. Utilize Playwright's Auto-wait Features
- 6. Combine Selectors for Precision
- 7. Regular Expressions for Flexible Text Matching
- 8. Test Accessibility with Role Selectors
- 9. Keep Selectors Short and Readable
- 10. Review and Refactor Selectors Regularly
- Creating Locators
- Selector Strategies
- Locator Actions
- Working with Multiple Elements
- Playwright Chain Locators and Multiple Locators
- FAQ - Playwright Selector and Locators
Playwright Locators are designed to locate HTML elements on a web page with precision and flexibility, offering a robust solution to the challenges of dynamic web applications. They are the central piece in the puzzle of web automation, enabling testers to specify locators using various strategies, such as CSS selectors, XPath expressions, text content, and custom attributes like test IDs. These locators are adept at handling multiple elements, matching elements by text, and even locating elements that contain or do not contain specified text somewhere inside, showcasing their versatility.
Check also our Playwright Cheat Sheet for more selectors and more.
Understanding Playwright Locators
One of the standout features of Playwright Locators is their auto-waiting and retry-ability, ensuring that actions on elements proceed only when conditions are right, thus mitigating the risks of flaky tests. They always normalize whitespace in text matches, enhancing the accuracy and reliability of tests that involve text verification. Moreover, Playwright allows for the use of regular expressions and filters by text, providing a fine-grained control over element selection that is unmatched by traditional testing tools.
The concept of chaining or using two locators together to pinpoint the exact element or list of elements adds another layer of precision. This approach, where a locator must be relative, allows for the construction of complex queries that can navigate the nested structures of modern web applications with ease. Furthermore, the built-in locators and the capability to create custom locators using the Playwright Inspector tool underline the flexibility and power that Playwright brings to the table.
Types of Playwright Selectors
Playwright supports a variety of selector engines, allowing for flexible and powerful element selection strategies. The main types include:
CSS Selectors
CSS selectors in Playwright are a cornerstone for selecting elements in the browser efficiently and effectively. They leverage standard CSS syntax to target elements based on their tag name, class, ID, attributes, and relationships within the DOM.
Types of CSS Selectors:
-
Type Selectors: Target elements by their tag name, e.g.,
div
,a
. -
Class Selectors: Use a period
.
followed by the class name, e.g.,.btn-primary
. -
ID Selectors: Use a hash
#
followed by the ID value, e.g.,#submit-button
. -
Attribute Selectors: Use square brackets to specify an element with a certain attribute, e.g.,
[type='checkbox']
. -
Pseudo-classes and Pseudo-elements: Use pseudo-classes (
:hover
,:nth-child(n)
) and pseudo-elements (::before
,::after
) for state-based and structural targeting. -
Combinators: Use combinators like
>
,+
,~
to define relationships between elements, e.g.,div > .item
selects elements with classitem
that are direct children of adiv
.
To use a CSS selector in Playwright, you pass the CSS string directly into the page.locator
or page.$
methods. For example:
// Selecting an element by tag name const heading = page.locator('h1');
// Selecting elements by class name const buttons = page.locator('.button');
// Selecting an element by ID const navbar = page.locator('#navbar'); // Selecting elements by attribute const input = page.locator('input[type="text"]');
Combining Selectors:
CSS selectors can be combined to create more specific queries. For example, to select a button within a specific section:
const loginButton = page.locator('#login-section .login-button');
This selects elements with the class login-button
within the element with the ID login-section
.
Pseudo-classes and Pseudo-elements:
Playwright supports CSS pseudo-classes and pseudo-elements, allowing for even more precise element selection:
// Selecting the first child of an element const firstItem = page.locator('ul > li:first-child');
// Selecting elements on hover state (pseudo-classes) const hoverButton = page.locator('button:hover');
Text Selectors
In Playwright, matching by text is a fundamental technique that enables precise targeting of elements based on their visible text content. This approach is especially useful for interacting with elements like buttons, links, and labels where the text content is a significant identifier.
- Target elements based on their visible text.
- Syntax:
text="button text"
for exact matches, ortext=/regex/
for regular expression matches. - Particularly useful for selecting links, buttons, or other elements where the visible text is a clear identifier.
ID Selectors
In Playwright, ID selectors are a straightforward and efficient way to target elements based on their unique id
attribute. Given that id
attributes are intended to be unique within an HTML document, using ID selectors can lead to very precise element selection, making them a reliable choice for identifying specific elements on a page.
To use an ID selector in Playwright, you can simply prefix the ID value with a hash (#
) symbol, similar to CSS. However, Playwright also provides a dedicated id=
selector engine that can be used explicitly. Here are both ways to target an element by its ID:
// Using the CSS-like syntax const element = page.locator('#elementId');
// Using the dedicated ID selector engine const sameElement = page.locator('id=elementId');
Both lines above will target an element with the id
attribute of elementId
.
XPath Selectors
XPath selectors in Playwright provide a powerful and flexible way to select elements based on their structure and content within the HTML document. XPath, or XML Path Language, allows you to navigate the DOM tree using paths, offering features that go beyond the capabilities of CSS selectors. This includes selecting elements based on their text content, attributes, hierarchy, and more complex criteria.
- Use XPath expressions to select elements based on their hierarchical position in the DOM or specific attributes.
- Syntax:
xpath=//button[@name='submit']
selectsbutton
elements with aname
attribute equal tosubmit
. - Provides a powerful way to navigate complex DOM structures or select elements based on sibling or ancestor relationships.
Check also our Ultimate Guide to Selectors: XPath vs CSS selectors.
Data Attribute Selectors
In Playwright, data attribute selectors provide a robust way to target elements based on custom data attributes. These attributes, often prefixed with data-
, are used for providing additional information about HTML elements without interfering with their styling or behavior. Utilizing data attributes for selectors in automated testing is a highly recommended practice because it creates a clear separation between elements designated for testing and those used for styling (classes) or identification (IDs) purposes, thus enhancing test stability and maintainability.
To use data attribute selectors in Playwright, you directly utilize the attribute in your locator string. Here are some examples demonstrating how to select elements by their data attributes:
// Targeting an element with a specific data attribute and value const element = page.locator('[data-test-id="unique-element"]');
// Using a data attribute to find a button within a specific component const button = page.locator('.component-class [data-action="save"]');
In these examples, data-test-id
and data-action
are custom attributes used to uniquely identify elements within the page.
- Target elements by custom data attributes, which are often used specifically for testing purposes.
- Syntax:
data-test-id=my-element
or[data-test-id="my-element"]
selects elements with adata-test-id
attribute equal tomy-element
. - Helps maintain stable tests by separating testing identifiers from CSS classes and IDs used for styling.
Role Selectors
Playwright's role selectors provide a powerful and semantic way to target elements based on their Accessible Rich Internet Applications (ARIA) role, enhancing the accessibility testing capabilities within your automated testing suite. Role selectors make it easier to ensure that web applications are accessible and functional for users with disabilities, by allowing tests to interact with elements in a way that mirrors how assistive technologies interpret and interact with web content.
To use a role selector in Playwright, you specify the role
followed by the role name you are targeting. The syntax looks like this:
const button = page.locator('role=button');
This example targets all elements with an ARIA role of button
.
Component Selectors (React, Vue, etc.)
- Target elements based on their framework-specific component names. This requires using Playwright's framework-specific selectors plugin.
- Syntax:
react=MyComponent
orvue=MyComponent
to select elements corresponding to a specific React or Vue component. - Enables testing that is more closely tied to the application's architectural components.
Best Practices for Using Playwright Selectors
1. Prefer User-facing Attributes
- Use locator that mimic user interactions, such as text content or labels, over technical attributes like classes or IDs that may change more frequently.
- Use attributes that are meaningful to the application's users, such as
role
attributes for accessibility, which tend to be more stable.
2. Use Data Attributes for Stability
- Implement custom data attributes (e.g.,
data-testid
,data-cy
) in your application specifically for testing purposes. These attributes provide a stable way to select elements without relying on CSS classes or IDs that might change due to styling updates.
3. Avoid Brittle Selectors
- Avoid using selectors that are highly dependent on the page structure or that use indexed positions, as these can easily break with UI changes.
- CSS selectors should be concise and not overly specific to avoid breakage from minor changes in the DOM structure.
4. Use CSS and Text Selectors
- CSS selectors are powerful for selecting elements based on their class, ID, or other attributes. They are a good balance between simplicity and specificity.
- Text selectors are invaluable for interacting with elements in a way that mirrors user behavior, such as clicking buttons or links labeled with specific text.
5. Utilize Playwright's Auto-wait Features
- Playwright automatically waits for elements to be actionable before interacting with them. Ensure your selectors take advantage of this feature to reduce flakiness and the need for explicit waits.
6. Combine Selectors for Precision
- When necessary, combine selectors to refine element targeting. For example, use a combination of CSS and text selectors to identify an element within a specific section of a page.
- Playwright's
>>
syntax allows chaining selectors, enhancing specificity without increasing brittleness.
7. Regular Expressions for Flexible Text Matching
- Use regular expressions with text selectors when you need to match elements based on patterns rather than fixed strings. This is particularly useful for dynamic content that follows a predictable format.
8. Test Accessibility with Role Selectors
- Utilize role selectors to ensure that your application is accessible. Selecting elements by their ARIA role can help validate that important elements are present and correctly labeled for screen readers.
9. Keep Selectors Short and Readable
- While specificity is important, overly complex selectors can be hard to read and maintain. Aim for a balance between specificity and readability.
10. Review and Refactor Selectors Regularly
- As your application evolves, so too should your selectors. Regularly review and update selectors to ensure they remain effective and reflect any changes in the application's UI.
Creating Locators
To create a locator in Playwright, you use the page.locator()
method, passing in a string that specifies the selection criteria. Playwright supports a wide range of selector engines, including CSS, text, XPath, and others, allowing you to craft locators that can match elements in almost any scenario:
// CSS selector const button = page.locator('button.submit');
// Text selector const welcomeMessage = page.locator('text="Welcome, User"');
// XPath selector const checkbox = page.locator('//input[@type="checkbox"]');
Selector Strategies
Playwright supports multiple strategies for selecting elements, including:
-
CSS Selectors: For selecting elements based on their CSS properties.
const button = page.locator('button.submit');
-
XPath: For selecting elements with XPath expressions.
const listItem = page.locator('//ul/li[3]');
-
Text Selectors: For selecting elements based on their text content.
const heading = page.locator('text="Welcome to Our Site"');
-
ID Selectors: For selecting elements by their ID.
const passwordField = page.locator('#password');
-
Composite Selectors: Combining multiple strategies for more precise targeting.
const loginButton = page.locator('text="Login" >> css=button');
Locator Actions
Once you have defined a locator, you can perform various actions on the targeted element(s), such as:
- Clicking:
await locator.click();
- Filling Text:
await locator.fill('text');
- Getting Text:
const text = await locator.textContent();
- Asserting Visibility:
await expect(locator).toBeVisible();
Working with Multiple Elements
Playwright locators can also handle multiple elements. For instance, to count elements matching a selector:
const itemCount = await page.locator('ul > li').count();
To iterate over multiple elements:
const items = page.locator('ul > li'); const count = await items.count(); for (let i = 0; i < count; ++i) { console.log(await items.nth(i).textContent()); }
Playwright Chain Locators and Multiple Locators
Chaining locators in Playwright refers to the process of creating a locator that is based on the context of another locator. This is particularly useful when you need to perform actions on elements that are within a specific part of the page or are related to other elements in some way.
You can chain locators using the locator
method on an existing locator object, allowing you to refine your selection based on a relative context. This approach enables you to create precise and resilient selectors that can navigate complex page structures.
Example of Chaining Locators:
const parentLocator = page.locator('div.parent'); const childLocator = parentLocator.locator('div.child'); await childLocator.click();
In this example, childLocator
is a locator that specifically targets div.child
elements that are descendants of div.parent
elements. This allows for precise targeting of elements within a specific context.
In summary, Playwright's locators and selector engines offer a powerful and flexible way to interact with web elements, supporting a wide range of scenarios from simple element selection to complex, dynamic interactions. Chaining locators further enhance this by allowing for context-specific element selection, making it easier to write stable and reliable tests.
Conclusion
In conclusion, locators are the central piece of the puzzle when it comes to efficiently interacting with web pages using Playwright. With the ability to precisely pinpoint the exact element on the page, regardless of the many HTML elements present, locators provide a versatile and powerful way to locate elements based on a myriad of criteria, from the text it contains to specific attributes. Playwright comes equipped with a rich suite of locator strategies, including the widely recommended locators such as role, text, CSS selectors, and XPath. These locators can be filtered to match the locator to elements that do or do not contain certain criteria, enhancing the flexibility and precision in testing scenarios.
The difference between locators and selectors is nuanced yet significant. While a selector describes how to find elements on a web page, a locator goes a step further by encapsulating this logic to interact with those elements directly. This distinction is vital as the element locator resolves the given locator and ensures the matching of the locator with the element corresponding to the locator is as intended, even as the state of elements changes over time. Furthermore, the introduction of locator and FrameLocator classes in Playwright underscores the framework's commitment to providing robust tools for testers to locate and interact with elements efficiently.
Whether you're dealing with dynamic content, elements that load asynchronously, or elements based on their accessibility attributes, Playwright's locators ensure you can interact with specific elements on the web page without a hitch. From simple tasks like clicking a button to more complex interactions within nested frames, the right locator will be used to ensure seamless automation. With locators such as role, text, CSS, and XPath in Playwright, testers have at their disposal highly effective ways to locate elements in web pages, marking a clear evolution in how automated testing is approached. Thus, understanding and leveraging the difference between locators and selectors, along with the sophisticated locator and FrameLocator classes, empowers developers and testers alike to create more reliable, maintainable, and efficient test suites for web applications.
FAQ - Playwright Selector and Locators
What are Locators in Playwright?
Locators in Playwright represent a way to interact with elements on a web page. Unlike a direct reference to an element (like an ElementHandle), a Locator is an abstraction that allows Playwright to efficiently re-query the element in the DOM whenever an action is performed. This means that even if the page changes or the element is dynamically loaded or reloaded, Playwright can still interact with the element using the locator.
Can I Use XPath with Playwright?
Yes, you can use XPath with Playwright. Playwright supports a wide range of selector engines for identifying elements, and XPath is one of them. XPath selectors allow you to navigate through elements and attributes in an XML document. In the context of Playwright, XPath can be used to locate web elements based on their XML path in the HTML document.
What are the Playwright Selector Options?
Playwright supports multiple selector engines, enabling various strategies for selecting elements. Some of the selector options include:
- CSS: Standard CSS selectors to select elements based on their class, ID, attributes, etc.
- XPath: An expression language that allows for the navigation of XML documents to select nodes or node-sets.
- Text: Allows selection of elements based on their text content.
- ID: Shortcut for selecting elements based on their ID attribute.
- Data-testid: A common pattern for selecting elements using a specific attribute often used for testing.
These selectors can be combined and used together to create powerful and precise locators for any element on a page.
What is the Difference Between Locator and Element Handle in Playwright?
The primary difference between a Locator and an ElementHandle in Playwright lies in how they reference and interact with elements on a web page:
-
Locator: Represents a query that can be used to find an element or elements every time an action is performed. It is stateless and re-evaluates the query on the DOM whenever it is accessed. This makes locators particularly useful for dealing with dynamic content that might change or be loaded asynchronously.
-
ElementHandle: Represents a reference to an actual DOM element. ElementHandles are stateful, meaning they hold a direct reference to a particular element. If the element they reference is removed from the DOM, the handle becomes useless. ElementHandles are useful when you need to perform multiple operations on the same element and are sure that the element won't be recreated or removed.
Check also Top Playwright Alternatives.