Michael
Michael

Reputation: 55

Why added value en each loop hasn't been stored on next iteration?

Brief logic is the next: after clicking on 'li' element, request is sent, and based on response value of 'contacts', it should select if it's greater than 0, once such element is find, i need to break each loop. But currently, despite I set value, which should break each loop on next iteration (returns false). count[] has been restored with old values, what's an issue?

    cy.get('div[id=company_select]').then($el => {

        const count = []
        cy.wrap($el).click().find('li').each((element, index) => {
            cy.intercept('GET', '**/company/view-json**').as('getCompanyProps')

            cy.log(count.length)
            if (count.length > 0) {
                return false
            } else {
                cy.wrap(element).click().wait('@getCompanyProps').then((interception) => {
                    if (interception.response.body.contacts.length === 0) {
                        cy.wrap($el).find('button[vs__clear]').click()
                    } else {
                        count.push(1)
                        cy.log(count.length)
                    }
                })
            }
        })

    })

cy log

Upvotes: 4

Views: 177

Answers (2)

Black Cat Coding
Black Cat Coding

Reputation: 79

If I understand your question correctly, you wish to know why on the second pass of your cypress each loop cy.wrap($el).click().find('li').each((element, index) => { the cy.log(count.length) is equal to 0.

Even though further down inside another then loop cy.wrap(element).click().wait('@getCompanyProps').then((interception) => { you increase count by count.push(1) and right after cy.log(count.length) which returns 1.

The short answer is scope. If you change a variable within a cypress loop to return that variable you need to add something like this after .then( () =>{ cy.wrap(count)} My solution is below but I also changed the position of your const count = [] if you want to know why I suggest reading What is the difference between 'let' and 'const' ECMAScript 2015 (ES6)?

const count = []
cy.intercept('GET', '**/company/view-json**').as('getCompanyProps')
cy.get('div[id="company_select"]')
.then( ($el) => {
  cy.wrap($el)
  .click()
  .find('li')
  .each( ($el) => {
    if (count.length === 0){
        cy.wrap($el)
        .click()
        .wait('@getCompanyProps')
        .then((interception) => {
            if (interception.response.body.contacts.length === 0) {
            cy.wrap($el)
            .find('button[vs__clear]')
            .click()
            } else {
            count.push(1)
            cy.log(count.length)
            }
          })
        }
      })
      .then( () =>{
        cy.wrap(count).as('count')
    })
})
cy.get('@count')
.then( (count) =>{
  cy.log(count.length)
})

Upvotes: 0

Fody
Fody

Reputation: 32034

You can't early-exit with return false in this scenario, but you can use count to prevent inner execution after body.contacts.length > 0.

cy.intercept('GET', '**/company/view-json**').as('getCompanyProps') // this can be here

cy.get('div[id=company_select]').then($el => {

  const count = []
  cy.wrap(count).as('count')   // make an alias value of the count variable

  cy.wrap($el).click().find('li')
    .each((element, index) => {

      cy.get('@count').then(count => {  // retrieve count asynchronously
        if (count.length === 0) {       // no result yet?
                
          cy.wrap(element).click().wait('@getCompanyProps')
            .then((interception) => {
              if (interception.response.body.contacts.length === 0) {
                cy.wrap($el).find('button[vs__clear]').click()
              } else {
                count.push(1)
                console.log(count.length)
              }
            })
        }
      })
    })
})

The reason for this behaviour is the mixture of asynchronous commands like .wait('@getCompanyProps') and synchronous code for checking the early exit.

If you use console.log() instead of cy.log() to debug the values, you'll see the logs before the early exit all run before the logs after count.push(1).

Upvotes: 6

Related Questions