Install

cypress-io/cypress

Cypress Testing Framework

Last updated on Dec 18, 2025 (Commit: 08d0c1b)

Overview

Relevant Files
  • README.md
  • package.json
  • lerna.json
  • CONTRIBUTING.md

Cypress is a modern end-to-end testing framework built for the web. This repository contains the complete Cypress application, including the CLI, desktop app, driver, and numerous supporting packages. The project is organized as a monorepo using Lerna and Yarn workspaces, enabling independent development and publishing of multiple packages.

Project Structure

The repository is divided into four main package categories:

CLI Package (cli/) The command-line interface distributed as the cypress npm module. This is the entry point users interact with when installing Cypress via npm.

Core Packages (packages/) Private packages in the @packages/ namespace that form the Cypress application. Key packages include:

  • @packages/app – Frontend UI rendered in the browser
  • @packages/driver – Core API command execution engine
  • @packages/server – Backend orchestration and proxy layer
  • @packages/electron – Electron integration
  • @packages/launchpad – Project setup and launch interface
  • @packages/data-context – GraphQL data layer for app communication

Public Packages (npm/) Standalone modules published under @cypress/ namespace, including component testing adapters for React, Vue, Angular, Svelte, and webpack/Vite dev servers.

Tooling Packages (tooling/) Development-only packages for building and optimizing the Cypress binary, including V8 snapshot creation and dependency bundling.

Architecture Overview

Loading diagram...

Key Technologies

The project uses TypeScript for type safety, Vite for frontend bundling, and Electron for the desktop application. Testing is handled through Vitest and Mocha, with comprehensive CI/CD via CircleCI. The monorepo structure enables independent versioning and publishing of public packages while maintaining tight integration of core packages.

Getting Started

Contributors should review the CONTRIBUTING.md file for detailed setup instructions, including Node.js version requirements, dependency installation, and common development tasks. The project requires Node.js >= 22.19.0 and Yarn >= 1.22.22.

Architecture & Core Components

Relevant Files
  • packages/server/README.md
  • packages/driver/README.md
  • packages/data-context/README.md
  • packages/electron/README.md
  • cli/README.md
  • packages/socket/README.md

Cypress is a monorepo composed of several interconnected packages that work together to provide a complete end-to-end testing platform. Understanding how these components interact is essential for contributing to the codebase.

System Architecture Overview

Loading diagram...

Core Components

CLI (cli/)

The CLI is the entry point for users. It provides command-line interfaces for:

  • Installing and managing the Cypress executable
  • Running tests in headless mode (cypress run)
  • Opening the interactive Test Runner (cypress open)
  • Managing the Cypress binary cache
  • Passing configuration options (browsers, specs, parallelization, recording)

The CLI spawns the Electron binary with appropriate arguments and handles process lifecycle management.

Electron (packages/electron/)

This package manages the Electron binary that powers Cypress. It:

  • Installs and packages the Electron binary for the current platform
  • Provides a development shell matching the production binary 1:1 using symlinks
  • Handles platform-specific concerns (macOS, Linux, Windows)
  • Manages Node.js and Chromium versions bundled with Electron

The Electron app serves as the container for the Server and provides native OS integration.

Server (packages/server/)

The Server is the heart of Cypress. Running as a Node.js process, it:

  • Proxies every byte of traffic between the browser and the application under test
  • Automates browser interactions and normalizes tasks across different browsers
  • Coordinates state synchronization with the Driver and Launchpad
  • Orchestrates nearly every other layer and package
  • Manages HTTP/static file servers, video recording, and Mocha reporters
  • Handles 3rd-party plugins and configuration

The Server communicates with the Driver via WebSocket and manages the Data Context.

Driver (packages/driver/)

The Driver is the core JavaScript library injected into the browser. It:

  • Executes Cypress commands (cy.get, cy.click, etc.)
  • Manages the test runtime and command queue
  • Handles cross-origin testing via postMessage communication
  • Provides the cy and Cypress global objects to test code
  • Manages snapshots, logs, and command state

The Driver is consumed by the Runner package and runs inside the browser context.

Data Context (packages/data-context/)

This package provides centralized data access for the entire application. It:

  • Exposes a GraphQL API that the Launchpad and App use to query/mutate data
  • Manages coreData (top-level application state)
  • Provides Sources for derived and read-only data
  • Implements Actions for all mutations and destructive operations
  • Coordinates with the Server to manage project configuration, specs, and browser state

The Data Context acts as the single source of truth for application state.

Communication Patterns

Socket.io: The Server and frontend (Launchpad/App) communicate via Socket.io for real-time updates and GraphQL queries.

PostMessage: The Driver communicates with cross-origin iframes using the browser's postMessage API for secure cross-origin testing.

IPC: The Server and child processes (like the plugin process) communicate via Node.js IPC for configuration and event handling.

Data Flow

  1. User runs cypress run or cypress open via CLI
  2. CLI spawns Electron, passing configuration arguments
  3. Electron starts the Server process
  4. Server initializes the Data Context and creates a GraphQL server
  5. Server launches the browser and injects the Driver
  6. Driver executes test commands and communicates results back to Server
  7. Server proxies all network traffic and manages browser automation
  8. Launchpad/App queries Data Context via GraphQL for UI updates
  9. Results are aggregated and reported back to the user

Key Design Principles

  • Separation of Concerns: Each package has a specific responsibility
  • Centralized State: Data Context is the single source of truth
  • Async Communication: Socket.io and postMessage enable non-blocking updates
  • Browser Isolation: The Driver runs in the browser; the Server runs in Node.js
  • Plugin Support: The Server manages 3rd-party plugins via a standardized interface

CLI & Binary Management

Relevant Files
  • cli/README.md
  • cli/lib/cli.ts
  • cli/bin/cypress
  • scripts/binary.js
  • scripts/binary/index.js
  • scripts/binary/build.ts
  • packages/electron/README.md

The CLI and binary management system is the backbone of Cypress distribution. It handles both the command-line interface that users interact with and the underlying binary build, packaging, and deployment pipeline.

CLI Architecture

The CLI is built as an npm package that provides the cypress command. The entry point is cli/bin/cypress, a Node.js shebang script that loads the compiled CLI module and initializes it. The main CLI logic lives in cli/lib/cli.ts, which uses the commander library to parse commands and options.

Key CLI responsibilities:

  • Print CLI commands and help information
  • Install and verify the Cypress executable
  • Run tests from the terminal (cypress run)
  • Open the interactive Test Runner (cypress open)
  • Manage the binary cache
  • Accept options for browsers, spec files, grouping, and parallelization

The CLI is built using TypeScript and compiled to both CommonJS and ES Modules. The build process is defined in cli/scripts/build.ts and outputs to cli/build/dist/.

Binary Build Pipeline

The binary build system is orchestrated through scripts/binary.js, which dispatches to various build commands defined in scripts/binary/index.js. The pipeline includes several stages:

Loading diagram...

Core build commands:

  • build: Compiles the Cypress application using Electron and electron-builder
  • package: Packages the compiled app into platform-specific installers
  • zip: Creates compressed archives for distribution
  • upload: Uploads binaries to S3 and manages CDN cache
  • smoke: Runs smoke tests to verify the built binary works
  • deploy: Orchestrates the full pipeline (build > zip > upload)

Electron Binary Management

The Electron binary is managed by @packages/electron, which handles installation, versioning, and launching. It provides both a CLI interface (./bin/cypress-electron) and a public API for programmatic use.

Key functions:

  • installIfNeeded(): Checks if the binary exists and is up-to-date, installs if needed
  • install(): Forces installation of the Electron binary
  • open(appPath, argv, callback): Launches an Electron app with specified arguments
  • getElectronVersion(): Returns the current Electron version
  • cli(argv): Entry point for command-line operations

The Electron package uses TypeScript and compiles to CommonJS by default. The build output includes the compiled JavaScript in dist/cjs/ and the Electron binary in dist/Cypress/.

Sub-package API

Cypress ships pre-assembled mounting libraries for major frameworks (Vue, React, Angular, Svelte) as sub-packages. These are embedded directly in the npm package without requiring separate installations.

Example imports:

// Instead of installing @cypress/vue separately
import { mount } from 'cypress/vue'

// Or use the external package if you need a specific version
import { mount } from '@cypress/vue'

To add a new sub-package, ensure its rollup build is self-contained, invoke node ./scripts/sync-exported-npm-with-cli.js in the postbuild script, add the package name to .gitignore and cli/scripts/post-build.js, and run yarn build to automate package.json updates.

Platform-Specific Considerations

The binary system supports multiple platforms: Linux (x64, arm64), macOS (x64, arm64), and Windows (x64). Platform detection uses os.platform() and architecture detection via the arch package.

Windows-specific: Path length is limited to 260 characters. The build system checks paths against typical Windows cache locations to prevent exceeding this limit during unzipping.

Linux-specific: The system can use Xvfb (virtual framebuffer) for headless testing when needed, detected via the needsSandbox() check.

macOS-specific: Code signing and notarization are handled through scripts/after-sign-hook.js and scripts/after-pack-hook.js.

Frontend UI & Launchpad

Relevant Files
  • packages/launchpad – Electron-based UI for cypress open
  • packages/app – Web-based UI for interactive and run modes
  • packages/frontend-shared – Shared components, styles, and utilities
  • packages/data-context/graphql – GraphQL schema and server

Cypress has two primary frontend applications: Launchpad (Electron-based) and App (web-based). Both are built with Vue 3, Vite, and TypeScript, sharing components and utilities through the frontend-shared package.

Architecture Overview

Loading diagram...

Launchpad

Launchpad is the entry point when users run cypress open. It handles:

  • Authentication – Login through Cypress Cloud
  • Onboarding – Configure Component Testing, install dependencies
  • Mode Selection – Choose between E2E or Component Testing
  • Welcome Screens – Major version release announcements

Built with Vue 3 Composition API and <script setup> syntax. Uses Urql for GraphQL queries and mutations. The app is bundled with Vite and rendered by Electron.

App

The App is the main interactive interface after selecting a testing mode. It has two distinct modes:

  • Open Mode – Full UI with navigation, spec list, settings. Powered by GraphQL and Urql for real-time state management.
  • Run Mode – Minimal UI showing only the runner (command log, spec header, AUT iframe). Avoids GraphQL for performance on CI machines.

Routes are auto-generated from src/pages using vite-plugin-pages and Vue Router. Route metadata can be configured in <route> blocks within page components.

Frontend Shared

This package contains reusable components and infrastructure:

  • Base Components – Form inputs, buttons, cards, modals, alerts
  • Styling – Tailwind CSS configuration with explicit pixel values (e.g., m-[8px])
  • Icons – Custom duotone icon library with auto-importing via unplugin-icons
  • GraphQL Components – Components in src/gql-components that use GraphQL queries/mutations
  • Composables – Reusable Vue 3 logic (e.g., useModelWrapper)
  • Accessibility – Semantic HTML, Headless UI for patterns, ARIA where needed

Data Flow: GraphQL & Data Context

The @packages/data-context package provides a centralized data layer:

  • CoreData – Top-level state (specs, projects, settings)
  • Sources – Read-only derived data (e.g., filtered specs)
  • Actions – Mutative operations that update CoreData via ctx.update()
  • GraphQL Schema – Built with Nexus, exposes CoreData and Sources as resolvers

Frontend components query this via Urql. Type safety is maintained through graphql-code-generator, which generates TypeScript types from gql queries in Vue components.

Development Workflow

  1. Run yarn watch to start Vite dev server and code generation
  2. Run yarn cypress:open to start GraphQL server and open Cypress
  3. Access GraphQL playground at http://localhost:52200/graphql
  4. Edit components and see hot-module reloads
  5. Write component tests in Cypress (component tests for frontend-shared, E2E for app and launchpad)

Key Technologies

  • Vue 3 – Composition API with <script setup>
  • Vite – Fast dev server and build tool
  • Urql – GraphQL client with Vue integration
  • Tailwind CSS – Utility-first styling
  • Pinia – State management for global state
  • Headless UI – Accessible component patterns
  • Nexus GraphQL – Type-safe schema generation

Test Execution & Runner

Relevant Files
  • packages/driver/src/cypress/runner.ts
  • packages/server/lib/modes/run.ts
  • packages/server/lib/reporter.js
  • packages/runner/README.md
  • packages/reporter/README.md
  • packages/server/lib/socket-base.ts
  • packages/app/src/runner/event-manager.ts

Overview

Test execution in Cypress involves a coordinated flow between the server (Node.js process), the runner (browser bundle), and the driver (in-browser test executor). The server orchestrates spec execution, the runner bundles and serves assets, and the driver executes tests within the browser.

Architecture Flow

Loading diagram...

Server-Side Execution (run.ts)

The server orchestrates test execution through packages/server/lib/modes/run.ts. Key responsibilities:

  • Spec Iteration: Iterates through specs serially or in parallel using iterateThroughSpecs()
  • Browser Launch: Opens the browser for each spec via openProject.launch()
  • Lifecycle Hooks: Calls beforeSpecRun() and afterSpecRun() for setup/teardown
  • Video Recording: Manages video capture for each spec run
  • Result Collection: Aggregates test results and exit codes

For parallel execution, the server coordinates with the Cypress Cloud API to claim instances and distribute specs across workers.

Runner Bundle

The runner package (packages/runner) bundles three critical components:

  1. Driver (@packages/driver) - Core test execution logic
  2. Reporter (@packages/reporter) - UI for displaying test results
  3. Styles - Bundled SCSS for the reporter interface

The runner is deprecated in favor of @packages/app but remains necessary for webpack bundling until those packages can be directly imported.

Driver-Side Execution (runner.ts)

The driver (packages/driver/src/cypress/runner.ts) manages test execution within the browser:

  • Mocha Integration: Wraps Mocha's test runner with Cypress-specific lifecycle events
  • Test Lifecycle Events: Fires events like runner:test:before:run:async and runner:test:after:run:async
  • Command Execution: Manages the cy command queue and assertion handling
  • Error Handling: Captures uncaught exceptions and hook failures
  • State Management: Tracks test state, retries, and timing information

The run() method initiates Mocha's execution, which triggers a cascade of events that the reporter listens to.

Reporter UI

The reporter (packages/reporter) displays:

  • Test suite hierarchy and individual test results
  • Command log with detailed command information
  • Assertions and failures with stack traces
  • Test statistics (passed, failed, pending counts)
  • Real-time updates via Socket.io from the server

Socket Communication

The server and browser communicate via Socket.io (packages/server/lib/socket-base.ts):

  • Automation Requests: Driver requests browser automation (cookies, screenshots, etc.)
  • Push Messages: Server pushes file changes and automation updates to the driver
  • Event Streaming: Reporter events flow back to the server for logging and recording

Test Execution Sequence

  1. Server launches browser with spec URL
  2. Runner loads and initializes the driver
  3. Driver parses spec file and creates Mocha test suite
  4. Driver fires before:add event, adds tests to reporter
  5. Driver calls Mocha.run() to start test execution
  6. For each test: fire lifecycle events, execute hooks, run test code
  7. Reporter captures and displays results in real-time
  8. After all tests: collect results and return exit code to server
  9. Server processes results, records video, and moves to next spec

Network & Proxy Layer

Relevant Files
  • packages/proxy/ – HTTP interception proxy
  • packages/https-proxy/ – HTTPS certificate authority and proxy
  • packages/net-stubbing/ – Network stubbing server-side logic
  • packages/network/ – Node.js networking utilities

Cypress's network layer enables request interception, stubbing, and modification through a multi-layered proxy architecture. This system allows tests to inspect, modify, and stub HTTP/HTTPS requests and responses in real-time.

Architecture Overview

Loading diagram...

Core Components

HTTPS Proxy (packages/https-proxy) acts as a certificate authority, generating dynamic SSL/TLS certificates on-the-fly. This allows Cypress to intercept and inspect encrypted HTTPS traffic. The CA class manages certificate generation, while the Server handles the actual proxy connections.

HTTP Proxy (packages/proxy) contains the main request/response interception logic through the NetworkProxy class. It orchestrates three middleware stacks:

  • Request Middleware – Processes incoming requests, handles authentication, correlates browser pre-requests, and applies cy.intercept() routes
  • Response Middleware – Modifies responses, injects Cypress code, handles CSP headers, and manages compression
  • Error Middleware – Handles network errors and connection failures

Net Stubbing (packages/net-stubbing) provides the server-side implementation of cy.intercept(). The InterceptRequest middleware checks if a request matches any registered routes. If matched, it creates an InterceptedRequest object that allows handlers to modify, stub, or continue the request. Routes can provide static responses, modify headers/body, or pass through to the real network.

Network Utilities (packages/network) exports low-level networking tools:

  • agent – HTTP/HTTPS agent with proxy and keepalive support
  • connect – Socket creation with retry logic
  • blocked – Glob matching for blocked hosts
  • clientCertificates – Client certificate management

Request Flow

  1. Browser sends request → HTTPS Proxy decrypts and forwards to HTTP Proxy
  2. Request Middleware runs: extracts metadata, correlates with browser pre-request, applies basic auth
  3. SetMatchingRoutes middleware checks if request matches any cy.intercept() routes
  4. If matched, InterceptRequest middleware invokes route handlers with before:request event
  5. Handler can: modify request, send static response, or call req.continue()
  6. If continuing, SendRequestOutgoing uses the Network Agent to make the actual outbound request
  7. Response Middleware processes the response: modifies headers, injects Cypress code, handles compression
  8. InterceptResponse middleware invokes after:response handlers if registered
  9. Final response sent back to browser

Key Middleware Stages

Request middleware includes: LogRequest, ExtractCypressMetadataHeaders, CorrelateBrowserPreRequest, SetMatchingRoutes, InterceptRequest, SendRequestOutgoing.

Response middleware includes: LogResponse, InterceptResponse, SetInjectionLevel, MaybeInjectHtml, MaybeRemoveSecurity, GzipBody, SendResponseBodyToClient.

Debugging

Enable detailed logs with DEBUG=cypress:proxy:* for high-level proxy events or DEBUG=cypress-verbose:proxy:http for per-request details. The proxy integrates with Cypress's telemetry system to track request/response timing and performance.

Published NPM Packages

Relevant Files
  • npm/README.md
  • npm/react
  • npm/vue
  • npm/angular
  • npm/svelte
  • npm/webpack-dev-server
  • npm/vite-dev-server
  • npm/mount-utils
  • npm/grep
  • npm/puppeteer

The npm/ directory contains standalone packages published under the @cypress/ namespace on npm. These packages extend Cypress functionality and are independently versioned using semantic versioning. They are automatically released when changes merge into the develop branch.

Component Testing Adapters

Framework-specific adapters enable component testing in Cypress:

  • @cypress/react - Mount and test React components (18+). Includes support for React Router and modern hooks.
  • @cypress/vue - Test Vue 3 components with full SFC support and TypeScript integration.
  • @cypress/angular - Test Angular components (18+) with dependency injection and zone.js support.
  • @cypress/svelte - Test Svelte components with reactive state and lifecycle support.

All adapters depend on @cypress/mount-utils, which provides shared types and utilities for building mount adapters.

Dev Server Integrations

These packages configure bundlers for component testing:

  • @cypress/vite-dev-server - Launches Vite dev server for component testing. Supports Vite 5, 6, and 7 with automatic config inference.
  • @cypress/webpack-dev-server - Launches Webpack dev server for component testing. Handles framework-specific configurations and bundle analysis.

Both are bundled with Cypress and typically don't require separate installation.

Utility Packages

  • @cypress/grep - Filter and organize tests by title or custom tags. Supports test burning (repeating tests to catch flakiness) and pre-filtering specs.
  • @cypress/puppeteer - Integrate Puppeteer's browser API within Cypress tests. Currently in public beta.
  • @cypress/mount-utils - Internal library exporting shared types and utilities for mount adapters.
  • @cypress/eslint-plugin-dev - Internal ESLint rules for Cypress package development.
  • @cypress/webpack-preprocessor - Webpack preprocessor for spec file bundling.
  • @cypress/webpack-batteries-included-preprocessor - Webpack preprocessor with built-in loaders.
  • @cypress/vite-plugin-cypress-esm - Vite plugin for ESM support in Cypress.
  • @cypress/cypress-schematic - Angular schematic for Cypress setup.

Release Process

Packages use semantic versioning with commit message prefixes (feat, fix, chore). The release pipeline automatically:

  1. Detects changes in each package
  2. Bumps versions based on commit types
  3. Publishes to npm with @cypress/ scope
  4. Syncs framework adapters to the main Cypress CLI

This decoupled approach allows rapid iteration on individual packages while maintaining compatibility with the core Cypress application.

Configuration & Type System

Relevant Files
  • packages/config/src - Configuration validation and options
  • packages/types/src/config.ts - Core configuration types
  • packages/scaffold-config/src - Framework detection and scaffolding
  • packages/web-config - Web build configuration
  • cli/types/cypress.d.ts - TypeScript definitions for Cypress config

Cypress uses a multi-layered configuration system that validates, resolves, and manages settings across the entire application. The system supports both E2E and component testing modes, with framework-specific scaffolding and comprehensive type safety.

Configuration Architecture

The configuration system is split into three main packages:

@packages/config handles validation and runtime options. It exports browser-safe configuration utilities and project-specific configuration logic. Configuration options are defined with validation rules, default values, and metadata about whether they require server or browser restarts when changed.

@packages/types provides TypeScript definitions for all configuration interfaces. The FullConfig type represents the complete resolved configuration including metadata about how each option was resolved (from defaults, config file, environment, CLI, or runtime). The ResolvedConfigurationOptions tracks the source of each setting for UI display and debugging.

@packages/scaffold-config handles automatic project setup, including framework detection, dependency installation, and cypress.config.js generation. It supports React, Vue, Angular, Svelte, and Next.js with both Vite and Webpack bundlers.

Configuration Resolution Pipeline

Loading diagram...

Configuration Options

Configuration options are defined in packages/config/src/options.ts with metadata:

  • name - The configuration key (e.g., baseUrl, viewportWidth)
  • defaultValue - Fallback value if not specified
  • validation - Function that validates the option value
  • overrideLevel - Whether the option can be overridden at test/suite level (any, suite, or never)
  • requireRestartOnChange - Whether changing this option requires restarting the server or browser

Framework Detection & Scaffolding

The scaffold system automatically detects project frameworks and generates appropriate configuration:

  1. Template Detection - Checks for Next.js, Nuxt, or other code-generated projects first
  2. Library Detection - Identifies React, Vue, Angular, Svelte if not a template
  3. Bundler Detection - Determines if using Vite, Webpack, or other build tools
  4. Dependency Installation - Installs required adapters and dev dependencies
  5. Config Generation - Creates cypress.config.js with sensible defaults

Type Safety

All configuration is fully typed through TypeScript definitions in cli/types/cypress.d.ts. The system distinguishes between:

  • RuntimeConfigOptions - Options available at test runtime
  • ResolvedConfigOptions - Options resolved during initialization
  • ReceivedCypressOptions - Validated subset of options required for project creation

Breaking changes to configuration options are tracked with error keys like CONFIG_FILE_INVALID_ROOT_CONFIG to provide clear migration guidance to users.

Development Workflow & Testing

Relevant Files
  • CONTRIBUTING.md
  • guides/testing-strategy-and-styleguide.md
  • guides/protocol-development.md
  • system-tests/README.md

Getting Started with Development

The Cypress repository is a monorepo using Yarn workspaces and Lerna. All scripts should be run from the repository root, not from individual package directories.

Initial setup:

yarn                    # Install all dependencies
yarn start              # Launch Cypress in dev mode

For Windows users, configure Yarn to use Command Prompt:

yarn config set script-shell "C:\\Windows\\system32\\cmd.exe"

Core Development Tasks

Common top-level tasks execute across all packages by default. Use --scope to target specific packages:

yarn build              # Compile TypeScript
yarn watch              # Auto-rebuild on file changes
yarn test-unit          # Run unit tests
yarn test-integration   # Run integration tests
yarn test-system        # Run system tests
yarn test-watch         # Run tests in watch mode

Scoped execution examples:

yarn test-unit --scope cypress                    # Test CLI only
yarn test-unit --scope @packages/server           # Test server package
yarn test-unit --scope @packages/*                # Test all @packages/*

Testing Strategy

Cypress follows Test-Driven Development (TDD) with a shift-left approach. Tests are categorized by scope and environment:

Test Types:

  • Unit - Single function or module in isolation
  • Integration - Feature with some mocking (e.g., backend)
  • Component - Single UI component or group of components
  • E2E - Full feature with no mocking
  • System - Entire Cypress app in real-world conditions
  • Snapshot - Text output comparison (CLI tests)
  • Screenshot - Visual regression testing via Percy

Development Workflow Example (Frontend Feature):

  1. Write failing component test
  2. Build component to pass test
  3. Repeat until feature requirements met
  4. Add CSS for design completeness
  5. Add screenshot test
  6. Write E2E test for integration
  7. Add performance tests if needed

Component & E2E Testing

Component tests should assert both user-facing behavior and developer contracts (props, events, side effects). Use mountFragment() to mock GraphQL data scenarios.

Testing Best Practices:

  • Locate interactive elements by accessible name: cy.contains('button', 'Log In').click()
  • Assert non-interactive elements with semantic HTML: cy.contains('h1', 'Page Title').should('be.visible')
  • Use data-cy attributes only when content is dynamic or element type doesn't matter
  • Prefer Percy snapshots over hardcoded CSS color assertions
  • Import test strings from i18n constants, not hardcoded

System Tests

System tests launch the Cypress server and run specs under real conditions. They live in system-tests/ with two parts:

  1. Test file in ./test - Mocha wrapper using systemTests helper
  2. Project fixture in ./projects - Self-contained Cypress project

Running system tests:

yarn test-system                          # Run all
yarn test-system screenshot*element       # Run matching specs
yarn test-system go_spec.js --no-exit     # Keep browser open
yarn test-system go_spec.js --cypress-inspect-brk  # Debug Cypress process

Updating snapshots:

SNAPSHOT_UPDATE=1 yarn test-system go_spec

Docker Testing

For CI environment reproduction, use Docker:

yarn docker                 # Run in CI Docker image
docker compose run --service-port dev  # Performance-constrained environment

Dependency Management

Add dependencies from the repository root using Yarn workspaces:

yarn add -W my-new-dep              # Add to root
yarn workspace @packages/server add my-new-dep  # Add to specific package

Note: There is a known Yarn bug with workspace dependencies. If issues occur, temporarily downgrade: npx yarn@1.19.1 workspace @packages/server add my-dep.

Code Quality

  • Linting: ESLint via @cypress/eslint-plugin-dev; auto-fixed with lint-staged pre-commit hook
  • No Prettier: Repository uses .prettierignore to disable Prettier formatting
  • Links: Use https://on.cypress.io/slug redirects for documentation links (requires internal PR to cypress-services)

Pull Request Guidelines

  • Use semantic-release prefixes: feat, fix, breaking, perf, test, docs, chore, refactor
  • Add changelog entry to cli/CHANGELOG.md for user-facing changes
  • Require minimum two approvals before merge
  • Use Squash and merge (exceptions: language conversions, release branch merges)
  • Allow maintainer edits for smoother collaboration

Utilities & Tooling

Relevant Files
  • packages/errors
  • packages/telemetry
  • packages/socket
  • tooling/v8-snapshot
  • tooling/packherd
  • tooling/electron-mksnapshot

Cypress includes several utility packages and build tooling that support core functionality across the application. These tools handle error management, observability, real-time communication, and performance optimization through snapshot generation.

Error Handling

The @packages/errors module provides centralized error definitions and utilities for Cypress. It exports error types, formatting utilities, and stack trace processing functions. This package standardizes how errors are created, displayed, and handled throughout the codebase, ensuring consistent error messages and proper stack trace manipulation.

Telemetry & Observability

The @packages/telemetry package wraps OpenTelemetry to collect performance and usage insights. Telemetry is disabled by default but can be enabled via CYPRESS_INTERNAL_ENABLE_TELEMETRY="true". The system uses spans to measure timing between events and supports three execution contexts:

  • Server Process - Main Cypress server, exports data via HTTP to Cypress Cloud
  • Child Process - Worker processes, forwards spans via IPC to the server
  • Browser - Cypress app running in Electron, sends spans via WebSocket

Spans can be started, retrieved, and ended independently, allowing flexible timing across async operations. Active spans automatically nest child spans, creating hierarchical traces for complex workflows.

Socket Communication

The @packages/socket package provides a shared Socket.IO implementation for real-time bidirectional communication between server and client. It exports both server-side and browser-side APIs, with support for standard Socket.IO events (connect, disconnect, event) and Chrome DevTools Protocol (CDP) socket variants for browser automation.

Build & Performance Tooling

Three specialized tools optimize Cypress startup performance:

V8 Snapshots (@tooling/v8-snapshot) - Creates V8 heap snapshots of bundled modules that are embedded in the Electron app. The Snapshot Doctor analyzes modules to determine which can be fully initialized, deferred, or marked as non-rewritable, balancing startup speed with compatibility.

Packherd (@tooling/packherd) - Bundles application files and dependencies using esbuild, producing metadata for snapshot generation. It also provides on-demand TypeScript transpilation with caching.

Electron mksnapshot (@tooling/electron-mksnapshot) - Wraps the Electron mksnapshot binary to support multiple Electron versions, downloading matching versions on-demand rather than at install time.

Loading diagram...

These tools work together to reduce startup latency by pre-initializing frequently-used modules into the application binary.