Jest setupFilesAfterEnv Not Applied - Globals/Matchers Missing
Custom matchers (toBeInTheDocument) or global beforeEach hooks are undefined because your setup file never ran. Usually the path in setupFilesAfterEnv is wrong, or it was placed in setupFiles (which runs before the test framework exists).
What this error means
Tests fail with "expect(...).toBeInTheDocument is not a function" or your global hooks simply never fire. Importing the matcher directly in a single test works, proving the shared setup file is not being loaded.
TypeError: expect(...).toBeInTheDocument is not a function
> 6 | expect(screen.getByRole('button')).toBeInTheDocument();
| ^Diagnose it: flake, environment, or genuine failure?
Before debugging the assertion, establish whether the test is deterministic. A test that fails only in CI is usually order-dependent, time-dependent, or racing something, and fixing the assertion will not help.
# does it fail in isolation?
npx vitest run path/to/file.test.ts
# is it order dependent? run the suite in a random order twice
npx vitest run --sequence.shuffle
# is it a race? run the same file repeatedly
for i in $(seq 1 20); do npx vitest run path/to/file.test.ts || break; doneCommon causes
Matchers placed in setupFiles, not setupFilesAfterEnv
setupFiles runs before the test framework is installed, so expect.extend (jest-dom) has no expect to attach to. Matcher setup must live in setupFilesAfterEnv, which runs after the framework loads.
Wrong path or overridden by a project config
A wrong <rootDir> path means the file is never found, or a projects[] entry overrides the root setupFilesAfterEnv so the root one is ignored for that project.
How to fix it
Register the setup file in the right key
Put framework-dependent setup (matchers, global hooks) in setupFilesAfterEnv.
// jest.config.js
module.exports = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
};
// jest.setup.ts
import '@testing-library/jest-dom';Verify the file actually loads
- Add a
console.login the setup file and confirm it prints once per worker. - Check the
<rootDir>resolves to where the file lives. - For
projects[], setsetupFilesAfterEnvinside each project, not only at the root.
CI-only causes worth ruling out
- Runners have fewer cores than a laptop, so timing-sensitive tests that pass locally fail under contention.
- No TTY and a different locale or timezone. Snapshot tests containing formatted dates or numbers are the usual casualty; pin
TZandLANGin the job. - Parallel workers sharing a database, a port, or a temp directory. Give each worker its own namespace.
- Default timeouts calibrated on a fast machine. A cold runner is slower on first execution, especially before any cache warms.
How to prevent it
- Use
setupFilesAfterEnvfor anything that touchesexpector test lifecycle. - Keep one shared setup module and reference it from every project.
- Log from setup once to confirm it is wired in.