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 console is unmockable #5223

Closed
kentcdodds opened this issue Jan 3, 2018 · 6 comments

Comments

@kentcdodds
Copy link
Contributor

commented Jan 3, 2018

Do you want to request a feature or report a bug?

Feature. React@16 made some changes that cause this issue.

What is the current behavior?

It's impossible to mock the console used by JSDOM. This is a problem because react-dom uses the browser to dispatch an event:

https://github.com/facebook/react/blob/46b3c3e4ae0d52565f7ed2344036a22016781ca0/packages/shared/invokeGuardedCallback.js#L137-L147

They do this

To preserve the expected "Pause on exceptions" behavior

It's kind of interesting actually. See the comments above the linked code.

But because of this, an error thrown in this way gets logged by JSDOM's VirtualConsole which is initialized in a different environment from my tests. This means it's impossible for me to mock it for an individual test.

That said, I can provide my own stub for JSDOM's VirtualConsole, but that will stub it for all tests which could lead to me missing legitimate errors being logged. Also, I can't make any assertions for my stub of VirtualConsole.

If the current behavior is a bug, please provide the steps to reproduce and
either a repl.it demo through https://repl.it/languages/jest or a minimal
repository on GitHub that we can yarn install and yarn test.

Here's a repo: https://github.com/kentcdodds/jest-jsdom-react-console-issues

  • npm/yarn install
  • npm run test:1
  • npm run test:2

The test:2 script uses the jest.custom-config.js config which provides the stub of VirtualConsole and you'll see it's not a problem in that situation, but I have the aforementioned problems.

What is the expected behavior?

I would like the console used to initialize JSDOM's VirtualConsole to be the same one that I have access to in my test so I can mock it.

Please provide your exact Jest configuration and mention your Jest, node,
yarn/npm version and operating system.

See the repo above.

Thanks!

@kentcdodds

This comment has been minimized.

Copy link
Contributor Author

commented Jan 3, 2018

I've done a little more digging, and I'll open a quick and dirty PR to get some feedback on to address this 👍

@kentcdodds

This comment has been minimized.

Copy link
Contributor Author

commented Jan 4, 2018

PR Opened: #5227

@gaearon

This comment has been minimized.

Copy link
Member

commented Jan 5, 2018

Could you do this?

window.addEventListener('error', e => {
  // I want to silence all errors and know what I'm doing
  e.preventDefault();
});

It doesn't solve React printing an error as a warning but you could either override console.error and ignore it or help us fix it: facebook/react#11098 (comment)

@kentcdodds

This comment has been minimized.

Copy link
Contributor Author

commented Jan 5, 2018

Hmm... I'll give that a look. That may help with the double-error issue (different but related issue) I'm seeing. Thanks!

@lamhieu-vk

This comment has been minimized.

Copy link
Contributor

commented May 4, 2019

@kentcdodds I detailed this problem at #8393 (comment)

@mzedeler

This comment has been minimized.

Copy link

commented May 5, 2019

I fixed this by not playing around with the virtualConsole option because it seems to be inconsistent depending on whether Jest runs in parallel or not, but just this:

  beforeEach(() => {
    ['log', 'warn', 'error'].forEach((type) => {
      origConsole[type] = window.console[type]
      window.console[type] = jest.fn()
    })
  })

  afterEach(() => {
    ['log', 'warn', 'error'].forEach((type) => {
      window.console[type] = origConsole[type]
    })
  })

Then, in the tests, you can do stuff like expect(window.console.error).toHaveBeenCalled() and so on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.