Day 1: Welcome to Cypress
What You'll Learn Today
- What E2E testing is and why it matters
- The testing pyramid concept (Unit, Integration, E2E)
- What Cypress is, its features, and advantages
- Cypress vs Selenium comparison
- Cypress architecture
- Installation and initial setup
- How to use the Cypress Test Runner
What Is E2E Testing?
When developing web applications, you need to verify behaviors like "Does clicking this button navigate to the correct page?" or "Does submitting a form actually save the data?" Checking all of this manually every time is tedious and error-prone.
E2E (End-to-End) testing is a testing approach that automates browser interactions to verify your entire application works correctly β just as a real user would experience it.
flowchart LR
subgraph Manual["Manual Testing"]
M1["Open the browser"]
M2["Fill in the form"]
M3["Click the button"]
M4["Visually verify results"]
end
subgraph E2E["E2E Testing (Automated)"]
E1["cy.visit()"]
E2["cy.type()"]
E3["cy.click()"]
E4["cy.should() auto-verifies"]
end
M1 --> M2 --> M3 --> M4
E1 --> E2 --> E3 --> E4
style Manual fill:#f59e0b,color:#fff
style E2E fill:#22c55e,color:#fff
Why Do We Need E2E Testing?
| Problem | How E2E Testing Helps |
|---|---|
| Manual testing is time-consuming | Automated tests finish in minutes |
| Humans make mistakes | Tests execute the same steps accurately every time |
| Regressions are hard to detect | Automatically checks the entire app after every change |
| Cross-browser verification is tedious | Can run automatically across multiple browsers |
| Verifying after late-night deployments | Runs automatically in CI/CD pipelines |
The Testing Pyramid
Software testing comes in several types depending on scope and purpose. The testing pyramid provides a systematic way to think about them.
flowchart TB
subgraph Pyramid["Testing Pyramid"]
E2E["E2E Tests\n(Few Β· High cost Β· High confidence)"]
INT["Integration Tests\n(Moderate)"]
UNIT["Unit Tests\n(Many Β· Low cost Β· Fast)"]
end
E2E --> INT --> UNIT
style E2E fill:#ef4444,color:#fff
style INT fill:#f59e0b,color:#fff
style UNIT fill:#22c55e,color:#fff
| Test Type | Scope | Speed | Cost | Example |
|---|---|---|---|---|
| Unit Tests | Individual functions/components | Fast | Low | Testing input/output of a calculation function |
| Integration Tests | Multiple components working together | Moderate | Moderate | Testing API and database interaction |
| E2E Tests | The entire application | Slow | High | User login flow |
Testing Pyramid Principles
- Write the most unit tests: They are fast and stable
- Limit E2E tests to critical flows: They are slow to run and expensive to maintain
- Balance is key: Each layer of tests complements the others to ensure quality
What Is Cypress?
Cypress is an E2E testing framework built for modern web applications. Development began in 2014 by Brian Mann, with the goal of fundamentally solving the problems that plagued traditional Selenium-based testing tools.
Key Features of Cypress
- Runs directly in the browser: Test code executes within the same browser as your application
- Auto-waiting: Automatically waits for elements to appear and animations to complete
- Time-travel debugging: Review each test step through DOM snapshots
- Real-time reloading: Tests re-run automatically when you save a test file
- Stubs and spies: Easily mock and intercept network requests
flowchart TB
subgraph Features["Cypress Features"]
F1["Auto-waiting"]
F2["Time-travel\nDebugging"]
F3["Real-time\nReloading"]
F4["Network\nStubbing"]
F5["Screenshots\n& Video Recording"]
end
style Features fill:#3b82f6,color:#fff
Cypress vs Selenium
Let's compare Cypress with Selenium, the long-established E2E testing tool.
flowchart TB
subgraph Selenium["Selenium Architecture"]
S_TEST["Test Code"]
S_DRIVER["WebDriver"]
S_BROWSER["Browser"]
S_APP["Application"]
end
subgraph Cypress["Cypress Architecture"]
C_TEST["Test Code"]
C_BROWSER["Browser (Same Process)"]
C_APP["Application"]
end
S_TEST --> S_DRIVER --> S_BROWSER --> S_APP
C_TEST --> C_BROWSER
C_BROWSER --> C_APP
style Selenium fill:#f59e0b,color:#fff
style Cypress fill:#3b82f6,color:#fff
Selenium places a WebDriver layer between the test code and the browser, while Cypress executes test code directly inside the browser. This architectural difference brings numerous advantages.
| Aspect | Selenium | Cypress |
|---|---|---|
| Architecture | Controls the browser externally via WebDriver | Runs directly inside the browser |
| Setup | Requires installing and managing WebDriver | Just npm install |
| Languages | Java, Python, C#, Ruby, JavaScript, etc. | JavaScript only |
| Browser Support | Chrome, Firefox, Safari, Edge, IE | Chrome, Firefox, Edge, Electron |
| Auto-waiting | Must write manual waits | Built-in auto-waiting |
| Debugging | Difficult (external process) | Time-travel debugging |
| Network Control | Requires external proxy | Built-in interception |
| Execution Speed | Relatively slow | Fast |
| Learning Curve | Steep | Gentle |
When Cypress Is a Good Fit
- Testing modern JavaScript frameworks (React, Vue, Angular, etc.)
- Frontend-focused E2E testing
- Teams proficient in JavaScript
- When fast feedback loops are essential
When Selenium Is a Better Fit
- Multi-language support is required
- Safari or legacy browser testing is mandatory
- Large-scale cross-browser testing is needed
Cypress Architecture
Cypress has a fundamentally different architecture from traditional testing tools.
flowchart TB
subgraph Browser["Browser (Electron / Chrome)"]
subgraph CypressRunner["Cypress Test Runner"]
SPEC["Test Files\n(spec.cy.js)"]
CMD["Cypress Commands\n(cy.get, cy.click, etc.)"]
end
subgraph AppFrame["Application iframe"]
APP["Application\nUnder Test"]
DOM["DOM"]
end
CMD --> DOM
end
subgraph NodeServer["Node.js Server"]
PROXY["Proxy"]
FILE["File System"]
NET["Network Control"]
end
Browser <--> NodeServer
style Browser fill:#3b82f6,color:#fff
style NodeServer fill:#8b5cf6,color:#fff
style CypressRunner fill:#22c55e,color:#fff
style AppFrame fill:#f59e0b,color:#fff
Architecture Highlights
- Test code runs inside the browser: Since it shares the same execution environment as the application, it has direct access to the DOM
- Node.js server handles the backend: File operations and network control are processed by a Node.js process
- Proxy-based network control: All HTTP requests pass through a proxy, enabling request interception and mocking
Installation and Setup
Prerequisites
- Node.js 18 or later installed
- npm or yarn available
Installation Steps
# Create a project directory
mkdir my-cypress-project
cd my-cypress-project
# Initialize package.json
npm init -y
# Install Cypress
npm install cypress --save-dev
Once installation is complete, the executable is placed at node_modules/.bin/cypress.
First Launch
# Launch the Cypress Test Runner
npx cypress open
On the first launch, Cypress automatically creates the following directory structure:
my-cypress-project/
βββ cypress/
β βββ e2e/ # Directory for test files
β βββ fixtures/ # Test data (JSON, etc.)
β βββ support/ # Custom commands and global configuration
β β βββ commands.js # Custom command definitions
β β βββ e2e.js # Global configuration for E2E tests
β βββ downloads/ # Downloaded file storage
βββ cypress.config.js # Cypress configuration file
βββ package.json
Basic cypress.config.js Configuration
The Cypress configuration file is cypress.config.js. Let's look at the key settings.
const { defineConfig } = require('cypress')
module.exports = defineConfig({
e2e: {
// Base URL for the application under test
baseUrl: 'http://localhost:3000',
// Test file pattern
specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
// Viewport size
viewportWidth: 1280,
viewportHeight: 720,
// Screenshot on test failure
screenshotOnRunFailure: true,
// Video recording of test runs
video: false,
// Timeout settings (milliseconds)
defaultCommandTimeout: 4000,
pageLoadTimeout: 60000,
// Retry settings
retries: {
runMode: 2, // Retries when running cypress run
openMode: 0, // Retries when running cypress open
},
setupNodeEvents(on, config) {
// Register Node.js event listeners
},
},
})
Key Configuration Options
| Option | Default | Description |
|---|---|---|
baseUrl |
null | Base URL for cy.visit('/') |
viewportWidth |
1000 | Browser width |
viewportHeight |
660 | Browser height |
defaultCommandTimeout |
4000 | Command timeout (ms) |
pageLoadTimeout |
60000 | Page load timeout (ms) |
video |
false | Video recording of test runs |
screenshotOnRunFailure |
true | Screenshot on failure |
retries |
{ runMode: 0, openMode: 0 } |
Number of test retries |
The Cypress Test Runner
Launching the Test Runner with npx cypress open opens a GUI.
Main Components of the Test Runner
- Test type selection screen: Choose between E2E Testing or Component Testing
- Browser selection: Choose the browser for running tests (Chrome, Firefox, Edge, Electron)
- Test file list: Displays available test files
- Test execution view: Command log on the left, application preview on the right
Running in Headless Mode
In CI/CD environments, you run tests without a GUI.
# Run all tests in headless mode
npx cypress run
# Run a specific test file
npx cypress run --spec "cypress/e2e/login.cy.js"
# Run with a specific browser
npx cypress run --browser chrome
Summary
| Concept | Description |
|---|---|
| E2E Testing | Tests that automate user interactions to verify the entire application |
| Testing Pyramid | A three-layer structure: Unit β Integration β E2E. Write more tests at lower layers |
| Cypress | A modern E2E testing framework that runs directly inside the browser |
| Auto-waiting | Cypress automatically waits for elements to appear and animations to complete |
| Time Travel | A debugging feature that lets you inspect DOM snapshots at each test step |
| cypress.config.js | The Cypress configuration file for setting baseUrl, timeouts, etc. |
Key Points
- E2E testing is essential for automating manual tests and preventing regressions
- Cypress runs directly in the browser, enabling fast and stable tests
- The auto-waiting feature eliminates the need for sleep or wait calls in test code
Practice Exercises
Exercise 1: Basic
Describe the three layers of the testing pyramid and provide an example of what kind of test belongs at each layer.
Exercise 2: Applied
Explain the architectural differences between Cypress and Selenium, and list three advantages that Cypress's architecture provides.
Challenge Exercise
Set up Cypress in a new project and add the following settings to cypress.config.js: set the base URL to http://localhost:8080, the viewport size to 1920x1080, and the default command timeout to 10 seconds.
References
Next Up: In Day 2, we'll learn about writing your first test. You'll understand the structure of test files and write an actual E2E test for a Todo app.