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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (192) hide show
  1. package/Detox-android/com/wix/detox/{20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar → 20.0.2/detox-20.0.2-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar → 20.0.2/detox-20.0.2-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom → 20.0.2/detox-20.0.2.pom} +1 -7
  17. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.0.2/detox-20.0.2.pom.sha512 +1 -0
  21. package/Detox-android/com/wix/detox/maven-metadata.xml +4 -4
  22. package/Detox-android/com/wix/detox/maven-metadata.xml.md5 +1 -1
  23. package/Detox-android/com/wix/detox/maven-metadata.xml.sha1 +1 -1
  24. package/Detox-android/com/wix/detox/maven-metadata.xml.sha256 +1 -1
  25. package/Detox-android/com/wix/detox/maven-metadata.xml.sha512 +1 -1
  26. package/Detox-ios-src.tbz +0 -0
  27. package/Detox-ios.tbz +0 -0
  28. package/README.md +1 -1
  29. package/android/build.gradle +12 -7
  30. package/android/detox/build.gradle +13 -9
  31. package/android/detox/proguard-rules-app.pro +6 -0
  32. package/android/detox/proguard-rules.pro +3 -0
  33. package/android/detox/publishing.gradle +27 -27
  34. package/android/detox/src/full/java/com/wix/detox/DetoxCrashHandler.kt +1 -1
  35. package/android/detox/src/full/java/com/wix/detox/LaunchArgs.java +9 -0
  36. package/android/detox/src/full/java/com/wix/detox/TestEngineFacade.kt +1 -1
  37. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeExtension.kt +15 -2
  38. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeIdlingResources.kt +43 -38
  39. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/IdlingResourceDescription.kt +19 -13
  40. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/NetworkIdlingResource.java +33 -30
  41. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/DelegatedIdleInterrogationStrategy.kt +7 -27
  42. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/IdleInterrogationStrategy.kt +1 -11
  43. package/android/detox/src/main/java/com/wix/detox/common/TextFileReader.kt +1 -1
  44. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/DetoxMultiTapSpec.kt +4 -3
  45. package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/NetworkIdlingResourcesTest.kt +61 -0
  46. package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/timers/DelegatedIdleInterrogationStrategySpec.kt +3 -11
  47. package/index.d.ts +195 -59
  48. package/internals.d.ts +216 -49
  49. package/local-cli/build.js +2 -2
  50. package/local-cli/build.test.js +14 -14
  51. package/local-cli/cli.js +11 -6
  52. package/local-cli/init.js +61 -21
  53. package/local-cli/rebuild-framework-cache.js +1 -1
  54. package/local-cli/reset-lock-file.js +16 -0
  55. package/local-cli/templates/jest.js +13 -10
  56. package/local-cli/test.js +14 -8
  57. package/local-cli/test.test.js +143 -62
  58. package/local-cli/testCommand/TestRunnerCommand.js +97 -77
  59. package/local-cli/testCommand/TestRunnerError.js +17 -0
  60. package/local-cli/testCommand/TestRunnerError.test.js +25 -0
  61. package/local-cli/testCommand/builder.js +0 -1
  62. package/local-cli/testCommand/middlewares.js +4 -13
  63. package/local-cli/testCommand/warnings.js +0 -3
  64. package/local-cli/utils/jestInternals.js +4 -1
  65. package/package.json +23 -17
  66. package/runners/deprecation.js +42 -44
  67. package/runners/jest/globalSetup.js +1 -1
  68. package/runners/jest/globalTeardown.js +1 -1
  69. package/runners/jest/index.d.ts +60 -0
  70. package/runners/jest/index.js +3 -8
  71. package/runners/jest/index.test.js +13 -0
  72. package/runners/jest/reporters/DetoxReporter.js +33 -2
  73. package/runners/jest/testEnvironment/index.js +119 -69
  74. package/runners/jest/testEnvironment/listeners/DetoxCoreListener.js +94 -47
  75. package/runners/jest/testEnvironment/listeners/DetoxPlatformFilterListener.js +1 -1
  76. package/runners/jest/testEnvironment/listeners/SpecReporter.js +14 -16
  77. package/runners/jest/testEnvironment/listeners/WorkerAssignReporter.js +2 -6
  78. package/runners/jest/testEnvironment/utils/assertJestCircus27.js +17 -3
  79. package/runners/jest/testEnvironment/utils/assertJestCircus27.test.js +0 -1
  80. package/src/DetoxWorker.js +105 -62
  81. package/src/android/core/NativeElement.js +56 -20
  82. package/src/android/core/NativeExpect.js +28 -9
  83. package/src/android/interactions/native.js +25 -18
  84. package/src/artifacts/ArtifactsManager.js +14 -47
  85. package/src/artifacts/instruments/ios/SimulatorInstrumentsRecording.js +3 -3
  86. package/src/artifacts/log/ios/SimulatorLogRecording.js +1 -1
  87. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +1 -1
  88. package/src/artifacts/templates/artifact/Artifact.js +1 -1
  89. package/src/artifacts/templates/plugin/ArtifactPlugin.js +1 -1
  90. package/src/artifacts/timeline/TimelineContextTypes.js +7 -0
  91. package/src/artifacts/utils/temporaryPath.js +49 -8
  92. package/src/artifacts/video/SimulatorRecordVideoPlugin.js +1 -1
  93. package/src/client/AsyncWebSocket.js +8 -17
  94. package/src/client/Client.js +19 -2
  95. package/src/client/actions/formatters/sync-resources/NetworkFormatter.js +1 -1
  96. package/src/configuration/collectCliConfig.js +1 -12
  97. package/src/configuration/composeAppsConfig.js +4 -0
  98. package/src/configuration/composeDeviceConfig.js +1 -1
  99. package/src/configuration/composeLoggerConfig.js +19 -10
  100. package/src/configuration/composeRunnerConfig.js +61 -9
  101. package/src/configuration/index.js +14 -9
  102. package/src/configuration/loadExternalConfig.js +1 -1
  103. package/src/devices/allocation/DeviceAllocator.js +3 -2
  104. package/src/devices/allocation/drivers/android/emulator/AVDValidator.js +5 -5
  105. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +4 -3
  106. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +1 -1
  107. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +3 -2
  108. package/src/devices/allocation/drivers/android/emulator/EmulatorVersionResolver.js +4 -6
  109. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +1 -1
  110. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +1 -1
  111. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +3 -3
  112. package/src/devices/common/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  113. package/src/devices/common/drivers/android/tools/EmulatorTelnet.js +1 -1
  114. package/src/devices/common/drivers/android/tools/FreeDeviceFinder.js +1 -1
  115. package/src/devices/common/drivers/android/tools/MonitoredInstrumentation.js +1 -1
  116. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +29 -3
  117. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +13 -15
  118. package/src/devices/runtime/RuntimeDevice.js +19 -12
  119. package/src/devices/runtime/drivers/DeviceDriverBase.js +1 -1
  120. package/src/devices/runtime/drivers/android/AndroidDriver.js +10 -2
  121. package/src/devices/runtime/drivers/ios/SimulatorDriver.js +1 -1
  122. package/src/errors/DetoxConfigErrorComposer.js +17 -2
  123. package/src/errors/DetoxError.js +5 -1
  124. package/src/ios/expectTwo.js +153 -67
  125. package/src/ipc/IPCClient.js +12 -13
  126. package/src/ipc/IPCServer.js +28 -24
  127. package/src/ipc/{state.js → SessionState.js} +26 -53
  128. package/src/logger/DetoxLogger.js +287 -154
  129. package/src/logger/index.js +5 -0
  130. package/src/logger/utils/BunyanLogger.js +115 -0
  131. package/src/logger/utils/CategoryThreadDispatcher.js +37 -0
  132. package/src/logger/utils/DetoxLogFinalizer.js +162 -0
  133. package/src/logger/utils/MessageStack.js +35 -0
  134. package/src/logger/utils/ThreadDispatcher.js +61 -0
  135. package/src/logger/{customConsoleLogger.js → utils/customConsoleLogger.js} +23 -6
  136. package/src/logger/utils/getMainCategory.js +5 -0
  137. package/src/logger/utils/sanitizeBunyanContext.js +30 -0
  138. package/src/logger/utils/streams/BunyanTransformer.js +72 -0
  139. package/src/logger/utils/streams/ChromeTraceTransformer.js +127 -0
  140. package/src/logger/utils/streams/DetoxJSONLParser.js +31 -0
  141. package/src/logger/utils/streams/JSONLStringer.js +55 -0
  142. package/src/logger/utils/streams/index.js +7 -0
  143. package/src/logger/utils/streams/transformers.js +39 -0
  144. package/src/logger/utils/tracerLegacy.js +37 -0
  145. package/src/realms/DetoxContext.js +79 -65
  146. package/src/realms/DetoxInternalsFacade.js +8 -12
  147. package/src/realms/DetoxPrimaryContext.js +111 -72
  148. package/src/realms/DetoxSecondaryContext.js +29 -32
  149. package/src/server/DetoxConnection.js +18 -23
  150. package/src/server/DetoxServer.js +7 -10
  151. package/src/server/DetoxSession.js +6 -6
  152. package/src/server/DetoxSessionManager.js +1 -1
  153. package/src/server/handlers/RegisteredConnectionHandler.js +1 -2
  154. package/src/symbols.js +16 -22
  155. package/src/utils/Timer.js +55 -38
  156. package/src/utils/argparse.js +11 -0
  157. package/src/utils/childProcess/exec.js +1 -1
  158. package/src/utils/childProcess/spawn.js +1 -1
  159. package/src/utils/errorUtils.js +24 -3
  160. package/src/utils/invocationTraceDescriptions.js +43 -0
  161. package/src/utils/logger.js +1 -1
  162. package/src/utils/pathUtils.js +11 -0
  163. package/src/utils/shellUtils.js +17 -0
  164. package/src/utils/traceInvocationCall.js +21 -0
  165. package/src/utils/traceMethods.js +15 -0
  166. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar.md5 +0 -1
  167. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar.sha1 +0 -1
  168. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar.sha256 +0 -1
  169. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-javadoc.jar.sha512 +0 -1
  170. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar.md5 +0 -1
  171. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar.sha1 +0 -1
  172. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar.sha256 +0 -1
  173. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0-sources.jar.sha512 +0 -1
  174. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar +0 -0
  175. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar.md5 +0 -1
  176. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar.sha1 +0 -1
  177. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar.sha256 +0 -1
  178. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.aar.sha512 +0 -1
  179. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom.md5 +0 -1
  180. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom.sha1 +0 -1
  181. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom.sha256 +0 -1
  182. package/Detox-android/com/wix/detox/20.0.2-breaking.new-global-lifecycle.0/detox-20.0.2-breaking.new-global-lifecycle.0.pom.sha512 +0 -1
  183. package/android/detox/src/full/java/com/wix/detox/reactnative/idlingresources/timers/DefaultIdleInterrogationStrategy.kt +0 -84
  184. package/android/detox/src/testFull/java/com/wix/detox/reactnative/idlingresources/timers/DefaultIdleInterrogationStrategySpec.kt +0 -115
  185. package/runners/jest/deprecation.js +0 -25
  186. package/src/configuration/utils/warnings.js +0 -12
  187. package/src/logger/DetoxTraceEventBuilder.js +0 -21
  188. package/src/logger/DetoxTracer.js +0 -133
  189. package/src/logger/TraceThreadDispatcher.js +0 -52
  190. package/src/utils/ChromeTracingExporter.js +0 -54
  191. package/src/utils/streamUtils.js +0 -214
  192. package/src/utils/trace.js +0 -19
@@ -2,17 +2,19 @@ const os = require('os');
2
2
 
3
3
  const _ = require('lodash');
4
4
 
5
+ const log = require('../utils/logger');
6
+
5
7
  /**
6
8
  * @param {object} opts
7
9
  * @param {Detox.DetoxConfig} opts.globalConfig
8
10
  * @param {Detox.DetoxConfiguration} opts.localConfig
9
- * @param {DetoxInternals.DetoxCLIConfig} opts.cliConfig
11
+ * @param {DetoxInternals.CLIConfig} opts.cliConfig
10
12
  * @param {Record<string, any>} opts.testRunnerArgv
11
13
  * @param {import('../errors/DetoxConfigErrorComposer')} opts.errorComposer
12
14
  * @returns {Detox.DetoxTestRunnerConfig} opts.testRunnerArgv
13
15
  */
14
16
  function composeRunnerConfig(opts) {
15
- const globalConfig = opts.globalConfig.testRunner;
17
+ const globalConfig = adaptLegacyRunnerConfig(opts.globalConfig);
16
18
  if (globalConfig != null && typeof globalConfig !== 'object') {
17
19
  throw opts.errorComposer.invalidTestRunnerProperty(true);
18
20
  }
@@ -29,8 +31,11 @@ function composeRunnerConfig(opts) {
29
31
  {
30
32
  retries: 0,
31
33
  inspectBrk: inspectBrkHookDefault,
34
+ forwardEnv: false,
35
+ bail: false,
32
36
  jest: {
33
- initTimeout: 300000,
37
+ setupTimeout: 300000,
38
+ teardownTimeout: 30000,
34
39
  retryAfterCircusRetries: false,
35
40
  reportSpecs: undefined,
36
41
  reportWorkerAssign: true,
@@ -51,16 +56,62 @@ function composeRunnerConfig(opts) {
51
56
 
52
57
  if (typeof merged.inspectBrk === 'function') {
53
58
  if (cliConfig.inspectBrk) {
59
+ merged.retries = 0;
60
+ merged.forwardEnv = true;
54
61
  merged.inspectBrk(merged);
55
- merged.inspectBrk = true;
56
- } else {
57
- merged.inspectBrk = false;
58
62
  }
63
+
64
+ delete merged.inspectBrk;
59
65
  }
60
66
 
61
67
  return merged;
62
68
  }
63
69
 
70
+ function adaptLegacyRunnerConfig(globalConfig) {
71
+ let isLegacy = false;
72
+
73
+ const runnerConfigKey = 'runnerConfig' in globalConfig ? 'runnerConfig' : 'runner-config';
74
+ if (_.isString(globalConfig[runnerConfigKey])) {
75
+ isLegacy = true;
76
+ log.warn(`Detected a deprecated "${runnerConfigKey}" property (string).`);
77
+ }
78
+
79
+ const testRunnerKey = 'testRunner' in globalConfig ? 'testRunner' : 'test-runner';
80
+ if (_.isString(globalConfig[testRunnerKey])) {
81
+ isLegacy = true;
82
+ log.warn(`Detected a deprecated "${testRunnerKey}" property (string).`);
83
+ }
84
+
85
+ if (globalConfig.specs != null) {
86
+ isLegacy = true;
87
+ log.warn(`Detected a deprecated "specs" property.`);
88
+ }
89
+
90
+ if (!isLegacy) {
91
+ return globalConfig.testRunner;
92
+ }
93
+
94
+ log.warn(`Please migrate your Detox config according to the guide:\nhttps://wix.github.io/Detox/docs/guide/migration\n`);
95
+ const testRunner = globalConfig[testRunnerKey];
96
+ const runnerConfig = globalConfig[runnerConfigKey];
97
+ const specs = globalConfig.specs != null ? String(globalConfig.specs) : undefined;
98
+
99
+ const args = {};
100
+ if (_.isString(testRunner)) {
101
+ args.$0 = testRunner;
102
+ }
103
+
104
+ if (_.isString(runnerConfig)) {
105
+ args.config = runnerConfig;
106
+ }
107
+
108
+ if (specs) {
109
+ args._ = [specs];
110
+ }
111
+
112
+ return { args };
113
+ }
114
+
64
115
  function hasEmptyPositionalArgs(value, key) {
65
116
  return key === '_' ? _.isEmpty(value) : false;
66
117
  }
@@ -69,9 +120,10 @@ function hasEmptyPositionalArgs(value, key) {
69
120
  * @param {Detox.DetoxTestRunnerConfig} config
70
121
  */
71
122
  function inspectBrkHookDefault(config) {
72
- config.args.$0 = /* istanbul ignore if */ os.platform() === 'win32'
73
- ? `node --inspect-brk ./node_modules/jest/bin/jest.js`
74
- : `node --inspect-brk ./node_modules/.bin/jest`;
123
+ /* istanbul ignore next */
124
+ config.args.$0 = os.platform() !== 'win32'
125
+ ? `node --inspect-brk ./node_modules/.bin/jest`
126
+ : `node --inspect-brk ./node_modules/jest/bin/jest.js`;
75
127
  config.args.runInBand = true;
76
128
  delete config.args.w;
77
129
  delete config.args.workers;
@@ -105,18 +105,23 @@ async function composeDetoxConfig({
105
105
  });
106
106
 
107
107
  const result = {
108
- appsConfig,
109
- artifactsConfig,
110
- behaviorConfig,
111
- cliConfig,
112
108
  configurationName,
113
- deviceConfig,
114
- errorComposer,
115
- loggerConfig,
116
- runnerConfig,
117
- sessionConfig,
109
+
110
+ apps: appsConfig,
111
+ artifacts: artifactsConfig,
112
+ behavior: behaviorConfig,
113
+ cli: cliConfig,
114
+ device: deviceConfig,
115
+ logger: loggerConfig,
116
+ testRunner: runnerConfig,
117
+ session: sessionConfig,
118
118
  };
119
119
 
120
+ Object.defineProperty(result, 'errorComposer', {
121
+ enumerable: false,
122
+ value: errorComposer,
123
+ });
124
+
120
125
  return result;
121
126
  }
122
127
 
@@ -6,7 +6,7 @@ const fs = require('fs-extra');
6
6
  const _ = require('lodash');
7
7
  const resolveFrom = require('resolve-from');
8
8
 
9
- const log = require('../utils/logger').child({ __filename });
9
+ const log = require('../utils/logger').child({ cat: 'config' });
10
10
 
11
11
  async function locateExternalConfig(cwd) {
12
12
  return findUp([
@@ -1,5 +1,6 @@
1
1
  // @ts-nocheck
2
- const { traceMethods } = require('../../utils/trace');
2
+ const log = require('../../utils/logger').child({ cat: 'device' });
3
+ const traceMethods = require('../../utils/traceMethods');
3
4
 
4
5
  class DeviceAllocator {
5
6
  /**
@@ -7,7 +8,7 @@ class DeviceAllocator {
7
8
  */
8
9
  constructor(allocationDriver) {
9
10
  this._driver = allocationDriver;
10
- traceMethods(this, 'device', ['allocate', 'free']);
11
+ traceMethods(log, this, ['allocate', 'free']);
11
12
  }
12
13
 
13
14
  /**
@@ -2,7 +2,7 @@ const _ = require('lodash');
2
2
 
3
3
  const DetoxRuntimeError = require('../../../../../errors/DetoxRuntimeError');
4
4
  const environment = require('../../../../../utils/environment');
5
- const logger = require('../../../../../utils/logger').child({ __filename });
5
+ const logger = require('../../../../../utils/logger').child({ cat: 'device' });
6
6
 
7
7
  const REQUIRED_EMULATOR_MAJOR = 29;
8
8
 
@@ -12,11 +12,11 @@ class AVDValidator {
12
12
  this._emulatorVersionResolver = emulatorVersionResolver;
13
13
  }
14
14
 
15
- async validate(avdName) {
15
+ async validate(avdName, isHeadless) {
16
16
  const avds = await this._avdsResolver.resolve(avdName);
17
17
  this._assertAVDs(avds);
18
18
  await this._assertAVDMatch(avds, avdName);
19
- await this._validateEmulatorVer();
19
+ await this._validateEmulatorVer(isHeadless);
20
20
  }
21
21
 
22
22
  _assertAVDs(avds) {
@@ -37,8 +37,8 @@ class AVDValidator {
37
37
  }
38
38
  }
39
39
 
40
- async _validateEmulatorVer() {
41
- const emulatorVersion = await this._emulatorVersionResolver.resolve();
40
+ async _validateEmulatorVer(isHeadless) {
41
+ const emulatorVersion = await this._emulatorVersionResolver.resolve(isHeadless);
42
42
  if (!emulatorVersion) {
43
43
  logger.warn({ event: 'AVD_VALIDATION' }, 'Emulator version detection failed (See previous logs)');
44
44
  return;
@@ -1,7 +1,8 @@
1
1
  // @ts-nocheck
2
2
  const _ = require('lodash');
3
3
 
4
- const { traceMethods } = require('../../../../../utils/trace');
4
+ const log = require('../../../../../utils/logger').child({ cat: 'device' });
5
+ const traceMethods = require('../../../../../utils/traceMethods');
5
6
  const AndroidEmulatorCookie = require('../../../../cookies/AndroidEmulatorCookie');
6
7
  const AllocationDriverBase = require('../../AllocationDriverBase');
7
8
 
@@ -23,7 +24,7 @@ class EmulatorAllocDriver extends AllocationDriverBase {
23
24
  this._emulatorLauncher = emulatorLauncher;
24
25
  this._allocationHelper = allocationHelper;
25
26
 
26
- traceMethods(this, 'device', ['_launchEmulator']);
27
+ traceMethods(log, this, ['_launchEmulator']);
27
28
  }
28
29
 
29
30
  /**
@@ -33,7 +34,7 @@ class EmulatorAllocDriver extends AllocationDriverBase {
33
34
  async allocate(deviceConfig) {
34
35
  const avdName = deviceConfig.device.avdName;
35
36
 
36
- await this._avdValidator.validate(avdName);
37
+ await this._avdValidator.validate(avdName, deviceConfig.headless);
37
38
  await this._fixAvdConfigIniSkinNameIfNeeded(avdName, deviceConfig.headless);
38
39
 
39
40
  const allocResult = await this._allocationHelper.allocateDevice(avdName);
@@ -1,4 +1,4 @@
1
- const logger = require('../../../../../utils/logger').child({ __filename });
1
+ const logger = require('../../../../../utils/logger').child({ cat: 'device' });
2
2
  const DeviceAllocationHelper = require('../../../../common/drivers/DeviceAllocationHelper');
3
3
 
4
4
  const DetoxEmulatorsPortRange = {
@@ -1,7 +1,8 @@
1
1
  // @ts-nocheck
2
2
  const { DetoxRuntimeError } = require('../../../../../errors');
3
+ const log = require('../../../../../utils/logger').child({ cat: 'device' });
3
4
  const retry = require('../../../../../utils/retry');
4
- const { traceMethods } = require('../../../../../utils/trace');
5
+ const traceMethods = require('../../../../../utils/traceMethods');
5
6
  const DeviceLauncher = require('../../../../common/drivers/DeviceLauncher');
6
7
  const { LaunchCommand } = require('../../../../common/drivers/android/emulator/exec/EmulatorExec');
7
8
 
@@ -14,7 +15,7 @@ class EmulatorLauncher extends DeviceLauncher {
14
15
  super(eventEmitter);
15
16
  this._adb = adb;
16
17
  this._emulatorExec = emulatorExec;
17
- traceMethods(this, 'device', ['_awaitEmulatorBoot']);
18
+ traceMethods(log, this, ['_awaitEmulatorBoot']);
18
19
  }
19
20
 
20
21
  /**
@@ -1,8 +1,6 @@
1
- const log = require('../../../../../utils/logger').child({ __filename });
1
+ const log = require('../../../../../utils/logger').child({ cat: 'device' });
2
2
  const { QueryVersionCommand } = require('../../../../common/drivers/android/emulator/exec/EmulatorExec');
3
3
 
4
- const EMU_BIN_VERSION_DETECT_EV = 'EMU_BIN_VERSION_DETECT';
5
-
6
4
  class EmulatorVersionResolver {
7
5
  constructor(emulatorExec) {
8
6
  this._emulatorExec = emulatorExec;
@@ -21,18 +19,18 @@ class EmulatorVersionResolver {
21
19
  try {
22
20
  rawOutput = await this._emulatorExec.exec(new QueryVersionCommand({ headless })) || '';
23
21
  } catch (error) {
24
- log.error({ event: EMU_BIN_VERSION_DETECT_EV, success: false, error }, 'Could not detect emulator binary version', error);
22
+ log.error({ success: false, error }, 'Could not detect emulator binary version', error);
25
23
  return null;
26
24
  }
27
25
 
28
26
  const matches = rawOutput.match(/Android emulator version ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]*)/);
29
27
  if (!matches) {
30
- log.warn({ event: EMU_BIN_VERSION_DETECT_EV, success: false }, 'Could not detect emulator binary version, got:', rawOutput);
28
+ log.warn({ success: false }, 'Could not detect emulator binary version, got:', rawOutput);
31
29
  return null;
32
30
  }
33
31
 
34
32
  const version = this._parseVersionString(matches[1]);
35
- log.debug({ event: EMU_BIN_VERSION_DETECT_EV, success: true }, 'Detected emulator binary version', version);
33
+ log.debug({ success: true }, 'Detected emulator binary version', version);
36
34
  return version;
37
35
  }
38
36
 
@@ -3,7 +3,7 @@ const fs = require('fs');
3
3
  const _ = require('lodash');
4
4
  const { Tail } = require('tail');
5
5
 
6
- const unitLogger = require('../../../../../utils/logger').child({ __filename });
6
+ const unitLogger = require('../../../../../utils/logger').child({ cat: 'device' });
7
7
 
8
8
  function launchEmulatorProcess(emulatorName, emulatorExec, emulatorLaunchCommand) {
9
9
  let childProcessOutput;
@@ -1,5 +1,5 @@
1
1
  // @ts-nocheck
2
- const logger = require('../../../../../utils/logger').child({ __filename });
2
+ const logger = require('../../../../../utils/logger').child({ cat: 'device' });
3
3
  const DeviceAllocationHelper = require('../../../../common/drivers/DeviceAllocationHelper');
4
4
 
5
5
  const { ALLOCATE_DEVICE_LOG_EVT } = DeviceAllocationHelper;
@@ -1,9 +1,9 @@
1
- const session = () => require('../../../../../../../internals').session;
1
+ const internals = () => require('../../../../../../../internals');
2
2
 
3
3
  class GenyInstanceNaming {
4
4
  generateName() {
5
- const { id, workerId } = session();
6
- return `Detox.${id}.${workerId}`;
5
+ const { session, worker } = internals();
6
+ return `Detox.${session.id}.${worker.id}`;
7
7
  }
8
8
 
9
9
  isFamilial(name) {
@@ -1,4 +1,4 @@
1
- const logger = require('../../../../../../utils/logger').child({ __filename });
1
+ const logger = require('../../../../../../utils/logger').child({ cat: 'device' });
2
2
 
3
3
  const Recipe = require('./dto/GenyRecipe');
4
4
 
@@ -5,7 +5,7 @@ const path = require('path');
5
5
  const fs = require('fs-extra');
6
6
  const Telnet = require('telnet-client');
7
7
 
8
- const log = require('../../../../../utils/logger').child({ __filename });
8
+ const log = require('../../../../../utils/logger').child({ cat: 'device' });
9
9
 
10
10
  class EmulatorTelnet {
11
11
  constructor() {
@@ -1,4 +1,4 @@
1
- const log = require('../../../../../utils/logger').child({ __filename });
1
+ const log = require('../../../../../utils/logger').child({ cat: 'device' });
2
2
 
3
3
  const DEVICE_LOOKUP_LOG_EVT = 'DEVICE_LOOKUP';
4
4
 
@@ -77,7 +77,7 @@ class MonitoredInstrumentation {
77
77
  'while it was waiting for "ready" message (over WebSocket) ' +
78
78
  'from the instrumentation process.',
79
79
  debugInfo: this.instrumentationStackTrace
80
- ? `Native stacktrace dump: ${this.instrumentationStackTrace}`
80
+ ? `Native stacktrace dump:\n${this.instrumentationStackTrace}`
81
81
  : '',
82
82
  });
83
83
  }
@@ -7,7 +7,7 @@ const DetoxRuntimeError = require('../../../../../errors/DetoxRuntimeError');
7
7
  const { joinArgs } = require('../../../../../utils/argparse');
8
8
  const childProcess = require('../../../../../utils/childProcess');
9
9
  const environment = require('../../../../../utils/environment');
10
- const log = require('../../../../../utils/logger').child({ __filename });
10
+ const log = require('../../../../../utils/logger').child({ cat: 'device' });
11
11
  const { quote } = require('../../../../../utils/shellQuote');
12
12
 
13
13
  class AppleSimUtils {
@@ -93,7 +93,7 @@ class AppleSimUtils {
93
93
  `(https://developer.apple.com/xcode/). In case you already have the latest Xcode version installed, ` +
94
94
  `try run the command: \`sudo xcode-select -s /Applications/Xcode.app\`. If you are running tests from CI, ` +
95
95
  `we recommend running them with "--headless" device configuration (see: ` +
96
- `https://wix.github.io/Detox/docs/next/api/configuration/#device-configurations).`
96
+ `https://wix.github.io/Detox/docs/cli/test/#options).`
97
97
  );
98
98
  }
99
99
 
@@ -157,6 +157,30 @@ class AppleSimUtils {
157
157
  }
158
158
 
159
159
  async sendToHome(udid) {
160
+ if (await this._isSpringBoardInaccessible(udid)) {
161
+ // SpringBoard is not directly accessible by Simctl on iOS 16.0 and above, therefore we launch and terminate the
162
+ // Settings app instead. This sends the currently open app to the background and brings the home screen to the
163
+ // foreground.
164
+ await this._launchAndTerminateSettings(udid);
165
+ return;
166
+ }
167
+
168
+ await this._launchSpringBoard(udid);
169
+ }
170
+
171
+ async _isSpringBoardInaccessible(udid) {
172
+ const device = await this._findDeviceByUDID(udid);
173
+ const majorIOSVersion = parseInt(device.os.version.split('.')[0]);
174
+ return majorIOSVersion >= 16;
175
+ }
176
+
177
+ async _launchAndTerminateSettings(udid) {
178
+ const bundleId = 'com.apple.Preferences';
179
+ await this._execSimctl({ cmd: `launch ${udid} ${bundleId}`, retries: 10 });
180
+ await this._execSimctl({ cmd: `terminate ${udid} ${bundleId}`, retries: 10 });
181
+ }
182
+
183
+ async _launchSpringBoard(udid) {
160
184
  await this._execSimctl({ cmd: `launch ${udid} com.apple.springboard`, retries: 10 });
161
185
  }
162
186
 
@@ -271,7 +295,9 @@ class AppleSimUtils {
271
295
  // ```
272
296
  // This workaround is done to ignore the error above, as we do not care if the app was running before, we just
273
297
  // want to make sure it isn't now.
274
- if (err.code === 3 && err.stderr.includes(`the app is not currently running`)) {
298
+ if (err.code === 3 &&
299
+ (err.stderr.includes(`the app is not currently running`) ||
300
+ err.stderr.includes(`The operation couldn’t be completed. found nothing to terminate`))) {
275
301
  return;
276
302
  }
277
303
 
@@ -1,6 +1,4 @@
1
- const onSignalExit = require('signal-exit');
2
-
3
- const logger = require('../../utils/logger').child({ __filename });
1
+ const logger = require('../../utils/logger').child({ cat: 'device' });
4
2
 
5
3
  const cleanupLogData = {
6
4
  event: 'GENYCLOUD_TEARDOWN',
@@ -12,16 +10,16 @@ class GenyGlobalLifecycleHandler {
12
10
  this._instanceLifecycleService = instanceLifecycleService;
13
11
  }
14
12
 
15
- async globalInit() {
16
- onSignalExit((code, signal) => {
17
- if (signal) {
18
- const { rawDevices } = this._deviceCleanupRegistry.readRegisteredDevicesUNSAFE();
19
- const instanceHandles = rawDevicesToInstanceHandles(rawDevices);
20
- if (instanceHandles.length) {
21
- reportGlobalCleanupSummary(instanceHandles);
22
- }
23
- }
24
- });
13
+ // TODO: remove this ignore as soon as DetoxPrimaryContext is covered with tests
14
+ /* istanbul ignore next */
15
+ async globalInit() {}
16
+
17
+ emergencyCleanup() {
18
+ const { rawDevices } = this._deviceCleanupRegistry.readRegisteredDevicesUNSAFE();
19
+ const instanceHandles = rawDevicesToInstanceHandles(rawDevices);
20
+ if (instanceHandles.length) {
21
+ reportGlobalCleanupSummary(instanceHandles);
22
+ }
25
23
  }
26
24
 
27
25
  async globalCleanup() {
@@ -34,7 +32,7 @@ class GenyGlobalLifecycleHandler {
34
32
  }
35
33
 
36
34
  async function doSafeCleanup(instanceLifecycleService, instanceHandles) {
37
- logger.info(cleanupLogData, 'Initiating Genymotion cloud instances teardown...');
35
+ logger.info(cleanupLogData, 'Initiating Genymotion SaaS instances teardown...');
38
36
 
39
37
  const deletionLeaks = [];
40
38
  const killPromises = instanceHandles.map((instanceHandle) =>
@@ -47,7 +45,7 @@ async function doSafeCleanup(instanceLifecycleService, instanceHandles) {
47
45
 
48
46
  function reportGlobalCleanupSummary(deletionLeaks) {
49
47
  if (deletionLeaks.length) {
50
- logger.warn(cleanupLogData, 'WARNING! Detected a Genymotion cloud instance leakage, for the following instances:');
48
+ logger.warn(cleanupLogData, 'WARNING! Detected a Genymotion SaaS instance leakage, for the following instances:');
51
49
 
52
50
  deletionLeaks.forEach(({ uuid, name, error }) => {
53
51
  logger.warn(cleanupLogData, [
@@ -1,6 +1,7 @@
1
1
  const DetoxRuntimeError = require('../../errors/DetoxRuntimeError');
2
2
  const debug = require('../../utils/debug'); // debug utils, leave here even if unused
3
- const { traceCall, traceMethods } = require('../../utils/trace');
3
+ const log = require('../../utils/logger').child({ cat: 'device' });
4
+ const traceMethods = require('../../utils/traceMethods');
4
5
  const wrapWithStackTraceCutter = require('../../utils/wrapWithStackTraceCutter');
5
6
 
6
7
  const LaunchArgsEditor = require('./utils/LaunchArgsEditor');
@@ -20,6 +21,7 @@ class RuntimeDevice {
20
21
  'disableSynchronization',
21
22
  'enableSynchronization',
22
23
  'installApp',
24
+ 'installUtilBinaries',
23
25
  'launchApp',
24
26
  'matchFace',
25
27
  'matchFinger',
@@ -48,7 +50,7 @@ class RuntimeDevice {
48
50
  'unreverseTcpPort',
49
51
  ];
50
52
 
51
- traceMethods(this, 'device', methodNames);
53
+ traceMethods(log, this, methodNames);
52
54
  wrapWithStackTraceCutter(this, methodNames);
53
55
 
54
56
  this._appsConfig = appsConfig;
@@ -234,29 +236,34 @@ class RuntimeDevice {
234
236
  }
235
237
 
236
238
  async installApp(binaryPath, testBinaryPath) {
237
- await traceCall('appInstall', () => {
238
- const currentApp = binaryPath ? { binaryPath, testBinaryPath } : this._getCurrentApp();
239
- return this.deviceDriver.installApp(currentApp.binaryPath, currentApp.testBinaryPath);
240
- });
239
+ const currentApp = binaryPath ? { binaryPath, testBinaryPath } : this._getCurrentApp();
240
+ await this.deviceDriver.installApp(currentApp.binaryPath, currentApp.testBinaryPath);
241
+
242
+ // This abstraction leaks because our drivers themselves leak,
243
+ // so don't blame me - DeviceBaseDriver itself has `reverseTcpPort`,
244
+ // setting a vicious downward spiral. I can't refactor everything
245
+ // in a single pull request, so let's bear with it for now.
246
+ if (Array.isArray(currentApp.reversePorts)) {
247
+ for (const port of currentApp.reversePorts) {
248
+ await this.reverseTcpPort(port);
249
+ }
250
+ }
241
251
  }
242
252
 
243
253
  async uninstallApp(bundleId) {
244
254
  const _bundleId = bundleId || this._bundleId;
245
- await traceCall('appUninstall', () =>
246
- this.deviceDriver.uninstallApp(_bundleId));
255
+ await this.deviceDriver.uninstallApp(_bundleId);
247
256
  }
248
257
 
249
258
  async installUtilBinaries() {
250
259
  const paths = this._deviceConfig.utilBinaryPaths;
251
260
  if (paths) {
252
- await traceCall('installUtilBinaries', () =>
253
- this.deviceDriver.installUtilBinaries(paths));
261
+ await this.deviceDriver.installUtilBinaries(paths);
254
262
  }
255
263
  }
256
264
 
257
265
  async reloadReactNative() {
258
- await traceCall('reloadRN', () =>
259
- this.deviceDriver.reloadReactNative());
266
+ await this.deviceDriver.reloadReactNative();
260
267
  }
261
268
 
262
269
  async openURL(params) {
@@ -4,7 +4,7 @@ const path = require('path');
4
4
 
5
5
  const fs = require('fs-extra');
6
6
 
7
- const log = require('../../../utils/logger').child({ __filename });
7
+ const log = require('../../../utils/logger').child({ cat: 'device' });
8
8
 
9
9
  /**
10
10
  * @typedef DeviceDriverDeps
@@ -18,7 +18,7 @@ const sleep = require('../../../../utils/sleep');
18
18
  const apkUtils = require('../../../common/drivers/android/tools/apk');
19
19
  const DeviceDriverBase = require('../DeviceDriverBase');
20
20
 
21
- const log = logger.child({ __filename });
21
+ const log = logger.child({ cat: 'device' });
22
22
 
23
23
  /**
24
24
  * @typedef AndroidDriverProps
@@ -148,7 +148,15 @@ class AndroidDriver extends DeviceDriverBase {
148
148
 
149
149
  async waitUntilReady() {
150
150
  try {
151
- await Promise.race([super.waitUntilReady(), this.instrumentation.waitForCrash()]);
151
+ await Promise.race([
152
+ super.waitUntilReady(),
153
+ this.instrumentation.waitForCrash()
154
+ ]);
155
+ } catch (e) {
156
+ log.warn({ error: e }, 'An error occurred while waiting for the app to become ready. Waiting for disconnection...');
157
+ await this.client.waitUntilDisconnected();
158
+ log.warn('The app disconnected.');
159
+ throw e;
152
160
  } finally {
153
161
  this.instrumentation.abortWaitForCrash();
154
162
  }
@@ -7,7 +7,7 @@ const _ = require('lodash');
7
7
  const temporaryPath = require('../../../../artifacts/utils/temporaryPath');
8
8
  const DetoxRuntimeError = require('../../../../errors/DetoxRuntimeError');
9
9
  const getAbsoluteBinaryPath = require('../../../../utils/getAbsoluteBinaryPath');
10
- const log = require('../../../../utils/logger').child({ __filename });
10
+ const log = require('../../../../utils/logger').child({ cat: 'device' });
11
11
  const pressAnyKey = require('../../../../utils/pressAnyKey');
12
12
 
13
13
  const IosDriver = require('./IosDriver');
@@ -507,6 +507,14 @@ Examine your Detox config${this._atPath()}`,
507
507
  });
508
508
  }
509
509
 
510
+ unsupportedReversePorts(appPath) {
511
+ return new DetoxConfigError({
512
+ message: `Non-Android app configs cannot have "reversePorts" property:`,
513
+ debugInfo: this._focusOnAppConfig(appPath),
514
+ inspectOptions: { depth: 4 },
515
+ });
516
+ }
517
+
510
518
  missingAppBinaryPath(appPath) {
511
519
  return new DetoxConfigError({
512
520
  message: `Missing "binaryPath" property in the app config.\nExpected a string:`,
@@ -656,12 +664,19 @@ Examine your Detox config${this._atPath()}`,
656
664
  }
657
665
 
658
666
  invalidTestRunnerProperty(isGlobal) {
667
+ const testRunner = _.get(
668
+ isGlobal
669
+ ? this.contents
670
+ : this._getSelectedConfiguration(),
671
+ ['testRunner']
672
+ );
673
+
659
674
  return new DetoxConfigError({
660
- message: `testRunner should be an object, not a string`,
675
+ message: `testRunner should be an object, not a ${typeof testRunner}`,
661
676
  hint: `Check that in your Detox config${this._atPath()}`,
662
677
  inspectOptions: { depth: isGlobal ? 0 : 3 },
663
678
  debugInfo: isGlobal ? {
664
- testRunner: _.get(this.contents, ['testRunner']),
679
+ testRunner,
665
680
  ...this.contents,
666
681
  } : {
667
682
  ...this._focusOnConfiguration(c => _.pick(c, ['testRunner'])),
@@ -8,6 +8,10 @@ class DetoxError extends Error {
8
8
  this.name = 'DetoxError';
9
9
  }
10
10
 
11
+ format() {
12
+ return this.message;
13
+ }
14
+
11
15
  static get reportIssue() {
12
16
  return 'Please report this issue on our GitHub tracker:\nhttps://github.com/wix/Detox/issues';
13
17
  }
@@ -32,7 +36,7 @@ class DetoxError extends Error {
32
36
  */
33
37
  static format(err, inspectOptions = { depth: 1 }) {
34
38
  if (err instanceof DetoxError) {
35
- return err.message;
39
+ return err.format();
36
40
  }
37
41
 
38
42
  if (_.isError(err) && /^Command failed:/.test(err.message)) {