HomeSegun Adebayo

How to fix react testing library createEvent error

  • #testing
  • #react
Segun Adebayo

Segun Adebayo

1 min read
How to fix react testing library createEvent error

In Chakra UI, we've had to deal a weird testing issue in CI. When we run `yarn test` locally, all tests passed without issues.

After a while, we noticed tested started to fail randomly. The errors we from `react-testing-library` and looks like

TypeError: Cannot read property 'createEvent' of null

After several attempts and almost giving up 😆, I found out the isse was related to the subtle difference between `findbyTestId` and `getByTestId`.

The `findBy*` queries requires return a promise, not the element itself. Hence the test to be async and you'd have to `await` the promise before carrying out assertions on the element.

Here's a preview of the failure point

test('should not be interactive when disabled', () => {
  render(
    <Editable defaultValue="editable" isDisabled>
      <EditablePreview data-testid="preview" />
      <EditableInput data-testid="input" />
    </Editable>,
  );

  userEvent.click(screen.getByText(/editable/));
  // ❌ Error: Cannot read property 'createEvent' of null
  // Reason: `findByTestId` returns a promise, not the element itself.
  expect(screen.findByTestId('input')).not.toBeVisible();
});

We can fix this by:

  • Converting the test to an `async` function
  • Using `await` to wait for the promise returned by `findByTestId`
test('should not be interactive when disabled', async () => {
  render(
    <Editable defaultValue="editable" isDisabled>
      <EditablePreview data-testid="preview" />
      <EditableInput data-testid="input" />
    </Editable>,
  );

  userEvent.click(screen.getByText(/editable/));
  // ✅ Success: Found the element
  expect(await screen.findByTestId('input')).not.toBeVisible();
});

Another way to resolve this is to use `getByTestId` instead of `findByTestId`.

test('should not be interactive when disabled', () => {
  render(
    <Editable defaultValue="editable" isDisabled>
      <EditablePreview data-testid="preview" />
      <EditableInput data-testid="input" />
    </Editable>,
  );

  userEvent.click(screen.getByText(/editable/));
  // ✅ Success: Found the element
  expect(screen.getByTestId('input')).not.toBeVisible();
});

and that's it!


Stay up to date

Get emails from me about web development, tech, and early access to new projects.


Segun Adebayo

Written by Segun Adebayo (Sage)

Sage is a Github Star 🌟 and Design Engineer 👨🏽‍💻. He is passionate about helping people build an accessible web faster. Sage is the author of Chakra UI, a React UI library for building accessible experiences.

Segun Adebayo

Passionate UI engineer looking to bridge the gap between design and code

All rights reserved © Segun Adebayo 2024