50

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:

queries

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();
});

Html structure

<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="">

Error thrown by RTL

 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.

3
  • Are these the full tests? I think we may need a bit more context. Usually you get that error if you try getByRole and there's multiple elements, yet I don't see that called anywhere Commented Aug 26, 2021 at 18:27
  • @JonathanS. I update my question with the complete test... Commented Aug 26, 2021 at 18:32
  • Did you ever find a solution to this? Commented Dec 10, 2021 at 14:17

7 Answers 7

50

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');
});
Sign up to request clarification or add additional context in comments.

3 Comments

Is this the best practice or would it be better to use data-testid on original doc and use it on tests when more than 1 element are present?
You can do that as well, if you prefer.
Also, in my case I actually wanted to see that there was two instances of what I was searching for. In such a case I used getAllByText('some text').toHaveLength(2)
20

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 :-)

1 Comment

Along similar lines, I ran into this in a test file that had both enzyme and RTL tests. Had to call wrapper.unmount() on earlier tests so that there was no extra lingering component by the time my RTL test ran
12

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();
})

Comments

2

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

Comments

0

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()
})

1 Comment

I'm using @testing-library/react: ^11.2.3. So I need to downgrade to 10.4.9?
0

You can fix it using string instead of regex:

const toRadio = screen.getByLabelText("to");

There is some problem with two caracters names in Jest.

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.