How to Get an Element’s Attribute in Playwright

Playwright helps you access element attributes during automated tests. Learn the syntax, language examples, assertions, and how to handle missing values.

Last updated: 28 July 2026 9 min read

Key Takeaways

  • Locator.getAttribute() reads an attribute from the matched element, while toHaveAttribute() checks whether that attribute has the expected value.
  • Use Locator.getAttribute() when you need to store, log, compare, or reuse an attribute value in your test.
  • Handle missing attributes and dynamic UI states by checking for null, using specific locators, and avoiding unstable attributes such as generated class names.

Retrieving an element’s attribute is a common part of Playwright testing. You may need to check an element’s `id`, `class`, `href`, `src`, ARIA label, or a custom `data-*` attribute before interacting with it or making an assertion.

Playwright gives you a few straightforward ways to read these values, most often through the Locator API. Once you know which method to use, you can verify UI states, inspect dynamic content, and make your tests easier to debug and maintain.

By the end of this article, you will know how to retrieve attributes in JavaScript, TypeScript, Python, and Java, check them in assertions, and handle cases where an attribute may be missing.

What does it mean to get an element’s attribute in Playwright?

In Playwright, getting an element’s attribute refers to extracting the value of a specific attribute for a given element in the DOM. This can be crucial for assertions, verifying UI states, and debugging tests. Playwright provides robust methods to handle this, ensuring that you can interact with and validate the state of web elements efficiently.

Understanding Locator.getAttribute and ElementHandle.getAttribute

Playwright provides two primary methods to get an element’s attribute: Locator.getAttribute and ElementHandle.getAttribute.

  • Locator.getAttribute: Works with Playwright’s Locator API and is the recommended approach for locating elements in modern test automation. It returns the value of the specified attribute from the matching element.
  • ElementHandle.getAttribute: This method is used when you have an ElementHandle object, which directly represents a DOM element. You call this method on an existing element handle to fetch the value of its attribute.

Playwright getAttribute() Syntax and Examples

The basic syntax is:

locator.getAttribute(attributeName)

You first create a locator for the element, then pass the name of the attribute you want to retrieve.

JavaScript and TypeScript

Use getAttribute() with the attribute name:

const src = await page.locator('img').getAttribute('src');



console.log(src);

This returns the value of the image’s src attribute. If the attribute does not exist, the result is null.

You can also store the locator first when you plan to reuse it:

const submitButton = page.locator('button[type="submit"]');

const ariaLabel = await submitButton.getAttribute('aria-label');


console.log(ariaLabel);

Python

In Python, the equivalent method is get_attribute():

placeholder = page.locator('input[type="text"]').get_attribute('placeholder')


print(placeholder)

When using Playwright’s asynchronous Python API, add await:

placeholder = await page.locator('input[type="text"]').get_attribute('placeholder')


print(placeholder)

The method returns None when the attribute is missing.

Java

In Java, use getAttribute() on the locator:

String placeholder = page

    .locator("input[name='email']")

    .getAttribute("placeholder");


System.out.println(placeholder);

The method returns null if the selected element does not contain the requested attribute.

Across all three languages, make sure your locator points to the correct element before reading the attribute. A broad selector may match a different element than you expect, especially when several similar elements appear on the page.

Extracting attributes from multiple elements at once

When a locator matches several elements, you can loop through them and retrieve the same attribute from each one.

const links = page.locator('a');

const count = await links.count();


for (let i = 0; i < count; i++) {

  const href = await links.nth(i).getAttribute('href');

  console.log(href);

}

This example gets the href value from every link on the page.

You can also collect the values in an array:

const links = page.locator('a');

const hrefs = [];



for (let i = 0; i < await links.count(); i++) {

  hrefs.push(await links.nth(i).getAttribute('href'));

}



console.log(hrefs);

If an element does not have the requested attribute, Playwright adds null for that element. You may need to filter those values before using the result.

const validHrefs = hrefs.filter(href => href !== null);

This approach works well when you need to validate a group of links, image sources, test IDs, or ARIA attributes.

Using attributes in assertions (toHaveAttribute) and validation

One of the most common use cases for getting an element’s attribute is to assert that an element has the correct attribute value. Playwright provides built-in assertions like toHaveAttribute to make this process easier.

await page.locator(‘button’).first().toHaveAttribute(‘aria-label’, ‘Submit’);

This assertion checks if the first button on the page has the expected aria-label value of “Submit.” It’s a powerful way to ensure that the web elements behave as expected during your automated tests.

Common Mistakes When Retrieving Attributes and How to Avoid them

Attribute checks often fail because the locator is too broad, the attribute is missing, or the test is reading the wrong type of value. The following cases are worth checking before you treat an attribute result as reliable.

1. Assuming the attribute is always present

getAttribute() returns null when the selected element does not contain the requested attribute. This can happen when the attribute is optional, added after a user action, or only present in certain UI states.

Check the result before passing it to another function or comparing it as a string.

const link = page.locator('a.download-link');

const href = await link.getAttribute('href');


if (href === null) {

  throw new Error('The download link does not have an href attribute');

}


console.log(href);

2. Using a locator that matches several elements

A broad locator such as page.locator(‘a’) may match dozens of elements. Before retrieving an attribute, narrow the locator to the element you actually want.

In this example, the locator targets the first link inside the main navigation rather than the first link on the entire page.

const navLink = page.locator('nav[aria-label="Main"] a').first();

const href = await navLink.getAttribute('href');


console.log(href);

When you expect a single match, you can also verify the locator count before reading the attribute.

const submitButton = page.getByRole('button', { name: 'Submit' });


await expect(submitButton).toHaveCount(1);


const buttonType = await submitButton.getAttribute('type');

3. Using getAttribute() when you only need an assertion

When the purpose of the test is to verify an attribute value, use toHaveAttribute() instead of retrieving the value and comparing it manually.

Playwright will wait for the attribute to reach the expected value, which is useful when the UI updates asynchronously.

const submitButton = page.getByRole('button', { name: 'Submit' });


await expect(submitButton).toHaveAttribute(

  'aria-label',

  'Submit form'

);

Use getAttribute() when you need to store, transform, log, or reuse the value elsewhere in the test.

4. Confusing an HTML attribute with the current DOM value

An element’s attribute does not always reflect its current state. For example, the value attribute may contain the input’s initial value, while the user may have already entered different text.

Use inputValue() when you need the value currently shown in an input.

const emailInput = page.getByLabel('Email address');


await emailInput.fill('user@example.com');


const currentValue = await emailInput.inputValue();


expect(currentValue).toBe('user@example.com');

The same distinction applies to other element states. Depending on what you need, methods such as isChecked(), isDisabled(), or textContent() may be more suitable than getAttribute().

5. Treating CSS classes as stable test data

Class names often change during redesigns, refactoring, or CSS build updates. Reading a class attribute can be useful when the class itself is the subject of the test, but it should not usually be your main way of locating an element.

Prefer roles, labels, visible names, or stable test IDs.

const saveButton = page.getByRole('button', { name: 'Save changes' });


await expect(saveButton).toHaveAttribute('data-state', 'ready');

This keeps the test focused on behaviour and stable UI contracts rather than implementation details.

Maintenance and Refactoring of Attribute-Based Locators and Checks

As web applications evolve, so do their elements, attributes, and structures. Over time, the attributes you rely on for locating elements may change, or new attributes may be added. It’s crucial to maintain and refactor your attribute-based locators to ensure your tests remain stable and accurate.

To streamline this process and avoid frequent test failures, consider the following approaches:

  • Use the Page Object Model (POM): Centralizing locators in a Page Object Model (POM) helps isolate changes to a single location. This design pattern encourages modular test code and reduces the risk of having to update locators in multiple places across your test suite. When an element’s attribute changes, you only need to update it in the Page Object, rather than across every test that interacts with that element.
  • Adopt Dynamic Locators: Web applications are often dynamic, and hardcoded locators may become outdated as attributes or structures change. Where possible, opt for more flexible locators that can adapt to minor changes in the UI. For instance, use attribute selectors like data-* attributes or ARIA attributes, which are less likely to change during refactoring or redesigns.
  • Version Control for UI Changes: Collaborate with the development team to stay informed about UI changes, especially those that affect attributes. If you’re aware of upcoming changes, you can proactively adjust your locators before they break your tests.
  • Regularly Review and Update Tests: Just as the UI evolves, so should your test suite. Regularly review and refactor tests to ensure they reflect the current state of the application. Periodic audits of locators help you identify obsolete or fragile selectors before they become a problem.

Conclusion

Use Locator.getAttribute() when you need to read and reuse an attribute value, and toHaveAttribute() when the test only needs to verify it. Keep your locators specific, account for null when an attribute may be missing, and use methods such as inputValue() when you need the element’s current state rather than its original HTML attribute.

Version History

  1. Jul 28, 2026 Current Version

    Revamped the article with updated information, deeper technical insights, and practical examples to make the content more useful and remove generic AI-style explanations.

    Rushabh Shroff
    Reviewed by Rushabh Shroff Lead - Software Development Engineer
Tags
Playwright
Yashraj Shrivastava
Yashraj Shrivastava

Product Manager

Yashraj Shrivastava is a Product Manage with 7+ years of experience in test automation, software quality, and product development. He writes about automation testing, QA best practices, and strategies for building reliable release pipelines.

Are attribute checks failing?
Run tests on real devices to catch browser-specific issues.