vitest: Random test crashes with "window is not defined" error

Describe the bug

From time to time I get the error ReferenceError: window is not defined.

image

or

image

Reproduction

I couldn’t find any pattern. It just happens sometimes.

This happens with any value of environment, and happy-dom and jsdom.

vitest.config.ts:

/// <reference types="vitest" />

import path from 'path';
import { defineConfig } from 'vite';

// eslint-disable-next-line import/no-default-export -- by design
export default defineConfig({
  test: {
    environment: 'happy-dom',
    include: ['**/*.test.ts'],
    setupFiles: [path.resolve(__dirname, 'vitest.setup.ts')],
  },
});

System Info

System:
    OS: macOS 12.2.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 2.14 GB / 32.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 16.15.0 - /usr/local/bin/node
    Yarn: 1.22.18 - /usr/local/bin/yarn
    npm: 8.5.5 - /usr/local/bin/npm
  Browsers:
    Brave Browser: 101.1.38.111
    Chrome: 101.0.4951.54
    Chrome Canary: 103.0.5057.0
    Firefox: 100.0
    Safari: 15.3
  npmPackages:
    vite: ^2.9.9 => 2.9.9 
    vitest: ^0.12.4 => 0.12.4

Used Package Manager

npm

Validations

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 1
  • Comments: 16 (5 by maintainers)

Most upvoted comments

I had the same problem with an integration test. The problem was that the “window” object was global. Normally vitest starts in enviroment mode “node” More here

My solution was to set the environment to “jsdom” in my “vite.config.js”.

  test: {
    environment: "jsdom"
  }

Catch-22

You need to remove this when running in Vitest, because Vitest runs in node where it exists. You can remove it conditionally with process.env.VITEST or mode === 'test':

export default defineConfig(({ mode }) => ({
  define: process.env.VITEST ? {} : { global: 'window' }
})

It seems like vitest should not tear down the environment if there’s still stuff in the event queue then?

I get that this is some async thing that’s coming in late, but usually it would find window and it’d be a-ok. Never had this issue with jest which we just came from (same tests), which might indicate that they do wait(?).

If it is meant to be a feature, then it should always warn about things being run after teardown, and not just when it crashes due to an env issue.

These are some quite big integration tests, and I’m also unable to tell which tests they came from, even almost-so. The console.log I put in doesn’t happen for this after-teardown run, only for things inside the test. 🤔

@dartess what was your solution to this ? I have a similar problem but I don’t know how to kill my socket handlers after the tests are completed.