wait

Wait for a number of milliseconds or wait for an aliased resource to resolve before moving on to the next command.

Syntax

cy.wait(time)
cy.wait(alias)
cy.wait(aliases)
cy.wait(time, options)
cy.wait(alias, options)
cy.wait(aliases, options)

Usage

Correct Usage

cy.wait(500)
cy.wait('@getProfile')

Arguments

time (Number)

The amount of time to wait in milliseconds.

alias (String)

An aliased route as defined using the .as() command and referenced with the @ character and the name of the alias.

aliases (Array)

An array of aliased routes as defined using the .as() command and referenced with the @ character and the name of the alias.

options (Object)

Pass in an options object to change the default behavior of cy.wait().

OptionDefaultDescription
logtrueDisplays the command in the Command log
timeoutrequestTimeout, responseTimeoutTime to wait for cy.wait() to resolve before timing out
requestTimeoutrequestTimeoutOverrides the global requestTimeout for this request. Defaults to timeout.
responseTimeoutresponseTimeoutOverrides the global responseTimeout for this request. Defaults to timeout.

Yields

When given a time argument:

  • cy.wait() yields the same subject it was given.
  • It is unsafe to chain further commands that rely on the subject after .wait().

When given an alias argument:

  • cy.wait() 'yields an object containing the HTTP request and response properties of the request.

Examples

Time

Wait for an arbitrary period of milliseconds:

cy.wait(2000) // wait for 2 seconds

Additionally, it is often much easier to use cy.debug() or cy.pause() when debugging your test code.

Alias

For a detailed explanation of aliasing, read more about waiting on routes here.

Wait for a specific request to respond

// Wait for the alias 'getAccount' to respond
// without changing or stubbing its response
cy.intercept('/accounts/*').as('getAccount')
cy.visit('/accounts/123')
cy.wait('@getAccount').then((interception) => {
  // we can now access the low level interception
  // that contains the request body,
  // response body, status, etc
})
// Wait for the alias 'getAccount' to respond
// without changing or stubbing its response
cy.intercept('/accounts/*').as('getAccount')
cy.mount(<Account />)
cy.wait('@getAccount').then((interception) => {
  // we can now access the low level interception
  // that contains the request body,
  // response body, status, etc
})

Wait automatically increments responses

Each time we use cy.wait() for an alias, Cypress waits for the next nth matching request.

// stub an empty response to requests for books
cy.intercept('GET', '/books', []).as('getBooks')
cy.get('#search').type('Peter Pan')

// wait for the first response to finish
cy.wait('@getBooks')

// the results should be empty because we
// responded with an empty array first
cy.get('#book-results').should('be.empty')

// now the request (aliased again as `getBooks`) will return one book
cy.intercept('GET', '/books', [{ name: 'Peter Pan' }]).as('getBooks')

cy.get('#search').type('Peter Pan')

// when we wait for 'getBooks' again, Cypress will
// automatically know to wait for the 2nd response
cy.wait('@getBooks')

// we responded with one book the second time
cy.get('#book-results').should('have.length', 1)

Aliases

You can pass an array of aliases that will be waited on before resolving.

When passing an array of aliases to cy.wait(), Cypress will wait for all requests to complete within the given requestTimeout and responseTimeout.

cy.intercept('/users/*').as('getUsers')
cy.intercept('/activities/*').as('getActivities')
cy.intercept('/comments/*').as('getComments')
cy.visit('/dashboard')

cy.wait(['@getUsers', '@getActivities', '@getComments']).then(
  (interceptions) => {
    // interceptions will now be an array of matching requests
    // interceptions[0] <-- getUsers
    // interceptions[1] <-- getActivities
    // interceptions[2] <-- getComments
  }
)
cy.intercept('/users/*').as('getUsers')
cy.intercept('/activities/*').as('getActivities')
cy.intercept('/comments/*').as('getComments')
cy.mount(<Dashboard />)

cy.wait(['@getUsers', '@getActivities', '@getComments']).then(
  (interceptions) => {
    // interceptions will now be an array of matching requests
    // interceptions[0] <-- getUsers
    // interceptions[1] <-- getActivities
    // interceptions[2] <-- getComments
  }
)

Using .spread() to spread the array into multiple arguments.

cy.intercept('/users/*').as('getUsers')
cy.intercept('/activities/*').as('getActivities')
cy.intercept('/comments/*').as('getComments')
cy.wait(['@getUsers', '@getActivities', '@getComments']).spread(
  (getUsers, getActivities, getComments) => {
    // each interception is now an individual argument
  }
)

Notes

Nesting

Cypress automatically waits for the network call to complete before proceeding to the next command.

// Anti-pattern: placing Cypress commands inside .then callbacks
cy.wait('@alias')
  .then(() => {
    cy.get(...)
  })

// Recommended practice: write Cypress commands serially
cy.wait('@alias')
cy.get(...)

// Example: assert status from cy.intercept() before proceeding
cy.wait('@alias').its('response.statusCode').should('eq', 200)
cy.get(...)

Read Guide: Introduction to Cypress

Timeouts

requestTimeout and responseTimeout

When used with an alias, cy.wait() goes through two separate "waiting" periods.

The first period waits for a matching request to leave the browser. This duration is configured by the requestTimeout option - which has a default of 5000 ms.

This means that when you begin waiting for an aliased request, Cypress will wait up to 5 seconds for a matching request to be created. If no matching request is found, you will get an error message that looks like this:

Error for no matching request

Once Cypress detects that a matching request has begun its request, it then switches over to the 2nd waiting period. This duration is configured by the responseTimeout option - which has a default of 30000 ms.

This means Cypress will now wait up to 30 seconds for the external server to respond to this request. If no response is detected, you will get an error message that looks like this:

Timeout error for request wait

This gives you the best of both worlds - a fast error feedback loop when requests never go out and a much longer duration for the actual external response.

Using an Array of Aliases

When passing an array of aliases to cy.wait(), Cypress will wait for all requests to complete within the given requestTimeout and responseTimeout.

Rules

Requirements

  • When passed a time argument cy.wait() can be chained off of cy or off another command..
  • When passed an alias argument cy.wait() requires being chained off of cy ..

Assertions

  • cy.wait() will only run assertions you have chained once, and will not retry .

Timeouts

  • cy.wait() can time out waiting for the request to go out.
  • cy.wait() can time out waiting for the response to return.

Command Log

Wait for the PUT to users to resolve.

cy.intercept('PUT', /users/, {}).as('userPut')
cy.get('form').submit()
cy.wait('@userPut').its('request.url').should('include', 'users')

The cy.wait() will display in the Command Log as:

Command Log wait

When clicking on wait within the command log, the console outputs the following:

Console Log wait

History

VersionChanges
3.1.3Added requestTimeout and responseTimeout option
< 0.3.3cy.wait() command added

See also