Test if each button in a component is disabled after click [React]

Viewed 640

I have a component which maps of some directions and renders a <button> for each direction. On click of a button it is disabled.

I have to setup a test to find wether the button is disabled after click.

My component:

 <div>
                    {sortDirections.map((sortDirection) => (
                      <button
                        key={sortDirection}
                        disabled={
                          sortFilters.direction === sortDirection &&
                          sortFilters.payType === sortVariant.payType
                        }
                        className="btn"
                        onClick={() =>
                          handleSortFilters({
                            payType: sortVariant.payType,
                            direction: sortDirection,
                          })
                        }
                      >
                        {sortDirection}
                      </button>
                    ))}
                  </div>

I will provide my test so far but it does have errors

 it('Sort button should be disabled on click', () => {
    render(
      <ProductSorter
        sortFilters={sortFilters}
        handleSortFilters={handleSortFilters}
      />
    );
    expect(screen.getAllByRole('button')).toHaveLength(4);

    // ERROR: Argument of type 'HTMLElement[]' is not assignable to parameter of type 'Element | Node | Document | Window'.
    fireEvent.click(screen.getAllByRole('button'));
  });

I can successfully test for one button but struggling due to it being an array of buttons and I need to test each one. Wondering if I must write each button with specific test individually?

2 Answers

You should be able to just use a forEach loop on the array:

it('Sort button should be disabled on click', () => {
    render(
      <ProductSorter
        sortFilters={sortFilters}
        handleSortFilters={handleSortFilters}
      />
    );
    const buttons = screen.getAllByRole('button')
    buttons.forEach((x)=>expect(x).toHaveProperty('disabled'))
  });

Because screen.getAllByRole('button') return an array of element. So you can use a loop to click each element like this:

screen.getAllByRole('button').forEach(element => {
  fireEvent.click(element )
})
Related