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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. package/Detox-android/com/wix/detox/{20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-javadoc.jar → 20.0.0/detox-20.0.0-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-sources.jar → 20.0.0/detox-20.0.0-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.pom → 20.0.0/detox-20.0.0.pom} +2 -8
  17. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.0.0/detox-20.0.0.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 +13 -8
  30. package/android/detox/build.gradle +14 -10
  31. package/android/detox/proguard-rules-app.pro +6 -0
  32. package/android/detox/proguard-rules.pro +3 -0
  33. package/android/detox/publish-pom.gradle +5 -1
  34. package/android/detox/publishing.gradle +35 -33
  35. package/android/detox/src/full/java/com/wix/detox/DetoxCrashHandler.kt +1 -1
  36. package/android/detox/src/full/java/com/wix/detox/LaunchArgs.java +9 -0
  37. package/android/detox/src/full/java/com/wix/detox/TestEngineFacade.kt +1 -1
  38. package/android/detox/src/full/java/com/wix/detox/adapters/server/WebSocketClient.java +3 -1
  39. package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAction.java +1 -3
  40. package/android/detox/src/full/java/com/wix/detox/espresso/UiAutomatorHelper.java +1 -1
  41. package/android/detox/src/full/java/com/wix/detox/espresso/action/AdjustSliderToPositionAction.kt +22 -0
  42. package/android/detox/src/{main → full}/java/com/wix/detox/espresso/action/GetAttributesAction.kt +13 -1
  43. package/android/detox/src/full/java/com/wix/detox/espresso/common/SliderHelper.kt +75 -0
  44. package/android/detox/src/full/java/com/wix/detox/espresso/matcher/ViewMatchers.kt +16 -23
  45. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeExtension.kt +15 -2
  46. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeIdlingResources.kt +43 -38
  47. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeLoadingMonitor.kt +54 -8
  48. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/IdlingResourceDescription.kt +19 -13
  49. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/NetworkIdlingResource.java +33 -30
  50. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/DelegatedIdleInterrogationStrategy.kt +7 -27
  51. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/IdleInterrogationStrategy.kt +1 -11
  52. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/uimodule/RN66Workaround.kt +13 -4
  53. package/android/detox/src/main/java/com/wix/detox/common/DetoxErrors.java +4 -1
  54. package/android/detox/src/main/java/com/wix/detox/common/TextFileReader.kt +1 -1
  55. package/android/detox/src/main/java/com/wix/detox/espresso/UiControllerSpy.kt +2 -1
  56. package/android/detox/src/main/java/com/wix/detox/espresso/action/common/ReflectUtils.kt +10 -0
  57. package/android/detox/src/main/java/com/wix/detox/espresso/action/common/utils/UiControllerUtils.kt +1 -1
  58. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/DetoxMultiTapSpec.kt +4 -3
  59. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/GetAttributesActionTest.kt +15 -3
  60. package/android/detox/src/testFull/java/com/wix/detox/espresso/common/SliderHelperTest.kt +39 -0
  61. package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/NetworkIdlingResourcesTest.kt +61 -0
  62. package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/timers/DelegatedIdleInterrogationStrategySpec.kt +3 -11
  63. package/android/gradle/wrapper/gradle-wrapper.properties +2 -1
  64. package/android/gradlew +181 -107
  65. package/index.d.ts +198 -57
  66. package/internals.d.ts +220 -51
  67. package/local-cli/build.js +2 -2
  68. package/local-cli/build.test.js +14 -14
  69. package/local-cli/cli.js +8 -6
  70. package/local-cli/init.js +61 -21
  71. package/local-cli/rebuild-framework-cache.js +1 -1
  72. package/local-cli/reset-lock-file.js +16 -0
  73. package/local-cli/templates/jest.js +13 -10
  74. package/local-cli/test.js +14 -8
  75. package/local-cli/test.test.js +148 -61
  76. package/local-cli/testCommand/TestRunnerCommand.js +78 -71
  77. package/local-cli/testCommand/builder.js +0 -1
  78. package/local-cli/testCommand/middlewares.js +4 -13
  79. package/local-cli/testCommand/warnings.js +0 -3
  80. package/local-cli/utils/jestInternals.js +4 -1
  81. package/package.json +22 -15
  82. package/runners/deprecation.js +42 -44
  83. package/runners/jest/globalSetup.js +1 -1
  84. package/runners/jest/globalTeardown.js +1 -1
  85. package/runners/jest/index.d.ts +60 -0
  86. package/runners/jest/index.js +3 -8
  87. package/runners/jest/index.test.js +13 -0
  88. package/runners/jest/reporters/DetoxReporter.js +33 -2
  89. package/runners/jest/testEnvironment/index.js +119 -69
  90. package/runners/jest/testEnvironment/listeners/DetoxCoreListener.js +94 -51
  91. package/runners/jest/testEnvironment/listeners/DetoxPlatformFilterListener.js +1 -1
  92. package/runners/jest/testEnvironment/listeners/SpecReporter.js +14 -16
  93. package/runners/jest/testEnvironment/listeners/WorkerAssignReporter.js +2 -6
  94. package/runners/jest/testEnvironment/utils/assertJestCircus27.js +17 -3
  95. package/runners/jest/testEnvironment/utils/assertJestCircus27.test.js +0 -1
  96. package/src/DetoxWorker.js +107 -59
  97. package/src/android/core/NativeElement.js +56 -20
  98. package/src/android/core/NativeExpect.js +28 -9
  99. package/src/android/interactions/native.js +25 -18
  100. package/src/artifacts/ArtifactsManager.js +14 -47
  101. package/src/artifacts/instruments/ios/SimulatorInstrumentsRecording.js +3 -3
  102. package/src/artifacts/log/android/ADBLogcatRecording.js +11 -28
  103. package/src/artifacts/log/ios/SimulatorLogRecording.js +1 -1
  104. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +1 -1
  105. package/src/artifacts/templates/artifact/Artifact.js +1 -1
  106. package/src/artifacts/templates/plugin/ArtifactPlugin.js +1 -1
  107. package/src/artifacts/timeline/TimelineContextTypes.js +7 -0
  108. package/src/artifacts/utils/temporaryPath.js +18 -7
  109. package/src/artifacts/video/SimulatorRecordVideoPlugin.js +1 -1
  110. package/src/client/AsyncWebSocket.js +8 -17
  111. package/src/client/Client.js +19 -2
  112. package/src/client/actions/formatters/sync-resources/NetworkFormatter.js +1 -1
  113. package/src/configuration/collectCliConfig.js +1 -12
  114. package/src/configuration/composeAppsConfig.js +5 -1
  115. package/src/configuration/composeDeviceConfig.js +1 -1
  116. package/src/configuration/composeLoggerConfig.js +19 -10
  117. package/src/configuration/composeRunnerConfig.js +62 -9
  118. package/src/configuration/index.js +14 -9
  119. package/src/configuration/loadExternalConfig.js +1 -1
  120. package/src/devices/allocation/DeviceAllocator.js +3 -2
  121. package/src/devices/allocation/drivers/android/emulator/AVDValidator.js +5 -5
  122. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +4 -3
  123. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +1 -1
  124. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +3 -2
  125. package/src/devices/allocation/drivers/android/emulator/EmulatorVersionResolver.js +4 -6
  126. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +1 -1
  127. package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +1 -0
  128. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +1 -1
  129. package/src/devices/common/drivers/android/exec/ADB.js +5 -0
  130. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +3 -3
  131. package/src/devices/common/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  132. package/src/devices/common/drivers/android/tools/EmulatorTelnet.js +1 -1
  133. package/src/devices/common/drivers/android/tools/FreeDeviceFinder.js +1 -1
  134. package/src/devices/common/drivers/android/tools/MonitoredInstrumentation.js +1 -1
  135. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +29 -3
  136. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +13 -15
  137. package/src/devices/runtime/RuntimeDevice.js +19 -12
  138. package/src/devices/runtime/drivers/DeviceDriverBase.js +1 -1
  139. package/src/devices/runtime/drivers/android/AndroidDriver.js +10 -2
  140. package/src/devices/runtime/drivers/ios/SimulatorDriver.js +1 -1
  141. package/src/errors/DetoxConfigErrorComposer.js +18 -3
  142. package/src/ios/expectTwo.js +153 -67
  143. package/src/ipc/IPCClient.js +12 -12
  144. package/src/ipc/IPCServer.js +34 -17
  145. package/src/ipc/{state.js → SessionState.js} +26 -31
  146. package/src/logger/DetoxLogger.js +261 -157
  147. package/src/logger/index.js +5 -0
  148. package/src/logger/utils/BunyanLogger.js +76 -0
  149. package/src/logger/utils/CategoryThreadDispatcher.js +36 -0
  150. package/src/logger/utils/DetoxLogFinalizer.js +140 -0
  151. package/src/logger/utils/MessageStack.js +24 -0
  152. package/src/logger/utils/ThreadDispatcher.js +61 -0
  153. package/src/logger/{customConsoleLogger.js → utils/customConsoleLogger.js} +5 -4
  154. package/src/logger/utils/sanitizeBunyanContext.js +30 -0
  155. package/src/{utils → logger/utils}/streamUtils.js +51 -17
  156. package/src/logger/utils/tracerLegacy.js +37 -0
  157. package/src/realms/DetoxContext.js +78 -65
  158. package/src/realms/DetoxInternalsFacade.js +8 -12
  159. package/src/realms/DetoxPrimaryContext.js +106 -73
  160. package/src/realms/DetoxSecondaryContext.js +29 -31
  161. package/src/server/DetoxConnection.js +18 -23
  162. package/src/server/DetoxServer.js +7 -10
  163. package/src/server/DetoxSession.js +6 -6
  164. package/src/server/DetoxSessionManager.js +1 -1
  165. package/src/server/handlers/RegisteredConnectionHandler.js +1 -2
  166. package/src/symbols.js +16 -22
  167. package/src/utils/Timer.js +55 -38
  168. package/src/utils/argparse.js +11 -0
  169. package/src/utils/childProcess/exec.js +1 -1
  170. package/src/utils/childProcess/spawn.js +1 -1
  171. package/src/utils/environment.js +30 -15
  172. package/src/utils/errorUtils.js +24 -3
  173. package/src/utils/invocationTraceDescriptions.js +43 -0
  174. package/src/utils/logger.js +1 -1
  175. package/src/utils/traceInvocationCall.js +21 -0
  176. package/src/utils/traceMethods.js +15 -0
  177. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-javadoc.jar.md5 +0 -1
  178. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-javadoc.jar.sha1 +0 -1
  179. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-javadoc.jar.sha256 +0 -1
  180. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-javadoc.jar.sha512 +0 -1
  181. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-sources.jar.md5 +0 -1
  182. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-sources.jar.sha1 +0 -1
  183. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-sources.jar.sha256 +0 -1
  184. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0-sources.jar.sha512 +0 -1
  185. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.aar +0 -0
  186. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.aar.md5 +0 -1
  187. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.aar.sha1 +0 -1
  188. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.aar.sha256 +0 -1
  189. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.aar.sha512 +0 -1
  190. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.pom.md5 +0 -1
  191. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.pom.sha1 +0 -1
  192. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.pom.sha256 +0 -1
  193. package/Detox-android/com/wix/detox/20.0.0-breaking.new-global-lifecycle.0/detox-20.0.0-breaking.new-global-lifecycle.0.pom.sha512 +0 -1
  194. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/DefaultIdleInterrogationStrategy.kt +0 -84
  195. package/android/detox/src/main/java/com/wix/detox/espresso/action/AdjustSliderToPositionAction.kt +0 -36
  196. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/AdjustSliderToPositionActionTest.kt +0 -59
  197. package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/timers/DefaultIdleInterrogationStrategySpec.kt +0 -115
  198. package/runners/jest/deprecation.js +0 -25
  199. package/src/configuration/utils/warnings.js +0 -12
  200. package/src/logger/DetoxTraceEventBuilder.js +0 -21
  201. package/src/logger/DetoxTracer.js +0 -133
  202. package/src/logger/TraceThreadDispatcher.js +0 -52
  203. package/src/utils/ChromeTracingExporter.js +0 -53
  204. package/src/utils/trace.js +0 -19
package/internals.d.ts CHANGED
@@ -3,99 +3,268 @@
3
3
 
4
4
  declare global {
5
5
  namespace DetoxInternals {
6
+ type DetoxStatus = 'inactive' | 'init' | 'active' | 'cleanup';
7
+
6
8
  type Facade = {
7
- // region Initialization
9
+ //#region Initialization
8
10
  /**
9
- * Use with a caution, when you still have no config, yet need to avoid {@link Facade#globalSetup}
11
+ * Use with a caution, when you still have no config, yet need to avoid {@link Facade#init}
10
12
  */
11
- resolveConfig(options?: Partial<DetoxGlobalSetupOptions>): Promise<RuntimeConfig>;
13
+ resolveConfig(options?: Partial<DetoxInitOptions>): Promise<RuntimeConfig>;
12
14
 
13
15
  /**
14
- * This is the phase where Detox reads its configuration, starts a server.
16
+ * Returns one of statuses depending on what’s going with the current Detox context:
17
+ *
18
+ * `inactive` – before `init()` and after `cleanup()` is called.
19
+ * `init` – while `init()` is executing.
20
+ * `active` – after `init()` and before `cleanup()` is called.
21
+ * `cleanup` – while `cleanup()` is executing.
15
22
  */
16
- globalSetup(options?: Partial<DetoxGlobalSetupOptions>): Promise<void>;
23
+ getStatus(): DetoxStatus;
17
24
 
18
25
  /**
19
- * This is the phase where Detox loads its expection library and starts a device.
26
+ * Starts a new Detox test session with the provided configuration.
27
+ * See {@link https://wix.github.io/Detox/docs/api/internals} for more details.
20
28
  */
21
- setup(options?: Partial<DetoxConfigurationSetupOptions>): Promise<void>;
29
+ init(options?: Partial<DetoxInitOptions>): Promise<void>;
22
30
 
23
31
  /**
24
- * The teardown phase deallocates the device.
32
+ * This is the phase where Detox loads its expectation library and boots a device.
33
+ * You don't need to call it separately unless you use `init({ workerId: null })` override.
25
34
  */
26
- teardown(): Promise<void>;
35
+ installWorker(options?: Partial<DetoxInstallWorkerOptions>): Promise<void>;
27
36
 
28
37
  /**
29
- * The global cleanup phase should happen after all the tests have finished.
30
- * This is the phase where the Detox server shuts down.
38
+ * Deallocates the device.
39
+ * Most Client API (device, by, element, expect) will stop working, except for the logger.
31
40
  */
32
- globalTeardown(): Promise<void>;
33
- // endregion
41
+ uninstallWorker(): Promise<void>;
34
42
 
35
- // region Lifecycle
36
- onRunStart(event: unknown): Promise<void>;
37
- onRunDescribeStart(event: unknown): Promise<void>;
38
- onTestStart(event: unknown): Promise<void>;
39
- onHookStart(event: unknown): Promise<void>;
40
- onHookFailure(event: unknown): Promise<void>;
41
- onHookSuccess(event: unknown): Promise<void>;
42
- onTestFnStart(event: unknown): Promise<void>;
43
- onTestFnFailure(event: unknown): Promise<void>;
44
- onTestFnSuccess(event: unknown): Promise<void>;
45
- onTestDone(event: unknown): Promise<void>;
46
- onRunDescribeFinish(event: unknown): Promise<void>;
47
- onRunFinish(event: unknown): Promise<void>;
43
+ /**
44
+ * This method should be called when the main or child process is about to exit.
45
+ * See {@link https://wix.github.io/Detox/docs/api/internals} for more details.
46
+ */
47
+ cleanup(): Promise<void>;
48
+ //#endregion
48
49
 
50
+ //#region Lifecycle
51
+ /**
52
+ * Reports that the test runner started executing a test suite, e.g. a `beforeAll` hook or a first test.
53
+ */
54
+ onRunDescribeStart(event: {
55
+ /** Test suite name */
56
+ name: string;
57
+ }): Promise<void>;
58
+ /**
59
+ * Reports that the test runner started executing a specific test.
60
+ */
61
+ onTestStart(event: {
62
+ /** Test name */
63
+ title: string;
64
+ /** Test name including the ancestor suite titles */
65
+ fullName: string;
66
+ /**
67
+ * N-th time this test is running, if there is a retry mechanism.
68
+ *
69
+ * @default 1
70
+ */
71
+ invocations?: number;
72
+ status: 'running';
73
+ }): Promise<void>;
49
74
  /**
50
- * Powers the "--retries <N>" of Detox CLI under the hood.
75
+ * Reports about an error in the midst of `beforeAll`, `beforeEach`, `afterEach`, `afterAll` or any other hook.
51
76
  */
52
- reportFailedTests(testFilePaths: string[]): Promise<void>;
53
- // endregion
77
+ onHookFailure(event: {
78
+ error: Error | string;
79
+ /**
80
+ * @example 'beforeAll'
81
+ * @example 'afterEach'
82
+ */
83
+ hook: string;
84
+ }): Promise<void>;
85
+ /**
86
+ * Reports about an error in the midst of a test function, `test` or `it`.
87
+ */
88
+ onTestFnFailure(event: {
89
+ error: Error | string;
90
+ }): Promise<void>;
91
+ /**
92
+ * Reports the final status of the test, `passed` or `failed`.
93
+ */
94
+ onTestDone(event: {
95
+ /** Test name */
96
+ title: string;
97
+ /** Test name including the ancestor suite titles */
98
+ fullName: string;
99
+ /**
100
+ * N-th time this test is running, if there is a retry mechanism.
101
+ *
102
+ * @default 1
103
+ */
104
+ invocations?: number;
105
+ status: 'passed' | 'failed';
106
+ /** Whether a timeout was the reason for why the test failed. */
107
+ timedOut?: boolean;
108
+ }): Promise<void>;
109
+ /**
110
+ * Reports that the test runner has finished executing a test suite, e.g. all the `afterAll` hooks have been executed or the last test has finished running.
111
+ */
112
+ onRunDescribeFinish(event: {
113
+ /** Test suite name */
114
+ name: string;
115
+ }): Promise<void>;
116
+
117
+ /**
118
+ * Reports to Detox CLI about passed and failed test files.
119
+ * The failed test files might be re-run again if
120
+ * {@link Detox.DetoxTestRunnerConfig#retries} is set to a non-zero.
121
+ *
122
+ * @param testResults - reports about test files
123
+ */
124
+ reportTestResults(testResults: DetoxTestFileReport[]): Promise<void>;
125
+ //#endregion
54
126
 
55
127
  readonly config: RuntimeConfig;
56
128
  readonly log: Detox.Logger;
57
- readonly trace: Detox.Tracer;
58
129
  readonly session: SessionState;
130
+ readonly tracing: {
131
+ /**
132
+ * Creates a readable stream of the currently recorded events in Chrome Trace Event format.
133
+ *
134
+ * @see {@link https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU}
135
+ * @see {import('trace-event-lib').DurationBeginEvent}
136
+ * @see {import('trace-event-lib').DurationEndEvent}
137
+ * @see {import('trace-event-lib').InstantEvent}
138
+ */
139
+ createEventStream(): NodeJS.ReadableStream;
140
+ };
59
141
 
60
- readonly worker: unknown;
142
+ /**
143
+ * Not documented on purpose.
144
+ * Provides direct access to the object which holds the device driver, websocket client, matchers, expectations, etc.
145
+ */
146
+ readonly worker: Worker;
61
147
  }
62
148
 
63
- type DetoxGlobalSetupOptions = {
149
+ interface Worker extends Detox.DetoxExportWrapper {
150
+ readonly id: string;
151
+ }
152
+
153
+ type DetoxInitOptions = {
64
154
  cwd: string;
155
+ /**
156
+ * @internal
157
+ */
65
158
  argv: Record<string, unknown>;
66
159
  testRunnerArgv: Record<string, unknown>;
67
160
  override: Partial<Detox.DetoxConfig>;
161
+ /** @inheritDoc */
162
+ global: NodeJS.Global | {};
163
+ /**
164
+ * Worker ID. Used to distinguish allocated workers in parallel test execution environment.
165
+ *
166
+ * If explicitly set to null, tells {@link Facade#init} to skip {@link Facade#installWorker} call.
167
+ * Useful for complex test runner integrations, where you have to install the worker via a separate call,
168
+ * when the environment is ready for that.
169
+ *
170
+ * @default 'worker'
171
+ */
172
+ workerId: string | null;
68
173
  };
69
174
 
70
- type DetoxConfigurationSetupOptions = {
71
- global: NodeJS.Global;
72
- workerId: number;
175
+ type DetoxInstallWorkerOptions = {
176
+ /**
177
+ * Used for integration with sandboxed test environments.
178
+ * {@link DetoxInternals.Facade#setup} might override {@link Console} methods
179
+ * to integrate it with Detox loggeing subsystem.
180
+ */
181
+ global: NodeJS.Global | {};
182
+ /**
183
+ * Worker ID. Used to distinguish allocated workers in parallel test execution environment.
184
+ *
185
+ * @default 'worker'
186
+ */
187
+ workerId: string;
73
188
  };
74
189
 
75
- type SessionState = Readonly<PrimarySessionState | SecondarySessionState>;
76
-
77
- type SecondarySessionState = {
78
- workersCount: number;
190
+ type DetoxTestFileReport = {
191
+ /**
192
+ * Global or relative path to the failed test file.
193
+ */
194
+ testFilePath: string;
195
+ /**
196
+ * Whether the test passed or not.
197
+ */
198
+ success: boolean;
199
+ /**
200
+ * Top-level error if the entire test file failed.
201
+ */
202
+ testExecError?: { name?: string; message: string; stack?: string; };
203
+ /**
204
+ * If the test failed, it should tell whether the failure is permanent.
205
+ * Permanent failure means that the test file should not be re-run.
206
+ *
207
+ * @default false
208
+ * @see {Detox.DetoxTestRunnerConfig#retries}
209
+ */
210
+ isPermanentFailure?: boolean;
79
211
  };
80
212
 
81
- type PrimarySessionState = PrimarySessionState & {
82
- failedTestFiles: string[];
83
- };
213
+ type SessionState = Readonly<{
214
+ /**
215
+ * Randomly generated ID for the entire Detox test session, including retries.
216
+ */
217
+ id: string;
218
+ /**
219
+ * Results of test file executions. Primarily used for Detox CLI retry mechanism.
220
+ */
221
+ testResults: DetoxTestFileReport[];
222
+ /**
223
+ * Retry index of the test session: 0..retriesCount.
224
+ */
225
+ testSessionIndex: number;
226
+ /**
227
+ * Count of Detox contexts with a worker installed.
228
+ * Oversimplified, it reflects the count of allocated devices in the current test session.
229
+ *
230
+ * @see {Facade#init}
231
+ * @see {Facade#installWorker}
232
+ */
233
+ workersCount: number;
234
+ }>;
84
235
 
85
236
  type RuntimeConfig = Readonly<{
86
237
  configurationName: string;
87
238
 
88
- appsConfig: Record<string, Readonly<Detox.DetoxAppConfig>>;
89
- artifactsConfig: Detox.DetoxArtifactsConfig;
90
- behaviorConfig: Detox.DetoxBehaviorConfig;
91
- cliConfig: DetoxCLIConfig;
92
- deviceConfig: Detox.DetoxDeviceConfig;
93
- loggerConfig: Detox.DetoxLoggerConfig;
94
- runnerConfig: Detox.DetoxTestRunnerConfig;
95
- sessionConfig: Detox.DetoxSessionConfig;
239
+ /**
240
+ * Dictionary of app configurations,
241
+ * where the keys are defined by {@link Detox.DetoxAppConfig#name}
242
+ * or equal to "default" if the name is not configured.
243
+ */
244
+ apps: Record<string, Readonly<Detox.DetoxAppConfig>>;
245
+ artifacts: Readonly<RuntimeArtifactsConfig>;
246
+ behavior: Readonly<Detox.DetoxBehaviorConfig>;
247
+ cli: Readonly<CLIConfig>;
248
+ device: Readonly<Detox.DetoxDeviceConfig>;
249
+ logger: Readonly<Detox.DetoxLoggerConfig>;
250
+ testRunner: Readonly<Detox.DetoxTestRunnerConfig>;
251
+ session: Readonly<Detox.DetoxSessionConfig>;
96
252
  }>;
97
253
 
98
- type DetoxCLIConfig = Readonly<Partial<{
254
+ type RuntimeArtifactsConfig = {
255
+ rootDir: string;
256
+ pathBuilder: string;
257
+ plugins: Readonly<{
258
+ log: Readonly<Detox.DetoxLogArtifactsPluginConfig>;
259
+ screenshot: Readonly<Detox.DetoxScreenshotArtifactsPluginConfig>;
260
+ video: Readonly<Detox.DetoxVideoArtifactsPluginConfig>;
261
+ instruments: Readonly<Detox.DetoxInstrumentsArtifactsPluginConfig>;
262
+ uiHierarchy: Readonly<Detox.DetoxUIHierarchyArtifactsPluginConfig>;
263
+ [pluginId: string]: unknown;
264
+ }>;
265
+ };
266
+
267
+ type CLIConfig = Readonly<Partial<{
99
268
  appLaunchArgs: string;
100
269
  artifactsLocation: string;
101
270
  captureViewHierarchy: string;
@@ -37,7 +37,7 @@ module.exports.builder = {
37
37
  };
38
38
 
39
39
  module.exports.handler = async function build(argv) {
40
- const { appsConfig, errorComposer } = await detox.resolveConfig({ argv });
40
+ const { apps: appsConfig, errorComposer } = await detox.resolveConfig({ argv });
41
41
  const apps = _.entries(appsConfig);
42
42
 
43
43
  for (const [appName, app] of apps) {
@@ -65,7 +65,7 @@ module.exports.handler = async function build(argv) {
65
65
  }
66
66
 
67
67
  if (app.binaryPath && !fs.existsSync(app.binaryPath)) {
68
- detox.log.warn('\nImportant: after running the build command, Detox could not find your app at the given binary path:\n\t' + app.binaryPath + "\nMake sure it is correct, otherwise you'll get an error on an attempt to install your app.\n");
68
+ detox.log.warn('After running the build command, Detox could not find your app at the given binary path:\n\t' + app.binaryPath + "\nMake sure it is correct, otherwise you'll get an error on an attempt to install your app.\n");
69
69
  }
70
70
  }
71
71
  };
@@ -14,12 +14,12 @@ describe('build', () => {
14
14
  const DetoxConfigErrorComposer = require('../src/errors/DetoxConfigErrorComposer');
15
15
 
16
16
  const config = {
17
- appsConfig: {},
18
- artifactsConfig: {},
19
- behaviorConfig: {},
17
+ apps: {},
18
+ artifacts: {},
19
+ behavior: {},
20
20
  errorComposer: new DetoxConfigErrorComposer(),
21
- deviceConfig: {},
22
- sessionConfig: {}
21
+ device: {},
22
+ session: {}
23
23
  };
24
24
 
25
25
  return ({
@@ -44,14 +44,14 @@ describe('build', () => {
44
44
  });
45
45
 
46
46
  it('runs the build script from the composed device config', async () => {
47
- detox.config.appsConfig.default = { build: 'yet another command' };
47
+ detox.config.apps.default = { build: 'yet another command' };
48
48
 
49
49
  await callCli('./build', 'build');
50
50
  expect(execSync).toHaveBeenCalledWith('yet another command', expect.anything());
51
51
  });
52
52
 
53
53
  it('skips building the app if the binary exists and --if-missing flag is set', async () => {
54
- detox.config.appsConfig.default = { build: 'yet another command', binaryPath: __filename };
54
+ detox.config.apps.default = { build: 'yet another command', binaryPath: __filename };
55
55
 
56
56
  await callCli('./build', 'build -i');
57
57
  expect(execSync).not.toHaveBeenCalled();
@@ -63,32 +63,32 @@ describe('build', () => {
63
63
  });
64
64
 
65
65
  it('fails with an error if a build script has not been found', async () => {
66
- detox.config.appsConfig.default = {};
66
+ detox.config.apps.default = {};
67
67
  await expect(callCli('./build', 'build')).rejects.toThrowError(/Failed to build/);
68
68
  });
69
69
 
70
70
  it('should ignore missing build command with -s, --silent flag', async () => {
71
- detox.config.appsConfig.default = {};
71
+ detox.config.apps.default = {};
72
72
  await expect(callCli('./build', 'build -s')).resolves.not.toThrowError();
73
73
  expect(detox.log.warn).not.toHaveBeenCalled();
74
74
  });
75
75
 
76
76
  it('should print a warning upon user build script failure', async () => {
77
- detox.config.appsConfig.default = { build: 'a command' };
77
+ detox.config.apps.default = { build: 'a command' };
78
78
  execSync.mockImplementation(() => { throw new Error('Build failure'); });
79
79
  await expect(callCli('./build', 'build')).rejects.toThrowError(/Build failure/);
80
80
  expect(detox.log.warn).toHaveBeenCalledWith(expect.stringContaining('You are responsible'));
81
81
  });
82
82
 
83
83
  it('should print a warning if app is not found at binary path', async () => {
84
- detox.config.appsConfig.default = { binaryPath: tempfile() };
84
+ detox.config.apps.default = { binaryPath: tempfile() };
85
85
  await expect(callCli('./build', 'build -s')).resolves.not.toThrowError();
86
86
  expect(detox.log.warn).toHaveBeenCalledWith(expect.stringContaining('could not find your app at the given binary path'));
87
87
  });
88
88
 
89
89
  it('should print extra message with the app name before building (in a multi-app configuration)', async () => {
90
- detox.config.appsConfig.app1 = { binaryPath: tempfile(), build: ':' };
91
- detox.config.appsConfig.app2 = { binaryPath: tempfile(), build: ':' };
90
+ detox.config.apps.app1 = { binaryPath: tempfile(), build: ':' };
91
+ detox.config.apps.app2 = { binaryPath: tempfile(), build: ':' };
92
92
 
93
93
  await expect(callCli('./build', 'build -s')).resolves.not.toThrowError();
94
94
  expect(detox.log.info).toHaveBeenCalledWith(expect.stringContaining('app1'));
@@ -96,7 +96,7 @@ describe('build', () => {
96
96
  });
97
97
 
98
98
  it('should not print that extra message when the app is single', async () => {
99
- detox.config.appsConfig.default = { binaryPath: tempfile(), build: ':' };
99
+ detox.config.apps.default = { binaryPath: tempfile(), build: ':' };
100
100
 
101
101
  await expect(callCli('./build', 'build -s')).resolves.not.toThrowError();
102
102
  expect(detox.log.info).not.toHaveBeenCalledWith(expect.stringContaining('default'));
package/local-cli/cli.js CHANGED
@@ -1,8 +1,11 @@
1
1
  #!/usr/bin/env node
2
+ const fs = require('fs');
3
+
4
+ const _ = require('lodash');
2
5
  const yargs = require('yargs');
3
6
 
7
+ const logger = require('../internals').log.child({ cat: 'cli' });
4
8
  const DetoxError = require('../src/errors/DetoxError');
5
- const logger = require('../src/utils/logger').child({ __filename });
6
9
 
7
10
  yargs
8
11
  .scriptName('detox')
@@ -25,12 +28,11 @@ yargs
25
28
  .wrap(yargs.terminalWidth() * 0.9)
26
29
  .fail(function(msg, err, program) {
27
30
  if (err) {
28
- const lines = DetoxError.format(err).split('\n');
29
- for (const line of lines) {
30
- logger.error(line);
31
- }
31
+ logger.error(DetoxError.format(err));
32
32
  // eslint-disable-next-line no-console
33
- console.error('');
33
+ process.stderr.write('\n');
34
+ // @ts-ignore
35
+ _.attempt(() => fs.unlinkSync(logger.file));
34
36
  // eslint-disable-next-line no-process-exit
35
37
  process.exit(1);
36
38
  }
package/local-cli/init.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const fs = require('fs');
2
2
  const path = require('path');
3
+ const util = require('util');
3
4
 
4
5
  const detox = require('../internals');
5
6
 
@@ -8,10 +9,11 @@ const jestTemplates = require('./templates/jest');
8
9
  let exitCode = 0;
9
10
 
10
11
  module.exports.command = 'init';
11
- module.exports.desc = 'Scaffold initial E2E test folder structure for Detox';
12
+ module.exports.desc = 'Creates template files to get you started with Detox';
12
13
  module.exports.builder = {};
13
14
 
14
15
  module.exports.handler = async function init() {
16
+ createDetoxConfig();
15
17
  createJestFolderE2E();
16
18
  process.exit(exitCode); // eslint-disable-line
17
19
  };
@@ -51,44 +53,66 @@ function createFile(filename, content) {
51
53
 
52
54
  function createJestFolderE2E() {
53
55
  createFolder('e2e', {
54
- 'config.json': jestTemplates.runnerConfig,
56
+ 'jest.config.js': jestTemplates.runnerConfig,
55
57
  'starter.test.js': jestTemplates.starter,
56
58
  });
59
+ }
57
60
 
58
- createFile('.detoxrc.json', JSON.stringify({
59
- testRunner: {
60
- args: {
61
- config: 'e2e/config.json'
62
- },
63
- },
64
-
65
- ...createDefaultConfigurations(),
66
- }, null, 2));
61
+ function createDetoxConfig() {
62
+ createFile('.detoxrc.js',
63
+ '/** @type {Detox.DetoxConfig} */\n' +
64
+ 'module.exports = ' +
65
+ util.inspect(createDefaultConfigurations(), { compact: false, depth: Infinity }) +
66
+ ';\n'
67
+ );
67
68
  }
68
69
 
70
+ /** @returns {Detox.DetoxConfig} */
69
71
  function createDefaultConfigurations() {
70
72
  return {
71
73
  testRunner: {
72
74
  args: {
73
75
  $0: 'jest',
74
- config: 'e2e/config.json',
76
+ config: 'e2e/jest.config.js',
77
+ },
78
+ jest: {
79
+ setupTimeout: 120000,
75
80
  },
76
81
  },
77
82
  apps: {
78
- ios: {
83
+ 'ios.debug': {
79
84
  type: 'ios.app',
80
- binaryPath: 'SPECIFY_PATH_TO_YOUR_APP_BINARY',
85
+ binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/YOUR_APP.app',
86
+ build: 'xcodebuild -workspace ios/YOUR_APP.xcworkspace -scheme YOUR_APP -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build',
87
+ },
88
+ 'ios.release': {
89
+ type: 'ios.app',
90
+ binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/YOUR_APP.app',
91
+ build: 'xcodebuild -workspace ios/YOUR_APP.xcworkspace -scheme YOUR_APP -configuration Release -sdk iphonesimulator -derivedDataPath ios/build',
92
+ },
93
+ 'android.debug': {
94
+ type: 'android.apk',
95
+ binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk',
96
+ build: 'cd android ; ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug ; cd -',
97
+ reversePorts: [8081],
81
98
  },
82
- android: {
99
+ 'android.release': {
83
100
  type: 'android.apk',
84
- binaryPath: 'SPECIFY_PATH_TO_YOUR_APP_BINARY',
101
+ binaryPath: 'android/app/build/outputs/apk/release/app-release.apk',
102
+ build: 'cd android ; ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release ; cd -',
85
103
  },
86
104
  },
87
105
  devices: {
88
106
  simulator: {
89
107
  type: 'ios.simulator',
90
108
  device: {
91
- type: 'iPhone 11',
109
+ type: 'iPhone 12',
110
+ },
111
+ },
112
+ attached: {
113
+ type: 'android.attached',
114
+ device: {
115
+ adbName: '.*',
92
116
  },
93
117
  },
94
118
  emulator: {
@@ -99,13 +123,29 @@ function createDefaultConfigurations() {
99
123
  },
100
124
  },
101
125
  configurations: {
102
- ios: {
126
+ 'ios.sim.debug': {
127
+ device: 'simulator',
128
+ app: 'ios.debug',
129
+ },
130
+ 'ios.sim.release': {
103
131
  device: 'simulator',
104
- app: 'ios',
132
+ app: 'ios.release',
133
+ },
134
+ 'android.att.debug': {
135
+ device: 'attached',
136
+ app: 'android.debug',
137
+ },
138
+ 'android.att.release': {
139
+ device: 'attached',
140
+ app: 'android.release',
141
+ },
142
+ 'android.emu.debug': {
143
+ device: 'emulator',
144
+ app: 'android.debug',
105
145
  },
106
- android: {
146
+ 'android.emu.release': {
107
147
  device: 'emulator',
108
- app: 'android',
148
+ app: 'android.release',
109
149
  },
110
150
  },
111
151
  };
@@ -4,7 +4,7 @@ const path = require('path');
4
4
 
5
5
  const fs = require('fs-extra');
6
6
 
7
- const log = require('../src/utils/logger').child({ __filename });
7
+ const log = require('../src/utils/logger').child({ cat: 'cli' });
8
8
 
9
9
  module.exports.command = 'rebuild-framework-cache';
10
10
  module.exports.desc = 'Rebuilds a cached Detox framework for the current environment in ~/Library/Detox. The cached framework is unique for each combination of Xcode and Detox version. (macOS only)';
@@ -0,0 +1,16 @@
1
+ const { log } = require('../internals');
2
+ const DeviceRegistry = require('../src/devices/DeviceRegistry');
3
+ const { getDetoxLibraryRootPath } = require('../src/utils/environment');
4
+
5
+
6
+ module.exports.command = 'reset-lock-file';
7
+ module.exports.desc = 'Resets all Detox lock files. Useful when you need to run multiple `detox test` commands in parallel with --keepLockFile.';
8
+
9
+ module.exports.handler = async function resetLockFile() {
10
+ await Promise.all([
11
+ DeviceRegistry.forIOS().reset(),
12
+ DeviceRegistry.forAndroid().reset(),
13
+ ]);
14
+
15
+ log.info(`Cleaned lock files from: ${getDetoxLibraryRootPath()}`);
16
+ };
@@ -1,15 +1,18 @@
1
1
  const firstTestContent = require('./firstTestContent');
2
2
 
3
- const runnerConfig = `{
4
- "globalSetup": "detox/runners/jest/globalSetup",
5
- "globalTeardown": "detox/runners/jest/globalTeardown",
6
- "maxWorkers": 1,
7
- "reporters": ["detox/runners/jest/reporter"],
8
- "testEnvironment": "detox/runners/jest/testEnvironment",
9
- "testMatch": ["<rootDir>/e2e/**/*.test.js"],
10
- "testTimeout": 120000,
11
- "verbose": true
12
- }
3
+ const runnerConfig = `\
4
+ /** @type {import('@jest/types').Config.InitialOptions} */
5
+ module.exports = {
6
+ rootDir: '..',
7
+ testMatch: ['<rootDir>/e2e/**/*.test.js'],
8
+ testTimeout: 120000,
9
+ maxWorkers: 1,
10
+ globalSetup: 'detox/runners/jest/globalSetup',
11
+ globalTeardown: 'detox/runners/jest/globalTeardown',
12
+ reporters: ['detox/runners/jest/reporter'],
13
+ testEnvironment: 'detox/runners/jest/testEnvironment',
14
+ verbose: true,
15
+ };
13
16
  `;
14
17
 
15
18
  exports.starter = firstTestContent;