---
id: ui-coverage/faq
title: Cypress UI Coverage FAQ
description: >-
  Answers to common questions about Cypress UI Coverage: how it differs from
  code coverage, coverage scores, closing gaps, configuration, and the Results
  API.
section: ui-coverage
source_path: docs/ui-coverage/faq.mdx
version: 29f95bf8bb06f320986f3749f5bf09a35a409eab
updated_at: '2026-09-04T10:49:54.630Z'
---
# Cypress UI Coverage FAQ

**UI Coverage** turns your runs into a visual map of the interactive elements your tests exercise and the ones they miss, with no code changes or instrumentation. [Schedule a demo](https://www.cypress.io/ui-coverage?utm_medium=premium-solution-tip&utm_source=docs.cypress.io&utm_content=Schedule%20a%20demo).

## General

### What is UI Coverage?

[UI Coverage](/llm/markdown/ui-coverage/get-started/introduction.md) is a Cypress Cloud feature that shows you which interactive elements of your application your tests actually exercise. Every recorded run produces a visual report of tested and untested elements across all of your application's [views](/llm/markdown/ui-coverage/core-concepts/views.md), along with a coverage score you can track over time.

### Do I need to install anything to use UI Coverage?

No. UI Coverage requires no code changes or instrumentation. Reports are generated from [Test Replay](/llm/markdown/cloud/features/test-replay.md) data, so any run recorded to Cypress Cloud with Test Replay on Cypress v13 or later is ready to use. See [setup](/llm/markdown/ui-coverage/get-started/setup.md) for details.

### How is the UI Coverage score calculated?

The Cypress UI Coverage score compares the number of tested interactive elements to the total number of interactive elements in your application. Three rules determine what goes into that comparison:

*   **[Grouped elements](/llm/markdown/ui-coverage/core-concepts/element-grouping.md) count as a single unit.** The group counts once toward the total, and an interaction with any element in the group marks the whole group as tested.
*   **Links share the same total.** Each distinct link destination counts as one unit, and counts as tested when a test either interacts with the link or visits its destination.
*   **Only [visible](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Visibility) elements count.** An element that was never visible in any snapshot is excluded from both the tested and total counts, so it neither raises nor lowers your score.

### How do I get started with UI Coverage?

Record a run to Cypress Cloud with [Test Replay](/llm/markdown/cloud/features/test-replay.md) enabled on Cypress v13 or later, then open its **UI Coverage** tab. A report is generated automatically for every recorded run, with no code changes, plugin, or instrumentation. From there you can read your coverage score, drill into your lowest-scoring [views](/llm/markdown/ui-coverage/core-concepts/views.md), and optionally tune the report with [App Quality configuration](/llm/markdown/ui-coverage/configuration/overview.md). The [Get Started guide](/llm/markdown/ui-coverage/get-started/setup.md) walks through the whole path.

### What do I need to use UI Coverage?

Three things: a Cypress project recording to [Cypress Cloud](/llm/markdown/cloud/get-started/introduction.md), [Test Replay](/llm/markdown/cloud/features/test-replay.md) enabled for the run (reports are built entirely from Test Replay data), and Cypress v13 or later. UI Coverage isn't included in standard Cloud plans, so you'll also need it enabled for your organization, which you can do with a [free trial](/llm/markdown/ui-coverage/get-started/setup.md#Step-1-Start-your-UI-Coverage-trial). No test changes, plugins, or code instrumentation are required.

### Is UI Coverage included in my Cypress Cloud plan?

UI Coverage isn't part of the standard Cypress Cloud plans; it's enabled separately for your organization. You can turn it on for your projects with a [free trial](/llm/markdown/ui-coverage/get-started/setup.md#Step-1-Start-your-UI-Coverage-trial), which uses your existing recorded runs so you can see your coverage gaps before committing. To find out what's available for your account, start a trial or talk to your Cypress point-of-contact.

### How soon after a run can I see its UI Coverage report?

The report is generated in Cypress Cloud after the run finishes recording, so it's ready shortly after your run completes rather than during the run itself. Nothing in your Cypress pipeline waits on or fails because of UI Coverage; open the run's **UI Coverage** tab once processing finishes to read it.

### Does UI Coverage work with Cypress component testing?

Yes. UI Coverage reports on both end-to-end and component runs. In component testing, each spec file becomes a single [view](/llm/markdown/ui-coverage/core-concepts/views.md) named by the spec's file path, and every component mounted in that spec is grouped into it. Everything else, including the coverage score, untested elements, and configuration, works the same way as it does for end-to-end runs.

### Is UI Coverage the same as code coverage?

No. Code coverage measures which lines, branches, or functions of your source code ran during a test. UI Coverage measures your application the way a user meets it: the share of _interactive elements_ (buttons, inputs, links, and controls) your tests actually exercised. The two answer different questions. A line of code can back many controls, and simply importing a module can mark it "covered" without a user ever touching the interface, so high code coverage can still hide untested buttons and pages. UI Coverage closes that gap by reporting on the rendered DOM, and it needs no instrumentation or build tooling to do it. The two are complementary, and many teams track both.

### Does UI Coverage affect how my tests run or slow them down?

No. UI Coverage adds nothing to test execution. Reports are generated in Cypress Cloud _after_ a run finishes recording, from the [Test Replay](/llm/markdown/cloud/features/test-replay.md) data your run already captured, so there's no extra work during the run and nothing in your Cypress pipeline waits on or fails because of UI Coverage.

### Does UI Coverage work with my framework, and do I have to change my code?

Yes, and no. UI Coverage analyzes the rendered DOM captured by [Test Replay](/llm/markdown/cloud/features/test-replay.md), not your source code, so it's framework-agnostic. React, Vue, Angular, Svelte, server-rendered HTML, or anything else that produces a DOM works the same way. You don't change your application code, add a plugin, or write any configuration to get a report; configuration is opt-in and comes later, only when you want to sharpen the results.

### What's the difference between UI Coverage and Cypress Accessibility?

Both are Cypress Cloud [App Quality](/llm/markdown/ui-coverage/configuration/overview.md) features built on the same [Test Replay](/llm/markdown/cloud/features/test-replay.md) data, and both need no code changes. They measure different things: UI Coverage tells you _how much_ of your interactive UI your tests exercise (a coverage score plus untested elements and links), while [Cypress Accessibility](/llm/markdown/accessibility/get-started/introduction.md) tells you _whether_ the UI your tests render has accessibility violations. They share configuration properties like [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md) and [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md), which you can scope to one product or the other. See [Configuration scope](/llm/markdown/ui-coverage/configuration/overview.md#Configuration-scope).

### Can I use UI Coverage with AI agents?

Yes. Because every report is structured data about which interactive elements your tests exercised, a compatible AI agent can read it and act on it through the [Cypress Cloud MCP](/llm/markdown/cloud/integrations/cloud-mcp.md). An agent can pull a run's coverage score and untested elements, summarize the biggest gaps, correlate a coverage drop with specific specs, and draft targeted tests to close the gaps, while your team keeps ownership of what "enough coverage" means for each area. See [Use AI agents with UI Coverage](/llm/markdown/ui-coverage/work-with-ai-agents.md) for example prompts and how to tune reports for clearer agent signal.

## Finding coverage gaps

### How do I find which parts of my UI aren't tested?

Record a run to Cypress Cloud with [Test Replay](/llm/markdown/cloud/features/test-replay.md) enabled, then open its **UI Coverage** tab. Every recorded run produces a report automatically, with no code changes. The report ranks your application's [views](/llm/markdown/ui-coverage/core-concepts/views.md) by coverage score, lists the untested interactive elements on each one, and flags the pages your tests never visited as [untested links](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Untested-Links). The [Identify coverage gaps](/llm/markdown/ui-coverage/guides/identify-coverage-gaps.md) guide walks through the full workflow step by step.

### Where should I start if my UI Coverage score is low?

In Cypress Cloud, start with your lowest-scoring [views](/llm/markdown/ui-coverage/core-concepts/views.md), weighed against how critical each one is to your users, since a checkout or signup view at 40% is more urgent than a settings page at the same score. Before writing tests, rule out noise: third-party widgets counted as untested elements (exclude them with [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md)) and links to pages you'll never test (exclude them with [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md)) both lower a score without pointing to a real gap. See [Why is my UI Coverage score lower than I expect?](#Why-is-my-UI-Coverage-score-lower-than-I-expect) and [Identify coverage gaps](/llm/markdown/ui-coverage/guides/identify-coverage-gaps.md).

### In Cypress UI Coverage, what's the difference between an untested element, an untested link, and an untested view?

They describe three different gaps. An **untested element** is an interactive element (a button, input, or control) on a page your tests opened that no recognized command interacted with. An **untested link** is an `<a>` element whose destination URL was never visited during the run. An **untested view** is a page discovered from those untested links that no test ever opened, so it has no coverage at all. Untested elements and untested links both count against your score; untested views surface pages that need a test to reach them. See [Interactivity](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Untested-Links) and [Views](/llm/markdown/ui-coverage/core-concepts/views.md).

### How do I find pages my tests never visit?

Use the **Untested links** section of the UI Coverage report. It lists links whose destinations your Cypress tests never opened during the run, and expanding one shows a **Referrers** tab (the views that link to the page) and a **URLs** tab (the concrete destinations, grouped for dynamic routes like `/orders/*`). Because a page with no view can still be linked from a tested page, this is how UI Coverage surfaces flows your suite is missing entirely. Add navigation to reach them, as shown in [Address coverage gaps](/llm/markdown/ui-coverage/guides/address-coverage-gaps.md#Cover-untested-links).

## Closing coverage gaps

### How do I close a coverage gap in Cypress UI Coverage?

Add a test that exercises the untested element the report surfaces. First [confirm each gap is worth testing](/llm/markdown/ui-coverage/guides/address-coverage-gaps.md#Step-1-Confirm-the-gap-is-real), starting with the ones that carry the most risk, such as controls on your checkout or login views, then close each one either with [Test Generation](#What-is-Test-Generation-in-Cypress-UI-Coverage) or by writing a targeted test yourself. An element moves from untested to tested once a [recognized interaction command](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Interaction-Commands) targets it. See [Address coverage gaps](/llm/markdown/ui-coverage/guides/address-coverage-gaps.md) for the full workflow.

### What is Test Generation in Cypress UI Coverage?

Test Generation uses AI to draft a Cypress test for an untested interactive element, following the setup and conventions your existing specs already use. Select an untested element in the report, click **Generate test code**, and choose a spec from the list of specs where that element appears. Cypress generates a test that reproduces the setup to reach the element (reusing your custom commands), performs an appropriate interaction, and leaves a `TODO` marking where to add your assertions. Treat it as a reviewed starting point, then add the assertions that prove the flow works. See [Generate tests from UI Coverage reports](/llm/markdown/ui-coverage/guides/address-coverage-gaps.md#Generate-tests-from-UI-Coverage-reports).

### Can Cypress UI Coverage write tests for me?

Yes, through [Test Generation](#What-is-Test-Generation-in-Cypress-UI-Coverage). It produces a working test that exercises the untested element so UI Coverage counts it, built from the same patterns and custom commands your existing specs use. It's a starting point rather than a finished test: you copy the snippet into the suggested spec and add the assertions that verify behavior. Test Generation is part of UI Coverage and isn't available on standard Cloud plans; it also requires a report processed on or after November 21, 2024, project membership, and that AI capabilities are enabled for your organization.

### How do I test a page that my Cypress suite never visits?

Add navigation to the page so it renders during a run. Pages your tests link to but never visit appear in the [**Untested links**](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Untested-Links) section, and UI Coverage can't report on any element they contain until a test goes there. Add a `cy.visit()` (or a click that navigates to it), which turns the untested link green and creates a [view](/llm/markdown/ui-coverage/core-concepts/views.md) for the page that then surfaces its own untested elements. Test Generation doesn't apply to untested links; it targets interactive elements, so navigation is the fix here.

### How do I cover an element that only appears after login or a click?

Drive the interaction that puts the UI into that state before interacting with the element. A control inside a collapsed menu, a modal, or a section that only renders after signing in won't be exercised until your test reveals it, so click the toggle or run your `cy.login()` command first, then interact with the now-visible element. Each new state your tests reach adds its snapshot to the Cypress UI Coverage report, so previously hidden elements start appearing as tested.

### Which coverage gaps should I fix first in Cypress UI Coverage?

Prioritize by risk, not by count. Start with the views behind your highest-value flows (checkout, login, account settings), then untested links, which often hide an entire flow rather than a single control, and weight the list by real usage so a heavily used page with low coverage is closed before a lightly used one. See [Confirm the gap is real](/llm/markdown/ui-coverage/guides/address-coverage-gaps.md#Step-1-Confirm-the-gap-is-real) and [Start with your lowest-scoring views](/llm/markdown/ui-coverage/guides/identify-coverage-gaps.md#Step-3-Start-with-your-lowest-scoring-views).

### Why did closing one coverage gap reveal more untested elements?

Because visiting a page or reaching a new state exposes controls Cypress UI Coverage had never seen. When a test navigates to a previously [untested link](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Untested-Links), UI Coverage creates a [view](/llm/markdown/ui-coverage/core-concepts/views.md) for that page and lists every interactive element on it, most of which start untested. This is expected, and it's why closing gaps is a loop: each pass surfaces the next set of elements to prioritize.

## Comparing reports across runs

### How do I compare UI Coverage reports between two runs?

You have two routes. In [Branch Review](/llm/markdown/cloud/features/branch-review.md) in Cypress Cloud, pick a **base run** and a **changed run** from the dropdowns (or let Cypress select them automatically when the changed run is tied to a pull request) and it shows only what changed between them: the elements and pages that became untested, the gaps the change closed, and everything new it added. If you'd rather stay in your editor, the [Cypress Cloud MCP](/llm/markdown/cloud/integrations/cloud-mcp.md) lets an AI agent pull both runs' coverage and report the diff for you. Both compare any two runs already recorded to Cypress Cloud. See [Compare reports](/llm/markdown/ui-coverage/guides/compare-reports.md) for the full workflow with each.

### What's the difference between the base run and the changed run in Branch Review?

The **changed run** is the focal point of the comparison, so everything you see, including every count and drilldown, is data from the changed run. The **base run** is the reference it's measured against. In a pull request, the changed run is your feature branch and the base run is the branch you're merging into, so the diff shows exactly what your change did to coverage.

### How do I tell whether a pull request reduced my UI Coverage?

Open the pull request's run in [Branch Review](/llm/markdown/cloud/features/branch-review.md) and read the coverage-score change at the top: it's labeled a **coverage improvement** when the score rose and a **reduction in coverage** when it fell. A reduction points you to the **New untested elements** and **New untested links** sections, which list the specific controls and pages the change left untested. You can also ask an AI agent to report the same diff from your editor with the [Cypress Cloud MCP](/llm/markdown/cloud/integrations/cloud-mcp.md). See [Compare reports](/llm/markdown/ui-coverage/guides/compare-reports.md) and [Block pull requests](/llm/markdown/ui-coverage/guides/block-pull-requests.md) to fail CI automatically when coverage drops.

### What's the difference between a new untested element and a resolved untested element in UI Coverage?

A **new untested element** is untested in the changed run and was either tested in the base run or didn't exist there, so it represents coverage that regressed. A **resolved untested element** was untested in the base run and is now tested, so it's proof a gap was closed. Branch Review shows both, along with a link to the elements untested in both runs. Untested links are broken out the same way. A new untested element appears either because the test code stopped interacting with it, or because an application change added it without a test. See [Compare reports](/llm/markdown/ui-coverage/guides/compare-reports.md#Step-3-Review-new-untested-elements-and-links).

### Why does a page or element appear as "new" when I compare two UI Coverage runs?

Usually because a dynamic value in the URL or an element attribute isn't being matched consistently across runs. A URL slug that isn't grouped into a stable [view](/llm/markdown/ui-coverage/core-concepts/views.md) can appear as a new page, and an identifier carrying a per-build hash can make one element show as both resolved and new. Group dynamic URLs with [`views`](/llm/markdown/ui-coverage/configuration/views.md) and exclude unstable identifiers with [`attributeFilters`](/llm/markdown/ui-coverage/configuration/attributefilters.md), then regenerate the run. See [Stabilize the comparison](/llm/markdown/ui-coverage/guides/compare-reports.md#Step-6-Stabilize-the-comparison-with-configuration).

### How do I get an accurate Cypress UI Coverage comparison between two runs?

For an accurate Cypress UI Coverage comparison, compare passing runs that ran similar tests on the same content, so each run visited roughly the same pages and completed the same workflows; then any difference in the diff reflects the change in the newer run. This is what you get out of the box when comparing a pull-request branch against its base. Comparing runs from different points in time is still valid, as long as you account for the other sources of difference as you read the results. To see unified changes for your whole suite, group all of a commit's tests under a single Cypress run per report. This guidance applies whether you compare in Branch Review or with the [Cypress Cloud MCP](/llm/markdown/cloud/integrations/cloud-mcp.md), since both read the same recorded runs. See [Compare reports](/llm/markdown/ui-coverage/guides/compare-reports.md) and [Branch Review best practices](/llm/markdown/cloud/features/branch-review.md#Best-Practices).

### Do I need to rerun my tests to compare two UI Coverage reports?

No. Branch Review compares two runs that are already recorded to Cypress Cloud, so any two recorded runs can be compared without re-running anything. The same is true when comparing with the [Cypress Cloud MCP](/llm/markdown/cloud/integrations/cloud-mcp.md), which reads those same recorded runs. If you only changed configuration and want to compare the effect, regenerate a past run from its **Properties** tab instead of recording again. See [Compare reports](/llm/markdown/ui-coverage/guides/compare-reports.md).

### Can I compare UI Coverage reports with an AI agent or the Cypress Cloud MCP?

Yes. The [Cypress Cloud MCP](/llm/markdown/cloud/integrations/cloud-mcp.md) lets a compatible AI agent pull the UI Coverage for two runs and report the diff from your editor, using `cypress_get_runs` to find the runs and `cypress_get_ui_coverage_report`, `cypress_get_ui_coverage_views`, and `cypress_get_ui_coverage_elements` to read each run's coverage. There's no single compare tool; the agent assembles the diff and can then draft a test to close a regression. It's a peer to Branch Review, which remains the place to see full-page DOM snapshots of what changed. See [Compare reports with the Cypress Cloud MCP](/llm/markdown/ui-coverage/guides/compare-reports.md#Compare-reports-with-the-Cypress-Cloud-MCP).

## Monitoring coverage over time

### How do I track my UI Coverage score over time?

Record runs on a regular cadence so there's always something to compare, then watch the direction the score moves rather than a single number. Record a run for every pull request to catch regressions before they merge, and add a scheduled job (such as a nightly CI cron) that records against a stable environment for a consistent baseline that isn't affected by which files a given pull request touched. From there, [Branch Review](/llm/markdown/cloud/features/branch-review.md) diffs any two runs and the [Results API](/llm/markdown/ui-coverage/results-api.md) enforces the trend in CI. See [Monitor changes](/llm/markdown/ui-coverage/guides/monitor-changes.md) for the full workflow.

### How do I get notified when my UI Coverage changes?

Connect [Slack](/llm/markdown/cloud/integrations/slack.md) or [Microsoft Teams](/llm/markdown/cloud/integrations/microsoft-teams.md) to your project so your team is alerted whenever a run finishes, with Slack surfacing UI Coverage results directly. To put the change in front of reviewers, connect a version control integration ([GitHub](/llm/markdown/cloud/integrations/github.md#Pull-request-comments), [GitLab](/llm/markdown/cloud/integrations/gitlab.md#Merge-Request-comments), or [Bitbucket](/llm/markdown/cloud/integrations/bitbucket.md#Pull-Request-comments)) so Cypress Cloud comments on each pull request with the run summary and a link straight to Branch Review. See [Monitor changes](/llm/markdown/ui-coverage/guides/monitor-changes.md#Step-1-Record-runs-on-a-regular-cadence).

### Can I see UI Coverage trends across all my projects?

Yes. [Enterprise Reporting](/llm/markdown/cloud/features/analytics/enterprise-reporting.md#UI-Coverage) in Cypress Cloud rolls UI Coverage trends up across every project in your organization rather than one run at a time. You can view high-level trends, download reports, or pull the numbers through the [data extract API](/llm/markdown/cloud/integrations/data-extract-api.md) to build your own dashboards. See [Track trends across projects](/llm/markdown/ui-coverage/guides/monitor-changes.md#Step-4-Track-trends-across-projects).

## Reducing test duplication

### What is test duplication in Cypress UI Coverage?

Test duplication is when many separate tests exercise the same interactive element to pass _through_ a flow rather than to test it, such as every test clicking a **Log in** or **Continue** button during setup. UI Coverage surfaces it in the **Tested elements** section, where those shared setup steps rise to the top on interaction and test count. It's wasted suite time, not a coverage gap: the element is tested, just redundantly. See [Reduce test duplication](/llm/markdown/ui-coverage/guides/reduce-test-duplication.md).

### How do I find elements my tests exercise more than they need to?

Open the **Tested elements** section of the Cypress UI Coverage report. It lists every interactive element your tests exercised, with an **Interactions** column (how many times a command targeted it) and a **Tests** column (how many separate tests touched it), and it's sorted by interactions with the most-exercised elements first. A control that a large share of your suite interacts with, such as a **Log in** or **Continue** button, is usually shared setup being repeated across tests. Expand a row to break its counts down by view and open [Test Replay](/llm/markdown/cloud/features/test-replay.md) on each occurrence. See [Reduce test duplication](/llm/markdown/ui-coverage/guides/reduce-test-duplication.md).

### What's the difference between the Interactions and Tests columns in UI Coverage?

In Cypress UI Coverage, **Interactions** counts every recognized command against an element across the run, so one test that hits a control in a loop can run the number up on its own. **Tests** counts the distinct tests that interacted with it, so a high number there means many _separate_ tests all touch the same control. The **Tests** column is the better signal for duplication, because shared setup repeated across your suite shows up as one element touched by a large share of your tests.

### How do I reduce test duplication?

Use Cypress UI Coverage to find the elements at the top of the **Tested elements** list, confirm with [Test Replay](/llm/markdown/cloud/features/test-replay.md) that the tests are passing _through_ a flow rather than testing it, then replace the repeated UI steps with a single programmatic step: cache authentication with [`cy.session()`](/llm/markdown/api/commands/session.md), set a cookie or storage flag directly, or seed state with [`cy.request()`](/llm/markdown/api/commands/request.md). Keep one test that still drives the flow through the UI so its coverage is preserved. The [Reduce test duplication](/llm/markdown/ui-coverage/guides/reduce-test-duplication.md) guide walks through the full workflow.

### Does reducing test duplication lower my UI Coverage score?

No. In Cypress UI Coverage, an element stays tested as long as at least one test still interacts with it, so consolidating redundant setup removes _interactions_, not _coverage_. When you replace a UI login in 200 tests with [`cy.session()`](/llm/markdown/api/commands/session.md) and keep one test that drives the login form, the form's interaction count drops sharply while it remains marked as tested, and your overall score is unchanged.

### What's the difference between reducing noise and reducing test duplication in UI Coverage?

[Reducing noise](/llm/markdown/ui-coverage/guides/reduce-noise.md) is a report-accuracy problem: the report over-counts because one control is reported as many elements, or unrelated pages are split into separate views, and you fix it with [App Quality configuration](/llm/markdown/ui-coverage/configuration/overview.md) in Cypress Cloud. [Reducing test duplication](/llm/markdown/ui-coverage/guides/reduce-test-duplication.md) is a test-effort problem: the report is correct, but your suite repeats the same setup across many tests, and you fix it in your test code by consolidating that setup.

## Interactive elements

### What does Cypress UI Coverage count as an interactive element?

UI Coverage follows the WHATWG definition of [interactive content](https://html.spec.whatwg.org/dev/dom.html#interactive-content), plus a few Cypress-specific rules. In short, an element counts when it is natively interactive (like `<a>`, `<button>`, or a form control), when it has an interactive ARIA `role` (such as `button` or `tab`), or when it is keyboard-focusable with `tabindex="0"` or higher. See [Interactive Elements](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Interactive-Elements) for the full rules.

### Why doesn't Cypress UI Coverage track my custom widget as an interactive element?

UI Coverage detects interactivity from HTML semantics, not from event handlers, so a `<div>` with a click handler isn't recognized as interactive. The best fix is to give the control real semantics, such as using a `<button>` or adding an appropriate `role`, which also improves accessibility. When that isn't possible, add [`data-cy-ui-interactive="include"`](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Overriding-interactive-elements-with-data-cy-ui-interactive) to the element so UI Coverage tracks it.

### How do I stop Cypress UI Coverage from tracking an element or a whole section?

You have two options. In your markup, add [`data-cy-ui-interactive="exclude"`](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Overriding-interactive-elements-with-data-cy-ui-interactive) to a single element or `data-cy-ui-interactive="exclude-all"` to a container to also exclude everything inside it (and `reset` to re-enable a subtree). To do the same from Cypress Cloud without changing application code, add an [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md) rule with `include: false`. Excluded elements are removed from both the report and the score.

## Views and URLs

### Why do similar URLs show up as separate views in Cypress UI Coverage?

Automatic grouping only replaces path segments that are numbers or IDs (UUIDs and UUID-like values) with a wildcard. Segments like usernames or slugs are not recognized as dynamic, so `/users/alice` and `/users/bob` remain separate views. Add a [`views`](/llm/markdown/ui-coverage/configuration/views.md) pattern to group them yourself. See [how views are created](/llm/markdown/ui-coverage/core-concepts/views.md#How-views-are-created) for the full set of automatic rules.

### Do query parameters create separate Cypress UI Coverage views?

No. Query strings are ignored when grouping, so `/dashboard?tab=overview` and `/dashboard?tab=settings` become a single `/dashboard` view. If a query parameter meaningfully changes the page, use a [`views`](/llm/markdown/ui-coverage/configuration/views.md) pattern with `groupBy` on that parameter to split it into separate views.

### How do I create a separate UI Coverage view for each value of a URL parameter?

In Cypress UI Coverage, write a [`views`](/llm/markdown/ui-coverage/configuration/views.md) pattern that names the parameter, then list that name in `groupBy`. For a pattern like `/analytics/:type/:id`, `groupBy: ["type"]` creates a distinct view for each `type` value (such as `/analytics/performance/:id` and `/analytics/usage/:id`) while still collapsing the dynamic `:id`. `groupBy` accepts a single string or an array of strings, and each name can come from the path, query string, or hash. See [Using groupBy](/llm/markdown/ui-coverage/configuration/views.md#Using-groupBy).

### How do I exclude URLs from UI Coverage?

In Cypress Cloud, add a [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md) rule with `include: false` for a URL pattern. Excluding a URL removes its snapshots from the report and stops links pointing to it from counting against your coverage score. The [Ignore views and links](/llm/markdown/ui-coverage/guides/ignore-views-and-links.md) guide walks through common cases.

### In Cypress UI Coverage, what's the difference between viewFilters and views?

They do opposite things. [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md) _removes_ URLs from your report and score, so excluded pages and the links pointing to them stop counting. [`views`](/llm/markdown/ui-coverage/configuration/views.md) _keeps_ URLs but changes how they're grouped and named, so related pages collapse into a single view or a dynamic route splits into several. Use `viewFilters` for pages you don't own or intend to test, and `views` to organize the pages you do. See [Which option do I need?](/llm/markdown/ui-coverage/configuration/overview.md#Which-option-do-I-need).

### How do I exclude a third-party login or OAuth page from UI Coverage?

Add a [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md) rule with `include: false` for the provider's URL, such as `{ "pattern": "https://acme.okta.com/*", "include": false }`. Tests that sign in through an external identity provider (Okta, Auth0, and similar) capture snapshots of its pages, and your links to it count as untested elements. One rule removes both, while every other URL stays included by default. See [Ignore views and links](/llm/markdown/ui-coverage/guides/ignore-views-and-links.md).

### Can I exclude a URL from UI Coverage without affecting Cypress Accessibility?

Yes. A [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md) list at the root of your configuration applies to both products, but nesting it under a `uiCoverage` key applies it to UI Coverage only, so Cypress Accessibility keeps scanning the URL. A nested list completely replaces the root-level one for UI Coverage; the two are not merged, so include every rule UI Coverage needs. See [Scope](/llm/markdown/ui-coverage/configuration/viewfilters.md#Scope).

### Why is a URL still in my UI Coverage report after I excluded it with viewFilters?

The most common causes in Cypress UI Coverage are:

*   An earlier rule matches the URL first. Rules apply in order and the first match wins, so a broad `include: true` rule listed before your exclusion prevents it from ever applying.
*   The pattern doesn't match the full URL. Hostnames must match exactly (`https://my-app.com/*` doesn't match `www.my-app.com`), or you can use a path-only pattern like `/admin/*` to match any hostname.
*   The report was processed before you saved the configuration. Regenerate the run to apply the current configuration.

See [pattern matching behavior](/llm/markdown/ui-coverage/configuration/viewfilters.md#How-are-viewFilters-rules-applied) for details.

### Can I include only specific URLs in UI Coverage?

Yes. In Cypress Cloud, list `include: true` rules for the URLs you want, followed by a catch-all rule that excludes everything else: `{ "pattern": "*", "include": false }`. Because the first matching rule wins, the catch-all must come last. See [Include only your application's URLs](/llm/markdown/ui-coverage/configuration/viewfilters.md#Include-only-your-applications-URLs) for a complete example.

### Why is a page missing from my Cypress UI Coverage report?

Views are created from URLs your tests actually visit, so a page that no test navigates to has no view. Check [untested links](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Untested-Links) in the report, where pages that are linked to but never visited appear. Also confirm that a [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md) rule isn't excluding the page unintentionally.

### What is an untested link in Cypress UI Coverage?

An untested link is an `<a>` element whose destination URL is never visited during your run. Because a link points to a page, an untested link surfaces a flow your suite is missing even when no [view](/llm/markdown/ui-coverage/core-concepts/views.md) exists for that page. Untested links count against your score unless you exclude their destination with [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md). See [Untested Links](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Untested-Links).

### Why don't `mailto:` and `tel:` links appear in Cypress UI Coverage?

Contact links, meaning anchors whose `href` uses `tel:`, `mailto:`, or `sms:`, aren't treated as interactive elements, so they never appear in reports and never count toward your score. If you need one tracked, add [`data-cy-ui-interactive="include"`](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Overriding-interactive-elements-with-data-cy-ui-interactive) to the anchor.

### Why does Cypress UI Coverage count an external or non-`http` link as an untested link?

Any `href` that resolves to a URL is treated as a link to a destination, including absolute URLs to external sites and schemes like `ftp:`, `file:`, `data:`, `blob:`, or a custom app scheme. If the destination is never visited, it appears as an untested link. Only `#`, `javascript:`, on-page fragments like `#pricing`, and the contact schemes above are excluded. Exclude destinations you don't intend to test with [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md). See [Which hrefs count as links](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Which-hrefs-count-as-links).

### In Cypress UI Coverage, what's the difference between a hash route like `#/settings` and a page anchor like `#pricing` for untested links?

The leading slash. A hash route (`#/settings`) is treated as a URL, so it can be a destination and can appear as an untested link if never visited. A page anchor, or document fragment (`#pricing`), points to a section of the current page, so it's an ordinary interactive element that must be interacted with to count as tested and never appears as an untested link.

## Element grouping and identification

### How does UI Coverage group elements automatically?

Out of the box, with no Cypress Cloud configuration, UI Coverage combines elements it recognizes as variations of the same control. It groups interactive elements that share the same [identifying attribute](/llm/markdown/ui-coverage/core-concepts/element-identification.md#How-an-element-is-identified) value (such as a `data-cy="favorite"` button repeated on every card), form controls with their `<label>`, controls in the same position across table and grid rows, repeated structures that share a tag and class hierarchy, and links that resolve to the same [view](/llm/markdown/ui-coverage/core-concepts/views.md). Automatic grouping needs at least two similar elements; a control that appears once stays on its own. See [Element Grouping](/llm/markdown/ui-coverage/core-concepts/element-grouping.md#Automatic-grouping) for the full set of rules.

### How does grouping affect my UI Coverage score?

A [group](/llm/markdown/ui-coverage/core-concepts/element-grouping.md) counts once toward your total element count in Cypress Cloud, and interacting with any one member marks the whole group as tested. So a list of 50 identical "Remove" buttons contributes a single unit to your score, and one test that removes one item covers all 50. This keeps repeated elements from inflating your total and keeps a single untested set from sinking your score for no real gap in testing.

### Why does my UI Coverage report show one group instead of every repeated element?

That's grouping working as intended. When UI Coverage detects that many elements are copies of the same control, such as a "Delete" button on every table row, it collapses them into one named group so the report stays readable and the score reflects distinct behaviors rather than raw element counts. If the automatic grouping is combining elements you'd rather see separately, split them apart with an [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) rule in your Cypress Cloud configuration.

### Which UI Coverage grouping mechanism wins when more than one could apply?

The [`data-cy-ui-group` markup attribute](/llm/markdown/ui-coverage/core-concepts/element-grouping.md#Grouping-with-markup-attributes) takes priority over everything, then [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) configuration rules in Cypress Cloud, and finally the [automatic grouping rules](/llm/markdown/ui-coverage/core-concepts/element-grouping.md#Automatic-grouping) apply to whatever no attribute or rule claimed. Elements removed by [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md) are never grouped at all.

### What happens if two UI Coverage elementGroups rules match the same element?

In Cypress UI Coverage, the first matching rule in your [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) configuration wins, so list specific rules before broad catch-all rules. A rule that appears after another rule matching the same elements never applies to them.

### Can I group UI Coverage elements in my application code instead of Cypress Cloud configuration?

Yes. Add the [`data-cy-ui-group` attribute](/llm/markdown/ui-coverage/core-concepts/element-grouping.md#Grouping-with-markup-attributes) to your markup, and elements sharing the same attribute value are grouped together with no Cloud configuration needed. Placing the attribute on a wrapper element groups every interactive element inside it. Groups defined this way take priority over [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) configuration rules.

### Can I group or filter UI Coverage elements inside iframes or shadow DOM?

Yes. In Cypress UI Coverage, the [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md), [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md), [`elements`](/llm/markdown/ui-coverage/configuration/elements.md), and [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md) configuration options all accept a `documentScope` property that limits a rule to elements inside specific iframes or shadow DOM hosts. List one CSS selector per host, ordered from the outermost document to the innermost.

**Note:** Shadow DOM and iframe processing for UI Coverage is optional and off by default. If you are experiencing unexpected results, reach out to your Cypress representative or use the feedback button in the product.

### Why isn't my element group showing up in the UI Coverage report?

The most common causes in Cypress UI Coverage are:

*   An earlier `elementGroups` rule matches the same elements, and the first matching rule wins.
*   The elements are excluded by [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md), so they're never considered for grouping.
*   The elements declare a group in markup with the `data-cy-ui-group` attribute, which takes priority over configuration rules.
*   The selector matches a container rather than the interactive elements themselves.
*   The report was processed before you saved the configuration. Regenerate the run to apply the current configuration.

### How do I exclude elements from UI Coverage?

In Cypress Cloud, add an [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md) rule with `include: false` for a CSS selector that matches the elements. Excluded elements are removed from the report and don't count toward your coverage score. This is the standard way to remove third-party widgets, such as chat launchers or cookie banners, from your reports. The [Ignore elements](/llm/markdown/ui-coverage/guides/ignore-elements.md) guide walks through common cases.

### How do I exclude a third-party widget like a chat launcher or cookie banner from UI Coverage?

In Cypress Cloud, add an [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md) rule with `include: false` whose selector matches the widget's container _and_ its descendants, so every control inside it is removed rather than just the wrapper. For a support chat like Intercom, that's `{ "selector": "#intercom-container, #intercom-container *", "include": false }`. Widgets rendered inside an iframe or shadow DOM are removed by pairing a `*` selector with [`documentScope`](/llm/markdown/ui-coverage/configuration/elementfilters.md#Options). See [Ignore elements](/llm/markdown/ui-coverage/guides/ignore-elements.md) for the full walkthrough.

### Should I exclude UI Coverage elements with elementFilters or data-cy-ui-interactive?

Both remove an element from the report and the score; choose by who owns the decision. Use [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md) to manage exclusions centrally in Cypress Cloud with no code change, which fits when the team editing configuration isn't the team that owns the markup. Use the [`data-cy-ui-interactive`](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Overriding-interactive-elements-with-data-cy-ui-interactive) attribute (`exclude` on one element, `exclude-all` on a container) when the exclusion belongs next to the markup that owns it. `elementFilters` also supports `include: true` exceptions and `documentScope`, which the markup attribute doesn't.

### Do excluded elements count toward my UI Coverage score?

No. In Cypress UI Coverage, an element excluded by [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md) doesn't appear in the report and doesn't count toward the score, whether your tests interacted with it or not. It's also not considered by [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) or [`elements`](/llm/markdown/ui-coverage/configuration/elements.md) rules.

### Why isn't my UI Coverage elementFilters rule excluding an element?

The most common causes in Cypress UI Coverage are:

*   The selector matches a container instead of the element itself. Filters use standard CSS matching against each tracked element, so `footer` matches only the `<footer>` element. Use a descendant selector like `footer *` to exclude everything inside a container.
*   An earlier `elementFilters` rule already matched the element, and the first matching rule wins. An `include: true` rule above your exclude rule protects the elements it matches.
*   The rule has a `documentScope` that doesn't match the element's iframe or shadow DOM hosts.
*   The report was processed before you saved the configuration. Regenerate the run to apply the current configuration.

### Can I exclude elements from UI Coverage without affecting Cypress Accessibility?

Yes. An `elementFilters` list at the root of your configuration applies to both products, but nesting it under a `uiCoverage` or `accessibility` key applies it to that product only. A nested list completely replaces a root-level one for that product; the two are not merged. See [Exclude elements](/llm/markdown/ui-coverage/configuration/elementfilters.md#Scope).

### Why does one element appear as multiple elements in my Cypress UI Coverage report?

This usually means the element's identifying attributes change between [snapshots](/llm/markdown/ui-coverage/core-concepts/element-identification.md#Snapshots), for example auto-generated IDs or dynamic class names. Use [`attributeFilters`](/llm/markdown/ui-coverage/configuration/attributefilters.md) to ignore the dynamic attributes, or [`elements`](/llm/markdown/ui-coverage/configuration/elements.md) to define the element's identity explicitly. See [troubleshooting](/llm/markdown/ui-coverage/troubleshooting.md) for more scenarios.

### Which attributes does UI Coverage use to identify elements?

Cypress UI Coverage checks a prioritized list of attributes on each element and uses the first one present with a usable value. In order, that's: `data-cy-ui-id` (which replaces the element's identity outright), any attributes you add to [`significantAttributes`](/llm/markdown/ui-coverage/configuration/significantattributes.md), then the default test attributes `data-cy`, `data-test`, `data-testid`, `data-test-id`, `data-qa`, and `row-id`, falling back to `id` and `name` when none of those are present. See [Element Identification](/llm/markdown/ui-coverage/core-concepts/element-identification.md#How-an-element-is-identified) for the full priority list and how identification works across snapshots.

### How does UI Coverage identify an element that has no test attribute or id?

When an element has none of the [identifying attributes](/llm/markdown/ui-coverage/core-concepts/element-identification.md#How-an-element-is-identified), Cypress UI Coverage falls back to identifying it by its structure and position in the DOM. Because that identity is less stable than an attribute you control, adding a stable `data-cy` (or similar) attribute is the reliable fix. See [When an element has no identifying attribute](/llm/markdown/ui-coverage/core-concepts/element-identification.md#When-an-element-has-no-identifying-attribute).

### How do I make UI Coverage use my own attribute to identify elements?

Add the attribute name to [`significantAttributes`](/llm/markdown/ui-coverage/configuration/significantattributes.md). In Cypress UI Coverage, attributes you list are checked before the default list, in the order you list them, so an attribute your application already renders, such as `data-component-name`, can identify, name, and group elements in your reports.

### In UI Coverage, does significantAttributes replace the default attribute list?

No. In Cypress UI Coverage, your attributes are checked first, and the defaults still apply after them, so an element without any of your attributes is identified exactly as it would be without configuration. Listing a default attribute like `data-qa` promotes it above the other defaults. To stop an attribute from being used at all, use [`attributeFilters`](/llm/markdown/ui-coverage/configuration/attributefilters.md) instead.

### Can I use a non-`data-` attribute like aria-label as a UI Coverage significant attribute?

Yes. In Cypress UI Coverage, any valid HTML attribute qualifies, not only `data-*` attributes. Listing [`aria-label`](/llm/markdown/ui-coverage/configuration/significantattributes.md) identifies elements by their label text, which gives icon-only controls a readable identity. Because UI Coverage lists every interactive element, it also surfaces every label for a person to read and judge for clarity, since automated accessibility tools confirm only that a label exists, not that it is well written.

### Why isn't my UI Coverage elements rule applying?

In Cypress UI Coverage, an [`elements`](/llm/markdown/ui-coverage/configuration/elements.md) rule applies only when its selector matches exactly one interactive element in a snapshot. The most common causes are:

*   The selector matches more than one interactive element in the same snapshot, so the rule is skipped for that snapshot. Add [`documentScope`](/llm/markdown/ui-coverage/configuration/elements.md#Options) or a more specific selector, or use [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) if several elements should share an identity.
*   The selector only matches non-interactive elements, such as a wrapper around the actual button or input.
*   The element is excluded by [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md), so it's never considered.
*   A later `elements` rule matches the same element, and the last matching rule wins.
*   The report was processed before you saved the configuration. Regenerate the run to apply the current configuration.

### How do I stop dynamic IDs or class names from splitting one UI Coverage element into many?

Add an [`attributeFilters`](/llm/markdown/ui-coverage/configuration/attributefilters.md) rule with `include: false` that matches the unstable attribute and value, for example an `id` like `:r11:` or a hashed `class`. Once the volatile attribute is ignored, Cypress identifies the element by a stable attribute instead, so the same control is recognized across [snapshots](/llm/markdown/ui-coverage/core-concepts/element-identification.md#Snapshots) and counted once. When you filter a dynamic `id`, also filter the attributes that reference it (`for`, `aria-labelledby`, `aria-describedby`, and similar), or the element can still be identified by those related values.

### Do I need to configure UI Coverage attributeFilters for auto-generated IDs?

Often not. Cypress already ignores the most common unstable identifiers, including values containing UUIDs or long hexadecimal hashes, digit-only `id`/`name`/`for`/`aria-*` values, and generated `class` patterns like `jss*` and `ng-tns-*`. Add an [`attributeFilters`](/llm/markdown/ui-coverage/configuration/attributefilters.md) rule only when your application produces unstable attributes these built-in filters don't already cover.

### In UI Coverage, what's the difference between attributeFilters and significantAttributes?

They pull in opposite directions. [`attributeFilters`](/llm/markdown/ui-coverage/configuration/attributefilters.md) _removes_ attributes from consideration so Cypress won't identify elements by them, while [`significantAttributes`](/llm/markdown/ui-coverage/configuration/significantattributes.md) _prioritizes_ attributes so Cypress prefers them when they're available. Use `attributeFilters` to hide noisy or dynamic attributes, and `significantAttributes` to promote a stable attribute such as `data-component-name`.

### Why isn't my UI Coverage attributeFilters rule working?

The most common causes in Cypress UI Coverage are:

*   The pattern doesn't match the full value. Patterns are anchored automatically (as if wrapped in `^(...)$`), so `value: "user"` matches only the exact string `user`. Use wildcards for partial matches, such as `value: "user-.*"`.
*   An earlier rule matches the same attribute first, and the first matching rule wins. List specific `include: true` exceptions before broad `include: false` rules.
*   The rule targets a tag name or sibling position. Only attributes and individual `class` tokens can be filtered, not an element's tag name or `nth-child` position.
*   The report was processed before you saved the configuration. Regenerate the run to apply the current configuration.

## Interaction commands

### Which Cypress commands does UI Coverage count as coverage by default?

UI Coverage marks an element as tested when it's targeted by one of a default set of Cypress interaction commands: `blur`, `check`, `clear`, `click`, `dblclick`, `focus`, `rightclick`, `scrollIntoView`, `scrollTo`, `select`, `selectFile`, `submit`, `trigger`, `type`, and `uncheck`. Commands outside this set, including plugin commands like `realClick` and `realHover` and assertions, don't count until you add them with [`additionalInteractionCommands`](/llm/markdown/ui-coverage/configuration/additionalinteractioncommands.md) or [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md). See [Interaction Commands](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Interaction-Commands).

Two commands in this list behave differently from the rest. `scrollIntoView` credits the element's nearest **scrollable ancestor**, not the element you called it on, so it usually produces no coverage for the target itself. Use a real interaction to mark that element tested. `scrollTo` credits only an exact match and is never credited through a parent element.

### How do I make UI Coverage count cypress-real-events commands like realClick and realType?

[`cypress-real-events`](https://github.com/dmtrKovalenko/cypress-real-events) commands (`realClick`, `realType`, `realHover`) aren't built-in Cypress commands, so UI Coverage doesn't count them until you list them in [`additionalInteractionCommands`](/llm/markdown/ui-coverage/configuration/additionalinteractioncommands.md), nested under the `uiCoverage` key. Once listed, the elements they target are marked as tested.

### Why isn't my custom command counted as an interaction in UI Coverage?

Two conditions must both hold. First, the command name must be listed in [`additionalInteractionCommands`](/llm/markdown/ui-coverage/configuration/additionalinteractioncommands.md) (or [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md)), matched case-sensitively and written exactly as you registered it. Second, the command must log a [snapshot](/llm/markdown/ui-coverage/core-concepts/element-identification.md#Snapshots) that references the subject element, so UI Coverage knows which element to credit. In practice, register the command with [`prevSubject`](/llm/markdown/api/cypress-api/custom-commands.md#Arguments), call [`Cypress.log`](/llm/markdown/api/cypress-api/cypress-log.md) with the subject as `$el`, and capture a snapshot. If you added the command after a run was processed, regenerate the run to apply the change.

### In UI Coverage, what's the difference between additionalInteractionCommands and allowedInteractionCommands?

In Cypress UI Coverage, [`additionalInteractionCommands`](/llm/markdown/ui-coverage/configuration/additionalinteractioncommands.md) _extends_ the set of commands recognized as interactions everywhere, so a custom or plugin command counts as coverage on any element. [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md) works _per element_: for elements matching a selector, only the commands you list count, which lets you both restrict coverage to a meaningful interaction and accept commands that are otherwise ignored. Use `additionalInteractionCommands` to recognize a command globally, and `allowedInteractionCommands` to control which commands matter for specific elements.

### How do I require a specific interaction in UI Coverage, like a hover, to mark an element tested?

In Cypress UI Coverage, add an [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md) rule whose `selector` matches the element and whose `commands` list contains only the interaction you require. Because matching a rule replaces the default commands for that element, interactions you didn't list, including a plain `click`, no longer mark it tested, so the element only counts once the meaningful interaction runs.

### Can I count assertions as UI Coverage?

Yes. In Cypress UI Coverage, assertions don't count by default, but an [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md) rule listing `assert` credits assertions against the matching elements. This is useful for read-only elements such as status badges or computed totals that your tests validate but never interact with. Remember that the rule replaces the defaults for those elements, so include any other commands you also want to accept alongside `assert`.

### In UI Coverage, do commands in allowedInteractionCommands also need to be in additionalInteractionCommands?

No. In Cypress UI Coverage, listing a command in an [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md) rule automatically registers it as a recognized interaction, so a custom or plugin command works without also appearing in [`additionalInteractionCommands`](/llm/markdown/ui-coverage/configuration/additionalinteractioncommands.md). As with any custom command, it only produces coverage if it logs a snapshot that references the subject element.

### Why did an element stop counting as tested in UI Coverage after I added an allowedInteractionCommands rule?

In Cypress UI Coverage, once an element matches an [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md) rule, only the commands listed in the matching rules count for it, and the default commands no longer apply. If your tests exercise the element with a command you didn't list, it's now treated as untested. Add that command to the rule, or tighten the `selector` so the rule doesn't match elements you didn't intend to restrict.

## Configuration

### Do I need to configure anything to use UI Coverage?

No. Cypress UI Coverage works out of the box with no configuration. Every recorded run produces a report automatically. Configuration is opt-in and incremental: add a rule only when you want to sharpen the report, such as ignoring a dynamic attribute, filtering out a third-party widget, or grouping related elements. See the [Configuration overview](/llm/markdown/ui-coverage/configuration/overview.md) for what each option does.

### Where do I set UI Coverage configuration?

In the **App Quality** tab of your project settings in Cypress Cloud. By default, only Admin users can edit configuration; your Cypress point-of-contact can change this on request. See [Setting configuration](/llm/markdown/ui-coverage/configuration/overview.md#Setting-configuration).

### How do I document why a UI Coverage configuration rule exists?

Add a `comment` property to any rule. Comments are for humans only and have no effect on behavior, so they're the supported place to explain a rule for teammates or your future self. Because Cypress Cloud rejects properties it doesn't recognize, `comment` is the only field you can use for freeform notes. See [Comments](/llm/markdown/ui-coverage/configuration/overview.md#Comments).

### Why is Cypress Cloud rejecting my UI Coverage configuration as invalid?

Cypress Cloud validates your configuration against a strict schema and rejects any property it doesn't recognize. The usual causes are a misspelled property name, a value of the wrong type (for example, a string where an array is expected), or a note added on an unsupported field. Put explanations in a [`comment`](/llm/markdown/ui-coverage/configuration/overview.md#Comments) instead. The editor reports the offending property so you can correct it before saving.

### Do I need to rerun my tests after changing UI Coverage configuration?

No. You can regenerate any historical run from its **Properties** tab, and the report is reprocessed with the current configuration. This lets you iterate on configuration and see the effects immediately without running your Cypress tests again.

### Does my configuration apply to Cypress Accessibility too?

Root-level properties like [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md), [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md), and [`views`](/llm/markdown/ui-coverage/configuration/views.md) apply to both UI Coverage and Cypress Accessibility. To configure the products separately, nest `viewFilters`, `elementFilters`, `attributeFilters`, or `significantAttributes` under a `uiCoverage` or `accessibility` key; the nested list completely replaces the root-level one for that product. See [Configuration scope](/llm/markdown/ui-coverage/configuration/overview.md#Configuration-scope).

### Can I use different UI Coverage configuration for different runs?

Yes. In Cypress UI Coverage, the [`profiles`](/llm/markdown/ui-coverage/configuration/profiles.md) property applies configuration overrides based on [run tags](/llm/markdown/app/references/command-line.md#cypress-run-tag-lt-tag-gt), so a smoke-test run and a full regression run can each use their own settings.

## Profiles

### How do I apply different UI Coverage settings to different runs?

In your project's App Quality configuration in Cypress Cloud, add a [`profiles`](/llm/markdown/ui-coverage/configuration/profiles.md) array, give each profile a `name`, and record the run with a matching [`--tag`](/llm/markdown/app/references/command-line.md#cypress-run-tag-lt-tag-gt). When a run's tag matches a profile's `name`, that profile's `config` overrides your base configuration for that run, so a smoke run and a full regression run can each use their own settings without changing your test code. If no tag matches, the base configuration is used unchanged.

### Does a UI Coverage profile override my base configuration or merge with it?

Cypress Cloud overrides one property at a time with a shallow merge, not a deep merge. Any property the profile lists replaces the root value for that property entirely (arrays are replaced, not concatenated), so if a profile defines [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md), repeat any root rules you still want to keep. Properties the profile doesn't mention are inherited from the root. The `uiCoverage` and `accessibility` objects merge one level deep, so a profile can override `uiCoverage.elementGroups` while still inheriting `uiCoverage.attributeFilters`. See [How a profile changes your configuration](/llm/markdown/ui-coverage/configuration/profiles.md#How-a-profile-changes-your-configuration).

### If a run has multiple tags that match profiles, which UI Coverage profile is used?

Cypress Cloud uses the first profile in the [`profiles`](/llm/markdown/ui-coverage/configuration/profiles.md) array whose `name` matches one of the run's tags. The tie is broken by the order of the profiles array, not the order of the tags on the run, so reordering tags on the command line never changes which profile applies.

### Why isn't my UI Coverage profile applied even though I tagged the run?

The most common causes are:

*   The run tag doesn't exactly match the profile `name`. Matching is case-sensitive and exact, so `aq-config-regression` matches only the tag `aq-config-regression`, not `AQ-Config-Regression` or `aq-config-regression-nightly`.
*   The tag never reached Cypress Cloud. Profiles are selected from the tags passed to `cypress run --record --tag`, so a run recorded without `--record`, or without that specific `--tag`, falls back to the base configuration.
*   An earlier profile in the array also matches one of the tags and is used instead, because the first match wins.
*   The report was processed before you saved the configuration. Regenerate the run to apply the current configuration.

### Can a profile turn off UI Coverage or skip a run entirely?

There's no dedicated "skip this run" switch in a profile. To suppress a report for certain runs, point a profile at a deliberately narrow configuration (for example, [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md) that exclude every view) so Cypress Cloud produces an empty or tightly scoped report for the run instead. See [Why use profiles?](/llm/markdown/ui-coverage/configuration/profiles.md#Why-use-profiles).

## Results API and CI

### What are the prerequisites for using the Cypress UI Coverage Results API?

A few conditions must hold before `getUICoverageResults` can return a report:

*   **Test Replay must be enabled** for the run. UI Coverage reports are built from [Test Replay](/llm/markdown/cloud/features/test-replay.md) data, so a run recorded with Test Replay off has no report and the helper throws. Enable it in your project settings.
*   **Record with Cypress v13 or later.** [Azure Pipelines](/llm/markdown/app/continuous-integration/overview.md#Azure-Pipelines) and [CircleCI](/llm/markdown/app/continuous-integration/circleci.md) additionally require **Cypress v13.13.1 or later** to capture the CI metadata needed to identify runs.
*   **The run must have been recorded within the last 7 days.** Older runs can no longer be identified from CI context.
*   **Run the script after recording, in the same CI build**, so the run it should report on already exists.

### How do I fail a CI build or block a pull request when Cypress UI Coverage drops?

Use the [Results API](/llm/markdown/ui-coverage/results-api.md). Add a step to your CI workflow that installs the `@cypress/extract-cloud-results` module and calls `getUICoverageResults()` after your Cypress run. The helper returns the run's coverage summary and per-view breakdown, and your script decides whether to fail, for example by throwing an error when `summary.coverage` is below a threshold. Because the check lives in your CI job, nothing in the Cypress run itself fails; enforcement is entirely opt-in. See [Block pull requests and set policies](/llm/markdown/ui-coverage/guides/block-pull-requests.md) for a complete example.

### Do I need to install anything to use the Cypress UI Coverage Results API?

Only in CI. Install the `@cypress/extract-cloud-results` module in your CI install step with `npm install --force https://cdn.cypress.io/extract-cloud-results/v1/extract-cloud-results.tgz`. Don't add it to your `package.json` dependencies; install it separately with `--force` so you always get the latest version, as documented in the [Results API installation steps](/llm/markdown/ui-coverage/results-api.md#Installation).

### Why can't the Cypress UI Coverage Results API find my Cypress Cloud run?

`getUICoverageResults` identifies the run from the CI environment variables present when the run was recorded, so the most common causes are:

*   The script runs in a **different CI build** than the one that recorded the run, or **before** the `cypress run --record` step. Run it after recording, in the same build.
*   The run was recorded **more than 7 days ago**. Only runs from the last 7 days can be identified from CI context.
*   You record **multiple runs in one CI build** but didn't pass `runTags`. Tag each run with `--tag` and pass the matching tag to `getUICoverageResults`.
*   The run was recorded on an **unsupported Cypress version**. Azure Pipelines and CircleCI require Cypress v13.13.1 or later.

See [Required CI environment variables](/llm/markdown/ui-coverage/results-api.md#Required-CI-environment-variables) for how each provider is matched.

### Why does the Cypress UI Coverage Results API say no report was found for my run?

UI Coverage reports are generated from [Test Replay](/llm/markdown/cloud/features/test-replay.md) data. If Test Replay was disabled for the run, no report is produced and the helper throws. Enable Test Replay in your project settings and record a new run.

### How do I get Cypress UI Coverage results when I record multiple runs in one CI build?

Record each run with a distinct [`--tag`](/llm/markdown/app/references/command-line.md#cypress-run-tag-lt-tag-gt) and pass that same tag to the helper via `runTags`. For example, `cypress run --record --tag staging` is retrieved with `getUICoverageResults({ runTags: ['staging'] })`. Without tags, Cypress can't tell the runs apart and can't return a single run's results.

### Can I see which App Quality configuration or profile produced a Cypress UI Coverage report?

Yes. The result object includes a `config` property containing the [App Quality Config](/llm/markdown/ui-coverage/configuration/overview.md) as saved for the project when the run was processed. Read `config.value` for the rules and `config.updatedAt` for when that configuration last changed. Note that `config.value` is not resolved against the run's tags, so if a [Profile](/llm/markdown/ui-coverage/configuration/profiles.md) applied you match the run's tags against profile names yourself. See [Assert the configuration](/llm/markdown/ui-coverage/results-api.md#Assert-the-configuration).

### Should I block pull requests on a coverage threshold or on new coverage gaps?

Both are valid Cypress UI Coverage policies, and they suit different situations. A **coverage threshold** fails the build when overall or per-view coverage drops below a fixed percentage; it's simple and works well once your coverage is already where you want it, or for holding a critical flow like checkout to a high bar. A **baseline comparison** fails only when a run introduces _new_ untested elements, which is the better fit for an existing app with known coverage debt: it stops gaps from growing without blocking every pull request until all the old debt is paid down. Many teams enforce a threshold on critical views and a baseline everywhere else. See [Block pull requests and set policies](/llm/markdown/ui-coverage/guides/block-pull-requests.md#Choose-a-policy).

### How do I block a pull request only when new untested elements are introduced?

Compare each run against a stored **baseline** instead of a fixed threshold. Record a known-good run, save each [view's](/llm/markdown/ui-coverage/core-concepts/views.md) `untestedElementsCount` to a small JSON file committed to your repository, then in CI use the [Cypress UI Coverage Results API](/llm/markdown/ui-coverage/results-api.md) to fail the build only when a view's untested-element count rises above its baseline (or a new view arrives carrying untested elements). This lets you pay down existing gaps on your own schedule while preventing new ones from merging. The [Block pull requests and set policies](/llm/markdown/ui-coverage/guides/block-pull-requests.md#comparing-against-a-baseline) guide has the complete script.

### Why compare untested-element counts instead of the UI Coverage score when gating pull requests?

The [coverage score](/llm/markdown/ui-coverage/guides/identify-coverage-gaps.md#Step-2-Read-your-overall-coverage-score) is the share of your app's interactive elements that your tests exercise (tested ÷ total, with grouped elements counting once), which makes it ideal for tracking direction over time but noisy as a per-run gate: adding a single test can reveal a whole page of previously unseen elements and _lower_ the score even though coverage improved. In Cypress UI Coverage, a view's `untestedElementsCount` is a more direct answer to "did this change add gaps?": if it rises against the baseline, the change introduced untested elements regardless of what the percentage did. Note the two aren't interchangeable, since the score's denominator also counts navigable links while `untestedElementsCount` doesn't. See [Why compare untested-element counts instead of the coverage score?](/llm/markdown/ui-coverage/guides/block-pull-requests.md#Why-compare-untested-element-counts-instead-of-the-coverage-score).

### Where should I store my UI Coverage baseline?

Commit the Cypress UI Coverage baseline JSON file to version control so it's reviewed and versioned alongside the code that changes your coverage, and is available to every CI run. If you can't commit it, store it as a CI build artifact retrieved on later runs, or in a database when you need richer versioning across many projects. For long-lived branches, keep branch-specific baseline files so a feature branch isn't gated against `main`'s numbers. See [Best practices](/llm/markdown/ui-coverage/guides/block-pull-requests.md#Where-to-store-the-baseline).

## Troubleshooting

### Why is my UI Coverage score lower than I expect?

A few sources of untested elements commonly lower a Cypress UI Coverage score without pointing to a real gap in your suite. Third-party widgets, such as chat launchers, cookie banners, and analytics overlays, are interactive elements each counted as untested; exclude them with [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md). [Untested links](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Untested-Links) to pages no test visits, including your own help center, marketing pages, and external sites, also count against the score; exclude their destinations with [`viewFilters`](/llm/markdown/ui-coverage/configuration/viewfilters.md). Finally, one control [split into many](/llm/markdown/ui-coverage/troubleshooting.md#One-element-is-reported-as-many) by an unstable attribute adds duplicate untested elements. See [the coverage score looks wrong](/llm/markdown/ui-coverage/troubleshooting.md#The-coverage-score-looks-wrong) for the fixes.

### Why does an element my test interacts with still show as untested in UI Coverage?

Usually the command your test uses isn't one UI Coverage recognizes. It counts only a [default set of interaction commands](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Interaction-Commands), so custom commands and plugin commands like `cypress-real-events`' `realClick` don't count until you add them with [`additionalInteractionCommands`](/llm/markdown/ui-coverage/configuration/additionalinteractioncommands.md) or [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md). A custom command also has to log a [snapshot](/llm/markdown/ui-coverage/core-concepts/element-identification.md#Snapshots) referencing the element it acts on. And if you added an `allowedInteractionCommands` rule, only the commands you listed count for the matching elements, so a command you left out, even a plain `click`, no longer marks them tested. See [an element you tested is shown as untested](/llm/markdown/ui-coverage/troubleshooting.md#An-element-you-tested-is-shown-as-untested).

### I changed my UI Coverage configuration but the report didn't change. Why?

Most often the run was processed before you saved: Cypress UI Coverage reports use the configuration that was applied when they were generated, so [regenerate](/llm/markdown/ui-coverage/configuration/overview.md#Setting-configuration) the run to apply your current configuration. If it still has no effect, check whether an earlier rule matched first (the first matching rule wins for most properties), whether a [nested list replaced a root one](/llm/markdown/ui-coverage/configuration/overview.md#Configuration-scope) instead of merging with it, or whether the configuration failed to save because a property was misspelled or misplaced. See [a configuration rule has no effect](/llm/markdown/ui-coverage/troubleshooting.md#A-configuration-rule-has-no-effect) for the full checklist.

### How do I debug a UI Coverage report that looks wrong?

Start by [regenerating the run](/llm/markdown/ui-coverage/configuration/overview.md#Setting-configuration) in Cypress Cloud so it reflects your current configuration, then match your symptom to a cause on the [Troubleshooting](/llm/markdown/ui-coverage/troubleshooting.md) page, which covers duplicate elements, mis-grouped elements, tested elements shown as untested, configuration that has no effect, and unexpected scores. Because you can regenerate any past run, the fastest approach is to make one change, regenerate a recent run, and check the result before making the next.

## Using AI agents with Cypress UI Coverage

### Which Cypress Cloud MCP tools expose UI Coverage data to AI agents?

Cypress Cloud MCP provides three UI Coverage tools: `cypress_get_ui_coverage_report` returns a run's overall coverage score, tested and untested element and link counts, and the top 5 riskiest views; `cypress_get_ui_coverage_views` pages through all views sorted by most untested elements and links; and `cypress_get_ui_coverage_elements` pages through individual elements, filterable by tested or untested and scopable to a single view. Your AI agent selects them automatically based on your prompt.

### Can Cypress Cloud MCP update my Cypress tests, configuration, or runs?

No. The Cypress UI Coverage MCP tools are read-only: they retrieve report data and can't edit your test code, update your [App Quality configuration](/llm/markdown/ui-coverage/configuration/overview.md), or delete runs. An AI agent can draft test code locally in your editor, but nothing an agent does through Cypress Cloud MCP writes back to Cypress Cloud. Access is also scoped to the projects your Cypress Cloud user can already see. See [Cloud MCP security](/llm/markdown/cloud/integrations/cloud-mcp.md#Security--Privacy).

### How do I make Cypress UI Coverage reports easier for an AI agent to use?

Shape your Cypress UI Coverage report the same way you would for human review. [Filter out](/llm/markdown/ui-coverage/configuration/elementfilters.md) third-party widgets you don't own, [promote a stable attribute](/llm/markdown/ui-coverage/configuration/significantattributes.md) so elements have clean, readable names, and [group](/llm/markdown/ui-coverage/configuration/elementgroups.md) repeated controls so they count once. A high-signal report gives the agent accurate context and avoids wasting tokens on noise. See [Tune reports for better agent results](/llm/markdown/ui-coverage/work-with-ai-agents.md#Tune-reports-for-better-agent-results).

### Can an AI agent write Cypress tests for my untested UI Coverage elements?

Yes, with your review. Because Cypress UI Coverage lists untested elements with the selectors and views that produced them, an AI agent can draft Cypress tests targeting those elements and suggest the existing spec file that's the best home for them. Pair the agent with [Cypress AI Skills](/llm/markdown/app/tooling/ai-skills.md) so the tests it drafts follow Cypress best practices and match your project's conventions. Ask it to show a diff before writing files, and confirm intent and risk yourself before merging. See the [prompts to plan and draft tests](/llm/markdown/ui-coverage/work-with-ai-agents.md#Prompts-to-plan-and-draft-tests).

### Is my Cypress UI Coverage data used to train AI models?

No. Cypress UI Coverage data returned through Cypress Cloud MCP is used only to fulfill the agent's request and is never used to train or improve any LLM. Cypress also has no visibility into your AI assistant's conversation or outputs. See [Cloud MCP security and privacy](/llm/markdown/cloud/integrations/cloud-mcp.md#Security--Privacy).

## See also

*   [Troubleshooting UI Coverage](/llm/markdown/ui-coverage/troubleshooting.md) maps common report problems to their causes and fixes.
*   [Monitor changes](/llm/markdown/ui-coverage/guides/monitor-changes.md) sets up a repeatable workflow to track coverage trends and catch regressions before they merge.
*   [Work with AI agents](/llm/markdown/ui-coverage/work-with-ai-agents.md) uses the Cypress Cloud MCP to read reports, summarize gaps, and draft tests.
*   [Results API](/llm/markdown/ui-coverage/results-api.md) fetches a run's UI Coverage results in CI so you can enforce coverage standards.
*   [Configuration overview](/llm/markdown/ui-coverage/configuration/overview.md) lists every configuration option and what each one is for.
*   [Profiles](/llm/markdown/ui-coverage/configuration/profiles.md) apply different configuration to runs based on run tags.
*   [Views](/llm/markdown/ui-coverage/core-concepts/views.md) explains how URLs become views and how automatic grouping works.
*   [Element Identification](/llm/markdown/ui-coverage/core-concepts/element-identification.md) covers how elements are identified and grouped across snapshots.
*   [Interactivity](/llm/markdown/ui-coverage/core-concepts/interactivity.md) describes which commands count as coverage.
