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.
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.
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.
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.