Vicko
Vicko

Reputation: 254

How to repeat a request until getting a different response in Cypress

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

Answers (1)

Visal
Visal

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

Related Questions