Search code examples
reactjsunit-testingantdreact-testing-library

React testing library, how to open a Collapse in Ant Design


I want to write a unit test that opens an antd. Collapse <Panel />

But no matter what combination of fireEvent or userEvent mouse actions I try, I cannot get React testing library to properly "click" on this antD component the same way a real user does.

Example code:

import { Collapse } from 'antd'
const { Panel } = Collapse

const Example = () => (
<Collapse>
  <Panel header="test" data-testid="testid">hello_world</Panel>
</Collapse>
)

and in my unit test:

I have tried the following combinations to open the Panel with the header "test"

const panel = screen.getByText('test')
userEvent.click(panel)

const result = screen.getByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
userEvent.click(panel)

const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
fireEvent.click(panel)

const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
fireEvent.mouseDown(panel)

const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
await act(async () => {
  fireEvent.mouseDown(panel)
})

const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByText('test')
await act(async () => {
  fireEvent.mouseDown(panel)
})

await waait(500) // using waait library, to force time to pass to see if it was that...

const result = await screen.findByText('hello_world') // FAILED and never finds hello_world
const panel = screen.getByTestId('testid')
fireEvent.click(panel) // FAILED, never finds anything with data-testid="testid"
// I guess antd did not bother passing the test-id to the component.

const result = await screen.findByText('hello_world')

This is what the HTML looks like:

                    <div
                      class="ant-collapse ant-collapse-icon-position-left css-14dabdk"
                    >
                      <div
                        class="ant-collapse-item"
                      >
                        <div
                          aria-expanded="false"
                          class="ant-collapse-header"
                          role="button"
                          tabindex="0"
                        >
                          test
                        </div>
                      </div>

I did also try to use querySelector on container to target .ant-collapse-header, ant-collapse-item or .ant-collapse with userEvent.click and fireEvent.mouseDown. But those didn't work either.

Why is this thing so difficult to open in a test 🤯.

Does anyone know how to open and antD Collapse component?


Solution

  • Using user-event, you can try:

    await userEvent.click(screen.getByText(/test/i))
    

    Or click the button, like:

    await userEvent.click(screen.getByRole("button"))
    

    Then you can use findByText like:

    expect(await screen.findByText(/hello_world/i)).toBeInTheDocument();
    

    (Working example)