78

I am trying to get started with state-of-the-art web development learning React and Redux.

Right now I am stuck at getting tests running. For some reason, Jest fails with

Task :frontend:test
yarn jest v1.0.2
$ "/Users/gunnar/git/app.oakstair.se/frontend/node_modules/.bin/jest"
FAIL src/containers/App/App.test.js
  ● Test suite failed to run

 ReferenceError: window is not defined

  at Object.<anonymous> (config/polyfills.js:18:1)
  at next (native)
  at process._tickCallback (internal/process/next_tick.js:109:7)

I have googled for a while without any success...

This is my starting test.js

And this my App test code

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gunnar Eketrapp
  • 2,009
  • 1
  • 19
  • 33
  • could you please add your test code ? – José Quinto Zamora Sep 19 '17 at 16:50
  • I added two images.I could make the repo public but its quite big since it is based on a react/redux template that I bought which contains a lot! – Gunnar Eketrapp Sep 23 '17 at 08:14
  • Do you run it with jsdom? – Quoc-Anh Nguyen Sep 30 '17 at 15:41
  • Please review *[Why not upload images of code/errors when asking a question?](https://meta.stackoverflow.com/questions/285551/)* (e.g., *"Images should only be used to illustrate problems that* ***can't be made clear in any other way,*** *such as to provide screenshots of a user interface."*) and take the appropriate [action](https://stackoverflow.com/posts/46274889/edit). Thanks in advance. – Peter Mortensen Aug 04 '22 at 19:50
  • Somewhat related: *[How can I mock the JavaScript 'window' object using Jest?](https://stackoverflow.com/questions/41885841/)*. A crypto answer states *"Instead of `window`, use `global`"*. – Peter Mortensen Aug 04 '22 at 21:09

5 Answers5

103

I had the same issue and I do not believe modifying globals is the way to do it.

The issue was because in my Jest configuration I had testEnvironment set to node when it should've been jsdom. For me, this setting was located in file package.json as defined by the React starter app.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JacksonHaenchen
  • 1,437
  • 1
  • 11
  • 16
  • 1
    For info `jsdom` is the default value (see https://jestjs.io/docs/en/configuration.html#testenvironment-string) so unless you have overwritten it (like they do in `create-react-app`) you should be ok – Arnaud Valle Jan 10 '19 at 14:33
  • If you need to support canvas you'll need to set `testEnvironment` to `environment-jsdom-fourteen` and install it with `npm install --save-dev jest-environment-jsdom-fourteen` https://github.com/jsdom/jsdom#canvas-support – Ivan Castellanos Jun 13 '19 at 00:46
  • If you use react-native, chances are you're using the `preset: react-native` jest config which overwrites the default value to exclude the DOM: https://jestjs.io/docs/en/tutorial-react-native#environment – Jeroen Vannevel Apr 23 '20 at 17:02
  • i am also getting same error but i am using vue.js , if any suggestions please help me – Sravani Jun 22 '21 at 14:07
  • testEnvironment:jsdom' doesn't pass value of window.location.href from one function to another, but setting globals: { window: { location works ok https://stackoverflow.com/questions/46274889/jest-test-fails-with-window-is-not-defined/72275917#72275917 – Michael Freidgeim Feb 20 '23 at 04:13
84

In your package.json file, add window like a global. Something like this:

"jest": {
  "verbose": true,
  "preset": "react-native",
  "setupFiles": ["./jest/setup.js"],
  "testRegex": "(/tests/.*|\\.(test|spec))\\.(ts|tsx|js)$",
  "transformIgnorePatterns": [
    "node_modules/(?!(jest-)?react-native|lottie-react-native)"
  ],
  "globals": {
    "window": {}
  }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Miguel Cardenas
  • 1,215
  • 9
  • 5
  • 2
    Unfortunately create-react-app does not support configuring globals this way. Any suggestion there? – Faust Apr 29 '19 at 05:11
  • @Faust See JacksonHaenchen's answer – Ivan Castellanos Jun 13 '19 at 00:44
  • 1
    This is could be helpful, but it's an empty object anyway, so you have no properties such as `userAgent`, etc. Maybe it's a way to map here an object from jsdom or something. Would be way more helpful – eXception Sep 10 '21 at 10:06
  • Consider to populate properties like window.location -see Solders's answer below https://stackoverflow.com/questions/46274889/jest-test-fails-with-window-is-not-defined/72275917#72275917 – Michael Freidgeim Feb 20 '23 at 04:09
41

2021 (Jest 27)

Jest's testEnvironment default used to be jsdom. It was changed to node starting with version 27.

You can set testEnvironment: 'jsdom' in your configuration file to keep using JSDOM.

However, 'node' seems to be a lot faster, so you should be mocking browser APIs where possible.

Jest 27: New Defaults for Jest, 2021 edition

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
j2L4e
  • 6,914
  • 34
  • 40
  • 4
    But it sounds that it should be possible to have "window" and etc in "node" env. Is it? I'd like to speed up my project with switching from jsdom to node, but wonder if it possible, cause I have same issues with undefined "window". – eXception Sep 10 '21 at 10:03
  • also need to install jest-environment-jsdom npm module seperately – Vipul Dessai May 07 '22 at 13:46
  • Can you address the need for 'jest-environment-jsdom' in your answer (even if it is not required)? And possible ***silent failure*** if it isn't installed(?). (But ************* ***without*** *************** "Edit:", "Update:", or similar - the answer should appear as if it was written today) – Peter Mortensen Aug 04 '22 at 20:12
  • @Vipul Dessai: As of version 28 (released 2022-04-25): *"As of Jest 28 "jest-environment-jsdom" is no longer shipped by default. Make sure to install it separately."*. From [its blog post](https://jestjs.io/blog/2022/04/25/jest-28): *"Please note that both of the removed modules (jest-environment-jsdom and jest-jasmine2) are still actively maintained and tested in the same way, so the only breaking change here is that you'll need to explicitly install them."* – Peter Mortensen Aug 04 '22 at 21:44
7

If you want to keep testEnvironment set to node, you can configure a global window in your jest.config.js/ts and then mock what you need in your test cases.

It works fine as long as you don't need any advanced features. It is the same answer as some of the high rated previous ones, but including some examples.

import type {Config} from '@jest/types';

const config: Config.InitialOptions = {
  ...jestConfig,
  testEnvironment: "node",
  globals: {
    window: {
     location: {}
    }
  }
};

export default config;

SomeTestCase.spec.ts

test('Is correct href', () => {
  window.location.href = 'https://somedomain.com';
  expect(window.location.href).toBe('https://somedomain.com');
})
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Solders
  • 391
  • 1
  • 4
  • 11
6
npm i jest-environment-jsdom

File index.test.tsx

/**
 * @jest-environment jsdom
 */
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
小弟调调
  • 1,315
  • 1
  • 17
  • 33
  • An explanation would be in order. E.g., why do you need to install something extra? Is that really necessary? What is the advantage? What is the idea/gist? From [the Help Center](https://stackoverflow.com/help/promotion): *"...always explain why the solution you're presenting is appropriate and how it works"*. Please respond by [editing (changing) your answer](https://stackoverflow.com/posts/68911353/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Aug 04 '22 at 20:00
  • It seems to be a requirement for Jest version 28 (released 2022-04-25): *"As of Jest 28 "jest-environment-jsdom" is no longer shipped by default. Make sure to install it separately."*. From [its blog post](https://jestjs.io/blog/2022/04/25/jest-28): *"Please note that both of the removed modules (jest-environment-jsdom and jest-jasmine2) are still actively maintained and tested in the same way, so the only breaking change here is that you'll need to explicitly install them."* – Peter Mortensen Aug 04 '22 at 21:42
  • Can you make your answer more comprehensive, please? (But ***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today.) – Peter Mortensen Aug 04 '22 at 21:46
  • See https://stackoverflow.com/questions/72013449/upgrading-jest-to-v29-error-test-environment-jest-environment-jsdom-cannot-be – Michael Freidgeim Feb 20 '23 at 03:44