ScreenshotNeo

BlogHow-to

How to Measure Element Coverage in Cypress

Learn how Cypress UI Coverage measures exercised interface elements, and when to use Istanbul source-code coverage instead.

By the ScreenshotNeo team4 October 20268 min read

To measure which buttons, links, forms, and other interactive elements Cypress tests exercise, use Cypress UI Coverage. It uses Test Replay data in Cypress Cloud and does not require source instrumentation, a coverage plugin, or changes to your tests to get started. If by “coverage” you mean which application statements, branches, and functions ran, use Istanbul instrumentation and the @cypress/code-coverage collector instead. These are different measurements.

How do I measure element coverage in Cypress? First decide what you want counted: UI Coverage tracks interaction with interface elements; source-code coverage tracks execution of instrumented application code. A percentage from one workflow does not stand in for the other.

1. Measure interactive element coverage with Cypress UI Coverage

UI Coverage is the direct fit when you want to find controls and flows your tests have not interacted with. Its reports are based on Test Replay data in Cypress Cloud. Follow the official setup guide for your Cypress project and Cloud configuration. The documented starting workflow requires no application instrumentation or coverage plugin.

  1. Enable Cypress Cloud and configure the project to record the Test Replay data used by UI Coverage.
  2. Run the Cypress tests whose interactions you want represented. Coverage reflects the test and replay data available to the project.
  3. Open the UI Coverage report in Cypress Cloud and inspect the elements and views represented there.
  4. Use configuration to filter third-party or irrelevant UI, organize views, and define which interactions count when the default report needs refinement.
  5. Use uncovered elements to identify missing test interactions. Add assertions that check the behavior and outcome; interaction coverage alone does not establish that a test would catch a defect.

What UI Coverage counts

UI Coverage is about interactive elements and their exercise in the interface, rather than whether source lines or branches ran. Its report can help expose controls or areas of the UI that recorded tests did not touch. The report is only as representative as the runs and replay data it uses, so include the relevant flows and environments in your test runs.

Configure UI Coverage for useful reports

Use the UI Coverage configuration guide for supported filters, view organization, and interaction rules. Common reasons to configure it include excluding third-party UI that your team does not own, focusing a report on a relevant part of the application, and deciding which interactions should count as meaningful. Keep the configuration aligned with the question the report should answer; filtering too broadly can hide gaps you intended to see.

2. Measure source-code coverage with Istanbul

If you mean statements, branches, and functions, instrument the application before Cypress loads it. Cypress does not instrument the application for this workflow. @cypress/code-coverage collects browser coverage data and generates reports; it is not the instrumenter. The application should expose coverage data such as window.__coverage__ after instrumented code runs.

Install the collector

npm install --save-dev @cypress/code-coverage

Add the support import to the support file for each test type you run, and register the plugin task in Cypress’s Node event setup. For example, for E2E testing:

// cypress/support/e2e.js
import '@cypress/code-coverage/support'

// cypress.config.js
const { defineConfig } = require('cypress')

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      require('@cypress/code-coverage/task')(on, config)
      return config
    },
  },
})

Adapt the config module syntax to the format your project already uses. The important pieces are the support import, task registration in setupNodeEvents, and returning the configuration object as in the official guide.

Instrument the application before serving it

Choose an instrumenter that fits your build pipeline. Cypress documents Babel with babel-plugin-istanbul and Vite with vite-plugin-istanbul. Configure instrumentation to include the application source you want measured and exclude generated output, dependencies, or other irrelevant files. Preserve source maps where your build setup supports them. The documented Babel and nyc paths do not instrument node_modules.

For Vite, configure the Istanbul plugin in the app’s Vite pipeline, including the relevant include/exclude rules and file extensions. You can conditionally enable instrumentation for Cypress or CI runs so ordinary development builds are not instrumented. See Cypress’s code coverage guide for the Vite and Babel configuration examples; exact plugin configuration belongs in the build pipeline that serves the application to Cypress.

Run tests and read the report

  1. Start the instrumented application and point Cypress at that build.
  2. Run the relevant E2E tests. Confirm that the application-under-test window exposes window.__coverage__ when instrumented code has executed.
  3. The collector merges browser coverage data and uses nyc to produce reports. The maintained plugin workflow describes raw data in .nyc_output and an HTML report under coverage/lcov-report.
  4. Open the generated HTML report and inspect uncovered files, lines, branches, and functions. Focus follow-up tests on important uncovered behavior rather than chasing a universal percentage target.

3. Configure component and backend coverage when needed

Component testing

Component tests need the collector support import in the component support file as well as task registration in Cypress’s Node configuration. An E2E support import alone does not collect component coverage. With Vite, configure the Istanbul plugin in the component dev server pipeline; with Webpack, configure Babel/Istanbul for the component testing dev server.

Backend coverage

Front-end instrumentation does not measure server code. For backend coverage, instrument the backend separately and expose its coverage object through middleware or an endpoint for the test environment. Configure env.codeCoverage.url so the plugin can retrieve and merge backend data. Restrict that endpoint to an appropriate local or test environment rather than exposing coverage data from production.

4. Choose the right coverage workflow

Question Use Setup Results
Which interactive elements did tests use? Cypress UI Coverage Test Replay data in Cypress Cloud; no source instrumentation or coverage plugin for the documented start Cypress Cloud
Which source statements, branches, or functions ran? Istanbul with @cypress/code-coverage Instrument application code and configure support collection and Node task registration Generated local reports, including HTML
Did tests exercise server-side code? Backend instrumentation collected alongside Cypress Instrument backend and expose coverage to the collector through the configured URL Merged coverage report

UI element coverage and source coverage can complement each other. A test can interact with a button while missing an important source branch, or execute shared source code without covering every meaningful control. Use the measure that answers the testing question you have.

5. Troubleshoot missing or misleading coverage

Symptom Likely cause Fix
No source coverage appears The collector is installed, but the application was not instrumented. Instrument the app in its Babel or Vite build pipeline before Cypress loads it; inspect the app window for window.__coverage__.
Coverage data exists in the browser but no report is produced The support import or Node task registration is missing or in the wrong configuration. Check the support file and setupNodeEvents for the test type being run, then confirm the task is registered and config returned.
E2E coverage works but component coverage is absent The component support file has no collector import, or its dev server is not instrumented. Add the support import to component support and instrument the component dev server using the Vite or Webpack path.
Third-party or generated files dominate the report Instrumentation include/exclude patterns are too broad. Scope patterns to application source and exclude dependencies, generated output, and irrelevant files.
Duplicate or confusing coverage with another runner Jest or another runner and Cypress may both be applying Istanbul configuration. Use separate Babel environments/configuration where needed so the Cypress instrumentation path does not duplicate the other runner’s setup.
Backend code is missing from an otherwise valid report Backend coverage is not instrumented or cannot be fetched by the plugin. Instrument the backend, expose its coverage object in the test environment, and set env.codeCoverage.url.
UI Coverage omits a control or includes irrelevant UI The relevant interaction may be absent from recorded replay data, or report filtering and interaction rules may not match the team’s intent. Run the relevant flow with replay data available, then review UI Coverage filters, views, and interaction configuration.

6. Performance, reliability, and cost considerations

Source instrumentation adds work to the build and can change runtime characteristics, so scope it to the application files and Cypress runs that need it. Keep source maps where supported to make reports easier to interpret. Cypress’s documentation does not establish a universal performance overhead or coverage target; measure the impact in your own build rather than assuming a fixed number.

Coverage is reliable only when the correct instrumented build and the intended test runs feed the report. A missing window.__coverage__, incomplete replay data, an unrepresentative test selection, or over-aggressive filters can all produce incomplete conclusions. Treat percentages as signals for where to investigate, not as proof that assertions catch defects.

The Cypress coverage sources describe the Cloud-based UI Coverage workflow and local code coverage reports, but do not establish pricing here. Check current Cypress plan and product details before making a cost decision.

Or skip the browser setup

For capturing a page image in a test or developer workflow, ScreenshotNeo is a website screenshot API and MCP server. It does not calculate Cypress element or source-code coverage; it handles page capture. One GET request returns an image or PDF. See the ScreenshotNeo API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(({ writeFile }) => writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server gives AI agents screenshot tools. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up free for 1,000 screenshots a month, with no card required.

FAQ

Does an Istanbul percentage tell me how many UI elements tests covered?

No. Istanbul measures execution of instrumented source code. Cypress UI Coverage is the workflow for interactive elements.

Do I need to change my Cypress tests to start with UI Coverage?

The documented setup uses Test Replay data and does not require test changes to get started. Configuration can refine what the reports include.

Does the coverage plugin instrument my app?

No. Instrument the application in its build pipeline; the plugin collects the coverage data and creates reports.

Should I aim for 100% coverage?

There is no universal target established by the cited Cypress documentation. Prioritize uncovered critical flows and branches, then verify that assertions check meaningful outcomes.

Sources