Sunday, April 6, 2025

Playwright built-in locators

Locators are the central piece of Playwright's auto-waiting and retry-ability. In a nutshell, locators represent a way to find element(s) on the page at any moment. ​Playwright is a robust automation framework for web applications, offering a variety of locator strategies to interact with web elements effectively. Utilizing the appropriate locator methods enhances test reliability and maintainability.

Playwright built-in locators


Various build-in locators :


These are the recommended built-in locators.

  1. page.getByRole() to locate by explicit and implicit accessibility attributes.
  2. page.getByText() to locate by text content.
  3. page.getByLabel() to locate a form control by associated label's text.
  4. page.getByPlaceholder() to locate an input by placeholder.
  5. page.getByAltText() to locate an element, usually image, by its text alternative.
  6. page.getByTitle() to locate an element by its title attribute.
  7. page.getByTestId() to locate an element based on its data-testid attribute (other attributes can be configured).


1. page.getByRole()

Targets elements based on their ARIA role. The page.getByRole() locator reflects how users and assistive technology perceive the page, for example whether some element is a button or a checkbox. When locating by role, you should usually pass the accessible name as well, so that the locator pinpoints the exact element.

For example, consider the following DOM structure.

page.getByRole()


You can locate each element by its implicit role:

await expect(page.getByRole('heading', { name: 'Sign up' })).toBeVisible();

await page.getByRole('checkbox', { name: 'Subscribe' }).check();

await page.getByRole('button', { name: /submit/i }).click();

Role locators include buttons, checkboxes, headings, links, lists, tables, and many more and follow W3C specifications for ARIA role, ARIA attributes and accessible name. Note that many html elements like <button> have an implicitly defined role that is recognized by the role locator.

Note that role locators do not replace accessibility audits and conformance tests, but rather give early feedback about the ARIA guidelines.


2. page.getByText()

Finds elements containing specific text. Find an element by the text it contains. You can match by a substring, exact string, or a regular expression when using page.getByText().

For example, consider the following DOM structure.

page.getByText()

You can locate the element by the text it contains:

await expect(page.getByText('Welcome, John')).toBeVisible();


Set an exact match:

await expect(page.getByText('Welcome, John', { exact: true })).toBeVisible();


Match with a regular expression:

await expect(page.getByText(/welcome, [A-Za-z]+$/i)).toBeVisible();
You can also filter by text which can be useful when trying to find a particular item in a list.


3. page.getByLabel()

Targets form elements associated with a label. Most form controls usually have dedicated labels that could be conveniently used to interact with the form. In this case, you can locate the control by its associated label using page.getByLabel().

For example, consider the following DOM structure.

page.getByLabel()


You can fill the input after locating it by the label text:

await page.getByLabel('Password').fill('secret');


4. page.getByPlaceholder() 

Finds input elements by their placeholder text. Inputs may have a placeholder attribute to hint to the user what value should be entered. You can locate such an input using page.getByPlaceholder().

For example, consider the following DOM structure.

page.getByPlaceholder()

You can fill the input after locating it by the placeholder text:

await page
    .getByPlaceholder('name@example.com')
    .fill('playwright@microsoft.com');


5. page.getByAltText()

Locates images using the alt attribute. All images should have an alt attribute that describes the image. You can locate an image based on the text alternative using page.getByAltText().

For example, consider the following DOM structure.

page.getByAltText()

You can click on the image after locating it by the text alternative:

await page.getByAltText('playwright logo').click();

6. page.getByTitle()

Selects elements based on the title attribute. Locate an element with a matching title attribute using page.getByTitle().

For example, consider the following DOM structure.

page.getByTitle()

You can check the issues count after locating it by the title text:

await expect(page.getByTitle('Issues count')).toHaveText('25 issues');


NOTE : Use this locator when your element has the title attribute.


7. page.getByTestId()

selecting elements based on attributes like data-testid. Testing by test ids is the most resilient way of testing as even if your text or role of the attribute changes, the test will still pass. QA's and developers should define explicit test ids and query them with page.getByTestId(). However testing by test ids is not user facing. If the role or text value is important to you then consider using user facing locators such as role and text locators.

For example, consider the following DOM structure.

page.getByTestId()


You can locate the element by its test id:

await page.getByTestId('directions').click();

Set a custom test id attribute

By default, page.getByTestId() will locate elements based on the data-testid attribute, but you can configure it in your test config or by calling selectors.setTestIdAttribute().

Set the test id to use a custom data attribute for your tests.

playwright.config.ts

import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    testIdAttribute: 'data-pw'
  }
});


In your html you can now use data-pw as your test id instead of the default data-testid.

page.getByTestId()

And then locate the element as you would normally do:

await page.getByTestId('directions').click();

By following these practices, you can effectively select elements in Playwright and create robust, maintainable tests.


1 comment:

  1. Thanks for the detailed information about playwright locators.

    ReplyDelete