Handling Async
Wait for elements, network requests, and conditions without brittle fixed delays.
Automatic Waiting
Cypress retries commands and assertions until defaultCommandTimeout (4s default). This replaces most explicit waits from Selenium-era tests.
Increase timeout per command with { timeout: 10000 } for slow operations—not globally unless necessary.
cy.get('[data-cy="slow-widget"]', { timeout: 15000 })
.should("be.visible");Waiting for Network
cy.intercept registers route alias; cy.wait("@alias") pauses until matching request completes. Wait for multiple aliases in array for parallel requests.
Do not wait arbitrary milliseconds after click—wait for UI or network signal proving action completed.
cy.intercept("GET", "/api/user").as("getUser");
cy.visit("/profile");
cy.wait("@getUser");
cy.get('[data-cy="username"]').should("not.be.empty");cy.wait() for Time and Conditions
cy.wait(ms) pauses fixed time—anti-pattern except debugging. Prefer should with callback polling condition or cy.waitUntil from cypress-wait-until plugin.
Route wait is preferred over time wait for API-dependent UI.
- Flaky tests often contain cy.wait numbers—replace with assertions
- Stub slow third parties to speed tests and stabilize timing
- Document required intercept aliases in spec header comments
// Avoid
cy.wait(3000);
// Prefer
cy.get('[data-cy="loaded"]').should("exist");Timeouts Configuration
Configure defaultCommandTimeout, requestTimeout, responseTimeout in cypress.config.ts. pageLoadTimeout affects cy.visit.
Per-test override in beforeEach for suite hitting slow backend. CI environments may need higher timeouts than local if resources constrained.
export default defineConfig({
e2e: {
defaultCommandTimeout: 8000,
requestTimeout: 10000,
},
});Race Conditions
Double form submit, stale list after create, and websocket updates cause races. Assert final steady state, not intermediate loading unless testing loading UI explicitly.
Disable animations and use deterministic test data seeds to reduce timing variance.
- Reset database state before each spec via cy.task
- Avoid parallel tests mutating same user account
- Use intercept to delay responses when testing loading states intentionally