As your test suite grows, repetition accumulates. Cypress gives you two tools to fight it: fixtures for static test data, and custom commands for repeated interaction sequences.
Fixtures
Fixtures are JSON (or other) files stored in cypress/fixtures/. Load them with cy.fixture().
// cypress/fixtures/user.json
{
"email": "alice@example.com",
"password": "s3cr3t",
"name": "Alice"
}Ctrl+Enter
HTML
CSS
JS
Preview
Custom Commands
Add reusable commands to cypress/support/commands.js:
Ctrl+Enter
HTML
CSS
JS
Preview
Now every test can call cy.login() instead of repeating the login flow:
Ctrl+Enter
HTML
CSS
JS
Preview
cy.session() — Session Caching
cy.session() caches the browser session (cookies, localStorage) after the first login and restores it on subsequent runs. This saves the round-trip to the login page on every test.
First test: cy.session() → runs login flow → caches session
Second test: cy.session() → restores cache → skips login (fast)Command Reuse Visualiser
Custom command flow
Ctrl+Enter
HTML
CSS
JS
Preview
TypeScript Declarations
If you use TypeScript, add your commands to the global Cypress interface:
// cypress/support/index.d.ts
declare namespace Cypress {
interface Chainable {
login(email: string, password: string): Chainable<void>
loginAsAdmin(): Chainable<void>
}
}
Now cy.login() gets autocomplete and type checking in your IDE.