Introduction
Choosing the right locator is one of the most important skills in UI automation testing. A reliable locator makes your tests stable, readable, and easy to maintain, while a poor locator often leads to flaky tests and frequent failures. Playwright provides modern locator APIs that are designed around how users interact with web applications rather than relying only on HTML structure.
This guide explains Playwright Python Locators in detail, covering accessibility-first locators, CSS selectors, XPath, locator chaining, filtering, strict mode, dynamic elements, and enterprise locator strategies. Whether you’re learning Playwright Python, transitioning from Selenium, or preparing for an automation interview, this tutorial will help you write robust and maintainable Playwright tests.
What Are Playwright Python Locators?
Playwright Python Locators are APIs used to find and interact with elements on a web page. Instead of immediately searching the DOM, a locator represents a way to find an element whenever an action is performed. This design works well with Playwright’s built-in auto-waiting and retry mechanisms.
Examples of supported locators include:
- get_by_role()
- get_by_text()
- get_by_label()
- get_by_placeholder()
- get_by_alt_text()
- get_by_title()
- get_by_test_id()
- CSS selectors
- XPath selectors
Why Locators Are Important in UI Automation
Reliable locators provide several advantages:
- Stable automation scripts
- Fewer flaky tests
- Better readability
- Easier maintenance
- Improved accessibility testing
- Better compatibility with Page Object Model (POM)
Locator Workflow
Test Script
│
▼
Playwright Locator
│
▼
Find Element
│
▼
Auto-Wait
│
▼
Perform Action
Playwright automatically waits for elements to become ready before interacting with them, reducing the need for explicit waits.
Types of Playwright Python Locators
Playwright recommends using user-facing locators whenever possible.
Recommended priority:
- get_by_role()
- get_by_label()
- get_by_placeholder()
- get_by_text()
- get_by_test_id()
- CSS selectors
- XPath selectors
get_by_role()
Role-based locators identify elements by their accessibility role.
page.get_by_role(
“button”,
name=”Login”
).click()
Step-by-Step Explanation
- Finds a button element.
- Matches the accessible name Login.
- Clicks the button.
Why Use It?
- Accessibility-friendly
- Stable across UI changes
- Recommended by Playwright
get_by_text()
Find elements using visible text.
page.get_by_text(
“Welcome”
).click()
Explanation
The locator searches for visible text displayed on the page and clicks the matching element.
Best used when the displayed text is stable and unique.
get_by_label()
Useful for forms.
page.get_by_label(
“Username”
).fill(“admin”)
Explanation
- Finds the input associated with the label Username.
- Enters the provided value.
This approach is easier to read than locating an input by its HTML structure.
get_by_placeholder()
Locate an input using its placeholder.
page.get_by_placeholder(
“Enter email”
).fill(“user@example.com”)
This works well when placeholders are unique and meaningful.
get_by_alt_text()
Locate images by alternate text.
page.get_by_alt_text(
“Company Logo”
).click()
Useful for validating accessible image elements.
get_by_title()
Locate elements by their HTML title attribute.
page.get_by_title(
“Settings”
).click()
This is helpful when a tooltip or title uniquely identifies the element.
get_by_test_id()
Many teams add dedicated test attributes for automation.
HTML:
<button data-testid=”login-btn”>
Login
</button>
Python:
page.get_by_test_id(
“login-btn”
).click()
Why Use Test IDs?
- Stable across UI redesigns
- Independent of visible text
- Easy to maintain
CSS Selectors
CSS selectors remain useful when semantic locators are unavailable.
page.locator(
“#username”
).fill(“admin”)
Example using a class:
page.locator(
“.submit-button”
).click()
Best Use Cases
- Stable IDs
- Well-structured CSS classes
- Legacy applications
XPath Selectors
XPath can locate complex elements.
page.locator(
“//button[text()=’Login’]”
).click()
Although supported, XPath should generally be a fallback when semantic locators or CSS selectors are not suitable.
Locator Chaining, Filtering, and Strict Mode
Locator Chaining
You can narrow the search by chaining locators.
page.locator(“.product”) \
.get_by_role(“button”, name=”Buy”) \
.click()
Explanation
- Finds a product container.
- Searches only within that container.
- Clicks the Buy button.
This reduces the chance of selecting the wrong element.
Locator Filtering
page.locator(“.product”).filter(
has_text=”Laptop”
).click()
The filter limits results to products containing the text Laptop.
Strict Mode
Playwright expects a locator used for an action to resolve to a single element. If multiple elements match unexpectedly, it raises an error to help identify ambiguous locators.
Benefits include:
- Early detection of incorrect selectors
- Improved test reliability
- Easier debugging
Exact vs Partial Text Matching
Exact Text
page.get_by_text(
“Submit”,
exact=True
).click()
Only elements with the exact text Submit are matched.
Partial Text
page.get_by_text(
“Submit”
).click()
Matches elements containing the specified text.
Use exact matching when multiple similar elements exist.
Handling Dynamic Elements and Multiple Matches
Dynamic applications often generate changing IDs or content.
Example
Instead of:
page.locator(“#user12345”)
Use:
page.get_by_role(
“button”,
name=”Save”
)
For repeated elements:
page.locator(“.product”).nth(0).click()
Or select the first matching element:
page.get_by_role(“link”).first.click()
Choose positional locators only when there is no stable user-facing identifier.
Real-World Python Locator Examples
Login Automation
page.goto(“https://example.com”)
page.get_by_label(“Username”).fill(“admin”)
page.get_by_label(“Password”).fill(“admin123”)
page.get_by_role(
“button”,
name=”Login”
).click()
Explanation
- Opens the application.
- Enters the username.
- Enters the password.
- Clicks the Login button.
Product Search
page.get_by_placeholder(
“Search products”
).fill(“Laptop”)
page.keyboard.press(“Enter”)
This example automates a common e-commerce search workflow.
Best Practices
- Prefer get_by_role() whenever possible.
- Use accessibility-first locators.
- Store locators inside Page Object Models.
- Avoid brittle XPath expressions.
- Use data-testid for dynamic components.
- Keep locators descriptive and readable.
- Rely on Playwright’s auto-waiting instead of unnecessary delays.
- Review locator stability during code reviews.
Common Mistakes
Avoid these common errors:
- Using long XPath expressions.
- Hardcoding dynamic IDs.
- Depending on changing CSS classes.
- Ignoring accessibility-based locators.
- Mixing locator definitions throughout test files instead of centralizing them in Page Objects.
- Overusing positional selectors like nth() when a stable locator is available.
Locator Strategy Comparison (Role vs Text vs CSS vs XPath)
| Locator | Best Use Case | Maintainability | |
| get_by_role() | Buttons, links, form controls | Excellent | |
| get_by_label() | Form fields | Excellent | |
| get_by_placeholder() | Input fields | Very Good | |
| get_by_text() | Visible content | Very Good | |
| get_by_test_id() | Dynamic applications | Very Good | |
| CSS Selector | Stable IDs and classes | Good | |
| XPath | Complex legacy pages | Fair |
Real-Time Enterprise Automation Scenarios
Banking Application
- Login using get_by_label()
- Approve transactions with get_by_role()
- Verify account summaries using get_by_text()
E-Commerce Application
- Search products using get_by_placeholder()
- Add items to the cart using get_by_role()
- Validate order confirmation using get_by_text()
Healthcare Portal
- Complete patient registration forms using get_by_label()
- Verify appointment details with get_by_text()
- Upload reports using stable test IDs
Page Object Model Example
class LoginPage:
def __init__(self, page):
self.page = page
def login(self, username, password):
self.page.get_by_label(“Username”).fill(username)
self.page.get_by_label(“Password”).fill(password)
self.page.get_by_role(
“button”,
name=”Login”
).click()
Keeping locators inside Page Objects improves reuse and maintainability across large automation projects.
Playwright Python Locator Interview Questions
- What are Playwright Python locators?
- Why are locators important?
- What is the recommended locator priority?
- Why is get_by_role() preferred?
- What is get_by_label() used for?
- When should you use get_by_placeholder()?
- What is get_by_test_id()?
- When should CSS selectors be used?
- When is XPath appropriate?
- What is locator chaining?
- What is locator filtering?
- What is strict mode?
- How does Playwright auto-waiting improve locator reliability?
- What is exact text matching?
- What is partial text matching?
- How do you handle dynamic elements?
- How do you locate repeated elements?
- Why use the Page Object Model?
- How do you reduce flaky tests caused by locators?
- What are accessibility-first locator strategies?
- How do you organize reusable locators?
- How do test IDs improve maintainability?
- What are common locator mistakes?
- How would you debug a failing locator?
- Which locator strategy would you choose for an enterprise application and why?
FAQs
What are Playwright Python Locators?
They are APIs used to locate and interact with elements in a web application using Playwright.
Which locator should I use first?
Start with get_by_role() whenever possible because it reflects user interactions and accessibility semantics.
Is XPath supported?
Yes, but it is generally recommended only when better locator options are unavailable.
What is strict mode?
It ensures that action locators resolve to a single element, helping detect ambiguous selectors.
Why use data-testid?
It provides stable automation hooks that are less likely to change during UI updates.
How do Playwright locators differ from Selenium?
Playwright locators include built-in auto-waiting and encourage accessibility-first strategies, reducing the need for explicit waits and brittle selectors.
Should I store locators inside Page Objects?
Yes. Centralizing locators in Page Object Models improves maintainability and reuse.
Are Playwright locators suitable for enterprise automation?
Yes. They support scalable framework design, reliable execution, and modern locator strategies for large automation projects.
