Playwright Built-in Locators
What is a Locator ?
A locator is a way to identify and point to a specific element within a user interface or a data structure.
👉 Think of a locator as the address of a web element inside the webpage’s DOM (Document Object Model).
Locators in Playwright – Auto-Waiting & Retry-ability
In Playwright, locators are not just simple selectors. They are the central piece that make tests stable and less flaky.
🔑 Key Concept
- A locator represents a “live pointer” to an element (or multiple elements) on the page.
- Unlike Selenium, Playwright does not grab the element immediately.
- Instead, it re-evaluates the element on each action (
click,fill,expect). - This ensures your tests are always interacting with the current state of the page
👉 In short: Locators auto-wait + retry until the element is ready.
Example – Auto-Waiting for Button
Playwright auto-waits until the button is:
- Attached to the DOM
- Visible
- Enabled
- Stable (not moving/animating)
Example – Retry-ability for button
– If the element doesn’t appear immediately, Playwright keeps retrying.
– Prevents flaky failures due to slow network or animations.
Why This is Important
- No more manual waits → reduces flakiness.
- Dynamic handling → works well with modern SPAs (React, Angular, Vue).
- Cleaner code → fewer explicit wait statements.
7 Built-in locators
Playwright provides seven built-in locators that allow us to interact with web elements in a stable and accessible way.
1. getByRole → Locate elements by their role (button, link, textbox, checkbox, etc.) and accessible name.
2. getByText → Locate elements using their visible text content.
3. getByLabel → Locate form controls using the associated label’s text.
4. getByPlaceholder → Locate input fields by their placeholder text.
5. getByAltText → Locate elements (usually images/icons) by their alt attribute.
6. getByTitle → Locate elements by their title attribute (tooltip-style hints).
7. getByTestId → Locate elements using the data-testid attribute (or custom test ID attribute).
The above 7 locators are preferred over XPath/CSS because they are based on roles, labels, accessibility attributes, and test IDs.
1. What is getByRole?
– getByRole is a built-in Playwright locator that identifies elements using their ARIA role (such as textbox, button, checkbox, radio, or link) and their accessible name (the label shown to users).
– It’s one of the most stable and recommended locator strategies, especially for accessibility-friendly applications.
Example Program – Using getByRole
Here’s a simple Playwright test that demonstrates getByRole with different form elements:
import { test, expect } from '@playwright/test'
test('Get By Role Locator', async ({ page }) => {
// Launch application
await page.goto('https://vinothqaacademy.com/demo-site/')
// Text Box
await page.getByRole('textbox', { name: 'First Name *' }).fill('Vinoth')
// Radio button
await page.getByRole('radio', { name: 'Female' }).check();
// Checkbox
await page.getByRole('checkbox', { name: 'Selenium WebDriver' }).check()
await page.getByRole('checkbox', { name: 'DevOps' }).uncheck()
// Button
await page.getByRole('button', { name: 'Submit' }).click()
// Link
await page.getByRole('link', { name: 'Tutorials' }).click()
})
Why getByRole is Important?
– Works across browsers because it’s based on accessibility roles.
– More resilient than raw CSS or XPath selectors.
– Improves test readability — anyone can understand that getByRole('button', { name: 'Submit' }) is pointing to the Submit button.
– Encourages developers to build accessible web apps.
2. What is getByText?
- getByText locates elements on the page by their visible text content.
– It is useful when you want to validate or interact with labels, messages, headings, or links.
– It supports exact matches and partial matches.
Example Program – Using getByText
Here’s a Playwright test that demonstrates how getByText works:
test('Get By Text Locator', async ({ page }) => {
// Launch application
await page.goto('https://vinothqaacademy.com/demo-page-healthcare/')
// Heading validation
const formTitle = page.getByText('Patient Details Form')
await expect(formTitle).toHaveText('Patient Details Form')
console.log(await formTitle.textContent())
// Link
await page.getByText('Payment Link').click()
// Partial Link
await page.getByText('send for MRI').click()
})
Why getByTextis Important?
– Easy to use when working with static text like labels, headings, or messages.
– Great for validating success/error messages after form submissions.
– Supports partial matches, which is handy when only part of the text is known.
3. What is ?getByLabel
– getByLabel locates a form control (like textbox, dropdown, radio, or checkbox) using the text of its associated <label> tag.
– If a field has a visible label linked with it (via the for attribute or implicit nesting), Playwright can interact with it directly.
– This makes tests more readable and less dependent on technical attributes like IDs or classes.
Example Program – Using getByLabel
Here’s a Playwright test that demonstrates how works:getByLabel
test('Get By Label Locator', async ({ page }) => {
// Launch application
await page.goto('https://vinothqaacademy.com/demo-site/');
// Enter your query
await page.getByLabel('Enter your query ').fill('Is playwright easy to learn?');
});
Why getByLabel is Important?
– Matches real-world usage (users identify fields by their labels).
– More readable than CSS or XPath.
– Works for various controls: textboxes, radio buttons, checkboxes, dropdowns.
– Great for form-heavy applications (banking, healthcare, HR systems).
4. What is ?getByPlaceholder
– getByPlaceholder locates an input field based on the value of its placeholder attribute.
– Useful when input fields don’t have labels or stable IDs.
– Keeps your tests clean and user-focused, because placeholder text is what the end user sees.
Example Program – Using getByPlaceholder
Here’s a Playwright test that demonstrates how works:getByPlaceholder
test('Get By Place Holder Locator', async ({ page }) => {
// Launch application
await page.goto('https://vinothqaacademy.com/demo-site-keyboard-events/');
// Search Box
await page.getByPlaceholder('Type to search').fill('JAVA');
});
Why getByPlaceholderis Important?
– Ideal for apps where labels are missing or hidden.
– Makes test scripts easy to read.
– Best suited for search fields, login fields, and inline forms.
– More stable than CSS/XPath if UI changes frequently.
5. What is getByAltText?
– getByAltText locates elements (usually images or icons) by their alternative text (alt attribute).
– It’s extremely useful for validating images, logos, and accessibility compliance.
– Helps ensure your tests interact with the intended visual element.s.
Example Program – Using getByAltText
Here’s a Playwright test that demonstrates how to use getByAltText:
test('Get By Alt Text Locator', async ({ page }) => {
// Launch application
await page.goto('https://vinothqaacademy.com/');
// Logo Image
const logoImage = page.getByAltText('Vinoth Tech Solutions');
await expect(logoImage).toHaveAttribute('alt', 'Vinoth Tech Solutions');
});
Why getByAltText is Useful?
– Ensures brand/logo presence is tested.
– Validates accessibility standards (important for compliance testing).
– Provides a stable locator for images when IDs or classes are dynamic.
– Useful in e-commerce (product images) and corporate websites (logos, banners).
6. What is getByTitle?
– getByTitle locates elements by their title attribute.
– This attribute is often displayed as a tooltip when you hover over an element.
– It is useful for inputs, buttons, and icons where no other accessible labels exist.
Example Program – Using getByTitle
Here’s a Playwright test that demonstrates getByTitle:
test('Get By Title Locator', async ({ page }) => {
// Launch application
await page.goto('https://vinothqaacademy.com/mouse-event/');
// Enter First Name text field located by its title attribute
const firstName = page.getByTitle('Enter First Name');
await expect(firstName).toHaveAttribute('title', 'Enter First Name');
});
Why getByTitle is Useful?
– Perfect for locating icons (e.g., edit, delete, info icons) that don’t have visible text.
– Useful for form inputs when developers set the title attribute for accessibility.
– Ensures that tooltips and hints are correctly implemented.
– Provides a fallback locator if labels, placeholders, or roles are missing.
7. What is getByTestId?
– getByTestId locates elements by their data-testid attribute (or any custom test ID attribute configured).
– These attributes are added by developers for the sole purpose of making automation easier.
– Unlike text or labels, data-testid values are less likely to change when UI design changes.
Example Program – Using getByTestId
Here’s a Playwright test that demonstrates how to fill a registration form using getByTestId:
test('Get By Test ID Locator', async ({ page }) => {
// Launch application
await page.goto('https://vinothqaacademy.com/demo-site-create-account/')
// Form - data-testid
await page.getByTestId('input-firstName').fill('Vinoth')
await page.getByTestId('input-lastName').fill('R')
await page.getByTestId('input-address').fill('XYZ')
await page.getByTestId('input-city').fill('Chennai')
await page.getByTestId('input-state').fill('Tamil Nadu')
await page.getByTestId('input-zip').fill('600000')
await page.getByTestId('input-phone').fill('6383544892')
await page.getByTestId('input-email').fill('vinothtechsolutions@gmail.com')
await page.getByTestId('btn-register').click()
})
Configuration in Playwrightconfig.ts
// using name locator
use: {
testIdAttribute:'name'
},
Why getByTestId is Useful?
– Most stable locator for automation since it’s added only for testing.
– Unaffected by UI changes like text updates or redesigns.
– Encourages collaboration with developers → testers can request data-testid attributes for critical elements.
– Commonly used in enterprise-grade automation frameworks.