When writing automated tests with Playwright, selecting elements efficiently is crucial to ensure reliable and maintainable test scripts. A common scenario is selecting an element that contains specific text inside a table. Playwright provides two approaches for this:
- .filter({ hasText: 'TEXT' }) - filters elements that contain the specified text.
- .locator('text=TEXT') - finds elements that match the exact text.
Both methods can be useful, but understanding their differences will help you write more robust selectors. Let’s dive into a practical example.
Example Scenario: Selecting a Button in a Table Row
Imagine you have the following table:
<table>
<tr>
<td>Processing</td>
<td><button>Retry</button></td>
</tr>
<tr>
<td>COMPLETED</td>
<td><button>View</button></td>
</tr>
<tr>
<td>Pending</td>
<td><button>Retry</button></td>
</tr>
</table>
You want to select the View button that belongs to the row where the status is COMPLETED.
Using .filter({ hasText })
await expect(
page.locator('tr')
.filter({hasText:'COMPLETED'})
.locator('button'))
.toHaveText('View')
✅ Why is this approach better?
- It first selects all
<tr>
elements in the table. - Then, it filters the rows that contain the text COMPLETED.
- Finally, it finds the
<button>
inside the filtered row
Using .locator('text=')
await expect(
page.locator('tr')
.locator('text=COMPLETED')
.locator('button'))
.toHaveText('View');
❌ What’s the issue here?
- .locator('text=COMPLETED') tries to find any element containing COMPLETED, even if it’s deep inside another nested element.
- It may return unexpected results if there are multiple matching elements inside different rows.
- The search is not restricted to the row (tr) but instead looks for any match in the selected context.
🔥 Key Takeaways
Approach | Behavior | Best Use Case |
---|---|---|
.filter({ hasText: 'TEXT' }) |
Filters elements that contain the specified text | Selecting elements within a parent scope (e.g., table rows) |
.locator('text=TEXT') |
Locates any element that exactly matches the text | Quick selection when structure is simple |
✅ When to Use .filter({ hasText })?
- When dealing with structured elements (tables, lists, div containers, etc.).
- When the text is part of a larger element (like a row containing multiple elements).
- When you need precision and don’t want to match unintended elements.
⚠️ When .locator('text=') Can Cause Issues?
- If the text appears multiple times on the page, you may get unexpected matches.
- If the element you’re targeting is deeply nested, Playwright may not find it reliably.
- It doesn’t work well when the text is inside an element with other dynamic content.
🚀 So
If you’re working with structured elements like tables or lists, prefer using .filter({ hasText }). It ensures you only interact with elements that are within the expected scope.
Use .locator('text=') carefully, as it may return unexpected elements depending on the page structure.
Follow me on Instagran and Linkedin
See more in TheCollege
Top comments (0)