How to access an input element of type checkbox and name using react testing library?
Asked Answered
D

3

10

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

Dinnie answered 8/11, 2021 at 16:25 Comment(5)
How did you tried? Post your code.Blende
Does this answer your question? How to fetch element with 'name' attribute in react-testing-libraryCarve
@HenryWoody: thanks but i had tried the same answer and i get the same error as the author in the question.Dinnie
I added another answer to that that should work for youCarve
yes this seems to work. but still i need to use if statement. without that i get the error in questionDinnie
A
11

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' });
Arv answered 14/11, 2021 at 18:22 Comment(0)
C
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

Cain answered 8/11, 2021 at 18:13 Comment(1)
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.Antimatter
N
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

Nato answered 14/12, 2021 at 13:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.