Search code examples
javascripthtmlreactjsunit-testingreact-testing-library

RTL: name option in getByRole


I have been practicing RTL in testing-playground.com and saw this behavior. below is the markup I'm playing with

<div role="option">
  <div role="item">
    Apple
  </div>
  <div>...</div>
</div>
<div role="option">
  ...
</div>

In the above markup screen.getByRole('option', {name: /apple/i}) return the outer div element wrapping the option Apple with attribute role='option' . However, screen.getByRole('item', {name: /apple/i}) doesn't return anything. I expected the inner div element with attribute role="item". Can anyone explain this behavior ?


Solution

  • Because there is no item role in the ARIA role list. You can't create a "custom role". Instead, you can query it by its text content:

    <div role="option">
      <div>
        Apple
      </div>
    </div>
    
    // find by element's text content, not its accessible name.
    screen.getByText(/apple/i);
    

    The possible accessible names of an HTML div element are:

    aria-labelledby
    aria-label
    title
    

    div's accessible name is not its text content. So if you want to find element by its role and accessible name, you can add title attribute to div element.

    <div
      role="item"
      title="apple"
    >
      Apple
    </div>
    
    // it works 
    screen.getByRole('item', { name: /apple/i })
    

    You can use the Chrome DevTools => inspect element => accessibility pane to check the accessible names of an HTML element.

    enter image description here

    See more Full accessibility tree in Chrome DevTools