# No Arbitrary Waits (cy.wait Anti-Pattern)
## Rule
`cy.wait(ms)` with a numeric argument is PROHIBITED in all Cypress tests. Use intercept aliases, assertions, or Cypress's built-in retry-ability instead.
## Why This Rule Exists
- `cy.wait(5000)` is either too slow (wastes CI time) or too fast (flaky)
- Cypress has built-in retry-ability — most assertions auto-retry for 4 seconds
- Intercept aliases wait for the exact moment data arrives
## Alternatives
### Instead of Waiting for API Data
```typescript
// Bad
cy.visit('/users');
cy.wait(3000);
cy.get('[data-cy="user-list"]').should('have.length', 5);
// Good
cy.intercept('GET', '/api/users').as('getUsers');
cy.visit('/users');
cy.wait('@getUsers');
cy.get('[data-cy="user-list"]').children().should('have.length', 5);
```
### Instead of Waiting for UI Updates
```typescript
// Bad
cy.get('[data-cy="submit"]').click();
cy.wait(2000);
cy.get('[data-cy="success-message"]').should('be.visible');
// Good — assertion auto-retries until timeout
cy.get('[data-cy="submit"]').click();
cy.get('[data-cy="success-message"]').should('be.visible');
```
### Instead of Waiting for Animations
```typescript
// Bad
cy.get('[data-cy="modal"]').click();
cy.wait(500); // wait for animation
// Good — assert on the final state
cy.get('[data-cy="modal-content"]').should('be.visible');
```
### Instead of Waiting for Navigation
```typescript
// Bad
cy.get('[data-cy="link"]').click();
cy.wait(1000);
// Good
cy.get('[data-cy="link"]').click();
cy.url().should('include', '/target-page');
```
## The Only Acceptable cy.wait Usage
```typescript
// Waiting for intercept aliases — this is correct
cy.wait('@apiCall');
cy.wait(['@apiCall1', '@apiCall2']); // wait for multiple
```
## Enforcement
Add an ESLint rule or code review checklist item:
```
RULE: cy.wait() must ONLY be called with @ alias arguments, never numeric ms values
```
## Anti-Patterns
- `cy.wait(1000)` before any assertion
- Increasing wait times to "fix" flaky tests
- Using `cy.wait()` to "let the page load"
- Wrapping `cy.wait()` in a custom command to hide it