playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature] Add locator.hasAttribute()

Open azad-derakhshani-GS opened this issue 2 years ago • 7 comments

There is this function element.hasAttribute but apparently it doesn't exist in the PW framework.
This would be very useful to have as there are cases where we need to check if a certain attribute is present (not its actual value as it doesn't have a value).

So it would be great if we could add locator.HasAttribute() similar to the already existing locator.getAttribute().

azad-derakhshani-GS avatar Aug 04 '22 20:08 azad-derakhshani-GS

This would be great to have built-in. As a workaround, this can be handled by adding a matcher extension:

// playwright.config.ts

expect.extend({
    async hasAttribute(recieved: Locator, attribute: string) {
        const pass = await recieved.evaluate(
            (node, attribute) => node.hasAttribute(attribute),
            attribute
        );

        return {
            message: () => `expected ${recieved} to have attribute \`${attribute}\``,
            pass,
        };
    },
});
// global.d.ts

declare global {
    namespace PlaywrightTest {
        interface Matchers<R> {
            hasAttribute(a: string): Promise<R>;
        }
    }
}

export {};

Then it works like this:

test("should have the `disabled` attribute", async ({ page }) => {
    await page.setContent("<div disabled></div>");
    const element = page.locator("div");

    await expect(element).hasAttribute("disabled");

    await expect(element).not.hasAttribute("tabindex");
});

radium-v avatar Aug 12 '22 23:08 radium-v

Awesome, thank you I'll try that! @radium-v One of my next tasks was to add custom assertions anyway, so this is a good place to get started.
I tried adding the custom assertion now, however it doesn't seem to work. Can you tell me where the global.d.ts should be placed? It didn't exist yet anywhere (not even in node_modules) so I created it in the PW root folder.

That said, this GitHub issue is not about expect assertions but rather about a locator accessor locator.HasAttribute() that returns a boolean value (expect doesn't return anything), so hopefully this feature makes it into the PW codebase some day. 🤞

azad-derakhshani-GS avatar Aug 16 '22 21:08 azad-derakhshani-GS

This is specially painful at using Qwik for testing the framework rendering!

manucorporat avatar Oct 04 '22 08:10 manucorporat

@radium-v your workaround looks great, but I can't get it to work.

I have put your code into my playwright.global.ts, but when running the tests, I get this:

josua@Josuas-M1 adg-combobox % npm run test:run

> [email protected] test:run
> playwright test

ReferenceError: expect is not defined
    at Object.<anonymous> (/Users/josua/Documents/Work/AccessifyMe/Kunden/ETH/adg-combobox/playwright.config.ts:111:1)

I also don't have a global.d.ts file.

jmuheim avatar Nov 05 '22 16:11 jmuheim

Another pain point that this would solve is that when using .getAttribute('disabled') on a button with the disabled attr returns an empty string, but hasAttribute('disabled') returns true. The work around is awkward right now to find that.

JamieVaughn avatar Mar 13 '23 03:03 JamieVaughn

the hasAttrbute feature is much needed! - because sometimes I wanna check if the attribute even exist in an if statement to assert something else based on that condition! I hope this will get released soon!

Romarionijim avatar Dec 23 '23 11:12 Romarionijim

You know those password visibility toggles? I need it for that.

frattaro avatar Apr 24 '24 18:04 frattaro