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:

Processing
    Retry
  
  
    COMPLETED
    View
  
  
    Pending
    Retry

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 elements in the table.
  • Then, it filters the rows that contain the text COMPLETED.
  • Finally, it finds the 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