How to assert a HTML element is valid link in Playwright?

I'm trying to do some assertions in Playwright. I need to assert that in a list of links <a> all of them have the attribute href. However, I don't know how to achieve that with Playwright functions.

My code is here:

test.only('then a list of 44 links is displayed', async({ page }) => {
         const linkList = await page.locator('div#content > ul > li > a');
         for(let i = 0; i < await linkList.count(); i++) {
             expect(await linkList.nth(i)).toHaveAttribute('href', '');             }
         await expect(linkList).toHaveCount(44);
    })

toHaveAttribute() function need 2 to 3 arguments because it get the key attribute and the value of the attribute, but I need just to check if it has the href attr.

How can I achieve that?

This is the website being tested: https://the-internet.herokuapp.com/

Upvotes: 7

Views: 10213

Answers (2)

Johnny Magrippis
Johnny Magrippis

Reputation: 729

It feels like Playwright isn't the best tool for this! Feels like it'd be better done by linting if the links are in your version control, or ensuring your database query only fetches rows with a valid href to begin with.

Much faster to catch the problem than any browser test, and would keep things dynamic so you don't have to amend the test when you add or remove a link.


However, if you do want to do it with Playwright, with less code than the other suggestion, and to generate good habits for great tests for accessibility, you can do it with a .getByRole selector.

Anchor elements with an href have the "link" role, without they are "generic":

https://www.w3.org/TR/html-aria/#docconformance

Using the byRole locators helps ensure you've got semantically correct & accessible elements:

https://playwright.dev/docs/locators#locate-by-role

In this case, anchor tags that actually have hrefs!

So you could do something like:

await expect(page.getByRole('link')).toHaveCount(44);

Instead of querying the whole page, you'd probably chain another locator, so you only query within the section you're interested in.

Upvotes: 0

After trying some options, I realize that I can assert if when using Locator.getAttribute('href') does not return null, so that's a link. So I implemented that:

const linkList = await page.locator('div#content > ul > li > a');
for(let i = 0; i < await linkList.count(); i++) {
    expect(await linkList.nth(i).getAttribute('href')).not.toBeNull();
}

Upvotes: 4

Related Questions