Hero Background

Next-Gen App & Browser Testing Cloud

Trusted by 2 Mn+ QAs & Devs to accelerate their release cycles

Next-Gen App & Browser Testing Cloud
Playwright TestingAutomationTutorial

Playwright Locators: Types, Methods, and Examples

Learn Playwright locators with Python examples: get_by_role, CSS and XPath, filtering, chaining, and methods like fill(), first, and all().

Author

Jaydeep Karale

Author

Last Updated on: July 3, 2026

Locators are one of the most effective ways to locate elements for web testing. They provide automatic waiting and retry features, making it simple for developers and testers to find and interact with specific elements on a web page, ensuring test scripts work smoothly with those elements.

Playwright, one of the most commonly used frameworks for end-to-end testing, provides various locator strategies to find and interact with WebElements. In this blog, we will learn various Playwright locators and see how to use them for effective end-to-end testing.

Key Takeaways

  • Playwright locators target a specific element and add auto-wait and retry, so an action runs only after the element is ready rather than throwing a TimeoutError.
  • Locators resolve lazily against the live DOM and pass five actionability checks, visible, stable, receives events, enabled, and editable, before Playwright acts.
  • Built-in locators handle most cases, including get_by_role, get_by_text, get_by_label, get_by_placeholder, get_by_alt_text, get_by_title, and get_by_test_id, while page.locator takes raw CSS or XPath.
  • Locator priority runs from role and user-facing locators first, to a data-testid contract next, to CSS or XPath last, since CSS and XPath break when the DOM changes.
  • Locator methods such as fill, click, first, nth, all, count, and text_content act on and read elements, while filter and chaining narrow a broad match to one element.
  • Cloud execution runs locator suites across 3,000+ browser and OS combinations in parallel on the TestMu AI cloud grid.

What Are Playwright Locators?

Playwright locators allow your test scripts to interact with a specific element on a web page. They are equipped with auto-wait and retry abilities. This means the locator will wait for the elements to load and keep retrying automatically before throwing TimeoutError.

Playwright gives you two ways to create a locator. The page.locator() method takes a CSS or XPath selector, while built-in locators such as get_by_role() and get_by_text() target elements by role, text, and other user-facing attributes. Both are valid, but the built-in locators are recommended for most cases because they are easier to read and hold up better when the DOM changes.

Key takeaway: Playwright locators find a web element and auto-wait for it to become actionable, letting tests click, type, and assert reliably without manual waits.

Key features of Playwright locators

  • Built-in support for auto-wait and retry, helping write resilient and non-flaky tests.
  • Built-in methods are available to perform various actions on located elements.
  • The page object offers the Playwright wait for navigation to pause until specific actions on a web page are completed or a timeout/exception occurs.
  • For tests that depend on a specific backend call rather than a navigation event, Playwright waitForResponse synchronizes locator-driven actions with the matching API response, removing flakiness in workflows that load data after a click or form submission.
  • When the backend isn't available or you need to test failure paths, pair locators with Playwright mock API testing, which uses page.route() to fulfill, modify, or block requests with custom responses.
  • Locators work on the most up-to-date DOM every time action is performed, ensuring reliable tests.
  • Built-in locators capable of locating elements using ARIA roles, text, alt-text, placeholders, titles, labels, and custom test-ids.
  • Ability to chain and filter locators provides precision to narrow the search for the element.

Enhance your testing strategy with our detailed guide on Playwright Headless Testing. Explore further insights into Playwright’s capabilities in this guide.

Key takeaway: Playwright locators provide auto-waiting, automatic retries, and always query the latest DOM, which makes end-to-end tests faster, more stable, and less flaky.

How Playwright Identifies Elements

A Playwright locator does not query the page the moment you define it. It is a lazy description of how to find an element, and it resolves only when you perform an action such as a click, fill, or assertion, always against the latest DOM. This is why locators stay reliable on dynamic pages where elements load, move, or re-render after the first paint.

Before acting on the element it found, Playwright runs a set of auto-wait actionability checks and keeps retrying until they pass or the action times out. According to the Playwright actionability documentation, the core checks are:

  • Visible: the element has a non-empty bounding box and is not set to visibility: hidden.
  • Stable: the element has kept the same bounding box for at least two consecutive animation frames, so it is not mid-animation.
  • Receives Events: the element is the actual hit target at the action point, not hidden behind an overlay or modal.
  • Enabled: the element is not disabled.
  • Editable: for input actions like fill(), the element is enabled and not read-only.

Because these checks are built into every locator, you rarely need manual sleeps or explicit waits. The same auto-wait behavior powers the assertions used throughout this guide: when a test calls expect(locator).to_be_visible(), Playwright polls the DOM until the condition holds or the timeout expires, which is what keeps the examples below stable across browsers.

Key takeaway: Playwright identifies elements by resolving a locator lazily on the live DOM, then running actionability checks (visible, stable, enabled, editable) before it acts.

Types of Playwright Locators

These are the built-in locators that Playwright supports:

  • page.get_by_role(): Locates elements by explicit and implicit accessibility attributes.
  • page.get_by_text(): Locates elements by their text content.
  • page.get_by_label(): Locates form controls by the associated label’s text.
  • page.get_by_placeholder(): Locates inputs by their placeholder text.
  • page.get_by_alt_text(): Locates elements, usually images, by their text alternative.
  • page.get_by_title(): Locates elements by their title attribute.
  • page.get_by_test_id(): Locates elements based on their data-testid attribute (other attributes can be configured).

Key takeaway: Playwright's built-in locators are get_by_role, get_by_text, get_by_label, get_by_placeholder, get_by_alt_text, get_by_title, and get_by_test_id, while page.locator handles CSS and XPath selectors.

CSS vs XPath vs Role-Based Locators

Playwright lets you find the same element in more than one way: through built-in, user-facing locators like get_by_role(), or through raw CSS and XPath selectors passed to page.locator(). Choosing the right approach is what keeps a suite readable today and resilient when the UI changes tomorrow.

The table below compares the three approaches using the same kind of button we located earlier on the TestMu AI eCommerce Playground.

ApproachExample (Python)How it matchesBest for
Role-basedpage.get_by_role("button", name="Search")Accessibility tree (ARIA role plus accessible name)User-facing elements like buttons, links, and inputs; most resilient to markup changes
CSS selectorpage.locator("css=button.type-text")DOM structure, classes, and attributesFast, familiar targeting when a stable class or id exists
XPathpage.locator("xpath=//button[@type='submit']")DOM tree traversal and axesTraversals CSS cannot express; the most brittle option

When to Use Which Locator

The Playwright locators guide recommends prioritizing role locators because they reflect how users and assistive technology perceive the page. A practical order of preference looks like this:

  • Role and user-facing locators first: get_by_role(), then get_by_text(), get_by_label(), and get_by_placeholder() for form fields.
  • An explicit test contract next: add a data-testid attribute and use get_by_test_id() for elements with no stable user-facing text.
  • CSS or XPath last: reach for page.locator() with a raw selector only when no built-in locator can target the element.

The reason for this order is stability. Playwright notes that CSS and XPath selectors are tied to the DOM structure and can break when that structure changes, while role and text locators track what the user actually sees. A button keeps its role and label through a redesign far more often than it keeps its nth-child position or CSS class.

Key takeaway: For Playwright locators, use role-based locators first and CSS or XPath selectors last, because CSS and XPath depend on DOM structure and break when the HTML changes.

Installing and Setting Up Playwright

In this section, we will learn how to install Playwright and set it up in a dedicated virtual environment:

  • Create a dedicated folder for our project called playwright locators (This step is not mandatory but good practice).
  • Inside the folder we just created, use the built-in venv module to create a virtual environment named playwright locators.
  • Activate the virtual environment by calling the activate script.
  • Install the Playwright module using pip install pytest-playwright.
  • Lastly, install the required browsers using the playwright install.

All tests in this blog use these versions: Python 3.12.4, pytest 8.2.2, and Playwright 1.44.0.

We will use the Python API of Playwright and, more specifically, the sync_api version. The reason for choosing sync_api, as mentioned in the answer on StackOverflow, is that the sync_api is simply a wrapper around Python’s asyncio_api. So Playwright makes async calls under the hood.

When executed, the Python test generates code using sync_api, as shown in the screenshot below:

Python test

So, when running the Playwright test, feel free to use sync_api unless you need fine control over the request behavior in which you can use async_api.

Key takeaway: To install Playwright in Python, run pip install pytest-playwright and playwright install, then write tests with the Playwright sync API.

How to Use Playwright Locators?

Playwright locators are essential in automation testing, especially when testing on cloud platforms. It provides a way to interact with web page elements when testing websites across web browsers online.

Let’s demonstrate some use cases of Playwright locators using cloud-based testing platforms like TestMu AI. It is an AI-driven test execution platform that allows you to run automated Playwright tests at scale across 50+ browser versions.

Test across 3000+ browser and OS environments with TestMu AI

When running tests in the cloud, efficient and reliable element identification is crucial due to the variety of browsers and environments involved. To use Playwright locators, you must set up the necessary imports and dependencies along with the username and access key to run the test on the TestMu AI cloud grid.

The load_dotenv() reads the username and access key required to access the Playwright on the TestMu AI Playwright grid. The username and access key are available in your TestMu AI Profile > Account Settings > Password & Security.

import json
import os
import re
import subprocess
import sys
import urllib
 
import pytest
from dotenv import load_dotenv
  
load_dotenv()

Setting Up the Capabilities

The capabilities dictionary contains the configuration of our test environment on the TestMu AI Playwright grid. The configurations encompass various parameters, such as the preferred browser, its specific version, the operating system required to execute the tests, and other relevant settings.

capabilities = {
    'browserName': 'Chrome',  # Browsers allowed: `Chrome`, `MicrosoftEdge`, `pw-chromium`, `pw-firefox` and `pw-webkit`
    'browserVersion': 'latest',
    'LT:Options': {
        'platform': 'Windows 10',
        'build': 'Playwright Locators Demo Build',
        'name': 'Playwright Locators Test For Windows 10 & Chrome',
        'user': os.getenv('LT_USERNAME'),
        'accessKey': os.getenv('LT_ACCESS_KEY'),
        'network': True,
        'video': True,
        'visual': True,
        'console': True,
        'tunnel': False,   # Add tunnel configuration if testing locally hosted webpage
        'tunnelName': '',  # Optional
        'geoLocation': '', # country code can be fetched from https://www.lambdatest.com/capabilities-generator/
    }
}

Setting Up the pytest Fixtures:

We set up two fixtures, one for our cloud grid and the other for our local grid. So, it becomes easy to switch between local and cloud depending on where you want to run the tests.

Use the local_grid_page fixture when you run the tests on the local machine:

@pytest.fixture(name="local_grid_page")
def playwright_local_grid_page():
    with sync_playwright() as playwright:
        browser = playwright.chromium.launch(headless=True)
        page = browser.new_

Use the cloud_grid_page fixture when you wish to run the tests on the TestMu AI cloud grid:

@pytest.fixture(name="cloud_grid_page")
def playwright_local_grid_page():    
    with sync_playwright() as playwright:
        playwrightVersion = str(subprocess.getoutput('playwright --version')).strip().split(" ")[1]
        capabilities['LT:Options']['playwrightClientVersion'] = playwrightVersion        
        lt_cdp_url = 'wss://cdp.lambdatest.com/playwright?capabilities=' + urllib.parse.quote(json.dumps(capabilities))    
        browser = playwright.chromium.connect(lt_cdp_url)
        page = browser.new_page()    
        yield page

Locating Elements by Role in Playwright

The locator get_by_role() allows locating elements by their ARIA role, ARIA attributes, and accessible name. ARIA stands for Accessible Rich Internet Applications. It’s a set of attributes that can be added to HTML elements to help people who use assistive technologies, like screen readers, navigate and understand web content more easily.

ARIA roles are like labels for different parts of a website, like headings, buttons, and links. These labels help people who use assistive technologies understand the different parts of the website and how to use them.

Let’s understand the get_by_role() locator using the TestMu AI eCommerce Playground website.

ARIA roles

Test Scenario:

  • The demo website home page should contain the Search button.
  • The Search button should have a CSS class type-text.

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_homepage_contains_search_button(cloud_grid_page):
    cloud_grid_page.goto("https://ecommerce-playground.lambdatest.io/")
    search_button_locator = cloud_grid_page.get_by_role(role="button", name="Search")
    expect(search_button_locator).to_have_class("type-text")

Code Walkthrough:

  • Upon inspecting the homepage, we see that Search is a button for the type submit with a CSS class ”type-text” assigned to it.
  • Use the Playwright locator get_by_role() with arguments as role=”button” and name=”Search”.
  • The expect() method then checks if the located element has class type-text using the to_have_class() method.

It’s worth mentioning that for the get_by_role() Playwright locator, only the role argument is mandatory. All other arguments are optional, including the name we used. An important optional argument is exact. It can be used to force an exact case-sensitive and whole-string match.

Test Execution:

Let’s now execute the test using the following command:

pytest -v -k “test_homepage_contains_search_button”

Locating Elements by Text in Playwright

The locator get_by_text() allows finding elements by the text it contains. This Playwright locator can match exact string and substring and allows using regular expressions.

It is recommended to find non-interactive elements such as those contained within HTML tags div, span, and p. Let’s see this Playwright locator in action using a few scenarios to explore exact matches and regular expressions.

For this, we will again use the TestMu AI eCommerce Playground website.

Test Scenario:

  • The product page of the LambdaTest eCommerce Playground website should contain the exact text for product details:
    • Brand
    • Viewed
    • Reward Points
    • Availability
 LambdaTest eCommerce Playground

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_product_details_text_should_be_visible(cloud_grid_page):    
    cloud_grid_page.goto(
        "https://ecommerce-playground.lambdatest.io/index.php?route=product/product&path=57&product_id=28"
    )
    brand_text_locator = cloud_grid_page.get_by_text(text="Brand:", exact=True)
    viewed_text_locator = cloud_grid_page.get_by_text(text="Viewed:", exact=True)
    points_text_locator = cloud_grid_page.get_by_text(text="Reward Points:", exact=True)
    availability_text_locator = cloud_grid_page.get_by_text(text="Availability", exact=True)
    expect(brand_text_locator).to_be_visible()
    expect(viewed_text_locator).to_be_visible()
    expect(points_text_locator).to_be_visible()
    expect(availability_text_locator).not_to_be_visible()

Code Walkthrough:

  • Upon inspecting the product page, we see the details within the <span> tag.
  • The steps to navigate the product page remain the same as in the previous test case.
  • In the next steps, we use the get_by_text() Playwright locator to match the texts for Brand:, Viewed:, and Reward Points:. We use the expect() assertion on each of the three locators and call the to_be_visible() method.
  • For the ‘Availability’, we exclude the ‘:’ to demonstrate that the exact argument works. Since we know the exact match, in this case, the test will fail on the expect() assertion, and we call the not_to_be_visible() method.

Test Execution:

Let’s run the test using the following command:

pytest -v -k “test_product_details_text_should_be_visible”

Locating Form Elements by Label in Playwright

Almost all websites have form fields, and most form controls usually have dedicated labels that could be conveniently used to interact with the form. Playwright locators provide a convenient way of locating form elements using the get_by_label() locator.

Let’s jump into a demo using the TestMu AI eCommerce Playground website.

Test Scenario:

  • The login form should have exactly one Email Address label.
  • The login form should have exactly one Password label.
Password label

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_exactly_one_email_and_password_field(cloud_grid_page):    
    cloud_grid_page.goto(
        "https://ecommerce-playground.lambdatest.io/index.php?route=account/login"
    )
    email_address_locator = cloud_grid_page.get_by_label(text="E-Mail Address", exact=True)
    password_locator = cloud_grid_page.get_by_label(text="Password", exact=True)
    expect(email_address_locator).to_have_count(1)
    expect(password_locator).to_have_count(1)

Code Walkthrough:

  • The code snippet until the goto() method will keep the login page the same.
  • Initialize two locators using get_by_label(), one of which is an email and password with the exact=True, to confirm that only one login form element exists.
  • On the expect() assertion, we call the method to_have_count(1) to test only one of each email and password field.

Test Execution:

Let’s execute the test using the following command:

pytest -v -k “test_exactly_one_email_password_field”

Locating Input Elements by Placeholder in Playwright

Most websites have several forms for login, registration, reviews, and customer support. Forms usually have a placeholder text to assist the user in correctly filling out forms.

Playwright locator get_by_placeholder() comes in handy when locating elements using the placeholder text. The TestMu AI eCommerce Playground website has a review form that can be used to explore this locator.

Test Scenario:

  • The review form should have one field for the customer name.
  • The review form should have one field for customer review.
Playwright get_by_placeholder locating review form fields

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_review_form_has_customername_customerreview_fields(cloud_grid_page):    
    cloud_grid_page.goto(
        "https://ecommerce-playground.lambdatest.io/index.php?route=product/product&path=25&product_id=28"
    )
    name_locator = cloud_grid_page.get_by_placeholder(text="Your Name", exact=True)
    review_locator = cloud_grid_page.get_by_placeholder(text="Your Review", exact=True)
    expect(name_locator).to_have_count(1)
    expect(review_locator).to_have_count(1)

Code Walkthrough:

  • We use the name of the placeholders as an argument to the get_by_placeholder() locator. We also only look for an exact matching by setting the argument exact=True.
  • Calling to_have_count(1) on the except() assertion helps to test our scenario of only one reviewer name field and review input field.

Test Execution:

Let’s execute the test using the following command:

pytest -v -k “test_review_form_has_customername_customerreview_fields”

Locating Image Elements by Alt Text in Playwright

All websites have images, and all images must have an alt-text. The reason it’s important to have alt-text is beyond the scope of this blog. Still, to provide a brief explanation, alt-text is important for accessibility, user experience, and image search SEO.

Playwright has an efficient get_by_alt_text() locator to locate image and area elements using the alt-text attribute.

Test Scenario:

  • The logo with alt-text=”Poco Electro” should be visible.
locate image

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_logo_with_alt_text_should_be_visible(cloud_grid_page):
    cloud_grid_page.goto(
        "https://ecommerce-playground.lambdatest.io/index.php?route=common/home"
    )
    logo_locator = cloud_grid_page.get_by_alt_text(text="Poco Electro", exact=True).first
    expect(logo_locator).to_be_visible()

Code Walkthrough:

  • We just get the alt-text from the Chrome Developer Tools and pass it onto the get_by_alt_text() locator.
  • Since there could be multiple uses of the same alt-text, we use the attribute first to narrow down our results to the first element.
  • The expect() then asserts if the selected element by the locator is visible.

Test Execution:

Let’s now execute the test using the following command:

pytest -v -k “test_logo_with_alt_text_should_be_visible”

Locating Elements by Title in Playwright

The HTML title attribute specifies additional information about an element. It is most commonly used on the <a> and <img> elements to provide a text description for screen readers and other assistive technologies. The text within the title attribute will typically appear as a tooltip when the mouse pointer hovers over the element.

We can use the get_by_title() Playwright locator to locate elements by title. It’s worth noting that the TestMu AI eCommerce Playground website uses the same title text for all images. Hence, our locator will return more than one element(20).

Test Scenario:

  • Twenty elements with title=’HTC Touch HD’ should be present.
Twenty elements with

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_display_count_of_all_elements_with_title_htc_touch_hd(cloud_grid_page):    
    cloud_grid_page.goto(
        "https://ecommerce-playground.lambdatest.io/index.php?route=product/product&path=18&product_id=28"
    )
    alt_text_locator = cloud_grid_page.get_by_title(text=re.compile("htc touch hd", re.IGNORECASE))
    expect(alt_text_locator).to_have_count(20)

Code Walkthrough:

  • As usual, we open the product page using the page.goto() method.
  • Next, we pass the title text we want to locate. Notice the use of the regex Python module to ignore the case.
  • The expect() assertion then verifies if the locator can detect all 20 elements.

Test Execution:

Let’s now execute the test using the following command:

pytest -v -k “test_display_count_of_all_elements_with_title_htc_touch_hd”

Locating Elements by Test ID in Playwright

The Playwright locators are based on HTML tags or attributes assigned to each element. However, the challenge with this approach is that these tags, such as roles and attributes may change over time. If this happens, our tests will fail and must be refactored to account for the changes.

To avoid this, Test IDs are the most resilient way of testing a web application. Testers can define explicit Test IDs for elements. Using these Test IDs to query the elements ensures that our tests continue to work even if the role, text, or title of the elements changes.

Playwright provides the get_by_test_id() locator for locating elements by predefined Test IDs. The default attribute that the get_by_test_id() locator looks for is data-testid. This behavior can be easily changed by setting a custom attribute to look for playwright.selectors.set_test_id_attribute(“data-pw”).

Locating Elements by CSS and XPath

Playwright is fully flexible, and while the recommended locators should always be used, there might be scenarios of personal preferences for using CSS or XPath to locate elements. For such cases, we need to use the page locator(), which takes a selector to describe how to find the element on the page.

Below are some examples of creating locators using the page.locator() method using CSS and XPath. We can omit the CSS and XPath prefixes, which will work fine.

# Construction locators using CSS
page.locator("css=button").click()
page.locator("button").click()
page.locator( "#tsf > div:nth-child(2) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input").click()
 
# Construction locators Xpath
page.locator("xpath=//button").click()
page.locator("//button").click()    
    page.locator('//*[@id="tsf"]/div[2]/div[1]/div[1]/div/div[2]/input').click()

As evident from the examples above, CSS and XPath-based locators are tied to the Document Object Model (DOM) and quickly become complicated to read, maintain, and unreliable. The DOM is subject to change; hence, the locators that use them lead to non-resilient tests.

So, it’s best to develop tests using the recommended built-in locators such as role and text, or even better, define explicit testing contracts using Test IDs.

Locating Multiple Elements by Regular Expressions in Playwright

While we saw exact matches while testing modern web applications, we frequently may need to look for approximate matches, and Playwright locators have us covered.

We can use regular expressions to locate multiple elements. Let’s look at an example.

Test Scenario:

  • On the product page of TestMu AI eCommerce Playground, there should be multiple occurrences of the brand HTC.
  • There should be ten matches.
 brand HTC

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_product_name_to_appear_more_than_once(cloud_grid_page):    
    cloud_grid_page.goto(
        "https://ecommerce-playground.lambdatest.io/index.php?route=product/product&path=57&product_id=28"
    )
    brand_name_locator = cloud_grid_page.get_by_text(re.compile("htc", re.IGNORECASE))
    expect(brand_name_locator).to_have_count(10)
Github

Code Walkthrough:

  • Upon inspecting the product page, there are ten brand name ‘htc’ occurrences.
  • In preparing the locator, we use the Python re module to match all occurrences and IGNORECASE.
  • On the expect() assertion, we call the to_have_count() method to complete our test.

Test Execution:

Let’s run the test using the following command:

pytest -v -k “test_product_name_to_appear_more_than_once”

Locating Elements Using Playwright Test Generator

We have been writing the tests manually by inspecting the DOM. But since we are talking about an automation framework, it only makes sense that Playwright has something which can assist and automate part of locating elements on a web page. Playwright has a powerful feature called the Test Generator, which can help you locate the elements and make it easier to write tests.

My only feedback about this feature is that it’s called Test Generator. The command to start it has the word codegen, and the subsequent generator that starts has the title, Playwright Inspector. I wish Microsoft would fix this and agree on one name to simplify lives.

To start the Test Generator, we simply use the command shown below:

playwright codegen https://ecommerce-playground.lambdatest.io/

Feel free to replace the URL with the website you intend to write tests for.

The Test Generator will generate the code for us based on our actions. The best thing about the Test Generator is that you can choose your intended programming language. I have chosen Python for this blog, but Playwright allows you to choose whichever you wish from the drop-down highlighted in red.

Based on your selection, the Test Generator will write the code for us.

Test Generator

We want to locate the search bar, type in mobile, and hit the Search button. Here is the snapshot of the actions performed and the code the Test Generator was able to write code for us with all the locators. We can then use these locators to run tests using the except() assertion.

 locators to run tests

The Playwright Test Generator also has several built-in options to emulate devices, such as viewport sizes, color schemes, geolocation, time zones, etc.

  • Emulate Viewport Size: Notice how Playwright generates all the boiler-plate code for setting the viewport as a fixture.
  • playwright codegen --viewport-size=800,600 https://ecommerce-playground.lambdatest.io/
    
    Playwright generates
  • Emulate Devices: Notice how Playwright generates all the boiler-plate code for setting the device selected for testing as a fixture.
  • playwright codegen --device=”iPhone 14 Pro Max” https://ecommerce-playground.lambdatest.io/
    
    boiler-plate code

Understanding how to use Playwright locators effectively is an essential step in building reliable automation tests. Once you’re comfortable with these locators, you can move on to more advanced tasks, such as handling alerts and dropdowns, interacting with iframes, managing multiple windows, and performing other complex operations, enabling you to create robust and versatile Playwright automation scripts.

Key takeaway: To use a Playwright locator, create it with get_by_role or page.locator, perform an action such as click() or fill(), then verify it with an expect() assertion.

Note

Note: Run automated Playwright tests online. Try TestMu AI Now!

Playwright Locator Methods and Actions

Once a locator points at an element, you call methods on it to interact with the page or read its state. Because a locator resolves lazily, these methods trigger the same auto-wait actionability checks covered earlier, so you rarely need an explicit wait before them. Here are the methods you will reach for most, shown with the Python sync API.

MethodWhat it doesExample (Python)
fill(value)Clears an input and types the given textpage.locator("#input-email").fill("[email protected]")
click()Clicks the element after auto-waitpage.get_by_role("button", name="Login").click()
first / last / nth(i)Selects one element when the locator matches manypage.get_by_role("listitem").nth(2)
all()Returns a list of locators, one per match, to loop overpage.get_by_role("listitem").all()
count()Returns how many elements the locator matchespage.get_by_role("listitem").count()
text_content()Reads the text content of the elementpage.get_by_role("listitem").first.text_content()

Filling and Submitting a Form With fill()

The fill() method clears an input and types a value in a single call, which is the quickest way to complete a form field. On the TestMu AI eCommerce Playground login page, the email and password inputs carry the ids input-email and input-password, so you can target them by CSS id and fill them before clicking Login:

# replace cloud_grid_page with local_grid_page while running on local
def test_fill_login_form(cloud_grid_page):
    cloud_grid_page.goto(
        "https://ecommerce-playground.lambdatest.io/index.php?route=account/login"
    )
    cloud_grid_page.locator("#input-email").fill("[email protected]")
    cloud_grid_page.locator("#input-password").fill("Password123")
    cloud_grid_page.get_by_role("button", name="Login").click()

fill() waits for the field to be visible, enabled, and editable before typing, so no manual wait is needed. When you need to trigger key events character by character, use press_sequentially() instead of fill().

Selecting One Element With first, nth, and all

When a locator matches several elements, use first, last, or nth(index) to pick one, and all() to loop over every match. The product list on the TestMu AI eCommerce Playground is a good example:

products = cloud_grid_page.get_by_role("listitem")
products.first.click()          # the first match
products.nth(2).click()         # the third match (nth is zero-based)
print(products.count())         # how many elements matched
for product in products.all():  # iterate over every match
    print(product.text_content())

nth() is zero-based, so nth(0) is the same as first. Use count() to check how many elements a locator found, as the earlier tests did with the to_have_count() assertion.

Locating Elements by CSS Class

A common question is how to locate an element by its CSS class. Pass a standard class selector to page.locator(). The login button above carries the class btn-primary, so either form below finds it:

page.locator(".btn-primary").click()           # locate by class
page.locator("css=input.btn-primary").click()  # explicit css= prefix, same result

Class-based locators are quick, but as the comparison table showed, they are tied to the DOM and break when styling changes. Prefer a role or test-id locator when the class exists only for styling.

Key takeaway: Playwright locator methods include fill() to enter text, click() to click, text_content() to read text, and first, nth, all, and count() to handle multiple matches.

Filtering and Chaining With Playwright Locators

In modern software development, which strongly advocates code reuse and principles like Don’t Repeat Yourself (DRY), there may be instances where we need to refine our results to pinpoint particular elements.

To handle this narrowing down of elements efficiently, Playwright has us covered by providing the ability to filter and chain locators.

Filtering is used to narrow down the search for elements on a web page by specifying additional conditions that must be met. For example, you can use the filter(has_text=) to find an element containing a specific text piece.

Chaining is used to combine multiple locators in a single search. For example, you can use the get_by_text() and get_by_role() locators to find an element with a specific text and a specific role.

Filtering Playwright Locators

Playwright locators can be filtered by text. This search is case-insensitive and can also be done via regular expression. Playwright locators can also be filtered by not having text. For both cases, the method used is the locator.filter().

Filtering by Text

To understand filtering by text, let’s use the LambaTest Selenium Playground website but a different list with a lot of text with the word ‘Table’.

Test Scenario:

  • Locate the list containing the word Table.
  • Ensure the list has five items.
containing the word Table

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_locator_filter_by_text(cloud_grid_page):
    cloud_grid_page.goto(
        "https://www.lambdatest.com/selenium-playground/"
    )
    base_locator = cloud_grid_page.get_by_role("listitem")
    table_list_locator = base_locator.filter(
        has_text=re.compile("table", re.IGNORECASE)
        )    
    expect(table_list_locator).to_have_count(5)

Code Walkthrough:

  • The steps till we set up the base_locator remain the same.
  • From there, instead of using another locator-based filter, we filter based on text=’table’ by passing it to the filter() method.
  • The demo website inspection clearly shows the table list has five items, which is what we assert in the except() method.

Test Execution:

Let’s execute the test using the below command:

pytest -v test_playwright_locators.py::test_locator_filter_by_text.

Filtering by not having Text

To understand filtering by not having text, let’s use the LambaTest Selenium Playground website, which has a nice block containing list items.

Test Scenario:

  • Locate the list containing input forms.
  • Filter and locate the Input Form Submit list item.
containing input forms

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_locator_filter_by_another_locator(cloud_grid_page):
    cloud_grid_page.goto(
        "https://www.lambdatest.com/selenium-playground/"
    )
    base_locator = cloud_grid_page.get_by_role("listitem")
    list_heading_locator = base_locator.filter(
        has=cloud_grid_page.get_by_text(text=re.compile("input form submit", re.IGNORECASE))
        )    
    expect(list_heading_locator).to_have_text('Input Form Submit')

Code Walkthrough:

  • We form the base_locator using the get_by_role() locator and the ARIA role listitem.
  • The base_locator will contain all the lists on the page.
  • We narrow our lookup by calling the filter() method on our base_locator.
  • In the filter, we use the recommended get_by_text() locator and also make sure we handle case sensitivity using regular expressions by searching for the text ‘input for submit’. This filtered locator is called list_heading_locator.
  • On the filtered list_heading_locator, we call the except() assertion and ensure we have only located the exact list item (for input form submission) that we intended to locate.

Test Execution:

Let’s execute the test using the following command:

pytest -v -k “test_locator_filter_by_another_locator”

TestMu AI named a Challenger in the 2025 Gartner Magic Quadrant for AI-Augmented Software Testing Tools

Chaining Playwright Locators

It’s not always possible for a single locator to locate the exact element on a web page. In such scenarios, chaining is the second method to narrow the search to a specific element by combining multiple Playwright locators.

Test Scenario:

  • Locate the HTC Touch HD active breadcrumb on the TestMu AI eCommerce website.
  • Expect it to be visible.
Expect it to be visible.

Implementation:

# replace cloud_grid_page with local_grid_page while running on local
def test_locator_chaining(cloud_grid_page):    
    cloud_grid_page.goto("https://ecommerce-playground.lambdatest.io/index.php?route=product/product&path=18&product_id=28")
    breadcrumb_locator = cloud_grid_page.get_by_label("breadcrumb").get_by_text("HTC Touch HD")    
    expect(breadcrumb_locator).to_be_visible()

Code Walkthrough:

  • The first locator get_by_label(“breadcrumb”) will locate the breadcrumbs section as shown on the top left.
  • The get_by_text(“HTC Touch HD”) will filter out the exact one from the three that are visible.
  • Lastly, the except() assertion checks if the located breadcrumb is visible.

Test Execution:

Let’s execute the test using the following command:

pytest -v -k “test_locator_chaining”.

Having explored the power of filtering and chaining locators in Playwright, it’s essential to understand how selectors play a crucial role in this process. Playwright selectors are the foundational tools that enable precise interactions with web elements. By utilizing various selector types, such as CSS, XPath, and text selectors, you can effectively target elements in a way that complements the filtering and chaining methods we just discussed.

Selectors are vital for optimizing test accuracy and efficiency, ensuring that your tests remain robust even as the complexity of the application grows.

To understand Playwright Selectors better, follow the video given below

Key takeaway: Playwright locator filtering and chaining narrow multiple matches to one element using filter(has_text=...) or chained locators like get_by_role().get_by_text().

Best Practices for Stable and Fast Playwright Locators

The locators you choose decide how often your suite breaks on a harmless UI change and how much time you lose to flaky reruns. These practices keep Playwright tests both resilient and quick.

  • Prefer user-facing locators: reach for get_by_role(), get_by_text(), and get_by_label() before CSS or XPath. They map to what the user sees and survive redesigns that shift the DOM.
  • Add a data-testid for dynamic elements: when text or roles change at runtime, an explicit get_by_test_id() contract is the most stable target.
  • Let auto-wait replace fixed sleeps: never pad tests with time.sleep(). Playwright's actionability checks already wait for the element to be ready, so fixed delays only make suites slower and more brittle.
  • Chain and filter instead of writing long selectors: combine get_by_role() with filter() or a second locator to narrow results, rather than a deep, fragile CSS or XPath path.
  • Keep any CSS or XPath shallow: if you must use them, target a single stable attribute rather than a long nth-child chain that breaks when a wrapper element moves.
  • Scale speed with parallelism, not shorter waits: the fastest way to cut suite runtime is running locators across many browsers at once, not trimming the waits that keep them stable.

That last point is where cloud execution pays off. TestMu AI's Automation Cloud runs your existing Playwright scripts across 3,000+ real browser and OS combinations in parallel, so a locator-heavy suite finishes in minutes instead of hours. It also adds SmartWait, which holds each action until the element passes its actionability checks, and Auto Healing, which reformulates a Playwright locator when the DOM shifts, so locator drift does not turn into failed pipelines. Point an existing suite at the grid using the Playwright testing documentation.

Key takeaway: Playwright locator best practices: prefer user-facing role and text locators, rely on auto-wait instead of fixed sleeps, and run tests in parallel across browsers.

Conclusion

Playwright locators allow you to locate and interact with elements on a web page with the ability to locate elements by their attributes, role, text, label, alt-text, etc. Understanding the locators, filtering, and chaining and how to use them effectively is essential for writing efficient and reliable Playwright tests.

Moreover, the Playwright Test Generator can help you quickly and easily create boilerplate code for locating elements. The time and effort saved can be used to focus on more important tasks like writing resilient tests and improving coverage.

Author

...

Jaydeep Karale

Blogs: 6

  • Twitter
  • Linkedin

Jaydeep is a software engineer with 10 years of experience, most recently developing and supporting applications written in Python. He has extensive with shell scripting and is also an AI/ML enthusiast. He is also a tech educator, creating content on Twitter, YouTube, Instagram, and LinkedIn.

Open in ChatGPT Icon

Open in ChatGPT

Open in Claude Icon

Open in Claude

Open in Perplexity Icon

Open in Perplexity

Open in Grok Icon

Open in Grok

Open in Gemini AI Icon

Open in Gemini AI

Copied to Clipboard!
...

3000+ Browsers. One Platform.

See exactly how your site performs everywhere.

Try it free
...

Write Tests in Plain English with KaneAI

Create, debug, and evolve tests using natural language.

Try for free

Playwright Locators FAQs

Did you find this page helpful?

More Related Blogs

TestMu AI forEnterprise

Get access to solutions built on Enterprise
grade security, privacy, & compliance

  • Advanced access controls
  • Advanced data retention rules
  • Advanced Local Testing
  • Premium Support options
  • Early access to beta features
  • Private Slack Channel
  • Unlimited Manual Accessibility DevTools Tests