How to get cypress to return children length of 0 when there isnt any children

Viewed 1495

So I am writing a test that will add a card to a container(payment-card-container) and I want to confirm an element was added later by seeing if the children have increased by 1. But I am having issues when we try to count the children length when there isnt any. I am currently using the below:

cy.get('[data-test-id="payment-card-container"]')
    .children()
    .its('length')
    .then(length => {
        const childrenLength = length;
    })

But Cypress seems to get an error because it cant find the children (Error below).

Timed out retrying: Expected to find element: ``, but never found it.

Is there a way this can work when there isnt any children and it returns the value of 0?

2 Answers

The problem with using a jQuery expression like

Cypress.$('[data-test-id="payment-card-container"]').children().length

is you don't get the Cypress retry for async updates.

If adding a payment card calls an API, the above expression will falsely report 0 children instead of waiting for the DOM to update.

There's really no good way to handle the no-cards situation,

Except

  • set up your test scenario such that there are no cards initially
  • add a card
  • confirm that there is now exactly one card

If you must test for zero children, a trailing .should() will remove the error message.

cy.get('[data-test-id="payment-card-container"]')
  .children()
  .should('have.length', 0);   // no error when should expression passes

// Add card here

cy.get('[data-test-id="payment-card-container"]')
  .children()
  .should('have.length', 1);   // waits for async add-card operation

Tested with

<body>

  <div data-test-id="payment-card-container"></div>

  <script>
    setTimeout(() => {
      const div = document.querySelector('[data-test-id="payment-card-container"]');
      const p = document.createElement('p')
      div.appendChild(p)
    }, 2000)
  </script>

</body>

One hacky way that I could think of is this. You can use the jQuery length and children() property to check the length:

cy.get('body').then(() = > {

    if (Cypress.$('[data-test-id="payment-card-container"]').children().length == 0) {
        //Do Something
    }
    else {
        //Do Something
    }
})
Related