Reputation: 2771
Im having a problem with a query, I'm trying to get two radio inputs, I don't have any problem with one of them, but with the other one React Testing Library thrown an error: It Found multiple elements with the role "radio" and name /to/i:
test('Render form with default items', () => {
const handleUpdateValue = jest.fn();
const handleNextStep = jest.fn();
render(
<Form
handleNextStep={handleNextStep}
updateValue={handleUpdateValue}
transferFundsValues={{}}
/>
);
const amountInput = screen.getByLabelText(/amount/i);
const fromRadio = screen.getByLabelText(/from/i);
const toRadio = screen.getByLabelText(/to/i);
const messageInput = screen.getByLabelText(/message/i);
const continueButton = screen.getByRole('button', { name: /continue/i });
const cancelButton = screen.getByRole('button', { name: /cancel/i });
// If no value has been entered to the inputs, the continue button must be
// disabled
expect(continueButton).toBeDisabled();
});
<label for="transferFunds_from" class="ant-form-item-required" title="From">From</label>
<input id="transferFunds_from" type="radio" class="ant-radio-button-input" value="">
<label for="transferFunds_to" class="ant-form-item-required" title="To">To</label>
<input id="transferFunds_to" type="radio" class="ant-radio-button-input" value="">
TestingLibraryElementError: Found multiple elements with the role "radio" and name `/to/i`
Here are the matching elements:
<input
class="ant-radio-button-input"
id="transferFunds_from"
type="radio"
value=""
/>
<input
class="ant-radio-button-input"
id="transferFunds_to"
type="radio"
value=""
/>
I don't know if I'm doing something wrong in the HTML structure or if it's a React Testing Library error.
Upvotes: 47
Views: 95055
Reputation: 18070
I'm using vitest
and didn't have this in initially:
afterEach(cleanup);
this can be added to the test, or it may be due to the config.
test: {
globals: true
}
This can be added to vite.config.ts
More information here: https://github.com/testing-library/vue-testing-library/issues/296
Upvotes: 0
Reputation: 1118
If you are having multiple tests under it and you have a single render function in the describe then you can try putting that render function inside a beforeEach
describe('This is a test section'), () => {
beforeEach(() => render(<Element {...testProps}/>))
it('smaller test',() => {
// actual test
})
})
and then try to run the test. This should solve it. If not then you can try to run the cleanup function and clear all the mocks after each test
Upvotes: 1
Reputation: 1
You can fix it using string instead of regex:
const toRadio = screen.getByLabelText("to");
There is some problem with two caracters names in Jest.
Upvotes: 0
Reputation: 697
Just a quick tip, if you have multiple matching elements, you can query like this:
HTML:
<a href="/my-element">My element</a>
<a href="/my-element">My element</a>
TEST:
test('renders my element', () => {
let link = screen.getAllByText('My element')[0] as HTMLAnchorElement;
expect(link.href).toContain('/my-element');
});
Upvotes: 44
Reputation: 1094
If you have multiple matching elements try this one
<Typography component={"span"}>
Some text
</Typography>
getAllByText
if more then 1 Matches it`ll return array
Types of Queries Please check the documentation Summary Table
it('It will display Some text', () => {
const subTitle = screen.getAllByText(/Some text/i);
expect(subTitle[0]).toBeInTheDocument();
})
Upvotes: 12
Reputation: 361
What was causing this for me was simply having another render() in the test file that was not inside an it().... so the component was being rendered twice.
rookie mistake :-)
Upvotes: 19
Reputation:
I wrote similar expects and for me works well. Maybe something is wrong with your current @testing-library/react
version. Try 10.4.9
The code that I used
import React from 'react'
import { render, screen } from '@testing-library/react'
function Form() {
return (
<div>
<label
htmlFor="transferFunds_from"
className="ant-form-item-required"
title="From"
>
From
</label>
<input
id="transferFunds_from"
type="radio"
className="ant-radio-button-input"
value=""
/>
<label
htmlFor="transferFunds_to"
className="ant-form-item-required"
title="To"
>
To
</label>
<input
id="transferFunds_to"
type="radio"
className="ant-radio-button-input"
value=""
/>
</div>
)
}
test('Render form with default items', () => {
render(<Form />)
const fromRadio = screen.getByLabelText(/from/i)
const toRadio = screen.getByLabelText(/to/i)
expect(fromRadio).toBeVisible()
expect(toRadio).toBeVisible()
})
Upvotes: 0