how to filter the getByLabelText
query, if It is throwing an error of the type: TestingLibraryElementError: Found multiple elements with the text of: /to/i
, I have the following HTML structure, which has some nested labels:
Current HTML structure
<div class="ant-row ant-form-item ant-radio-group-cards" style="row-gap: 0px;">
<div class="ant-col ant-form-item-label">
<!-- <label> with "To" text -->
<label for="transferFunds_to" class="ant-form-item-required" title="To">To</label>
</div>
<div class="ant-col ant-form-item-control">
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content">
<!-- Other <label> with "To" text here -->
<label class="ant-radio-button-wrapper">
<span class="ant-radio-button"><input id="transferFunds_to" type="radio" class="ant-radio-button-input" value="" /><span class="ant-radio-button-inner"></span></span>
<span>
<li class="ant-list-item">
<div class="ant-list-item-meta">
<div class="ant-list-item-meta-avatar">
<svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" style="font-size: 48px;"></svg>
</div>
<div class="ant-list-item-meta-content">
<!-- "To" word here inside a label -->
<h4 class="ant-list-item-meta-title">Account to</h4>
<div class="ant-list-item-meta-description">Choose the account to transfer to</div>
</div>
</div>
<span role="img" class="anticon icon-size-middle" style="align-self: center;">
<svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false" class=""></svg>
</span>
</li>
</span>
</label>
</div>
</div>
</div>
</div>
RTL Test
import { screen } from '@testing-library/react';
// query applied
screen.getByLabelText(/to/i);
how to filter the getByLabelText
query, if It is throwing an error of the type: TestingLibraryElementError: Found multiple elements with the text of: /to/i
, I have the following HTML structure, which has some nested labels:
Current HTML structure
<div class="ant-row ant-form-item ant-radio-group-cards" style="row-gap: 0px;">
<div class="ant-col ant-form-item-label">
<!-- <label> with "To" text -->
<label for="transferFunds_to" class="ant-form-item-required" title="To">To</label>
</div>
<div class="ant-col ant-form-item-control">
<div class="ant-form-item-control-input">
<div class="ant-form-item-control-input-content">
<!-- Other <label> with "To" text here -->
<label class="ant-radio-button-wrapper">
<span class="ant-radio-button"><input id="transferFunds_to" type="radio" class="ant-radio-button-input" value="" /><span class="ant-radio-button-inner"></span></span>
<span>
<li class="ant-list-item">
<div class="ant-list-item-meta">
<div class="ant-list-item-meta-avatar">
<svg width="1em" height="1em" viewBox="0 0 16 16" fill="none" style="font-size: 48px;"></svg>
</div>
<div class="ant-list-item-meta-content">
<!-- "To" word here inside a label -->
<h4 class="ant-list-item-meta-title">Account to</h4>
<div class="ant-list-item-meta-description">Choose the account to transfer to</div>
</div>
</div>
<span role="img" class="anticon icon-size-middle" style="align-self: center;">
<svg width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true" focusable="false" class=""></svg>
</span>
</li>
</span>
</label>
</div>
</div>
</div>
</div>
RTL Test
import { screen } from '@testing-library/react';
// query applied
screen.getByLabelText(/to/i);
Share
Improve this question
edited Sep 8, 2021 at 5:38
Drew Reese
203k17 gold badges237 silver badges268 bronze badges
asked Sep 8, 2021 at 4:22
Cristian FlórezCristian Flórez
2,7818 gold badges35 silver badges61 bronze badges
9
- Does any of these help ? github./testing-library/dom-testing-library/issues/482 - stackoverflow./questions/68943625/… – Mauricio Gracia Gutierrez Commented Sep 8, 2021 at 4:28
- 1 Thanks for the links but I had already seen both of them and I tried to apply those solutions and it does not work as expected, the test keeps crashing with the same error. – Cristian Flórez Commented Sep 8, 2021 at 4:31
- i'm unable to reproduce the error, could you have a look on codesandbox.io/s/sad-easley-doom6, based on your HTML is it returning the input#transferFunds_to, can you fork it and make a reproducible error? – oieduardorabelo Commented Sep 8, 2021 at 4:36
- 1 @oieduardorabelo I create a new one with all the html structure, there u can reproduce the error... I going to update my answer with the plet HTML. codesandbox.io/s/trhh8?file=/src/App.js:71-14670 – Cristian Flórez Commented Sep 8, 2021 at 4:59
- App.test.js is empty on that link, could you double check you shared it correctly? thank you – oieduardorabelo Commented Sep 8, 2021 at 5:03
2 Answers
Reset to default 11Issue
All getBy*
queries throw an error when there are zero matches or greater than one match.
Queries
The error says you should use one of the getAllBy*
queries which return an array of matches and only throws an error if no matches are found.
Solutions
Since you want to target a specific input
element with id="transferFunds_to"
attribute you've at least a couple options:
Add a
testid
to the input and query by that.<input id="transferFunds_to" data-testid="transferFunds_to" // <-- add a data test id type="radio" class="ant-radio-button-input" value="" />
test
test("case-sensitive To", () => { render(<App />); screen.getByTestId("transferFunds_to"); });
Use a manual query and target by the specified
id
attribute.test("case-sensitive To", () => { const { container } = render(<App />); container.querySelector("#transferFunds_to") });
thanks for the codesandbox Cristian: https://codesandbox.io/s/trhh8
as you pointed in your question, there is conflicting text matching on both labels
texts "Account to", "Choose the account to transfer to" inside the second label
if you are happy with that, and you don't want to change the html structure, the only available option is to use a more strict regex in your screen.getByLabelText
i forked your example and updated the regex to screen.getByLabelText(/^to$/i)
, and it worked as expected, since all other "to" are followed by or have a space after it, e.g. " to"
or "to "
, the label "To"
doesn't have pre or post space, which fulfills the regex
the final test case is:
import { screen, render } from "@testing-library/react";
import App from "./App";
test("case-sensitive To", () => {
render(<App />);
expect(screen.getByLabelText(/^to$/i).id).toBe("transferFunds_to");
});
have a look on https://codesandbox.io/s/react-testing-library-get-by-label-regex-g8tlx
of course, you can also change the API and use a .querySelector
or more generic JS apis