detox 20.14.0-smoke.0 → 20.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. package/.eslintignore +1 -0
  2. package/Detox-android/com/wix/detox/{20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar → 20.14.0/detox-20.14.0-javadoc.jar} +0 -0
  3. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0-javadoc.jar.md5 +1 -0
  4. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0-javadoc.jar.sha1 +1 -0
  5. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0-javadoc.jar.sha256 +1 -0
  6. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0-javadoc.jar.sha512 +1 -0
  7. package/Detox-android/com/wix/detox/{20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar → 20.14.0/detox-20.14.0-sources.jar} +0 -0
  8. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0-sources.jar.md5 +1 -0
  9. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0-sources.jar.sha1 +1 -0
  10. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0-sources.jar.sha256 +1 -0
  11. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0-sources.jar.sha512 +1 -0
  12. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0.aar +0 -0
  13. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0.aar.md5 +1 -0
  14. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0.aar.sha1 +1 -0
  15. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0.aar.sha256 +1 -0
  16. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0.aar.sha512 +1 -0
  17. package/Detox-android/com/wix/detox/{20.14.0-smoke.0/detox-20.14.0-smoke.0.pom → 20.14.0/detox-20.14.0.pom} +1 -1
  18. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0.pom.md5 +1 -0
  19. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0.pom.sha1 +1 -0
  20. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0.pom.sha256 +1 -0
  21. package/Detox-android/com/wix/detox/20.14.0/detox-20.14.0.pom.sha512 +1 -0
  22. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  26. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  27. package/Detox-ios-src.tbz +0 -0
  28. package/Detox-ios.tbz +0 -0
  29. package/android/detox/build.gradle +8 -4
  30. package/android/detox/src/full/java/com/wix/detox/Detox.java +1 -7
  31. package/android/detox/src/full/java/com/wix/detox/DetoxMain.kt +55 -72
  32. package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxActionHandlers.kt +0 -15
  33. package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxActionsDispatcher.kt +16 -6
  34. package/android/detox/src/full/java/com/wix/detox/adapters/server/DetoxServerAdapter.kt +0 -2
  35. package/android/detox/src/full/java/com/wix/detox/espresso/web/WebElement.java +4 -4
  36. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeExtension.kt +0 -14
  37. package/android/detox/src/full/java/com/wix/invoke/types/Invocation.java +2 -2
  38. package/android/detox/src/main/java/com/wix/detox/espresso/action/common/MotionEvents.kt +60 -4
  39. package/android/detox/src/testFull/java/com/wix/invoke/JsonParserTest.java +23 -7
  40. package/android/detox/src/testFull/resources/targetInvocationEspressoWebDetoxScript.json +47 -0
  41. package/detox.d.ts +1830 -0
  42. package/globals.d.ts +23 -0
  43. package/index.d.ts +2 -1838
  44. package/internals.d.ts +2 -1
  45. package/jest.config.js +108 -0
  46. package/local-cli/testCommand/TestRunnerCommand.js +26 -3
  47. package/local-cli/utils/interruptListeners.js +15 -0
  48. package/package.json +3 -99
  49. package/runners/jest/reporter.js +21 -1
  50. package/runners/jest/reporters/DetoxIPCReporter.js +34 -0
  51. package/runners/jest/reporters/DetoxReporterDispatcher.js +144 -0
  52. package/runners/jest/reporters/DetoxSummaryReporter.js +16 -0
  53. package/runners/jest/reporters/DetoxVerboseReporter.js +16 -0
  54. package/runners/jest/reporters/index.js +6 -0
  55. package/runners/jest/testEnvironment/index.js +7 -1
  56. package/src/android/core/WebElement.js +24 -6
  57. package/src/android/espressoapi/web/WebElement.js +1 -4
  58. package/src/configuration/composeRunnerConfig.js +3 -1
  59. package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +3 -5
  60. package/src/devices/allocation/factories/ios.js +1 -4
  61. package/src/devices/common/drivers/android/tools/instrumentationArgs.js +7 -1
  62. package/src/devices/runtime/drivers/ios/SimulatorDriver.js +5 -4
  63. package/src/devices/runtime/factories/ios.js +0 -2
  64. package/src/ipc/IPCClient.js +2 -2
  65. package/src/ipc/IPCServer.js +5 -3
  66. package/src/realms/DetoxContext.js +1 -1
  67. package/src/realms/DetoxPrimaryContext.js +2 -2
  68. package/src/realms/DetoxSecondaryContext.js +2 -2
  69. package/src/utils/assertIsFunction.js +35 -0
  70. package/src/utils/isArrowFunction.js +24 -0
  71. package/tsconfig.json +3 -0
  72. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar.md5 +0 -1
  73. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar.sha1 +0 -1
  74. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar.sha256 +0 -1
  75. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-javadoc.jar.sha512 +0 -1
  76. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar.md5 +0 -1
  77. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar.sha1 +0 -1
  78. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar.sha256 +0 -1
  79. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0-sources.jar.sha512 +0 -1
  80. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar +0 -0
  81. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar.md5 +0 -1
  82. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar.sha1 +0 -1
  83. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar.sha256 +0 -1
  84. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.aar.sha512 +0 -1
  85. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.pom.md5 +0 -1
  86. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.pom.sha1 +0 -1
  87. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.pom.sha256 +0 -1
  88. package/Detox-android/com/wix/detox/20.14.0-smoke.0/detox-20.14.0-smoke.0.pom.sha512 +0 -1
  89. package/runners/jest/reporters/DetoxReporter.js +0 -154
  90. package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +0 -25
@@ -32,6 +32,7 @@ function composeRunnerConfig(opts) {
32
32
  retries: 0,
33
33
  inspectBrk: inspectBrkHookDefault,
34
34
  forwardEnv: false,
35
+ detached: false,
35
36
  bail: false,
36
37
  jest: {
37
38
  setupTimeout: 300000,
@@ -56,8 +57,9 @@ function composeRunnerConfig(opts) {
56
57
 
57
58
  if (typeof merged.inspectBrk === 'function') {
58
59
  if (cliConfig.inspectBrk) {
59
- merged.retries = 0;
60
+ merged.detached = false;
60
61
  merged.forwardEnv = true;
62
+ merged.retries = 0;
61
63
  merged.inspectBrk(merged);
62
64
  }
63
65
 
@@ -20,12 +20,10 @@ class SimulatorAllocDriver {
20
20
  * @param {import('../../DeviceRegistry')} options.deviceRegistry
21
21
  * @param {DetoxInternals.RuntimeConfig} options.detoxConfig
22
22
  * @param {import('../../../common/drivers/ios/tools/AppleSimUtils')} options.applesimutils
23
- * @param {import('./SimulatorLauncher')} options.simulatorLauncher
24
23
  */
25
- constructor({ detoxConfig, deviceRegistry, applesimutils, simulatorLauncher }) {
24
+ constructor({ detoxConfig, deviceRegistry, applesimutils }) {
26
25
  this._deviceRegistry = deviceRegistry;
27
26
  this._applesimutils = applesimutils;
28
- this._simulatorLauncher = simulatorLauncher;
29
27
  this._launchInfo = {};
30
28
  this._shouldShutdown = detoxConfig.behavior.cleanup.shutdownDevice;
31
29
  }
@@ -61,7 +59,7 @@ class SimulatorAllocDriver {
61
59
  async postAllocate(deviceCookie) {
62
60
  const { udid } = deviceCookie;
63
61
  const { deviceConfig } = this._launchInfo[udid];
64
- await this._simulatorLauncher.launch(udid, deviceConfig.type, deviceConfig.bootArgs, deviceConfig.headless);
62
+ await this._applesimutils.boot(udid, deviceConfig.bootArgs, deviceConfig.headless);
65
63
 
66
64
  return {
67
65
  id: udid,
@@ -105,7 +103,7 @@ class SimulatorAllocDriver {
105
103
  */
106
104
  async _doShutdown(udid) {
107
105
  try {
108
- await this._simulatorLauncher.shutdown(udid);
106
+ await this._applesimutils.shutdown(udid);
109
107
  } catch (err) {
110
108
  log.warn({ err }, `Failed to shutdown simulator ${udid}`);
111
109
  }
@@ -9,11 +9,8 @@ class IosSimulator extends DeviceAllocatorFactory {
9
9
  const DeviceRegistry = require('../../../devices/allocation/DeviceRegistry');
10
10
  const deviceRegistry = new DeviceRegistry({ sessionId: detoxSession.id });
11
11
 
12
- const SimulatorLauncher = require('../drivers/ios/SimulatorLauncher');
13
- const simulatorLauncher = new SimulatorLauncher({ applesimutils, eventEmitter });
14
-
15
12
  const SimulatorAllocDriver = require('../drivers/ios/SimulatorAllocDriver');
16
- return new SimulatorAllocDriver({ detoxConfig, deviceRegistry, applesimutils, simulatorLauncher });
13
+ return new SimulatorAllocDriver({ detoxConfig, deviceRegistry, applesimutils });
17
14
  }
18
15
  }
19
16
 
@@ -1,6 +1,7 @@
1
1
  const _ = require('lodash');
2
2
 
3
3
  const { encodeBase64 } = require('../../../../../utils/encoding');
4
+ const { autoEscape } = require('../../../../../utils/shellUtils');
4
5
 
5
6
  const reservedInstrumentationArgs = new Set(['class', 'package', 'func', 'unit', 'size', 'perf', 'debug', 'log', 'emma', 'coverageFile']);
6
7
  const isReservedInstrumentationArg = (arg) => reservedInstrumentationArgs.has(arg);
@@ -17,7 +18,8 @@ function prepareInstrumentationArgs(args) {
17
18
  valueEncoded = encodeBase64(valueAsString);
18
19
  }
19
20
 
20
- result.push('-e', key, valueEncoded);
21
+ const valueEscaped = hasLegacyIssues(key) ? valueEncoded : autoEscape.shell(valueEncoded);
22
+ result.push('-e', key, valueEscaped);
21
23
  return result;
22
24
  }, []);
23
25
 
@@ -27,6 +29,10 @@ function prepareInstrumentationArgs(args) {
27
29
  };
28
30
  }
29
31
 
32
+ function hasLegacyIssues(key) {
33
+ return key === 'detoxURLBlacklistRegex';
34
+ }
35
+
30
36
  module.exports = {
31
37
  prepareInstrumentationArgs,
32
38
  };
@@ -14,7 +14,6 @@ const IosDriver = require('./IosDriver');
14
14
 
15
15
  /**
16
16
  * @typedef SimulatorDriverDeps { DeviceDriverDeps }
17
- * @property simulatorLauncher { SimulatorLauncher }
18
17
  * @property applesimutils { AppleSimUtils }
19
18
  */
20
19
 
@@ -38,7 +37,6 @@ class SimulatorDriver extends IosDriver {
38
37
  this._bootArgs = bootArgs;
39
38
  this._headless = headless;
40
39
  this._deviceName = `${udid} (${this._type})`;
41
- this._simulatorLauncher = deps.simulatorLauncher;
42
40
  this._applesimutils = deps.applesimutils;
43
41
  }
44
42
 
@@ -150,9 +148,12 @@ class SimulatorDriver extends IosDriver {
150
148
  }
151
149
 
152
150
  async resetContentAndSettings() {
153
- await this._simulatorLauncher.shutdown(this.udid);
151
+ await this.emitter.emit('beforeShutdownDevice', { deviceId: this.udid });
152
+ await this._applesimutils.shutdown(this.udid);
153
+ await this.emitter.emit('shutdownDevice', { deviceId: this.udid });
154
154
  await this._applesimutils.resetContentAndSettings(this.udid);
155
- await this._simulatorLauncher.launch(this.udid, this._type, this._bootArgs, this._headless);
155
+ await this._applesimutils.boot(this.udid, this._bootArgs, this._headless);
156
+ await this.emitter.emit('bootDevice', { deviceId: this.udid });
156
157
  }
157
158
 
158
159
  getLogsPaths() {
@@ -7,11 +7,9 @@ class RuntimeDriverFactoryIos extends RuntimeDeviceFactory {
7
7
  const AppleSimUtils = require('../../../devices/common/drivers/ios/tools/AppleSimUtils');
8
8
  const applesimutils = new AppleSimUtils();
9
9
 
10
- const SimulatorLauncher = require('../../allocation/drivers/ios/SimulatorLauncher');
11
10
  return {
12
11
  ...commonDeps,
13
12
  applesimutils,
14
- simulatorLauncher: new SimulatorLauncher({ applesimutils, eventEmitter }),
15
13
  };
16
14
  }
17
15
  }
@@ -86,8 +86,8 @@ class IPCClient {
86
86
  this._sessionState.patch(sessionState);
87
87
  }
88
88
 
89
- async conductEarlyTeardown() {
90
- const sessionState = await this._emit('conductEarlyTeardown', {});
89
+ async conductEarlyTeardown({ permanent }) {
90
+ const sessionState = await this._emit('conductEarlyTeardown', { permanent });
91
91
  this._sessionState.patch(sessionState);
92
92
  }
93
93
 
@@ -73,6 +73,7 @@ class IPCServer {
73
73
  this._ipc.server.emit(socket, 'registerContextDone', {
74
74
  testResults: this._sessionState.testResults,
75
75
  testSessionIndex: this._sessionState.testSessionIndex,
76
+ unsafe_earlyTeardown: this._sessionState.unsafe_earlyTeardown,
76
77
  });
77
78
  }
78
79
 
@@ -90,10 +91,11 @@ class IPCServer {
90
91
  }
91
92
  }
92
93
 
93
- onConductEarlyTeardown(_data = null, socket = null) {
94
- // Note that we don't save `unsafe_earlyTeardown` in the primary session state
95
- // because it's transient and needed only to make the workers quit early.
94
+ onConductEarlyTeardown({ permanent }, socket = null) {
96
95
  const newState = { unsafe_earlyTeardown: true };
96
+ if (permanent) {
97
+ Object.assign(this._sessionState, newState);
98
+ }
97
99
 
98
100
  if (socket) {
99
101
  this._ipc.server.emit(socket, 'conductEarlyTeardownDone', newState);
@@ -102,7 +102,7 @@ class DetoxContext {
102
102
  /** @abstract */
103
103
  [symbols.reportTestResults](_testResults) {}
104
104
  /** @abstract */
105
- [symbols.conductEarlyTeardown]() {}
105
+ [symbols.conductEarlyTeardown](_permanent) {}
106
106
  /**
107
107
  * @abstract
108
108
  * @param {Partial<DetoxInternals.DetoxInitOptions>} _opts
@@ -51,9 +51,9 @@ class DetoxPrimaryContext extends DetoxContext {
51
51
  }
52
52
  }
53
53
 
54
- [symbols.conductEarlyTeardown] = async () => {
54
+ [symbols.conductEarlyTeardown] = async (permanent = false) => {
55
55
  if (this[_ipcServer]) {
56
- await this[_ipcServer].onConductEarlyTeardown();
56
+ await this[_ipcServer].onConductEarlyTeardown({ permanent });
57
57
  }
58
58
  };
59
59
 
@@ -33,9 +33,9 @@ class DetoxSecondaryContext extends DetoxContext {
33
33
  }
34
34
  }
35
35
 
36
- [symbols.conductEarlyTeardown] = async () => {
36
+ [symbols.conductEarlyTeardown] = async (permanent = false) => {
37
37
  if (this[_ipcClient]) {
38
- await this[_ipcClient].conductEarlyTeardown();
38
+ await this[_ipcClient].conductEarlyTeardown({ permanent });
39
39
  } else {
40
40
  throw new DetoxInternalError('Detected an attempt to report early teardown using a non-initialized context.');
41
41
  }
@@ -0,0 +1,35 @@
1
+ const isArrowFunction = require('./isArrowFunction');
2
+
3
+ const EXAMPLE = `Here are some examples of valid function strings:
4
+
5
+ 1. function(el) { el.click(); }
6
+ 2. el => el.click()
7
+ 3. (el) => el.click()
8
+ `;
9
+
10
+ /**
11
+ * Dynamically evaluates a string as a function and throws an error if it's not a function
12
+ * @param {string} str serialized function like 'function() { return 42; }'
13
+ */
14
+ function assertIsFunction(str) {
15
+ let isFunction;
16
+
17
+ try {
18
+ isFunction = isFunctionDeclaration(str) && Function(`return typeof (${str})`)() === 'function';
19
+ } catch (e) {
20
+ isFunction = false;
21
+ }
22
+
23
+ if (!isFunction) {
24
+ throw new TypeError(`Expected a valid function string, but got: ${str}\n\n${EXAMPLE}`);
25
+ }
26
+
27
+ return str;
28
+ }
29
+
30
+ function isFunctionDeclaration(rawStr) {
31
+ const str = rawStr.trimStart();
32
+ return str.startsWith('async') || str.startsWith('function') || isArrowFunction(str);
33
+ }
34
+
35
+ module.exports = assertIsFunction;
@@ -0,0 +1,24 @@
1
+ function isArrowFunction(code) {
2
+ if (!code.includes('=>')) {
3
+ return false;
4
+ }
5
+
6
+ const syncCode = removeAsync(code.trimStart());
7
+ return syncCode.startsWith('(') || isSimpleArrowFunction(code);
8
+ }
9
+
10
+ function removeAsync(code) {
11
+ return code.startsWith('async') ? code.slice(5).trimStart() : code;
12
+ }
13
+
14
+ function isSimpleArrowFunction(code) {
15
+ const [signature] = code.split('=>', 1);
16
+
17
+ return isAlphanumericId(removeAsync(signature.trim()));
18
+ }
19
+
20
+ function isAlphanumericId(code) {
21
+ return /^[a-zA-Z0-9]+$/.test(code);
22
+ }
23
+
24
+ module.exports = isArrowFunction;
package/tsconfig.json CHANGED
@@ -15,6 +15,9 @@
15
15
  },
16
16
  "rootDir": ".",
17
17
  "include": [
18
+ "detox.d.ts",
19
+ "globals.d.ts",
20
+ "index.d.ts",
18
21
  "**/*.js",
19
22
  "**/*.ts"
20
23
  ],
@@ -1 +0,0 @@
1
- 0c2bae26c123edf10cb62b77d5e5acdd
@@ -1 +0,0 @@
1
- 96b7351396c83931de86925d213b5bc9d12a827d
@@ -1 +0,0 @@
1
- dbe5afc9df9a7c857a961781ebd58be8cf1d82c39771819b6c801f36b44434d4
@@ -1 +0,0 @@
1
- 8e4f2278448ac644826386e11b95b24f44037c1483f0bae0c1347dfc0a01783e058f9b229b5d9e217f8be08984ff0035a8a9a028503f672f2baff523d3dc037c
@@ -1 +0,0 @@
1
- 4db28745d12fb52a9b94eefe7aef7c6d
@@ -1 +0,0 @@
1
- 5101597e82e164ba10f7ecd0e15ee7a4316fdccc
@@ -1 +0,0 @@
1
- e7bc12d7cbefc0831194c059a2b62166bfda3a63e9e34d212418eed88155462f
@@ -1 +0,0 @@
1
- 6cc5ce462ef6068c314ffa8d8a06d6c091b819baa7d3d1b329bd6a907e3c7909db097fac66381b3833bbfcb3bd1226f5c1e511cad080b1e2a3a914ff91af6f61
@@ -1 +0,0 @@
1
- b8569c6d3b296face8b6d34037e27b6e
@@ -1 +0,0 @@
1
- fe831778fa7fbeffb2ccdbb15bf3200ec0e641b2
@@ -1 +0,0 @@
1
- 305c99310501d83ad114e4357d1af6efccf8ff774ec5ad25a04f7d9921203225
@@ -1 +0,0 @@
1
- f02ad136e06b87c385b1ec7d8d9ad27259cdd2f9eec6dae79eb79eb9e7e78614b55bbb33773da61990ea5e594b0dff92c8013f5d3687c9c04710916e95d70418
@@ -1 +0,0 @@
1
- 84130ea1d35084f1db1652765a011da8
@@ -1 +0,0 @@
1
- 0dc75a3ca7a62dadea9abdd8c20d8cade91ff0ad
@@ -1 +0,0 @@
1
- cc11f65f610d8f9cc708b0295e6998ee7e819ae7dc34d9f54586790ee253d4b2
@@ -1 +0,0 @@
1
- 592a6a8c132c98bb7e7cb531ec495cb83bd4bc004fd8388f361199359c293d10169e9af1a771efd9d79db0e9e65d2dd75cb3d4aa9b32909c01dc561368165ea0
@@ -1,154 +0,0 @@
1
- const resolveFrom = require('resolve-from');
2
- /** @type {new (globalConfig: any) => import('@jest/reporters').VerboseReporter} */
3
- const JestVerboseReporter = require(resolveFrom(process.cwd(), '@jest/reporters')).VerboseReporter;
4
- /** @type {new (globalConfig: any) => import('@jest/reporters').SummaryReporter} */
5
- const SummaryReporter = require(resolveFrom(process.cwd(), '@jest/reporters')).SummaryReporter;
6
-
7
- const { config, reportTestResults, unsafe_conductEarlyTeardown, cleanup } = require('../../../internals');
8
- const Deferred = require('../../../src/utils/Deferred');
9
-
10
- class DetoxReporter extends JestVerboseReporter {
11
- constructor(globalConfig) {
12
- super(globalConfig);
13
-
14
- /** @type {Deferred | null} */
15
- this._lastRunComplete = null;
16
- /** @type {Set<string>} */
17
- this._pendingTestFiles = new Set();
18
- /** @type {Promise<any> | null} */
19
- this._runCompletePromise = null;
20
- /** @type {import('@jest/reporters').SummaryReporter | null} */
21
- this._summaryReporter = this._initSummaryReporter();
22
- }
23
-
24
- onRunStart(aggregatedResults, options) {
25
- super.onRunStart(aggregatedResults, options);
26
-
27
- if (this._summaryReporter) {
28
- this._summaryReporter.onRunStart(aggregatedResults, options);
29
- }
30
- }
31
-
32
- onTestFileStart(test) {
33
- this._pendingTestFiles.add(test.path);
34
-
35
- // @ts-ignore Precaution in case Jest migrates to the new signature
36
- if (typeof super.onTestFileStart === 'function') {
37
- // @ts-ignore
38
- super.onTestFileStart(test);
39
- } else {
40
- super.onTestStart(test);
41
- }
42
- }
43
-
44
- onTestFileResult(test, testResult, aggregatedResult) {
45
- this._pendingTestFiles.delete(test.path);
46
-
47
- // @ts-ignore Precaution in case Jest migrates to the new signature
48
- if (typeof super.onTestFileResult === 'function') {
49
- // @ts-ignore
50
- super.onTestFileResult(test, testResult, aggregatedResult);
51
- } else {
52
- super.onTestResult(test, testResult, aggregatedResult);
53
- }
54
-
55
- if (this._lastRunComplete && this._pendingTestFiles.size === 0) {
56
- this._lastRunComplete.resolve(aggregatedResult);
57
- }
58
- }
59
-
60
- /**
61
- * @param {Set<import('@jest/reporters').TestContext>} testContexts
62
- * @param {import('@jest/reporters').AggregatedResult} aggregatedResult
63
- * @returns {Promise<any> | null}
64
- */
65
- // @ts-ignore We need to use the complete signature, not the one from the base class
66
- onRunComplete(testContexts, aggregatedResult) {
67
- if (!this._runCompletePromise) {
68
- // Both `_lastRunComplete` and `_runCompletePromise` are used to prevent
69
- // a bug in Jest, where `onRunComplete` is called multiple times when
70
- // Jest runs with `--bail` and multiple workers, and `onRunComplete`
71
- // is implemented as an asynchronous long-running operation.
72
- this._lastRunComplete = this._pendingTestFiles.size === 0
73
- ? Deferred.resolved(aggregatedResult)
74
- : new Deferred();
75
-
76
- this._runCompletePromise = this._onRunComplete(testContexts, aggregatedResult).catch(err => {
77
- console.error(err);
78
- throw err;
79
- });
80
- }
81
-
82
- return this._runCompletePromise;
83
- }
84
-
85
- /**
86
- * @param {Set<import('@jest/reporters').TestContext>} testContexts
87
- * @param {import('@jest/reporters').AggregatedResult} aggregatedResult
88
- * @returns {Promise<any> | null}
89
- */
90
- async _onRunComplete(testContexts, { numFailedTests }) {
91
- const bail = this._globalConfig.bail;
92
- const earlyTeardown = bail > 0 && numFailedTests >= bail;
93
- if (earlyTeardown) {
94
- await unsafe_conductEarlyTeardown();
95
- }
96
-
97
- const aggregatedResult = await this._lastRunComplete.promise;
98
- const lostTests = aggregatedResult.numTotalTestSuites - aggregatedResult.testResults.length;
99
-
100
- // @ts-expect-error TS2554
101
- super.onRunComplete(testContexts, aggregatedResult);
102
-
103
- if (earlyTeardown && lostTests > 0 && config.testRunner.retries > 0) {
104
- console.warn(
105
- 'Jest aborted the test execution before all scheduled test files have been reported.\n' +
106
- 'This brings us to a dilemma: retry the whole test run, or retry only known failed test files.\n' +
107
- 'Both options are bad in their own way, this is why we have decided to not support this edge case.\n' +
108
- 'If you want to retry the whole test run, please disable Jest\'s --bail option.'
109
- );
110
- }
111
-
112
- await reportTestResults(aggregatedResult.testResults.map(r => ({
113
- success: !r.failureMessage,
114
- testFilePath: r.testFilePath,
115
- testExecError: r.testExecError,
116
- isPermanentFailure: lostTests > 0 || this._isPermanentFailure(r),
117
- })));
118
-
119
- if (this._summaryReporter) {
120
- this._summaryReporter.onRunComplete(testContexts, aggregatedResult);
121
- }
122
-
123
- if (earlyTeardown) {
124
- await cleanup();
125
- }
126
- }
127
-
128
- /**
129
- * @returns {import('@jest/reporters').SummaryReporter | null}
130
- * @private
131
- */
132
- _initSummaryReporter() {
133
- /** @type {(config: import('@jest/types').Config.ReporterConfig) => boolean} */
134
- const isSummaryReporter = (config) => config[0] === 'summary';
135
- if (this._globalConfig.reporters.some(isSummaryReporter)) {
136
- return null;
137
- }
138
-
139
- return new SummaryReporter(this._globalConfig);
140
- }
141
-
142
- /**
143
- * @param {import('@jest/test-result').TestResult} testResult
144
- */
145
- _isPermanentFailure(testResult) {
146
- if (config.testRunner.jest.retryAfterCircusRetries) {
147
- return false;
148
- }
149
-
150
- return testResult.testResults.some(r => r.status === 'failed' && r.invocations > 1);
151
- }
152
- }
153
-
154
- module.exports = DetoxReporter;
@@ -1,25 +0,0 @@
1
- class SimulatorLauncher {
2
- constructor({ applesimutils, eventEmitter }) {
3
- this._applesimutils = applesimutils;
4
- this._eventEmitter = eventEmitter;
5
- }
6
-
7
- async launch(udid, type, bootArgs, headless) {
8
- const coldBoot = await this._applesimutils.boot(udid, bootArgs, headless);
9
- return coldBoot;
10
- }
11
-
12
- async shutdown(udid) {
13
- if (this._eventEmitter) {
14
- await this._eventEmitter.emit('beforeShutdownDevice', { deviceId: udid });
15
- }
16
-
17
- await this._applesimutils.shutdown(udid);
18
-
19
- if (this._eventEmitter) {
20
- await this._eventEmitter.emit('shutdownDevice', { deviceId: udid });
21
- }
22
- }
23
- }
24
-
25
- module.exports = SimulatorLauncher;