I have a unit test written in react jest and for unknown reason its failing. This is the test
it('handles filter addition and removal', async () => {
const addNewButton = await screen.findByText('actions.addNew')
await act(async () => {
userEvent.click(addNewButton)
const compareDropdown = await waitFor(() => screen.getByTestId('dimensionDropdown'), { timeout: 5000 })
userEvent.click(compareDropdown)
const optionSelect = await screen.findByRole('option')
userEvent.click(optionSelect)
const treeSelect = await screen.findByTestId('dimensionValues')
userEvent.click(treeSelect)
const optionTreeSelect = await screen.findByRole('treeitem')
userEvent.click(optionTreeSelect)
const submitButton = await screen.findByTestId('filtersSubmit')
userEvent.click(submitButton)
await waitFor(() => {
const chips = screen.queryByTestId('filterChips0')
expect(chips).toBeInTheDocument()
})
const chips = screen.getByTestId('filterChips0')
const chipsContent = chips.querySelector('p') as HTMLElement
expect(chipsContent).toHaveTextContent('Department = test-1')
const removeButton = await screen.findByTestId('removeFilterChips')
userEvent.click(removeButton)
await waitFor(() => {
const chips = screen.queryByTestId('filterChips0')
expect(chips).not.toBeInTheDocument()
})
})
})
The warning I receive it's
Warning: An update to DomainFilterWindow inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
But can not find the reason why. It seems that I wrapped the DOM changes into act, but still receive the error for it
I use React Native testing library, so there migth be slight differences. But I am believe you have to setup a user with userEvent.setup. user.click is already wrapped in act and it is async, so you shouldn't reWrap it and you should await it directly instead. I think the issue was that all your code was inside the act(). Also you defined 3 consts named filterChips, I don't think you want to do that. I think it should look more like this:
const user = userEvent.setup();
it('handles filter addition and removal', async () => {
renderScreen() // I don't see where you do this, but it is best practice to have it inside your test.
const addNewButton = await screen.findByText('actions.addNew')
await user.click(addNewButton)
const compareDropdown = screen.getByTestId('dimensionDropdown')
await user.click(compareDropdown)
const optionSelect = await screen.findByRole('option')
await user.click(optionSelect)
const treeSelect = await screen.findByTestId('dimensionValues')
await user.click(treeSelect)
const optionTreeSelect = await screen.findByRole('treeitem')
await user.click(optionTreeSelect)
const submitButton = await screen.findByTestId('filtersSubmit')
await user.click(submitButton)
const chips = screen.getByTestId('filterChips0')
expect(chips).toBeInTheDocument()
const chipsContent = chips.querySelector('p') as HTMLElement
expect(chipsContent).toHaveTextContent('Department = test-1')
const removeButton = await screen.findByTestId('removeFilterChips')
await userEvent.click(removeButton)
expect(screen.queryByTestId('filterChips0')).toBeNull()
})