QA Graphic

Filtering Locators by Text Content in Playwright with TypeScript

How I used Playwright's locator filtering to extract data

Introduction

Automating web testing often involves interacting with elements that lack unique identifiers like IDs or classes. In such cases, Playwright's powerful locator filtering capabilities can save the day. In this post, we'll explore how to filter locators by text content in TypeScript, using a real-world example from the American Freight Refrigerators & Freezers page.

Our goal is to capture the number of items displayed on the page, where the text (e.g., "Showing 24 results") is not tied to a unique ID. We'll use Playwright's text-based filtering and parse the result to extract the number.

The Challenge

On the American Freight page, the text indicating the number of results is displayed dynamically, something like:

Showing 24 results

The element containing this text doesn't have a unique ID or class, making it tricky to locate directly. A naive approach might grab multiple elements with similar text, leading to incorrect results. Playwright's locator filtering allows us to narrow down the search by combining text matching with additional conditions.

Refrigerators
Screenshot of the page that I am testing.

Solution: Playwright Locator Filtering

Playwright provides the getByText method to locate elements by their text content. We can further refine this using the filter method to ensure we target the exact element. Here's how it works:

  1. Use page.getByText('Showing', { exact: false }) to find elements containing the word "Showing".
  2. Apply filter({ hasText: 'results' }) to narrow down to elements that also contain "results".
  3. Extract the text content and parse it to get the number using a regular expression.

Below is the complete TypeScript code for the test:

import { test, expect } from '@playwright/test';
test('American Freight Refrigerator Numbers', async ({ page }) => {
  await page.goto('https://www.americanfreight.com/plp/appliances/refrigerators-freezers/695');
  // Locate element with text starting with "Showing" and containing "results"
  const locator = page.getByText('Showing', { exact: false });
  const element = locator.filter({ hasText: 'results' });
  const text = await element.innerText();   
  const match = text.match(/Showing (d+) results/);
  const resultsNumber = match ? match[1] : null;
  
  console.log(`Number of results: ${resultsNumber}`);
  expect(resultsNumber).not.toBeNull();
});

Code Breakdown

Let's dissect the key parts of the code:

  • Navigating to the Page: await page.goto(...) loads the American Freight page.
  • Locating by Text: page.getByText('Showing', { exact: false }) finds all elements containing "Showing". The exact: false option allows partial matches.
  • Filtering: locator.filter({ hasText: 'results' }) refines the locator to only include elements that also contain "results".
  • Extracting Text: await element.innerText() retrieves the full text content (e.g., "Showing 24 results").
  • Parsing the Number: The regex /Showing (d+) results/ captures the number between "Showing" and "results". The result is stored in resultsNumber.

Why Use Locator Filtering?

Locator filtering is a game-changer for several reasons:

  • Precision: It allows you to target elements based on multiple conditions, reducing false positives.
  • Flexibility: You can combine text, attributes, or even child elements in the filter.
  • Robustness: It handles dynamic content where IDs or classes may change.

In our example, filtering ensured we got the exact element with "Showing" and "results", avoiding other elements with similar text.

Tips for Success

  • Inspect the Page: Use browser DevTools to confirm the text content and structure before writing your locator.
  • Test Your Locator: Use Playwright's locator.count() or locator.all() to verify how many elements match your criteria.
  • Handle Edge Cases: Add checks for null or unexpected text formats, as we did with the regex match.
  • Debugging: Log the innerText or use Playwright's tracing to inspect the locator's behavior.

Conclusion

Playwright's locator filtering by text content is a powerful tool for tackling elements without unique identifiers. By combining getByText and filter, we successfully extracted the number of refrigerators from the American Freight page. This approach is versatile and can be adapted to many scenarios in web automation.

Try it out in your next Playwright project, and explore other filtering options like has or hasNotText to handle even more complex cases!

 

Comments

Add Your Comments

Name:
Comment:

 

About

Welcome to Playwright Tips and Tricks, your go-to resource for mastering the art of web automation and testing with Playwright! Whether you're a seasoned developer looking to streamline your workflows or a curious beginner eager to dive into the world of browser automation, this blog is designed with you in mind. Here, I'll share a treasure trove of practical insights, clever hacks, and step-by-step guides to help you harness the full power of Playwright - a modern, open-source tool that's revolutionizing how we interact with web applications.

Schedule

Wednesday 18 Pytest
Thursday 19 PlayWright
Friday 20 Macintosh
Saturday 21 Internet Tools
Sunday 22 Misc
Monday 23 Media
Tuesday 24 QA