100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Testing

Waiting for Requests

Learn how cy.wait() synchronizes Cypress tests with network activity, avoiding both flaky race conditions and unnecessary fixed delays.

Network & FixturesIntermediate8 min readJul 10, 2026
Analogies

Why Explicit Waiting Matters

Cypress commands are asynchronous and automatically retry many assertions, but a network request triggered by a click or page load doesn't block the test by default, which means the UI might not yet reflect the response when the next command runs. cy.wait('@alias') pauses the test until a request matching that alias's intercept has actually completed, giving you a reliable synchronization point instead of guessing with a fixed cy.wait(2000), which is both slower than necessary when the request is fast and flaky when the request is slow.

🏏

Cricket analogy: Waiting on a specific alias is like a scorer waiting for the actual ball to be bowled and its outcome confirmed before updating the scoreboard, rather than updating it after a fixed guessed number of seconds.

Waiting on Aliases and Response Assertions

cy.wait('@alias') returns a subject containing the full request and response cycle, which you can chain assertions onto, such as .its('response.statusCode').should('eq', 200) or .its('request.body').should('deep.include', { status: 'active' }). You can also pass an array of aliases like cy.wait(['@getUser', '@getSettings']) to wait for multiple requests fired in parallel, or add a custom timeout as a second argument, { timeout: 15000 }, when a particular endpoint is known to be slower than Cypress's default four-second command timeout.

🏏

Cricket analogy: Asserting on the waited response is like a match referee not just confirming the ball was bowled, but checking specifically whether it was called a no-ball, similar to checking response.statusCode after confirming the request happened.

javascript
cy.intercept('GET', '/api/user/settings').as('getSettings');
cy.intercept('GET', '/api/user/profile').as('getProfile');

cy.visit('/account');

// Wait for both parallel requests before asserting on the page
cy.wait(['@getProfile', '@getSettings']);

cy.wait('@getSettings', { timeout: 15000 })
  .its('response.statusCode')
  .should('eq', 200);

cy.wait('@getSettings')
  .its('request.body')
  .should('deep.include', { theme: 'dark' });

cy.get('[data-testid="settings-panel"]').should('be.visible');

Waiting on the Same Alias Multiple Times

When the same endpoint is called more than once during a test, such as a search box that fires a new request on every keystroke, calling cy.wait('@search') repeatedly returns each successive matched call in order, first-in-first-out, so the first cy.wait() gets the first request and the next cy.wait() gets the second. You can also inspect the total number of matched calls with cy.get('@search.all') to assert on how many requests fired in total, which is useful for verifying debounce logic actually reduced network calls rather than firing one per keystroke.

🏏

Cricket analogy: Waiting on repeated calls to the same alias in order is like a scorer processing deliveries strictly ball by ball within an over, never skipping ahead to ball six before ball three has been recorded.

cy.get('@search.all') returns an array of every intercepted call matching that alias so far in the test, letting you assert cy.get('@search.all').should('have.length', 1) to confirm a debounced search input only fired a single network request despite multiple keystrokes.

Avoid using a bare cy.wait(milliseconds) with a hardcoded number as a substitute for cy.wait('@alias'). It either wastes time waiting longer than necessary on fast networks or produces flaky failures on slower CI runners where the real request takes longer than your guessed delay.

  • cy.wait('@alias') pauses the test until a request matching that intercept alias completes, avoiding both flakiness and wasted time.
  • The waited subject exposes request and response data for chained assertions like .its('response.statusCode').
  • An array of aliases can be passed to cy.wait() to synchronize on multiple parallel requests at once.
  • A custom { timeout } option overrides Cypress's default four-second command timeout for slower endpoints.
  • Repeated calls to cy.wait('@alias') for the same alias return matched requests in first-in-first-out order.
  • cy.get('@alias.all') returns every call matched so far, useful for asserting on debounce or call counts.
  • Hardcoded cy.wait(ms) delays should be avoided in favor of alias-based waiting for reliability.

Practice what you learned

Was this page helpful?

Topics covered

#Testing#CypressStudyNotes#TestingQA#WaitingForRequests#Waiting#Requests#Explicit#Matters#StudyNotes#SkillVeris