How to Set Up Automated Regression Testing in Cypress
Every time your team ships a new feature, there is a risk that existing functionality breaks. Manual regression testing is slow, inconsistent, and scales terribly — what took 30 minutes to test manually when you had 10 features takes a full day when you have 100. Automated regression tests run the same checks in minutes, every time, with perfect consistency.
Cypress is the most popular end-to-end testing framework for web applications, known for its developer-friendly API, real browser execution, and visual debugging tools. This guide covers setting up Cypress for regression testing specifically — organizing tests around critical user flows, running them in CI, and maintaining them as your product evolves.
Step-by-step guide
Install Cypress and configure the project
Install Cypress as a dev dependency with npm install -D cypress. Run npx cypress open to launch the Cypress GUI and initialize the project structure. Configure cypress.config.ts with your application's base URL, viewport dimensions, and timeout settings. Set the base URL to your local development server so tests run against a consistent target.
- Run npm install -D cypress and npx cypress open to initialize the project
- Set baseUrl in cypress.config.ts to your local dev server (e.g., http://localhost:3000)
- Configure default viewport to match your primary user device (1280x720 for desktop, 375x812 for mobile)
Identify your critical regression test scenarios
List the 10-15 user flows that must never break: signup, login, core feature usage, payment, and data CRUD operations. Prioritize flows by business impact — a broken checkout flow costs revenue, while a broken profile edit is an inconvenience. Your initial regression suite should cover these high-impact flows with broad coverage, not deep edge-case testing.
- List every user flow that directly impacts revenue or activation if broken
- Rank flows by severity: P0 flows (signup, payment, core feature) are first to automate
- Write the test scenario names in a document before writing any code to align with the team
Write your first regression test for the critical path
Create a test file for your most critical flow — typically the signup-to-activation path. Use Cypress commands (cy.visit, cy.get, cy.type, cy.click, cy.should) to simulate the user journey. Each test should cover one complete flow, asserting on key outcomes rather than implementation details. Use data-testid attributes for selectors so tests survive CSS and text changes.
- Use cy.visit('/') to start from the entry point and navigate through the flow naturally
- Select elements using data-testid attributes rather than CSS classes or text content
- Assert on visible outcomes ('success message is visible') not implementation details ('API returned 200')
Organize tests by feature area and priority
Structure your cypress/e2e directory with subdirectories for each feature area: auth/, onboarding/, billing/, core/. Within each directory, name test files descriptively: login.cy.ts, signup-flow.cy.ts, checkout.cy.ts. Add a @regression tag to all regression tests and a @smoke tag to the critical subset that runs on every commit. This organization lets you run targeted test suites based on what changed.
- Create directories for each feature area: cypress/e2e/auth/, cypress/e2e/core/, cypress/e2e/billing/
- Name test files after the user flow they cover, not the page they test
- Use Cypress tags or grep plugin to mark tests as @smoke (fastest, most critical) or @regression (full suite)
Configure CI integration for automated execution
Add Cypress to your CI pipeline (GitHub Actions, CircleCI, or Jenkins) so tests run on every pull request. Use the official Cypress GitHub Action or Docker image for consistent execution. Run the smoke suite on every PR and the full regression suite on merges to main. Configure the CI step to fail the build if any regression test fails, blocking deployment of broken code.
- Add the Cypress GitHub Action to your CI workflow with the start command pointing to your dev server
- Run the @smoke subset on PRs and the full @regression suite on merges to main
- Configure the CI job to upload test artifacts (screenshots and videos) on failure for debugging
Maintain tests as the product evolves
Set up a process for updating regression tests when features change. When a PR modifies a feature covered by a regression test, require the test to be updated in the same PR. Review flaky tests weekly — a test that sometimes passes and sometimes fails is worse than no test because it erodes trust in the suite. Fix or delete flaky tests immediately rather than letting them accumulate.
- Add a CI check that runs affected regression tests when specific files change using path-based triggers
- Track test flakiness using Cypress Dashboard or a simple pass/fail log to identify problematic tests
- Hold a monthly test maintenance session where the team fixes flaky tests and adds coverage for new features
Common mistakes
Writing tests that depend on specific data or state
Tests that assume a specific user exists in the database or a specific item is in a list break when the test data changes. Use setup and teardown hooks (beforeEach, afterEach) to create the test data each test needs, or use API calls to seed data at the start of each test run.
Using brittle selectors like CSS classes or text content
Tests that select elements by class name (.btn-primary) or text content ('Submit') break whenever the UI is styled or copy is updated. Use dedicated data-testid attributes that exist solely for testing and are stable across design changes.
Testing too many things in one test
A single test that covers signup, onboarding, feature usage, and billing is impossible to debug when it fails. Each test should cover one flow with a clear pass/fail signal. Longer journeys should be broken into independent tests that can fail independently.
Ignoring flaky tests instead of fixing them
A test that fails intermittently and gets retried until it passes teaches the team to ignore test failures. Track flaky tests, fix the root cause (usually timing issues or test data collisions), and delete any test you cannot stabilize within a week.
Tips
Use cy.intercept() to mock API responses for edge cases and error states that are difficult to reproduce with a real backend
Run Cypress in headless mode in CI (cypress run) and headed mode locally (cypress open) for the best development experience
Use Cypress's built-in retry-ability (cy.should() automatically retries assertions) instead of adding explicit waits that slow down tests
Record test runs to Cypress Cloud for team visibility into test history, flake detection, and parallelized execution
How Vantage helps
Vantage generates implementation tickets that include testing tasks alongside feature development. When your PRD specifies a user flow, Vantage can generate corresponding regression test tickets that reference the exact acceptance criteria, ensuring test coverage is planned from the start rather than tacked on after shipping.