testing-library/dom-testing-library

Regression: "ReferenceError: global is not defined"

Closed this issue ยท 22 comments

  • @testing-library/dom version: 7.22.6
  • Testing Framework and version: QUnit 2.11.0
  • DOM Environment: Chrome 84.0.4147.135 (via Testem)

Relevant code or config:

import { screen } from "@testing-library/dom";

What you did:

I ran my tests: ember test --server.

What happened:

Tests couldn't be executed, the following error was thrown:

ReferenceError: global is not defined
    at Object../node_modules/pretty-format/build/plugins/AsymmetricMatcher.js (test-support.js:37305)
    at __webpack_require__ (test-support.js:18993)
    at Object../node_modules/pretty-format/build/index.js (test-support.js:36889)
    at __webpack_require__ (test-support.js:18993)
    at Module../node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js (test-support.js:19861)
    at __webpack_require__ (test-support.js:18993)
    at Module.callback (test-support.js:19106)
    at Module.exports (vendor.js:118)
    at Module._reify (vendor.js:155)
    at Module.reify (vendor.js:142)

Reproduction:

Problem description:

@testing-library/dom 7.22.3 was working fine.

@testing-library/dom 7.22.6 doesn't work.

Suggested solution:

I can see there was a bump of pretty-format between 7.22.3 and 7.22.6: 9cbc428, perhaps it's the culprit.

Could you include a minimal repro? There are no references to global in https://unpkg.com/pretty-format@26.4.2/build/index.js but there are some in https://unpkg.com/@testing-library/dom@7.22.6/dist/@testing-library/dom.esm.js.

Though the references in the bundled @testing-library/dom build have been there for a year now. They assume that we either run in a browser (typeof window !== 'undefined') or in node (where global is defined). Though standalone JS engines don't have global. Though we don't actually support standalone JS shells. We do require an environment where setTimeout is implemented. And as far as I can tell all these environments either have global or window.

@eps1lon Of course, here: https://github.com/EvgenyOrekhov/ember-with-testing-library.

It is a freshly-generated Ember app with a single test file: https://github.com/EvgenyOrekhov/ember-with-testing-library/blob/master/tests/integration/components/my-component-test.js.

Importing screen into the test file on line 5 breaks the test suite.

Steps to reproduce:

git clone git@github.com:EvgenyOrekhov/ember-with-testing-library.git
cd ember-with-testing-library
npm install
npm run test:watch

A new Chrome window will open up and throw an error.

Important observation: when I run the tests in CLI mode (using npm test:ember), it works fine. It doesn't work only when the actual browser window is launched. So it looks like it works fine with jsdom, but doesn't work with an actual browser. Is my understanding correct?

It definitely should work with an actual browser (many people are testing with actual browsers). Something else is going on where this is somehow running in an environment that has neither a window nor a global. I think that we could change the code to support such an environment (assuming that it has a global setTimeout and clearTimeout. However, I imagine that this environment would have several other problems as well.

So investigation needs to be made to determine why window and global are not available in this particular environment...

Well, this looks like an actual browser to me :)

image

You can see on the screenshot that I tried it in the console and got the following results:

  • window is defined
  • global is not defined
  • globalThis is defined

I get the same results in my regular Chrome instance that I use for browsing the Internet.

I'm not sure what to tell you ๐Ÿคทโ€โ™‚๏ธ

@eps1lon This is the first file from the stack trace that references global: https://unpkg.com/browse/pretty-format@26.4.2/build/plugins/AsymmetricMatcher.js (line 10).

Thanks. I see the issue and think I know how to solve it. I just want to get the fix right so that we don't regress in the future.

pretty-format caused us quite some trouble in the past since it's part of the jest stack which doesn't work in a browser. So using any package from that stack in a browser is always sketchy because it's untested. But we do want to use it so that the formatting in our library is familiar.

I personally don't have the bandwidth to fix this. Codesandbox, rollup as well as karma do transpile global so that it's safe in a browser. Maybe ember should follow, maybe jest should change.

@eps1lon global is not standard, globalThis is.

Ember uses webpack and Babel under the hood, so it should be able to transpile globalThis if needed, but it doesn't include Node.js polyfills by default.

Were you able to solve this, @eps1lon ?
I just created a react app using nx + react-admin. As soon as i add react-admin it complains about global not defined, and points to that "AsymmetricMatcher.js" plugin.

@Bulletninja This is still the latest status:

I personally don't have the bandwidth to fix this.

this is happening for us in jest27

is there a workaround?

@sibelius If you're using webpack, I believe you can enable node.global polyfill in your webpack config:

module.exports = {
  //...
  node: {
    global: true
  }
};

Reference: https://v4.webpack.js.org/configuration/node/.

this is a problem only when running tests with jest 27

this is happening for us in jest27

Adding this dev dep solves the error for me (jest 27)
"jest-environment-jsdom": "~27.0"

In the Jest 27 release notes, they note the shift from defaulting to jsdom to node for performance reasons. Rather than flipping the setting back, it may be more efficient to set the test environment in inidividual files only when needed ala https://jestjs.io/docs/configuration#testenvironment-string

@cliener even if you set your test environment to jsdom I think you still need jest-environment-jsdom like what @fc1943s mentioned since it's no longer included as a default. The default is node now.

Adding this dev dep solves the error for me (jest 27)
"jest-environment-jsdom": "~27.0"

This solved the problem for me. Big thanks, I worked on this for couple of days, nothing else worked.

Closed by #966

Sorry to comment on closed issue, but I still have the same problem. I'm using wtr and vite. (So, fully esm and browser environment).

This is wtr config. nothing special:

import vite from 'vite-web-test-runner-plugin';
export default {
    nodeResolve: true,
    esbuildTarget: 'auto',
    files: 'src/**/__tests__/**/*.test.js',
    plugins: [
        vite()
    ]
};

This is the stack trace:

ReferenceError: global is not defined
        at ../node_modules/.pnpm/pretty-format@26.6.2/node_modules/pretty-format/build/plugins/AsymmetricMatcher.js (node_modules/.vite/@testing-library_vue.js:11652:19)
        at __require2 (node_modules/.vite/chunk-IHTDASF6.js:17:44)
        at ../node_modules/.pnpm/pretty-format@26.6.2/node_modules/pretty-format/build/index.js (node_modules/.vite/@testing-library_vue.js:12372:53)
        at __require2 (node_modules/.vite/chunk-IHTDASF6.js:17:44)
        at ../node_modules/.pnpm/@testing-library+dom@7.31.2/node_modules/@testing-library/dom/dist/@testing-library/dom.esm.js (node_modules/.vite/@testing-library_vue.js:25879:39)
        at __init (node_modules/.vite/chunk-IHTDASF6.js:14:50)
        at ../node_modules/.pnpm/@testing-library+vue@6.5.0_df3f769d1ea316852686577c1510cc0d/node_modules/@testing-library/vue/dist/render.js (node_modules/.vite/@testing-library_vue.js:27069:17)
        at __require2 (node_modules/.vite/chunk-IHTDASF6.js:17:44)
        at ../node_modules/.pnpm/@testing-library+vue@6.5.0_df3f769d1ea316852686577c1510cc0d/node_modules/@testing-library/vue/dist/index.js (node_modules/.vite/@testing-library_vue.js:27329:19)
        at __require2 (node_modules/.vite/chunk-IHTDASF6.js:17:44)

This issue is fixed in pretty-format@27.4.2 - may have been fixed in an earlier version. I don't know which version of @testing-library/dom this dependency was first fixed in, but it's fixed in 8.11.1.