## TL;DR

The test did not finish in 5 seconds, usually because a promise never resolved or a callback was never called. Fix the async handling first; only raise the timeout for tests that are legitimately slow.

## Error

```text
thrown: "Exceeded timeout of 5000 ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
```

## Steps

1. Check for a missing `done()` call, an un-awaited promise, or a forgotten `return`. Expected: the most common cause found in seconds.
2. Look for timers or intervals the test never clears; use `jest.useFakeTimers()` where appropriate. Expected: the test is not waiting on real time.
3. If the test awaits a real network call, mock it. Expected: no real I/O in unit tests.
4. If the test is legitimately slow (integration), raise it locally: `jest.setTimeout(30000)` at the top of that file. Expected: only that file gets more time.
5. Re-run the file. Expected: green quickly.

## When to use

- Exactly one or a few tests time out at 5000ms.
- The error suggests `jest.setTimeout`.

## When not to use

- The whole suite is slow (parallelism and splitting, not timeouts).
- Playwright's 30s timeout (different framework).

## Tool compatibility

- Jest 27 through 30; `jest.setTimeout`, fake timers.

## Variant phrasing

### Jest async test timeout

The general async variant; check awaits and done() first.

### Jest did not exit / open handles

The sibling symptom; `--detectOpenHandles` finds the leak.

## Why it happens

Jest waits for the test function to signal completion. Anything that never resolves (pending promise, live server, uncleared timer) runs out the clock.

## Edge cases

- `jest.setTimeout` in setup files affects everything; prefer per-file.
- Fake timers break libraries that need real time; scope them to the test.
- A test that needs 30s is an integration test; consider moving it out of the unit suite.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_3RTUEAQeqir47LK0BzNuTw
