detox 20.0.2-breaking.new-global-lifecycle.0 → 20.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. package/Detox-android/com/wix/detox/{20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar → 20.0.2/detox-20.0.2-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar → 20.0.2/detox-20.0.2-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom → 20.0.2/detox-20.0.2.pom} +1 -7
  17. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.pom.sha512 +1 -0
  21. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  22. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  26. package/Detox-ios-src.tbz +0 -0
  27. package/Detox-ios.tbz +0 -0
  28. package/README.md +1 -1
  29. package/android/build.gradle +12 -7
  30. package/android/detox/build.gradle +13 -9
  31. package/android/detox/proguard-rules-app.pro +6 -0
  32. package/android/detox/proguard-rules.pro +3 -0
  33. package/android/detox/publishing.gradle +27 -27
  34. package/android/detox/src/full/java/com/wix/detox/DetoxCrashHandler.kt +1 -1
  35. package/android/detox/src/full/java/com/wix/detox/LaunchArgs.java +9 -0
  36. package/android/detox/src/full/java/com/wix/detox/TestEngineFacade.kt +1 -1
  37. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeExtension.kt +15 -2
  38. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeIdlingResources.kt +43 -38
  39. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/IdlingResourceDescription.kt +19 -13
  40. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/NetworkIdlingResource.java +33 -30
  41. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/DelegatedIdleInterrogationStrategy.kt +7 -27
  42. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/IdleInterrogationStrategy.kt +1 -11
  43. package/android/detox/src/main/java/com/wix/detox/common/TextFileReader.kt +1 -1
  44. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/DetoxMultiTapSpec.kt +4 -3
  45. package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/NetworkIdlingResourcesTest.kt +61 -0
  46. package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/timers/DelegatedIdleInterrogationStrategySpec.kt +3 -11
  47. package/index.d.ts +195 -59
  48. package/internals.d.ts +216 -49
  49. package/local-cli/build.js +2 -2
  50. package/local-cli/build.test.js +14 -14
  51. package/local-cli/cli.js +11 -6
  52. package/local-cli/init.js +61 -21
  53. package/local-cli/rebuild-framework-cache.js +1 -1
  54. package/local-cli/reset-lock-file.js +16 -0
  55. package/local-cli/templates/jest.js +13 -10
  56. package/local-cli/test.js +14 -8
  57. package/local-cli/test.test.js +143 -62
  58. package/local-cli/testCommand/TestRunnerCommand.js +97 -77
  59. package/local-cli/testCommand/TestRunnerError.js +17 -0
  60. package/local-cli/testCommand/TestRunnerError.test.js +25 -0
  61. package/local-cli/testCommand/builder.js +0 -1
  62. package/local-cli/testCommand/middlewares.js +4 -13
  63. package/local-cli/testCommand/warnings.js +0 -3
  64. package/local-cli/utils/jestInternals.js +4 -1
  65. package/package.json +23 -17
  66. package/runners/deprecation.js +42 -44
  67. package/runners/jest/globalSetup.js +1 -1
  68. package/runners/jest/globalTeardown.js +1 -1
  69. package/runners/jest/index.d.ts +60 -0
  70. package/runners/jest/index.js +3 -8
  71. package/runners/jest/index.test.js +13 -0
  72. package/runners/jest/reporters/DetoxReporter.js +33 -2
  73. package/runners/jest/testEnvironment/index.js +119 -69
  74. package/runners/jest/testEnvironment/listeners/DetoxCoreListener.js +94 -47
  75. package/runners/jest/testEnvironment/listeners/DetoxPlatformFilterListener.js +1 -1
  76. package/runners/jest/testEnvironment/listeners/SpecReporter.js +14 -16
  77. package/runners/jest/testEnvironment/listeners/WorkerAssignReporter.js +2 -6
  78. package/runners/jest/testEnvironment/utils/assertJestCircus27.js +17 -3
  79. package/runners/jest/testEnvironment/utils/assertJestCircus27.test.js +0 -1
  80. package/src/DetoxWorker.js +105 -62
  81. package/src/android/core/NativeElement.js +56 -20
  82. package/src/android/core/NativeExpect.js +28 -9
  83. package/src/android/interactions/native.js +25 -18
  84. package/src/artifacts/ArtifactsManager.js +14 -47
  85. package/src/artifacts/instruments/ios/SimulatorInstrumentsRecording.js +3 -3
  86. package/src/artifacts/log/ios/SimulatorLogRecording.js +1 -1
  87. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +1 -1
  88. package/src/artifacts/templates/artifact/Artifact.js +1 -1
  89. package/src/artifacts/templates/plugin/ArtifactPlugin.js +1 -1
  90. package/src/artifacts/timeline/TimelineContextTypes.js +7 -0
  91. package/src/artifacts/utils/temporaryPath.js +49 -8
  92. package/src/artifacts/video/SimulatorRecordVideoPlugin.js +1 -1
  93. package/src/client/AsyncWebSocket.js +8 -17
  94. package/src/client/Client.js +19 -2
  95. package/src/client/actions/formatters/sync-resources/NetworkFormatter.js +1 -1
  96. package/src/configuration/collectCliConfig.js +1 -12
  97. package/src/configuration/composeAppsConfig.js +4 -0
  98. package/src/configuration/composeDeviceConfig.js +1 -1
  99. package/src/configuration/composeLoggerConfig.js +19 -10
  100. package/src/configuration/composeRunnerConfig.js +61 -9
  101. package/src/configuration/index.js +14 -9
  102. package/src/configuration/loadExternalConfig.js +1 -1
  103. package/src/devices/allocation/DeviceAllocator.js +3 -2
  104. package/src/devices/allocation/drivers/android/emulator/AVDValidator.js +5 -5
  105. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +4 -3
  106. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +1 -1
  107. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +3 -2
  108. package/src/devices/allocation/drivers/android/emulator/EmulatorVersionResolver.js +4 -6
  109. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +1 -1
  110. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +1 -1
  111. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +3 -3
  112. package/src/devices/common/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  113. package/src/devices/common/drivers/android/tools/EmulatorTelnet.js +1 -1
  114. package/src/devices/common/drivers/android/tools/FreeDeviceFinder.js +1 -1
  115. package/src/devices/common/drivers/android/tools/MonitoredInstrumentation.js +1 -1
  116. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +29 -3
  117. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +13 -15
  118. package/src/devices/runtime/RuntimeDevice.js +19 -12
  119. package/src/devices/runtime/drivers/DeviceDriverBase.js +1 -1
  120. package/src/devices/runtime/drivers/android/AndroidDriver.js +10 -2
  121. package/src/devices/runtime/drivers/ios/SimulatorDriver.js +1 -1
  122. package/src/errors/DetoxConfigErrorComposer.js +17 -2
  123. package/src/errors/DetoxError.js +5 -1
  124. package/src/ios/expectTwo.js +153 -67
  125. package/src/ipc/IPCClient.js +12 -13
  126. package/src/ipc/IPCServer.js +28 -24
  127. package/src/ipc/{state.js → SessionState.js} +26 -53
  128. package/src/logger/DetoxLogger.js +287 -154
  129. package/src/logger/index.js +5 -0
  130. package/src/logger/utils/BunyanLogger.js +115 -0
  131. package/src/logger/utils/CategoryThreadDispatcher.js +37 -0
  132. package/src/logger/utils/DetoxLogFinalizer.js +162 -0
  133. package/src/logger/utils/MessageStack.js +35 -0
  134. package/src/logger/utils/ThreadDispatcher.js +61 -0
  135. package/src/logger/{customConsoleLogger.js → utils/customConsoleLogger.js} +23 -6
  136. package/src/logger/utils/getMainCategory.js +5 -0
  137. package/src/logger/utils/sanitizeBunyanContext.js +30 -0
  138. package/src/logger/utils/streams/BunyanTransformer.js +72 -0
  139. package/src/logger/utils/streams/ChromeTraceTransformer.js +127 -0
  140. package/src/logger/utils/streams/DetoxJSONLParser.js +31 -0
  141. package/src/logger/utils/streams/JSONLStringer.js +55 -0
  142. package/src/logger/utils/streams/index.js +7 -0
  143. package/src/logger/utils/streams/transformers.js +39 -0
  144. package/src/logger/utils/tracerLegacy.js +37 -0
  145. package/src/realms/DetoxContext.js +79 -65
  146. package/src/realms/DetoxInternalsFacade.js +8 -12
  147. package/src/realms/DetoxPrimaryContext.js +111 -72
  148. package/src/realms/DetoxSecondaryContext.js +29 -32
  149. package/src/server/DetoxConnection.js +18 -23
  150. package/src/server/DetoxServer.js +7 -10
  151. package/src/server/DetoxSession.js +6 -6
  152. package/src/server/DetoxSessionManager.js +1 -1
  153. package/src/server/handlers/RegisteredConnectionHandler.js +1 -2
  154. package/src/symbols.js +16 -22
  155. package/src/utils/Timer.js +55 -38
  156. package/src/utils/argparse.js +11 -0
  157. package/src/utils/childProcess/exec.js +1 -1
  158. package/src/utils/childProcess/spawn.js +1 -1
  159. package/src/utils/errorUtils.js +24 -3
  160. package/src/utils/invocationTraceDescriptions.js +43 -0
  161. package/src/utils/logger.js +1 -1
  162. package/src/utils/pathUtils.js +11 -0
  163. package/src/utils/shellUtils.js +17 -0
  164. package/src/utils/traceInvocationCall.js +21 -0
  165. package/src/utils/traceMethods.js +15 -0
  166. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar.md5 +0 -1
  167. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar.sha1 +0 -1
  168. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar.sha256 +0 -1
  169. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar.sha512 +0 -1
  170. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar.md5 +0 -1
  171. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar.sha1 +0 -1
  172. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar.sha256 +0 -1
  173. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar.sha512 +0 -1
  174. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar +0 -0
  175. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar.md5 +0 -1
  176. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar.sha1 +0 -1
  177. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar.sha256 +0 -1
  178. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar.sha512 +0 -1
  179. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom.md5 +0 -1
  180. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom.sha1 +0 -1
  181. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom.sha256 +0 -1
  182. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom.sha512 +0 -1
  183. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/DefaultIdleInterrogationStrategy.kt +0 -84
  184. package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/timers/DefaultIdleInterrogationStrategySpec.kt +0 -115
  185. package/runners/jest/deprecation.js +0 -25
  186. package/src/configuration/utils/warnings.js +0 -12
  187. package/src/logger/DetoxTraceEventBuilder.js +0 -21
  188. package/src/logger/DetoxTracer.js +0 -133
  189. package/src/logger/TraceThreadDispatcher.js +0 -52
  190. package/src/utils/ChromeTracingExporter.js +0 -54
  191. package/src/utils/streamUtils.js +0 -214
  192. package/src/utils/trace.js +0 -19
package/local-cli/test.js CHANGED
@@ -3,24 +3,30 @@ const detox = require('../internals');
3
3
  const TestRunnerCommand = require('./testCommand/TestRunnerCommand');
4
4
 
5
5
  module.exports.command = 'test';
6
- module.exports.desc = 'Run your test suite with the test runner specified in package.json';
6
+ module.exports.desc = 'Run your test suites with the test runner specified in the project\'s Detox config';
7
7
  module.exports.builder = require('./testCommand/builder');
8
8
  module.exports.middlewares = require('./testCommand/middlewares').default;
9
9
 
10
10
  module.exports.handler = async function test({ detoxArgs, runnerArgs }) {
11
11
  try {
12
- await detox.globalSetup({
12
+ const opts = {
13
13
  argv: detoxArgs,
14
14
  testRunnerArgv: runnerArgs,
15
- });
15
+ workerId: null,
16
+ };
17
+
18
+ const config = await detox.resolveConfig(opts);
19
+ if (!config.cli.inspectBrk) {
20
+ await detox.init(opts);
21
+ }
16
22
 
17
- const runnerCommand = new TestRunnerCommand()
18
- .setRunnerConfig(detox.config.runnerConfig)
19
- .setDeviceConfig(detox.config.deviceConfig)
20
- .replicateCLIConfig(detox.config.cliConfig);
23
+ const runnerCommand = new TestRunnerCommand({
24
+ config,
25
+ env: process.env,
26
+ });
21
27
 
22
28
  await runnerCommand.execute();
23
29
  } finally {
24
- await detox.globalTeardown();
30
+ await detox.cleanup();
25
31
  }
26
32
  };
@@ -8,8 +8,11 @@ jest.mock('../src/devices/DeviceRegistry');
8
8
  jest.mock('../src/devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory');
9
9
  jest.mock('./utils/jestInternals');
10
10
 
11
+ const cp = require('child_process');
12
+ const cpSpawn = cp.spawn;
11
13
  const os = require('os');
12
14
  const path = require('path');
15
+ const util = require('util');
13
16
 
14
17
  const fs = require('fs-extra');
15
18
  const _ = require('lodash');
@@ -28,6 +31,10 @@ describe('CLI', () => {
28
31
  let GenyDeviceRegistryFactory;
29
32
  let jestInternals;
30
33
 
34
+ afterEach(() => {
35
+ cp.spawn = cpSpawn;
36
+ });
37
+
31
38
  beforeEach(() => {
32
39
  _cliCallDump = undefined;
33
40
  _env = process.env;
@@ -46,6 +53,7 @@ describe('CLI', () => {
46
53
  $0: os.platform() === 'win32' ? `node ${executable}` : executable,
47
54
  config: 'e2e/config.json'
48
55
  },
56
+ forwardEnv: true,
49
57
  },
50
58
  configurations: {
51
59
  single: {
@@ -100,23 +108,53 @@ describe('CLI', () => {
100
108
  ])('given no extra args (%s)', (_platform, deviceType) => {
101
109
  beforeEach(async () => {
102
110
  singleConfig().device.type = deviceType;
103
- await run();
104
111
  });
105
112
 
106
- test('should produce a default command', () => {
107
- expect(cliCall().argv).toEqual([expect.stringContaining('executable'), '--config', 'e2e/config.json']);
108
- });
113
+ describe('when testRunner.forwardEnv is true', () => {
114
+ beforeEach(async () => {
115
+ singleConfig().testRunner = { forwardEnv: true };
116
+ await run();
117
+ });
118
+
119
+ test('should produce a default command', () => {
120
+ expect(cliCall().argv).toEqual([expect.stringContaining('executable'), '--config', 'e2e/config.json']);
121
+ });
109
122
 
110
- test('should not override environment variables', () => {
111
- expect(cliCall().env).toEqual({ DETOX_CONFIG_SNAPSHOT_PATH: expect.any(String) });
123
+ test('should override environment variables', () => {
124
+ expect(cliCall().env).toEqual({
125
+ DETOX_CONFIG_PATH: expect.any(String),
126
+ DETOX_CONFIG_SNAPSHOT_PATH: expect.any(String)
127
+ });
128
+ });
129
+
130
+ test('should hint essential environment variables', () => {
131
+ expect(cliCall().fullCommand).toMatch(/\bDETOX_CONFIG_PATH=.*\bexecutable\b/);
132
+ });
112
133
  });
113
134
 
114
- test('should hint essential environment variables', () => {
115
- expect(cliCall().fullCommand).toMatch(/^DETOX_CONFIG_PATH=.*\bexecutable/);
135
+ describe('when testRunner.forwardEnv is false', () => {
136
+ beforeEach(async () => {
137
+ singleConfig().testRunner = { forwardEnv: false };
138
+ await run();
139
+ });
140
+
141
+ test('should produce a default command', () => {
142
+ expect(cliCall().argv).toEqual([expect.stringContaining('executable'), '--config', 'e2e/config.json']);
143
+ });
144
+
145
+ test('should not override environment variables', () => {
146
+ expect(cliCall().env).toEqual({
147
+ DETOX_CONFIG_SNAPSHOT_PATH: expect.any(String)
148
+ });
149
+ });
150
+
151
+ test('should not hint essential environment variables', () => {
152
+ expect(cliCall().fullCommand).not.toMatch(/\bDETOX_CONFIG_PATH=.*\bexecutable\b/);
153
+ });
116
154
  });
117
155
  });
118
156
 
119
- test('should use runnerConfig.specs as default specs', async () => {
157
+ test('should use testRunner.args._ as default specs', async () => {
120
158
  detoxConfig.testRunner.args._ = ['e2e/sanity'];
121
159
  await run();
122
160
  expect(_.last(cliCall().argv)).toEqual('e2e/sanity');
@@ -129,7 +167,7 @@ describe('CLI', () => {
129
167
 
130
168
  test.each([['-l'], ['--loglevel']])('%s <value> should be passed as environment variable', async (__loglevel) => {
131
169
  await run(__loglevel, 'trace');
132
- expect(cliCall().env).not.toHaveProperty('DETOX_LOGLEVEL');
170
+ expect(cliCall().env).toHaveProperty('DETOX_LOGLEVEL');
133
171
  expect(cliCall().fullCommand).toMatch(/ DETOX_LOGLEVEL="trace" /);
134
172
  });
135
173
 
@@ -139,11 +177,28 @@ describe('CLI', () => {
139
177
  });
140
178
 
141
179
  test.each([['-R'], ['--retries']])('%s <value> should execute unsuccessful run N extra times', async (__retries) => {
180
+ function toTestResult(testFilePath) {
181
+ return {
182
+ testFilePath,
183
+ success: false,
184
+ isPermanentFailure: false,
185
+ };
186
+ }
187
+
142
188
  const context = require('../internals');
143
- context.session.testFilesToRetry = ['e2e/failing1.test.js', 'e2e/failing2.test.js'];
144
- context.session.testFilesToRetry.splice = jest.fn()
145
- .mockImplementationOnce(() => ['e2e/failing1.test.js', 'e2e/failing2.test.js'])
146
- .mockImplementationOnce(() => ['e2e/failing2.test.js']);
189
+
190
+ jest.spyOn(cp, 'spawn')
191
+ .mockImplementationOnce((...args) => {
192
+ context.session.testResults = ['e2e/failing1.test.js', 'e2e/failing2.test.js'].map(toTestResult);
193
+ return cpSpawn(...args);
194
+ })
195
+ .mockImplementationOnce((...args) => {
196
+ context.session.testResults = ['e2e/failing2.test.js'].map(toTestResult);
197
+ return cpSpawn(...args);
198
+ })
199
+ .mockImplementationOnce((...args) => {
200
+ return cpSpawn(...args);
201
+ });
147
202
 
148
203
  mockExitCode(1);
149
204
 
@@ -154,18 +209,35 @@ describe('CLI', () => {
154
209
  expect(cliCall(2).argv).toEqual([expect.stringMatching(/executable$/), '--config', 'e2e/config.json', 'e2e/failing2.test.js']);
155
210
  });
156
211
 
157
- test.each([['-R'], ['--retries']])('%s <value> should bail if has permanently failed tests', async (__retries) => {
158
- const context = require('../internals');
159
- context.session.failedTestFiles = ['e2e/failing1.test.js'];
160
- context.session.testFilesToRetry = ['e2e/failing2.test.js'];
212
+ describe('when there are permanently failed tests', () => {
213
+ beforeEach(() => {
214
+ const context = require('../internals');
215
+ context.session.testResults = ['e2e/failing1.test.js', 'e2e/failing2.test.js'].map((testFilePath, index) => ({
216
+ testFilePath,
217
+ success: false,
218
+ isPermanentFailure: index > 0,
219
+ }));
161
220
 
162
- mockExitCode(1);
221
+ mockExitCode(1);
222
+ });
163
223
 
164
- await run(__retries, 2).catch(_.noop);
224
+ test.each([['-R'], ['--retries']])('%s <value> should not bail by default', async (__retries) => {
225
+ await run(__retries, 2).catch(_.noop);
165
226
 
166
- expect(cliCall(0).env).not.toHaveProperty('DETOX_RERUN_INDEX');
167
- expect(cliCall(0).argv).toEqual([expect.stringMatching(/executable$/), '--config', 'e2e/config.json']);
168
- expect(cliCall(1)).toBe(null);
227
+ expect(cliCall(0).argv).toEqual([expect.stringMatching(/executable$/), '--config', 'e2e/config.json']);
228
+ expect(cliCall(1).env).not.toHaveProperty('DETOX_RERUN_INDEX');
229
+ expect(cliCall(1).argv).toEqual([expect.stringMatching(/executable$/), '--config', 'e2e/config.json', 'e2e/failing1.test.js']);
230
+ // note that it does not take the permanently failed test
231
+ });
232
+
233
+ test.each([['-R'], ['--retries']])('%s <value> should bail if configured', async (__retries) => {
234
+ detoxConfig.testRunner.bail = true;
235
+ await run(__retries, 2).catch(_.noop);
236
+
237
+ expect(cliCall(0).env).not.toHaveProperty('DETOX_RERUN_INDEX');
238
+ expect(cliCall(0).argv).toEqual([expect.stringMatching(/executable$/), '--config', 'e2e/config.json']);
239
+ expect(cliCall(1)).toBe(null);
240
+ });
169
241
  });
170
242
 
171
243
  test.each([['-R'], ['--retries']])('%s <value> should not restart test runner if there are no failing tests paths', async (__retries) => {
@@ -178,7 +250,11 @@ describe('CLI', () => {
178
250
 
179
251
  test.each([['-R'], ['--retries']])('%s <value> should retain -- <...explicitPassthroughArgs>', async (__retries) => {
180
252
  const context = require('../internals');
181
- context.session.testFilesToRetry = ['tests/failing.test.js'];
253
+ context.session.testResults = [{
254
+ testFilePath: 'tests/failing.test.js',
255
+ success: false,
256
+ isPermanentFailure: false,
257
+ }];
182
258
 
183
259
  mockExitCode(1);
184
260
 
@@ -190,111 +266,104 @@ describe('CLI', () => {
190
266
 
191
267
  test.each([['-r'], ['--reuse']])('%s <value> should be passed as environment variable', async (__reuse) => {
192
268
  await run(__reuse);
193
- expect(cliCall().env).not.toHaveProperty('DETOX_REUSE');
269
+ expect(cliCall().env).toHaveProperty('DETOX_REUSE');
194
270
  expect(cliCall().fullCommand).toMatch(/\bDETOX_REUSE=true /);
195
271
  });
196
272
 
197
273
  test.each([['-u'], ['--cleanup']])('%s <value> should be passed as environment variable', async (__cleanup) => {
198
274
  await run(__cleanup);
199
- expect(cliCall().env).not.toHaveProperty('DETOX_CLEANUP');
275
+ expect(cliCall().env).toHaveProperty('DETOX_CLEANUP');
200
276
  expect(cliCall().fullCommand).toMatch(/\bDETOX_CLEANUP=true /);
201
277
  });
202
278
 
203
279
  test.each([['-d'], ['--debug-synchronization']])('%s <value> should be passed as environment variable', async (__debug_synchronization) => {
204
280
  await run(__debug_synchronization, 5000);
205
- expect(cliCall().env).not.toHaveProperty('DETOX_DEBUG_SYNCHRONIZATION');
281
+ expect(cliCall().env).toHaveProperty('DETOX_DEBUG_SYNCHRONIZATION');
206
282
  expect(cliCall().fullCommand).toMatch(/\bDETOX_DEBUG_SYNCHRONIZATION=5000 /);
207
283
  });
208
284
 
209
285
  test.each([['-d'], ['--debug-synchronization']])('%s <value> should be passed as 0 when given false', async (__debug_synchronization) => {
210
286
  await run(__debug_synchronization, false);
211
- expect(cliCall().env).not.toHaveProperty('DETOX_DEBUG_SYNCHRONIZATION');
287
+ expect(cliCall().env).toHaveProperty('DETOX_DEBUG_SYNCHRONIZATION');
212
288
  expect(cliCall().fullCommand).toMatch(/\bDETOX_DEBUG_SYNCHRONIZATION=0 /);
213
289
  });
214
290
 
215
291
  test.each([['-d'], ['--debug-synchronization']])('%s <value> should have default value = 3000', async (__debug_synchronization) => {
216
292
  await run(`${__debug_synchronization}`);
217
- expect(cliCall().env).not.toHaveProperty('DETOX_DEBUG_SYNCHRONIZATION');
293
+ expect(cliCall().env).toHaveProperty('DETOX_DEBUG_SYNCHRONIZATION');
218
294
  expect(cliCall().fullCommand).toMatch(/\bDETOX_DEBUG_SYNCHRONIZATION=3000 /);
219
295
  });
220
296
 
221
297
  test.each([['-a'], ['--artifacts-location']])('%s <value> should be passed as environment variable', async (__artifacts_location) => {
222
298
  await run(__artifacts_location, '/tmp');
223
- expect(cliCall().env).not.toHaveProperty('DETOX_ARTIFACTS_LOCATION');
299
+ expect(cliCall().env).toHaveProperty('DETOX_ARTIFACTS_LOCATION');
224
300
  expect(cliCall().fullCommand).toMatch(/\bDETOX_ARTIFACTS_LOCATION="\/tmp" /);
225
301
  });
226
302
 
227
303
  test('--record-logs <value> should be passed as environment variable', async () => {
228
304
  await run('--record-logs', 'all');
229
- expect(cliCall().env).not.toHaveProperty('DETOX_RECORD_LOGS');
305
+ expect(cliCall().env).toHaveProperty('DETOX_RECORD_LOGS');
230
306
  expect(cliCall().fullCommand).toMatch(/\bDETOX_RECORD_LOGS="all" /);
231
307
  });
232
308
 
233
309
  test('--take-screenshots <value> should be passed as environment variable', async () => {
234
310
  await run('--take-screenshots', 'failing');
235
- expect(cliCall().env).not.toHaveProperty('DETOX_TAKE_SCREENSHOTS');
311
+ expect(cliCall().env).toHaveProperty('DETOX_TAKE_SCREENSHOTS');
236
312
  expect(cliCall().fullCommand).toMatch(/\bDETOX_TAKE_SCREENSHOTS="failing" /);
237
313
  });
238
314
 
239
315
  test('--record-videos <value> should be passed as environment variable', async () => {
240
316
  await run('--record-videos', 'failing');
241
- expect(cliCall().env).not.toHaveProperty('DETOX_RECORD_VIDEOS');
317
+ expect(cliCall().env).toHaveProperty('DETOX_RECORD_VIDEOS');
242
318
  expect(cliCall().fullCommand).toMatch(/\bDETOX_RECORD_VIDEOS="failing" /);
243
319
  });
244
320
 
245
321
  test('--record-performance <value> should be passed as environment variable', async () => {
246
322
  await run('--record-performance', 'all');
247
- expect(cliCall().env).not.toHaveProperty('DETOX_RECORD_PERFORMANCE');
323
+ expect(cliCall().env).toHaveProperty('DETOX_RECORD_PERFORMANCE');
248
324
  expect(cliCall().fullCommand).toMatch(/\DETOX_RECORD_PERFORMANCE="all" /);
249
325
  });
250
326
 
251
327
  test('--capture-view-hierarchy <value> should be passed as environment variable', async () => {
252
328
  await run('--capture-view-hierarchy', 'enabled');
253
- expect(cliCall().env).not.toHaveProperty('DETOX_CAPTURE_VIEW_HIERARCHY');
329
+ expect(cliCall().env).toHaveProperty('DETOX_CAPTURE_VIEW_HIERARCHY');
254
330
  expect(cliCall().fullCommand).toMatch(/\DETOX_CAPTURE_VIEW_HIERARCHY="enabled" /);
255
331
  });
256
332
 
257
333
  test('--jest-report-specs, set explicitly, should be passed as an environment variable', async () => {
258
334
  await run('--jest-report-specs');
259
- expect(cliCall().env).not.toHaveProperty('DETOX_REPORT_SPECS');
335
+ expect(cliCall().env).toHaveProperty('DETOX_REPORT_SPECS');
260
336
  expect(cliCall().fullCommand).toMatch(/\bDETOX_REPORT_SPECS=true /);
261
337
  });
262
338
 
263
339
  test.each([['-H'], ['--headless']])('%s <value> should be passed as environment variable', async (__headless) => {
264
340
  await run(__headless);
265
- expect(cliCall().env).not.toHaveProperty('DETOX_HEADLESS');
341
+ expect(cliCall().env).toHaveProperty('DETOX_HEADLESS');
266
342
  expect(cliCall().fullCommand).toMatch(/\bDETOX_HEADLESS=true /);
267
343
  });
268
344
 
269
345
  test('--gpu <value> should be passed as environment variable', async () => {
270
346
  await run('--gpu', 'angle_indirect');
271
- expect(cliCall().env).not.toHaveProperty('DETOX_GPU');
347
+ expect(cliCall().env).toHaveProperty('DETOX_GPU');
272
348
  expect(cliCall().fullCommand).toMatch(/\bDETOX_GPU="angle_indirect" /);
273
349
  });
274
350
 
275
351
  test('--device-boot-args should be passed as an environment variable (without deprecation warnings)', async () => {
276
352
  await run('--device-boot-args="--verbose"');
277
- expect(cliCall().env).not.toHaveProperty('DETOX_DEVICE_BOOT_ARGS');
353
+ expect(cliCall().env).toHaveProperty('DETOX_DEVICE_BOOT_ARGS');
278
354
  expect(cliCall().fullCommand).toMatch(/\bDETOX_DEVICE_BOOT_ARGS="--verbose" /);
279
355
  expect(logger().warn).not.toHaveBeenCalledWith(DEVICE_LAUNCH_ARGS_DEPRECATION);
280
356
  });
281
357
 
282
- test('--device-launch-args should serve as a deprecated alias to --device-boot-args', async () => {
283
- await run(`--device-launch-args="--verbose"`);
284
- expect(cliCall().env).not.toHaveProperty('DETOX_DEVICE_BOOT_ARGS');
285
- expect(cliCall().fullCommand).toMatch(/\bDETOX_DEVICE_BOOT_ARGS="--verbose" /);
286
- expect(logger().warn).toHaveBeenCalledWith(DEVICE_LAUNCH_ARGS_DEPRECATION);
287
- });
288
-
289
358
  test('--app-launch-args should be passed as an environment variable', async () => {
290
359
  await run(`--app-launch-args="--debug yes"`);
291
- expect(cliCall().env).not.toHaveProperty('DETOX_APP_LAUNCH_ARGS');
360
+ expect(cliCall().env).toHaveProperty('DETOX_APP_LAUNCH_ARGS');
292
361
  expect(cliCall().fullCommand).toMatch(/\bDETOX_APP_LAUNCH_ARGS="--debug yes" /);
293
362
  });
294
363
 
295
364
  test('--use-custom-logger false should be prevent passing environment variable', async () => {
296
365
  await run(`--use-custom-logger=false`);
297
- expect(cliCall().env).not.toHaveProperty('DETOX_USE_CUSTOM_LOGGER');
366
+ expect(cliCall().env).toHaveProperty('DETOX_USE_CUSTOM_LOGGER');
298
367
  expect(cliCall().fullCommand).toMatch(/\bDETOX_USE_CUSTOM_LOGGER=false /);
299
368
  });
300
369
 
@@ -308,13 +377,13 @@ describe('CLI', () => {
308
377
  test('--force-adb-install should be passed as environment variable', async () => {
309
378
  singleConfig().device.type = 'android.emulator';
310
379
  await run(`--force-adb-install`);
311
- expect(cliCall().env).not.toHaveProperty('DETOX_FORCE_ADB_INSTALL');
380
+ expect(cliCall().env).toHaveProperty('DETOX_FORCE_ADB_INSTALL');
312
381
  expect(cliCall().fullCommand).toMatch(/\bDETOX_FORCE_ADB_INSTALL=true /);
313
382
  });
314
383
 
315
384
  test.each([['-n'], ['--device-name']])('%s <value> should be passed as environment variable', async (__device_name) => {
316
385
  await run(__device_name, 'TheDevice');
317
- expect(cliCall().env).not.toHaveProperty('DETOX_DEVICE_NAME');
386
+ expect(cliCall().env).toHaveProperty('DETOX_DEVICE_NAME');
318
387
  expect(cliCall().fullCommand).toMatch(/\bDETOX_DEVICE_NAME="TheDevice" /);
319
388
  });
320
389
 
@@ -326,8 +395,6 @@ describe('CLI', () => {
326
395
  expect(cliCall().argv.slice(-2)).toEqual(['e2e/01.sanity.test.js', 'e2e/02.sanity.test.js']);
327
396
  });
328
397
 
329
- test.todo('--inspect-brk should work');
330
-
331
398
  test.each([
332
399
  ['-d e2eFolder', / e2eFolder$/, /\bDETOX_DEBUG_SYNCHRONIZATION=3000/],
333
400
  ['--debug-synchronization e2eFolder', / e2eFolder$/, /\bDETOX_DEBUG_SYNCHRONIZATION=3000/],
@@ -405,15 +472,14 @@ describe('CLI', () => {
405
472
  expect(cliCall().argv).toContain('--deepParameter');
406
473
  });
407
474
 
408
- // TODO: revive this test
409
- test.skip('--inspect-brk should prepend "node --inspect-brk" to the command', async () => {
410
- await run('--inspect-brk');
475
+ test('--inspect-brk should activate inspectBrk hook', async () => {
476
+ detoxConfig.testRunner.inspectBrk = (config) => {
477
+ config.args.customFlag = true;
478
+ return config;
479
+ };
411
480
 
412
- if (process.platform === 'win32') {
413
- expect(cliCall().argv).toMatch(/^node --inspect-brk \.\/node_modules\/jest\/bin\/jest\.js/);
414
- } else {
415
- expect(cliCall().argv).toMatch(/^node --inspect-brk \.\/node_modules\/\.bin\/jest/);
416
- }
481
+ await run('--inspect-brk');
482
+ expect(cliCall().argv).toContain('--customFlag');
417
483
  });
418
484
 
419
485
  test('should append $DETOX_ARGV_OVERRIDE to detox test ... command and print a warning', async () => {
@@ -429,6 +495,16 @@ describe('CLI', () => {
429
495
  expect(logger().warn).toHaveBeenCalledWith(expect.stringContaining('$DETOX_ARGV_OVERRIDE is detected'));
430
496
  });
431
497
 
498
+ test('should append $DETOX_ARGV_OVERRIDE "--" part to test runner command', async () => {
499
+ process.env.PLATFORM = 'ios';
500
+ process.env.DETOX_ARGV_OVERRIDE = '-- --help';
501
+
502
+ await run();
503
+
504
+ expect(cliCall().argv.slice(-1)).toEqual(['--help']);
505
+ expect(logger().warn).toHaveBeenCalledWith(expect.stringContaining('$DETOX_ARGV_OVERRIDE is detected'));
506
+ });
507
+
432
508
  // Helpers
433
509
 
434
510
  function tempfile(extension, content) {
@@ -483,7 +559,12 @@ describe('CLI', () => {
483
559
  }
484
560
 
485
561
  async function run(...args) {
486
- detoxConfigPath = tempfile('.json', JSON.stringify(detoxConfig));
562
+ let contents = `module.exports = ${util.inspect(detoxConfig, { depth: Infinity })};`;
563
+ if (detoxConfig.testRunner && detoxConfig.testRunner.inspectBrk) {
564
+ contents = contents.replace(/\[Function.*\]/m, detoxConfig.testRunner.inspectBrk.toString());
565
+ }
566
+
567
+ detoxConfigPath = tempfile('.js', contents);
487
568
  const __configPath = Math.random() > 0.5 ? '-C' : '--config-path';
488
569
  return runRaw('test', __configPath, detoxConfigPath, ...args);
489
570
  }
@@ -504,7 +585,7 @@ describe('CLI', () => {
504
585
  return {
505
586
  ...mockCall,
506
587
  fullCommand: _.chain(logger().log.mock.calls)
507
- .filter(([_level, _childMeta, meta]) => meta && meta.event === 'RUN_START')
588
+ .filter(([_level, _childMeta, meta]) => meta && meta.env)
508
589
  .get(index)
509
590
  .get(3)
510
591
  .value(),