testing-library / testing-library/user-event
Modify docs suggesting fireEvent as fallback
Nobody has claimed this yet.
- 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
userEventoverfireEvent, 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 iffireEventis 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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