One of Cypress’s greatest strengths is how quickly you go from zero to a running test. A single npm install command installs Cypress and all its dependencies — including a bundled browser (Electron). There is no separate driver download, no Java runtime, no PATH configuration. Within five minutes of installation, you can have a test running against a live website. This lesson walks through the complete setup, folder structure, and configuration.
Installing Cypress and Exploring the Project Structure
Cypress is installed as a Node.js package and configured via a single JavaScript or TypeScript config file.
// ── Step 1: Initialise a Node.js project ──
// $ mkdir cypress-project && cd cypress-project
// $ npm init -y
// ── Step 2: Install Cypress ──
// $ npm install cypress --save-dev
// ── Step 3: Open Cypress for the first time ──
// $ npx cypress open
// This launches the Test Runner, creates the default folder structure,
// and lets you select E2E or Component testing.
// ── Step 4: Choose E2E Testing in the UI ──
// Cypress generates the following folder structure:
/*
cypress-project/
cypress/
e2e/ # Your test files (.cy.ts or .cy.js)
spec.cy.ts # Example test (auto-generated)
fixtures/ # Static test data (JSON files)
example.json
support/
commands.ts # Custom Cypress commands
e2e.ts # Support file — runs before every test
cypress.config.ts # Main configuration file
package.json
tsconfig.json # TypeScript config (if using TS)
*/
// ── cypress.config.ts — Main configuration ──
import { defineConfig } from 'cypress';
export default defineConfig({
e2e: {
baseUrl: 'https://www.saucedemo.com', // Prepended to cy.visit('/')
defaultCommandTimeout: 6000, // Retry timeout for commands (ms)
viewportWidth: 1280, // Browser viewport width
viewportHeight: 720, // Browser viewport height
video: false, // Disable video recording (saves time)
screenshotOnRunFailure: true, // Auto-screenshot on failure
retries: {
runMode: 2, // Retry failed tests 2x in CI (cypress run)
openMode: 0, // No retries in interactive mode
},
specPattern: 'cypress/e2e/**/*.cy.{js,ts}', // Test file pattern
supportFile: 'cypress/support/e2e.ts',
},
});
// ── package.json scripts ──
/*
{
"scripts": {
"cy:open": "cypress open", // Interactive Test Runner
"cy:run": "cypress run", // Headless CLI execution (CI)
"cy:run:chrome": "cypress run --browser chrome",
"cy:run:firefox": "cypress run --browser firefox"
}
}
*/
// ── Verify installation ──
// $ npx cypress verify
// Output: "Cypress is installed correctly"
// ── Run in headless mode (CI) ──
// $ npx cypress run
// Runs all specs headlessly, outputs results to terminal
// ── Run specific spec ──
// $ npx cypress run --spec "cypress/e2e/login.cy.ts"
console.log("Cypress installed and configured!");
console.log("Interactive: npx cypress open");
console.log("Headless CI: npx cypress run");
npx cypress open) launches the interactive Test Runner with time-travel debugging, DOM snapshots, and real-time reloading. Run mode (npx cypress run) executes tests headlessly in the terminal — this is what you use in CI/CD. The retries configuration lets you set different retry counts for each mode: typically 0 retries in open mode (you want to see failures immediately during development) and 1-2 retries in run mode (to handle transient CI flakiness).baseUrl in cypress.config.ts immediately after installation. This lets you write cy.visit('/') and cy.visit('/login') in your tests instead of repeating the full URL. It also makes switching between environments trivial: CYPRESS_BASE_URL=https://staging.app.com npx cypress run overrides the config value via environment variable without editing any file.npm install -g cypress). Install it as a dev dependency in each project (npm install --save-dev cypress). Global installations create version conflicts between projects and make CI/CD setup unreliable because the CI machine may not have the global package. Project-local installation ensures every team member and every CI run uses the exact same Cypress version.Common Mistakes
Mistake 1 — Skipping the cypress.config.ts configuration
❌ Wrong: Using all default settings without configuring baseUrl, timeouts, or viewport — then hardcoding full URLs in every test.
✅ Correct: Setting baseUrl, defaultCommandTimeout, viewportWidth/Height, and retries immediately after installation. These settings apply globally and eliminate repetitive configuration in individual tests.
Mistake 2 — Enabling video recording in development
❌ Wrong: Leaving video: true (the default) during local development — every test run generates a video file, consuming disk space and slowing test completion.
✅ Correct: Setting video: false in config and enabling it only in CI where video evidence of failures is valuable: CYPRESS_VIDEO=true npx cypress run.