React-Testing-Library can't find component with given role and name

Viewed 3323

I have an input with a dynamically-generated name that I would like to select with react-testing-library. RTL doesn't detect the input, even though the CLI error output contains an element with the correct name and role.

Here is an excerpt of the test code:

const attributeInput = await getByRole(container, 'textbox', {name: 'attributes[0].value'});
await waitFor(() => {
      expect(attributeInput).toBeTruthy();
});

The error message of the test is as follows:

TestingLibraryElementError: Unable to find an accessible element with the role "textbox" and name "attributes[0].value"

Here are the accessible roles:

... (list of accessible roles and inputs of different types with various names, omitted for brevity) ...

  --------------------------------------------------
  textbox:

  Name "":
  <input
    aria-invalid="false"
    class="MuiInputBase-input MuiOutlinedInput-input"
    name="attributes[0].value"
    rows="1"
    type="text"
    value=""
  />

Clearly, the element is in the container, is of role "textbox," and has a name property with the value 'attributes[0].value' associated with it. Why then does RTL not register that this component of the correct type and name, is the one I'm looking for? Why the erroneous

Name: ""

output in the command line?

Possibly relevant: I am using material-ui and this HTML is generated from a TextField wrapped in a react-hook-form controller. Moreover, this assertion is arrived at after some previous react-testing-library actions that programmatically navigate to this page and expect to see this input. None of the previous 'gets' 'acts' or 'waitFor/expects' fail, and a number of the other inputs have names recognized by react-testing-library (although the names assigned to them by RTL appear to be their InputLabel texts and not what is assigned to the 'name' attribute on the generated HTML).

1 Answers

For any Async operation it is recommended to not use getBy instead please try with findByRole/findAllByRole method. Reference:

  [
                { name: 'Chocolate', imagePath: '/images/chocolate.png' },
                { name: 'Vanilla', imagePath: '/images/vanilla.png' },
            ]
  test("display each impage of scoop as response api", async () => {
    render(<Options optionType="scoops" />);

    // Find images
    const scoopImages =  await screen.findAllByRole('img', {
        name: /scoop$/i
    });
    expect(scoopImages).toHaveLength(2);

    const altText = scoopImages.map((elem) => elem.alt);
    expect(altText).toEqual('Chcolate scoop', 'Vanilla scoop');
})

Related