Promise Passed To An Event Dispatch

ID

javascript.promise_in_fire_event

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

JavaScript

Tags

async, reliability, testing

Description

Reports a promise handed to fireEvent or userEvent as an argument. Both take a DOM node and, optionally, an event-init object; neither awaits anything it is given, so a promise in either position is used as the object it is.

Three shapes of argument are read as a promise, all of them stated in the source: a findBy* or findAllBy* query, a chain ending in .then() / .catch() / .finally(), and a Promise.*(…​) or new Promise(…​).

An argument that is a call to a locally declared async function is left to javascript.missing_await, which resolves the callee and already reports a promise consumed as a value in any position.

Rationale

// Bad
fireEvent.click(screen.findByRole('button'));    // clicks a Promise
  • The asynchronous queries look almost exactly like the synchronous ones — getByRole returns the button, findByRole returns a promise of the button — so the missing await reads as correct code.

  • Dispatching at a Promise object hits nothing: it has no event target, no handler runs, and no error is raised.

  • The interaction simply does not happen, and the assertion that follows fails for a reason that points nowhere near the missing keyword.

  • In the event-init position the same mistake produces an event whose properties are all undefined, which handlers read as a default event rather than the one the test described.

Remediation

Await the query, then dispatch on the resolved element.

// Good
const button = await screen.findByRole('button');
fireEvent.click(button);

© 2026 Xygeni. All rights reserved