1

I have a few Jest tests that test functionality in the app that is not at all related to FirebaseUI and do not need a browser window to execute. I use FirebaseUI in other, unrelated parts of my application.

With that being said, when I try to run one of the tests, FirebaseUI throws an error "ReferenceError: window is not defined", even though I'm not calling any code that is related to FirebaseUI or requires a browser.

I understand that Jest tests run in the Node.js environment, so the browser window simply doesn't exist. However, since my Jest tests don't call any FirebaseUI code, this shouldn't be happening.

What should I do? Is there a way to mock a dummy browser window with Jest?

Here's the test file:

import '../../../../cbjs/setup_test'
import {getCenter, rgbaNormalizedToCSS, templateStructToNewCollage} from "./template_converter";
import {Point, Size} from "@piccollage/cbjs";
import {serverStringToStruct} from "../string_struct_converters";
import {ImageScrape} from "../../collage_editor/models/image_scrape";

// TODO: can't run tests from this file (Firebase error => window is not defined in ref_store constructor)

it("rgbaNormalizedToCSS works", () => {
  expect(rgbaNormalizedToCSS([0, 0.5, 0.3, 0.4]))
    .toBe("rgba(0, 128, 77, 0.4")
})

it("getCenter works", () => {
  expect(getCenter([0, 0], [100, 100]))
    .toBe(new Point(50, 50))
})

it("templateStructToNewCollage works (just a single ImageScrape)", () => {
  const struct = serverStringToStruct("../test_files/test.plist", true)

  console.log(struct)

  const collage = templateStructToNewCollage('0', struct)

  expect(collage.size$.value).toBe(new Size(300, 300))
  expect(collage.ownerId).toBe('0')
  expect(collage.backgroundURL$.value).toBe("photo-framework:/AAF82513-DA99-4F71-A371-7CCED92F4D52/L0/001")
  expect(collage.scrapes$.value.length).toBe(1)

  const scrape = collage.scrapes$.value[0]

  expect(scrape instanceof ImageScrape).toBeTruthy()
  expect(scrape.sizeBase$.value).toBe(new Size(300, 58.843537414965986))
  expect(scrape.positioning$.value.point).toBe(new Point(396.9729729729729, 518.6104045537717))
  expect(scrape.positioning$.value.rotation).toBe(0)
  expect(scrape.positioning$.value.scale).toBe(1.8990109511630093)
  expect(scrape.z$.value).toBe(1)
  expect((scrape as ImageScrape).imageSourceUrl$.value)
    .toBe("photo-framework:/687200F1-2A1C-40A0-BF76-B1D678C64799/L0/001")
})

Here is the stack trace:

    ReferenceError: window is not defined

      at node_modules/firebaseui/dist/npm.js:1:270
      at node_modules/firebaseui/dist/npm.js:26:301
      at Object.<anonymous> (node_modules/firebaseui/dist/npm.js:460:359)
      at Object.<anonymous> (node_modules/@piccollage/cbjs/dist/src/firebaseAuth.js:15:33)

File jest.config.js

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  transformIgnorePatterns: [
    'node_modules/(?!(cbjs)/)',
  ],
  transform: {
    "^.+\\.(ts|js|jsx)$": "ts-jest"
  },
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
};
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jasper Huang
  • 501
  • 2
  • 7
  • 15
  • 2
    If you provide the stack trace of the error, it might reveal something. – sdgluck Sep 09 '20 at 08:57
  • Could you provide some code for reference ? – kiratot Sep 09 '20 at 08:57
  • Could you share your jest config, especially what value is being used for `testEnvironment` – etarhan Sep 09 '20 at 09:05
  • 2
    The problem is specific to your setup. JSDOM is enabled by default in newer Jest versions. In case it isn't, it needs to be enabled in config. – Estus Flask Sep 09 '20 at 09:11
  • This can be ***the*** top search engine when searching for "`Jest ReferenceError window is defined`". As we have now learned, it is often due to [the breaking change with Jest 27](https://stackoverflow.com/questions/63808145/referenceerror-window-is-not-defined-when-running-jest-tests-for-a-react-proj#comment121480589_63808418). – Peter Mortensen Aug 04 '22 at 19:15
  • But perhaps there is a better-suited canonical question for this very common problem? – Peter Mortensen Aug 04 '22 at 19:28
  • [An answer](https://stackoverflow.com/questions/46274889/jest-test-fails-with-window-is-not-defined/67889107#67889107) to [Jest test fails with "window is not defined"](https://stackoverflow.com/questions/46274889) covers the Jest v27 breaking change. – Peter Mortensen Aug 04 '22 at 19:58
  • Does this answer your question? [Jest test fails with "window is not defined"](https://stackoverflow.com/questions/46274889/jest-test-fails-with-window-is-not-defined) – Michael Freidgeim Feb 20 '23 at 03:06

1 Answers1

2

window is a global browser object that is not defined when running your tests with Jest on a Node.js runtime. Usually Jest can be run using a jsdom environment that will provide those globals, using on --env=jsdom in the command-line interface should do the trick.

As for the library, you may want to mock it completely using a Jest configuration. See the docs: Mocking Node modules. It is as easy as creating a file in the proper location at the root of your project alongside the node_modules in a mocks directory.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
adz5A
  • 2,012
  • 9
  • 10
  • 2
    It seems that this was a breaking change in Jest 27. Adding `--env=jsdom` solved the problem after upgrading Jest from 26. – jcubic May 29 '21 at 14:39
  • @jcubic Yes, see https://github.com/facebook/jest/pull/9874 and https://jestjs.io/blog/2021/05/25/jest-27#flipping-defaults. So you have to set/overwrite`testEnvironment: "jsdom"` explicitly now in the jest.config file. – RiZKiT Aug 11 '21 at 08:32
  • @RiZKiT this is what I wrote, it was breaking change in Jest 27. – jcubic Aug 11 '21 at 10:16