Reputation: 254
I'm working with chained requests and need to wait until a condition is met so I can test the response. The prior request will always return a response but I need for its status to be "finished" and sometimes it's "in progress". I don't want to use a static wait for this cy.wait() because that either makes the tests flaky or last forever. How can I do? This is my code so far but it gets stuck and never finishes. With static wait (no loop) it works pretty well.
Any ideas?
it('name of the test', function() {
cy.processFile().then((response) => {
let i=0;
while (i<5){
cy.wait(1000);
cy.getInfo().then((resp) => {
if(resp.body.status !== 'finished'){
i++;
} else {
i = 5;
expect(.....);
}
})
}
})
})
Upvotes: 3
Views: 2541
Reputation: 737
The while (i<5) {
statement is synchronous and it runs through the five iterations before the test even starts.
Instead, this should work
function waitForStatus (status, count = 0) {
if (count === 5) {
throw 'Never finished'
}
return cy.getInfo().then(resp => {
if (resp.body.status !== status) {
cy.wait(1000) // may not need to wait
waitForStatus(status, ++count) // run again, up to 5 times
} else {
return resp // in case you want to expect(resp)...
}
})
}
cy.processFile().then((response) => {
waitForStatus('finished').then(resp => {
expect(resp)...
})
})
There is a more detailed info here Writing a Cypress Recursive Function
Your scenario
npm i -D cypress-recurse
# or use Yarn
yarn add -D cypress-recurse
import { recurse } from 'cypress-recurse'
it('waits for status', () => {
cy.processFile().then((response) => {
recurse(
() => cy.getInfo(),
(resp) => resp.body.status === 'finished',
{
log: true,
limit: 5, // max number of iterations
timeout: 30000, // time limit in ms
delay: 1000 // delay before next iteration, ms
},
)
.then(resp => {
expect(resp)...
})
})
Upvotes: 5