8

I have HTML code like so:

<label class="switch" value="true">
    <input name="source" type="checkbox"/>
</label>

How can I access input with name source? I have tried using getByRole and name attribute, but it throws an error that this input has name="".

Below is the tried solution that doesn't work:

screen.getByRole('checkbox', { name: 'source' });

How can I access this input element in other way?

I have tried to do like so as per solution provided

const elem = document.querySelector(
    `input[name="source"]`);
if (elem) {
    userEvent.click(elem);
}

This works but if I remove if statement like so

const elem = document.querySelector(
    `input[name="source"]`);
userEvent.click(elem);

I get an error:

Argument of type null| element is not assignable to parameter of type 'targetelement'. type null is not assignable to type targetelement

juliomalves
  • 42,130
  • 20
  • 150
  • 146
stackuser
  • 257
  • 1
  • 5
  • 14

3 Answers3

8

TL;DR: While you could use the container.querySelector approach, the recommended, idiomatic way of doing it is to use RTL's built-in queries.


The name option in *ByRole queries refers to the accessible name of the element, not the value of its name attribute. See What is the name option in react-testing-library? for details and references.

Given that the input element in your HTML doesn't have an accessible name, the only way to access it is to simply not include any option on the getByRole query.

screen.getByRole('checkbox');

However, if you wanted to use the name option, you'd first have to add an actual accessible name to it. In your case this could be done by using the existing label element.

<label class="switch" value="true">
    Source
    <input name="source" type="checkbox"/>
</label>

Which would allow you to query the input the way you were trying to, using the name option.

screen.getByRole('checkbox', { name: 'Source' });
juliomalves
  • 42,130
  • 20
  • 150
  • 146
0

Your

const elem = document.querySelector(
    `input[name="source"]`);
if (elem) {
    userEvent.click(elem);
}

is good because this only query for elements and return when not found any element, generally when you use get*/find* and do not find any element then rtl will throw an exception. https://testing-library.com/docs/react-testing-library/cheatsheet

If you have control over that HTML the best way it will be add data-testid attribute and use byTestId https://testing-library.com/docs/queries/bytestid

POLAKv93
  • 99
  • 1
  • 3
  • This is not a good practice. You shouldn't add new logic in unit test, because in unit test you're testing logic, so it's illogical to put `if` in unit test. – owenizedd Jul 25 '22 at 03:33
0

Try this way! The label will have htmlFor attribute which should match the id attribute of input:checkbox.

The text between opening and closing of label tag would then be the name of the checkbox that you can use for testing.

enter image description here

Sandeep Amarnath
  • 5,463
  • 3
  • 33
  • 43