What are Playwright Locators and Selectors?
Playwright is a Swiss Army knife for browser automation, and nearly all of Playwright's expansive functionality is based on two core tools: selectors and locators. They're essential for anyone serious about working with Playwright, and they're the focus of this article.
In the following post, we'll cover what they are, why they matter, and how to use them effectively. Once you understand the basics, visit my deep dive on strengthening your Playwright locators. It's a great resource for truly mastering these tools.
Let's get started!
What are Playwright Selectors?
Playwright selectors are search queries used to match elements within the page's DOM. They leverage various strategies such as CSS, XPath, textual content, pseudo-selectors, and even custom properties you define. Selectors are strings, and they are the foundation of Playwright's locators, though they don't enable interaction by themselves.
Here are some examples:
// create a locator using css
const $buttonByCSS = page.locator('css=button');
// create a locator using xpath
const $buttonByXPath = page.locator('xpath=//button');
// create a locator using psuedo-selectors
const $buttonByRole = page.getByRole('button');
Playwright also allows the registration of custom selectors, leveraging any logic you can dream up. At first blush, this might seem like overkill, but as code matures and you develop domain logic, custom selectors can dramatically simplify your code.
Here's a brief taste:
// target elements currently within a particular shadow DOM
await selectors.register('shadow', createShadowSelector);
// query all options within a custom select web component
const $options = page.locator('shadow=x-custom-select option');
await $options.count();
We'll return to this technique later with a complete example.
What are Playwright Locators?
Locators are a powerful abstraction built on top of selectors. They provide a clean interface for selecting elements, interacting with them, and traversing the DOM subtree within them. You use them constantly in Playwright.
As an improvement over the now-deprecated $()
API, they also come with some unique advantages. First, they are always up-to-date. A selector that targets a list of elements will always select the full list, no matter how many items have been added, removed, or changed.
And second, locators will wait until the selector pattern finds a match on the page. This is incredibly useful when working with dynamic content, as you no longer have to build arbitrary or complex timeout logic into your scripts.
We'll cover locators in great detail later, but here's a quick sample:
// find the button with `name="submit"`
const $submitButton = page.getByRole('button', {name: 'submit'});
// or...
const $submitButton = page.locator('role=button', {name: 'submit'});
// click it!
await $submitButton.click();
Locators can also be chained to increase specificity without having to resort to long selector queries. Example:
const $taskList = page.locator('ul#tasks');
const $taskLinks = $taskList.locator('a');
const $completedTasks = $taskLinks.filter({
has: page.locator('input[type="checkbox"]:checked'),
});
Next steps
By now, you should have a solid understanding of Playwright locators and selectors. To dive deeper, make sure you check out my everything guide to strengthening your Playwright locators.
Happy automating!