Context:
- Playwright Version: 1.25
- Operating System: Windows 11, Ubuntu 22.04 via WSL2
- Node.js version: 16.16.0
- Browser: All
Code Snippet
import { expect, test } from "@playwright/test";
test("should return false for nonexistent attributes", async ({ page }) => {
await page.setContent(`<div></div>`);
const element = page.locator("div");
// always passes
await expect(element).toHaveAttribute("", "");
// always passes
await expect(element).toHaveAttribute("any-arbitrary-attribute", "");
// always fails, `value` must be a string
await expect(element).not.toHaveAttribute("any-attribute", "");
// always fails (Matcher error: expected value must be a string or regular expression)
await expect(element).not.toHaveAttribute("attr");
// workaround: passes when the attribute is not present
expect(await element.getAttribute("attr")).toBeNull();
await element.evaluate(node => node.toggleAttribute("attr"));
// workaround: this solution checks for the existence of boolean attributes with no value, but doesn't cover every valid boolean attribute situation
expect(await element.getAttribute("attr")).toBe("");
});
Describe the bug
The toHaveAttribute matcher doesn't work as expected with the checks above, since await expect(element).toHaveAttribute("anything", "") will always pass. Likewise, await expect(element).not.toHaveAttribute("anything", "") will always fail for any attribute when used as a check for the presence of attributes. In our case, this primarily affects the use of boolean attributes like checked, disabled, hidden, open, which are considered true when they're present, regardless of value.
I think the value parameter for toHaveAttribute could be made optional, which would allow checking for the existence of attributes. The always-failing not.toHaveAttribute matcher would then be able to pass. This may also help to address #16270, though boolean attributes likely would need their own logic to match the allowed validity rules described in this MDN article.
Context:
Code Snippet
Describe the bug
The
toHaveAttributematcher doesn't work as expected with the checks above, sinceawait expect(element).toHaveAttribute("anything", "")will always pass. Likewise,await expect(element).not.toHaveAttribute("anything", "")will always fail for any attribute when used as a check for the presence of attributes. In our case, this primarily affects the use of boolean attributes likechecked,disabled,hidden,open, which are consideredtruewhen they're present, regardless of value.I think the
valueparameter fortoHaveAttributecould be made optional, which would allow checking for the existence of attributes. The always-failingnot.toHaveAttributematcher would then be able to pass. This may also help to address #16270, though boolean attributes likely would need their own logic to match the allowed validity rules described in this MDN article.