{
  "doc": {
    "id": "api/commands/getbyrole",
    "title": "cy.getByRole()",
    "description": "Get DOM elements by their role and accessible name in Cypress.",
    "section": "api",
    "source_path": "/llm/markdown/api/commands/getbyrole.md",
    "version": "1a4a7da10574e31b418e0a9ab065a8ca30708ab3",
    "updated_at": "2026-10-14T20:29:25.908Z",
    "headings": [
      {
        "id": "api/commands/getbyrole#getbyrole",
        "text": "getByRole",
        "level": 1
      },
      {
        "id": "api/commands/getbyrole#syntax",
        "text": "Syntax",
        "level": 2
      },
      {
        "id": "api/commands/getbyrole#usage",
        "text": "Usage",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#arguments",
        "text": "Arguments",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#yields",
        "text": "Yields",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#examples",
        "text": "Examples",
        "level": 2
      },
      {
        "id": "api/commands/getbyrole#role",
        "text": "Role",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#find-an-element-by-the-role-the-browser-gives-it",
        "text": "Find an element by the role the browser gives it",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#find-a-widget-by-its-aria-role-attribute",
        "text": "Find a widget by its ARIA role attribute",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#get-every-element-with-a-role",
        "text": "Get every element with a role",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#check-every-element-with-a-role",
        "text": "Check every element with a role",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#name",
        "text": "Name",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#match-by-accessible-name",
        "text": "Match by accessible name",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#match-part-of-a-name-with-a-regular-expression",
        "text": "Match part of a name with a regular expression",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#match-a-name-with-a-function",
        "text": "Match a name with a function",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#hidden-elements",
        "text": "Hidden elements",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#include-elements-hidden-from-the-accessibility-tree",
        "text": "Include elements hidden from the accessibility tree",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#native-elements",
        "text": "Native elements",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#native-elements-by-default",
        "text": "Native elements by default",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#include-elements-with-a-role-attribute",
        "text": "Include elements with a role attribute",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#change-the-native-default-for-your-project",
        "text": "Change the native default for your project",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#scope",
        "text": "Scope",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#search-inside-another-element",
        "text": "Search inside another element",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#act-inside-a-dialog-with-within",
        "text": "Act inside a dialog with .within()",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#narrow-the-results-by-state-with-filter",
        "text": "Narrow the results by state with .filter()",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#waiting-for-elements",
        "text": "Waiting for elements",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#wait-for-an-element-to-appear",
        "text": "Wait for an element to appear",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#assert-an-element-doesnt-exist",
        "text": "Assert an element doesn't exist",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#options",
        "text": "Options",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#find-elements-inside-shadow-dom-with-includeshadowdom",
        "text": "Find elements inside shadow DOM with includeShadowDom",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#typescript",
        "text": "TypeScript",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#type-the-yielded-element",
        "text": "Type the yielded element",
        "level": 4
      },
      {
        "id": "api/commands/getbyrole#notes",
        "text": "Notes",
        "level": 2
      },
      {
        "id": "api/commands/getbyrole#what-a-cy-getbyrole-error-looks-like",
        "text": "What a cy.getByRole() error looks like",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#how-cy-getbyrole-decides-an-elements-role",
        "text": "How cy.getByRole() decides an element's role",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#rename-an-existing-getbyrole-custom-command",
        "text": "Rename an existing getByRole custom command",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#how-to-migrate-from-testing-library-findbyrole-to-cy-getbyrole",
        "text": "How to migrate from Testing Library findByRole() to cy.getByRole()",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#rules",
        "text": "Rules",
        "level": 2
      },
      {
        "id": "api/commands/getbyrole#requirements",
        "text": "Requirements",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#assertions",
        "text": "Assertions",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#timeouts",
        "text": "Timeouts",
        "level": 3
      },
      {
        "id": "api/commands/getbyrole#command-log",
        "text": "Command Log",
        "level": 2
      },
      {
        "id": "api/commands/getbyrole#history",
        "text": "History",
        "level": 2
      },
      {
        "id": "api/commands/getbyrole#see-also",
        "text": "See also",
        "level": 2
      }
    ]
  },
  "content": {
    "type": "root",
    "children": [
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "getByRole"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Get every DOM element with the given role, optionally narrowed to the elements whose accessible name matches. The role is what a screen reader announces an element as, such as a button or a link, and the accessible name is the text it announces for it. A test written with `cy.getByRole()` finds elements the way assistive technology does, and fails if the role or text is changed."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Browsers expose accessible roles for many elements by default, such as a `<button>` or a `<nav>`. A `role` attribute can also set one, which is the only way to give an element a widget role such as `tab`. For the full list, see the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.w3.org/TR/html-aria/#docconformance",
            "children": [
              {
                "type": "text",
                "value": "implicit roles of HTML elements"
              }
            ]
          },
          {
            "type": "text",
            "value": " and the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.w3.org/TR/wai-aria-1.2/#role_definitions",
            "children": [
              {
                "type": "text",
                "value": "roles that a `role` attribute can set"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "By default, `cy.getByRole()` skips two kinds of elements:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Elements hidden from the accessibility tree"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Elements that duplicate a native browser role with an ARIA `role` attribute, such as a `<div role=\"button\">`"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The command has options to find both, but the defaults favor the elements most likely to be accessible to users. This follows the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://www.w3.org/TR/using-aria/#rule1",
            "children": [
              {
                "type": "text",
                "value": "first rule of ARIA"
              }
            ]
          },
          {
            "type": "text",
            "value": ", which advises using native browser elements over a custom re-implementation. To change the defaults for your project, "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Change-the-native-default-for-your-project",
            "children": [
              {
                "type": "text",
                "value": "overwrite the query"
              }
            ]
          },
          {
            "type": "text",
            "value": " or add a custom query of your own."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Syntax"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": ".getByRole(role)\n.getByRole(role, options)\n\n// ---or---\n\ncy.getByRole(role)\ncy.getByRole(role, options)"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Usage"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Correct Usage"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('button', { name: 'Save' }) // Yield the button named \"Save\"\ncy.get('nav').getByRole('link') // Yield every link inside <nav>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Incorrect Usage"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole(/button/) // Errors, the role must be a string\ncy.title().getByRole('heading') // Errors, 'title' does not yield DOM element\ncy.getByRole('switch checkbox') // Errors, query one role at a time\ncy.getByRole('tab', { native: true }) // Errors, HTML has no native tab element\ncy.getByRole('heading', { level: 2 }) // Errors, narrow by level with .filter()"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Arguments"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "role (String)"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The role to find, such as `'button'`, `'heading'`, `'navigation'`, or `'tab'`. An element has a role when:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Its tag implies one, such as `<button>` for `button`, `<nav>` for `navigation`, or `<input type=\"checkbox\">` for `checkbox`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Its `role` attribute sets one, such as `<div role=\"tab\">`. The attribute replaces the implied role. When it lists several roles as fallbacks, the first valid one counts, as in browsers: `role=\"switch checkbox\"` is a `switch`, and `role=\"foo button\"` is a `button`. With no valid role in the attribute, the element keeps its implied role."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "options (Object)"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Pass in an options object to change the default behavior of `cy.getByRole()`."
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Option"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Default"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Description"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`name`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`undefined`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Match only elements whose "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "#Match-by-accessible-name",
                    "children": [
                      {
                        "type": "text",
                        "value": "accessible name"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " matches. Accepts a string, number, regular expression, or function."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`hidden`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`false`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Include elements "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "#Include-elements-hidden-from-the-accessibility-tree",
                    "children": [
                      {
                        "type": "text",
                        "value": "hidden from the accessibility tree"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ", such as those with `aria-hidden=\"true\"`."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`native`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`true` for roles that HTML has an element for, otherwise `false`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Match only elements whose "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "#Native-elements-by-default",
                    "children": [
                      {
                        "type": "text",
                        "value": "HTML tag gives them the role"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ". Pass `false` to also match elements that have the role only through a `role` attribute."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`log`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`true`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Displays the command in the "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/core-concepts/open-mode.md#Command-Log",
                    "children": [
                      {
                        "type": "text",
                        "value": "Command log"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`timeout`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/configuration.md#Timeouts",
                    "children": [
                      {
                        "type": "text",
                        "value": "`defaultCommandTimeout`"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Time, in milliseconds, to wait for `cy.getByRole()` to resolve before "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "#Timeouts",
                    "children": [
                      {
                        "type": "text",
                        "value": "timing out"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ". Must be a number."
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`includeShadowDom`"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/configuration.md#Global",
                    "children": [
                      {
                        "type": "text",
                        "value": "`includeShadowDom` config option value"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Whether to traverse shadow DOM boundaries and include elements within the shadow DOM in the yielded results."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cy.getByRole()` throws an error for any other option. To narrow the results by an ARIA state such as `checked`, `expanded`, or `level`, chain "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Narrow-the-results-by-state-with-filter",
            "children": [
              {
                "type": "text",
                "value": "`.filter()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Yields"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.getByRole()` yields every matching element, in document order."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.getByRole()` is a query, and it is safe to chain further commands."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Examples"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Role"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Find an element by the role the browser gives it"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<main>\n  <h1>Account settings</h1>\n  <button>Save changes</button>\n</main>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('main').should('match', 'main')\ncy.getByRole('heading').should('have.text', 'Account settings')\ncy.getByRole('button').click()"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Find a widget by its ARIA `role` attribute"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "HTML has no element for widget roles such as `tab`, `menuitem`, or `switch`, so a page gives an element one with a `role` attribute. Roles applied this way follow the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA",
            "children": [
              {
                "type": "text",
                "value": "Accessible Rich Internet Applications (ARIA) spec"
              }
            ]
          },
          {
            "type": "text",
            "value": ", so assistive technology can represent custom UI that follows a standard pattern but isn't part of the HTML spec."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Native matching doesn't apply to these roles, so `cy.getByRole()` finds the element by its `role` attribute."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<div role=\"tablist\">\n  <button role=\"tab\" aria-selected=\"true\">Profile</button>\n  <button role=\"tab\" aria-selected=\"false\">Billing</button>\n</div>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('tab', { name: 'Billing' }).click()"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Get every element with a role"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cy.getByRole()` yields every match, like "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/get.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.get()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ", so assert on the length or pick one with "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/first.md",
            "children": [
              {
                "type": "text",
                "value": "`.first()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " or "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/eq.md",
            "children": [
              {
                "type": "text",
                "value": "`.eq()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<ul>\n  <li><a href=\"/profile\">Profile</a></li>\n  <li><a href=\"/billing\">Billing</a></li>\n  <li><a>Coming soon</a></li>\n</ul>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// An <a> without an href has no link role, so only two match\ncy.getByRole('link').should('have.length', 2)\ncy.getByRole('link').eq(1).should('have.attr', 'href', '/billing')"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Check every element with a role"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Chain "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/each.md",
            "children": [
              {
                "type": "text",
                "value": "`.each()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to run the same check against every match, or pass a callback to "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to assert on the whole set at once. A `.should()` callback retries until it passes, so it also waits for a list that is still loading."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<nav aria-label=\"Account\">\n  <a href=\"/profile\">Profile</a>\n  <a href=\"/billing\">Billing</a>\n  <a href=\"/security\">Security</a>\n</nav>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Runs once for each of the three links\ncy.getByRole('link').each(($link) => {\n  cy.wrap($link).should('have.attr', 'href').and('match', /^\\//)\n})\n\n// Retries until the links have these names, in this order\ncy.getByRole('link').should(($links) => {\n  const names = $links.toArray().map((link) => link.textContent)\n\n  expect(names).to.deep.equal(['Profile', 'Billing', 'Security'])\n})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Name"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Match by accessible name"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The accessible name comes from the element's content, a `<label>`, `aria-label`, `aria-labelledby`, an image's `alt` text, or a `title` attribute. A string must match the whole name, and it is case-sensitive. Whitespace in the name is collapsed to a single space and trimmed before it's compared."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<button>Save changes</button>\n<button aria-label=\"Close dialog\">×</button>\n<label>Email <input type=\"email\" /></label>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('button', { name: 'Save changes' }).click()\ncy.getByRole('button', { name: 'Close dialog' }).click()\ncy.getByRole('textbox', { name: 'Email' }).type('jane@example.com')\n\n// Neither matches: a string matches the whole name, case-sensitively\ncy.getByRole('button', { name: 'Save' }).should('not.exist')\ncy.getByRole('button', { name: 'save changes' }).should('not.exist')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Content hidden with `aria-hidden=\"true\"` is left out of the name. So is CSS `::before` and `::after` content, so that an icon-font glyph, which lives in a pseudo-element, doesn't become part of a button's name. Browsers include this content in the accessible name, so an element named only by `::before` or `::after` content has a name in the browser but not in `cy.getByRole()`. Match it with an `aria-label` or by another role and name instead."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<button>Send<span aria-hidden=\"true\"> ✉️</span></button>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Yields and clicks the <button>, whose accessible name is \"Send\" without the ✉️\ncy.getByRole('button', { name: 'Send' }).click()"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Match part of a name with a regular expression"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Pass a regular expression to match part of the name, or to ignore case."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<button>Delete account</button> <button>Delete draft</button>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Yields both buttons, since each name starts with \"Delete\"\ncy.getByRole('button', { name: /^delete/i }).should('have.length', 2)\n\n// Yields and clicks only the \"Delete draft\" button\ncy.getByRole('button', { name: /draft$/ }).click()"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Match a name with a function"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A function receives the accessible name and the element, and returns `true` for a match."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<button>Pay $20.00</button> <button>Pay $120.00</button>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('button', {\n  name: (name) => Number(name.replace(/[^\\d.]/g, '')) > 100,\n}).should('have.text', 'Pay $120.00')"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Hidden elements"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Include elements hidden from the accessibility tree"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "By default, `cy.getByRole()` skips an element that assistive technology can't reach:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The element or an ancestor has the `hidden` attribute, `aria-hidden=\"true\"`, or `display: none`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The element's computed `visibility` is `hidden`. It inherits this from a `visibility: hidden` ancestor unless it sets `visibility: visible` itself."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Pass `hidden: true` to include them, such as to find a closed menu."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<nav aria-label=\"Account\" hidden>\n  <a href=\"/settings\">Settings</a>\n</nav>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('link', { name: 'Settings' }).should('not.exist')\ncy.getByRole('link', { name: 'Settings', hidden: true }).should('exist')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "An element that is only visually hidden, such as one clipped to a single pixel or set to `opacity: 0`, is still in the accessibility tree, so `cy.getByRole()` finds it without `hidden: true`. The `hidden` option is about what a screen reader can reach, not what Cypress considers "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/interacting-with-elements.md#Visibility",
            "children": [
              {
                "type": "text",
                "value": "visible"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Native elements"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Native elements by default"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A `<div role=\"button\">` has the `button` role, but it doesn't get a button's keyboard behavior unless the page adds it. For a role that HTML has an element for, such as `button`, `link`, `heading`, `dialog`, or `checkbox`, `cy.getByRole()` matches only elements whose tag gives them the role. The test fails if a native control is replaced with an imitation."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<button>Save</button>\n<div role=\"button\" tabindex=\"0\">Cancel</div>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Yields and clicks the native <button>\ncy.getByRole('button', { name: 'Save' }).click()\n\n// The <div> has the role only through its role attribute, so it's skipped\ncy.getByRole('button', { name: 'Cancel' }).should('not.exist')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For widget roles that HTML has no element for, such as `tab`, `menuitem`, or `switch`, a `role` attribute is the only way to give an element the role, so `cy.getByRole()` always matches the `role` attribute. Passing `native: true` with one of these roles throws an error."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Include elements with a `role` attribute"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Pass `native: false` to also match elements that have the role only through a `role` attribute, such as a `<div role=\"dialog\">` rendered by a component library."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// Yields the <div role=\"button\">\ncy.getByRole('button', { name: 'Cancel', native: false }).click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Some widely used patterns need `native: false` even though they follow the ARIA authoring practices, because HTML has a different element for the role:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "An autocomplete `<input role=\"combobox\">`. The native combobox is a `<select>` or an `<input>` with a `list` attribute."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "An icon `<svg role=\"img\">`. The native image is an `<img>`."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When an element was skipped only because it has the role through a `role` attribute, the error says so and suggests passing `{ native: false }`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Change the `native` default for your project"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your project relies on a component library that re-implements browser roles with `role` attributes, such as a `<div role=\"button\">`, you can make `native: false` the default. Overwrite the query with "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/cypress-api/custom-queries.md#Overwriting-Existing-Queries",
            "children": [
              {
                "type": "text",
                "value": "`Cypress.Commands.overwriteQuery()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " in your support file. A test can still pass `native: true` to require a native element."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "cypress/support/commands.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "Cypress.Commands.overwriteQuery(\n  'getByRole',\n  function (originalFn, role, options = {}) {\n    return originalFn.call(this, role, { native: false, ...options })\n  }\n)"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Scope"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Search inside another element"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Chained off a command that yields DOM elements, `cy.getByRole()` searches the descendants of each of them. It never matches the subject element(s) it is chained off."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<header>\n  <nav aria-label=\"Main\">\n    <a href=\"/\">Home</a>\n  </nav>\n</header>\n<footer>\n  <a href=\"/privacy\">Privacy</a>\n</footer>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('navigation', { name: 'Main' })\n  .getByRole('link')\n  .should('have.length', 1)\n  .and('have.text', 'Home')"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Act inside a dialog with `.within()`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Inside a "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/within.md",
            "children": [
              {
                "type": "text",
                "value": "`.within()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " callback, `cy.getByRole()` searches only the `.within()` subject."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<button>Delete</button>\n<dialog open aria-label=\"Delete user\">\n  <button>Cancel</button>\n  <button>Delete</button>\n</dialog>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('dialog', { name: 'Delete user' }).within(() => {\n  cy.getByRole('button', { name: 'Delete' }).click()\n})"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Narrow the results by state with `.filter()`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cy.getByRole()` matches on role and name only. To narrow the results by a state or property, chain "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/filter.md",
            "children": [
              {
                "type": "text",
                "value": "`.filter()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ", or chain "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/not.md",
            "children": [
              {
                "type": "text",
                "value": "`.not()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to leave matches out."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// The tab that is currently selected\ncy.getByRole('tab').filter('[aria-selected=\"true\"]')\n\n// Level 2 headings\ncy.getByRole('heading').filter('[aria-level=\"2\"], h2:not([aria-level])')\n\n// A checked native checkbox\ncy.getByRole('checkbox').filter(':checked')\n\n// A checked checkbox that gets its role from a role attribute\ncy.getByRole('checkbox', { native: false }).filter('[aria-checked=\"true\"]')\n\n// The menu button whose menu is open\ncy.getByRole('button').filter('[aria-expanded=\"true\"]')\n\n// A toggle button that is switched on\ncy.getByRole('button').filter('[aria-pressed=\"true\"]')\n\n// The link to the page the reader is on\ncy.getByRole('link').filter('[aria-current=\"page\"]')\n\n// Every button except disabled ones\ncy.getByRole('button').not(':disabled, [aria-disabled=\"true\"]')"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Waiting for elements"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Wait for an element to appear"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cy.getByRole()` retries until a matching element exists and every chained assertion passes, so it waits for an alert that renders after a save."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('button', { name: 'Save' }).click()\ncy.getByRole('alert').should('have.text', 'Changes saved')"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Assert an element doesn't exist"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cy.getByRole()` retries a negative assertion too, until the element is gone."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('dialog').should('not.exist')"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Options"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Find elements inside shadow DOM with `includeShadowDom`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "By default, `cy.getByRole()` doesn't search inside shadow roots. Pass `includeShadowDom: true` to search them, including nested shadow roots, or set the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Global",
            "children": [
              {
                "type": "text",
                "value": "`includeShadowDom` configuration option"
              }
            ]
          },
          {
            "type": "text",
            "value": " to search them in every query."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('button', { name: 'Checkout', includeShadowDom: true }).click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To search one shadow root only, chain `cy.getByRole()` off "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/shadow.md",
            "children": [
              {
                "type": "text",
                "value": "`.shadow()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ":"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.get('checkout-panel').shadow().getByRole('button', { name: 'Checkout' })"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "TypeScript"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Type the yielded element"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The `role` argument autocompletes role names, and its type allows any other string. At runtime, a role that contains a space still "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Usage",
            "children": [
              {
                "type": "text",
                "value": "throws an error"
              }
            ]
          },
          {
            "type": "text",
            "value": ". Pass a type argument to type the yielded element."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole<HTMLInputElement>('textbox', { name: 'Email' }).then(($input) => {\n  // $input is typed as JQuery<HTMLInputElement>\n  expect($input[0].value).to.eq('')\n})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Notes"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "What a `cy.getByRole()` error looks like"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When no element matches before the timeout, the error says what it looked for and lists the roles and accessible names it did find. Here, the name was misspelled:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "Timed out retrying after 4000ms: Expected to find an accessible native element with the role \"button\" and name \"Svae\", but never did.\n\nHere are the accessible roles that were found, with the accessible name of each element:\n\n  - main: (no name)\n  - heading: \"Account settings\"\n  - button: \"Save\", \"Cancel\""
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "How `cy.getByRole()` decides an element's role"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cy.getByRole()` maps elements to roles with "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/A11yance/aria-query",
            "children": [
              {
                "type": "text",
                "value": "aria-query"
              }
            ]
          },
          {
            "type": "text",
            "value": ". Some roles depend on attributes: an `<a>` needs an `href` to be a `link`, a `<section>` needs an `aria-label` or `aria-labelledby` to be a `region`, and an `<input>` with a missing or unknown `type` is a `textbox`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Some roles depend on the surrounding table: a `<td>` is a `cell` in a table, a `gridcell` in a `grid` or `treegrid`, and has no role in a table with `role=\"presentation\"`. Otherwise, the mapping doesn't consider where an element sits in the page, so every `<header>` is a `banner` and every `<footer>` a `contentinfo`, even inside an `<article>`, where a browser gives them no landmark role."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Rename an existing `getByRole` custom command"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your project already defines its own `getByRole` with `Cypress.Commands.add()` or `Cypress.Commands.addQuery()`, that call now throws an error, because `getByRole` is a built-in Cypress query. Rename your command, or remove it and use the built-in `cy.getByRole()`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "How to migrate from Testing Library `findByRole()` to `cy.getByRole()`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cy.getByRole()` does what the `findByRole()` and `findAllByRole()` queries from "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/testing-library/cypress-testing-library",
            "children": [
              {
                "type": "text",
                "value": "Cypress Testing Library"
              }
            ]
          },
          {
            "type": "text",
            "value": " do for role queries, without a plugin. Most calls translate by renaming the query, and the state options become a chained "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Narrow-the-results-by-state-with-filter",
            "children": [
              {
                "type": "text",
                "value": "`.filter()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before: Cypress Testing Library"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.findByRole('button', { name: 'Save' }).click()\ncy.findByRole('button', { name: /save/i }).click()\ncy.findAllByRole('listitem').should('have.length', 3)\ncy.findByRole('tab', { selected: true }).should('have.text', 'Billing')\ncy.findByRole('checkbox', { checked: true }).should(\n  'have.attr',\n  'name',\n  'terms'\n)"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After: `cy.getByRole()`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "spec.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('button', { name: 'Save' }).click()\ncy.getByRole('button', { name: /save/i }).click()\ncy.getByRole('listitem').should('have.length', 3)\ncy.getByRole('tab')\n  .filter('[aria-selected=\"true\"]')\n  .should('have.text', 'Billing')\ncy.getByRole('checkbox').filter(':checked').should('have.attr', 'name', 'terms')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Keep these differences in mind as you migrate:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Native elements only, by default. For a role that HTML has an element for, `cy.getByRole()` skips elements that have the role only through a `role` attribute, so a test that found a `<div role=\"button\">` with `findByRole()` fails after the migration. Decide for each one whether the application should use the native element, or whether the test should pass `native: false`. To keep your current behavior while you migrate, "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "#Change-the-native-default-for-your-project",
                    "children": [
                      {
                        "type": "text",
                        "value": "overwrite the query"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " to default to `native: false`, or wrap it in a custom query of your own."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Every match, not one. `cy.getByRole()` yields every match, like `findAllByRole()`, instead of failing when more than one element matches. Narrow the `name`, or chain "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/first.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.first()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ", to act on one."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "State options. The `checked`, `selected`, `pressed`, `expanded`, `current`, `busy`, `level`, and `value` options become a chained `.filter()`. The error for each of these options names the filter to use."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When no other Testing Library queries remain in your tests, remove `@testing-library/cypress` from your dependencies, its import from your support file, and its entry in the `types` of your `tsconfig.json`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Rules"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Requirements"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.getByRole()` can be chained off of `cy` or off a command that yields DOM element(s). Chained off "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/window.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.window()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " or "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/document.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.document()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ", it searches the whole page."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Assertions"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.getByRole()` automatically "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/core-concepts/retry-ability.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "retries"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " until the element(s) "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/core-concepts/introduction-to-cypress.md#Implicit-Assertions",
                    "children": [
                      {
                        "type": "text",
                        "value": "exist in the DOM"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.getByRole()` automatically "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/core-concepts/retry-ability.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "retries"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " until all chained assertions have passed."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Timeouts"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.getByRole()` can time out waiting for the element(s) to "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/core-concepts/introduction-to-cypress.md#Implicit-Assertions",
                    "children": [
                      {
                        "type": "text",
                        "value": "exist in the DOM"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.getByRole()` can time out waiting for assertions you've added to pass."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Command Log"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Find a button by its role and name"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.getByRole('button', { name: 'Save changes' }).click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The Command Log shows a `getByRole` row with the role and options, followed by the `click`. When clicking on the `getByRole` command within the command log, the console outputs the role, the options, the element the query was applied to, the yielded element(s), and the number of elements found."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "History"
          }
        ]
      },
      {
        "type": "table",
        "align": [
          null,
          null
        ],
        "children": [
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Version"
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "Changes"
                  }
                ]
              }
            ]
          },
          {
            "type": "tableRow",
            "children": [
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/changelog.md#16-2-0",
                    "children": [
                      {
                        "type": "text",
                        "value": "16.2.0"
                      }
                    ]
                  }
                ]
              },
              {
                "type": "tableCell",
                "children": [
                  {
                    "type": "text",
                    "value": "`cy.getByRole()` command added"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "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/api/commands/contains.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.contains()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/filter.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.filter()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/get.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.get()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/within.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.within()`"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/guides/accessibility-testing.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Accessibility testing"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "token_estimate": 3803
}