This rule raises an issue when a promise is passed to a fireEvent method instead of a DOM element.
fireEvent dispatches a DOM event by calling DOM APIs directly on the value passed as its first argument. It expects a resolved DOM
element, not a promise.
The asynchronous queries findBy* and findAllBy* return a promise that resolves to an element once it appears in the DOM.
Passing that promise to fireEvent without awaiting it hands fireEvent a Promise object, which has none of the
DOM methods it tries to call, so the event is never dispatched and the test throws at runtime. This happens whether the query result is passed
directly, stored in a variable that still holds the unresolved promise, or built with new Promise(…). Because the failure is immediate
and deterministic rather than a subtle bug, the test is guaranteed to break.
To fix it, resolve the promise before handing it to fireEvent: await the asynchronous query, or use the synchronous
getBy* query when the element is already in the DOM.
import { fireEvent, screen } from '@testing-library/react';
test('submits on click', async () => {
fireEvent.click(screen.findByRole('button', { name: 'Submit' })); // Noncompliant: "findByRole" returns a promise, not a DOM element
});
import { fireEvent, screen } from '@testing-library/react';
test('submits on click', async () => {
fireEvent.click(await screen.findByRole('button', { name: 'Submit' }));
});