{
  "doc": {
    "id": "ui-coverage/core-concepts/element-grouping",
    "title": "How UI Coverage groups related elements",
    "description": "UI Coverage automatically groups repeated interactive elements so they count once and a single test can cover the whole set. Learn the automatic grouping rules and how to customize them.",
    "section": "ui-coverage",
    "source_path": "/llm/markdown/ui-coverage/core-concepts/element-grouping.md",
    "version": "fbc9225067c51c52ee13224e3b702cf8a025ec12",
    "updated_at": "2026-08-14T12:36:26.878Z",
    "headings": [
      {
        "id": "ui-coverage/core-concepts/element-grouping#element-grouping",
        "text": "Element Grouping",
        "level": 1
      },
      {
        "id": "ui-coverage/core-concepts/element-grouping#how-grouping-affects-your-report-and-score",
        "text": "How grouping affects your report and score",
        "level": 2
      },
      {
        "id": "ui-coverage/core-concepts/element-grouping#automatic-grouping",
        "text": "Automatic grouping",
        "level": 2
      },
      {
        "id": "ui-coverage/core-concepts/element-grouping#example-repeated-controls-in-a-table",
        "text": "Example: repeated controls in a table",
        "level": 3
      },
      {
        "id": "ui-coverage/core-concepts/element-grouping#custom-grouping",
        "text": "Custom grouping",
        "level": 2
      },
      {
        "id": "ui-coverage/core-concepts/element-grouping#grouping-with-configuration",
        "text": "Grouping with configuration",
        "level": 3
      },
      {
        "id": "ui-coverage/core-concepts/element-grouping#grouping-with-markup-attributes",
        "text": "Grouping with markup attributes",
        "level": 3
      },
      {
        "id": "ui-coverage/core-concepts/element-grouping#see-also",
        "text": "See also",
        "level": 2
      }
    ]
  },
  "chunks": [
    {
      "id": "ui-coverage/core-concepts/element-grouping#how-grouping-affects-your-report-and-score",
      "doc_id": "ui-coverage/core-concepts/element-grouping",
      "heading": "How grouping affects your report and score",
      "heading_level": 2,
      "content_markdown": "## How grouping affects your report and score\n\nGrouping changes what you see and what you're measured against:\n\n*   **The group counts once.** A group of 50 buttons contributes a single unit to your total element count, not 50.\n*   **One interaction covers the group.** Testing any one member marks the entire group as tested, since every member shares the same behavior.\n*   **Reports stay readable.** A group appears as one row, labeled by a shared attribute or a name you choose, instead of a long list of machine-generated selectors.\n",
      "section": "ui-coverage",
      "anchors": [
        "how-grouping-affects-your-report-and-score"
      ],
      "path": "/llm/json/chunked/ui-coverage/core-concepts/element-grouping.json",
      "token_estimate": 120
    },
    {
      "id": "ui-coverage/core-concepts/element-grouping#automatic-grouping",
      "doc_id": "ui-coverage/core-concepts/element-grouping",
      "heading": "Automatic grouping",
      "heading_level": 2,
      "content_markdown": "## Automatic grouping\n\nOut of the box, with no configuration, UI Coverage groups elements it can recognize as variations of the same control. It uses structural and behavioral signals from the DOM:\n\n*   **Shared test attributes.** Interactive elements with the same **test attribute** value are grouped (`data-cy`, `data-test`, `data-testid`, `data-test-id`, `data-qa`, `row-id`, or any attribute you add to [`significantAttributes`](/llm/markdown/ui-coverage/configuration/significantattributes.md)). For example, a `data-cy=\"favorite\"` button repeated on every product card. The `id` and `name` fallbacks used for [element identity](/llm/markdown/ui-coverage/core-concepts/element-identification.md#How-an-element-is-identified) do **not** group elements.\n    *   Forms are a boundary. Elements with the same test attribute inside **different** identified form-like ancestors are grouped separately, so a `<button data-cy=\"submit\">` inside `<form id=\"signup\">` isn't grouped with one inside `<form id=\"login\">`. Reports show these as `#signup [data-cy=\"submit\"]` and `#login [data-cy=\"submit\"]`. \"Form-like\" means a `<form>` element, an element with `role=\"form\"`, or a custom element whose tag name ends in `form`, such as `<checkout-form>`. This keeps a generic attribute like `data-cy=\"submit\"` from collapsing every form in your app into one group. If you want to group them anyway, use [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md).\n*   **Form controls and their labels.** A `<label>` is grouped with the form control it identifies, so the pair counts as one unit instead of two.\n*   **Table and grid rows.** Controls in the same position across sibling rows are grouped, in `<table>` elements and ARIA grids (`role=\"grid\"`, `role=\"table\"`, and `role=\"treegrid\"`).\n*   **Repeated structures.** Elements that sit at the same depth in the DOM and share a tag and class hierarchy up to a common parent are grouped, catching repeated lists and cards that behave alike even without test attributes. Elements stay separate when their tag names differ, their `id` values differ, or (for `<input>` and `<button>`) their `type` attributes differ.\n*   **Links to the same view.** Links whose `href` resolves to the same [view](/llm/markdown/ui-coverage/core-concepts/views.md) are represented by that view instead of listed separately. Same-page fragment links such as `#pricing` have no view, so they group only with other links whose `href` is exactly the same.\n\nAutomatic grouping requires at least two similar elements. A control that appears only once stays on its own.\n\n### Example: repeated controls in a table\n\nConsider a customer table where each row has a \"Delete\" button:\n\n```\n<table>  <tr>    <td>Aisha Rahman</td>    <td>      <button>Delete</button>    </td>  </tr>  <tr>    <td>Mateo Ramirez</td>    <td>      <button>Delete</button>    </td>  </tr></table>\n```\n\nThe \"Delete\" buttons occupy the same position in sibling rows, so UI Coverage groups them. A test that deletes one customer marks the group as tested, and the report shows a single \"Delete\" group instead of one element per row.\n",
      "section": "ui-coverage",
      "anchors": [
        "automatic-grouping"
      ],
      "path": "/llm/json/chunked/ui-coverage/core-concepts/element-grouping.json",
      "token_estimate": 561
    },
    {
      "id": "ui-coverage/core-concepts/element-grouping#example-repeated-controls-in-a-table",
      "doc_id": "ui-coverage/core-concepts/element-grouping",
      "heading": "Example: repeated controls in a table",
      "heading_level": 3,
      "content_markdown": "### Example: repeated controls in a table\n\nConsider a customer table where each row has a \"Delete\" button:\n\n```\n<table>  <tr>    <td>Aisha Rahman</td>    <td>      <button>Delete</button>    </td>  </tr>  <tr>    <td>Mateo Ramirez</td>    <td>      <button>Delete</button>    </td>  </tr></table>\n```\n\nThe \"Delete\" buttons occupy the same position in sibling rows, so UI Coverage groups them. A test that deletes one customer marks the group as tested, and the report shows a single \"Delete\" group instead of one element per row.\n",
      "section": "ui-coverage",
      "anchors": [
        "example-repeated-controls-in-a-table"
      ],
      "path": "/llm/json/chunked/ui-coverage/core-concepts/element-grouping.json",
      "token_estimate": 100
    },
    {
      "id": "ui-coverage/core-concepts/element-grouping#custom-grouping",
      "doc_id": "ui-coverage/core-concepts/element-grouping",
      "heading": "Custom grouping",
      "heading_level": 2,
      "content_markdown": "## Custom grouping\n\nAutomatic grouping handles most cases, but you can override it when it collapses too much, too little, or names things unhelpfully. You have two ways to take control: centrally in Cypress Cloud, or in your application's markup.\n\n### Grouping with configuration\n\nWhen you want to manage grouping centrally in Cypress Cloud without changing application code, use the [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) configuration. Each rule matches interactive elements with a CSS selector and collects them into one named group. This is the right tool when the team reading the reports isn't the team that owns the markup, or when you want to correct the automatic grouping without a code change.\n\nApp Quality Config\n\n```\n{  \"uiCoverage\": {    \"elementGroups\": [      {        \"selector\": \"[data-cy^='add-to-cart-']\",        \"name\": \"Add to Cart Button\"      }    ]  }}\n```\n\nThe [`elementGroups` configuration guide](/llm/markdown/ui-coverage/configuration/elementgroups.md) covers the full syntax, including how to name groups, order rules, and scope them to specific iframes or shadow DOM hosts with `documentScope`.\n\n### Grouping with markup attributes\n\nYou can also define groups directly in your application's markup with the `data-cy-ui-group` attribute, without any Cypress Cloud configuration. Elements that share the same attribute value are grouped together, and the group appears in reports under a selector formatted with that value, such as `[data-cy-ui-group=\"pagination\"]`.\n\n```\n<button data-cy-ui-group=\"pagination\">1</button><button data-cy-ui-group=\"pagination\">2</button><button data-cy-ui-group=\"pagination\">3</button>\n```\n\nWhere you place the attribute determines what it groups:\n\n*   **On an interactive element**, it groups that element only.\n*   **On a wrapper or parent element**, it groups every interactive element inside it.\n*   **On nested wrappers**, each interactive element joins the group of its closest ancestor that has the attribute.\n\nGroups defined this way take priority over every other grouping mechanism, including [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) configuration rules. Reach for the attribute when the team that owns the markup also owns the grouping decisions.\n",
      "section": "ui-coverage",
      "anchors": [
        "custom-grouping"
      ],
      "path": "/llm/json/chunked/ui-coverage/core-concepts/element-grouping.json",
      "token_estimate": 393
    },
    {
      "id": "ui-coverage/core-concepts/element-grouping#grouping-with-configuration",
      "doc_id": "ui-coverage/core-concepts/element-grouping",
      "heading": "Grouping with configuration",
      "heading_level": 3,
      "content_markdown": "### Grouping with configuration\n\nWhen you want to manage grouping centrally in Cypress Cloud without changing application code, use the [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) configuration. Each rule matches interactive elements with a CSS selector and collects them into one named group. This is the right tool when the team reading the reports isn't the team that owns the markup, or when you want to correct the automatic grouping without a code change.\n\nApp Quality Config\n\n```\n{  \"uiCoverage\": {    \"elementGroups\": [      {        \"selector\": \"[data-cy^='add-to-cart-']\",        \"name\": \"Add to Cart Button\"      }    ]  }}\n```\n\nThe [`elementGroups` configuration guide](/llm/markdown/ui-coverage/configuration/elementgroups.md) covers the full syntax, including how to name groups, order rules, and scope them to specific iframes or shadow DOM hosts with `documentScope`.\n",
      "section": "ui-coverage",
      "anchors": [
        "grouping-with-configuration"
      ],
      "path": "/llm/json/chunked/ui-coverage/core-concepts/element-grouping.json",
      "token_estimate": 156
    },
    {
      "id": "ui-coverage/core-concepts/element-grouping#grouping-with-markup-attributes",
      "doc_id": "ui-coverage/core-concepts/element-grouping",
      "heading": "Grouping with markup attributes",
      "heading_level": 3,
      "content_markdown": "### Grouping with markup attributes\n\nYou can also define groups directly in your application's markup with the `data-cy-ui-group` attribute, without any Cypress Cloud configuration. Elements that share the same attribute value are grouped together, and the group appears in reports under a selector formatted with that value, such as `[data-cy-ui-group=\"pagination\"]`.\n\n```\n<button data-cy-ui-group=\"pagination\">1</button><button data-cy-ui-group=\"pagination\">2</button><button data-cy-ui-group=\"pagination\">3</button>\n```\n\nWhere you place the attribute determines what it groups:\n\n*   **On an interactive element**, it groups that element only.\n*   **On a wrapper or parent element**, it groups every interactive element inside it.\n*   **On nested wrappers**, each interactive element joins the group of its closest ancestor that has the attribute.\n\nGroups defined this way take priority over every other grouping mechanism, including [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) configuration rules. Reach for the attribute when the team that owns the markup also owns the grouping decisions.\n",
      "section": "ui-coverage",
      "anchors": [
        "grouping-with-markup-attributes"
      ],
      "path": "/llm/json/chunked/ui-coverage/core-concepts/element-grouping.json",
      "token_estimate": 184
    },
    {
      "id": "ui-coverage/core-concepts/element-grouping#see-also",
      "doc_id": "ui-coverage/core-concepts/element-grouping",
      "heading": "See also",
      "heading_level": 2,
      "content_markdown": "## See also\n\n*   [`elementGroups`](/llm/markdown/ui-coverage/configuration/elementgroups.md) defines custom groups in Cypress Cloud and overrides the automatic rules.\n*   [`significantAttributes`](/llm/markdown/ui-coverage/configuration/significantattributes.md) changes which attributes identify and group elements.\n*   [`elementFilters`](/llm/markdown/ui-coverage/configuration/elementfilters.md) removes elements from reports entirely, so they're never grouped or scored.\n*   [Element Identification](/llm/markdown/ui-coverage/core-concepts/element-identification.md) explains the significant attributes that drive grouping and how elements are recognized across snapshots.\n*   [Guide: Reduce noise in UI Coverage reports](/llm/markdown/ui-coverage/guides/reduce-noise.md) walks through combining grouping and filtering to clean up a report.\n*   [UI Coverage FAQ](/llm/markdown/ui-coverage/faq.md) answers common questions about grouping, scores, and configuration.\n",
      "section": "ui-coverage",
      "anchors": [
        "see-also"
      ],
      "path": "/llm/json/chunked/ui-coverage/core-concepts/element-grouping.json",
      "token_estimate": 115
    }
  ]
}