testing-library / testing-library/user-event

Modify docs suggesting fireEvent as fallback

Open
#1,242 0 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement needs assessment
Dominant language
TypeScript
Stars
2.3k
Forks
258
PR merge metrics
No merged PRs in 30d

Description

Problem description

The current documentation seems to suggest that userEvent should be used almost always instead of fireEvent, but as others have called out, things like userEvent.type() are pretty expensive at scale. Heavy usage of that method may require overriding defaults (Jest timeout, userEvent's own delay, etc.).

A lot of developers are likely to take documentation as gospel... so can recommendations like this be reconsidered?

Most projects have a few use cases for fireEvent, but the majority of the time you should probably use @testing-library/user-event.

Suggested solution

Language suggesting fireEvent should be considered only a fallback solution seems to be dismissing test performance, and scale. Something more along these lines would make more sense in my opinion:

Projects writing mostly integration tests should prefer using userEvent over fireEvent, but that may require overriding test framework timeout defaults. However, projects that don't intend on changing any defaults, and don't require key-by-key emulation may need to consider if fireEvent is the more appropriate tool for the job when performance is a concern.

Or even something that mentions setting delay: null, as suggested by the aforementioned issue reviewer.

Additional context

Consider this Typescript example:

import React from 'react';
import { render, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

jest.setTimeout(60000);

const FIELDS = 20;
const CHARS = 200;

const fields = Array.from({ length: FIELDS }).map((_, i) => (
  <input type="text" key={i} aria-label={`fake${i}`} />
));
const chars = 'a'.repeat(CHARS);
const MyTest = () => <div>{fields}</div>;

describe('MyTest', () => {
  test('userEvent', async () => {
    const session = userEvent.setup();
    const { getByRole } = render(<MyTest />);
    for (let i = 0; i < fields.length; i++) {
      await session.type(getByRole('textbox', { name: `fake${i}` }), chars);
    }
  });

  test('fireEvent', async () => {
    const { getByRole } = render(<MyTest />);
    for (let i = 0; i < fields.length; i++) {
      fireEvent.input(getByRole('textbox', { name: `fake${i}` }), {
        target: { value: chars },
      });
    }
  });
});

The outcome:

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the DOM Testing Library API Events documentation linked in the issue and review the related user-event issue about typing performance. Reconsider the wording that presents userEvent as the usual choice, incorporating the performance and delay considerations described here; done means the recommendation accurately explains when fireEvent may be appropriate.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
documentation
Issue type
Documentation
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.