Sponsored Link
Looking for a unified way to  viewmonitor, and  debug Playwright Test Automation runs?
Try the Playwright Dashboard by today. Use the coupon code PWSOL10 for a 12 month 10% discount.

Utilizing the toHaveAttribute() method when making assertions in Playwright to check if a button is enabled or disabled.

Often when testing on the UI layer, you may want to validate a button or an element is in a certain state based on the users actions. A common scenario that I have faced is signing in, filling out address information, or entering credit card details. You don't want to give the user a chance to hit the submit button unitl required fields have some values in them, and typically these buttons will be disabled.

Example of a Payment Screen

In these scenarios I've found it helpful to build out tests that validates that certain buttons are properly in a disabled (non clickable state).

Below is a basic example via code pen, that we will write an automated test against.

CodePen showing off a disabled button until text is entered.

For the assertions we will be using the toHaveAttribute() method.

expect({locator}).toHaveAttribute("{name}", "{value}")

The locator in our example will be the button we want to check to see if it's disabled, the attribute name will be "disabled", and the value will be "true". Depending on how the disabled attribute is implemented in the site you are testing it's possible that disabled will just be an attribute without a value, if that's the case, the value is actually an empty string.

// If the dom looks like this 
<button class="button" disabled>Click Me</button>

expect({locator}).toHaveAttribute("disabled", "") 

// If the dom looks like this 
<button class="button" disabled="true">Click Me</button>

expect({locator}).toHaveAttribute("disabled", "true") 

Now let's take a look at a complete script. Note since we are using CodePen, in order to interact with the html elements genereted from our code, we will need to look into the iFrame with name "CodePen", all elements will be here. You'll aslo note in my example I've created variables for the elements we wnat to interact with, these could easily be added to a Page Object if we wanted to create multiple scenarios.

import { test, expect } from "@playwright/test";

test("test", async ({ page }) => {
  await page.goto("https://codepen.io/bmayhew/pen/eYLdwVg");

  // Create variables for the elements we will interact with
  const codePenFrame = page.frameLocator('iframe[name="CodePen"]');
  const textInput = codePenFrame.getByPlaceholder("fill me");
  const button = codePenFrame.getByRole("button", { name: "Click Me" });
  const result = codePenFrame.locator("id=result");

  // Disabled attribute is active
  expect(button).toHaveAttribute("disabled", "true");

  await textInput.fill("Testing 1234");
  await page.keyboard.press("Tab");

  // Disabled attribute is no longer active
  expect(button).not.toHaveAttribute("disabled", "true");

  await button.click();
  expect(result).toHaveText("You clicked the button");

Below is a link to the docs on the locator assertions, as there are many other ways to validate elements within the DOM.

LocatorAssertions | Playwright
The [LocatorAssertions] class provides assertion methods that can be used to make assertions about the [Locator] state in the tests.

Thanks for reading! If you found this helpful, reach out and let me know on LinkedIn or consider buying me a cup of coffee. If you want more content delivered to you in your inbox subscribe below.