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

The current version of jest-enzyme breaks the latest version of jest #351

Open
GreenGremlin opened this issue Oct 16, 2020 · 6 comments
Open

Comments

@GreenGremlin
Copy link
Contributor

GreenGremlin commented Oct 16, 2020

I just setup jest-enzyme in a package running jest 26 and ended up with a bunch of jest 24 packages. I'm now getting typescript errors for jest being undefined, which I assume is caused by incompatible versions of jest being installed. This appears to be caused by jest-enzyme's version pin for jest-environment-jsdom v24. The jest-environment-jsdom package appears to only be used in one place, ideally the latest version of jest-enzyme would support the latest two or three jest releases.

@GreenGremlin
Copy link
Contributor Author

Here's a diff of jest-environment-jsdom between v24.9.0 and v26.5.2, if that's helpful.

diff --git a/packages/jest-environment-jsdom/src/index.ts b/packages/jest-environment-jsdom/src/index.ts
index 5e362f9244..bdd5eec277 100644
--- a/packages/jest-environment-jsdom/src/index.ts
+++ b/packages/jest-environment-jsdom/src/index.ts
@@ -5,12 +5,12 @@
  * LICENSE file in the root directory of this source tree.
  */

-import {Script} from 'vm';
-import {Global, Config} from '@jest/types';
+import type {Context, Script} from 'vm';
+import type {Config, Global} from '@jest/types';
 import {installCommonGlobals} from 'jest-util';
-import mock, {ModuleMocker} from 'jest-mock';
-import {JestFakeTimers as FakeTimers} from '@jest/fake-timers';
-import {JestEnvironment, EnvironmentContext} from '@jest/environment';
+import {ModuleMocker} from 'jest-mock';
+import {LegacyFakeTimers, ModernFakeTimers} from '@jest/fake-timers';
+import type {EnvironmentContext, JestEnvironment} from '@jest/environment';
 import {JSDOM, VirtualConsole} from 'jsdom';

 // The `Window` interface does not have an `Error.stackTraceLimit` property, but
@@ -24,7 +24,8 @@ type Win = Window &

 class JSDOMEnvironment implements JestEnvironment {
   dom: JSDOM | null;
-  fakeTimers: FakeTimers<number> | null;
+  fakeTimers: LegacyFakeTimers<number> | null;
+  fakeTimersModern: ModernFakeTimers | null;
   global: Win;
   errorEventListener: ((event: Event & {error: Error}) => void) | null;
   moduleMocker: ModuleMocker | null;
@@ -37,12 +38,17 @@ class JSDOMEnvironment implements JestEnvironment {
       virtualConsole: new VirtualConsole().sendTo(options.console || console),
       ...config.testEnvironmentOptions,
     });
-    const global = (this.global = this.dom.window.document.defaultView as Win);
+    const global = (this.global = (this.dom.window.document
+      .defaultView as unknown) as Win);

     if (!global) {
       throw new Error('JSDOM did not return a Window object');
     }

+    // In the `jsdom@16`, ArrayBuffer was not added to Window, ref: https://github.com/jsdom/jsdom/commit/3a4fd6258e6b13e9cf8341ddba60a06b9b5c7b5b
+    // Install ArrayBuffer to Window to fix it. Make sure the test is passed, ref: https://github.com/facebook/jest/pull/7626
+    global.ArrayBuffer = ArrayBuffer;
+
     // Node's error-message stack size is limited at 10, but it's pretty useful
     // to see more than that when a test fails.
     this.global.Error.stackTraceLimit = 100;
@@ -61,7 +67,7 @@ class JSDOMEnvironment implements JestEnvironment {
     const originalAddListener = global.addEventListener;
     const originalRemoveListener = global.removeEventListener;
     let userErrorListenerCount = 0;
-    global.addEventListener = function(
+    global.addEventListener = function (
       ...args: Parameters<typeof originalAddListener>
     ) {
       if (args[0] === 'error') {
@@ -69,7 +75,7 @@ class JSDOMEnvironment implements JestEnvironment {
       }
       return originalAddListener.apply(this, args);
     };
-    global.removeEventListener = function(
+    global.removeEventListener = function (
       ...args: Parameters<typeof originalRemoveListener>
     ) {
       if (args[0] === 'error') {
@@ -78,29 +84,32 @@ class JSDOMEnvironment implements JestEnvironment {
       return originalRemoveListener.apply(this, args);
     };

-    this.moduleMocker = new mock.ModuleMocker(global as any);
+    this.moduleMocker = new ModuleMocker(global as any);

     const timerConfig = {
       idToRef: (id: number) => id,
       refToId: (ref: number) => ref,
     };

-    this.fakeTimers = new FakeTimers({
+    this.fakeTimers = new LegacyFakeTimers({
       config,
-      global: global as any,
+      global,
       moduleMocker: this.moduleMocker,
       timerConfig,
     });
-  }

-  setup() {
-    return Promise.resolve();
+    this.fakeTimersModern = new ModernFakeTimers({config, global});
   }

-  teardown() {
+  async setup(): Promise<void> {}
+
+  async teardown(): Promise<void> {
     if (this.fakeTimers) {
       this.fakeTimers.dispose();
     }
+    if (this.fakeTimersModern) {
+      this.fakeTimersModern.dispose();
+    }
     if (this.global) {
       if (this.errorEventListener) {
         this.global.removeEventListener('error', this.errorEventListener);
@@ -110,16 +119,23 @@ class JSDOMEnvironment implements JestEnvironment {
       this.global.close();
     }
     this.errorEventListener = null;
-    // @ts-ignore
+    // @ts-expect-error
     this.global = null;
     this.dom = null;
     this.fakeTimers = null;
-    return Promise.resolve();
+    this.fakeTimersModern = null;
+  }
+
+  runScript<T = unknown>(script: Script): T | null {
+    if (this.dom) {
+      return script.runInContext(this.dom.getInternalVMContext());
+    }
+    return null;
   }

-  runScript(script: Script) {
+  getVmContext(): Context | null {
     if (this.dom) {
-      return this.dom.runVMScript(script) as any;
+      return this.dom.getInternalVMContext();
     }
     return null;
   }

@valen22br
Copy link

Yes, I'm trying to run jest-environment-enzyme package with Jest 27.0.3, and it's breaking my tests.
I did the upgrade of jest-environment-jsdom inside package.json, and it is working.

Will this package be upgraded, or if not, what should we use instead?

@csalvato
Copy link

I did the upgrade of jest-environment-jsdom inside package.json, and it is working.

@valen22br how did you do this? Upgrading these packages independently didn't work for me, but I have a feeling you are doing something a bit more advanced.

@jamiegluk
Copy link

I did the upgrade of jest-environment-jsdom inside package.json, and it is working.

@valen22br how did you do this? Upgrading these packages independently didn't work for me, but I have a feeling you are doing something a bit more advanced.

You can manually edit your lockfile, that'll work, but the better way to do it is via resolutions, if you are using Yarn; add this to your package.json:

  "resolutions": {
    "jest-environment-jsdom": "27.3.1"
  },

You can also do this in classic NPM using the npm-force-resolutions package.

@StephenGrable1
Copy link

@jamiegluk ^ was encountering issues as well and this resolution block fixed it for me 🙏

Morpheu5 added a commit to isaacphysics/isaac-react-app that referenced this issue Feb 3, 2022
There is a bug between enzyme (https://stackoverflow.com/a/70943283/554491) and jest-enzyme (enzymejs/enzyme-matchers#351) so we need to force a certain version of an apparently unrelated page (jest-environment-jsdom, of course) and force npm to resolve to that version, which is done through the resolutions key in package.json and the npm-force-resolutions package (yarn wouldn't need it but hey, we're using npm).
@haixiangyan
Copy link

npm i -D jest-environment-jsdom@^27 could help

sjbarag added a commit to sjbarag/cockroach that referenced this issue Mar 14, 2022
Jest before v27 didn't support configuration options that allow test
files to be discovered across symlink boundaries, which is necessary
when running Jest tests within a Bazel sandbox. Upgrade Jest and its
dependencies (including a manual version resolution of
jest-environment-jsdom [1] defined in pkg/ui/package.json to avoid Jest
bugs [2]) to enable cluster-ui tests being run via Bazel.

[1] enzymejs/enzyme-matchers#351 (comment)
[2] yarnpkg/yarn#5039

Release justification: Upgrade of test dependencies
Release note: None
sjbarag added a commit to sjbarag/cockroach that referenced this issue Mar 15, 2022
Jest before v27 didn't support configuration options that allow test
files to be discovered across symlink boundaries, which is necessary
when running Jest tests within a Bazel sandbox. Upgrade Jest and its
dependencies (including a manual version resolution of
jest-environment-jsdom [1] defined in pkg/ui/package.json to avoid Jest
bugs [2]) to enable cluster-ui tests being run via Bazel.

[1] enzymejs/enzyme-matchers#351 (comment)
[2] yarnpkg/yarn#5039

Release justification: Upgrade of test dependencies
Release note: None
sjbarag added a commit to sjbarag/cockroach that referenced this issue Mar 22, 2022
Jest before v27 didn't support configuration options that allow test
files to be discovered across symlink boundaries, which is necessary
when running Jest tests within a Bazel sandbox. Upgrade Jest and its
dependencies (including a manual version resolution of
jest-environment-jsdom [1] defined in pkg/ui/package.json to avoid Jest
bugs [2]) to enable cluster-ui tests being run via Bazel.

[1] enzymejs/enzyme-matchers#351 (comment)
[2] yarnpkg/yarn#5039

Release justification: Upgrade of test dependencies
Release note: None
sjbarag added a commit to sjbarag/cockroach that referenced this issue Mar 23, 2022
Jest before v27 didn't support configuration options that allow test
files to be discovered across symlink boundaries, which is necessary
when running Jest tests within a Bazel sandbox. Upgrade Jest and its
dependencies (including a manual version resolution of
jest-environment-jsdom [1] defined in pkg/ui/package.json to avoid Jest
bugs [2]) to enable cluster-ui tests being run via Bazel.

[1] enzymejs/enzyme-matchers#351 (comment)
[2] yarnpkg/yarn#5039

Release justification: Upgrade of test dependencies
Release note: None
rickystewart pushed a commit to rickystewart/cockroach that referenced this issue Mar 31, 2022
Jest before v27 didn't support configuration options that allow test
files to be discovered across symlink boundaries, which is necessary
when running Jest tests within a Bazel sandbox. Upgrade Jest and its
dependencies (including a manual version resolution of
jest-environment-jsdom [1] defined in pkg/ui/package.json to avoid Jest
bugs [2]) to enable cluster-ui tests being run via Bazel.

[1] enzymejs/enzyme-matchers#351 (comment)
[2] yarnpkg/yarn#5039

Release justification: Upgrade of test dependencies
Release note: None
fqazi pushed a commit to fqazi/cockroach that referenced this issue Apr 4, 2022
Jest before v27 didn't support configuration options that allow test
files to be discovered across symlink boundaries, which is necessary
when running Jest tests within a Bazel sandbox. Upgrade Jest and its
dependencies (including a manual version resolution of
jest-environment-jsdom [1] defined in pkg/ui/package.json to avoid Jest
bugs [2]) to enable cluster-ui tests being run via Bazel.

[1] enzymejs/enzyme-matchers#351 (comment)
[2] yarnpkg/yarn#5039

Release justification: Upgrade of test dependencies
Release note: None
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants