Visible elements

📺 Watch this recipe explained at How To Check Visibility Of Many Elementsopen in new window.

At least one is visible

The built-in .should('be.visible') assertion passes if any of the elements are visible.

<ul id="items">
  <li>One</li>
  <li style="display:none">Two</li>
  <li>Three</li>
</ul>
// PASSES even when 1 out of 3 elements is invisible
cy.get('#items li').should('be.visible')

On the other hand, the assertion .should('not.be.visible') requires all elements to be invisible

// FAILS because 2 out of 3 elements ARE visible
cy.get('#items li').and('not.be.visible')

Check visibility of every element

<ul id="items">
  <li>One</li>
  <li style="display:none">Two</li>
  <li>Three</li>
</ul>

Let's compute visibility of every element using built-in Cypress.dom.isVisibleopen in new window method:

// FAILS because the middle element has visibility false
cy.get('#items li')
  .then(($el) => Cypress._.map($el, Cypress.dom.isVisible))
  .should('deep.equal', [true, true, true])
// let's confirm each element's visibility
cy.get('#items li')
  .then(($el) => Cypress._.map($el, Cypress.dom.isVisible))
  .should('deep.equal', [true, false, true])

With retries using cypress-map

Unfortunately, because of cy.then command, the above snippet does not retry. A better solution would be to use Cypress queries. For example, you could use cypress-mapopen in new window

<ul id="items">
  <li>One</li>
  <li style="display:none">Two</li>
  <li>Three</li>
</ul>
<script>
  setTimeout(() => {
    document
      .querySelector('#items li:nth-child(2)')
      .setAttribute('style', '')
  }, 1500)
</script>
cy.get('#items li')
  .map(Cypress.dom.isVisible)
  .should('deep.equal', [true, true, true])

Using cypress-map and chai-each plugins

To simplify check that each item in the visibility array is true, you can use the Chai plugin chai-each

<ul id="items">
  <li>One</li>
  <li style="display:none">Two</li>
  <li>Three</li>
</ul>
<script>
  setTimeout(() => {
    document
      .querySelector('#items li:nth-child(2)')
      .setAttribute('style', '')
  }, 1500)
</script>

In your support file, load and register the chai-each plugin

// https://www.chaijs.com/plugins/chai-each/
chai.use(require('chai-each'))

Use the each.equal assertion to make sure that every element of the visibility array is true.

cy.get('#items li')
  .map(Cypress.dom.isVisible)
  .should('each.equal', true)