Cypress Cloud: Recording, Test Replay, Orchestration & Analytics
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
Cypress is two products. The Cypress App is the free, open-source (MIT) test runner you use to write and run tests;
Cypress Cloud is a hosted service that receives the results of recorded runs and turns them into shared history,
debugging artifacts, orchestration and reports. This page covers the Cloud side. It targets Cypress 16.2.0 and was checked
on 25 October 2026, including the subscription tiers and prices in the last sections, which were read from the official pricing page on
that date. Everything that can run without a Cypress Cloud account was run against the Bookshelf demo application described
in Example Application & Test Layout: the test project,
the retry behaviour that Cloud classifies as flaky, the record flags and the errors they produce without a valid key, the
cy-cloud command line tool, and a webhook receiver that verifies signatures. No Cloud account was available, so
recording a real run, Test Replay, the dashboards, the integrations and the premium products are documented from the
official documentation and were not exercised; each section says so where it applies. Writing the tests themselves is
covered in Getting Started and the pages that follow it, and the
tool-independent view of CI and flakiness is in Running in CI/CD and
Flaky Tests & Reliability.
What Cypress Cloud is
Cypress Cloud never runs your tests and never sees your application’s source code. Your tests still execute on your own
machines (a laptop or CI agents) with the Cypress App; when you pass --record, the App also uploads the results, and
Cloud stores them. In exchange you get:
-
History and debugging: every recorded run with its tests, errors, screenshots, optional video and, on Chromium-based browsers, a Test Replay.
-
Orchestration: parallel runs balanced across your CI machines, with optional prioritization, cancellation and re-run optimization.
-
Test health: flaky test detection and alerts, Branch Review, and analytics for a project or a whole organization.
-
Workflow integrations: commit status checks and pull request comments, Slack, Microsoft Teams, Jira, webhooks, a command line tool and an MCP server for AI assistants.
-
Premium products: UI Coverage and Cypress Accessibility, built from the same captured data.
Source: Cypress Cloud introduction
The data stored for a recorded run is the terminal output, test results and definitions, the Cypress configuration (without Cypress environment variables), screenshots, videos, and the CI and git environment variables. With Test Replay enabled it also includes the rendered DOM and CSS, the Command Log events, network traffic and console logs of the application under test. Test content can be shared with an AI model only when Cloud AI features are enabled, and the documentation states that customer data is not used to train models.
Source: Data storage and controls
The test project used on this page
The examples use a small project, cy-cloud, with three spec files. The split into several files matters: Cypress
parallelizes whole spec files, so a project with a single spec cannot benefit from more than one machine.
// cypress.config.ts
import { defineConfig } from 'cypress';
export default defineConfig({
// Written into the file by "Connect to Cypress Cloud"; a 6-character id.
// This value is a placeholder, not a real project.
projectId: 'a1b2c3',
retries: { runMode: 2, openMode: 0 },
video: false,
screenshotsFolder: 'cypress/screenshots',
e2e: {
baseUrl: process.env.BASE_URL ?? 'http://localhost:3000',
specPattern: 'cypress/e2e/**/*.cy.ts',
supportFile: 'cypress/support/e2e.ts',
},
});
Source: Cypress Cloud: Project ID
// cypress/e2e/catalogue.cy.ts
describe('Catalogue', () => {
it('searches by title', () => {
cy.visit('/books');
cy.get('[data-testid=search-input]').type('quiet{enter}');
cy.get('[data-testid=book-card]').should('have.length', 1);
cy.contains('h3', 'The Quiet Compiler').should('be.visible');
});
it('paginates six books per page', () => {
cy.visit('/books');
cy.get('[data-testid=book-card]').should('have.length', 6);
});
});
Source: Writing and organizing tests
// cypress/e2e/reviews.cy.ts
describe('Reviews', () => {
beforeEach(() => {
cy.request('POST', '/api/test/seed');
cy.signIn('reader');
});
it('lets a reader add a review', () => {
cy.visit('/books/1');
cy.get('#rating').select('5');
cy.get('#text').type('A thorough and readable tour of compilers.');
cy.contains('button', 'Submit review').click();
cy.contains('[data-testid=review]', 'A thorough and readable tour').should('be.visible');
});
});
Source: cy.session
cy.signIn() is the cached-session command from Sessions, Authentication & Cross-Origin; it reads the password with cy.env() from the variable CYPRESS_READER_PASSWORD, so
no password appears in a file. The third spec fails on purpose on its first attempt, to show what Cloud calls a flaky test
(see Flaky test management):
// cypress/e2e/flaky-search.cy.ts
describe('Flaky by design', () => {
it('fails on the first attempt and passes on the retry', () => {
cy.visit('/books');
// Cypress.currentRetry is 0 on the first attempt, 1 on the first retry.
const expected = Cypress.currentRetry === 0 ? 7 : 6;
cy.get('[data-testid=book-card]').should('have.length', expected);
});
});
Source: Test retries
Running the project locally, without recording, against Bookshelf on port 3928 (Electron, headless, which is the default
for cypress run):
$ BASE_URL=http://localhost:3928 CYPRESS_READER_PASSWORD=$BOOKSHELF_READER_PASSWORD npx cypress run --browser electron
...
Flaky by design
(Attempt 1 of 3) fails on the first attempt and passes on the retry
✓ fails on the first attempt and passes on the retry (75ms)
1 passing (4s)
...
(Run Finished)
Spec Tests Passing Failing Pending Skipped
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ✔ catalogue.cy.ts 255ms 2 2 - - - │
├────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ✔ flaky-search.cy.ts 00:04 1 1 - - - │
├────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ✔ reviews.cy.ts 496ms 1 1 - - - │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
✔ All specs passed! 00:05 4 4 - - -
Source: Command line: cypress run
The terminal reports four passing tests and exit code 0, and the "Attempt 1 of 3" line is the only trace of the failed first attempt of the flaky test. Cypress also saved a failure screenshot for that attempt. This is exactly the situation where a terminal alone hides information that Cloud keeps. Electron is deprecated as a test browser since Cypress 16.0.0 and the run prints "Electron 146 (headless) (deprecated)"; it is used here because it ships with Cypress. Cloud features that need a Chromium-based browser (Test Replay) work with Chrome and Edge as well.
Recording a run
The projectId and the record key
Recording needs two identifiers, and both are created when you connect the project:
-
The projectId identifies the project. It is a six-character string that Cypress writes into the configuration file when you click Connect to Cypress Cloud on the Runs tab of the App. It is not secret; the documentation recommends committing it. If you prefer to keep it out of the file, set the environment variable
CYPRESS_PROJECT_ID. -
The record key authorizes the project to write runs. Anyone who holds both the projectId and the record key can record or cancel runs in the project, so treat the key as a secret. It does not allow reading runs. Pass it with
--keyor, in CI, as the operating system environment variableCYPRESS_RECORD_KEY. It is read from the real process environment; it is not read fromcypress.env.jsonor from theenvblock of the configuration, because those only feed test variables.
Whether a project is public or private also matters: anyone who knows the projectId of a public project can view its recorded runs, screenshots and Test Replays, while a private project is limited to invited users.
# direct
npx cypress run --record --key "$CYPRESS_RECORD_KEY"
# or, preferred in CI: the key comes from a secret in the environment
export CYPRESS_RECORD_KEY=... # injected by the CI provider's secret store
npx cypress run --record
Since Cypress 16, test code reads secrets with cy.env() and public values with Cypress.expose(), and Cypress.env() no
longer exists. That change is unrelated to recording: CYPRESS_RECORD_KEY and CYPRESS_PROJECT_ID are consumed by the
Cypress process itself, not by tests.
Because no Cloud account was available, no run was actually recorded for this page. What can be shown without an account is how the flags behave and which errors Cypress prints. These were run against the project above.
$ npx cypress run --record --spec cypress/e2e/catalogue.cy.ts
You passed the --record flag but did not provide us your Record Key.
You can pass us your Record Key like this:
$ cypress run --record --key <record_key>
You can also set the key as an environment variable with the name: CYPRESS_RECORD_KEY
# exit code 1
Source: Command line: record and key
The flags that only make sense for recorded runs are rejected when --record is missing:
$ npx cypress run --parallel --spec cypress/e2e/catalogue.cy.ts
You passed the --ci-build-id, --group, --tag, --parallel, or --auto-cancel-after-failures flag without also passing the --record flag.
The --parallel flag you passed was: true
The --auto-cancel-after-failures flag you passed was: undefined
These flags can only be used when recording to Cypress Cloud.
https://on.cypress.io/record-params-without-recording
# exit code 1
Source: Command line: cypress run
A project that has no projectId cannot record, and a record key is checked against the projectId on the Cloud side, so even
with network access an invalid key fails immediately and the tests are not run. In the commands below,
cypress.noid.config.ts is the configuration shown earlier without its projectId line, and the key is a made-up string:
$ CYPRESS_RECORD_KEY=not-a-real-key npx cypress run -C cypress.noid.config.ts --record --spec cypress/e2e/catalogue.cy.ts
You passed the --record flag but this project has not been setup to record.
This project is missing the projectId inside of: cypress.noid.config.ts
We cannot uniquely identify this project without this id.
You need to setup this project to record. This will generate a unique projectId.
Alternatively if you omit the --record flag this project will run without recording.
https://on.cypress.io/recording-project-runs
$ CYPRESS_PROJECT_ID=q9w8e7 CYPRESS_RECORD_KEY=not-a-real-key npx cypress run -C cypress.noid.config.ts --record --spec cypress/e2e/catalogue.cy.ts
Your Record Key not-a...l-key is not valid with this projectId: q9w8e7
It may have been recently revoked by you or another user.
Please log into Cypress Cloud to see the valid Record Keys.
https://on.cypress.io/dashboard/projects/q9w8e7
# exit code 1 for both commands
Source: Cypress Cloud: Projects
The second command shows two things at once: CYPRESS_PROJECT_ID is honoured when the file has no projectId, and a
failed authentication aborts the run with exit code 1 before any spec starts. A pipeline that records must therefore treat
the record key as a hard dependency. The placeholder values above are not real credentials.
Flags and environment variables that affect recording
| Option | Effect | Needs --record |
|---|---|---|
|
Upload results to Cypress Cloud. |
- |
|
The record key. |
yes |
|
Distribute spec files across the machines of one run. |
yes |
|
Label one |
yes |
|
The identifier that links several machines or groups to one run. Detected automatically on the common CI providers. |
yes |
|
One or more comma-separated tags on the run, useful as filters and for UI Coverage and Accessibility profiles. |
yes |
|
Overrides the project’s Auto Cancellation threshold for this run, or turns it off. Added in Cypress 12.6.0. |
yes |
|
Force the Cypress Runner UI to be rendered (or hidden) during |
no |
|
Project id when it is not in the configuration file. |
- |
|
Rerun group for re-run optimization on CI providers that are not detected automatically (Cypress 15.15.0 or later). |
- |
Source: Cypress command line
Cloud also reads git and CI information to label runs. When Cypress cannot see it (for example inside a container that
does not pass the CI variables through), set COMMIT_INFO_SHA, COMMIT_INFO_MESSAGE and the related variables yourself;
pull request comments and status checks depend on a correct commit SHA.
Recording works locally as well as in CI, but results recorded from a laptop count against the same usage allowance and
appear in the same run list. Teams normally record only in CI and run without --record while developing.
A recording workflow in GitHub Actions
The official cypress-io/github-action (v7, latest release 7.4.7 on 23 October 2026) maps the flags to inputs. The workflow
below records a run split across three machines. It was syntax-checked as YAML but not executed, because a recorded run
needs a Cloud account and a GitHub runner.
name: Cypress
on:
pull_request:
push:
branches: [main]
jobs:
cypress:
runs-on: ubuntu-24.04
strategy:
fail-fast: false # let every machine finish; Cypress Cloud balances the specs
matrix:
containers: [1, 2, 3] # three machines share one recorded run
steps:
- uses: actions/checkout@v7
- uses: cypress-io/github-action@v7
with:
start: npm start
wait-on: 'http://localhost:3000'
browser: chrome
record: true
parallel: true
group: 'bookshelf-chrome'
tag: ${{ github.event_name }}
env:
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
CYPRESS_READER_PASSWORD: ${{ secrets.BOOKSHELF_READER_PASSWORD }}
# Lets Cypress tell a new build from a re-run of the same build.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Report the pull request's own commit instead of the merge commit.
COMMIT_INFO_SHA: ${{ github.event.pull_request.head.sha }}
Source: Cypress: GitHub Actions
Passing GITHUB_TOKEN lets Cypress distinguish "re-run jobs" from a new build; without it a re-run can appear to pass with
no tests. COMMIT_INFO_SHA restores pull request comments that otherwise point at the synthetic merge commit. Other
providers follow the same pattern; see
Running in CI/CD for the provider-neutral view.
Recorded runs
Every recorded run appears under Latest Runs, filterable and paginated, with the branch, author, commit, duration and counts of flaky, skipped, pending, passed and failed tests. The details page of one run has four tabs:
-
Overview: the run duration graph against previous runs (with markers where configuration changed), a Recommendations box that simulates your last 100 tests under different Smart Orchestration settings, and the Tests for Review panel, which orders what needs attention: failed first, then flaky, then modified.
-
Test Results: every test, sortable and filterable by status or flakiness.
-
Specs: the spec files as a timeline, a bar chart of durations or a machines view of how a parallel run was distributed.
-
Errors: the errors thrown during the run, grouped, each linking to the test.
Opening a test shows a detail sidebar: status and spec, a Cloud AI "Test Intent Summary" and "At a glance" Error Summary (when Cloud AI is enabled), each attempt with its error, stack trace and code frame, the history of previous runs of that test, the screenshots, videos and CI log, and the commits that touched the test with their diffs. The diff is of the transpiled code, since source maps are not collected.
A test is marked Modified when its body or the hooks around it (before, beforeEach, afterEach, after) differ from
an earlier recorded version, and New when none exists. Tests are matched by spec file path and test title, so renaming
either makes Cloud see a new test. The comparison also considers the base branch, so a test may show as modified in a branch
where you did not touch it.
A run in progress can be cancelled from its page (by project members) or through the Run Cancellation API (which needs the record key); results already recorded still count toward your usage. Cancelled or errored runs can be archived, which hides them from lists and analytics but not from usage counts.
The Cypress App connects to the same data. After you log in, the Runs page shows recorded runs for the current branch, the Debug page brings failed CI runs into the App so you can rerun and debug them locally, and, since Cypress 12.17.0 on macOS and Linux, desktop notifications tell you when a run on your current commit starts, fails or completes.
Source: Recorded runs
Test Replay
Test Replay replaces "reproduce it locally" for failures that happened in CI. During a recorded cypress run, Cypress
captures the commands, network requests, console logs, JavaScript errors, DOM mutations, CSS, SVG, iframes, shadow DOM and
canvas elements. Cloud rebuilds the page from that data, so you open a test and get the Command Log with time travel, the
developer tools (network, console, element inspection) and playback controls, with a timeline that lets you scrub through
each attempt. It is the same debugging model as the App’s Command Log, but for a run that is long over.
-
Enable: it is on by default for recorded runs; there is nothing to add to the tests. You can switch it off per project in the Test Replay section of the project settings (the canvas capture has its own toggle, worth disabling if you have many or large canvas elements).
-
Where: it needs Cypress 13.0.0 or later and a Chromium-based browser (Chrome, Edge, or Electron). Firefox and WebKit runs do not produce a Test Replay.
-
Plans: it is available on every plan, including Starter, within the usage limits.
-
Access: from the hover actions on a Test for Review, from the header of the test detail sidebar, or above each attempt.
-
Not captured: video and audio elements,
localStorageandsessionStorage, cookies, network traffic ofcy.request(), web sockets, server-sent events, shadow DOM canvases andslotAssignment="manual"shadow roots, among others listed in the documentation. -
Cost: capturing uses some resources, comparable to recording video. Disable video when you rely on Test Replay (the project above sets
video: false; the default is alreadyfalsesince Cypress 13). To keep the standard terminal output informative, the upload size and time are printed, for example "Test Replay - 298 kB" in the documentation’s example. -
Runner UI: with Test Replay on, the Cypress Runner UI is no longer rendered during
cypress run, which speeds up runs on small machines; screenshots and video therefore show only the page. Pass--runner-uito bring it back.
Test Replay data is visible to everyone with access to the project. By default Cypress redacts sensitive values locally,
before upload: authentication headers (authorization, cookie, set-cookie, x-api-key), credential fields in bodies
(password, client_secret, access, refresh and ID tokens), tokens in URL parameters, and JWT and SAML patterns, shown
as (redacted). Values typed into password, hidden and payment fields are masked with asterisks. Response bodies larger
than 512 KB are dropped. Owners and admins can turn redaction or masking off per project, which you should do only with
test data that contains nothing sensitive.
Troubleshooting follows a short list: the button is disabled when the run used a version older than 13, a non-Chromium browser, a project with Test Replay disabled, or when the upload failed (network, firewall, or a spec that outlasted the project’s run timeout; see the standard output of the spec).
The same captured data is reachable from a terminal, which is useful for scripts and AI agents:
cy-cloud replay info --testId <testId>
cy-cloud replay timeline --testId <testId> --commands --aroundFailure 5 --network --logs
Source: Test Replay
These commands need an authenticated Cloud account and were not run here. Test Replay itself was not run either, since no recorded run exists.
Smart Orchestration
Smart Orchestration is the family of features that run your recorded tests faster and cheaper in CI.
| Feature | What it does | Plans |
|---|---|---|
Parallelization |
Runs spec files simultaneously on several CI machines. |
All, including Starter |
Load balancing |
Assigns specs to machines from the measured duration history, longest first, so machines finish together. |
All |
Manual cancellation |
Cancel a run in progress from the UI or the Run Cancellation API. |
All |
Spec Prioritization |
Moves specs that failed in the previous run to the front of the queue. |
Business, Enterprise |
Auto Cancellation |
Cancels the run once failed tests reach a threshold. |
Business, Enterprise |
Re-run optimization |
When a CI build is re-run, skips what already passed (experimental). |
Business, Enterprise |
Source: Smart Orchestration overview
Parallelization and load balancing
Cypress parallelizes by spec file. Add --parallel (together with --record) on every machine that belongs to the run, and
Cloud coordinates them: each machine reports the specs it knows about, asks for work, and receives one spec at a time.
Source: Parallelization
Behaviour worth knowing:
-
Order is not guaranteed. Specs are handed out dynamically, longest estimated duration first, so a run is not alphabetical. Specs must not depend on each other.
-
Estimates come from history, per spec and per browser, and old data is discarded so estimates follow the suite. The first runs of a new project are therefore less well balanced.
-
Whole files are the unit. One slow spec limits the run however many machines you add. Aim for specs of similar length; splitting specs shorter than about ten seconds is rarely worth it because browser start-up and uploads dominate. The Specs tab (bar chart and machines views) and the Recommendations box show where the imbalance is.
-
Linking machines uses a CI build id. Cypress derives it from the provider’s environment variables (for example
BUILD_NUMBERon Jenkins,CI_PIPELINE_IDon GitLab andBUILDKITE_BUILD_IDon Buildkite); pass--ci-build-idyourself when detection fails or you want a different identifier such asBUILD_TAG. -
Run Completion Delay. After the last known machine finishes, Cloud waits (60 seconds by default, configurable in project settings) in case another group is still queued, and only then marks the run complete. A short experimental Run Completion API (
POST https://api.cypress.io/runs/complete, authenticated with the projectId and record key) tells Cloud that no more groups are coming so webhooks, notifications and UI Coverage and Accessibility reports are not held back. -
Parallelism and usage. Parallelization is disabled when a plan’s test result allowance is exhausted and on-demand usage is not available; recording itself keeps working.
Groups
--group labels a cypress run call and attaches it to a shared run, with or without --parallel. It is the mechanism
behind cross-browser matrices, where each browser is a group of the same commit, and behind monorepos, where each package is
a group selected with --spec:
npx cypress run --record --group bookshelf-chrome --browser chrome --parallel
npx cypress run --record --group bookshelf-firefox --browser firefox --parallel
npx cypress run --record --group api --spec 'cypress/e2e/api/**/*'
Source: Grouping test runs
Group names must be unique within a run, and the machines of all groups need the same CI build id. These commands were not
run: they require a record key. A common convention is a prefix such as 2x-chrome to show the number of machines.
Branch Review depends on exactly one run per commit, so use groups instead of recording several independent runs for one
commit.
Spec Prioritization
When Spec Prioritization is on (Business and Enterprise), the specs that failed in the previous run of the same branch go first in the next run, still balanced across machines. After a fix the verdict arrives in minutes instead of waiting for the whole suite. The run’s Properties tab shows "Applied" and "Prioritized failed specs from run #N", and prioritized specs are marked in the Specs tab. It is enabled by a project admin in the Smart Orchestration section of the project settings.
Auto Cancellation
Auto Cancellation (Business and Enterprise) cancels the whole run once the number of failed tests across all machines reaches a threshold (1 by default). Flaky tests, which pass on a retry, do not count. Specs already in progress finish, and no machine starts a new spec. The threshold is a project setting, overridden per run:
npx cypress run --record --parallel --auto-cancel-after-failures 5
npx cypress run --record --parallel --auto-cancel-after-failures false # keep going on main
Source: Auto Cancellation
Disable it on protected branches and nightly runs that must report everything, and be aware that a cancelled run only scores the specs that ran, which affects UI Coverage and Accessibility reports. Pairing it with Spec Prioritization means the failure that cancels the run is found early.
Re-run optimization
Re-run optimization (Business and Enterprise, experimental) detects that a CI build is being re-run and avoids executing what already passed. Choose the granularity in the organization or project settings:
-
Run only failed specs: re-executes every spec that contained a failure (the default for new organizations).
-
Run only failed tests: re-executes only the tests that failed or were skipped, plus new or modified ones; it needs Cypress 15.21.0 or later and assumes each
itblock is independent (if it would work with.only, it works here). -
Run everything again: turns it off.
Cloud links the runs of one CI build through a rerun group id and uses the latest completed run of the group as the anchor.
GitHub Actions, Azure Pipelines, CircleCI, Bitbucket Pipelines and GitLab CI are detected automatically (CircleCI and
Bitbucket need Cypress 15.15.0 or later); elsewhere set CYPRESS_RERUN_GROUP_ID to a value shared by a build and its re-runs
and unique across builds. Because the anchor is the latest completed run, a re-run started during the Run Completion Delay
executes everything, which is what the Run Completion API above is for. Skipped specs and tests are not billed.
Source: Re-run optimization
None of the Smart Orchestration features was run for this page; each needs a recorded Cloud project, and spec prioritization, auto cancellation and re-run optimization additionally need a Business or Enterprise plan or a trial.
Flaky test management
A test is flaky when it fails an attempt and then passes on retry without a code change. Cypress Cloud detects flakiness
from test retries, so retries must be on for recorded runs; the project above has retries: { runMode: 2, openMode: 0 },
which retries only under cypress run. The local run shown earlier is a faithful miniature of what Cloud sees: attempt 1
fails, attempt 2 passes, the test is reported as passed, and the run is flagged as containing one flaky test. Cloud keeps
the failed attempt (error, screenshot and, with Test Replay, the full replay), which the terminal does not.
Flake detection, flake analytics and alerts need a Team plan or higher. The pieces are:
-
Flagging: runs with flaky tests carry a flaky count on Latest Runs, with a Flaky filter.
-
Severity: derived from the flake rate, the share of recent runs in which the spec had a flaky test (low: above 0 and up to 10%; medium: above 10% and up to 50%; high: above 50%).
-
Flaky test analytics: flaky tests over time, the project’s flakiness level, tests grouped by severity and a filterable log. Selecting a test shows its latest flaky runs, most common errors and the plot of failure rate versus flake rate. A test can have a failure rate of zero and still flake, since retries make the final status pass.
-
Alerting: a
cypress/flakecommit status on GitLab and Bitbucket and a flakiness section in GitHub pull request comments, plus a Flaky tests notification preference for Slack and Microsoft Teams that fires even when the run passed. -
Fixing: open a flaky run in Test Replay and compare a passing attempt with a failing one; the Cloud MCP tool
cypress_get_flaky_testslists them for an AI assistant. -
Across projects: Enterprise Reporting has a Flaky Tests tab and the Data Extract API exports the data.
The run.completed webhook carries flakyTestCount, which counts passing tests that failed at least one attempt.
Experimental flake-detection features that change a flaky test’s pass or fail result are described in the experiments
reference. The tool-independent discussion of why tests flake and how to remove the cause is in
Flaky Tests & Reliability.
Source: Flaky Test Management
Cloud was not available, so none of the detection, scoring or alert screens was seen; the local run above only demonstrates the retry behaviour that feeds them.
Branch Review
Branch Review compares a changed run with a base run in one view: new failures, flaky tests, pending tests, tests that were added or modified, and, if enabled, how UI Coverage and Accessibility changed. Every test state is labelled new (introduced by the branch), existing (already on the base) or resolved (no longer present), so reviewers can separate what the pull request caused from pre-existing noise. Opening a test shows the base and feature results side by side with Test Replay, screenshots, attempts and the code diff.
You reach it from the project list, the Branches navigation, a run’s branch name, or the "View all changes introduced in this branch" link in the Cypress pull request comment. It needs the GitHub integration with pull request comments for the pull-request path, but it compares any two runs, so it also works for nightly runs or different builds. If one branch has no run for the relevant commit, Branch Review falls back to the last run on that branch or shows non-comparison data; a banner names the missing commit. It is on every plan.
Source: Branch Review
Analytics
-
Project analytics (every plan): runs over time by final status, run duration with average parallelization and time saved by it (passing runs only), test suite size, top failures, slowest tests and most common errors. Reports filter by branch, tag, time range, interval, run group, committer, spec, browser, Cypress version and operating system, and download as CSV.
-
Enterprise Reporting (Enterprise): organization-wide cards in the tabs Overall Usage, Test Results, Test Setup, Test Execution, Flaky Tests and Raw Data, plus UI Coverage and Accessibility trends. Data is current up to midnight UTC of the previous day and can be downloaded as CSV, XLSX, JSON or PNG.
-
Data Extract API (Enterprise): the same reporting data through
https://cloud.cypress.io/enterprise-reporting/report?token=YOUR-API-KEY&report_id=REPORT-TYPE&export_format=csv, with the requiredstart_dateparameter, for BI tools and scripts. Individual results are available about 30 minutes after a run completes.
Source: Types of Analytics
Integrations
Integrations are configured by organization owners and admins in Cypress Cloud, never in the test code.
| Integration | What you get | Plan |
|---|---|---|
GitHub |
Cypress GitHub App: commit status checks (one per run group or one per spec), flaky status, pull request comments with run context, statistics, tests for review and a Branch Review link. GitHub Enterprise Server is supported on higher plans. |
Starter and up; self-managed on Business and Enterprise |
GitLab, Bitbucket |
Commit statuses (including |
Starter and up; see the notes after the pricing table |
Slack, Microsoft Teams |
Run results posted to channels or users, with per-status preferences, flaky test alerts, and UI Coverage and Accessibility results; organization-level and project-level configuration. |
All plans |
Jira |
Create or link a Jira issue from any test result, with the run linked back; one installation per organization through the Atlassian Marketplace app. |
Team and up |
Webhooks |
Signed HTTP POST of run events to your own endpoint. |
Team and up |
Cloud CLI, Cloud MCP |
Query runs, tests and Test Replay from a terminal or an AI assistant. |
All plans |
Source: GitHub integration
Status checks are what turn Cypress into a merge gate: make the Cypress check required in the branch protection rules and a
failing or flaky run blocks the merge. The integration depends on the CI environment providing the commit SHA, which is why
the COMMIT_INFO_SHA setting above matters.
Webhooks
A webhook posts a JSON payload to a public HTTPS endpoint when an event happens. The events are run.completed (passed,
failed, errored, timed out or cancelled), run.accessibility.completed and run.uiCoverage.completed. Up to five webhooks
can be created per project, by an owner, admin or team admin, in the project settings. Cloud refuses private, loopback and
link-local destinations and does not follow redirects, each attempt times out after 10 seconds, and failed deliveries are
retried up to ten attempts in total with exponential backoff for network errors and responses 408, 429 and 5xx.
Every delivery carries headers: X-Cypress-Event, X-Cypress-Event-Id (stable across retries, so use it to deduplicate,
since delivery is at-least-once), X-Cypress-Timestamp, and, when you set a signing secret, X-Cypress-Signature equal
to sha256= followed by the hex HMAC-SHA256 of the string timestamp, a dot, and the exact raw request body. The receiver
below is written for Node.js without dependencies. It verifies the signature in constant time, rejects timestamps older than
five minutes and ignores duplicate event ids.
// webhook/receiver.mjs
import crypto from 'node:crypto';
import http from 'node:http';
const SECRET = process.env.CYPRESS_WEBHOOK_SECRET;
if (!SECRET) throw new Error('Set CYPRESS_WEBHOOK_SECRET');
const seen = new Set();
http
.createServer((req, res) => {
if (req.method !== 'POST' || req.url !== '/receive-webhook') {
res.writeHead(404).end();
return;
}
const chunks = [];
req.on('data', (c) => chunks.push(c));
req.on('end', () => {
const raw = Buffer.concat(chunks); // exact bytes, before any JSON parsing
const signature = req.headers['x-cypress-signature'];
const timestamp = req.headers['x-cypress-timestamp'];
if (!signature || !timestamp) return res.writeHead(400).end('Missing signature headers');
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) {
return res.writeHead(400).end('Timestamp outside of tolerance');
}
const expected =
'sha256=' + crypto.createHmac('sha256', SECRET).update(`${timestamp}.${raw.toString('utf8')}`).digest('hex');
const ok =
signature.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
if (!ok) return res.writeHead(401).end('Invalid signature');
const eventId = req.headers['x-cypress-event-id'];
if (seen.has(eventId)) return res.writeHead(200).end('duplicate ignored'); // at-least-once delivery
seen.add(eventId);
const event = JSON.parse(raw.toString('utf8'));
console.log(`${req.headers['x-cypress-event']}: run #${event.runNumber} ${event.status}, flaky=${event.flakyTestCount}`);
res.writeHead(200).end('ok');
});
})
.listen(Number(process.env.PORT ?? 3929), () => console.log('listening'));
Source: Webhooks: verify signatures
Cloud cannot deliver to localhost, so the receiver was exercised with a script that signs a sample run.completed body with
a throwaway secret using the algorithm from the documentation. This proves the verification code, not Cloud’s delivery:
// webhook/send-sample.mjs
import crypto from 'node:crypto';
const SECRET = process.env.CYPRESS_WEBHOOK_SECRET;
const url = process.env.TARGET ?? 'http://localhost:3929/receive-webhook';
const body = JSON.stringify({
runNumber: 42,
status: 'passed',
flakyTestCount: 1,
projectId: 'a1b2c3',
});
async function send(label, { secret = SECRET, timestamp = Math.floor(Date.now() / 1000), eventId = 'evt-1' } = {}) {
const signature = 'sha256=' + crypto.createHmac('sha256', secret).update(`${timestamp}.${body}`).digest('hex');
const res = await fetch(url, {
method: 'POST',
headers: {
'content-type': 'application/json',
'x-cypress-event': 'run.completed',
'x-cypress-event-id': eventId,
'x-cypress-timestamp': String(timestamp),
'x-cypress-signature': signature,
},
body,
});
console.log(`${label}: ${res.status} ${await res.text()}`);
}
await send('valid signature');
await send('same event again');
await send('wrong secret', { secret: 'some-other-secret', eventId: 'evt-2' });
await send('stale timestamp', { timestamp: Math.floor(Date.now() / 1000) - 3600, eventId: 'evt-3' });
Source: Webhooks: payload
$ CYPRESS_WEBHOOK_SECRET=<throwaway secret> node webhook/receiver.mjs &
listening
$ CYPRESS_WEBHOOK_SECRET=<throwaway secret> node webhook/send-sample.mjs
valid signature: 200 ok
same event again: 200 duplicate ignored
wrong secret: 401 Invalid signature
stale timestamp: 400 Timestamp outside of tolerance
run.completed: run #42 passed, flaky=1
Source: Webhooks integration
The last line is the receiver’s log output. With a secret set, an unsigned or tampered request never reaches the handler; a destination that cannot compute an HMAC (several no-code tools) should be protected by keeping the payload URL secret and by its own authentication.
Cloud CLI
The Cloud CLI, cy-cloud, ships in the npm package @cypress/cloud (0.5.0 at the check date, Node.js 22.21.0 or later) and
needs the integration enabled by an organization admin. Every command prints JSON, so it suits scripts and AI agents. It was
installed in an empty directory and the commands that do not need an account were run:
$ npm install @cypress/cloud@0.5.0
$ npx cy-cloud version
{
"version": "0.5.0",
"latestVersion": "0.5.0",
"status": "Unknown",
"suggestedMinVersionUpgrade": null
}
$ npx cy-cloud status
{
"authenticated": false
}
$ npx cy-cloud run list --projectId a1b2c3 --limit 1
This command requires authentication. Run `login` to authenticate.
Source: Cloud CLI
Interactive use authenticates with cy-cloud login (OAuth in the browser); CI uses a personal access token in the
environment variable CYPRESS_CLOUD_TOKEN, which takes precedence over stored credentials and writes nothing to disk. The
command groups are org list, project list|get, run list|get, spec list|get, test list|get (with --screenshot to save
the failure screenshot), replay info|timeline and replay view (open a Test Replay viewer and query the DOM, accessibility
tree, element details and screenshots at a point in time), and cache and logout. Typical filters are --branch,
--status failed and --onlyFlaky. Authenticated commands were not run.
Cloud MCP
Cloud MCP is a remote, read-only Model Context Protocol server at https://mcp.cypress.io/mcp that lets an AI assistant
(Claude, Cursor, VS Code Copilot and others) query your Cloud data. It reached general availability on 20 May 2026 and is
included on every plan. An admin enables it for the organization, then each user authenticates with OAuth (recommended, the
client keeps the session for 30 days) or a personal access token sent as a bearer token. Its tools include
cypress_get_projects, cypress_get_runs, cypress_get_specs, cypress_get_tests, cypress_get_failed_tests,
cypress_get_flaky_tests, cypress_get_test_screenshots, and tools for Accessibility and UI Coverage reports. A client
configuration for OAuth looks like this (documented; no assistant was connected):
{
"mcpServers": {
"cypress-cloud": {
"serverUrl": "https://mcp.cypress.io/mcp"
}
}
}
Source: Cloud MCP
The AI features of the Cypress App itself (cy.prompt, Studio AI, AI skills) and how Cloud MCP fits among them are covered
in AI Features in Cypress & Selenium.
UI Coverage
UI Coverage is a premium Cloud product that answers a question code coverage cannot: which interactive things a user can do in your application are exercised by your tests. It needs no code changes, plugin or instrumentation. Cloud analyzes the DOM snapshots that Test Replay already captured for every unique state reached in end-to-end and component tests, finds every interactive element (buttons, inputs, links and so on), and checks whether a recognized Cypress interaction command touched it. The report on the run’s UI Coverage tab shows:
-
an overall coverage score, the tested share of interactive elements and distinct links (grouped elements count once; only elements that were visible count);
-
a score per view, a page or state of the application, to rank pages by risk;
-
the untested elements of each view with an inspectable full-page DOM snapshot;
-
untested links, pages your app links to that no test visits.
Requirements are a project that records with Test Replay enabled, Cypress 13 or later, and UI Coverage enabled for the
organization, which starts with a free-trial request. Configuration lives in Cloud, not in the repository: the App Quality
tab of the project settings holds a JSON document validated on save, with options such as elementFilters, viewFilters,
views, elements, elementGroups, significantAttributes, attributeFilters, additionalInteractionCommands,
allowedInteractionCommands and profiles (different settings by run tag). A historical run can be reprocessed after a
change without re-running the tests. This is the documentation’s example, which hides a chat widget and a third-party login:
{
"elementFilters": [
{
"selector": "#intercom-container, #intercom-container *",
"include": false,
"comment": "Support chat widget rendered on every page"
}
],
"viewFilters": [
{
"pattern": "https://auth.mycompany.com/*",
"include": false,
"comment": "Third-party identity provider"
}
]
}
Source: UI Coverage: Get started
Reports are produced after the run is recorded, so nothing in the pipeline waits for them. To turn the report into a merge gate,
install the @cypress/extract-cloud-results module in CI (from the tarball at
https://cdn.cypress.io/extract-cloud-results/v1/extract-cloud-results.tgz, not committed as a dependency) and call
getUICoverageResults() after cypress run --record in the same CI build; it finds the run from the CI environment,
polls until the report is ready and returns the scores:
// scripts/verify-ui-coverage.js
const { getUICoverageResults } = require('@cypress/extract-cloud-results');
getUICoverageResults()
.then(({ summary }) => {
if (summary.coverage < 80) {
throw new Error(`UI Coverage is ${summary.coverage}%, below the minimum of 80%.`);
}
console.log(`UI Coverage is ${summary.coverage}%.`);
})
.catch((error) => {
console.error(error.message);
process.exit(1);
});
Source: UI Coverage: Results API
The script’s syntax was checked, but it was not run: it needs a UI Coverage subscription and a recorded run. The guides also
describe gating on new gaps against a committed baseline rather than on a fixed score, which avoids blocking every pull request
in an application that already has coverage debt. UI Coverage appears in Branch Review, in Enterprise Reporting (since May
2026), through the run.uiCoverage.completed webhook and through three Cloud MCP tools added in April 2026.
Cypress Accessibility
Cypress Accessibility is the sibling premium product. It runs the Deque axe-core rules over the DOM snapshots of every unique state reached in your tests, server-side, with no effect on test execution and no accessibility code in the tests. It needs the same prerequisites as UI Coverage (recording with Test Replay, Cypress 13 or later, the product enabled by a trial) and produces a report on the run’s Accessibility tab: a percentage score, violations per view, and, for each violation, an inspectable DOM snapshot that highlights the element.
The score is the average over all snapshots of the ratio of passing check weights to total weight, where failed checks are
weighted by axe impact: critical 10, serious 7, moderate 3, minor 1. Incomplete and ignored results do not affect it. The
configuration is edited in the same App Quality tab and includes element filters, view filters, views,
significantAttributes, attributeFilters, profiles and, since the week of 5 October 2026, accessibility.axeConfig to
enable or disable individual rules or restrict a report to tags such as WCAG 2.1 A and AA. Reports can be downloaded as CSV
or JSON (since the week of 24 August 2026), compared in Branch Review to review only newly introduced violations, delivered
through the run.accessibility.completed webhook, and enforced from CI with a Results API analogous to the UI Coverage one.
It also supports scheduled runs against production for monitoring. Note that automated rules find only a part of the
accessibility problems; the guides themselves recommend combining them with manual review. For checks that run inside the
test itself (such as axe through cypress-axe), see
Accessibility Checks in E2E Tests.
Source: Cypress Accessibility
Neither product was available without a subscription, so the reports described here were not seen. The in-test cypress-axe
check on the Bookshelf home page is the free alternative; it ran against the example application with no violations in the
shared Cypress project, and cypress-axe 1.7.0 declares a peer range that stops at Cypress 15, so installing it next to
Cypress 16 needs --legacy-peer-deps.
Plans and pricing
Prices and limits change; the table below was read from https://www.cypress.io/pricing on 25 October 2026 with annual billing selected, in USD, and should be rechecked before a decision. The Cypress App is free under the MIT licence regardless of plan. Every account can start a 30-day free trial that includes the premium features.
| Item | Starter | Team | Business | Enterprise |
|---|---|---|---|---|
Price |
Free, no credit card |
from $67 per month, billed annually at $799 |
from $267 per month, billed annually at $3,199 |
Custom |
Users |
10 |
50 |
50 |
Unlimited |
Included test results |
500 per month |
120k per year |
120k per year |
1.8M per year |
Bundled test results (prepaid) |
not available |
$5.28 per 1000 |
$4.40 per 1000 |
$4.00 per 1000 |
On-demand test results |
not available |
$6 per 1000 |
$5 per 1000 |
custom |
Data retention |
30 days |
90 days |
90 days |
180 days |
Prompt executions ( |
100 per month |
9k per year |
24k per year |
60k per year |
Test Replay, Branch Review, test artifacts, AI summaries, parallelization, load balancing, manual cancellation, project analytics, Cloud MCP, Cloud CLI |
included |
included |
included |
included |
Flake detection and flaky analytics, Jira, webhooks, email support |
- |
included |
included |
included |
Spec Prioritization, Auto Cancellation, Re-run optimization, SSO, self-managed GitHub and GitLab |
- |
- |
included |
included |
Enterprise Reporting, Data Extract API, premium support |
- |
- |
- |
included |
UI Coverage, Cypress Accessibility |
not included |
add-on |
add-on |
add-on |
Source: Cypress Cloud pricing
How usage is counted decides the bill. A test result is each passed or failed it() recorded with --record; a test that
retries counts once, and skipped or pending tests, local runs without --record and anything that prevents a test from
running are not counted. Results are consumed in the order included, bundled, then on-demand. When the included and bundled
results are used up and your subscription has no on-demand pricing, recording still runs but parallelization is disabled and new results
are hidden from the dashboard until you upgrade or the billing period resets. The Billing & Usage page shows usage over time
and per project (downloadable as CSV), and owners and admins can create an email notification at a threshold of their choice.
Ways to lower the bill are to record only in CI, to record only the browsers you need, to enable Auto Cancellation and
re-run optimization where your subscription has them, and to remove redundant tests.
Qualifying open-source projects (non-commercial, public in Cloud, source under an OSI-approved licence, at least 500 tests) can request a free Open Source plan with five users, 100k test results per month, parallelization with load balancing and the integrations. The pricing page lists status checks and pull request comments for GitHub, GitLab and Bitbucket on Starter and Team, and for GitHub and GitLab, including their self-managed Enterprise variants, on Business and Enterprise; the integration documentation describes a Bitbucket integration without plan restrictions, so confirm Bitbucket on Business with Cypress if you rely on it. Plan figures can also differ for monthly billing, which was not checked.
Source: Billing & usage in Cypress Cloud
Pitfalls and good practice
-
Treat the record key as a secret. Put it in the CI secret store as
CYPRESS_RECORD_KEY, never in the repository, acypress.env.jsonor theenvblock of the configuration; it will not be read from there anyway. Rotate it from the project settings if it leaks. Test credentials stay separate and are read withcy.env(). -
One run per commit. Several unrelated recordings for the same commit break Branch Review and confuse status checks. Use
--groupand a shared CI build id. -
Several specs, similar length. Parallelization cannot split a file, and a single slow spec bounds the run time.
-
Do not rely on spec order in a recorded parallel run.
-
Keep retries on in CI. Without
retriesCloud has no way to tell flaky from broken, and the flaky features have nothing to show. Also keep the failing attempts visible by recording. -
Mind what Test Replay stores. It is visible to everyone with access to the project. Use private projects, keep real personal data out of test fixtures, and review the redaction and masking defaults before turning them off.
-
Pin the browser for Test Replay. Replays exist only for Chromium-based browsers; a Firefox group in the same run has no replay.
-
Electron is deprecated as a test browser; record with Chrome or Edge in CI.
-
Headed versus headless. Only
cypress runrecords;cypress openshows Cloud data on its Runs and Debug pages but does not upload a run. Test Replay is captured duringcypress run, which is headless by default. -
Local versus CI. Recording from a laptop is allowed and counted. When you only want to try a failing spec, run it without
--record, or open the replay of the CI failure instead of reproducing it.
What changed recently
-
12.6.0 (February 2023): the
--auto-cancel-after-failuresCLI flag, which overrides the project’s Auto Cancellation setting. -
12.17.0: desktop notifications for Cloud runs in the App (macOS and Linux).
-
13.0.0 (29 August 2023): Test Replay; video capture defaults to off and
videoUploadOnPasseswas removed because Test Replay is the primary debugging artifact. The Runner UI is hidden during recordedcypress runwhen Test Replay is on. -
15.15.0:
CYPRESS_RERUN_GROUP_IDand automatic rerun detection on CircleCI and Bitbucket Pipelines. -
15.21.0: "Run only failed tests" granularity for re-run optimization.
-
16.0.0 (1 September 2026): the Electron browser is deprecated,
Cypress.env()is removed in favour ofcy.env()andCypress.expose(), and Node.js 20 and 25 are dropped. None of it changes how recording works, but secrets in tests must be read withcy.env(). -
2026, Cloud: Cloud MCP reached general availability on 20 May; UI Coverage trends joined Enterprise Reporting in the week of 18 May and UI Coverage tools joined Cloud MCP in the week of 27 April; Accessibility gained
axeConfig(week of 5 October) and report download (week of 24 August); the Cloud CLI, webhooks and Cloud AI features (Test Intent and Error Summaries, withcy.promptdocumented as generally available on the Cloud AI page while its API page still marks it beta at the check date) are all recent additions. -
Cloud is continuously delivered: it has no version numbers, so the dates above come from the product changelogs and the documentation, and features and plan placement may have moved since 25 October 2026.