Search code examples
automationcypress

Cypress - How do I wait to select dropdown to load all options?


cy.get("#severities").then(($optionsArray) => {
           expect($optionsArray.get(0)).to.have.property('childElementCount', 6) 
       let optionVal = new Array()
       optionVal = $optionsArray.children()
       var randomChoice = optionVal[Math.floor(Math.random() * optionVal.length) + 1]
       addAppointment.selectSeverity(randomChoice.text)
       })

The expect assert will fail because not all options are loaded.

  • expected '<select#severities.form-control>' to have property 'childElementCount' of 7, but got 1

Is there any way to do it with cypress? if not, then with jQuery?


Solution

  • To wait for options to load, insert a .should() between the .get() and the .then(). Or perhaps even changing .then() to .should() will do the trick.

    The key thing with .should() is that it retires the preceding command until it's criteria succeed, so it's ideal for waiting for async data.

    So

    cy.get("#severities")
      .should(($optionsArray) => {
         expect($optionsArray.get(0)).to.have.property('childElementCount', 6)
       })
    

    will keep re-getting #severities and refreshing $optionsArray until the expect() succeeds, or timeout occurs.

    I would separate the part that waits from the part that processes, like this

    cy.get("#severities")
      .should($optionsArray => {
         expect($optionsArray.get(0)).to.have.property('childElementCount', 6)
       })
      .then($optionsArray => {
         let optionVal = new Array()
         optionVal = $optionsArray.children()
         var randomChoice = optionVal[Math.floor(Math.random() * optionVal.length) + 1]
         addAppointment.selectSeverity(randomChoice.text)
      });
    

    For reference

    Timeouts
    .should() will continue to retry its specified assertions until it times out.

    cy.get('input', { timeout: 10000 }).should('have.value', '10')
    // timeout here will be passed down to the '.should()'
    // and it will retry for up to 10 secs
    
    
    cy.get('input', { timeout: 10000 }).should(($input) => {
      // timeout here will be passed down to the '.should()'
      // unless an assertion throws earlier,
      // ALL of the assertions will retry for up to 10 secs
      expect($input).to.not.be('disabled')
      expect($input).to.not.have.class('error')
      expect($input).to.have.value('US')
    })