'Playwright: how to test that an element does not have a `hidden` attribute?

I need to check whether an element on my website has the hidden attribute. But this element is inside a container that can be hidden itself:

<div class="container"><!-- Can have `hidden` attribute, too! -->
  <ul>
    <li hidden>Item 1</li>
    <li>Item 2</li>
  </ul>
</div>

This makes it impossible to use toBeVisible() or not.toBeVisible(). So I tried not.toHaveAttribute().

The following does not work:

await expect(listItem).not.toHaveAttribute('hidden') // Expects value argument

Neither does:

await expect(listItem).not.toHaveAttribute('hidden', '') // Expected string: not "", Received string: ""

This seems wrong to me, because as there is no hidden attribute at all, I would not expect this to result its value in "".

I'm doing it in a different way now:

await expect(list.locator('li:not([hidden])')).toHaveCount(1)

But this feels ugly to me. Any suggestions on how to make not.toHaveAttribute() work?



Solution 1:[1]

UPDATED:

There is no built-in assertion for such a case. However, you can use the getAttribute method to get the hidden attribute and then verify it is not equal to the null.

test('container and element are hidden', async ({ page }) => {
  await page.setContent(`
    <div class="container" hidden>
      <ul>
        <li hidden>Item 1</li>
        <li>Item 2</li>
      </ul>
    </div>
  `);
  const hidden = await page.locator('li').first().getAttribute('hidden');

  expect(hidden).not.toBeNull() // ? Passed
});
test('element is hidden', async ({ page }) => {
  await page.setContent(`
    <div class="container">
      <ul>
        <li hidden>Item 1</li>
        <li>Item 2</li>
      </ul>
    </div>
  `);
  const hidden = await page.locator('li').first().getAttribute('hidden');

  expect(hidden).not.toBeNull() // ? Passed
});
test('element is not hidden', async ({ page }) => {
  await page.setContent(`
    <div class="container">
      <ul>
        <li hidden>Item 1</li>
        <li>Item 2</li>
      </ul>
    </div>
  `);
  // Getting attribute of element that doesn't have hidden attribute. We will receive null
  const hidden = await page.locator('li').last().getAttribute('hidden');

  expect(hidden).not.toBeNull() // ? Failed
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1