Home > other >  wait for API request to complete in Cypress
wait for API request to complete in Cypress

Time:03-29

I know how to wait for requests sent by application under test - using interception and alias and wait for this alias.

But how to wait for request issued by cy.request()?

I can assign an alias to it:

cy.request('POST', '/Sessions', USER_CREDENTIALS_ADMIN).as('login').then(response => {
    ....
});
cy.wait('@login');

But then I have error:

cy.wait() only accepts aliases for routes. The alias: login did not match a route.

Without cy.wait('@login'); it does what is expected (logins user).

CodePudding user response:

I think the best way to achieve something like this would be to add it as a custom command, and have that command be chainable.

Cypress.Commands.add('requestSessions', () => {
  return cy.request(...).then((res) => {...});
});

If you're declaring your custom commands in the Cypress namespace, you can leave off a return type.

declare global {
  namespace Cypress {
    interface Chainable {
      requestSessions();
    }
  }
}

You should be able to simply use the function in a Cypress chain and have Cypress wait for the command to finish before continuing.

cy.requestSessions()
  .visit('/foo');

CodePudding user response:

Cypress automatically waits for a cy.request() to complete.

Using deelay.me to fake a slow request

it('Cypress waits for request to complete', () => {
  
  // delay request response by 3 seconds
  cy.request('https://deelay.me/3000/https://jsonplaceholder.typicode.com/todos/1')
    .then(() => console.log('Request complete'))

  cy.visit('http://example.com', {
    onBeforeLoad: () => console.log('Before visit')
  })
})

Logs:

  • Request complete ✅
  • Before visit

However, if I have some asynchronous processing on the result of the request, it does not wait

it('Cypress waits for request to complete', () => {
  
  cy.request('https://deelay.me/3000/https://jsonplaceholder.typicode.com/todos/1')
    .then(() => {
      setTimeout(() => console.log('Timeout complete'), 2000)
    })
    .then(() => console.log('Request complete'))

  cy.visit('http://example.com', {
    onBeforeLoad: () => console.log('Before visit')
  })
})

Logs:

  • Request complete
  • Before visit
  • Timeout complete ❌

It can be fixed by wrapping in a Promise, since Cypress automatically waits for a Promise

it('Cypress waits for request to complete', () => {
  
  cy.request('https://deelay.me/3000/https://jsonplaceholder.typicode.com/todos/1')
    .then(() => {
      return new Cypress.Promise(resolve => {
        setTimeout(() => { 
          console.log('Timeout complete')
          resolve()
        }, 2000)
      })
    })
    .then(() => console.log('Request complete'))

  cy.visit('http://example.com', {
    onBeforeLoad: () => console.log('Before visit')
  })
})

Logs:

  • Timeout complete ✅
  • Request complete
  • Before visit
  • Related