Skip to content

'event was not wrapped in act' warning with React 18, react-datepicker and user.type #1231

@pzaczkiewicz-athenahealth

Description

Relevant code or config:

describe('ReactDatepicker', () => {
  beforeEach(() => (user = userEvent.setup()));

  it('should not emit act warnings', async () => {
    const now = new Date();
    const endOfNextYear = new Date(now.getFullYear() + 1, 11, 31);
    const dateFormat = 'M/d/yyyy';
    const userFormattedDate = format(endOfNextYear, dateFormat);
    const defaultFormattedDate = format(endOfNextYear, defaultDateFormat);

    render(<ReactDatepicker />);
    const input = screen.getByRole('textbox');
    await user.type(input, `${userFormattedDate}{Enter}`);
    expect(await screen.findByDisplayValue(defaultFormattedDate)).toBeInTheDocument()
  });

  it('should pass with fireEvent', async () => {
    const now = new Date();
    const endOfNextYear = new Date(now.getFullYear() + 1, 11, 31);
    const dateFormat = 'M/d/yyyy';
    const userFormattedDate = format(endOfNextYear, dateFormat);
    const defaultFormattedDate = format(endOfNextYear, defaultDateFormat);

    render(<ReactDatepicker />);
    const input = screen.getByRole('textbox');
    fireEvent.change(input, { target: { value: userFormattedDate } });
    fireEvent.keyDown(input, { key: 'Enter' });
    expect(await screen.findByDisplayValue(defaultFormattedDate)).toBeInTheDocument()
  });
});

What you did:

use userEvent.type when targeting react-datepicker to enter a date. The weird thing is the "not wrapped in act" error only appears when a valid date is typed and the {Enter} key is pressed. This is apparency causing some special condition to happen within the implementation of react-datepicker which userEvent isn't act wrapping appropriately.

What happened:

  console.error
    Warning: An update to r 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 */

    This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
        at r (C:\git\pzaczkiewicz\forge-contrib-react-datepicker-user-event-test-failure\.yarn\__virtual__\react-datepicker-virtual-69b8f1e761\0\cache\react-datepicker-npm-4.16.0-c94778dc5d-59da0305ca.zip\node_modules\react-datepicker\dist\index.js:1:78951)
        at ReactDatepicker (C:\git\pzaczkiewicz\forge-contrib-react-datepicker-user-event-test-failure\packages\react-datepicker-user-event-test-failure\src\ReactDatepicker\ReactDatepicker.tsx:7:45)

Reproduction:

https://github.com/pzaczkiewicz-athenahealth/react-datepicker-user-event-test-failure

Problem description:

Not wrapped in act warnings are usually good indications that what you are testing is not what the user sees. Ignoring them may hide bigger issues in tests.

Suggested solution:

Unknown. I dug into testing-library source code and couldn't completely wrap my head around why asyncWrapper and eventWrapper flip-flopped IS_REACT_ACT_ENVIRONMENT.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions