{
  "doc": {
    "id": "ui-coverage/configuration/additionalinteractioncommands",
    "title": "additionalInteractionCommands: count custom commands as coverage in UI Coverage",
    "description": "Make Cypress UI Coverage count your custom Cypress commands and third-party commands, such as cypress-real-events realClick and realType, as interactions so the elements they touch are marked as tested.",
    "section": "ui-coverage",
    "source_path": "/llm/markdown/ui-coverage/configuration/additionalinteractioncommands.md",
    "version": "29f95bf8bb06f320986f3749f5bf09a35a409eab",
    "updated_at": "2026-09-04T10:49:54.630Z",
    "headings": [
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#track-custom-commands-additionalinteractioncommands",
        "text": "Track custom commands - additionalInteractionCommands",
        "level": 1
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#why-use-additionalinteractioncommands",
        "text": "Why use additionalInteractionCommands?",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#scope",
        "text": "Scope",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#setting-additionalinteractioncommands",
        "text": "Setting additionalInteractionCommands",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#syntax",
        "text": "Syntax",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#validation-rules",
        "text": "Validation rules",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#how-additional-interaction-commands-are-applied",
        "text": "How additional interaction commands are applied",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#requirements-for-a-custom-command",
        "text": "Requirements for a custom command",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#relationship-to-allowedinteractioncommands",
        "text": "Relationship to allowedInteractionCommands",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#examples",
        "text": "Examples",
        "level": 2
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#track-cypress-real-events-commands",
        "text": "Track cypress-real-events commands",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#config",
        "text": "Config",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#usage-in-tests",
        "text": "Usage in tests",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#track-your-own-custom-commands",
        "text": "Track your own custom commands",
        "level": 3
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#config",
        "text": "Config",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#usage-in-tests",
        "text": "Usage in tests",
        "level": 4
      },
      {
        "id": "ui-coverage/configuration/additionalinteractioncommands#see-also",
        "text": "See also",
        "level": 2
      }
    ]
  },
  "chunks": [
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#why-use-additionalinteractioncommands",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Why use additionalInteractionCommands?",
      "heading_level": 2,
      "content_markdown": "## Why use additionalInteractionCommands?\n\n*   **Get credit for custom commands**: If your team wraps interactions in [custom commands](/llm/markdown/api/cypress-api/custom-commands.md), such as a `login()` helper that types and clicks, list them so the elements they touch count as tested.\n*   **Support third-party interaction plugins**: Plugins like [`cypress-real-events`](#Track-cypress-real-events-commands) add commands (`realClick`, `realType`, `realHover`) that fire native browser events. These aren't built-in Cypress commands, so UI Coverage doesn't recognize them until you list them.\n*   **Keep your score accurate**: Every command your tests rely on that UI Coverage doesn't recognize leaves real coverage unreported. Declaring them removes false gaps from your reports.\n",
      "section": "ui-coverage",
      "anchors": [
        "why-use-additionalinteractioncommands"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 131
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#scope",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Scope",
      "heading_level": 2,
      "content_markdown": "## Scope\n\n**Note:** `additionalInteractionCommands` applies to UI Coverage only and must be nested under the `uiCoverage` key. Unlike properties such as `significantAttributes`, it has no root-level or Cypress Accessibility equivalent, so it never affects Accessibility reports.\n",
      "section": "ui-coverage",
      "anchors": [
        "scope"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 48
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#setting-additionalinteractioncommands",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Setting additionalInteractionCommands",
      "heading_level": 2,
      "content_markdown": "## Setting additionalInteractionCommands\n\nTo add or edit `additionalInteractionCommands`, open the **App Quality** tab in your project settings in Cypress Cloud. See [Setting configuration](/llm/markdown/ui-coverage/configuration/overview.md#Setting-configuration) for details, including how to regenerate past reports with a new configuration without rerunning your tests.\n",
      "section": "ui-coverage",
      "anchors": [
        "setting-additionalinteractioncommands"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 52
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#syntax",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Syntax",
      "heading_level": 2,
      "content_markdown": "## Syntax\n\nApp Quality Config\n\n```\n{\n  \"uiCoverage\": {\n    \"additionalInteractionCommands\": [string]\n  }\n}\n```\n\nEach entry is the name of a Cypress command, such as `\"realClick\"` or `\"selectDate\"`, written exactly as it appears in your test code. Entries are command names only: not CSS selectors and not the `cy.` prefix. The property is optional and defaults to an empty list, so the [built-in interaction commands](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Interaction-Commands) always apply on their own.\n\n### Validation rules\n\nCypress Cloud rejects a configuration when the same command name appears twice in the list, or when an entry isn't a plain string.\n",
      "section": "ui-coverage",
      "anchors": [
        "syntax"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 128
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#how-additional-interaction-commands-are-applied",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "How additional interaction commands are applied",
      "heading_level": 2,
      "content_markdown": "## How additional interaction commands are applied\n\nA command you list here counts as an interaction only when it logs a [snapshot](/llm/markdown/ui-coverage/core-concepts/element-identification.md#Snapshots) that highlights the element it acts on. UI Coverage reads that snapshot to know which element the interaction belongs to, so a command with no subject-referencing snapshot is ignored even when its name is listed. Built-in commands log this snapshot automatically; a custom command must do it explicitly (see [Requirements for a custom command](#Requirements-for-a-custom-command)).\n\nKeep these behaviors in mind:\n\n*   **Your list is added to the defaults, not a replacement for them.** The built-in commands keep counting; you're extending the set, not overriding it. To _limit_ which commands count for specific elements, use [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md).\n*   **Listing a built-in command has no effect.** The [built-in interaction commands](/llm/markdown/ui-coverage/core-concepts/interactivity.md#Interaction-Commands) already count on their own. `additionalInteractionCommands` is only for names UI Coverage doesn't already recognize.\n*   **Overwriting a built-in command keeps its name.** UI Coverage matches on the name a command logs under, so a built-in interaction command customized with [`Cypress.Commands.overwrite`](/llm/markdown/api/cypress-api/custom-commands.md#Overwrite-Existing-Commands) stays recognized automatically under its original name, without being listed here, as long as your version still logs a snapshot referencing the subject. Only a brand-new command name added with `Cypress.Commands.add` needs to be listed.\n*   **Custom command names are matched case-sensitively.** `\"realClick\"` matches `realClick` but not `realclick`. Copy the name exactly as you registered it with `Cypress.Commands.add`.\n\n### Requirements for a custom command\n\nListing a command name isn't enough on its own. For UI Coverage to credit the interaction to an element, the custom command must give it an element to credit, by logging a snapshot that references the subject element. In practice that means the command should:\n\n1.  Receive the element as its subject, by registering with [`prevSubject`](/llm/markdown/api/cypress-api/custom-commands.md#Arguments).\n2.  Log the interaction against that element with [`Cypress.log`](/llm/markdown/api/cypress-api/cypress-log.md), passing the subject as `$el`.\n3.  Capture at least one snapshot on that log entry.\n\n*   JavaScript\n*   TypeScript\n\ncypress/support/commands.js\n\n```\n// A custom command that UI Coverage can track\nCypress.Commands.add(\n  'selectDate',\n  { prevSubject: ['element'] },\n  (subject, date) => {\n    const log = Cypress.log({ $el: subject, message: date, autoEnd: false })\n\n    log.snapshot('before')\n    // ...interact with the element to pick the date...\n\n    return cy.wrap(subject, { log: false }).then(() => {\n      log.snapshot('after').end()\n    })\n  }\n)\n```\n\ncypress/support/commands.ts\n\n```\n// A custom command that UI Coverage can track\nCypress.Commands.add(\n  'selectDate',\n  { prevSubject: ['element'] },\n  (subject: JQuery<HTMLElement>, date: string) => {\n    const log = Cypress.log({ $el: subject, message: date, autoEnd: false })\n\n    log.snapshot('before')\n    // ...interact with the element to pick the date...\n\n    return cy.wrap(subject, { log: false }).then(() => {\n      log.snapshot('after').end()\n    })\n  }\n)\n```\n\nBeyond letting UI Coverage credit the interaction, logging a snapshot that references the subject is what renders element highlights for the command in Cypress open mode and [Test Replay](/llm/markdown/cloud/features/test-replay.md). See [Custom Commands](/llm/markdown/api/cypress-api/custom-commands.md) for the full API.\n\n### Relationship to allowedInteractionCommands\n\nAny command name you list in [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md) is automatically recognized as an interaction command as well. You don't need to declare the same custom command in both places: use `additionalInteractionCommands` to count a command everywhere it's used, and `allowedInteractionCommands` when a command should count only for elements matching a specific selector.\n",
      "section": "ui-coverage",
      "anchors": [
        "how-additional-interaction-commands-are-applied"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 693
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#requirements-for-a-custom-command",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Requirements for a custom command",
      "heading_level": 3,
      "content_markdown": "### Requirements for a custom command\n\nListing a command name isn't enough on its own. For UI Coverage to credit the interaction to an element, the custom command must give it an element to credit, by logging a snapshot that references the subject element. In practice that means the command should:\n\n1.  Receive the element as its subject, by registering with [`prevSubject`](/llm/markdown/api/cypress-api/custom-commands.md#Arguments).\n2.  Log the interaction against that element with [`Cypress.log`](/llm/markdown/api/cypress-api/cypress-log.md), passing the subject as `$el`.\n3.  Capture at least one snapshot on that log entry.\n\n*   JavaScript\n*   TypeScript\n\ncypress/support/commands.js\n\n```\n// A custom command that UI Coverage can track\nCypress.Commands.add(\n  'selectDate',\n  { prevSubject: ['element'] },\n  (subject, date) => {\n    const log = Cypress.log({ $el: subject, message: date, autoEnd: false })\n\n    log.snapshot('before')\n    // ...interact with the element to pick the date...\n\n    return cy.wrap(subject, { log: false }).then(() => {\n      log.snapshot('after').end()\n    })\n  }\n)\n```\n\ncypress/support/commands.ts\n\n```\n// A custom command that UI Coverage can track\nCypress.Commands.add(\n  'selectDate',\n  { prevSubject: ['element'] },\n  (subject: JQuery<HTMLElement>, date: string) => {\n    const log = Cypress.log({ $el: subject, message: date, autoEnd: false })\n\n    log.snapshot('before')\n    // ...interact with the element to pick the date...\n\n    return cy.wrap(subject, { log: false }).then(() => {\n      log.snapshot('after').end()\n    })\n  }\n)\n```\n\nBeyond letting UI Coverage credit the interaction, logging a snapshot that references the subject is what renders element highlights for the command in Cypress open mode and [Test Replay](/llm/markdown/cloud/features/test-replay.md). See [Custom Commands](/llm/markdown/api/cypress-api/custom-commands.md) for the full API.\n",
      "section": "ui-coverage",
      "anchors": [
        "requirements-for-a-custom-command"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 317
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#relationship-to-allowedinteractioncommands",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Relationship to allowedInteractionCommands",
      "heading_level": 3,
      "content_markdown": "### Relationship to allowedInteractionCommands\n\nAny command name you list in [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md) is automatically recognized as an interaction command as well. You don't need to declare the same custom command in both places: use `additionalInteractionCommands` to count a command everywhere it's used, and `allowedInteractionCommands` when a command should count only for elements matching a specific selector.\n",
      "section": "ui-coverage",
      "anchors": [
        "relationship-to-allowedinteractioncommands"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 73
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#examples",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Examples",
      "heading_level": 2,
      "content_markdown": "## Examples\n\n### Track `cypress-real-events` commands\n\n[`cypress-real-events`](https://github.com/dmtrKovalenko/cypress-real-events) fires native browser events through commands like `realClick`, `realType`, and `realHover`. Because these aren't built-in Cypress commands, UI Coverage doesn't count them until you list them.\n\n#### Config\n\nApp Quality Config\n\n```\n{\n  \"uiCoverage\": {\n    \"additionalInteractionCommands\": [\"realClick\", \"realType\", \"realHover\"]\n  }\n}\n```\n\n#### Usage in tests\n\n```\n// Now these commands mark their target elements as tested\ncy.get('[data-cy=\"button\"]').realClick()\ncy.get('[data-cy=\"input\"]').realType('Hello World')\ncy.get('[data-cy=\"tooltip-trigger\"]').realHover()\n```\n\nAny plugin that adds commands acting on an element works the same way. `cypress-real-events` also provides `realPress`, `realSwipe`, and `realMouseDown`; other common examples are `drag` and `move` from [`@4tw/cypress-drag-drop`](https://www.npmjs.com/package/@4tw/cypress-drag-drop) and `tab` from [`cypress-plugin-tab`](https://www.npmjs.com/package/cypress-plugin-tab). Whichever plugin you use, the command counts only if it meets the [requirement above](#How-additional-interaction-commands-are-applied): it must log a snapshot that references the element it acts on.\n\n### Track your own custom commands\n\nList the custom commands your team defines with `Cypress.Commands.add`. Make sure each one meets the [requirements for a custom command](#Requirements-for-a-custom-command) so UI Coverage can credit the interaction to an element.\n\n#### Config\n\nApp Quality Config\n\n```\n{\n  \"uiCoverage\": {\n    \"additionalInteractionCommands\": [\"selectDate\", \"dragAndDrop\"]\n  }\n}\n```\n\n#### Usage in tests\n\n```\n// Custom commands that log a snapshot referencing their subject element\ncy.get('[data-testid=\"due-date\"]').selectDate('2026-01-01')\ncy.get('[data-testid=\"card\"]').dragAndDrop('[data-testid=\"done-column\"]')\n```\n",
      "section": "ui-coverage",
      "anchors": [
        "examples"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 264
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#track-cypress-real-events-commands",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Track cypress-real-events commands",
      "heading_level": 3,
      "content_markdown": "### Track `cypress-real-events` commands\n\n[`cypress-real-events`](https://github.com/dmtrKovalenko/cypress-real-events) fires native browser events through commands like `realClick`, `realType`, and `realHover`. Because these aren't built-in Cypress commands, UI Coverage doesn't count them until you list them.\n\n#### Config\n\nApp Quality Config\n\n```\n{\n  \"uiCoverage\": {\n    \"additionalInteractionCommands\": [\"realClick\", \"realType\", \"realHover\"]\n  }\n}\n```\n\n#### Usage in tests\n\n```\n// Now these commands mark their target elements as tested\ncy.get('[data-cy=\"button\"]').realClick()\ncy.get('[data-cy=\"input\"]').realType('Hello World')\ncy.get('[data-cy=\"tooltip-trigger\"]').realHover()\n```\n\nAny plugin that adds commands acting on an element works the same way. `cypress-real-events` also provides `realPress`, `realSwipe`, and `realMouseDown`; other common examples are `drag` and `move` from [`@4tw/cypress-drag-drop`](https://www.npmjs.com/package/@4tw/cypress-drag-drop) and `tab` from [`cypress-plugin-tab`](https://www.npmjs.com/package/cypress-plugin-tab). Whichever plugin you use, the command counts only if it meets the [requirement above](#How-additional-interaction-commands-are-applied): it must log a snapshot that references the element it acts on.\n",
      "section": "ui-coverage",
      "anchors": [
        "track-cypress-real-events-commands"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 168
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#usage-in-tests",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Usage in tests",
      "heading_level": 4,
      "content_markdown": "#### Usage in tests\n\n```\n// Now these commands mark their target elements as tested\ncy.get('[data-cy=\"button\"]').realClick()\ncy.get('[data-cy=\"input\"]').realType('Hello World')\ncy.get('[data-cy=\"tooltip-trigger\"]').realHover()\n```\n\nAny plugin that adds commands acting on an element works the same way. `cypress-real-events` also provides `realPress`, `realSwipe`, and `realMouseDown`; other common examples are `drag` and `move` from [`@4tw/cypress-drag-drop`](https://www.npmjs.com/package/@4tw/cypress-drag-drop) and `tab` from [`cypress-plugin-tab`](https://www.npmjs.com/package/cypress-plugin-tab). Whichever plugin you use, the command counts only if it meets the [requirement above](#How-additional-interaction-commands-are-applied): it must log a snapshot that references the element it acts on.\n",
      "section": "ui-coverage",
      "anchors": [
        "usage-in-tests"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 105
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#track-your-own-custom-commands",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "Track your own custom commands",
      "heading_level": 3,
      "content_markdown": "### Track your own custom commands\n\nList the custom commands your team defines with `Cypress.Commands.add`. Make sure each one meets the [requirements for a custom command](#Requirements-for-a-custom-command) so UI Coverage can credit the interaction to an element.\n\n#### Config\n\nApp Quality Config\n\n```\n{\n  \"uiCoverage\": {\n    \"additionalInteractionCommands\": [\"selectDate\", \"dragAndDrop\"]\n  }\n}\n```\n\n#### Usage in tests\n\n```\n// Custom commands that log a snapshot referencing their subject element\ncy.get('[data-testid=\"due-date\"]').selectDate('2026-01-01')\ncy.get('[data-testid=\"card\"]').dragAndDrop('[data-testid=\"done-column\"]')\n```\n",
      "section": "ui-coverage",
      "anchors": [
        "track-your-own-custom-commands"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 93
    },
    {
      "id": "ui-coverage/configuration/additionalinteractioncommands#see-also",
      "doc_id": "ui-coverage/configuration/additionalinteractioncommands",
      "heading": "See also",
      "heading_level": 2,
      "content_markdown": "## See also\n\n*   [Interactivity](/llm/markdown/ui-coverage/core-concepts/interactivity.md): how UI Coverage detects interactive elements and which commands count as interactions.\n*   [`allowedInteractionCommands`](/llm/markdown/ui-coverage/configuration/allowedinteractioncommands.md): limit which interaction commands count for specific elements.\n*   [Custom Commands](/llm/markdown/api/cypress-api/custom-commands.md): create custom commands and overwrite built-in ones.\n*   [Configuration overview](/llm/markdown/ui-coverage/configuration/overview.md): where to set configuration and regenerate reports.\n*   [UI Coverage FAQ](/llm/markdown/ui-coverage/faq.md): common questions and troubleshooting.\n",
      "section": "ui-coverage",
      "anchors": [
        "see-also"
      ],
      "path": "/llm/json/chunked/ui-coverage/configuration/additionalinteractioncommands.json",
      "token_estimate": 73
    }
  ]
}