Repository: wix/Detox
Pull request #2812 (2021-05-31 07:20:00)

hotfix(jest): compatibility with jest@^27.0.0
## Description

- This pull request addresses the issue described here: #2811

1. Using a low-level module resolution (via extra `path.join`) to extract `jest-cli` args.
2. Using `Symbol.for` for resolving internal RETRY_TIMES symbol to avoid another similar import error.
3. Updated `detox/test` project to Jest 27 (removed explicit jest-circus `devDependency` appropriately).

Also, for similar cases in the future, I added a more human-readable error, e.g.:

```
➜  test git:(hotfix/jest-27) ✗ npx detox test -c ios.sim.release

detox[18506] ERROR: [cli.js] Could not parse CLI arguments supported by "jest-cli" package, see the error below.
detox[18506] ERROR: [cli.js]
detox[18506] ERROR: [cli.js] HINT: Consider reporting this as an issue at: https://github.com/wix/Detox/issues
detox[18506] ERROR: [cli.js]
detox[18506] ERROR: [cli.js] Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath './build/cli/args' is not defined by "exports" in /Users/.../myapp/node_modules/jest-cli/package.json
detox[18506] ERROR: [cli.js]     at new NodeError (node:internal/errors:363:5)
detox[18506] ERROR: [cli.js]     at throwExportsNotFound (node:internal/modules/esm/resolve:321:9)
detox[18506] ERROR: [cli.js]     at packageExportsResolve (node:internal/modules/esm/resolve:546:3)
detox[18506] ERROR: [cli.js]     at resolveExports (node:internal/modules/cjs/loader:478:36)
detox[18506] ERROR: [cli.js]     at Function.Module._findPath (node:internal/modules/cjs/loader:518:31)
detox[18506] ERROR: [cli.js]     at Function.Module._resolveFilename (node:internal/modules/cjs/loader:927:27)
detox[18506] ERROR: [cli.js]     at resolveFileName (/Users/.../myapp/node_modules/resolve-from/index.js:29:39)
detox[18506] ERROR: [cli.js]     at resolveFrom (/Users/.../myapp/node_modules/resolve-from/index.js:43:9)
detox[18506] ERROR: [cli.js]     at module.exports (/Users/.../myapp/node_modules/resolve-from/index.js:46:47)
detox[18506] ERROR: [cli.js]     at resolveJestCliArgs (/Users/.../myapp/node_modules/detox/local-cli/utils/splitArgv.js:96:18)
detox[18506] ERROR: [cli.js]     at getJestBooleanArgs (/Users/.../myapp/node_modules/detox/local-cli/utils/splitArgv.js:56:12)
detox[18506] ERROR: [cli.js]     at Object.splitJestArgv [as jest] (/Users/.../myapp/node_modules/detox/local-cli/utils/splitArgv.js:120:53)
detox[18506] ERROR: [cli.js]     at prepareJestArgs (/Users/.../myapp/node_modules/detox/local-cli/test.js:156:44)
detox[18506] ERROR: [cli.js]     at Object.test [as handler] (/Users/.../myapp/node_modules/detox/local-cli/test.js:33:25)
detox[18506] ERROR: [cli.js]     at processTicksAndRejections (node:internal/process/task_queues:96:5)
```


Patch:
diff --git a/detox/local-cli/utils/splitArgv.js b/detox/local-cli/utils/splitArgv.js
index af8c5039c..53be1c5b5 100644
--- a/detox/local-cli/utils/splitArgv.js
+++ b/detox/local-cli/utils/splitArgv.js
@@ -93,7 +93,18 @@ function resolveJestCliArgs() {
     });
   }
 
-  return require(resolveFrom(jestLocation, 'jest-cli/build/cli/args'));
+  try {
+    const jestCliManifest = resolveFrom(jestLocation, 'jest-cli/package.json');
+    const argsJsFile = path.join(path.dirname(jestCliManifest), 'build/cli/args.js');
+
+    return require(argsJsFile);
+  } catch (e) {
+    throw new DetoxRuntimeError({
+      message: 'Could not parse CLI arguments supported by "jest-cli" package, see the error below.',
+      hint: 'Consider reporting this as an issue at: https://github.com/wix/Detox/issues',
+      debugInfo: e,
+    });
+  }
 }
 
 function splitDetoxArgv(argv) {
diff --git a/detox/package.json b/detox/package.json
index 60d78a83d..177d20dbc 100644
--- a/detox/package.json
+++ b/detox/package.json
@@ -36,9 +36,8 @@
     "eslint-plugin-import": "^2.23.3",
     "eslint-plugin-no-only-tests": "^2.6.0",
     "eslint-plugin-node": "^6.0.1",
-    "jest": "^26.5.0",
-    "jest-circus": "^26.5.2",
-    "jest-environment-node": "^26.5.0",
+    "jest": "^27.0.0",
+    "jest-environment-node": "^27.0.0",
     "mocha": ">=6.0.0",
     "mockdate": "^2.0.1",
     "prettier": "1.7.0",
diff --git a/detox/runners/jest-circus/listeners/DetoxCoreListener.js b/detox/runners/jest-circus/listeners/DetoxCoreListener.js
index 69c38b3e6..75b331bfa 100644
--- a/detox/runners/jest-circus/listeners/DetoxCoreListener.js
+++ b/detox/runners/jest-circus/listeners/DetoxCoreListener.js
@@ -1,4 +1,3 @@
-const { RETRY_TIMES } = require('jest-circus/build/types');
 const _ = require('lodash');
 
 const {
@@ -11,6 +10,8 @@ const {
 } = require('../../integration').lifecycle;
 const { getFullTestName, hasTimedOut } = require('../../jest/utils');
 
+const RETRY_TIMES = Symbol.for('RETRY_TIMES');
+
 class DetoxCoreListener {
   constructor({ detox, env }) {
     this._startedTests = new WeakSet();


Test patch:
diff --git a/detox/test/package.json b/detox/test/package.json
index 46c0ed29e..784862c6c 100644
--- a/detox/test/package.json
+++ b/detox/test/package.json
@@ -42,8 +42,7 @@
     "detox": "^18.15.0",
     "dtslint": "^4.0.6",
     "express": "^4.15.3",
-    "jest": "^26.5.0",
-    "jest-circus": "^26.5.2",
+    "jest": "^27.0.0",
     "jest-junit": "^10.0.0",
     "lodash": "^4.14.1",
     "metro-react-native-babel-preset": "^0.64.0",