Reputation: 55
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)
}
})
}
})
})
Upvotes: 4
Views: 177
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
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