Skip to content

Inconsistent behavior of selector option #372

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
airjp73 opened this issue Oct 6, 2019 · 4 comments · Fixed by #373
Closed

Inconsistent behavior of selector option #372

airjp73 opened this issue Oct 6, 2019 · 4 comments · Fixed by #373
Labels

Comments

@airjp73
Copy link
Contributor

airjp73 commented Oct 6, 2019

  • DOM Testing Library version: 6.3.0
  • node version: 8.12.0 (& whatever codesandbox is on)
  • npm (or yarn) 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:

  1. Find all labels with the matching text
  2. Find all elements that are labelled by those labels
  3. 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.

@kentcdodds
Copy link
Member

Yup, I've encountered this myself and it was annoying. Honestly, I think this is a bug and the intended behavior has always been what you're suggesting. Could you open a pull request with a fix please?

@kentcdodds
Copy link
Member

🎉 This issue has been resolved in version 6.16.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

kentcdodds pushed a commit that referenced this issue Mar 4, 2020
Closes #372

BREAKING CHANGE: If you used the `selector` option in `ByLabelText` queries, then you will probably need to update that code to be able to find the label you're looking for.
kentcdodds pushed a commit that referenced this issue Mar 4, 2020
Closes #372

BREAKING CHANGE: If you used the `selector` option in `ByLabelText` queries, then you will probably need to update that code to be able to find the label you're looking for.
@kentcdodds
Copy link
Member

🎉 This issue has been resolved in version 7.0.0-beta.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

kentcdodds pushed a commit that referenced this issue Mar 4, 2020
Closes #372

BREAKING CHANGE: If you used the `selector` option in `ByLabelText` queries, then you will probably need to update that code to be able to find the label you're looking for.
kentcdodds pushed a commit that referenced this issue Mar 12, 2020
Closes #372

BREAKING CHANGE: If you used the `selector` option in `ByLabelText` queries, then you will probably need to update that code to be able to find the label you're looking for.
@kentcdodds
Copy link
Member

🎉 This issue has been resolved in version 7.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants