dom-testing-library icon indicating copy to clipboard operation
dom-testing-library copied to clipboard

Ability to search for content of role="status"

Open petermarcoen opened this issue 4 years ago • 5 comments

Describe the feature you'd like:

The following component cannot be found by role+name:

<div role="status">loading...</div>

expect(await screen.findByRole('status', { name: /loading/ })); // Fails

If I use button as role this does work:

<div role="button">loading...</div>

expect(await screen.findByRole('button', { name: /loading/ })); // Succeeds

Suggested implementation:

/

Describe alternatives you've considered:

Searching for just the role does work but I could have multiple status messages and would like to specify the content:

expect(await screen.findByRole('status')); // Succeeds

Teachability, Documentation, Adoption, Migration Strategy:

The W3 documentation clearly allows this use case for the status role:

https://www.w3.org/WAI/WCAG21/Techniques/aria/ARIA22

image

petermarcoen avatar Feb 04 '21 12:02 petermarcoen

Hi @petermarcoen, thanks for taking the time and effort to open this one :) I'm not sure I'm 100% right but I believe that the issue here is that [role="status"] doesn't support name from content and [role="button"] does which is what you're trying to get here.. Maybe @eps1lon can correct me if I'm wrong :)

MatanBobi avatar Feb 09 '21 08:02 MatanBobi

If you're asking to search for status by their accessible name then the spec has a pretty clear answer. But it seems to me you want to search by what a screen reader announces if a status gets updated. I'm not familiar with how these work so this would need some research. I suspect it's not viable to do this in react-testing-library but rather some e2e (manual) testing with actual screen readers.

eps1lon avatar Feb 09 '21 08:02 eps1lon

Hi @MatanBobi and @eps1lon , thank you for taking the time to look into this issue.

I am not that familiar with the W3C aria definitions but this might be exactly why this doesn't work. It seems weird to me though that for example the "comment"-element does support name-from-content but status doesn't.

I assume the solution is then to use aria-label on my status element?

petermarcoen avatar Feb 09 '21 09:02 petermarcoen

If you want to get the element by it's text, why not just use getByText? You can then verify that it has the correct role. I'm just not sure that adding an aria-label here is the best approach, though I'm still in the learning process of accessibility best practices :)

MatanBobi avatar Feb 09 '21 12:02 MatanBobi

@petermarcoen even if getByRole('status', { name: 'Status message' }) query would work you might not want to use it. Querying role="status" containers directly with their content easily leads to false positives. As the spec declares, assistive technologies only announce updates of the status container.

In my opinnion correct way to assert these is to first query the role="status" container, validate that it is empty and then wait for the content to be updated. Check the Prevent possible false positives section from https://github.com/testing-library/dom-testing-library/issues/847#issue-761024182.

This doesn't really help your case where you have multiple role="status" containers but it's good to keep this in mind.

AriPerkkio avatar Feb 11 '21 05:02 AriPerkkio