How to Manage Locators and Selectors in Playwright

AnandkumarAnandkumar
4 min read

🎭 Master the art of web automation with Playwright, one locator at a time!

Locators and selectors are crucial when automating web interactions using Playwright. They help identify and interact with elements on a webpage. In this blog, I'll guide you through various types of locators Playwright supports and how to use them effectively to write stable, reliable tests.


🎯 1. The Basics of Locators

In Playwright, locators are powerful enough to identify web elements uniquely. They are used to perform actions like clicking, typing, and retrieving element attributes. Playwright offers an intuitive API for finding elements on a page using various strategies.

const locator = page.locator('selector');
await locator.click();

πŸ” 2. CSS Selectors

CSS selectors are one of the most common ways to target elements in Playwright. You can use class names, IDs, or any valid CSS selector to locate elements.

Example:

// By ID
await page.locator('#submit-button').click();

// By class
await page.locator('.login-input').fill('username');

// By attribute
await page.locator('input[type="password"]').fill('my-password');

πŸ’‘ Pro Tip: Use nth() method if you need to interact with a specific instance of a repeated element.

// Selecting the second item in a list
await page.locator('.item-class').nth(1).click();

πŸ–±οΈ 3. Text-Based Selectors

Playwright allows selecting elements based on their text content. This is useful when you want to select an element that has unique visible text.

Example:

// Clicking on a button by text
await page.locator('text=Submit').click();

πŸ’‘ Pro Tip: You can use exact=true to match the exact text content.

// Exact match
await page.locator('text="Submit"', { exact: true }).click();

πŸ”— 4. XPath Selectors

XPath is another robust method to locate elements, especially when dealing with complex or dynamically generated HTML structures. Playwright supports XPath selectors with the prefix //.

Example:

// Clicking a button using XPath
await page.locator('//button[text()="Submit"]').click();

πŸ’‘ Pro Tip: Use XPath selectors carefully as they tend to be brittle with changing page structures.


πŸ› οΈ 5. Combining Locators

Sometimes, a single selector isn’t enough. Playwright allows you to combine multiple selectors for more precision.

Example:

// Combining selectors
await page.locator('form#login-form >> text=Login').click();

πŸ“„ 6. Role Selectors

Playwright also offers role selectors, making it easier to target elements based on their accessibility roles, such as buttons, links, etc.

Example:

// Using role selector
await page.getByRole('button', { name: 'Submit' }).click();

πŸ’‘ Pro Tip: This is especially useful for improving test accessibility.


πŸ“… 7. Data Attributes

Web developers often use custom data attributes (like data-test-id) to make testing easier. Playwright fully supports targeting these attributes.

Example:

// Targeting elements by data attribute
await page.locator('[data-test-id="login-button"]').click();

πŸ”„ 8. Chained Selectors

Chaining allows you to narrow down your selection by combining multiple locators to interact with more complex UI elements.

Example:

// Chaining locators
await page.locator('div.container').locator('button.submit-btn').click();

🧭 9. Advanced: Locating nth-child Elements

When working with tables or lists, you may need to target specific rows or items. Playwright supports nth-child pseudo-classes.

Example:

// Selecting the 3rd item in a list
await page.locator('ul > li:nth-child(3)').click();

πŸ•΅οΈ 10. Working with Shadow DOM

Some modern web components use Shadow DOM, making it tricky to locate elements. Playwright supports direct interaction with elements inside Shadow DOM.

Example:

// Accessing elements inside Shadow DOM
await page.locator('css=element-with-shadow-dom').shadowRoot().locator('button').click();

🌐 11. Locator Assertions

You can also assert that elements are in the correct state before performing any interactions.

Example:

// Assert element is visible
await expect(page.locator('text=Submit')).toBeVisible();

πŸ’‘ Pro Tip: Assertions help ensure your tests remain stable and provide faster feedback when things go wrong.


πŸ”„ Putting It All Together: A Full Example

Here’s a complete script that combines different locators and strategies:

// Using CSS selectors to interact with form fields
await page.locator('#username').fill('my-username');
await page.locator('[type="password"]').fill('my-password');

// Clicking a button using text selector
await page.locator('text=Login').click();

// Waiting for a specific element to appear after login
await page.waitForSelector('text=Welcome, User!');

// Asserting that the logout button is visible
await expect(page.locator('text=Logout')).toBeVisible();

// Interacting with a role-based selector
await page.getByRole('button', { name: 'Logout' }).click();

Locators are the backbone of Playwright's automation. Whether you use CSS selectors, XPath, or text-based locators, mastering these will give you the power to write reliable, flexible tests. By combining different strategies and knowing when to apply each type, you can handle even the most complex UI interactions with ease.

0
Subscribe to my newsletter

Read articles from Anandkumar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Anandkumar
Anandkumar

"Passionate playwright dedicated to refining scripts through innovative methods. Embracing automated testing to enhance creativity and efficiency in crafting compelling narratives. Let's revolutionize storytelling together!"