{
  "doc": {
    "id": "ui-coverage/configuration/elementgroups",
    "title": "elementGroups: group related elements in UI Coverage",
    "description": "The elementGroups configuration in Cypress UI Coverage groups related elements into a single unit, so testing one element counts as testing them all.",
    "section": "ui-coverage",
    "source_path": "/llm/markdown/ui-coverage/configuration/elementgroups.md",
    "version": "f97f06d85653c51afe39a9bd3cefda946807f150",
    "updated_at": "2026-10-05T21:01:45.863Z",
    "headings": [
      {
        "id": "ui-coverage/configuration/elementgroups#group-related-elements-elementgroups",
        "text": "Group related elements - elementGroups",
        "level": 1
      },
      {
        "id": "ui-coverage/configuration/elementgroups#why-use-elementgroups",
        "text": "Why use elementGroups?",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/elementgroups#setting-elementgroups",
        "text": "Setting elementGroups",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/elementgroups#syntax",
        "text": "Syntax",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/elementgroups#options",
        "text": "Options",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#how-are-elementgroups-rules-applied",
        "text": "How are elementGroups rules applied?",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#validation-rules",
        "text": "Validation rules",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#examples",
        "text": "Examples",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/elementgroups#consolidate-repeated-elements",
        "text": "Consolidate repeated elements",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#config",
        "text": "Config",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#html",
        "text": "HTML",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#elements-shown-in-ui",
        "text": "Elements shown in UI",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#give-a-group-a-readable-name",
        "text": "Give a group a readable name",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#config",
        "text": "Config",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#html",
        "text": "HTML",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#elements-shown-in-ui",
        "text": "Elements shown in UI",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#order-specific-rules-before-broad-ones",
        "text": "Order specific rules before broad ones",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#config",
        "text": "Config",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#html",
        "text": "HTML",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#elements-shown-in-ui",
        "text": "Elements shown in UI",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#group-all-elements-in-a-container",
        "text": "Group all elements in a container",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#config",
        "text": "Config",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#html",
        "text": "HTML",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#elements-shown-in-ui",
        "text": "Elements shown in UI",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#group-form-controls-with-their-labels",
        "text": "Group form controls with their labels",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#config",
        "text": "Config",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#html",
        "text": "HTML",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#elements-shown-in-ui",
        "text": "Elements shown in UI",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#group-elements-inside-a-shadow-dom",
        "text": "Group elements inside a shadow DOM",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#config",
        "text": "Config",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#html",
        "text": "HTML",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#elements-shown-in-ui",
        "text": "Elements shown in UI",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#group-elements-inside-an-iframe",
        "text": "Group elements inside an iframe",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/elementgroups#config",
        "text": "Config",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#html",
        "text": "HTML",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#elements-shown-in-ui",
        "text": "Elements shown in UI",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/elementgroups#see-also",
        "text": "See also",
        "level": 2
      }
    ]
  },
  "content": {
    "type": "root",
    "children": [
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "Group related elements - `elementGroups`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `elementGroups` configuration combines related elements into a single unit in your UI Coverage report. A group counts once toward your coverage score, and an interaction with any element in the group marks the whole group as tested. This means a list of 50 untested product cards no longer appears as 50 untested elements dragging down your score. Instead, it appears as one clearly named group that a single test can cover."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Without meaningful groups, a report can fill up with elements listed under machine-generated names that are hard to act on:"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Why use elementGroups?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "UI Coverage already "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/ui-coverage/core-concepts/element-grouping.md",
            "children": [
              {
                "type": "text",
                "value": "groups elements automatically"
              }
            ]
          },
          {
            "type": "text",
            "value": " based on their structure in the DOM. Use `elementGroups` when the automatic grouping doesn't match how your application actually behaves:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Consolidate repeated elements: Collapse dynamic or repeated elements, such as items in a list, carousel, or data table, into one logical group."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Correct the automatic grouping: Split apart elements that were grouped together incorrectly, or unite elements that the automatic rules kept separate."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Make reports readable: Replace machine-generated selectors with meaningful names like \"Remove Item Button\" or \"Shipping Method Option\", so anyone reading the report understands what needs testing."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Group across markup differences: Combine elements that share behavior but not structure, such as form controls and their labels."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your goal is different, such as renaming a single element or removing elements from reports entirely, see "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/ui-coverage/configuration/overview.md#Which-option-do-I-need",
            "children": [
              {
                "type": "text",
                "value": "Which option do I need?"
              }
            ]
          },
          {
            "type": "text",
            "value": " in the configuration overview."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Setting elementGroups"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To add or edit `elementGroups`, open the App Quality tab in your project settings in Cypress Cloud. See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/ui-coverage/configuration/overview.md#Setting-configuration",
            "children": [
              {
                "type": "text",
                "value": "Setting configuration"
              }
            ]
          },
          {
            "type": "text",
            "value": " for details, including how to regenerate past reports with a new configuration without rerunning your tests."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Syntax"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "App Quality Config"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"uiCoverage\": {\n    \"elementGroups\": [\n      {\n        \"selector\": string,\n        \"name\": string,\n        \"documentScope\": [string],\n        \"comment\": string\n      }\n    ]\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Options"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Option"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Required"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Default"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Description"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`selector`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Required"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": []
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "A CSS selector matched against each interactive element. Supports standard CSS selector syntax, including IDs, classes, attributes, combinators, and functional pseudo-classes like `:has()`."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`name`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Optional"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`selector`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "A human-readable name for the group, displayed in UI Coverage reports. Each group's name must be unique."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`documentScope`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Optional"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": []
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "An ordered array of CSS selectors that match document hosts (iframes or shadow DOM hosts) in the element's ancestor chain, from outermost to innermost. Use this to group only elements inside a specific iframe or shadow DOM. Hosts that aren't listed may appear between the ones that are."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`comment`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Optional"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": []
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "A note about why this rule exists, for your team's benefit. Comments have no effect on how elements are grouped."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "How are elementGroups rules applied?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Rules are evaluated in order, and each element joins the group of the first rule whose `selector` matches it. Elements that match no rules fall back to the automatic "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/ui-coverage/core-concepts/element-grouping.md",
            "children": [
              {
                "type": "text",
                "value": "element grouping rules"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A few behaviors are worth knowing:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Custom groups override automatic grouping. An element that matches an `elementGroups` rule is grouped by that rule alone. This includes links, which would otherwise be grouped by their `href` patterns."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "A group forms even with one match. Unlike the automatic rules, which require at least two similar elements, an `elementGroups` rule that matches a single element still produces a named group in the report."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Filtered elements are never grouped. Elements excluded from reports by "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/ui-coverage/configuration/elementfilters.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`elementFilters`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " are not considered for grouping."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The `data-cy-ui-group` attribute wins. Elements that declare a group directly in your markup with the "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/ui-coverage/core-concepts/element-grouping.md#Grouping-with-markup-attributes",
                    "children": [
                      {
                        "type": "text",
                        "value": "`data-cy-ui-group` attribute"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " keep that group, even if they also match an `elementGroups` rule."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Validation rules"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress Cloud rejects a configuration when:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Two rules have the same `selector` (with the same `documentScope`). Duplicates can never both apply, because the first matching rule wins."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Two rules have the same `name`, or one rule's `name` matches another rule's `selector`. Groups are identified by these values, so they must be unique."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "A `selector` or `documentScope` entry isn't valid CSS selector syntax."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`documentScope` is present but empty. Omit the property to match in any document."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "A rule contains a property other than the four listed above."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Examples"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Consolidate repeated elements"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Elements generated from data often have dynamic attribute values, like an add to cart button rendered for each product in a listing. One rule with an attribute prefix selector collapses all of them into a single group. Without a `name`, the group is displayed under its selector."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Config"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "App Quality Config"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"uiCoverage\": {\n    \"elementGroups\": [\n      {\n        \"selector\": \"[data-cy^='add-to-cart-']\"\n      }\n    ]\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "HTML"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<body>\n  <button data-cy=\"add-to-cart-101\">Add to Cart</button>\n  <button data-cy=\"add-to-cart-102\">Add to Cart</button>\n  <button data-cy=\"add-to-cart-103\">Add to Cart</button>\n</body>"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Elements shown in UI"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Without the rule, the result depends on the automatic grouping heuristics. The buttons may appear individually or under a machine-generated name:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "[data-cy=\"add-to-cart-101\"]\n[data-cy=\"add-to-cart-102\"]\n[data-cy=\"add-to-cart-103\"]"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With the rule, the buttons always appear as one group:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "[data-cy^='add-to-cart-'] (3 instances)"
      },
      {
        "type": "thematicBreak"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Give a group a readable name"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Add a `name` so the report describes the interface instead of your selectors. Here, the remove buttons in a shopping cart appear as a single \"Remove Item Button\" group, no matter which products the cart contains."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Config"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "App Quality Config"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"uiCoverage\": {\n    \"elementGroups\": [\n      {\n        \"selector\": \"[id^='remove-item-']\",\n        \"name\": \"Remove Item Button\"\n      }\n    ]\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "HTML"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<body>\n  <button id=\"remove-item-101\">Remove</button>\n  <button id=\"remove-item-102\">Remove</button>\n  <button id=\"remove-item-103\">Remove</button>\n  <button id=\"remove-item-104\">Remove</button>\n</body>"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Elements shown in UI"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "Remove Item Button (4 instances)"
      },
      {
        "type": "thematicBreak"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Order specific rules before broad ones"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Each element joins the first rule that matches it, so list narrower rules first. Here, the featured product's button gets its own group because its rule comes before the catch-all rule. If the rules were reversed, the catch-all would capture all three buttons and the \"Featured Buy Now Button\" rule would never match anything."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Config"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "App Quality Config"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"uiCoverage\": {\n    \"elementGroups\": [\n      {\n        \"selector\": \"[data-cy='buy-now-featured']\",\n        \"name\": \"Featured Buy Now Button\"\n      },\n      {\n        \"selector\": \"[data-cy^='buy-now-']\",\n        \"name\": \"Buy Now Button\"\n      }\n    ]\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "HTML"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<body>\n  <button data-cy=\"buy-now-featured\">Buy Now</button>\n  <button data-cy=\"buy-now-101\">Buy Now</button>\n  <button data-cy=\"buy-now-102\">Buy Now</button>\n</body>"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Elements shown in UI"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "Featured Buy Now Button (1 instance)\nBuy Now Button (2 instances)"
      },
      {
        "type": "thematicBreak"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Group all elements in a container"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Use a descendant combinator to group every interactive element inside a container. This example collapses a delivery date picker's day buttons, which would otherwise appear as dozens of separate elements, into one group. The selector must match the interactive elements themselves, not just the container."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Config"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "App Quality Config"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"uiCoverage\": {\n    \"elementGroups\": [\n      {\n        \"selector\": \"#datepicker button\",\n        \"name\": \"Datepicker Day\"\n      }\n    ]\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "HTML"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<body>\n  <div id=\"datepicker\">\n    <button id=\"day-1\">1</button>\n    <button id=\"day-2\">2</button>\n    <button id=\"day-3\">3</button>\n  </div>\n</body>"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Elements shown in UI"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "Datepicker Day (3 instances)"
      },
      {
        "type": "thematicBreak"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Group form controls with their labels"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A comma-separated selector list can unite elements with different markup. This example groups a checkout page's shipping method radio inputs together with their clickable labels, using `:has()` to match the labels."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Config"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "App Quality Config"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"uiCoverage\": {\n    \"elementGroups\": [\n      {\n        \"selector\": \"input[name='shipping'], label:has(input[name='shipping'])\",\n        \"name\": \"Shipping Method Option\"\n      }\n    ]\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "HTML"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<body>\n  <label>\n    <input type=\"radio\" id=\"standard\" name=\"shipping\" />\n    Standard\n  </label>\n  <label>\n    <input type=\"radio\" id=\"express\" name=\"shipping\" />\n    Express\n  </label>\n</body>"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Elements shown in UI"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "Shipping Method Option (4 instances)"
      },
      {
        "type": "thematicBreak"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Group elements inside a shadow DOM"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Third-party widgets and design system components often render inside a shadow DOM. Use `documentScope` to apply a rule only to elements inside a specific shadow DOM host. Here, only the buttons inside the `<support-chat>` component's shadow root are grouped; the button in the main document also matches the `button` selector, but stays separate because it's outside the scope."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Config"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "App Quality Config"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"uiCoverage\": {\n    \"elementGroups\": [\n      {\n        \"selector\": \"button\",\n        \"name\": \"Support Chat Actions\",\n        \"documentScope\": [\"support-chat\"]\n      }\n    ]\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "HTML"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<body>\n  <button id=\"open-support-chat\">Chat with us</button>\n  <support-chat>\n    #shadow-dom\n      <button id=\"send-message\">Send</button>\n      <button id=\"attach-file\">Attach</button>\n  </support-chat>\n</body>"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Elements shown in UI"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "#open-support-chat\nSupport Chat Actions (2 instances)"
      },
      {
        "type": "thematicBreak"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Group elements inside an iframe"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`documentScope` works the same way for embedded services that render inside an iframe, such as a payment provider on a checkout page. The scope selector matches the `iframe` element itself in its parent document. Here, only the buttons inside the `#payment-provider` iframe are grouped, while the coupon button in the main document remains a separate element."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Config"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "App Quality Config"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{\n  \"uiCoverage\": {\n    \"elementGroups\": [\n      {\n        \"selector\": \"[data-action]\",\n        \"name\": \"Payment Widget Actions\",\n        \"documentScope\": [\"#payment-provider\"]\n      }\n    ]\n  }\n}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "HTML"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<body>\n  <button data-action=\"apply-coupon\">Apply Coupon</button>\n  <iframe id=\"payment-provider\" src=\"https://payments.example.com\">\n    <html>\n      <body>\n        <button data-action=\"submit-payment\">Pay Now</button>\n        <button data-action=\"change-method\">Change Payment Method</button>\n      </body>\n    </html>\n  </iframe>\n</body>"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Elements shown in UI"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "[data-action=\"apply-coupon\"]\nPayment Widget Actions (2 instances)"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For nested documents, list one selector per host from outermost to innermost, for example `\"documentScope\": [\"#payment-provider\", \"secure-card-input\"]`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After saving configuration changes, regenerate a recent run to preview your groups without rerunning your tests. See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/ui-coverage/configuration/overview.md#Setting-configuration",
            "children": [
              {
                "type": "text",
                "value": "Setting configuration"
              }
            ]
          },
          {
            "type": "text",
            "value": " for how to regenerate a report."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "See also"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/ui-coverage/core-concepts/element-grouping.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Element Grouping"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " explains the automatic grouping rules that apply when no `elementGroups` rule matches, and the `data-cy-ui-group` markup attribute."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/ui-coverage/configuration/elements.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`elements`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " assigns a stable identity and name to a single element rather than a group."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/ui-coverage/configuration/elementfilters.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`elementFilters`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " removes elements from reports entirely instead of grouping them."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/ui-coverage/configuration/overview.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Configuration overview"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " covers where configuration lives and how to regenerate reports after changing it."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/ui-coverage/guides/reduce-noise.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Guide: Reduce noise in UI Coverage reports"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " walks through combining these options to clean up a report."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/ui-coverage/faq.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "UI Coverage FAQ"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " answers common questions about grouping, scores, and configuration."
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "token_estimate": 2224
}