detox 20.0.4-breaking.new-global-lifecycle.0 → 20.0.7-prerelease.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. package/Detox-android/com/wix/detox/{20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-javadoc.jar → 20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-sources.jar → 20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.pom → 20.0.7-prerelease.0/detox-20.0.7-prerelease.0.pom} +1 -1
  17. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.0.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.0.7-prerelease.0/detox-20.0.7-prerelease.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/android/detox/proguard-rules-app.pro +4 -0
  29. package/android/detox/src/full/java/com/wix/detox/DetoxCrashHandler.kt +1 -1
  30. package/android/detox/src/full/java/com/wix/detox/LaunchArgs.java +9 -0
  31. package/android/detox/src/full/java/com/wix/detox/TestEngineFacade.kt +1 -1
  32. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeExtension.kt +15 -2
  33. package/android/detox/src/full/java/com/wix/detox/reactnative/ReactNativeIdlingResources.kt +43 -38
  34. package/index.d.ts +58 -40
  35. package/internals.d.ts +63 -15
  36. package/local-cli/cli.js +1 -1
  37. package/local-cli/rebuild-framework-cache.js +1 -1
  38. package/local-cli/test.js +3 -2
  39. package/local-cli/test.test.js +1 -1
  40. package/local-cli/testCommand/TestRunnerCommand.js +10 -7
  41. package/package.json +5 -4
  42. package/runners/jest/globalSetup.js +1 -1
  43. package/runners/jest/globalTeardown.js +1 -1
  44. package/runners/jest/testEnvironment/index.js +36 -18
  45. package/runners/jest/testEnvironment/listeners/DetoxCoreListener.js +76 -41
  46. package/runners/jest/testEnvironment/listeners/SpecReporter.js +1 -1
  47. package/runners/jest/testEnvironment/listeners/WorkerAssignReporter.js +1 -1
  48. package/src/DetoxWorker.js +4 -7
  49. package/src/android/core/NativeElement.js +56 -20
  50. package/src/android/core/NativeExpect.js +28 -9
  51. package/src/android/interactions/native.js +24 -18
  52. package/src/artifacts/ArtifactsManager.js +8 -23
  53. package/src/artifacts/instruments/ios/SimulatorInstrumentsRecording.js +3 -3
  54. package/src/artifacts/log/ios/SimulatorLogRecording.js +1 -1
  55. package/src/artifacts/screenshot/SimulatorScreenshotPlugin.js +1 -1
  56. package/src/artifacts/templates/artifact/Artifact.js +1 -1
  57. package/src/artifacts/templates/plugin/ArtifactPlugin.js +1 -1
  58. package/src/artifacts/timeline/TimelineContextTypes.js +7 -0
  59. package/src/artifacts/utils/temporaryPath.js +18 -7
  60. package/src/artifacts/video/SimulatorRecordVideoPlugin.js +1 -1
  61. package/src/client/AsyncWebSocket.js +8 -17
  62. package/src/client/Client.js +19 -2
  63. package/src/configuration/collectCliConfig.js +1 -1
  64. package/src/configuration/composeDeviceConfig.js +1 -1
  65. package/src/configuration/composeLoggerConfig.js +17 -8
  66. package/src/configuration/composeRunnerConfig.js +1 -1
  67. package/src/configuration/index.js +5 -1
  68. package/src/configuration/loadExternalConfig.js +1 -1
  69. package/src/devices/allocation/DeviceAllocator.js +3 -2
  70. package/src/devices/allocation/drivers/android/emulator/AVDValidator.js +1 -1
  71. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +3 -2
  72. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocationHelper.js +1 -1
  73. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +3 -2
  74. package/src/devices/allocation/drivers/android/emulator/EmulatorVersionResolver.js +4 -6
  75. package/src/devices/allocation/drivers/android/emulator/launchEmulatorProcess.js +1 -1
  76. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceAllocationHelper.js +1 -1
  77. package/src/devices/common/drivers/android/genycloud/services/GenyInstanceNaming.js +3 -3
  78. package/src/devices/common/drivers/android/genycloud/services/GenyRecipesService.js +1 -1
  79. package/src/devices/common/drivers/android/tools/EmulatorTelnet.js +1 -1
  80. package/src/devices/common/drivers/android/tools/FreeDeviceFinder.js +1 -1
  81. package/src/devices/common/drivers/android/tools/MonitoredInstrumentation.js +1 -1
  82. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +4 -2
  83. package/src/devices/lifecycle/GenyGlobalLifecycleHandler.js +9 -13
  84. package/src/devices/runtime/RuntimeDevice.js +9 -12
  85. package/src/devices/runtime/drivers/DeviceDriverBase.js +1 -1
  86. package/src/devices/runtime/drivers/android/AndroidDriver.js +10 -2
  87. package/src/devices/runtime/drivers/ios/SimulatorDriver.js +1 -1
  88. package/src/ios/expectTwo.js +152 -67
  89. package/src/ipc/IPCClient.js +3 -8
  90. package/src/ipc/IPCServer.js +11 -11
  91. package/src/ipc/{state.js → SessionState.js} +23 -50
  92. package/src/logger/DetoxLogger.js +268 -155
  93. package/src/logger/index.js +4 -0
  94. package/src/logger/utils/BunyanLogger.js +72 -0
  95. package/src/logger/utils/CategoryThreadDispatcher.js +58 -0
  96. package/src/logger/utils/MessageStack.js +24 -0
  97. package/src/logger/{TraceThreadDispatcher.js → utils/ThreadDispatcher.js} +34 -5
  98. package/src/logger/{customConsoleLogger.js → utils/customConsoleLogger.js} +4 -4
  99. package/src/logger/utils/sanitizeBunyanContext.js +28 -0
  100. package/src/logger/utils/tracerLegacy.js +48 -0
  101. package/src/realms/DetoxContext.js +65 -57
  102. package/src/realms/DetoxInternalsFacade.js +7 -5
  103. package/src/realms/DetoxPrimaryContext.js +125 -40
  104. package/src/realms/DetoxSecondaryContext.js +24 -29
  105. package/src/server/DetoxConnection.js +18 -23
  106. package/src/server/DetoxServer.js +7 -10
  107. package/src/server/DetoxSession.js +6 -6
  108. package/src/server/DetoxSessionManager.js +1 -1
  109. package/src/server/handlers/RegisteredConnectionHandler.js +1 -2
  110. package/src/symbols.js +12 -8
  111. package/src/utils/childProcess/exec.js +1 -1
  112. package/src/utils/childProcess/spawn.js +1 -1
  113. package/src/utils/errorUtils.js +4 -3
  114. package/src/utils/invocationTraceDescriptions.js +43 -0
  115. package/src/utils/streamUtils.js +10 -11
  116. package/src/utils/trace.js +2 -18
  117. package/src/utils/traceMethods.js +15 -0
  118. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-javadoc.jar.md5 +0 -1
  119. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-javadoc.jar.sha1 +0 -1
  120. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-javadoc.jar.sha256 +0 -1
  121. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-javadoc.jar.sha512 +0 -1
  122. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-sources.jar.md5 +0 -1
  123. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-sources.jar.sha1 +0 -1
  124. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-sources.jar.sha256 +0 -1
  125. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0-sources.jar.sha512 +0 -1
  126. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.aar +0 -0
  127. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.aar.md5 +0 -1
  128. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.aar.sha1 +0 -1
  129. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.aar.sha256 +0 -1
  130. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.aar.sha512 +0 -1
  131. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.pom.md5 +0 -1
  132. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.pom.sha1 +0 -1
  133. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.pom.sha256 +0 -1
  134. package/Detox-android/com/wix/detox/20.0.4-breaking.new-global-lifecycle.0/detox-20.0.4-breaking.new-global-lifecycle.0.pom.sha512 +0 -1
  135. package/src/logger/DetoxTraceEventBuilder.js +0 -21
  136. package/src/logger/DetoxTracer.js +0 -133
  137. package/src/utils/ChromeTracingExporter.js +0 -54
@@ -1,4 +1,5 @@
1
1
  // @ts-nocheck
2
+ const assert = require('assert');
2
3
  const path = require('path');
3
4
 
4
5
  const fs = require('fs-extra');
@@ -6,6 +7,8 @@ const _ = require('lodash');
6
7
  const tempfile = require('tempfile');
7
8
 
8
9
  const { assertEnum, assertNormalized } = require('../utils/assertArgument');
10
+ const { actionDescription, expectDescription } = require('../utils/invocationTraceDescriptions');
11
+ const { trace } = require('../utils/trace');
9
12
 
10
13
  const assertDirection = assertEnum(['left', 'right', 'up', 'down']);
11
14
  const assertSpeed = assertEnum(['fast', 'slow']);
@@ -23,7 +26,8 @@ class Expect {
23
26
  + (percent + (' (' + (typeof percent + ')'))));
24
27
  }
25
28
 
26
- return this.expect('toBeVisible', percent);
29
+ const traceDescription = expectDescription.toBeVisible(percent);
30
+ return this.expect('toBeVisible', traceDescription, percent);
27
31
  }
28
32
 
29
33
  toBeNotVisible() {
@@ -31,7 +35,8 @@ class Expect {
31
35
  }
32
36
 
33
37
  toBeFocused() {
34
- return this.expect('toBeFocused');
38
+ const traceDescription = expectDescription.toBeFocused();
39
+ return this.expect('toBeFocused', traceDescription);
35
40
  }
36
41
 
37
42
  toBeNotFocused() {
@@ -39,7 +44,8 @@ class Expect {
39
44
  }
40
45
 
41
46
  toExist() {
42
- return this.expect('toExist');
47
+ const traceDescription = expectDescription.toExist();
48
+ return this.expect('toExist', traceDescription);
43
49
  }
44
50
 
45
51
  toNotExist() {
@@ -47,7 +53,8 @@ class Expect {
47
53
  }
48
54
 
49
55
  toHaveText(text) {
50
- return this.expect('toHaveText', text);
56
+ const traceDescription = expectDescription.toHaveText(text);
57
+ return this.expect('toHaveText', traceDescription, text);
51
58
  }
52
59
 
53
60
  toNotHaveText(text) {
@@ -55,7 +62,8 @@ class Expect {
55
62
  }
56
63
 
57
64
  toHaveLabel(label) {
58
- return this.expect('toHaveLabel', label);
65
+ const traceDescription = expectDescription.toHaveLabel(label);
66
+ return this.expect('toHaveLabel', traceDescription, label);
59
67
  }
60
68
 
61
69
  toNotHaveLabel(label) {
@@ -63,7 +71,8 @@ class Expect {
63
71
  }
64
72
 
65
73
  toHaveId(id) {
66
- return this.expect('toHaveId', id);
74
+ const traceDescription = expectDescription.toHaveId(id);
75
+ return this.expect('toHaveId', traceDescription, id);
67
76
  }
68
77
 
69
78
  toNotHaveId(id) {
@@ -71,7 +80,8 @@ class Expect {
71
80
  }
72
81
 
73
82
  toHaveValue(value) {
74
- return this.expect('toHaveValue', value);
83
+ const traceDescription = expectDescription.toHaveValue(value);
84
+ return this.expect('toHaveValue', traceDescription, value);
75
85
  }
76
86
 
77
87
  toNotHaveValue(value) {
@@ -79,7 +89,8 @@ class Expect {
79
89
  }
80
90
 
81
91
  toHaveSliderPosition(position, tolerance = 0) {
82
- return this.expect('toHaveSliderPosition', position, tolerance);
92
+ const traceDescription = expectDescription.toHaveSliderPosition(position, tolerance);
93
+ return this.expect('toHaveSliderPosition', traceDescription, position, tolerance);
83
94
  }
84
95
 
85
96
  toHaveToggleValue(value) {
@@ -103,16 +114,18 @@ class Expect {
103
114
  };
104
115
  }
105
116
 
106
- expect(expectation, ...params) {
117
+ expect(expectation, traceDescription, ...params) {
118
+ assert(traceDescription, `must provide trace description for expectation: \n ${JSON.stringify(expectation)}`);
119
+
107
120
  const invocation = this.createInvocation(expectation, ...params);
108
- return this._invocationManager.execute(invocation);
121
+ traceDescription = expectDescription.full(traceDescription, this.modifiers.includes('not'));
122
+ return _executeInvocation(this._invocationManager, invocation, traceDescription);
109
123
  }
110
124
  }
111
125
 
112
126
  class InternalExpect extends Expect {
113
- expect(expectation, ...params) {
114
- const invocation = this.createInvocation(expectation, ...params);
115
- return invocation;
127
+ expect(expectation, _traceDescription, ...params) {
128
+ return this.createInvocation(expectation, ...params);
116
129
  }
117
130
  }
118
131
 
@@ -131,7 +144,8 @@ class Element {
131
144
  }
132
145
 
133
146
  getAttributes() {
134
- return this.withAction('getAttributes');
147
+ const traceDescription = actionDescription.getAttributes();
148
+ return this.withAction('getAttributes', traceDescription);
135
149
  }
136
150
 
137
151
  tap(point) {
@@ -140,12 +154,16 @@ class Element {
140
154
  if (typeof point.x !== 'number') throw new Error('point.x should be a number, but got ' + (point.x + (' (' + (typeof point.x + ')'))));
141
155
  if (typeof point.y !== 'number') throw new Error('point.y should be a number, but got ' + (point.y + (' (' + (typeof point.y + ')'))));
142
156
  }
143
- return this.withAction('tap', point);
157
+
158
+ const traceDescription = actionDescription.tapAtPoint(point);
159
+ return this.withAction('tap', traceDescription, point);
144
160
  }
145
161
 
146
162
  longPress(duration = 1000) {
147
163
  if (typeof duration !== 'number') throw new Error('duration should be a number, but got ' + (duration + (' (' + (typeof duration + ')'))));
148
- return this.withAction('longPress', duration);
164
+
165
+ const traceDescription = actionDescription.longPress(duration);
166
+ return this.withAction('longPress', traceDescription, duration);
149
167
  }
150
168
 
151
169
  longPressAndDrag(duration, normalizedPositionX, normalizedPositionY, targetElement,
@@ -162,13 +180,18 @@ class Element {
162
180
  assertNormalized({ normalizedTargetPositionX });
163
181
  assertNormalized({ normalizedTargetPositionY });
164
182
 
165
- return this.withActionAndTargetElement('longPress', targetElement, duration, normalizedPositionX, normalizedPositionY,
183
+ const traceDescription = actionDescription.longPressAndDrag(duration, normalizedPositionX, normalizedPositionY, targetElement,
184
+ normalizedTargetPositionX, normalizedTargetPositionY, speed, holdDuration);
185
+ return this.withActionAndTargetElement('longPress', targetElement, traceDescription, duration, normalizedPositionX, normalizedPositionY,
166
186
  normalizedTargetPositionX, normalizedTargetPositionY, speed, holdDuration);
167
187
  }
168
188
 
169
189
  multiTap(times) {
170
190
  if (typeof times !== 'number') throw new Error('times should be a number, but got ' + (times + (' (' + (typeof times + ')'))));
171
- return this.withAction('multiTap', times);
191
+ if (times < 1) throw new Error('times should be greater than 0, but got ' + times);
192
+
193
+ const traceDescription = actionDescription.multiTap(times);
194
+ return this.withAction('multiTap', traceDescription, times);
172
195
  }
173
196
 
174
197
  tapAtPoint(point) {
@@ -176,25 +199,32 @@ class Element {
176
199
  }
177
200
 
178
201
  tapBackspaceKey() {
179
- return this.withAction('tapBackspaceKey');
202
+ const traceDescription = actionDescription.tapBackspaceKey();
203
+ return this.withAction('tapBackspaceKey', traceDescription);
180
204
  }
181
205
 
182
206
  tapReturnKey() {
183
- return this.withAction('tapReturnKey');
207
+ const traceDescription = actionDescription.tapReturnKey();
208
+ return this.withAction('tapReturnKey', traceDescription);
184
209
  }
185
210
 
186
211
  typeText(text) {
187
212
  if (typeof text !== 'string') throw new Error('text should be a string, but got ' + (text + (' (' + (typeof text + ')'))));
188
- return this.withAction('typeText', text);
213
+
214
+ const traceDescription = actionDescription.typeText(text);
215
+ return this.withAction('typeText', traceDescription, text);
189
216
  }
190
217
 
191
218
  replaceText(text) {
192
219
  if (typeof text !== 'string') throw new Error('text should be a string, but got ' + (text + (' (' + (typeof text + ')'))));
193
- return this.withAction('replaceText', text);
220
+
221
+ const traceDescription = actionDescription.replaceText(text);
222
+ return this.withAction('replaceText', traceDescription, text);
194
223
  }
195
224
 
196
225
  clearText() {
197
- return this.withAction('clearText');
226
+ const traceDescription = actionDescription.clearText();
227
+ return this.withAction('clearText', traceDescription);
198
228
  }
199
229
 
200
230
  scroll(pixels, direction = 'down', startPositionX = NaN, startPositionY = NaN) {
@@ -202,12 +232,15 @@ class Element {
202
232
  if (typeof pixels !== 'number') throw new Error('amount of pixels should be a number, but got ' + (pixels + (' (' + (typeof pixels + ')'))));
203
233
  if (typeof startPositionX !== 'number') throw new Error('startPositionX should be a number, but got ' + (startPositionX + (' (' + (typeof startPositionX + ')'))));
204
234
  if (typeof startPositionY !== 'number') throw new Error('startPositionY should be a number, but got ' + (startPositionY + (' (' + (typeof startPositionY + ')'))));
205
- return this.withAction('scroll', pixels, direction, startPositionX, startPositionY);
235
+
236
+ const traceDescription = actionDescription.scroll(pixels, direction, startPositionX, startPositionY);
237
+ return this.withAction('scroll', traceDescription, pixels, direction, startPositionX, startPositionY);
206
238
  }
207
239
 
208
240
  scrollTo(edge) {
209
241
  if (!['left', 'right', 'top', 'bottom'].some(option => option === edge)) throw new Error('edge should be one of [left, right, top, bottom], but got ' + edge);
210
- return this.withAction('scrollTo', edge);
242
+ const traceDescription = actionDescription.scrollTo(edge);
243
+ return this.withAction('scrollTo', traceDescription, edge);
211
244
  }
212
245
 
213
246
  swipe(direction, speed = 'fast', normalizedSwipeOffset = NaN, normalizedStartingPointX = NaN, normalizedStartingPointY = NaN) {
@@ -218,42 +251,62 @@ class Element {
218
251
  assertNormalized({ normalizedStartingPointY });
219
252
 
220
253
  normalizedSwipeOffset = Number.isNaN(normalizedSwipeOffset) ? 0.75 : normalizedSwipeOffset;
221
- return this.withAction('swipe', direction, speed, normalizedSwipeOffset, normalizedStartingPointX, normalizedStartingPointY);
254
+ const traceDescription = actionDescription.swipe(direction, speed, normalizedSwipeOffset, normalizedStartingPointX, normalizedStartingPointY);
255
+ return this.withAction(
256
+ 'swipe',
257
+ traceDescription,
258
+ direction,
259
+ speed,
260
+ normalizedSwipeOffset,
261
+ normalizedStartingPointX,
262
+ normalizedStartingPointY
263
+ );
222
264
  }
223
265
 
224
266
  setColumnToValue(column, value) {
225
267
  if (typeof column !== 'number') throw new Error('column should be a number, but got ' + (column + (' (' + (typeof column + ')'))));
226
268
  if (typeof value !== 'string') throw new Error('value should be a string, but got ' + (value + (' (' + (typeof value + ')'))));
227
- return this.withAction('setColumnToValue', column, value);
269
+
270
+ const traceDescription = actionDescription.setColumnToValue(column, value);
271
+ return this.withAction('setColumnToValue', traceDescription, column, value);
228
272
  }
229
273
 
230
274
  setDatePickerDate(dateString, dateFormat) {
231
275
  if (typeof dateString !== 'string') throw new Error('dateString should be a string, but got ' + (dateString + (' (' + (typeof dateString + ')'))));
232
276
  if (typeof dateFormat !== 'string') throw new Error('dateFormat should be a string, but got ' + (dateFormat + (' (' + (typeof dateFormat + ')'))));
233
- return this.withAction('setDatePickerDate', dateString, dateFormat);
277
+
278
+ const traceDescription = actionDescription.setDatePickerDate(dateString, dateFormat);
279
+ return this.withAction('setDatePickerDate', traceDescription, dateString, dateFormat);
234
280
  }
235
281
 
236
282
  pinch(scale, speed = 'fast', angle = 0) {
237
283
  if (typeof scale !== 'number' || !Number.isFinite(scale) || scale < 0) throw new Error(`pinch scale must be a finite number larger than zero`);
238
284
  if (!['slow', 'fast'].includes(speed)) throw new Error(`pinch speed is either 'slow' or 'fast'`);
239
285
  if (typeof angle !== 'number' || !Number.isFinite(angle)) throw new Error(`pinch angle must be a finite number (radian)`);
240
- return this.withAction('pinch', scale, speed, angle);
286
+
287
+ const traceDescription = actionDescription.pinch(scale, speed, angle);
288
+ return this.withAction('pinch', traceDescription, scale, speed, angle);
241
289
  }
242
290
 
243
291
  pinchWithAngle(direction, speed = 'slow', angle = 0) {
244
292
  if (!['inward', 'outward'].includes(direction)) throw new Error(`pinchWithAngle direction is either 'inward' or 'outward'`);
245
293
  if (!['slow', 'fast'].includes(speed)) throw new Error(`pinchWithAngle speed is either 'slow' or 'fast'`);
246
294
  if (typeof angle !== 'number') throw new Error(`pinchWithAngle angle must be a number (radiant), got ${typeof angle}`);
247
- return this.withAction('pinchWithAngle', direction, speed, angle);
295
+
296
+ const traceDescription = actionDescription.pinchWithAngle(direction, speed, angle);
297
+ return this.withAction('pinchWithAngle', traceDescription, direction, speed, angle);
248
298
  }
249
299
 
250
300
  adjustSliderToPosition(position) {
251
301
  if (!(typeof position === 'number' && position >= 0 && position <= 1)) throw new Error('position should be a number [0.0, 1.0], but got ' + (position + (' (' + (typeof position + ')'))));
252
- return this.withAction('adjustSliderToPosition', position);
302
+
303
+ const traceDescription = actionDescription.adjustSliderToPosition(position);
304
+ return this.withAction('adjustSliderToPosition', traceDescription, position);
253
305
  }
254
306
 
255
307
  async takeScreenshot(fileName) {
256
- const { screenshotPath } = await this.withAction('takeScreenshot', fileName);
308
+ const traceDescription = actionDescription.takeScreenshot(fileName);
309
+ const { screenshotPath } = await this.withAction('takeScreenshot', traceDescription, fileName);
257
310
 
258
311
  const filePath = tempfile('.detox.element-screenshot.png');
259
312
  await fs.move(screenshotPath, filePath);
@@ -287,22 +340,20 @@ class Element {
287
340
  return invocation;
288
341
  }
289
342
 
290
- withAction(action, ...params) {
343
+ withAction(action, traceDescription, ...params) {
291
344
  const invocation = this.createInvocation(action, null, ...params);
292
- return this._invocationManager.execute(invocation);
345
+ return _executeInvocation(this._invocationManager, invocation, traceDescription);
293
346
  }
294
347
 
295
- withActionAndTargetElement(action, targetElement, ...params) {
348
+ withActionAndTargetElement(action, targetElement, traceDescription, ...params) {
296
349
  const invocation = this.createInvocation(action, targetElement, ...params);
297
- return this._invocationManager.execute(invocation);
350
+ return _executeInvocation(this._invocationManager, invocation, traceDescription);
298
351
  }
299
352
  }
300
353
 
301
354
  class InternalElement extends Element {
302
-
303
- withAction(action, ...params) {
304
- const invocation = this.createInvocation(action, null, ...params);
305
- return invocation;
355
+ withAction(action, _traceDescription, ...params) {
356
+ return this.createInvocation(action, null, ...params);
306
357
  }
307
358
  }
308
359
 
@@ -341,7 +392,6 @@ class By {
341
392
  }
342
393
 
343
394
  class Matcher {
344
-
345
395
  accessibilityLabel(label) {
346
396
  return this.label(label);
347
397
  }
@@ -395,14 +445,12 @@ class Matcher {
395
445
  if (!(matcher instanceof Matcher)) {
396
446
  throwMatcherError(matcher);
397
447
  }
448
+
398
449
  this.and({ predicate: { type: 'descendant', predicate: matcher.predicate } });
399
450
  return this;
400
451
  }
401
452
 
402
453
  and(matcher) {
403
- // if (!(matcher instanceof Matcher)) {
404
- // throwMatcherError(matcher);
405
- // }
406
454
  const tempPredicate = this.predicate;
407
455
  delete this.predicate;
408
456
  this.predicate = { type: 'and', predicates: [] };
@@ -493,7 +541,9 @@ class WaitFor {
493
541
  if (typeof timeout !== 'number') throw new Error('text should be a number, but got ' + (timeout + (' (' + (typeof timeout + ')'))));
494
542
  if (timeout < 0) throw new Error('timeout must be larger than 0');
495
543
  this.timeout = timeout;
496
- return this.waitForWithTimeout();
544
+
545
+ const traceDescription = expectDescription.withTimeout(timeout);
546
+ return this.waitForWithTimeout(traceDescription);
497
547
  }
498
548
 
499
549
  whileElement(matcher) {
@@ -504,106 +554,137 @@ class WaitFor {
504
554
 
505
555
  tap(point) {
506
556
  this.action = this.actionableElement.tap(point);
507
- return this.waitForWithAction();
557
+ const traceDescription = actionDescription.tapAtPoint(point);
558
+ return this.waitForWithAction(traceDescription);
508
559
  }
509
560
 
510
561
  longPress(duration) {
511
562
  this.action = this.actionableElement.longPress(duration);
512
- return this.waitForWithAction();
563
+ const traceDescription = actionDescription.longPress(duration);
564
+ return this.waitForWithAction(traceDescription);
513
565
  }
514
566
 
515
567
  multiTap(times) {
516
568
  this.action = this.actionableElement.multiTap(times);
517
- return this.waitForWithAction();
569
+ const traceDescription = actionDescription.multiTap(times);
570
+ return this.waitForWithAction(traceDescription);
518
571
  }
519
572
 
520
573
  tapAtPoint(point) {
521
574
  this.action = this.actionableElement.tap(point);
522
- return this.waitForWithAction();
575
+ const traceDescription = actionDescription.tapAtPoint(point);
576
+ return this.waitForWithAction(traceDescription);
523
577
  }
524
578
 
525
579
  tapBackspaceKey() {
526
580
  this.action = this.actionableElement.tapBackspaceKey();
527
- return this.waitForWithAction();
581
+ const traceDescription = actionDescription.tapBackspaceKey();
582
+ return this.waitForWithAction(traceDescription);
528
583
  }
529
584
 
530
585
  tapReturnKey() {
531
586
  this.action = this.actionableElement.tapReturnKey();
532
- return this.waitForWithAction();
587
+ const traceDescription = actionDescription.tapReturnKey();
588
+ return this.waitForWithAction(traceDescription);
533
589
  }
534
590
 
535
591
  typeText(text) {
536
592
  this.action = this.actionableElement.typeText(text);
537
- return this.waitForWithAction();
593
+ const traceDescription = actionDescription.typeText(text);
594
+ return this.waitForWithAction(traceDescription);
538
595
  }
539
596
 
540
597
  replaceText(text) {
541
598
  this.action = this.actionableElement.replaceText(text);
542
- return this.waitForWithAction();
599
+ const traceDescription = actionDescription.replaceText(text);
600
+ return this.waitForWithAction(traceDescription);
543
601
  }
544
602
 
545
603
  clearText() {
546
604
  this.action = this.actionableElement.clearText();
547
- return this.waitForWithAction();
605
+ const traceDescription = actionDescription.clearText();
606
+ return this.waitForWithAction(traceDescription);
548
607
  }
549
608
 
550
609
  scroll(pixels, direction, startPositionX, startPositionY) {
551
610
  this.action = this.actionableElement.scroll(pixels, direction, startPositionX, startPositionY);
552
- return this.waitForWithAction();
611
+
612
+ const traceDescription = actionDescription.scroll(pixels, direction, startPositionX, startPositionY);
613
+ return this.waitForWithAction(traceDescription);
553
614
  }
554
615
 
555
616
  scrollTo(edge) {
556
617
  this.action = this.actionableElement.scrollTo(edge);
557
- return this.waitForWithAction();
618
+ const traceDescription = actionDescription.scrollTo(edge);
619
+ return this.waitForWithAction(traceDescription);
558
620
  }
559
621
 
560
622
  swipe(direction, speed, percentage) {
561
623
  this.action = this.actionableElement.swipe(direction, speed, percentage);
562
- return this.waitForWithAction();
624
+ const traceDescription = actionDescription.swipe(direction, speed, percentage);
625
+ return this.waitForWithAction(traceDescription);
563
626
  }
564
627
 
565
628
  setColumnToValue(column, value) {
566
629
  this.action = this.actionableElement.setColumnToValue(column, value);
567
- return this.waitForWithAction();
630
+ const traceDescription = actionDescription.setColumnToValue(column, value);
631
+ return this.waitForWithAction(traceDescription);
568
632
  }
569
633
 
570
634
  setDatePickerDate(dateString, dateFormat) {
571
635
  this.action = this.actionableElement.setDatePickerDate(dateString, dateFormat);
572
- return this.waitForWithAction();
636
+ const traceDescription = actionDescription.setDatePickerDate(dateString, dateFormat);
637
+ return this.waitForWithAction(traceDescription);
573
638
  }
574
639
 
575
640
  pinch(scale, speed, angle) {
576
641
  this.action = this.actionableElement.pinch(scale, speed, angle);
577
- return this.waitForWithAction();
642
+ const traceDescription = actionDescription.pinch(scale, speed, angle);
643
+ return this.waitForWithAction(traceDescription);
578
644
  }
579
645
 
580
646
  pinchWithAngle(direction, speed, angle) {
581
647
  this.action = this.actionableElement.pinchWithAngle(direction, speed, angle);
582
- return this.waitForWithAction();
648
+ const traceDescription = actionDescription.pinchWithAngle(direction, speed, angle);
649
+ return this.waitForWithAction(traceDescription);
583
650
  }
584
651
 
585
- waitForWithAction() {
652
+ waitForWithAction(actionTraceDescription) {
586
653
  const expectation = this.expectation;
587
654
  const action = this.action;
588
655
 
589
- return this._invocationManager.execute({
656
+ const invocation = this.createWaitForWithActionInvocation(expectation, action);
657
+
658
+ const traceDescription = expectDescription.waitFor(actionTraceDescription);
659
+ return _executeInvocation(this._invocationManager, invocation, traceDescription);
660
+ }
661
+
662
+ createWaitForWithActionInvocation(expectation, action) {
663
+ return {
590
664
  ...action,
591
665
  while: {
592
666
  ...expectation
593
667
  }
594
- });
668
+ };
595
669
  }
596
670
 
597
- waitForWithTimeout() {
671
+ waitForWithTimeout(expectTraceDescription) {
598
672
  const expectation = this.expectation;
599
673
  const action = this.action;
600
674
  const timeout = this.timeout;
601
675
 
602
- return this._invocationManager.execute({
676
+ const invocation = this.createWaitForWithTimeoutInvocation(expectation, action, timeout);
677
+
678
+ const traceDescription = expectDescription.waitForWithTimeout(expectTraceDescription, timeout);
679
+ return _executeInvocation(this._invocationManager, invocation, traceDescription);
680
+ }
681
+
682
+ createWaitForWithTimeoutInvocation(expectation, action, timeout) {
683
+ return {
603
684
  ...action,
604
685
  ...expectation,
605
686
  timeout
606
- });
687
+ };
607
688
  }
608
689
  }
609
690
 
@@ -665,4 +746,8 @@ function throwElementError(param) {
665
746
  throw new Error(`${param} is not a Detox element. More about Detox elements here: https://wix.github.io/Detox/docs/api/matchers`);
666
747
  }
667
748
 
749
+ function _executeInvocation(invocationManager, invocation, traceDescription) {
750
+ return trace.invocationCall(traceDescription, invocation, invocationManager.execute(invocation));
751
+ }
752
+
668
753
  module.exports = IosExpect;
@@ -6,8 +6,8 @@ class IPCClient {
6
6
  constructor({ id, logger, state }) {
7
7
  this._id = id;
8
8
  /** @type {import('../logger/DetoxLogger')} logger */
9
- this._logger = logger.child({ __filename, cat: 'ipc' });
10
- /** @type {import('./state').SecondarySessionState} */
9
+ this._logger = logger.child({ cat: 'ipc' });
10
+ /** @type {import('./SessionState')} */
11
11
  this._state = state;
12
12
 
13
13
  this._client = null;
@@ -47,7 +47,6 @@ class IPCClient {
47
47
  }
48
48
 
49
49
  async registerWorker(workerId) {
50
- this._state.workerId = workerId;
51
50
  await this._emit('registerWorker', { workerId });
52
51
  }
53
52
 
@@ -75,11 +74,7 @@ class IPCClient {
75
74
  }
76
75
 
77
76
  async _registerContext() {
78
- const sessionState = await this._emit('registerContext', {
79
- id: this._id,
80
- logFile: this._logger.file,
81
- });
82
-
77
+ const sessionState = await this._emit('registerContext', { id: this._id });
83
78
  this._state.patch(sessionState);
84
79
  }
85
80
 
@@ -3,13 +3,14 @@ const { IPC } = require('node-ipc');
3
3
  class IPCServer {
4
4
  /**
5
5
  * @param {object} options
6
- * @param {import('./state').PrimarySessionState} options.sessionState
6
+ * @param {import('./SessionState')} options.sessionState
7
7
  * @param {Detox.Logger} options.logger
8
8
  */
9
9
  constructor({ sessionState, logger }) {
10
10
  this._sessionState = sessionState;
11
- this._logger = logger.child({ __filename, cat: 'ipc' });
11
+ this._logger = logger.child({ cat: 'ipc,ipc-server' });
12
12
  this._ipc = null;
13
+ this._workers = new Set();
13
14
  }
14
15
 
15
16
  get id() {
@@ -48,13 +49,9 @@ class IPCServer {
48
49
  });
49
50
  }
50
51
 
51
- onRegisterContext({ id, logFile }, socket) {
52
+ onRegisterContext({ id }, socket) {
52
53
  this._sessionState.contexts.push(id);
53
54
 
54
- if (logFile && !this._sessionState.logFiles.includes(logFile)) {
55
- this._sessionState.logFiles.push(logFile);
56
- }
57
-
58
55
  this._ipc.server.emit(socket, 'registerContextDone', {
59
56
  failedTestFiles: this._sessionState.failedTestFiles,
60
57
  testFilesToRetry: this._sessionState.testFilesToRetry,
@@ -62,13 +59,16 @@ class IPCServer {
62
59
  });
63
60
  }
64
61
 
65
- onRegisterWorker({ workerId }, socket) {
62
+ onRegisterWorker({ workerId }, socket = null) {
63
+ const workersCount = this._workers.add(workerId).size;
64
+ const shouldBroadcast = workersCount > this._sessionState.workersCount;
65
+ this._sessionState.workersCount = workersCount;
66
+
66
67
  if (socket) {
67
- this._ipc.server.emit(socket, 'registerWorkerDone', {});
68
+ this._ipc.server.emit(socket, 'registerWorkerDone', { workersCount });
68
69
  }
69
70
 
70
- if (workerId > this._sessionState.workersCount) {
71
- const workersCount = this._sessionState.workersCount = workerId;
71
+ if (shouldBroadcast) {
72
72
  this._ipc.server.broadcast('sessionStateUpdate', { workersCount });
73
73
  }
74
74
  }