Skip to main content

Cypress

A JavaScript end-to-end and component testing framework that runs inside a real browser. Time-travel debugging, automatic retries, network stubbing with cy.intercept(), session caching, and an interactive test runner — all built in.

✓ Runs in real browser ✓ Time-travel debugging ✓ Network stubbing ✓ Component testing ✓ Session caching ✓ TypeScript support

What is Cypress?

Cypress is an open-source end-to-end testing framework for JavaScript applications. Unlike Selenium-based tools that control the browser remotely via WebDriver, Cypress runs directly inside the browser alongside your application. This architecture gives Cypress access to real DOM events, network requests, cookies, and application state — and enables the time-travel debugging experience in its interactive test runner.

Cypress supports two modes: E2E testing (loading your full app in the browser) and component testing (mounting individual React, Vue, Angular, or Svelte components in isolation). Both use the same assertion and command API. Tests are written in JavaScript or TypeScript, and the interactive runner shows you a live DOM preview at every command step.

Key Features

Installation

# Install Cypress as a dev dependency
npm install --save-dev cypress

# Open the Cypress interactive test runner
npx cypress open

# Run tests headlessly (for CI)
npx cypress run

# Run a specific spec file
npx cypress run --spec "cypress/e2e/login.cy.ts"

# Run against a specific browser
npx cypress run --browser firefox

Writing E2E Tests

Tests are written with describe / it blocks using the cy command object. Commands chain together and execute sequentially; assertions auto-retry until they pass or time out.

// cypress/e2e/login.cy.ts
describe("Login flow", () => {
  beforeEach(() => {
    cy.visit("/login");
  });

  it("logs in with valid credentials", () => {
    cy.get('[data-testid="email"]').type("[email protected]");
    cy.get('[data-testid="password"]').type("s3cret");
    cy.get('[data-testid="submit"]').click();

    // Cypress auto-retries until the assertion passes or times out
    cy.url().should("include", "/dashboard");
    cy.contains("h1", "Dashboard").should("be.visible");
  });

  it("shows an error for wrong password", () => {
    cy.get('[data-testid="email"]').type("[email protected]");
    cy.get('[data-testid="password"]').type("wrong");
    cy.get('[data-testid="submit"]').click();

    cy.contains("Invalid credentials").should("be.visible");
  });
});

Network Stubbing with cy.intercept()

cy.intercept() lets you stub API responses with fixture files or inline objects, simulate error states, and alias requests to wait for them explicitly. This makes testing loading states and error handling deterministic.

// Intercept and stub network requests
describe("Posts page", () => {
  it("displays stubbed posts", () => {
    // Intercept GET /api/posts and return fixture data
    cy.intercept("GET", "/api/posts", { fixture: "posts.json" }).as("getPosts");

    cy.visit("/posts");
    cy.wait("@getPosts");

    cy.get('[data-testid="post-list"]').children().should("have.length", 3);
  });

  it("shows error state when API fails", () => {
    cy.intercept("GET", "/api/posts", { statusCode: 500 }).as("postsFail");

    cy.visit("/posts");
    cy.wait("@postsFail");

    cy.contains("Failed to load posts").should("be.visible");
  });
});

Custom Commands and Session Caching

Define custom commands in cypress/support/commands.ts. Combine them with cy.session() to cache authentication state across the entire test suite — login once, reuse everywhere.

// cypress/support/commands.ts — custom command for login
Cypress.Commands.add("login", (email: string, password: string) => {
  cy.session(
    [email, password],
    () => {
      cy.visit("/login");
      cy.get('[data-testid="email"]').type(email);
      cy.get('[data-testid="password"]').type(password);
      cy.get('[data-testid="submit"]').click();
      cy.url().should("include", "/dashboard");
    },
    {
      cacheAcrossSpecs: true, // reuse session across spec files
    }
  );
});

// In any test file:
beforeEach(() => {
  cy.login("[email protected]", "adminpass");
});

Component Testing

Cypress component testing mounts a component in a real browser environment. Use cy.mount() to render the component and the same cy assertions to verify behavior — no jsdom limitations.

// cypress/component/Button.cy.tsx — component test
import Button from "../../src/components/Button";

describe("Button", () => {
  it("renders the label", () => {
    cy.mount(

Cypress vs Playwright

Feature Cypress Playwright
ArchitectureIn-browserOut-of-process
Interactive runnerPolished GUIUI mode (newer)
Component testingStableExperimental
WebKit (Safari)ExperimentalStable
Multi-tab supportLimitedFull
Free parallelismRequires CloudBuilt-in

Pros and Cons

Pros

  • ✓ Polished interactive test runner with time-travel debugging
  • ✓ Excellent documentation and large community
  • ✓ Stable component testing for React, Vue, Angular, Svelte
  • ✓ cy.intercept() makes network stubbing intuitive
  • ✓ cy.session() dramatically speeds up authenticated test suites

Cons

  • ✗ Parallelism requires Cypress Cloud (paid)
  • ✗ Multi-tab and multi-origin scenarios are restricted
  • ✗ Only supports JavaScript / TypeScript
  • ✗ WebKit (Safari) support is still experimental
  • ✗ Tests run in a single browser tab by design — some architectures complicate this

Frequently Asked Questions

What is Cypress?▼

Cypress is a JavaScript end-to-end testing framework that runs tests inside a real browser. Unlike Selenium-based tools that run tests in a separate process, Cypress operates in the same event loop as your application, giving it direct access to DOM, network requests, and application state. It is designed for modern web applications and supports both E2E and component testing.

How does Cypress automatic retry work?▼

Cypress automatically retries most commands and assertions until they pass or the timeout is reached (default 4 seconds for most assertions). When you write cy.contains('Dashboard').should('be.visible'), Cypress keeps re-querying the DOM and checking the assertion on each retry cycle. This built-in retry eliminates most explicit wait calls and makes tests resilient to minor timing variations.

What is time-travel debugging in Cypress?▼

In the Cypress Test Runner, the command log on the left side shows every command that ran. Hovering over a command pins the DOM snapshot at that exact moment — you see exactly what the page looked like before and after each action. This time-travel capability makes it trivial to identify why a test failed without adding logging or taking screenshots manually.

How does cy.intercept() work for network stubbing?▼

cy.intercept() registers a network route handler that intercepts matching requests and can stub the response, modify it, or just alias it for waiting. You pass a URL pattern and optional response fixture or object. After calling cy.intercept(), alias it with .as('name') and use cy.wait('@name') to pause the test until that request completes. This is essential for testing loading states, error handling, and data-driven scenarios.

What is cy.session() and why should I use it?▼

cy.session() caches and restores browser session state (cookies, localStorage, sessionStorage) between tests. Instead of going through the full login UI before each test, cy.session() runs the setup once, caches the resulting session, and restores it on subsequent calls. With cacheAcrossSpecs: true, the session persists across spec files, dramatically speeding up test suites that need authentication.

What is Cypress Cloud (formerly Cypress Dashboard)?▼

Cypress Cloud is an optional paid service that records test runs, provides parallel test execution across multiple CI machines, stores video and screenshot artifacts, and gives a test analytics dashboard. It integrates with GitHub, GitLab, and Slack to report test status on pull requests. The free tier allows limited monthly test recordings; paid plans include more recordings, parallelization, and access controls.

Share this tool: X / Twitter LinkedIn
✓ 60,000+ developers use DevPlaybook ★★★★★ 4.8 / 5 on Gumroad ✓ MIT licensed · Instant download ✓ No login required

Related Products

on Gumroad

You Might Also Need

More Free Tools

Enjoying this tool? Get more like it.

Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.

DevPlaybook Pro 7 days free

Unlock AI-Powered Dev Tools

  • ⚡ AI Code Review, Doc Generator & SQL Builder
  • ⚡ All premium templates & early access
  • ⚡ Member discounts on Gumroad products
Start Free Trial →

$9/mo after trial · Cancel anytime

Want the full toolkit?

Get DevPlaybook Pro

Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.

$79
$241 separately Save $162 (67% off)
Get DevPlaybook Pro — $79 →

MIT licensed · Instant download · No subscription

See what's included → Browse all deals →