blogs/CypressTutorial
View on GitHub
TypeScript

Cypress E2E Testing — Staff Engineer Learning Repository

A comprehensive, production-grade learning repository for mastering Cypress E2E testing at Staff Engineer depth.

What This Repository Teaches

This is not a beginner tutorial. It's a deep-dive into Cypress architecture, test design, reliability, and CI strategy — the knowledge a Staff Engineer needs to own E2E testing for a production application.

Topics Covered

AreaDepth
Cypress ArchitectureRuntime model, command queue, browser/Node split
ConfigurationMulti-env configs, CI config, timeouts, reporters
Test DesignPatterns for auth, forms, tables, CRUD, error states
Network StrategyStubbing vs live backend, intercept patterns, API seeding
Authenticationcy.session, programmatic login, role-based testing
ReliabilityFlake reduction, deterministic data, resilient selectors
CI/CDParallelization, artifacts, smoke tests, quarantine
ArchitectureCustom commands vs helpers vs Page Objects
DebuggingCommand log, screenshots, videos, triage workflow

Repository Structure

text
├── cypress/
│   ├── e2e/                          # Test specs organized by feature
│   │   ├── auth/                     # Login, logout, protected routes
│   │   ├── dashboard/                # Dashboard data, loading, errors
│   │   ├── forms/                    # Form submission, validation
│   │   ├── tables/                   # Sorting, filtering, pagination
│   │   ├── uploads/                  # File upload testing
│   │   ├── error-handling/           # Error states, network failures
│   │   ├── search/                   # Search and filtering flows
│   │   ├── crud/                     # Full CRUD workflow tests
│   │   └── navigation/              # Protected routes, role-based access
│   ├── fixtures/                     # Static test data
│   │   ├── users/                    # User profile fixtures
│   │   ├── api-responses/            # API response fixtures
│   │   └── forms/                    # Form data fixtures
│   ├── support/
│   │   ├── commands.ts               # Custom Cypress commands
│   │   ├── e2e.ts                    # Support file (runs before each spec)
│   │   ├── selectors.ts              # Centralized selector registry
│   │   ├── utils/
│   │   │   ├── intercept-helpers.ts  # Reusable API intercept functions
│   │   │   └── test-helpers.ts       # Pure utility functions
│   │   └── builders/
│   │       └── employee-builder.ts   # Test data builder pattern
│   ├── configs/                      # Environment-specific configs
│   │   ├── ci.config.ts              # CI pipeline config
│   │   ├── staging.config.ts         # Staging environment config
│   │   └── production-smoke.config.ts # Production smoke test config
│   ├── downloads/                    # (gitignored) Downloaded files
│   ├── screenshots/                  # (gitignored) Failure screenshots
│   └── videos/                       # (gitignored) Test run videos
├── docs/                             # Comprehensive documentation
│   ├── cypress-overview.md           # What Cypress is, where it fits
│   ├── cypress-architecture.md       # Deep architecture dive
│   ├── cypress-configurations.md     # Configuration reference
│   ├── querying-and-assertion-strategy.md
│   ├── network-stubbing-and-api-strategy.md
│   ├── auth-testing-strategies.md
│   ├── reliable-e2e-patterns.md
│   ├── page-object-vs-app-actions.md
│   ├── flake-reduction.md
│   ├── debugging-guide.md
│   ├── ci-cd-strategy.md
│   ├── anti-patterns.md
│   └── staff-level-revision-cheatsheet.md
├── src/                              # Sample app (test target)
├── .github/workflows/                # CI pipeline definitions
│   ├── cypress-ci.yml                # PR/push E2E pipeline
│   └── cypress-smoke-schedule.yml    # Scheduled smoke tests
├── scripts/
│   └── run-e2e-local.sh             # Local test runner script
├── cypress.config.ts                 # Primary Cypress config
├── package.json
├── tsconfig.json
└── vite.config.ts

Quick Start

bash
# Install dependencies
npm install

# Open Cypress Test Runner (interactive)
npm run cy:open

# Run all tests headlessly
npm run cy:run

# Run specific test suites
npm run cy:run:auth        # Auth tests only
npm run cy:run:smoke       # Smoke tests only

# Run with specific browser
npm run cy:run:chrome
npm run cy:run:firefox

# Run with environment-specific config
npm run cy:run:ci          # CI config
npm run cy:run:staging     # Staging config
npm run cy:run:prod-smoke  # Production smoke

Key Architectural Decisions

1. Programmatic Login Everywhere Except Auth Specs

Only login.cy.ts tests the login UI. Every other spec uses cy.login() (programmatic, via API). This saves 2-5 seconds per test.

2. Stubbed APIs by Default, Live Backend for Integration

Most specs stub API responses for speed and determinism. The staging config runs against the real backend for integration confidence.

3. Test Data Builders Over Static Fixtures

Builders (buildEmployee().withRole('admin').build()) are preferred over fixture files for data that varies between tests.

4. Centralized Selectors

All data-testid selectors live in selectors.ts. When the UI changes a testid, fix it in one place.

5. No Retries Locally, 2 Retries in CI

Local development should surface flakes immediately. CI tolerates transient issues but tracks retry rates.

How to Study This Repository

  1. Start with docs: Read docs/cypress-overview.md and docs/cypress-architecture.md
  2. Understand config: Study cypress.config.ts and the variants in cypress/configs/
  3. Learn the support layer: Read commands.ts, selectors.ts, intercept-helpers.ts
  4. Study test patterns: Go through specs in order: auth → dashboard → forms → tables
  5. Go deeper: Read remaining docs on flake reduction, CI/CD, anti-patterns
  6. Self-assess: Use docs/staff-level-revision-cheatsheet.md for interview prep

For Each Concept

Every spec and support file includes inline comments explaining:

  • What it does
  • Why it exists
  • When to use it
  • When not to use it
  • Common mistakes to avoid
  • Staff-level tradeoffs

Test Classification

TypeScopeWhen to RunConfig
SmokeCritical paths onlyEvery deploy, every 30minproduction-smoke.config.ts
RegressionAll E2E testsEvery PRci.config.ts
LocalAll or targetedDuring developmentcypress.config.ts
StagingFull suite, live backendPre-releasestaging.config.ts

Cypress vs Playwright — Quick Comparison

AspectCypressPlaywright
ArchitectureIn-browser, same event loopOut-of-process, CDP/WebSocket
Multi-tabNot supportedSupported
Multi-browserChrome, Firefox, EdgeChrome, Firefox, Safari, Edge
ParallelismVia Cypress Cloud or manual splitBuilt-in, free
Network mockingcy.intercept (powerful)route.fulfill (similar)
RetriesBuilt-inBuilt-in
Component testingYesYes
Mobile testingViewport onlyDevice emulation
Learning curveLowerHigher
CommunityMature, largeGrowing fast
Best forTeams already using it, simpler setupsNew projects, multi-browser needs

License

MIT — Use this for learning, adapt for your projects.