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,261 @@
1
+ const { URL } = require('url');
2
+
3
+ const fs = require('fs-extra');
4
+ const onSignalExit = require('signal-exit');
5
+
6
+ const temporary = require('../artifacts/utils/temporaryPath');
7
+ const { DetoxRuntimeError } = require('../errors');
8
+ const SessionState = require('../ipc/SessionState');
9
+ const symbols = require('../symbols');
10
+ const { getCurrentCommand } = require('../utils/argparse');
11
+ const uuid = require('../utils/uuid');
12
+
13
+ const DetoxContext = require('./DetoxContext');
14
+
15
+ // Protected symbols
16
+ const { $logFinalizer, $restoreSessionState, $sessionState, $worker } = DetoxContext.protected;
17
+
18
+ //#region Private symbols
19
+ const _globalLifecycleHandler = Symbol('globalLifecycleHandler');
20
+ const _ipcServer = Symbol('ipcServer');
21
+ const _resetLockFile = Symbol('resetLockFile');
22
+ const _wss = Symbol('wss');
23
+ const _dirty = Symbol('dirty');
24
+ const _emergencyTeardown = Symbol('emergencyTeardown');
25
+ const _lifecycleLogger = Symbol('lifecycleLogger');
26
+ const _sessionFile = Symbol('sessionFile');
27
+ //#endregion
28
+
29
+ class DetoxPrimaryContext extends DetoxContext {
30
+ constructor() {
31
+ super();
32
+
33
+ this[_dirty] = false;
34
+ this[_wss] = null;
35
+ this[_globalLifecycleHandler] = null;
36
+ /** Path to file where the initial session object is serialized */
37
+ this[_sessionFile] = '';
38
+ /**
39
+ * @type {import('../ipc/IPCServer') | null}
40
+ */
41
+ this[_ipcServer] = null;
42
+ /** @type {Detox.Logger} */
43
+ this[_lifecycleLogger] = this[symbols.logger].child({ cat: 'lifecycle' });
44
+ }
45
+
46
+ //#region Internal members
47
+ async [symbols.reportTestResults](testResults) {
48
+ if (this[_ipcServer]) {
49
+ this[_ipcServer].onReportTestResults({ testResults });
50
+ }
51
+ }
52
+
53
+ async [symbols.resolveConfig](opts = {}) {
54
+ const session = this[$sessionState];
55
+ if (!session.detoxConfig) {
56
+ const configuration = require('../configuration');
57
+ session.detoxConfig = await configuration.composeDetoxConfig(opts);
58
+ }
59
+
60
+ return session.detoxConfig;
61
+ }
62
+
63
+ /**
64
+ * @override
65
+ * @param {Partial<DetoxInternals.DetoxInitOptions>} [opts]
66
+ */
67
+ async [symbols.init](opts = {}) {
68
+ if (this[_dirty]) {
69
+ throw new DetoxRuntimeError({
70
+ message: 'Cannot initialize primary Detox context more than once.',
71
+ hint: DetoxRuntimeError.reportIssueIfJest,
72
+ });
73
+ }
74
+
75
+ this[_dirty] = true;
76
+ onSignalExit(this[_emergencyTeardown]);
77
+
78
+ const detoxConfig = await this[symbols.resolveConfig](opts);
79
+
80
+ const {
81
+ behavior: behaviorConfig,
82
+ device: deviceConfig,
83
+ logger: loggerConfig,
84
+ session: sessionConfig
85
+ } = detoxConfig;
86
+ await this[symbols.logger].setConfig(loggerConfig);
87
+
88
+ this[_lifecycleLogger].trace.begin({
89
+ cwd: process.cwd(),
90
+ data: this[$sessionState],
91
+ }, getCurrentCommand());
92
+
93
+ const IPCServer = require('../ipc/IPCServer');
94
+ this[_ipcServer] = new IPCServer({
95
+ sessionState: this[$sessionState],
96
+ logger: this[symbols.logger],
97
+ });
98
+
99
+ await this[_ipcServer].init();
100
+
101
+ const environmentFactory = require('../environmentFactory');
102
+ this[_globalLifecycleHandler] = await environmentFactory.createGlobalLifecycleHandler(deviceConfig);
103
+
104
+ if (this[_globalLifecycleHandler]) {
105
+ await this[_globalLifecycleHandler].globalInit();
106
+ }
107
+
108
+ if (!behaviorConfig.init.keepLockFile) {
109
+ await this[_resetLockFile]();
110
+ }
111
+
112
+ const DetoxServer = require('../server/DetoxServer');
113
+ if (sessionConfig.autoStart) {
114
+ this[_wss] = new DetoxServer({
115
+ port: sessionConfig.server
116
+ ? new URL(sessionConfig.server).port
117
+ : 0,
118
+ standalone: false,
119
+ });
120
+
121
+ await this[_wss].open();
122
+ }
123
+
124
+ if (!sessionConfig.server && this[_wss]) {
125
+ // @ts-ignore
126
+ sessionConfig.server = `ws://localhost:${this[_wss].port}`;
127
+ }
128
+
129
+ this[_sessionFile] = temporary.for.json(this[$sessionState].id);
130
+ await fs.writeFile(this[_sessionFile], this[$sessionState].stringify());
131
+ process.env.DETOX_CONFIG_SNAPSHOT_PATH = this[_sessionFile];
132
+ this[_lifecycleLogger].trace(`Serialized the session state at: ${this[_sessionFile]}`);
133
+
134
+ if (opts.workerId !== null) {
135
+ await this[symbols.installWorker](opts);
136
+ }
137
+ }
138
+
139
+ /**
140
+ * @override
141
+ * @param {Partial<DetoxInternals.DetoxInstallWorkerOptions>} [opts]
142
+ */
143
+ async [symbols.installWorker](opts = {}) {
144
+ const workerId = opts.workerId || 'worker';
145
+
146
+ this[$sessionState].workerId = workerId;
147
+ this[_ipcServer].onRegisterWorker({ workerId });
148
+
149
+ await super[symbols.installWorker]({ ...opts, workerId });
150
+ }
151
+
152
+ /** @override */
153
+ async [symbols.cleanup]() {
154
+ try {
155
+ if (this[$worker]) {
156
+ await this[symbols.uninstallWorker]();
157
+ }
158
+ } finally {
159
+ if (this[_globalLifecycleHandler]) {
160
+ await this[_globalLifecycleHandler].globalCleanup();
161
+ this[_globalLifecycleHandler] = null;
162
+ }
163
+
164
+ if (this[_wss]) {
165
+ await this[_wss].close();
166
+ this[_wss] = null;
167
+ }
168
+
169
+ if (this[_ipcServer]) {
170
+ await this[_ipcServer].dispose();
171
+ this[_ipcServer] = null;
172
+ }
173
+
174
+ if (this[_sessionFile]) {
175
+ await fs.remove(this[_sessionFile]);
176
+ }
177
+
178
+ if (this[_dirty]) {
179
+ try {
180
+ this[_lifecycleLogger].trace.end();
181
+ await this[$logFinalizer].finalize();
182
+ } catch (err) {
183
+ this[_lifecycleLogger].error({ err }, 'Encountered an error while merging the process logs:');
184
+ }
185
+ }
186
+ }
187
+ }
188
+
189
+ [_emergencyTeardown] = (_code, signal) => {
190
+ if (!signal) {
191
+ return;
192
+ }
193
+
194
+ if (this[_globalLifecycleHandler]) {
195
+ this[_globalLifecycleHandler].emergencyCleanup();
196
+ this[_globalLifecycleHandler] = null;
197
+ }
198
+
199
+ if (this[_wss]) {
200
+ this[_wss].close();
201
+ }
202
+
203
+ if (this[_ipcServer]) {
204
+ this[_ipcServer].dispose();
205
+ }
206
+
207
+ if (this[_sessionFile]) {
208
+ fs.removeSync(this[_sessionFile]);
209
+ }
210
+
211
+ try {
212
+ this[_lifecycleLogger].trace.end({ abortSignal: signal });
213
+ this[$logFinalizer].finalizeSync();
214
+ } catch (err) {
215
+ this[symbols.logger].error({ err }, 'Encountered an error while merging the process logs:');
216
+ }
217
+ };
218
+
219
+ //#endregion
220
+
221
+ //#region Protected members
222
+ /**
223
+ * @protected
224
+ * @override
225
+ * @return {SessionState}
226
+ */
227
+ [$restoreSessionState]() {
228
+ return new SessionState({
229
+ id: uuid.UUID(),
230
+ detoxIPCServer: `primary-${process.pid}`,
231
+ });
232
+ }
233
+ //#endregion
234
+
235
+ //#region Private members
236
+ async[_resetLockFile]() {
237
+ const DeviceRegistry = require('../devices/DeviceRegistry');
238
+
239
+ const deviceType = this[symbols.config].device.type;
240
+
241
+ switch (deviceType) {
242
+ case 'ios.none':
243
+ case 'ios.simulator':
244
+ await DeviceRegistry.forIOS().reset();
245
+ break;
246
+ case 'android.attached':
247
+ case 'android.emulator':
248
+ case 'android.genycloud':
249
+ await DeviceRegistry.forAndroid().reset();
250
+ break;
251
+ }
252
+
253
+ if (deviceType === 'android.genycloud') {
254
+ const GenyDeviceRegistryFactory = require('../devices/allocation/drivers/android/genycloud/GenyDeviceRegistryFactory');
255
+ await GenyDeviceRegistryFactory.forGlobalShutdown().reset();
256
+ }
257
+ }
258
+ //#endregion
259
+ }
260
+
261
+ module.exports = DetoxPrimaryContext;
@@ -0,0 +1,91 @@
1
+ const fs = require('fs');
2
+
3
+ const { DetoxInternalError } = require('../errors');
4
+ const SessionState = require('../ipc/SessionState');
5
+ const symbols = require('../symbols');
6
+
7
+ const DetoxContext = require('./DetoxContext');
8
+
9
+ // Protected symbols
10
+ const { $restoreSessionState, $sessionState, $worker } = DetoxContext.protected;
11
+
12
+ //#region Private symbols
13
+ const _ipcClient = Symbol('ipcClient');
14
+ //#endregion
15
+
16
+ class DetoxSecondaryContext extends DetoxContext {
17
+ constructor() {
18
+ super();
19
+
20
+ /**
21
+ * @private
22
+ * @type {import('../ipc/IPCClient')}
23
+ */
24
+ this[_ipcClient] = null;
25
+ }
26
+
27
+ //#region Internal members
28
+ async [symbols.reportTestResults](testResults) {
29
+ if (this[_ipcClient]) {
30
+ await this[_ipcClient].reportTestResults(testResults);
31
+ } else {
32
+ throw new DetoxInternalError('Detected an attempt to report failed tests using a non-initialized context.');
33
+ }
34
+ }
35
+
36
+ async [symbols.resolveConfig]() {
37
+ return this[symbols.config];
38
+ }
39
+
40
+ /** @override */
41
+ async [symbols.init](opts = {}) {
42
+ const IPCClient = require('../ipc/IPCClient');
43
+
44
+ this[_ipcClient] = new IPCClient({
45
+ id: `secondary-${process.pid}`,
46
+ state: this[$sessionState],
47
+ logger: this[symbols.logger],
48
+ });
49
+
50
+ await this[_ipcClient].init();
51
+
52
+ if (opts.workerId !== null) {
53
+ await this[symbols.installWorker](opts);
54
+ }
55
+ }
56
+
57
+ /** @override */
58
+ async [symbols.cleanup]() {
59
+ try {
60
+ if (this[$worker]) {
61
+ await this[symbols.uninstallWorker]();
62
+ }
63
+ } finally {
64
+ if (this[_ipcClient]) {
65
+ await this[_ipcClient].dispose();
66
+ this[_ipcClient] = null;
67
+ }
68
+ }
69
+ }
70
+
71
+ /** @override */
72
+ async [symbols.installWorker](opts = {}) {
73
+ const workerId = opts.workerId || 'worker';
74
+ await this[_ipcClient].registerWorker(workerId);
75
+ await super[symbols.installWorker]({ ...opts, workerId });
76
+ }
77
+ //#endregion
78
+
79
+ //#region Protected members
80
+ /**
81
+ * @protected
82
+ * @override
83
+ * @return {SessionState}
84
+ */
85
+ [$restoreSessionState]() {
86
+ return SessionState.parse(fs.readFileSync(process.env.DETOX_CONFIG_SNAPSHOT_PATH));
87
+ }
88
+ //#endregion
89
+ }
90
+
91
+ module.exports = DetoxSecondaryContext;
@@ -0,0 +1,10 @@
1
+ function current() {
2
+ if (process.env.DETOX_CONFIG_SNAPSHOT_PATH) {
3
+ return require('./secondary');
4
+ } else {
5
+ return require('./primary');
6
+ }
7
+ }
8
+
9
+ /** @type {DetoxInternals.Facade} */
10
+ module.exports = global['__detox__'] || current();
@@ -0,0 +1,3 @@
1
+ const DetoxPrimaryContext = require('./DetoxPrimaryContext');
2
+
3
+ module.exports = new DetoxPrimaryContext();
@@ -0,0 +1,3 @@
1
+ const DetoxSecondaryContext = require('./DetoxSecondaryContext');
2
+
3
+ module.exports = new DetoxSecondaryContext();
@@ -1,43 +1,37 @@
1
- // @ts-nocheck
2
1
  const _ = require('lodash');
3
- const { WebSocket } = require('ws'); // eslint-disable-line @typescript-eslint/no-unused-vars, no-unused-vars
4
2
 
5
3
  const DetoxRuntimeError = require('../errors/DetoxRuntimeError');
6
- const logger = require('../utils/logger').child({ __filename });
4
+ const logger = require('../utils/logger').child({ cat: 'ws-server,ws' });
7
5
 
8
6
  const AnonymousConnectionHandler = require('./handlers/AnonymousConnectionHandler');
9
7
 
10
- const EVENTS = {
11
- NEW: { event: 'WSS_CONNECTION' },
12
- GET: { event: 'WSS_GET_FROM' },
13
- SEND: { event: 'WSS_SEND_TO' },
14
- ERROR: { event: 'ERROR' },
15
- SOCKET_ERROR: { event: 'WSS_SOCKET_ERROR' },
16
- };
17
-
18
8
  class DetoxConnection {
19
9
  /**
20
- * @param {DetoxSessionManager} sessionManager
21
- * @param {WebSocket} webSocket
22
- * @param {Socket} socket
10
+ * @param {{
11
+ * sessionManager: import('./DetoxSessionManager');
12
+ * webSocket: import('ws');
13
+ * socket: import('net').Socket;
14
+ * }} config
23
15
  */
24
16
  constructor({ sessionManager, webSocket, socket }) {
25
17
  this._onMessage = this._onMessage.bind(this);
26
18
  this._onError = this._onError.bind(this);
27
19
  this._onClose = this._onClose.bind(this);
28
20
 
29
- this._log = logger.child({ trackingId: socket.remotePort });
21
+ this._log = logger.child({ id: socket.remotePort });
22
+ this._log.debug.begin(`connection :${socket.localPort}<->:${socket.remotePort}`);
23
+
30
24
  this._sessionManager = sessionManager;
31
25
  this._webSocket = webSocket;
32
26
  this._webSocket.on('message', this._onMessage);
33
27
  this._webSocket.on('error', this._onError);
34
28
  this._webSocket.on('close', this._onClose);
35
- this._log.debug(EVENTS.NEW, 'registered a new connection.');
36
29
 
37
- const log = this._log;
30
+ // eslint-disable-next-line unicorn/no-this-assignment
31
+ const self = this;
38
32
  this._handler = new AnonymousConnectionHandler({
39
33
  api: {
40
- get log() { return log; },
34
+ get log() { return self._log; },
41
35
  appendLogDetails: (details) => { this._log = this._log.child(details); },
42
36
 
43
37
  registerSession: (params) => this._sessionManager.registerSession(this, params),
@@ -49,13 +43,13 @@ class DetoxConnection {
49
43
 
50
44
  sendAction(action) {
51
45
  const messageAsString = JSON.stringify(action);
52
- this._log.trace(EVENTS.SEND, messageAsString);
46
+ this._log.trace({ data: action }, 'send');
53
47
  this._webSocket.send(messageAsString + '\n ');
54
48
  }
55
49
 
56
50
  _onMessage(rawData) {
57
51
  const data = _.isString(rawData) ? rawData : rawData.toString('utf8');
58
- this._log.trace(EVENTS.GET, data);
52
+ this._log.trace({ data }, 'get');
59
53
 
60
54
  try {
61
55
  let action;
@@ -84,16 +78,17 @@ class DetoxConnection {
84
78
  this._handler.onError(handlerError, action);
85
79
  }
86
80
  } catch (error) {
87
- this._log.warn({ ...EVENTS.ERROR }, error instanceof DetoxRuntimeError ? error.message : `${error}`);
81
+ this._log.warn({ error }, 'Caught unhandled error:');
88
82
  }
89
83
  }
90
84
 
91
- _onError(e) {
92
- this._log.warn(EVENTS.SOCKET_ERROR, DetoxRuntimeError.format(e));
85
+ _onError(error) {
86
+ this._log.warn({ error }, 'Caught socket error:');
93
87
  }
94
88
 
95
89
  _onClose() {
96
90
  this._sessionManager.unregisterConnection(this._webSocket);
91
+ this._log.debug.end();
97
92
  }
98
93
  }
99
94
 
@@ -4,7 +4,7 @@ const WebSocket = require('ws');
4
4
 
5
5
  const { DetoxInternalError, DetoxRuntimeError } = require('../errors');
6
6
  const Deferred = require('../utils/Deferred');
7
- const log = require('../utils/logger').child({ __filename });
7
+ const log = require('../utils/logger').child({ cat: 'ws-server,ws' });
8
8
 
9
9
  const DetoxSessionManager = require('./DetoxSessionManager');
10
10
 
@@ -40,18 +40,16 @@ class DetoxServer {
40
40
  await this._startListening();
41
41
 
42
42
  const level = this._options.standalone ? 'info' : 'debug';
43
- log[level]({ event: 'WSS_CREATE' }, `Detox server listening on localhost:${this.port}...`);
43
+ log[level](`Detox server listening on localhost:${this.port}...`);
44
44
  }
45
45
 
46
46
  async close() {
47
47
  try {
48
48
  await this._closeWithTimeout(10000);
49
- log.debug({ event: 'WSS_CLOSE' }, 'Detox server has been closed gracefully');
50
- } catch (e) {
51
- log.warn({ event: 'ERROR' },
52
- `Detox server has been closed abruptly! See the error details below:\n`
53
- + DetoxRuntimeError.format(e) + '\n'
54
- + DetoxRuntimeError.reportIssue
49
+ log.debug('Detox server has been closed gracefully');
50
+ } catch (err) {
51
+ log.warn({ err },
52
+ `Detox server has been closed abruptly! See the error details below:`
55
53
  );
56
54
  }
57
55
  }
@@ -90,8 +88,7 @@ class DetoxServer {
90
88
  } else if (this._closing) {
91
89
  this._closing.reject(err);
92
90
  } else {
93
- const formattedError = DetoxRuntimeError.format(err);
94
- log.error('Detox server has got an unhandled error:\n' + formattedError);
91
+ log.error({ err }, 'Detox server has got an unhandled error:');
95
92
  }
96
93
  }
97
94
 
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  const DetoxInternalError = require('../errors/DetoxInternalError');
3
- const log = require('../utils/logger').child({ __filename });
3
+ const log = require('../utils/logger').child({ cat: 'ws-server,ws-session' });
4
4
 
5
5
  class DetoxSession {
6
6
  /**
@@ -17,7 +17,7 @@ class DetoxSession {
17
17
  /** @type {boolean | null} */
18
18
  this._pendingTesterStatus = null;
19
19
 
20
- log.trace({ event: 'SESSION_CREATED' }, `created session ${id}`);
20
+ log.trace(`created session ${id}`);
21
21
  }
22
22
 
23
23
  get id() {
@@ -120,7 +120,7 @@ class DetoxSession {
120
120
  }
121
121
 
122
122
  _notifyAboutAppConnect() {
123
- log.trace({ event: 'SESSION_JOINED' }, `app joined session ${this.id}`);
123
+ log.trace(`app joined session ${this.id}`);
124
124
 
125
125
  if (!this._tester) {
126
126
  return;
@@ -132,7 +132,7 @@ class DetoxSession {
132
132
  }
133
133
 
134
134
  _notifyAboutAppDisconnect() {
135
- log.trace({ event: 'SESSION_TORN' }, `app exited session ${this.id}`);
135
+ log.trace(`app exited session ${this.id}`);
136
136
 
137
137
  if (!this._tester) {
138
138
  return;
@@ -144,11 +144,11 @@ class DetoxSession {
144
144
  }
145
145
 
146
146
  _notifyAboutTesterConnect() {
147
- log.trace({ event: 'SESSION_JOINED' }, `tester joined session ${this.id}`);
147
+ log.trace(`tester joined session ${this.id}`);
148
148
  }
149
149
 
150
150
  _notifyAboutTesterDisconnect() {
151
- log.trace({ event: 'SESSION_TORN' }, `tester exited session ${this.id}`);
151
+ log.trace(`tester exited session ${this.id}`);
152
152
 
153
153
  if (!this._app) {
154
154
  return;
@@ -1,6 +1,6 @@
1
1
  // @ts-nocheck
2
2
  const DetoxInternalError = require('../errors/DetoxInternalError');
3
- const log = require('../utils/logger').child({ __filename });
3
+ const log = require('../utils/logger').child({ cat: 'ws-server,ws' });
4
4
 
5
5
  const DetoxConnection = require('./DetoxConnection');
6
6
  const DetoxSession = require('./DetoxSession');
@@ -1,7 +1,6 @@
1
1
  // @ts-nocheck
2
2
  const { serializeError } = require('serialize-error');
3
3
 
4
- const DetoxError = require('../../errors/DetoxError');
5
4
  const DetoxInternalError = require('../../errors/DetoxInternalError');
6
5
 
7
6
  class RegisteredConnectionHandler {
@@ -41,7 +40,7 @@ class RegisteredConnectionHandler {
41
40
  messageId: action && action.messageId,
42
41
  });
43
42
  } catch (err) {
44
- this._api.log.error('Cannot forward the error details to the tester due to the error:\n' + DetoxError.format(err));
43
+ this._api.log.error({ err }, 'Cannot forward the error details to the tester due to the error:');
45
44
  throw error;
46
45
  }
47
46
  }
package/src/symbols.js ADDED
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @type {{
3
+ * readonly cleanup: unique symbol;
4
+ * readonly config: unique symbol;
5
+ * readonly getStatus: unique symbol;
6
+ * readonly init: unique symbol;
7
+ * readonly installWorker: unique symbol;
8
+ * readonly logger: unique symbol;
9
+ * readonly onHookFailure: unique symbol;
10
+ * readonly onRunDescribeFinish: unique symbol;
11
+ * readonly onRunDescribeStart: unique symbol;
12
+ * readonly onTestDone: unique symbol;
13
+ * readonly onTestFnFailure: unique symbol;
14
+ * readonly onTestStart: unique symbol;
15
+ * readonly reportTestResults: unique symbol;
16
+ * readonly resolveConfig: unique symbol;
17
+ * readonly session: unique symbol;
18
+ * readonly tracing: unique symbol;
19
+ * readonly uninstallWorker: unique symbol;
20
+ * readonly worker: unique symbol;
21
+ * }}
22
+ */
23
+ module.exports = {
24
+ //#region Lifecycle
25
+ onRunDescribeStart: Symbol('run_describe_start'),
26
+ onTestStart: Symbol('test_start'),
27
+ onHookFailure: Symbol('hook_failure'),
28
+ onTestFnFailure: Symbol('test_fn_failure'),
29
+ onTestDone: Symbol('test_done'),
30
+ onRunDescribeFinish: Symbol('run_describe_finish'),
31
+ //#endregion
32
+
33
+ //#region IPC
34
+ reportTestResults: Symbol('reportTestResults'),
35
+ //#endregion
36
+
37
+ //#region Main
38
+ cleanup: Symbol('cleanup'),
39
+ config: Symbol('config'),
40
+ getStatus: Symbol('getStatus'),
41
+ init: Symbol('init'),
42
+ installWorker: Symbol('installWorker'),
43
+ logger: Symbol('logger'),
44
+ resolveConfig: Symbol('resolveConfig'),
45
+ session: Symbol('session'),
46
+ tracing: Symbol('tracing'),
47
+ uninstallWorker: Symbol('uninstallWorker'),
48
+ worker: Symbol('worker'),
49
+ //#endregion
50
+ };