Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSDOM virtualConsole environment option defunct in parallel mode #8393

Closed
mzedeler opened this issue Apr 29, 2019 · 6 comments · May be fixed by joseroubert08/jest#34 or joseroubert08/jest#76
Closed

Comments

@mzedeler
Copy link

mzedeler commented Apr 29, 2019

🐛 Bug Report

Overriding virtual console for jsdom isn't possible for parallel execution.

To Reproduce

(Repl.it link further down.)

In any project using jest with at least two test files using jsdom, override the virtual console setting:

In jest.config.js:

    ...
    testEnvironment: "jsdom",
    testEnvironmentOptions: {
        virtualConsole: new require('jsdom').VirtualConsole()
    }
    ...

Then run:

  • jest

Expected behavior

The tests run as they should.

Actual behavior

The tests die with an error from JSDOM:

TypeError: options.virtualConsole must be a VirtualConsole (from createVirtualConsole)

(createVirtualConsole is a bug in JSDOM - it should say VirtualConsole AFAIK.)

This looks like a bug in the way Jest fans out test to workers, because if you runs sequentially, it works. To demonstrate this, try:

  • jest --runInBand

Link to repl or repo (highly encouraged)

https://repl.it/@mzedeler/Reproducing-virtualConsole-option-bug

Change first line in index.js to switch between passing and failing case.

Issues without a reproduction link are likely to stall.

Run npx envinfo --preset jest

Paste the results here:

  System:
    OS: Linux 4.15 Ubuntu 18.04.1 LTS (Bionic Beaver)
    CPU: (8) x64 Intel(R) Core(TM) i7-4810MQ CPU @ 2.80GHz
  Binaries:
    Node: 12.0.0 - ~/.nvm/versions/node/v12.0.0/bin/node
    Yarn: 1.15.2 - ~/.nvm/versions/node/v12.0.0/bin/yarn
    npm: 6.9.0 - ~/.nvm/versions/node/v12.0.0/bin/npm
  npmPackages:
    jest: 24 => 24.7.1 

This is relate to #5223.

@mzedeler mzedeler changed the title virtualConsole environment option defunct in parallel mode JSDOM virtualConsole environment option defunct in parallel mode Apr 29, 2019
@lh0x00
Copy link
Contributor

lh0x00 commented May 4, 2019

In the test processing the environment when setup/teardown in each test suites and virtualConsole in the environment will create each time too. The params virtualConsole of testEnvironmentOptions just is an fn and after first suites, this ref will be changed something. For this case, when you want to pass a virtualConsole to options, you can use:

const { VirtualConsole } = require('jsdom')
module.exports = {
  testEnvironment: 'jsdom',
  testEnvironmentOptions: {
    virtualConsole: VirtualConsole,
  },
}

// instead of
const { VirtualConsole } = require('jsdom')
module.exports = {
  testEnvironment: 'jsdom',
  testEnvironmentOptions: {
    virtualConsole: new VirtualConsole(),
  },
}

If you want to use sendTo of the VirtualConsole, you can extend this class to set sendTo after creating an instance.

@SimenB @jeysal Should we add an option for virtualConsole field of testEnvironmentOptions is a function to call in the setup?

@mzedeler
Copy link
Author

mzedeler commented May 5, 2019

I think this exposes a more serious issue with Jest: that the presence or absence of --runInBand changes how testEnvironmentOptions are interpreted. That really shouldn't happen.

@SimenB
Copy link
Member

SimenB commented May 5, 2019

I'd guess the instance is lost when serialising config to the worker. You should create your own test environment instead so it's instantiated inside the worker.

const JsdomEnv = require('jest-environment-jsdom');

module.exports = class MyEnv extends JsdomEnv {
  constructor(config, context) {
    super(
      {
        ...config,
        testEnvironmentOptions: { my: 'things' },
      },
      context,
    );
  }
};

This is written on mobile, so please excuse typos :)

@mzedeler
Copy link
Author

mzedeler commented May 5, 2019

@SimenB - thanks for the suggestion. I wound up stubbing away window.console.(log|warn|error), but I still think that this issue should be addressed. Unfortunately it is a little complicated to reproduce - my repl.it example has suddenly stopped failing where it should have. I think it is because Jest isn't running in parallel with the default settings where it did before.

@SimenB
Copy link
Member

SimenB commented May 5, 2019

The bug here is that it works in run-in-band, btw, so I don't think you'd like the fix 😅 The way parallelized tests work is by running separate processes for them. The only way to communicate between processes is to pass serializable messages (in essence, we do JSON.stringify). This is done on config, so when you do new VirtualConsole, that's not gonna be sent across, leading to the error you're seeing in JSDOM.
Additionally, as probably noted, when you do new something in the config, that instance is shared across all tests, which you probably don't want.

I'll close this as the solution to your issue is to create a custom environment or just stub out console as you noted. We'll address config silently dropping fields as part of #7185

@SimenB @jeysal Should we add an option for virtualConsole field of testEnvironmentOptions is a function to call in the setup?

See above - the solution in this case is a custom env - we currently do not support non-serializable things (like functions) in the config

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.