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

globalThis is not the same as self when using jsdom #1146

Closed
6 tasks done
nknapp opened this issue Apr 12, 2022 · 7 comments · Fixed by #1256
Closed
6 tasks done

globalThis is not the same as self when using jsdom #1146

nknapp opened this issue Apr 12, 2022 · 7 comments · Fixed by #1256

Comments

@nknapp
Copy link

nknapp commented Apr 12, 2022

Describe the bug

Observation

When testing react-components, you have to make sure that component-state changes are wrapped in an act() function call, otherwise the warning Warning: An update to App inside a test was not wrapped in act(...). will be displayed.

In the normal create-react-app setup, this warning is disabled when the code is currently running inside the waitFor function of @testing-library/react.

The same test, run with vitest shows the warning again.

Expectation

My expectation is that no warning is shown.

Analysis

I figured out that @testing-library/react sets self.IS_REACT_ACT_ENVIRONMENT to false, while react accesses IS_REACT_ACT_ENVIRONMENT directly to determine, whether to the warning or not.

In jsdom-environment ofvitest, self and globalThis seem to be different object, so setting self.IS_REACT_ACT_ENVIRONMENT does not disable the warnings.

When I run the same test with react-scripts test (i.e. in jest), they are the same

Expectation

self and globalThis should be the same object.

Reproduction

I created the repository https://github.com/nknapp/vitest-react-18-testing-library-missing-act-workaround to reproduce the error.

  1. Setup dependencies

    yarn 
    
  2. Run the test with jest, no warning will appear

    yarn test
    
  3. Run the test with vitest, there will be a warning

    yarn vitest
    
  4. Open src/setupVitest.js and remove the comments from the workaround-code.
    The run yarn vitest again. No warning will appear

    The workaround defines IS_REACT_ACT_ENVIRONMENT as property that proxies its value to self.IS_REACT_ACT_ENVIRONMENT, so that the deactivation works correctly.

System Info

System:
    OS: Linux 5.4 Ubuntu 20.04.4 LTS (Focal Fossa)
    CPU: (4) x64 Intel(R) Core(TM) i7-3687U CPU @ 2.10GHz
    Memory: 2.73 GB / 15.51 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 16.13.0 - ~/.nvm/versions/node/v16.13.0/bin/node
    Yarn: 1.22.15 - ~/.nvm/versions/node/v16.13.0/bin/yarn
    npm: 8.1.0 - ~/.nvm/versions/node/v16.13.0/bin/npm
  Browsers:
    Brave Browser: 99.1.36.122
    Chrome: 99.0.4844.84
    Firefox: 99.0

Used Package Manager

yarn

Validations

@lukebelliveau
Copy link

I had a similar issue - it seemed the only way I could get the warning to go away was putting globalThis.IS_REACT_ACT_ENVIRONMENT = true in the actual *.test.ts file.

After much trial & error, here's what worked for me:

vitest.config.ts

import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";

export default defineConfig({
  plugins: [react()],
  test: {
    environment: "jsdom",
    setupFiles: "./testSetup.ts",
  },
});

testSetup.ts

globalThis.IS_REACT_ACT_ENVIRONMENT = true;

@sheremet-va
Copy link
Member

sheremet-va commented May 1, 2022

I think this is a bug in testing-library. Our current approach doesn't allow globalThis == global == self, unfortunately.

If they are putting a property on a global object that is read somewhere else, then the function to get the globalThis should be compatible in both reading/writing code.

@eps1lon
Copy link

eps1lon commented May 7, 2022

If they are putting a property on a global object that is read somewhere else, then the function to get the globalThis should be compatible in both reading/writing code.

What does "properly" mean here?

The way we're doing it, does match the globalThis polyfill.

@sheremet-va
Copy link
Member

sheremet-va commented May 7, 2022

If they are putting a property on a global object that is read somewhere else, then the function to get the globalThis should be compatible in both reading/writing code.

What does "properly" mean here?

The way we're doing it, does match the globalThis polyfill.

I wrote “property”. What I mean is it should write the same way it is read inside react (I haven’t check how it is read).

Also, MDN’s polyfill doesn't check for existing “globalThis”, assuming it is always undefined, which is in my opinion incorrect behaviour. If you a polyfilling something, you should first check if you need to.

@eps1lon
Copy link

eps1lon commented May 7, 2022

I wrote “property”. What I mean is it should write the same way it is read inside react (I haven’t check how it is read).

React just reads it with IS_REACT_ACT_ENVIRONMENT. But you can't write that way so you have to polyfill globalThis.

We can check for globalThis first but that still leaves vitest with with incorret behavior for how one writes global variables.

@Lynne42
Copy link

Lynne42 commented May 7, 2022

version:
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.2.0",
"react": "^18.1.0",
"react-dom": "^18.1.0",

Setting globalThis.IS_REACT_ACT_ENVIRONMENT = true in the jest.setup.js file does not work. On the contrary, the test runs continuously after the setting, repeating the problem of act()

image

@sheremet-va
Copy link
Member

This is a separate problem. See #1242

@github-actions github-actions bot locked and limited conversation to collaborators Jun 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants