Jest "ReferenceError: X is not defined" - jsdom Globals in CI
Code under test referenced a browser or Node global that does not exist in the Jest environment. Either the test environment is node when it should be jsdom, or jsdom simply does not implement that API.
What this error means
A test throws ReferenceError: document is not defined (DOM code under the node environment) or ReferenceError: TextEncoder is not defined (a Web API jsdom does not provide). The same code runs fine in a real browser.
ReferenceError: TextEncoder is not defined
6 | import { encode } from './codec';
7 |
> 8 | const enc = new TextEncoder();
| ^Common causes
Wrong testEnvironment for DOM code
Jest’s default environment in recent versions is node, which has no window/document. DOM-touching tests need the jsdom environment.
jsdom does not implement the API
jsdom omits some Web APIs (TextEncoder, crypto.subtle, ResizeObserver, fetch on older setups). Referencing them throws unless you polyfill in setup.
How to fix it
Select the jsdom environment
Set it globally, or per-file with a docblock for just the DOM tests.
// jest.config.js
module.exports = { testEnvironment: 'jsdom' };
// or per file:
/**
* @jest-environment jsdom
*/Polyfill the missing global in setup
Provide the API in a setup file referenced by setupFiles.
// jest.setup.js
import { TextEncoder, TextDecoder } from 'util';
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;How to prevent it
- Pick
jsdomfor component/DOM suites andnodefor pure-logic suites. - Keep polyfills in a shared
setupFilesmodule. - Pin
jest-environment-jsdom, which is a separate package since Jest 28.