Enhancing Playwright Test Automation with Regular Expressions
Regular expressions were formalized in the 1950s by mathematician Stephen Cole Kleene. The concept was later adopted into text processing tools. In the 1970s, Unix tools like grep
, sed
, and awk
Popularized the use of regular expressions in scripting and automation.
Playwright supports the use of grep in the Test Runner and Command Line. Test Runner grep is used to filter and only run tests with a title matching one of the patterns via testConfig.grep and testProject.grep. It is also available globally and in the command line with the -g
Option. Using the regular expression can filter the test string containing the project name, file name, and the test.describe()
Titles. The test titles and all test tags are separated by spaces when passing through the command line. The filter does not apply to tests from dependency projects. The opposite of --grep
is also available; --grep-invert
We will only run tests that do not match this regular expression.
Playwrights use regular expressions for locators, assertions, Test Runner, Command Line, and various Classes. This post will only include regular expression usage in locators, specifically for Locating elements and Filtering Locators.
const locator = page.locator("div").filter({ hasText: /Submit/ });
// Matches elements containing "Submit"
The most straightforward usage occurs when regular expressions match elements containing exact text patterns.
const locator = page.getByRole("button").filter({ hasText: /Log (in|out)/ });
// Matches "Log in" or "Log out" buttons
The first level of flavour in regular expressions allows for handling variations in the text to match.
const locator = page.locator("p").filter({ hasText: /\d{3}-\d{3}-\d{4}/ });
// Matches phone numbers (XXX-XXX-XXXX)
Use character classes (e.g., \d for digits, \w for word characters) and quantifiers (e.g., + for one or more occurrences) for complex matching.
const destination = "YourDestination"; // Your dynamic destination name
const regex = new RegExp(`^Looking for flights to ${destination} Airport?$`);
const locator = await page.locator("div").filter({ hasText: regex }).nth(1);
await locator.waitFor();
We can dynamically match an element containing exact text patterns. This involves creating a regular expression dynamically using template literals and locating the element using the regex pattern. Thus, we can combine regular expressions with template literals to insert variables into the pattern dynamically.
const destination = "YourDestination";
const destAvailPill = (destination: string) =>
page.locator('li').filter({ hasText: new RegExp(destination) }).getByTestId('avail-pill');
await destAvailPill(destination).textContent();
/[^a-zA-Z0-9 ]/g
This regular expression defines the pattern of characters to be replaced. Let’s break it down:
[]
: This defines a character class, specifying a set of characters to match.^
: The caret symbol (^
) negates the characters within the class. It means we want to match characters outside the following set.a-zA-Z
: This matches any lowercase letter (a-z) or uppercase letter (A-Z).0-9
: This matches any digit from 0 to 9.- : This matches a single-space character.
/
: These forward slashes mark the beginning and end of the regular expression.- The
g
flag at the end signifies a global search. It replaces all occurrences of the matched pattern in the string, not just the first one.
/\\s+/
This regular expression defines the pattern of special characters to be replaced. Let’s break it down:
\\s
: This is a special character class that matches any whitespace character. Whitespace characters include spaces, tabs, newlines, carriage returns, and other invisible characters that create space between visible characters.+
: The plus sign (+
) is a quantifier indicating the preceding element can be matched one or more times.*
: This symbol matches zero or more occurrences of the preceding element, similar to+
, but it also allows zero matches.?
: This symbol matches zero or one occurrence of the preceding element./\\s{2}/
matches exactly two whitespace characters (spaces, tabs, newlines)./\\d{3}/
matches exactly three digits (0-9)./ab{4}c/
matches "abc" followed by exactly four occurrences of "b" and then "c".
Regular expressions, while concise, can become complicated. It’s recommended to start with simple patterns and gradually increase their complexity as necessary. Online regex testers such as https://regex101.com/ can be used to experiment with and validate your patterns before incorporating them into the code. By effectively using regular expressions and adhering to best practices, you can enhance the precision and flexibility of your Playwright scripts for element interaction.
My recent publication compiled a comprehensive collection of 100 similar typescript programs. Each program not only elucidates essential Typescript concepts and expounds upon the significance of test automation but also provides practical guidance on its implementation using Playwright. This resource will undoubtedly be valuable if you look deeper into similar topics.