Description
DOM Testing Library
version: 6.3.0node
version: 8.12.0 (& whatever codesandbox is on)npm
(oryarn
) version: 6.4.1 (& whatever codesandbox is on)
Relevant code or config:
I have two main examples:
{/* Label associated with aria-labelledby */}
<label id="label1">Hi</label>
<span aria-labelledby="label1">Bye</span>
<input id="input1" aria-labelledby="label1" />
it('should find the input element', () => {
const result = render(<Comp />);
result.getByLabelText('Hi', { selector: 'input' });
// Throws because multiple elements were matched
});
{/* Label associated by nesting */}
<label>
<span>This one works</span>
<input />
</label>
it('should not work because the label is nested in a span', () => {
const result = render(<Comp />);
result.getByLabelText('This one works');
// Works fine
});
The documentation here suggests that the second one should not work and that the selector
option is necessary.
What you did:
I was trying to test an interaction with a dropdown I made using Downshift. My hope was that I could select the input element using getByLabelText
but that does not appear to be the case. In Downshift, multiple elements (e.g. the input element, the option list itself, the root div) get associated with the label via aria-labelledby
. When I tried to filter the options down using the selector
option, that lead me down this rabbit hole.
What happened:
It did not work the way I had hoped (filtering the results down based on the selector I provided). However, it also doesn't appear to work the way the documentation says it's supposed to work. The documentation I linked about provides this example:
<label> <span>Username</span> <input /> </label>
And says this:
It will NOT find the input node for label text broken up by elements. For this case, you can provide a selector in the options:
So it appears that the selector
option for the getByLabelText
is intended for filtering out elements that are inside labels. But as can be seen the codesandbox below, it is not actually necessary in the example given.
Reproduction:
https://codesandbox.io/embed/react-testing-library-demo-jipd1
Problem description:
It seems like the purpose and behavior of the selector
option is inconsistent. In the reproduction above, you can see that it works with the getByText
query the way I, personally, would expect it to. If two elements have the same text but only one matches the provided selector, that one gets returned. For getByLabelText
though, it does not work that way. If I have multiple elements that point to the same label via aria-labelledby
and I do a getByLabelText
, providing a selector
doesn't do anything and it throws an error unless I use getAllByLabelText
.
Suggested solution:
I think it would make sense for it to behave more like the way it does for getByText
. So it would:
- Find all labels with the matching text
- Find all elements that are labelled by those labels
- Filter down the results based on the provided selector.
If you agree, I would be happy to take a stab at this and put up a PR.