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

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.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-javadoc.jar → 20.0.3/detox-20.0.3-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-sources.jar → 20.0.3/detox-20.0.3-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0.pom → 20.0.3/detox-20.0.3.pom} +1 -7
  17. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.0.3/detox-20.0.3.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 +205 -43
  49. package/local-cli/build.js +1 -1
  50. package/local-cli/cli.js +11 -6
  51. package/local-cli/init.js +61 -21
  52. package/local-cli/rebuild-framework-cache.js +1 -1
  53. package/local-cli/reset-lock-file.js +16 -0
  54. package/local-cli/templates/jest.js +13 -10
  55. package/local-cli/test.js +14 -8
  56. package/local-cli/test.test.js +142 -61
  57. package/local-cli/testCommand/TestRunnerCommand.js +97 -77
  58. package/local-cli/testCommand/TestRunnerError.js +17 -0
  59. package/local-cli/testCommand/TestRunnerError.test.js +25 -0
  60. package/local-cli/testCommand/builder.js +0 -1
  61. package/local-cli/testCommand/middlewares.js +4 -13
  62. package/local-cli/testCommand/warnings.js +0 -3
  63. package/local-cli/utils/jestInternals.js +4 -1
  64. package/package.json +23 -18
  65. package/runners/deprecation.js +42 -44
  66. package/runners/jest/globalSetup.js +1 -1
  67. package/runners/jest/globalTeardown.js +1 -1
  68. package/runners/jest/index.d.ts +60 -0
  69. package/runners/jest/index.js +3 -8
  70. package/runners/jest/index.test.js +13 -0
  71. package/runners/jest/reporters/DetoxReporter.js +33 -2
  72. package/runners/jest/testEnvironment/index.js +119 -69
  73. package/runners/jest/testEnvironment/listeners/DetoxCoreListener.js +93 -46
  74. package/runners/jest/testEnvironment/listeners/DetoxPlatformFilterListener.js +1 -1
  75. package/runners/jest/testEnvironment/listeners/SpecReporter.js +13 -15
  76. package/runners/jest/testEnvironment/listeners/WorkerAssignReporter.js +1 -5
  77. package/runners/jest/testEnvironment/utils/assertJestCircus27.js +17 -3
  78. package/runners/jest/testEnvironment/utils/assertJestCircus27.test.js +0 -1
  79. package/src/DetoxWorker.js +99 -62
  80. package/src/android/core/NativeElement.js +56 -20
  81. package/src/android/core/NativeExpect.js +28 -9
  82. package/src/android/interactions/native.js +25 -18
  83. package/src/artifacts/ArtifactsManager.js +14 -47
  84. package/src/artifacts/instruments/ios/SimulatorInstrumentsRecording.js +3 -3
  85. package/src/artifacts/log/ios/SimulatorLogRecording.js +1 -1
  86. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +1 -1
  87. package/src/artifacts/templates/artifact/Artifact.js +1 -1
  88. package/src/artifacts/templates/plugin/ArtifactPlugin.js +1 -1
  89. package/src/artifacts/timeline/TimelineContextTypes.js +7 -0
  90. package/src/artifacts/utils/temporaryPath.js +49 -8
  91. package/src/artifacts/video/SimulatorRecordVideoPlugin.js +1 -1
  92. package/src/client/AsyncWebSocket.js +8 -17
  93. package/src/client/Client.js +19 -2
  94. package/src/client/actions/formatters/sync-resources/NetworkFormatter.js +1 -1
  95. package/src/configuration/collectCliConfig.js +1 -12
  96. package/src/configuration/composeAppsConfig.js +4 -0
  97. package/src/configuration/composeDeviceConfig.js +1 -1
  98. package/src/configuration/composeLoggerConfig.js +19 -10
  99. package/src/configuration/composeRunnerConfig.js +14 -9
  100. package/src/configuration/index.js +5 -1
  101. package/src/configuration/loadExternalConfig.js +1 -1
  102. package/src/devices/allocation/DeviceAllocator.js +3 -2
  103. package/src/devices/allocation/drivers/android/emulator/AVDValidator.js +5 -5
  104. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +4 -3
  105. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +1 -1
  106. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +6 -5
  107. package/src/devices/allocation/drivers/android/emulator/EmulatorVersionResolver.js +4 -6
  108. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +4 -17
  109. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +1 -1
  110. package/src/devices/common/drivers/android/exec/ADB.js +4 -0
  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 +14 -1
  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 +104 -70
  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.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-javadoc.jar.md5 +0 -1
  167. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-javadoc.jar.sha1 +0 -1
  168. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-javadoc.jar.sha256 +0 -1
  169. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-javadoc.jar.sha512 +0 -1
  170. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-sources.jar.md5 +0 -1
  171. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-sources.jar.sha1 +0 -1
  172. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-sources.jar.sha256 +0 -1
  173. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0-sources.jar.sha512 +0 -1
  174. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0.aar +0 -0
  175. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0.aar.md5 +0 -1
  176. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0.aar.sha1 +0 -1
  177. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0.aar.sha256 +0 -1
  178. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0.aar.sha512 +0 -1
  179. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0.pom.md5 +0 -1
  180. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0.pom.sha1 +0 -1
  181. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-breaking.new-global-lifecycle.0.pom.sha256 +0 -1
  182. package/Detox-android/com/wix/detox/20.0.3-breaking.new-global-lifecycle.0/detox-20.0.3-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
@@ -1,3 +1,4 @@
1
+ const CAF = require('caf');
1
2
  const _ = require('lodash');
2
3
 
3
4
  const Client = require('./client/Client');
@@ -11,7 +12,7 @@ const uuid = require('./utils/uuid');
11
12
  class DetoxWorker {
12
13
  constructor(context) {
13
14
  this._context = context;
14
- this._isCleaningUp = false;
15
+ this._injectedGlobalProperties = [];
15
16
  this._config = context[symbols.config];
16
17
  this._runtimeErrorComposer = new DetoxRuntimeErrorComposer(this._config);
17
18
  this._client = null;
@@ -32,6 +33,20 @@ class DetoxWorker {
32
33
  onError: this._onEmitError.bind(this),
33
34
  });
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';
35
50
  /** @type {Detox.Device} */
36
51
  this.device = null;
37
52
  /** @type {Detox.ElementFacade} */
@@ -51,11 +66,23 @@ class DetoxWorker {
51
66
  this.trace = this._context.trace;
52
67
  /** @deprecated */
53
68
  this.traceCall = this._context.traceCall;
54
- }
55
69
 
56
- async init() {
57
- if (this._isCleaningUp) return;
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
+ }
58
83
 
84
+ /** @this {DetoxWorker} */
85
+ init = function* (signal) {
59
86
  const {
60
87
  apps: appsConfig,
61
88
  artifacts: artifactsConfig,
@@ -63,14 +90,16 @@ class DetoxWorker {
63
90
  device: deviceConfig,
64
91
  session: sessionConfig
65
92
  } = this._config;
93
+
66
94
  this._appsConfig = appsConfig;
67
95
  this._artifactsConfig = artifactsConfig;
68
96
  this._behaviorConfig = behaviorConfig;
69
97
  this._deviceConfig = deviceConfig;
70
98
  this._sessionConfig = sessionConfig;
99
+ // @ts-ignore
100
+ this._sessionConfig.sessionId = sessionConfig.sessionId || uuid.UUID();
71
101
  this._runtimeErrorComposer.appsConfig = this._appsConfig;
72
102
 
73
- sessionConfig.sessionId = sessionConfig.sessionId || uuid.UUID();
74
103
  this._client = new Client(sessionConfig);
75
104
  this._client.terminateApp = async () => {
76
105
  // @ts-ignore
@@ -79,8 +108,7 @@ class DetoxWorker {
79
108
  }
80
109
  };
81
110
 
82
- await this._client.connect();
83
- if (this._isCleaningUp) return;
111
+ yield this._client.connect();
84
112
 
85
113
  const invocationManager = new InvocationManager(this._client);
86
114
 
@@ -97,8 +125,7 @@ class DetoxWorker {
97
125
  } = environmentFactory.createFactories(this._deviceConfig);
98
126
 
99
127
  const envValidator = envValidatorFactory.createValidator();
100
- await envValidator.validate();
101
- if (this._isCleaningUp) return;
128
+ yield envValidator.validate();
102
129
 
103
130
  const commonDeps = {
104
131
  invocationManager,
@@ -109,8 +136,7 @@ class DetoxWorker {
109
136
 
110
137
  this._artifactsManager = artifactsManagerFactory.createArtifactsManager(this._artifactsConfig, commonDeps);
111
138
  this._deviceAllocator = deviceAllocatorFactory.createDeviceAllocator(commonDeps);
112
- this._deviceCookie = await this._deviceAllocator.allocate(this._deviceConfig);
113
- if (this._isCleaningUp) return;
139
+ this._deviceCookie = yield this._deviceAllocator.allocate(this._deviceConfig);
114
140
 
115
141
  this.device = runtimeDeviceFactory.createRuntimeDevice(
116
142
  this._deviceCookie,
@@ -121,7 +147,6 @@ class DetoxWorker {
121
147
  deviceConfig: this._deviceConfig,
122
148
  sessionConfig,
123
149
  });
124
- if (this._isCleaningUp) return;
125
150
 
126
151
  const matchers = matchersFactory.createMatchers({
127
152
  invocationManager,
@@ -131,34 +156,37 @@ class DetoxWorker {
131
156
  Object.assign(this, matchers);
132
157
 
133
158
  if (behaviorConfig.init.exposeGlobals) {
134
- Object.assign(DetoxWorker.global, {
159
+ const injectedGlobals = {
135
160
  ...matchers,
136
161
  device: this.device,
137
162
  detox: this,
138
- });
163
+ };
164
+
165
+ this._injectedGlobalProperties = Object.keys(injectedGlobals);
166
+ Object.assign(DetoxWorker.global, injectedGlobals);
139
167
  }
140
168
 
141
169
  // @ts-ignore
142
- await this.device.installUtilBinaries();
143
- if (this._isCleaningUp) return;
170
+ yield this.device.installUtilBinaries();
144
171
 
145
172
  if (behaviorConfig.init.reinstallApp) {
146
- await this._reinstallAppsOnDevice();
147
- if (this._isCleaningUp) return;
173
+ yield this._reinstallAppsOnDevice(signal);
148
174
  }
149
175
 
150
176
  const appAliases = Object.keys(this._appsConfig);
151
177
  if (appAliases.length === 1) {
152
- await this.device.selectApp(appAliases[0]);
178
+ yield this.device.selectApp(appAliases[0]);
153
179
  } else {
154
- await this.device.selectApp(null);
180
+ yield this.device.selectApp(null);
155
181
  }
156
-
157
- return this;
158
- }
182
+ };
159
183
 
160
184
  async cleanup() {
161
- this._isCleaningUp = true;
185
+ this._initToken.abort('CLEANUP');
186
+
187
+ for (const key of this._injectedGlobalProperties) {
188
+ delete DetoxWorker.global[key];
189
+ }
162
190
 
163
191
  if (this._artifactsManager) {
164
192
  await this._artifactsManager.onBeforeCleanup();
@@ -187,46 +215,45 @@ class DetoxWorker {
187
215
  return this._context.log;
188
216
  }
189
217
 
190
- onRunStart = async (...args) => this._artifactsManager.onRunStart(...args);
191
- onRunDescribeStart = async (...args) => this._artifactsManager.onRunDescribeStart(...args);
192
- onTestStart = async (testSummary) => {
193
- if (this._isCleaningUp) return;
218
+ onRunDescribeStart = function* (_signal, ...args) {
219
+ yield this._artifactsManager.onRunDescribeStart(...args);
220
+ };
221
+
222
+ onTestStart = function* (_signal, testSummary) {
194
223
  this._validateTestSummary('beforeEach', testSummary);
195
- this._logTestRunCheckpoint('DETOX_BEFORE_EACH', testSummary);
196
224
 
197
- if (this._isCleaningUp) return;
198
- await this._dumpUnhandledErrorsIfAny({
225
+ yield this._dumpUnhandledErrorsIfAny({
199
226
  pendingRequests: false,
200
227
  testName: testSummary.fullName,
201
228
  });
202
229
 
203
- if (this._isCleaningUp) return;
204
- await this._artifactsManager.onTestStart(testSummary);
230
+ yield this._artifactsManager.onTestStart(testSummary);
231
+ };
232
+
233
+ onHookFailure = function* (_signal, ...args) {
234
+ yield this._artifactsManager.onHookFailure(...args);
205
235
  };
206
- onHookStart = async (...args) => this._artifactsManager.onHookStart(...args);
207
- onHookFailure = async (...args) => this._artifactsManager.onHookFailure(...args);
208
- onHookSuccess = async (...args) => this._artifactsManager.onHookSuccess(...args);
209
- onTestFnStart = async (...args) => this._artifactsManager.onTestFnStart(...args);
210
- onTestFnFailure = async (...args) => this._artifactsManager.onTestFnFailure(...args);
211
- onTestFnSuccess = async (...args) => this._artifactsManager.onTestFnSuccess(...args);
212
- onTestDone = async (testSummary) => {
213
- if (this._isCleaningUp) return;
236
+
237
+ onTestFnFailure = function* (_signal, ...args) {
238
+ yield this._artifactsManager.onTestFnFailure(...args);
239
+ };
240
+
241
+ onTestDone = function* (_signal, testSummary) {
214
242
  this._validateTestSummary('afterEach', testSummary);
215
- this._logTestRunCheckpoint('DETOX_AFTER_EACH', testSummary);
216
243
 
217
- if (this._isCleaningUp) return;
218
- await this._artifactsManager.onTestDone(testSummary);
244
+ yield this._artifactsManager.onTestDone(testSummary);
219
245
 
220
- if (this._isCleaningUp) return;
221
- await this._dumpUnhandledErrorsIfAny({
246
+ yield this._dumpUnhandledErrorsIfAny({
222
247
  pendingRequests: testSummary.timedOut,
223
248
  testName: testSummary.fullName,
224
249
  });
225
250
  };
226
- onRunDescribeFinish = async (...args) => this._artifactsManager.onRunDescribeFinish(...args);
227
- onRunFinish = async (...args) => this._artifactsManager.onRunFinish(...args);
228
251
 
229
- async _reinstallAppsOnDevice() {
252
+ onRunDescribeFinish = function* (_signal, ...args) {
253
+ yield this._artifactsManager.onRunDescribeFinish(...args);
254
+ };
255
+
256
+ *_reinstallAppsOnDevice(_signal) {
230
257
  const appNames = _(this._appsConfig)
231
258
  .map((config, key) => [key, `${config.binaryPath}:${config.testBinaryPath}`])
232
259
  .uniqBy(1)
@@ -234,24 +261,16 @@ class DetoxWorker {
234
261
  .value();
235
262
 
236
263
  for (const appName of appNames) {
237
- await this.device.selectApp(appName);
238
- if (this._isCleaningUp) return;
239
- await this.device.uninstallApp();
240
- if (this._isCleaningUp) return;
264
+ yield this.device.selectApp(appName);
265
+ yield this.device.uninstallApp();
241
266
  }
242
267
 
243
268
  for (const appName of appNames) {
244
- await this.device.selectApp(appName);
245
- if (this._isCleaningUp) return;
246
- await this.device.installApp();
247
- if (this._isCleaningUp) return;
269
+ yield this.device.selectApp(appName);
270
+ yield this.device.installApp();
248
271
  }
249
272
  }
250
273
 
251
- _logTestRunCheckpoint(event, { status, fullName }) {
252
- this.log.trace({ event, status }, `${status} test: ${JSON.stringify(fullName)}`);
253
- }
254
-
255
274
  _validateTestSummary(methodName, testSummary) {
256
275
  if (!_.isPlainObject(testSummary)) {
257
276
  throw this._runtimeErrorComposer.invalidTestSummary(methodName, testSummary);
@@ -280,10 +299,28 @@ class DetoxWorker {
280
299
  error
281
300
  );
282
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
+
283
320
  }
284
321
 
285
322
  /**
286
- * @type {NodeJS.Global}
323
+ * @type {NodeJS.Global | {}}
287
324
  */
288
325
  DetoxWorker.global = global;
289
326
 
@@ -5,6 +5,7 @@ const tempfile = require('tempfile');
5
5
 
6
6
  const DetoxRuntimeError = require('../../errors/DetoxRuntimeError');
7
7
  const invoke = require('../../invoke');
8
+ const { actionDescription } = require('../../utils/invocationTraceDescriptions');
8
9
  const actions = require('../actions/native');
9
10
  const DetoxMatcherApi = require('../espressoapi/DetoxMatcher');
10
11
  const { ActionInteraction } = require('../interactions/native');
@@ -18,12 +19,11 @@ class NativeElement {
18
19
  }
19
20
 
20
21
  _selectElementWithMatcher(matcher) {
21
- // if (!(matcher instanceof NativeMatcher)) throw new DetoxRuntimeError(`Element _selectElementWithMatcher argument must be a valid NativeMatcher, got ${typeof matcher}`);
22
22
  this._call = invoke.call(invoke.Espresso, 'onView', matcher._call);
23
23
  }
24
24
 
25
25
  atIndex(index) {
26
- if (typeof index !== 'number') throw new DetoxRuntimeError(`Element atIndex argument must be a number, got ${typeof index}`);
26
+ if (typeof index !== 'number') throw new DetoxRuntimeError({ message: `Element atIndex argument must be a number, got ${typeof index}` });
27
27
  const matcher = this._originalMatcher;
28
28
  this._originalMatcher._call = invoke.callDirectly(DetoxMatcherApi.matcherForAtIndex(index, matcher._call.value));
29
29
 
@@ -32,56 +32,84 @@ class NativeElement {
32
32
  }
33
33
 
34
34
  async tap(value) {
35
- return await new ActionInteraction(this._invocationManager, this, new actions.TapAction(value)).execute();
35
+ const action = new actions.TapAction(value);
36
+ const traceDescription = actionDescription.tapAtPoint(value);
37
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
36
38
  }
37
39
 
38
40
  async tapAtPoint(value) {
39
- return await new ActionInteraction(this._invocationManager, this, new actions.TapAtPointAction(value)).execute();
41
+ const action = new actions.TapAtPointAction(value);
42
+ const traceDescription = actionDescription.tapAtPoint(value);
43
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
40
44
  }
41
45
 
42
46
  async longPress() {
43
- return await new ActionInteraction(this._invocationManager, this, new actions.LongPressAction()).execute();
47
+ const action = new actions.LongPressAction();
48
+ const traceDescription = actionDescription.longPress();
49
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
44
50
  }
45
51
 
46
52
  async multiTap(times) {
47
- return await new ActionInteraction(this._invocationManager, this, new actions.MultiClickAction(times)).execute();
53
+ if (typeof times !== 'number') throw new Error('times should be a number, but got ' + (times + (' (' + (typeof times + ')'))));
54
+ if (times < 1) throw new Error('times should be greater than 0, but got ' + times);
55
+
56
+ const action = new actions.MultiClickAction(times);
57
+ const traceDescription = actionDescription.multiTap(times);
58
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
48
59
  }
49
60
 
50
61
  async tapBackspaceKey() {
51
- return await new ActionInteraction(this._invocationManager, this, new actions.PressKeyAction(67)).execute();
62
+ const action = new actions.PressKeyAction(67);
63
+ const traceDescription = actionDescription.tapBackspaceKey();
64
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
52
65
  }
53
66
 
54
67
  async tapReturnKey() {
55
- return await new ActionInteraction(this._invocationManager, this, new actions.TypeTextAction('\n')).execute();
68
+ const action = new actions.TypeTextAction('\n');
69
+ const traceDescription = actionDescription.tapReturnKey();
70
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
56
71
  }
57
72
 
58
73
  async typeText(value) {
59
- return await new ActionInteraction(this._invocationManager, this, new actions.TypeTextAction(value)).execute();
74
+ const action = new actions.TypeTextAction(value);
75
+ const traceDescription = actionDescription.typeText(value);
76
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
60
77
  }
61
78
 
62
79
  async replaceText(value) {
63
- return await new ActionInteraction(this._invocationManager, this, new actions.ReplaceTextAction(value)).execute();
80
+ const action = new actions.ReplaceTextAction(value);
81
+ const traceDescription = actionDescription.replaceText(value);
82
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
64
83
  }
65
84
 
66
85
  async clearText() {
67
- return await new ActionInteraction(this._invocationManager, this, new actions.ClearTextAction()).execute();
86
+ const action = new actions.ClearTextAction();
87
+ const traceDescription = actionDescription.clearText();
88
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
68
89
  }
69
90
 
70
91
  async scroll(amount, direction = 'down', startPositionX, startPositionY) {
71
- // override the user's element selection with an extended matcher that looks for UIScrollView children
72
- // this._selectElementWithMatcher(this._originalMatcher._extendToDescendantScrollViews());
73
- return await new ActionInteraction(this._invocationManager, this, new actions.ScrollAmountAction(direction, amount, startPositionX, startPositionY)).execute();
92
+ const action = new actions.ScrollAmountAction(direction, amount, startPositionX, startPositionY);
93
+ const traceDescription = actionDescription.scroll(amount, direction, startPositionX, startPositionY);
94
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
74
95
  }
75
96
 
76
97
  async scrollTo(edge) {
77
98
  // override the user's element selection with an extended matcher that looks for UIScrollView children
78
99
  this._selectElementWithMatcher(this._originalMatcher._extendToDescendantScrollViews());
79
- return await new ActionInteraction(this._invocationManager, this, new actions.ScrollEdgeAction(edge)).execute();
100
+
101
+ const action = new actions.ScrollEdgeAction(edge);
102
+ const traceDescription = actionDescription.scrollTo(edge);
103
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
80
104
  }
81
105
 
82
106
  async scrollToIndex(index) {
107
+ // override the user's element selection with an extended matcher that looks for UIScrollView children
83
108
  this._selectElementWithMatcher(this._originalMatcher._extendToDescendantScrollViews());
84
- return await new ActionInteraction(this._invocationManager, this, new actions.ScrollToIndex(index)).execute();
109
+
110
+ const action = new actions.ScrollToIndex(index);
111
+ const traceDescription = actionDescription.scrollToIndex(index);
112
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
85
113
  }
86
114
 
87
115
  /**
@@ -96,13 +124,17 @@ class NativeElement {
96
124
 
97
125
  // override the user's element selection with an extended matcher that avoids RN issues with RCTScrollView
98
126
  this._selectElementWithMatcher(this._originalMatcher._avoidProblematicReactNativeElements());
127
+
99
128
  const action = new actions.SwipeAction(direction, speed, normalizedSwipeOffset, normalizedStartingPointX, normalizedStartingPointY);
100
- return await new ActionInteraction(this._invocationManager, this, action).execute();
129
+ const traceDescription = actionDescription.swipe(direction, speed, normalizedSwipeOffset, normalizedStartingPointX, normalizedStartingPointY);
130
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
101
131
  }
102
132
 
103
133
  async takeScreenshot(screenshotName) {
104
134
  // TODO this should be moved to a lower-layer handler of this use-case
105
- const resultBase64 = await new ActionInteraction(this._invocationManager, this, new actions.TakeElementScreenshot()).execute();
135
+ const action = new actions.TakeElementScreenshot();
136
+ const traceDescription = actionDescription.takeScreenshot(screenshotName);
137
+ const resultBase64 = await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
106
138
  const filePath = tempfile('detox.element-screenshot.png');
107
139
  await fs.writeFile(filePath, resultBase64, 'base64');
108
140
 
@@ -115,12 +147,16 @@ class NativeElement {
115
147
  }
116
148
 
117
149
  async getAttributes() {
118
- const result = await new ActionInteraction(this._invocationManager, this, new actions.GetAttributes()).execute();
150
+ const action = new actions.GetAttributes();
151
+ const traceDescription = actionDescription.getAttributes();
152
+ const result = await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
119
153
  return JSON.parse(result);
120
154
  }
121
155
 
122
156
  async adjustSliderToPosition(newPosition) {
123
- return await new ActionInteraction(this._invocationManager, this, new actions.AdjustSliderToPosition(newPosition)).execute();
157
+ const action = new actions.AdjustSliderToPosition(newPosition);
158
+ const traceDescription = actionDescription.adjustSliderToPosition(newPosition);
159
+ return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
124
160
  }
125
161
  }
126
162
 
@@ -1,3 +1,4 @@
1
+ const { expectDescription } = require('../../utils/invocationTraceDescriptions');
1
2
  const { MatcherAssertionInteraction } = require('../interactions/native');
2
3
  const matchers = require('../matchers/native');
3
4
 
@@ -19,7 +20,9 @@ class NativeExpectElement extends NativeExpect {
19
20
  }
20
21
 
21
22
  async toBeVisible(pct) {
22
- return await new MatcherAssertionInteraction(this._invocationManager, this._element, this._notCondition ? new matchers.VisibleMatcher(pct).not : new matchers.VisibleMatcher(pct)).execute();
23
+ const matcher = new matchers.VisibleMatcher(pct);
24
+ const traceDescription = expectDescription.toBeVisible(pct);
25
+ return await new MatcherAssertionInteraction(this._invocationManager, this._element, matcher, this._notCondition, traceDescription).execute();
23
26
  }
24
27
 
25
28
  async toBeNotVisible() {
@@ -27,7 +30,9 @@ class NativeExpectElement extends NativeExpect {
27
30
  }
28
31
 
29
32
  async toExist() {
30
- return await new MatcherAssertionInteraction(this._invocationManager, this._element, this._notCondition ? new matchers.ExistsMatcher().not : new matchers.ExistsMatcher()).execute();
33
+ const matcher = new matchers.ExistsMatcher();
34
+ const traceDescription = expectDescription.toExist();
35
+ return await new MatcherAssertionInteraction(this._invocationManager, this._element, matcher, this._notCondition, traceDescription).execute();
31
36
  }
32
37
 
33
38
  async toNotExist() {
@@ -35,7 +40,9 @@ class NativeExpectElement extends NativeExpect {
35
40
  }
36
41
 
37
42
  async toHaveText(text) {
38
- return await new MatcherAssertionInteraction(this._invocationManager, this._element, this._notCondition ? new matchers.TextMatcher(text).not : new matchers.TextMatcher(text)).execute();
43
+ const matcher = new matchers.TextMatcher(text);
44
+ const traceDescription = expectDescription.toHaveText(text);
45
+ return await new MatcherAssertionInteraction(this._invocationManager, this._element, matcher, this._notCondition, traceDescription).execute();
39
46
  }
40
47
 
41
48
  async toNotHaveText(text) {
@@ -43,7 +50,9 @@ class NativeExpectElement extends NativeExpect {
43
50
  }
44
51
 
45
52
  async toHaveLabel(value) {
46
- return await new MatcherAssertionInteraction(this._invocationManager, this._element, this._notCondition ? new matchers.LabelMatcher(value).not : new matchers.LabelMatcher(value)).execute();
53
+ const matcher = new matchers.LabelMatcher(value);
54
+ const traceDescription = expectDescription.toHaveLabel(value);
55
+ return await new MatcherAssertionInteraction(this._invocationManager, this._element, matcher, this._notCondition, traceDescription).execute();
47
56
  }
48
57
 
49
58
  async toNotHaveLabel(value) {
@@ -51,7 +60,9 @@ class NativeExpectElement extends NativeExpect {
51
60
  }
52
61
 
53
62
  async toHaveId(value) {
54
- return await new MatcherAssertionInteraction(this._invocationManager, this._element, this._notCondition ? new matchers.IdMatcher(value).not : new matchers.IdMatcher(value)).execute();
63
+ const matcher = new matchers.IdMatcher(value);
64
+ const traceDescription = expectDescription.toHaveId(value);
65
+ return await new MatcherAssertionInteraction(this._invocationManager, this._element, matcher, this._notCondition, traceDescription).execute();
55
66
  }
56
67
 
57
68
  async toNotHaveId(value) {
@@ -59,7 +70,9 @@ class NativeExpectElement extends NativeExpect {
59
70
  }
60
71
 
61
72
  async toHaveValue(value) {
62
- return await new MatcherAssertionInteraction(this._invocationManager, this._element, this._notCondition ? new matchers.ValueMatcher(value).not : new matchers.ValueMatcher(value)).execute();
73
+ const matcher = new matchers.ValueMatcher(value);
74
+ const traceDescription = expectDescription.toHaveValue(value);
75
+ return await new MatcherAssertionInteraction(this._invocationManager, this._element, matcher, this._notCondition, traceDescription).execute();
63
76
  }
64
77
 
65
78
  async toNotHaveValue(value) {
@@ -67,15 +80,21 @@ class NativeExpectElement extends NativeExpect {
67
80
  }
68
81
 
69
82
  async toHaveToggleValue(value) {
70
- return await new MatcherAssertionInteraction(this._invocationManager, this._element, this._notCondition ? new matchers.ToggleMatcher(value).not : new matchers.ToggleMatcher(value)).execute();
83
+ const matcher = new matchers.ToggleMatcher(value);
84
+ const traceDescription = expectDescription.toHaveToggleValue(value);
85
+ return await new MatcherAssertionInteraction(this._invocationManager, this._element, matcher, this._notCondition, traceDescription).execute();
71
86
  }
72
87
 
73
88
  async toHaveSliderPosition(value, tolerance = 0) {
74
- return await new MatcherAssertionInteraction(this._invocationManager, this._element, this._notCondition ? new matchers.SliderPositionMatcher(value, tolerance).not : new matchers.SliderPositionMatcher(value, tolerance)).execute();
89
+ const matcher = new matchers.SliderPositionMatcher(value, tolerance);
90
+ const traceDescription = expectDescription.toHaveSliderPosition(value, tolerance);
91
+ return await new MatcherAssertionInteraction(this._invocationManager, this._element, matcher, this._notCondition, traceDescription).execute();
75
92
  }
76
93
 
77
94
  async toBeFocused() {
78
- return await new MatcherAssertionInteraction(this._invocationManager, this._element, this._notCondition ? new matchers.FocusMatcher().not : new matchers.FocusMatcher()).execute();
95
+ const matcher = new matchers.FocusMatcher();
96
+ const traceDescription = expectDescription.toBeFocused();
97
+ return await new MatcherAssertionInteraction(this._invocationManager, this._element, matcher, this._notCondition, traceDescription).execute();
79
98
  }
80
99
 
81
100
  async toBeNotFocused() {
@@ -1,4 +1,7 @@
1
1
  const DetoxRuntimeError = require('../../errors/DetoxRuntimeError');
2
+ const { expectDescription, actionDescription } = require('../../utils/invocationTraceDescriptions');
3
+ const log = require('../../utils/logger').child({ cat: 'ws-client, ws' });
4
+ const traceInvocationCall = require('../../utils/traceInvocationCall').bind(null, log);
2
5
  const { ScrollAmountStopAtEdgeAction } = require('../actions/native');
3
6
  const { NativeMatcher } = require('../core/NativeMatcher');
4
7
  const DetoxAssertionApi = require('../espressoapi/DetoxAssertion');
@@ -9,45 +12,50 @@ function call(maybeAFunction) {
9
12
  }
10
13
 
11
14
  class Interaction {
12
- constructor(invocationManager) {
15
+ constructor(invocationManager, traceDescription) {
13
16
  this._call = undefined;
17
+ this._traceDescription = traceDescription;
14
18
  this._invocationManager = invocationManager;
15
19
  }
16
20
 
17
21
  async execute() {
18
- const resultObj = await this._invocationManager.execute(this._call);
19
- return resultObj ? resultObj.result : undefined;
22
+ return traceInvocationCall(this._traceDescription, this._call,
23
+ this._invocationManager.execute(this._call).then((resultObj) => resultObj ? resultObj.result : undefined));
20
24
  }
21
25
  }
22
26
 
23
27
  class ActionInteraction extends Interaction {
24
- constructor(invocationManager, element, action) {
25
- super(invocationManager);
28
+ constructor(invocationManager, element, action, traceDescription) {
29
+ super(invocationManager, traceDescription);
26
30
  this._call = EspressoDetoxApi.perform(call(element._call), action._call);
27
31
  // TODO: move this.execute() here from the caller
28
32
  }
29
33
  }
30
34
 
31
35
  class MatcherAssertionInteraction extends Interaction {
32
- constructor(invocationManager, element, matcher) {
33
- super(invocationManager);
36
+ constructor(invocationManager, element, matcher, notCondition, traceDescription) {
37
+ traceDescription = expectDescription.full(traceDescription, notCondition);
38
+ super(invocationManager, traceDescription);
39
+
40
+ matcher = notCondition ? matcher.not : matcher;
34
41
  this._call = DetoxAssertionApi.assertMatcher(call(element._call), matcher._call.value);
35
42
  // TODO: move this.execute() here from the caller
36
43
  }
37
44
  }
38
45
 
39
46
  class WaitForInteraction extends Interaction {
40
- constructor(invocationManager, element, assertionMatcher) {
41
- super(invocationManager);
47
+ constructor(invocationManager, element, assertionMatcher, expectTraceDescription) {
48
+ super(invocationManager, expectTraceDescription);
42
49
  this._element = element;
43
50
  this._assertionMatcher = assertionMatcher;
44
51
  this._element._selectElementWithMatcher(this._element._originalMatcher);
45
52
  }
46
53
 
47
54
  async withTimeout(timeout) {
48
- if (typeof timeout !== 'number') throw new DetoxRuntimeError(`WaitForInteraction withTimeout argument must be a number, got ${typeof timeout}`);
49
- if (timeout < 0) throw new DetoxRuntimeError('timeout must be larger than 0');
55
+ if (typeof timeout !== 'number') throw new DetoxRuntimeError({ message: `WaitForInteraction withTimeout argument must be a number, got ${typeof timeout}` });
56
+ if (timeout < 0) throw new DetoxRuntimeError({ message: 'timeout must be larger than 0' });
50
57
 
58
+ this._traceDescription = expectDescription.waitForWithTimeout(this._traceDescription, timeout);
51
59
  this._call = DetoxAssertionApi.waitForAssertMatcher(call(this._element._call), this._assertionMatcher._call.value, timeout / 1000);
52
60
  await this.execute();
53
61
  }
@@ -58,20 +66,18 @@ class WaitForInteraction extends Interaction {
58
66
  }
59
67
 
60
68
  class WaitForActionInteractionBase extends Interaction {
61
- constructor(invocationManager, element, matcher, searchMatcher) {
62
- super(invocationManager);
63
- //if (!(element instanceof NativeElement)) throw new DetoxRuntimeError(`WaitForActionInteraction ctor 1st argument must be a valid NativeElement, got ${typeof element}`);
64
- //if (!(matcher instanceof NativeMatcher)) throw new DetoxRuntimeError(`WaitForActionInteraction ctor 2nd argument must be a valid NativeMatcher, got ${typeof matcher}`);
69
+ constructor(invocationManager, element, matcher, searchMatcher, traceDescription) {
70
+ super(invocationManager, traceDescription);
71
+
65
72
  if (!(searchMatcher instanceof NativeMatcher))
66
- throw new DetoxRuntimeError(`WaitForActionInteraction ctor 3rd argument must be a valid NativeMatcher, got ${typeof searchMatcher}`);
73
+ throw new DetoxRuntimeError({ message: `WaitForActionInteraction ctor 3rd argument must be a valid NativeMatcher, got ${typeof searchMatcher}` });
74
+
67
75
  this._element = element;
68
76
  this._originalMatcher = matcher;
69
77
  this._searchMatcher = searchMatcher;
70
78
  }
71
79
 
72
80
  _prepare(searchAction) {
73
- //if (!searchAction instanceof Action) throw new DetoxRuntimeError(`WaitForActionInteraction _execute argument must be a valid Action, got ${typeof searchAction}`);
74
-
75
81
  this._call = DetoxAssertionApi.waitForAssertMatcherWithSearchAction(
76
82
  call(this._element._call),
77
83
  call(this._originalMatcher._call).value,
@@ -83,6 +89,7 @@ class WaitForActionInteractionBase extends Interaction {
83
89
 
84
90
  class WaitForActionInteraction extends WaitForActionInteractionBase {
85
91
  async scroll(amount, direction = 'down', scrollPositionX, scrollPositionY) {
92
+ this._traceDescription = expectDescription.waitFor(actionDescription.scroll(amount, direction, scrollPositionX, scrollPositionY));
86
93
  this._prepare(new ScrollAmountStopAtEdgeAction(direction, amount, scrollPositionX, scrollPositionY));
87
94
  await this.execute();
88
95
  }