Search code examples
reactjsreact-testing-librarycustom-events

How can I pass event properties to a customEvent using React Testing Library?


I am trying to test a component using RTL that uses a customEvent to trigger a display. Given a component like this:

const Alerts = () => {
  const [alerts, setAlerts] = useState([]);

  const addAlert = (body, type = 'info', timeout = 7500) => {
    const key = nextIndex++;
    setAlerts([
      ...alerts,
      { key, body, type },
    ]);

    // Set a timer to remove the alert.
    setTimeout(() => {
      setAlerts(alerts.filter((alert) => alert.key !== key));
    }, timeout);
  };

  document.addEventListener(
    'newalert',
    ({ details:
      {
        body = '',
        type = '',
        timeout = 1000
      } = {}
    }) => {
      addAlert(body, type, timeout);
  });

  return (
    <>
      {alerts.map((alert) => <Alert {...alert} />)}
    </>
  );
};

I am trying to test it like this:

test('An alert is rendered on a newalert event', () => {
  render(<Alerts  />);
  fireEvent(
    document,
    createEvent('newalert', document,
    {
      details: {
        body: 'Hello World!',
        type: 'info',
        timeout: 1000,
      }
    })
  );

  expect(screen.getByText('Hello world'));
});

And it is firing the custom event as expected, however none of the properties (details, body, type, or timeout) is being passed to the event. What am I missing?


Solution

  • You need to pass the name of the event constructor as the fourth parameter, and it works!

    createEvent(
          'newalert',
          document,
          {
            detail: {
              body: 'Hello World!',
              type: 'info',
              timeout: 1000,
            }
          },
          { EventType: 'CustomEvent' }
        )
      );