detox 19.13.0 → 20.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (236) hide show
  1. package/Detox-android/com/wix/detox/{19.13.0/detox-19.13.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/{19.13.0/detox-19.13.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/{19.13.0/detox-19.13.0.pom → 20.0.0/detox-20.0.0.pom} +1 -1
  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/detox/src/full/java/com/wix/detox/Detox.java +2 -59
  30. package/android/detox/src/full/java/com/wix/detox/NotificationDataParser.kt +3 -3
  31. package/index.d.ts +354 -191
  32. package/index.js +1 -0
  33. package/internals.d.ts +298 -0
  34. package/internals.js +4 -0
  35. package/local-cli/build-framework-cache.js +2 -2
  36. package/local-cli/build.js +7 -8
  37. package/local-cli/build.test.js +46 -40
  38. package/local-cli/clean-framework-cache.js +3 -3
  39. package/local-cli/cli.js +8 -7
  40. package/local-cli/init.js +73 -68
  41. package/local-cli/rebuild-framework-cache.js +1 -1
  42. package/local-cli/reset-lock-file.js +16 -0
  43. package/local-cli/templates/jest.js +14 -36
  44. package/local-cli/test.js +24 -282
  45. package/local-cli/test.test.js +394 -648
  46. package/local-cli/testCommand/TestRunnerCommand.js +163 -0
  47. package/local-cli/{utils/testCommandArgs.js → testCommand/builder.js} +10 -36
  48. package/local-cli/testCommand/middlewares.js +66 -0
  49. package/local-cli/{utils → testCommand}/warnings.js +0 -13
  50. package/local-cli/utils/jestInternals.js +13 -2
  51. package/local-cli/utils/yargsUtils.js +67 -0
  52. package/package.json +32 -19
  53. package/runners/deprecation.js +45 -0
  54. package/runners/jest/JestCircusEnvironment.js +3 -38
  55. package/runners/jest/adapter.d.ts +4 -10
  56. package/runners/jest/adapter.js +3 -6
  57. package/runners/jest/assignReporter.d.ts +4 -1
  58. package/runners/jest/assignReporter.js +3 -6
  59. package/runners/jest/globalSetup.js +1 -0
  60. package/runners/jest/globalTeardown.js +1 -0
  61. package/runners/jest/index.d.ts +60 -0
  62. package/runners/jest/index.js +16 -0
  63. package/runners/jest/index.test.js +13 -0
  64. package/runners/jest/reporter.js +1 -0
  65. package/runners/jest/reporters/DetoxReporter.js +36 -0
  66. package/runners/jest/specReporter.d.ts +4 -9
  67. package/runners/jest/specReporter.js +3 -10
  68. package/runners/jest/streamlineReporter.js +3 -22
  69. package/runners/jest/testEnvironment/index.js +205 -0
  70. package/runners/jest/testEnvironment/listeners/DetoxCoreListener.js +166 -0
  71. package/runners/{jest-circus → jest/testEnvironment}/listeners/DetoxInitErrorListener.js +1 -1
  72. package/runners/jest/testEnvironment/listeners/DetoxPlatformFilterListener.js +27 -0
  73. package/runners/jest/{SpecReporterImpl.js → testEnvironment/listeners/SpecReporter.js} +61 -9
  74. package/runners/jest/testEnvironment/listeners/WorkerAssignReporter.js +30 -0
  75. package/runners/jest/testEnvironment/listeners/index.js +13 -0
  76. package/runners/{jest-circus → jest/testEnvironment}/utils/assertExistingContext.js +2 -2
  77. package/runners/jest/testEnvironment/utils/assertJestCircus27.js +70 -0
  78. package/runners/jest/testEnvironment/utils/assertJestCircus27.test.js +22 -0
  79. package/runners/jest/{utils → testEnvironment/utils}/getFullTestName.js +0 -0
  80. package/runners/jest/{utils → testEnvironment/utils}/hasTimedOut.js +0 -0
  81. package/runners/jest/{utils → testEnvironment/utils}/index.js +0 -0
  82. package/runners/jest/{utils → testEnvironment/utils}/stdout.js +0 -0
  83. package/runners/jest-circus/environment/index.js +6 -0
  84. package/runners/jest-circus/index.js +1 -10
  85. package/runners/jest-circus/reporter.js +1 -0
  86. package/runners/migration.js +37 -0
  87. package/runners/mocha/DetoxMochaAdapter.js +3 -35
  88. package/runners/mocha/adapter.d.ts +4 -7
  89. package/runners/mocha/adapter.js +3 -5
  90. package/src/DetoxWorker.js +327 -0
  91. package/src/android/interactions/native.js +2 -1
  92. package/src/artifacts/ArtifactsManager.js +51 -35
  93. package/src/artifacts/instruments/ios/SimulatorInstrumentsRecording.js +3 -3
  94. package/src/artifacts/log/ios/SimulatorLogRecording.js +1 -1
  95. package/src/artifacts/providers/index.js +0 -4
  96. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +1 -1
  97. package/src/artifacts/templates/artifact/Artifact.js +1 -1
  98. package/src/artifacts/templates/plugin/ArtifactPlugin.js +1 -1
  99. package/src/artifacts/utils/buildDefaultArtifactsRootDirpath.js +2 -4
  100. package/src/artifacts/utils/temporaryPath.js +18 -5
  101. package/src/artifacts/video/SimulatorRecordVideoPlugin.js +1 -1
  102. package/src/client/AsyncWebSocket.js +8 -17
  103. package/src/client/Client.js +1 -1
  104. package/src/client/actions/actions.js +2 -2
  105. package/src/configuration/collectCliConfig.js +3 -16
  106. package/src/configuration/composeAppsConfig.js +12 -66
  107. package/src/configuration/composeArtifactsConfig.js +6 -32
  108. package/src/configuration/composeBehaviorConfig.js +3 -13
  109. package/src/configuration/composeDeviceConfig.js +38 -63
  110. package/src/configuration/composeLoggerConfig.js +59 -0
  111. package/src/configuration/composeRunnerConfig.js +127 -14
  112. package/src/configuration/composeSessionConfig.js +1 -3
  113. package/src/configuration/index.js +36 -30
  114. package/src/configuration/loadExternalConfig.js +1 -1
  115. package/src/configuration/utils/deviceAppTypes.js +0 -1
  116. package/src/devices/allocation/DeviceAllocator.js +4 -2
  117. package/src/devices/allocation/drivers/android/emulator/AVDValidator.js +1 -1
  118. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +5 -3
  119. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +1 -1
  120. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +3 -5
  121. package/src/devices/allocation/drivers/android/emulator/EmulatorVersionResolver.js +4 -6
  122. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +1 -1
  123. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +1 -1
  124. package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +1 -1
  125. package/src/devices/allocation/drivers/ios/SimulatorLauncher.js +3 -3
  126. package/src/devices/allocation/factories/index.js +0 -1
  127. package/src/devices/common/drivers/DeviceLauncher.js +2 -2
  128. package/src/devices/common/drivers/android/emulator/exec/EmulatorExec.js +1 -1
  129. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +4 -9
  130. package/src/devices/common/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  131. package/src/devices/common/drivers/android/tools/EmulatorTelnet.js +1 -1
  132. package/src/devices/common/drivers/android/tools/FreeDeviceFinder.js +1 -1
  133. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +35 -10
  134. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +13 -15
  135. package/src/devices/runtime/RuntimeDevice.js +85 -86
  136. package/src/devices/runtime/drivers/DeviceDriverBase.js +1 -1
  137. package/src/devices/runtime/drivers/android/AndroidDriver.js +3 -3
  138. package/src/devices/runtime/drivers/index.js +0 -1
  139. package/src/devices/runtime/drivers/ios/SimulatorDriver.js +4 -3
  140. package/src/devices/runtime/factories/ios.js +1 -8
  141. package/src/devices/runtime/utils/LaunchArgsEditor.js +4 -59
  142. package/src/devices/runtime/utils/Storage.js +4 -0
  143. package/src/environmentFactory.js +0 -8
  144. package/src/errors/DetoxConfigErrorComposer.js +92 -30
  145. package/src/errors/DetoxError.js +4 -0
  146. package/src/errors/DetoxRuntimeError.js +5 -5
  147. package/src/errors/index.js +2 -0
  148. package/src/ios/expectTwo.js +2 -1
  149. package/src/ipc/IPCClient.js +117 -0
  150. package/src/ipc/IPCServer.js +98 -0
  151. package/src/ipc/SessionState.js +62 -0
  152. package/src/logger/DetoxLogger.js +348 -0
  153. package/src/logger/index.js +5 -0
  154. package/src/logger/utils/BunyanLogger.js +76 -0
  155. package/src/logger/utils/CategoryThreadDispatcher.js +36 -0
  156. package/src/logger/utils/DetoxLogFinalizer.js +140 -0
  157. package/src/logger/utils/MessageStack.js +24 -0
  158. package/src/logger/utils/ThreadDispatcher.js +61 -0
  159. package/src/{utils → logger/utils}/customConsoleLogger.js +5 -4
  160. package/src/logger/utils/sanitizeBunyanContext.js +30 -0
  161. package/src/logger/utils/streamUtils.js +248 -0
  162. package/src/logger/utils/tracerLegacy.js +37 -0
  163. package/src/realms/DetoxConstants.js +13 -0
  164. package/src/realms/DetoxContext.js +183 -0
  165. package/src/realms/DetoxInternalsFacade.js +31 -0
  166. package/src/realms/DetoxPrimaryContext.js +261 -0
  167. package/src/realms/DetoxSecondaryContext.js +91 -0
  168. package/src/realms/index.js +10 -0
  169. package/src/realms/primary.js +3 -0
  170. package/src/realms/secondary.js +3 -0
  171. package/src/server/DetoxConnection.js +18 -23
  172. package/src/server/DetoxServer.js +7 -10
  173. package/src/server/DetoxSession.js +6 -6
  174. package/src/server/DetoxSessionManager.js +1 -1
  175. package/src/server/handlers/RegisteredConnectionHandler.js +1 -2
  176. package/src/symbols.js +50 -0
  177. package/src/utils/Timer.js +58 -33
  178. package/src/utils/argparse.js +11 -0
  179. package/src/utils/childProcess/exec.js +1 -1
  180. package/src/utils/childProcess/spawn.js +1 -1
  181. package/{local-cli/utils/misc.js → src/utils/envUtils.js} +0 -9
  182. package/src/utils/errorUtils.js +20 -0
  183. package/src/utils/logger.js +2 -162
  184. package/src/utils/shellUtils.js +18 -0
  185. package/src/utils/traceInvocationCall.js +21 -0
  186. package/src/utils/traceMethods.js +15 -0
  187. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0-javadoc.jar.md5 +0 -1
  188. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0-javadoc.jar.sha1 +0 -1
  189. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0-javadoc.jar.sha256 +0 -1
  190. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0-javadoc.jar.sha512 +0 -1
  191. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0-sources.jar.md5 +0 -1
  192. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0-sources.jar.sha1 +0 -1
  193. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0-sources.jar.sha256 +0 -1
  194. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0-sources.jar.sha512 +0 -1
  195. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0.aar +0 -0
  196. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0.aar.md5 +0 -1
  197. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0.aar.sha1 +0 -1
  198. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0.aar.sha256 +0 -1
  199. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0.aar.sha512 +0 -1
  200. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0.pom.md5 +0 -1
  201. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0.pom.sha1 +0 -1
  202. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0.pom.sha256 +0 -1
  203. package/Detox-android/com/wix/detox/19.13.0/detox-19.13.0.pom.sha512 +0 -1
  204. package/local-cli/templates/mocha.js +0 -32
  205. package/local-cli/utils/splitArgv.js +0 -107
  206. package/runners/integration.js +0 -16
  207. package/runners/jest/DetoxAdapterCircus.js +0 -60
  208. package/runners/jest/DetoxAdapterImpl.js +0 -81
  209. package/runners/jest/DetoxAdapterJasmine.js +0 -67
  210. package/runners/jest/DetoxStreamlineJestReporter.js +0 -98
  211. package/runners/jest/FailingTestsReporter.js +0 -16
  212. package/runners/jest/SpecReporterCircus.js +0 -51
  213. package/runners/jest/SpecReporterJasmine.js +0 -39
  214. package/runners/jest/WorkerAssignReporterCircus.js +0 -17
  215. package/runners/jest/WorkerAssignReporterImpl.js +0 -21
  216. package/runners/jest/WorkerAssignReporterJasmine.js +0 -15
  217. package/runners/jest/runnerInfo.js +0 -9
  218. package/runners/jest-circus/environment.js +0 -206
  219. package/runners/jest-circus/listeners/DetoxCoreListener.js +0 -113
  220. package/runners/jest-circus/utils/assertJestCircus26.js +0 -39
  221. package/runners/jest-circus/utils/wrapErrorWithNoopLifecycle.js +0 -14
  222. package/src/Detox.js +0 -317
  223. package/src/DetoxConstants.js +0 -13
  224. package/src/DetoxExportWrapper.js +0 -140
  225. package/src/artifacts/timeline/TimelineArtifactPlugin.js +0 -92
  226. package/src/configuration/utils/warnings.js +0 -12
  227. package/src/devices/allocation/drivers/NoneAllocDriver.js +0 -10
  228. package/src/devices/allocation/factories/none.js +0 -11
  229. package/src/index.js +0 -6
  230. package/src/utils/ChromeTracingExporter.js +0 -54
  231. package/src/utils/MissingDetox.js +0 -78
  232. package/src/utils/fakeTimestampsProvider.js +0 -9
  233. package/src/utils/getWorkerId.js +0 -5
  234. package/src/utils/lastFailedTests.js +0 -38
  235. package/src/utils/sh.js +0 -18
  236. package/src/utils/trace.js +0 -96
@@ -0,0 +1,327 @@
1
+ const CAF = require('caf');
2
+ const _ = require('lodash');
3
+
4
+ const Client = require('./client/Client');
5
+ const environmentFactory = require('./environmentFactory');
6
+ const { DetoxRuntimeErrorComposer } = require('./errors');
7
+ const { InvocationManager } = require('./invoke');
8
+ const symbols = require('./symbols');
9
+ const AsyncEmitter = require('./utils/AsyncEmitter');
10
+ const uuid = require('./utils/uuid');
11
+
12
+ class DetoxWorker {
13
+ constructor(context) {
14
+ this._context = context;
15
+ this._injectedGlobalProperties = [];
16
+ this._config = context[symbols.config];
17
+ this._runtimeErrorComposer = new DetoxRuntimeErrorComposer(this._config);
18
+ this._client = null;
19
+ this._artifactsManager = null;
20
+ this._eventEmitter = new AsyncEmitter({
21
+ events: [
22
+ 'bootDevice',
23
+ 'beforeShutdownDevice',
24
+ 'shutdownDevice',
25
+ 'beforeTerminateApp',
26
+ 'terminateApp',
27
+ 'beforeUninstallApp',
28
+ 'beforeLaunchApp',
29
+ 'launchApp',
30
+ 'appReady',
31
+ 'createExternalArtifact',
32
+ ],
33
+ onError: this._onEmitError.bind(this),
34
+ });
35
+
36
+
37
+ /** @type {DetoxInternals.RuntimeConfig['apps']} */
38
+ this._appsConfig = null;
39
+ /** @type {DetoxInternals.RuntimeConfig['artifacts']} */
40
+ this._artifactsConfig = null;
41
+ /** @type {DetoxInternals.RuntimeConfig['behavior']} */
42
+ this._behaviorConfig = null;
43
+ /** @type {DetoxInternals.RuntimeConfig['device']} */
44
+ this._deviceConfig = null;
45
+ /** @type {DetoxInternals.RuntimeConfig['session']} */
46
+ this._sessionConfig = null;
47
+
48
+ /** @type {string} */
49
+ this.id = 'worker';
50
+ /** @type {Detox.Device} */
51
+ this.device = null;
52
+ /** @type {Detox.ElementFacade} */
53
+ this.element = null;
54
+ /** @type {Detox.WaitForFacade} */
55
+ this.waitFor = null;
56
+ /** @type {Detox.ExpectFacade} */
57
+ this.expect = null;
58
+ /** @type {Detox.ByFacade} */
59
+ this.by = null;
60
+ /** @type {Detox.WebFacade} */
61
+ this.web = null;
62
+
63
+ this._deviceAllocator = null;
64
+ this._deviceCookie = null;
65
+
66
+ this.trace = this._context.trace;
67
+ /** @deprecated */
68
+ this.traceCall = this._context.traceCall;
69
+
70
+ this._reinstallAppsOnDevice = CAF(this._reinstallAppsOnDevice.bind(this));
71
+ this._initToken = new CAF.cancelToken();
72
+
73
+ this._cafWrap([
74
+ 'init',
75
+ 'onRunDescribeStart',
76
+ 'onTestStart',
77
+ 'onHookFailure',
78
+ 'onTestFnFailure',
79
+ 'onTestDone',
80
+ 'onRunDescribeFinish',
81
+ ]);
82
+ }
83
+
84
+ /** @this {DetoxWorker} */
85
+ init = function* (signal) {
86
+ const {
87
+ apps: appsConfig,
88
+ artifacts: artifactsConfig,
89
+ behavior: behaviorConfig,
90
+ device: deviceConfig,
91
+ session: sessionConfig
92
+ } = this._config;
93
+
94
+ this._appsConfig = appsConfig;
95
+ this._artifactsConfig = artifactsConfig;
96
+ this._behaviorConfig = behaviorConfig;
97
+ this._deviceConfig = deviceConfig;
98
+ this._sessionConfig = sessionConfig;
99
+ // @ts-ignore
100
+ this._sessionConfig.sessionId = sessionConfig.sessionId || uuid.UUID();
101
+ this._runtimeErrorComposer.appsConfig = this._appsConfig;
102
+
103
+ this._client = new Client(sessionConfig);
104
+ this._client.terminateApp = async () => {
105
+ // @ts-ignore
106
+ if (this.device && this.device._isAppRunning()) {
107
+ await this.device.terminateApp();
108
+ }
109
+ };
110
+
111
+ yield this._client.connect();
112
+
113
+ const invocationManager = new InvocationManager(this._client);
114
+
115
+ const {
116
+ // @ts-ignore
117
+ envValidatorFactory,
118
+ deviceAllocatorFactory,
119
+ // @ts-ignore
120
+ artifactsManagerFactory,
121
+ // @ts-ignore
122
+ matchersFactory,
123
+ // @ts-ignore
124
+ runtimeDeviceFactory,
125
+ } = environmentFactory.createFactories(this._deviceConfig);
126
+
127
+ const envValidator = envValidatorFactory.createValidator();
128
+ yield envValidator.validate();
129
+
130
+ const commonDeps = {
131
+ invocationManager,
132
+ client: this._client,
133
+ eventEmitter: this._eventEmitter,
134
+ runtimeErrorComposer: this._runtimeErrorComposer,
135
+ };
136
+
137
+ this._artifactsManager = artifactsManagerFactory.createArtifactsManager(this._artifactsConfig, commonDeps);
138
+ this._deviceAllocator = deviceAllocatorFactory.createDeviceAllocator(commonDeps);
139
+ this._deviceCookie = yield this._deviceAllocator.allocate(this._deviceConfig);
140
+
141
+ this.device = runtimeDeviceFactory.createRuntimeDevice(
142
+ this._deviceCookie,
143
+ commonDeps,
144
+ {
145
+ appsConfig: this._appsConfig,
146
+ behaviorConfig: this._behaviorConfig,
147
+ deviceConfig: this._deviceConfig,
148
+ sessionConfig,
149
+ });
150
+
151
+ const matchers = matchersFactory.createMatchers({
152
+ invocationManager,
153
+ runtimeDevice: this.device,
154
+ eventEmitter: this._eventEmitter,
155
+ });
156
+ Object.assign(this, matchers);
157
+
158
+ if (behaviorConfig.init.exposeGlobals) {
159
+ const injectedGlobals = {
160
+ ...matchers,
161
+ device: this.device,
162
+ detox: this,
163
+ };
164
+
165
+ this._injectedGlobalProperties = Object.keys(injectedGlobals);
166
+ Object.assign(DetoxWorker.global, injectedGlobals);
167
+ }
168
+
169
+ // @ts-ignore
170
+ yield this.device.installUtilBinaries();
171
+
172
+ if (behaviorConfig.init.reinstallApp) {
173
+ yield this._reinstallAppsOnDevice(signal);
174
+ }
175
+
176
+ const appAliases = Object.keys(this._appsConfig);
177
+ if (appAliases.length === 1) {
178
+ yield this.device.selectApp(appAliases[0]);
179
+ } else {
180
+ yield this.device.selectApp(null);
181
+ }
182
+ };
183
+
184
+ async cleanup() {
185
+ this._initToken.abort('CLEANUP');
186
+
187
+ for (const key of this._injectedGlobalProperties) {
188
+ delete DetoxWorker.global[key];
189
+ }
190
+
191
+ if (this._artifactsManager) {
192
+ await this._artifactsManager.onBeforeCleanup();
193
+ this._artifactsManager = null;
194
+ }
195
+
196
+ if (this._client) {
197
+ this._client.dumpPendingRequests();
198
+ await this._client.cleanup();
199
+ this._client = null;
200
+ }
201
+
202
+ if (this.device) {
203
+ const shutdown = this._behaviorConfig ? this._behaviorConfig.cleanup.shutdownDevice : false;
204
+ // @ts-ignore
205
+ await this.device._cleanup();
206
+ await this._deviceAllocator.free(this._deviceCookie, { shutdown });
207
+ }
208
+
209
+ this._deviceAllocator = null;
210
+ this._deviceCookie = null;
211
+ this.device = null;
212
+ }
213
+
214
+ get log() {
215
+ return this._context.log;
216
+ }
217
+
218
+ onRunDescribeStart = function* (_signal, ...args) {
219
+ yield this._artifactsManager.onRunDescribeStart(...args);
220
+ };
221
+
222
+ onTestStart = function* (_signal, testSummary) {
223
+ this._validateTestSummary('beforeEach', testSummary);
224
+
225
+ yield this._dumpUnhandledErrorsIfAny({
226
+ pendingRequests: false,
227
+ testName: testSummary.fullName,
228
+ });
229
+
230
+ yield this._artifactsManager.onTestStart(testSummary);
231
+ };
232
+
233
+ onHookFailure = function* (_signal, ...args) {
234
+ yield this._artifactsManager.onHookFailure(...args);
235
+ };
236
+
237
+ onTestFnFailure = function* (_signal, ...args) {
238
+ yield this._artifactsManager.onTestFnFailure(...args);
239
+ };
240
+
241
+ onTestDone = function* (_signal, testSummary) {
242
+ this._validateTestSummary('afterEach', testSummary);
243
+
244
+ yield this._artifactsManager.onTestDone(testSummary);
245
+
246
+ yield this._dumpUnhandledErrorsIfAny({
247
+ pendingRequests: testSummary.timedOut,
248
+ testName: testSummary.fullName,
249
+ });
250
+ };
251
+
252
+ onRunDescribeFinish = function* (_signal, ...args) {
253
+ yield this._artifactsManager.onRunDescribeFinish(...args);
254
+ };
255
+
256
+ *_reinstallAppsOnDevice(_signal) {
257
+ const appNames = _(this._appsConfig)
258
+ .map((config, key) => [key, `${config.binaryPath}:${config.testBinaryPath}`])
259
+ .uniqBy(1)
260
+ .map(0)
261
+ .value();
262
+
263
+ for (const appName of appNames) {
264
+ yield this.device.selectApp(appName);
265
+ yield this.device.uninstallApp();
266
+ }
267
+
268
+ for (const appName of appNames) {
269
+ yield this.device.selectApp(appName);
270
+ yield this.device.installApp();
271
+ }
272
+ }
273
+
274
+ _validateTestSummary(methodName, testSummary) {
275
+ if (!_.isPlainObject(testSummary)) {
276
+ throw this._runtimeErrorComposer.invalidTestSummary(methodName, testSummary);
277
+ }
278
+
279
+ switch (testSummary.status) {
280
+ case 'running':
281
+ case 'passed':
282
+ case 'failed':
283
+ break;
284
+ default:
285
+ throw this._runtimeErrorComposer.invalidTestSummaryStatus(methodName, testSummary);
286
+ }
287
+ }
288
+
289
+ async _dumpUnhandledErrorsIfAny({ testName, pendingRequests }) {
290
+ if (pendingRequests) {
291
+ this._client.dumpPendingRequests({ testName });
292
+ }
293
+ }
294
+
295
+ _onEmitError({ error, eventName, eventObj }) {
296
+ this.log.error(
297
+ { event: 'EMIT_ERROR', fn: eventName },
298
+ `Caught an exception in: emitter.emit("${eventName}", ${JSON.stringify(eventObj)})\n\n`,
299
+ error
300
+ );
301
+ }
302
+
303
+ _cafWrap(methodNames) {
304
+ for (const methodName of methodNames) {
305
+ const cafMethod = CAF(this[methodName].bind(this));
306
+ this[methodName] = async (...args) => {
307
+ try {
308
+ await cafMethod(this._initToken.signal, ...args);
309
+ } catch (e) {
310
+ if (e !== 'CLEANUP') {
311
+ throw e;
312
+ }
313
+ }
314
+
315
+ return this;
316
+ };
317
+ }
318
+ }
319
+
320
+ }
321
+
322
+ /**
323
+ * @type {NodeJS.Global | {}}
324
+ */
325
+ DetoxWorker.global = global;
326
+
327
+ module.exports = DetoxWorker;
@@ -1,6 +1,7 @@
1
1
  const DetoxRuntimeError = require('../../errors/DetoxRuntimeError');
2
2
  const { expectDescription, actionDescription } = require('../../utils/invocationTraceDescriptions');
3
- const { traceInvocationCall } = require('../../utils/trace');
3
+ const log = require('../../utils/logger').child({ cat: 'ws-client, ws' });
4
+ const traceInvocationCall = require('../../utils/traceInvocationCall').bind(null, log);
4
5
  const { ScrollAmountStopAtEdgeAction } = require('../actions/native');
5
6
  const { NativeMatcher } = require('../core/NativeMatcher');
6
7
  const DetoxAssertionApi = require('../espressoapi/DetoxAssertion');
@@ -1,24 +1,66 @@
1
1
  const EventEmitter = require('events');
2
2
  const path = require('path');
3
- const util = require('util');
4
3
 
5
4
  const fs = require('fs-extra');
6
5
  const _ = require('lodash');
7
6
 
8
7
  const DetoxRuntimeError = require('../errors/DetoxRuntimeError');
9
- const log = require('../utils/logger').child({ __filename });
8
+ const log = require('../utils/logger').child({ cat: 'artifacts-manager,artifact' });
9
+ const resolveModuleFromPath = require('../utils/resolveModuleFromPath');
10
+ const traceMethods = require('../utils/traceMethods');
10
11
 
11
12
  const FileArtifact = require('./templates/artifact/FileArtifact');
13
+ const ArtifactPathBuilder = require('./utils/ArtifactPathBuilder');
12
14
 
13
15
  class ArtifactsManager extends EventEmitter {
14
- constructor({ pathBuilder, plugins }) {
16
+ constructor({ rootDir, pathBuilder, plugins }) {
15
17
  super();
16
18
 
17
19
  this._pluginConfigs = plugins;
18
20
  this._idlePromise = Promise.resolve();
19
21
  this._idleCallbackRequests = [];
20
22
  this._artifactPlugins = {};
21
- this._pathBuilder = pathBuilder;
23
+ this._pathBuilder = this._resolveArtifactsPathBuilder(pathBuilder, rootDir);
24
+
25
+ traceMethods(log, this, [
26
+ 'onAppReady',
27
+ 'onBeforeCleanup',
28
+ 'onBeforeLaunchApp',
29
+ 'onBeforeShutdownDevice',
30
+ 'onBeforeTerminateApp',
31
+ 'onBeforeUninstallApp',
32
+ 'onBootDevice',
33
+ 'onCreateExternalArtifact',
34
+ 'onHookFailure',
35
+ 'onLaunchApp',
36
+ 'onRunDescribeFinish',
37
+ 'onRunDescribeStart',
38
+ 'onShutdownDevice',
39
+ 'onTerminateApp',
40
+ 'onTestDone',
41
+ 'onTestFnFailure',
42
+ 'onTestStart',
43
+ ]);
44
+ }
45
+
46
+ _resolveArtifactsPathBuilder(pathBuilder, rootDir) {
47
+ if (typeof pathBuilder === 'string') {
48
+ pathBuilder = resolveModuleFromPath(pathBuilder);
49
+ }
50
+
51
+ if (typeof pathBuilder === 'function') {
52
+ try {
53
+ pathBuilder = pathBuilder({ rootDir });
54
+ } catch (e) {
55
+ pathBuilder = new pathBuilder({ rootDir });
56
+ }
57
+ }
58
+
59
+ if (!pathBuilder) {
60
+ pathBuilder = new ArtifactPathBuilder({ rootDir });
61
+ }
62
+
63
+ return pathBuilder;
22
64
  }
23
65
 
24
66
  _instantiateArtifactPlugin(pluginFactory, pluginUserConfig) {
@@ -137,8 +179,6 @@ class ArtifactsManager extends EventEmitter {
137
179
  });
138
180
  }
139
181
 
140
- async onRunStart() {}
141
-
142
182
  async onRunDescribeStart(suite) {
143
183
  await this._callPlugins('ascending', 'onRunDescribeStart', suite);
144
184
  }
@@ -147,22 +187,14 @@ class ArtifactsManager extends EventEmitter {
147
187
  await this._callPlugins('ascending', 'onTestStart', testSummary);
148
188
  }
149
189
 
150
- async onHookStart() {}
151
-
152
190
  async onHookFailure(testSummary) {
153
191
  await this._callPlugins('plain', 'onHookFailure', testSummary);
154
192
  }
155
193
 
156
- async onHookSuccess() {}
157
-
158
- async onTestFnStart() {}
159
-
160
194
  async onTestFnFailure(testSummary) {
161
195
  await this._callPlugins('plain', 'onTestFnFailure', testSummary);
162
196
  }
163
197
 
164
- async onTestFnSuccess() {}
165
-
166
198
  async onTestDone(testSummary) {
167
199
  await this._callPlugins('descending', 'onTestDone', testSummary);
168
200
  }
@@ -171,35 +203,27 @@ class ArtifactsManager extends EventEmitter {
171
203
  await this._callPlugins('descending', 'onRunDescribeFinish', suite);
172
204
  }
173
205
 
174
- async onRunFinish() {}
175
-
176
206
  async onBeforeCleanup() {
177
207
  await this._callPlugins('descending', 'onBeforeCleanup');
178
208
  await this._idlePromise;
179
209
  }
180
210
 
181
211
  async _callSinglePlugin(pluginId, methodName, ...args) {
182
- const callSignature = this._composeCallSignature('artifactsManager', methodName, args);
183
- log.trace(Object.assign({ event: 'ARTIFACTS_LIFECYCLE', fn: methodName }, ...args), callSignature);
184
-
185
212
  const plugin = this._artifactPlugins[pluginId];
186
213
  try {
187
214
  await plugin[methodName](...args);
188
215
  } catch (e) {
189
- this._unhandledPluginExceptionHandler(e, { plugin, methodName, args });
216
+ this._unhandledPluginExceptionHandler(e, { plugin, methodName });
190
217
  }
191
218
  }
192
219
 
193
220
  async _callPlugins(strategy, methodName, ...args) {
194
- const callSignature = this._composeCallSignature('artifactsManager', methodName, args);
195
- log.trace(Object.assign({ event: 'ARTIFACTS_LIFECYCLE', fn: methodName }, ...args), callSignature);
196
-
197
221
  for (const pluginGroup of this._groupPlugins(strategy)) {
198
222
  await Promise.all(pluginGroup.map(async (plugin) => {
199
223
  try {
200
224
  await plugin[methodName](...args);
201
225
  } catch (e) {
202
- this._unhandledPluginExceptionHandler(e, { plugin, methodName, args });
226
+ this._unhandledPluginExceptionHandler(e, { plugin, methodName });
203
227
  }
204
228
  }));
205
229
  }
@@ -229,28 +253,20 @@ class ArtifactsManager extends EventEmitter {
229
253
  }
230
254
  }
231
255
 
232
- _composeCallSignature(object, methodName, args) {
233
- const argsString = args.map(arg => util.inspect(arg)).join(', ');
234
- return `${object}.${methodName}(${argsString})`;
235
- }
236
-
237
- _unhandledPluginExceptionHandler(err, { plugin, methodName, args }) {
256
+ _unhandledPluginExceptionHandler(err, { plugin, methodName }) {
238
257
  const logObject = {
239
- event: 'ERROR',
240
258
  plugin: plugin.name,
241
- err,
242
259
  methodName,
260
+ err,
243
261
  };
244
262
 
245
- const callSignature = this._composeCallSignature(plugin.name, methodName, args);
246
- log.warn(logObject, `Suppressed error inside function call: ${callSignature}`);
263
+ log.warn(logObject, `Suppressed error inside function call.`);
247
264
  }
248
265
 
249
266
  _idleCallbackErrorHandle(err, caller) {
250
267
  this._unhandledPluginExceptionHandler(err, {
251
268
  plugin: caller,
252
269
  methodName: 'onIdleCallback',
253
- args: []
254
270
  });
255
271
  }
256
272
  }
@@ -2,7 +2,7 @@
2
2
  const fs = require('fs-extra');
3
3
  const _ = require('lodash');
4
4
 
5
- const log = require('../../../utils/logger').child({ __filename });
5
+ const log = require('../../../utils/logger').child({ cat: 'artifact' });
6
6
  const FileArtifact = require('../../templates/artifact/FileArtifact');
7
7
  const InstrumentsArtifactRecording = require('../InstrumentsArtifactRecording');
8
8
 
@@ -37,9 +37,9 @@ class SimulatorInstrumentsRecording extends InstrumentsArtifactRecording {
37
37
  SimulatorInstrumentsRecording.hintAboutDetoxInstruments = _.once(() => {
38
38
  log.warn(`Make sure either:
39
39
  1. You have installed Detox Instruments:
40
- https://github.com/wix/DetoxInstruments#installation
40
+ https://github.com/wix/DetoxInstruments#installation
41
41
  2. You have integrated Detox Instruments in your app:
42
- https://github.com/wix/DetoxInstruments/blob/master/Documentation/XcodeIntegrationGuide.md
42
+ https://github.com/wix/DetoxInstruments/blob/master/Documentation/XcodeIntegrationGuide.md
43
43
  3. You have set the environment variable with your custom Detox Instruments location:
44
44
  export DETOX_INSTRUMENTS_PATH="/path/to/Detox Instruments.app"`);
45
45
  });
@@ -2,7 +2,7 @@
2
2
  const fs = require('fs-extra');
3
3
 
4
4
  const childProcess = require('../../../utils/childProcess');
5
- const log = require('../../../utils/logger').child({ __filename });
5
+ const log = require('../../../utils/logger').child({ cat: 'artifact' });
6
6
  const sleep = require('../../../utils/sleep');
7
7
  const Artifact = require('../../templates/artifact/Artifact');
8
8
  const FileArtifact = require('../../templates/artifact/FileArtifact');
@@ -12,25 +12,21 @@ class AndroidArtifactPluginsProvider extends ArtifactPluginsProvider {
12
12
  const ADBLogcatPlugin = require('../log/android/ADBLogcatPlugin');
13
13
  const ADBScreencapPlugin = require('../screenshot/ADBScreencapPlugin');
14
14
  const ADBScreenrecorderPlugin = require('../video/ADBScreenrecorderPlugin');
15
- const TimelineArtifactPlugin = require('../timeline/TimelineArtifactPlugin');
16
15
 
17
16
  return {
18
17
  instruments: (api) => new AndroidInstrumentsPlugin({ api, adb, client, devicePathBuilder }),
19
18
  log: (api) => new ADBLogcatPlugin({ api, adb, devicePathBuilder }),
20
19
  screenshot: (api) => new ADBScreencapPlugin({ api, adb, devicePathBuilder }),
21
20
  video: (api) => new ADBScreenrecorderPlugin({ api, adb, devicePathBuilder }),
22
- timeline: (api) => new TimelineArtifactPlugin({ api }),
23
21
  };
24
22
  }
25
23
  }
26
24
 
27
25
  class IosArtifactPluginsProvider extends ArtifactPluginsProvider {
28
26
  declareArtifactPlugins({ client }) {
29
- const TimelineArtifactPlugin = require('../timeline/TimelineArtifactPlugin');
30
27
  const IosUIHierarchyPlugin = require('../uiHierarchy/IosUIHierarchyPlugin');
31
28
 
32
29
  return {
33
- timeline: (api) => new TimelineArtifactPlugin({ api }),
34
30
  uiHierarchy: (api) => new IosUIHierarchyPlugin({ api, client }),
35
31
  };
36
32
  }
@@ -1,7 +1,7 @@
1
1
  const path = require('path');
2
2
 
3
3
  const fs = require('../../utils/fsext');
4
- const log = require('../../utils/logger').child({ __filename });
4
+ const log = require('../../utils/logger').child({ cat: 'artifacts-plugin,artifacts' });
5
5
  const FileArtifact = require('../templates/artifact/FileArtifact');
6
6
  const temporaryPath = require('../utils/temporaryPath');
7
7
 
@@ -1,5 +1,5 @@
1
1
  // @ts-nocheck
2
- const log = require('../../../utils/logger').child({ __filename });
2
+ const log = require('../../../utils/logger').child({ cat: 'artifact' });
3
3
 
4
4
  class Artifact {
5
5
  constructor(template) {
@@ -3,7 +3,7 @@
3
3
 
4
4
  const _ = require('lodash');
5
5
 
6
- const log = require('../../../utils/logger').child({ __filename });
6
+ const log = require('../../../utils/logger').child({ cat: 'artifacts-plugin,artifacts' });
7
7
 
8
8
  /***
9
9
  * Almost non-opinionated building block for any artifact type
@@ -4,12 +4,10 @@ const getTimeStampString = require('./getTimeStampString');
4
4
 
5
5
  function buildDefaultRootForArtifactsRootDirpath(configuration, rootDir) {
6
6
  if (rootDir.endsWith('/') || rootDir.endsWith('\\')) {
7
- return rootDir;
7
+ return rootDir.slice(0, -1);
8
8
  }
9
9
 
10
- const seed = Number(process.env.DETOX_START_TIMESTAMP || String(Date.now()));
11
- const subdir = `${configuration}.${getTimeStampString(new Date(seed))}`;
12
- return path.join(rootDir, subdir);
10
+ return path.join(rootDir, `${configuration}.${getTimeStampString(new Date())}`);
13
11
  }
14
12
 
15
13
  module.exports = buildDefaultRootForArtifactsRootDirpath;
@@ -2,13 +2,26 @@ const path = require('path');
2
2
 
3
3
  const tempfile = require('tempfile');
4
4
 
5
+ function createTempFileBuilderFn(fileExtension) {
6
+ /**
7
+ * @param {string} [basename]
8
+ */
9
+ return (basename) => {
10
+ return basename
11
+ ? path.join(path.dirname(tempfile()), `${basename}.detox.${fileExtension}`)
12
+ : tempfile(`.detox.${fileExtension}`);
13
+ };
14
+ }
15
+
5
16
  module.exports = {
6
17
  for: {
7
- png: () => tempfile('.detox.png'),
8
- log: () => tempfile('.detox.log'),
9
- mp4: () => tempfile('.detox.mp4'),
10
- dtxrec: () => tempfile('.detox.dtxrec'),
11
- viewhierarchy: () => tempfile('.detox.viewhierarchy'),
18
+ json: createTempFileBuilderFn('json'),
19
+ jsonl: createTempFileBuilderFn('jsonl'),
20
+ png: createTempFileBuilderFn('png'),
21
+ log: createTempFileBuilderFn('log'),
22
+ mp4: createTempFileBuilderFn('mp4'),
23
+ dtxrec: createTempFileBuilderFn('dtxrec'),
24
+ viewhierarchy: createTempFileBuilderFn('viewhierarchy'),
12
25
  },
13
26
  mask: () => path.join(tempfile(), '..') + path.sep + '*.detox.*',
14
27
  };
@@ -1,7 +1,7 @@
1
1
  const fs = require('fs-extra');
2
2
 
3
3
  const { interruptProcess } = require('../../utils/childProcess');
4
- const log = require('../../utils/logger').child({ __filename });
4
+ const log = require('../../utils/logger').child({ cat: 'artifacts-plugin,artifact' });
5
5
  const Artifact = require('../templates/artifact/Artifact');
6
6
  const FileArtifact = require('../templates/artifact/FileArtifact');
7
7
  const temporaryPath = require('../utils/temporaryPath');