detox 20.12.0-smoke.0 → 20.12.0-smoke.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. package/Detox-android/com/wix/detox/{20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar → 20.12.0-smoke.1/detox-20.12.0-smoke.1-javadoc.jar} +0 -0
  2. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1-javadoc.jar.md5 +1 -0
  3. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1-javadoc.jar.sha1 +1 -0
  4. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1-javadoc.jar.sha256 +1 -0
  5. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1-javadoc.jar.sha512 +1 -0
  6. package/Detox-android/com/wix/detox/{20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar → 20.12.0-smoke.1/detox-20.12.0-smoke.1-sources.jar} +0 -0
  7. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1-sources.jar.md5 +1 -0
  8. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1-sources.jar.sha1 +1 -0
  9. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1-sources.jar.sha256 +1 -0
  10. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1-sources.jar.sha512 +1 -0
  11. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1.aar +0 -0
  12. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1.aar.md5 +1 -0
  13. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1.aar.sha1 +1 -0
  14. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1.aar.sha256 +1 -0
  15. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1.aar.sha512 +1 -0
  16. package/Detox-android/com/wix/detox/{20.12.0-smoke.0/detox-20.12.0-smoke.0.pom → 20.12.0-smoke.1/detox-20.12.0-smoke.1.pom} +1 -1
  17. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1.pom.md5 +1 -0
  18. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1.pom.sha1 +1 -0
  19. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1.pom.sha256 +1 -0
  20. package/Detox-android/com/wix/detox/20.12.0-smoke.1/detox-20.12.0-smoke.1.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/build.gradle +1 -1
  29. package/android/detox/src/full/java/com/wix/detox/espresso/DetoxAssertion.java +44 -25
  30. package/android/detox/src/full/java/com/wix/detox/espresso/EspressoDetox.java +6 -7
  31. package/android/detox/src/full/java/com/wix/detox/espresso/action/GetAttributesAction.kt +4 -4
  32. package/android/detox/src/full/java/com/wix/detox/espresso/performer/MultipleViewsActionPerformer.kt +43 -0
  33. package/android/detox/src/full/java/com/wix/detox/espresso/performer/SingleViewActionPerformer.kt +19 -0
  34. package/android/detox/src/full/java/com/wix/detox/espresso/performer/ViewActionPerformer.kt +24 -0
  35. package/android/detox/src/full/java/com/wix/invoke/types/Invocation.java +5 -4
  36. package/android/detox/src/main/java/com/wix/detox/espresso/MultipleViewsAction.kt +4 -0
  37. package/android/detox/src/main/java/com/wix/detox/espresso/UiControllerSpy.kt +0 -1
  38. package/android/detox/src/main/java/com/wix/detox/espresso/ViewActionWithResult.kt +2 -1
  39. package/android/detox/src/testFull/java/com/wix/detox/espresso/action/GetAttributesActionTest.kt +6 -5
  40. package/android/detox/src/testFull/java/com/wix/detox/espresso/performer/ViewActionPerformerSpec.kt +37 -0
  41. package/index.d.ts +47 -3
  42. package/package.json +2 -2
  43. package/runners/jest/testEnvironment/index.js +1 -0
  44. package/src/DetoxWorker.js +0 -2
  45. package/src/android/core/NativeElement.js +26 -29
  46. package/src/android/espressoapi/DetoxAssertion.js +16 -14
  47. package/src/android/espressoapi/EspressoDetox.js +9 -2
  48. package/src/android/interactions/native.js +2 -3
  49. package/src/configuration/composeLoggerConfig.js +1 -0
  50. package/src/devices/allocation/DeviceAllocator.js +24 -13
  51. package/src/devices/allocation/DeviceRegistry.js +3 -0
  52. package/src/devices/allocation/drivers/AllocationDriverBase.d.ts +15 -0
  53. package/src/devices/allocation/drivers/android/attached/AttachedAndroidAllocDriver.js +16 -12
  54. package/src/devices/allocation/drivers/android/emulator/EmulatorAllocDriver.js +39 -62
  55. package/src/devices/allocation/drivers/android/emulator/EmulatorLauncher.js +0 -3
  56. package/src/devices/allocation/drivers/android/genycloud/GenyAllocDriver.js +28 -16
  57. package/src/devices/allocation/drivers/android/genycloud/GenyInstanceLauncher.js +3 -5
  58. package/src/devices/allocation/drivers/android/genycloud/GenyRegistry.js +54 -26
  59. package/src/devices/allocation/drivers/ios/SimulatorAllocDriver.js +26 -13
  60. package/src/devices/common/drivers/DeviceCookie.d.ts +12 -0
  61. package/src/devices/common/drivers/android/cookies.d.ts +11 -0
  62. package/src/devices/common/drivers/ios/cookies.d.ts +9 -0
  63. package/src/devices/common/drivers/ios/tools/AppleSimUtils.js +3 -1
  64. package/src/devices/cookies/index.js +0 -6
  65. package/src/devices/runtime/drivers/android/genycloud/GenyCloudDriver.js +7 -6
  66. package/src/devices/runtime/factories/android.js +2 -10
  67. package/src/devices/validation/EnvironmentValidatorBase.js +1 -0
  68. package/src/ipc/IPCServer.js +3 -1
  69. package/src/logger/DetoxLogger.js +2 -2
  70. package/src/realms/DetoxPrimaryContext.js +1 -1
  71. package/src/utils/errorUtils.js +1 -1
  72. package/tsconfig.json +5 -3
  73. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.md5 +0 -1
  74. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha1 +0 -1
  75. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha256 +0 -1
  76. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-javadoc.jar.sha512 +0 -1
  77. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.md5 +0 -1
  78. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha1 +0 -1
  79. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha256 +0 -1
  80. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0-sources.jar.sha512 +0 -1
  81. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar +0 -0
  82. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.md5 +0 -1
  83. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha1 +0 -1
  84. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha256 +0 -1
  85. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.aar.sha512 +0 -1
  86. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.md5 +0 -1
  87. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha1 +0 -1
  88. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha256 +0 -1
  89. package/Detox-android/com/wix/detox/20.12.0-smoke.0/detox-20.12.0-smoke.0.pom.sha512 +0 -1
  90. package/src/devices/allocation/drivers/AllocationDriverBase.js +0 -36
  91. package/src/devices/cookies/AndroidDeviceCookie.js +0 -17
  92. package/src/devices/cookies/AndroidEmulatorCookie.js +0 -6
  93. package/src/devices/cookies/AttachedAndroidDeviceCookie.js +0 -12
  94. package/src/devices/cookies/DeviceCookie.js +0 -4
  95. package/src/devices/cookies/GenycloudEmulatorCookie.js +0 -18
  96. package/src/devices/cookies/IosCookie.js +0 -6
  97. package/src/devices/cookies/IosSimulatorCookie.js +0 -14
@@ -59,7 +59,6 @@ class DetoxWorker {
59
59
  /** @type {Detox.WebFacade} */
60
60
  this.web = null;
61
61
 
62
- this._deviceAllocator = null;
63
62
  this._deviceCookie = null;
64
63
 
65
64
  this.trace = this._context.trace;
@@ -207,7 +206,6 @@ class DetoxWorker {
207
206
  await this._context[symbols.deallocateDevice](this._deviceCookie);
208
207
  }
209
208
 
210
- this._deviceAllocator = null;
211
209
  this._deviceCookie = null;
212
210
  this.device = null;
213
211
  }
@@ -15,39 +15,37 @@ class NativeElement {
15
15
  constructor(invocationManager, emitter, matcher) {
16
16
  this._invocationManager = invocationManager;
17
17
  this._emitter = emitter;
18
- this._originalMatcher = matcher;
19
- this._selectElementWithMatcher(this._originalMatcher);
18
+ this._matcher = matcher;
20
19
  }
21
20
 
22
- _selectElementWithMatcher(matcher) {
23
- this._call = invoke.call(invoke.Espresso, 'onView', matcher._call);
21
+ get _call() {
22
+ return invoke.call(invoke.Espresso, 'onView', this._matcher._call);
24
23
  }
25
24
 
26
25
  atIndex(index) {
27
26
  if (typeof index !== 'number') throw new DetoxRuntimeError({ message: `Element atIndex argument must be a number, got ${typeof index}` });
28
- const matcher = this._originalMatcher;
29
- this._originalMatcher._call = invoke.callDirectly(DetoxMatcherApi.matcherForAtIndex(index, matcher._call.value));
27
+ const matcher = this._matcher;
28
+ this._matcher._call = invoke.callDirectly(DetoxMatcherApi.matcherForAtIndex(index, matcher._call.value));
30
29
 
31
- this._selectElementWithMatcher(this._originalMatcher);
32
30
  return this;
33
31
  }
34
32
 
35
33
  async tap(value) {
36
34
  const action = new actions.TapAction(value);
37
35
  const traceDescription = actionDescription.tapAtPoint(value);
38
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
36
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
39
37
  }
40
38
 
41
39
  async tapAtPoint(value) {
42
40
  const action = new actions.TapAtPointAction(value);
43
41
  const traceDescription = actionDescription.tapAtPoint(value);
44
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
42
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
45
43
  }
46
44
 
47
45
  async longPress() {
48
46
  const action = new actions.LongPressAction();
49
47
  const traceDescription = actionDescription.longPress();
50
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
48
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
51
49
  }
52
50
 
53
51
  async multiTap(times) {
@@ -56,61 +54,61 @@ class NativeElement {
56
54
 
57
55
  const action = new actions.MultiClickAction(times);
58
56
  const traceDescription = actionDescription.multiTap(times);
59
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
57
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
60
58
  }
61
59
 
62
60
  async tapBackspaceKey() {
63
61
  const action = new actions.PressKeyAction(67);
64
62
  const traceDescription = actionDescription.tapBackspaceKey();
65
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
63
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
66
64
  }
67
65
 
68
66
  async tapReturnKey() {
69
67
  const action = new actions.TypeTextAction('\n');
70
68
  const traceDescription = actionDescription.tapReturnKey();
71
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
69
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
72
70
  }
73
71
 
74
72
  async typeText(value) {
75
73
  const action = new actions.TypeTextAction(value);
76
74
  const traceDescription = actionDescription.typeText(value);
77
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
75
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
78
76
  }
79
77
 
80
78
  async replaceText(value) {
81
79
  const action = new actions.ReplaceTextAction(value);
82
80
  const traceDescription = actionDescription.replaceText(value);
83
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
81
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
84
82
  }
85
83
 
86
84
  async clearText() {
87
85
  const action = new actions.ClearTextAction();
88
86
  const traceDescription = actionDescription.clearText();
89
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
87
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
90
88
  }
91
89
 
92
90
  async scroll(amount, direction = 'down', startPositionX, startPositionY) {
93
91
  const action = new actions.ScrollAmountAction(direction, amount, startPositionX, startPositionY);
94
92
  const traceDescription = actionDescription.scroll(amount, direction, startPositionX, startPositionY);
95
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
93
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
96
94
  }
97
95
 
98
96
  async scrollTo(edge) {
99
97
  // override the user's element selection with an extended matcher that looks for UIScrollView children
100
- this._selectElementWithMatcher(this._originalMatcher._extendToDescendantScrollViews());
98
+ this._matcher = this._matcher._extendToDescendantScrollViews();
101
99
 
102
100
  const action = new actions.ScrollEdgeAction(edge);
103
101
  const traceDescription = actionDescription.scrollTo(edge);
104
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
102
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
105
103
  }
106
104
 
107
105
  async scrollToIndex(index) {
108
106
  // override the user's element selection with an extended matcher that looks for UIScrollView children
109
- this._selectElementWithMatcher(this._originalMatcher._extendToDescendantScrollViews());
107
+ this._matcher = this._matcher._extendToDescendantScrollViews();
110
108
 
111
109
  const action = new actions.ScrollToIndex(index);
112
110
  const traceDescription = actionDescription.scrollToIndex(index);
113
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
111
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
114
112
  }
115
113
 
116
114
  async setDatePickerDate(rawDateString, formatString) {
@@ -120,7 +118,7 @@ class NativeElement {
120
118
 
121
119
  const action = new actions.SetDatePickerDateAction(dateString, formatString);
122
120
  const traceDescription = actionDescription.setDatePickerDate(dateString, formatString);
123
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
121
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
124
122
  }
125
123
 
126
124
  /**
@@ -134,18 +132,18 @@ class NativeElement {
134
132
  normalizedSwipeOffset = Number.isNaN(normalizedSwipeOffset) ? 0.75 : normalizedSwipeOffset;
135
133
 
136
134
  // override the user's element selection with an extended matcher that avoids RN issues with RCTScrollView
137
- this._selectElementWithMatcher(this._originalMatcher._avoidProblematicReactNativeElements());
135
+ this._matcher = this._matcher._avoidProblematicReactNativeElements();
138
136
 
139
137
  const action = new actions.SwipeAction(direction, speed, normalizedSwipeOffset, normalizedStartingPointX, normalizedStartingPointY);
140
138
  const traceDescription = actionDescription.swipe(direction, speed, normalizedSwipeOffset, normalizedStartingPointX, normalizedStartingPointY);
141
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
139
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
142
140
  }
143
141
 
144
142
  async takeScreenshot(screenshotName) {
145
143
  // TODO this should be moved to a lower-layer handler of this use-case
146
144
  const action = new actions.TakeElementScreenshot();
147
145
  const traceDescription = actionDescription.takeScreenshot(screenshotName);
148
- const resultBase64 = await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
146
+ const resultBase64 = await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
149
147
  const filePath = tempfile('detox.element-screenshot.png');
150
148
  await fs.writeFile(filePath, resultBase64, 'base64');
151
149
 
@@ -160,19 +158,18 @@ class NativeElement {
160
158
  async getAttributes() {
161
159
  const action = new actions.GetAttributes();
162
160
  const traceDescription = actionDescription.getAttributes();
163
- const result = await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
164
- return JSON.parse(result);
161
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
165
162
  }
166
163
 
167
164
  async adjustSliderToPosition(newPosition) {
168
165
  const action = new actions.AdjustSliderToPosition(newPosition);
169
166
  const traceDescription = actionDescription.adjustSliderToPosition(newPosition);
170
- return await new ActionInteraction(this._invocationManager, this, action, traceDescription).execute();
167
+ return await new ActionInteraction(this._invocationManager, this._matcher, action, traceDescription).execute();
171
168
  }
172
169
 
173
170
  async performAccessibilityAction(actionName) {
174
171
  const traceDescription = actionDescription.performAccessibilityAction(actionName);
175
- return await new ActionInteraction(this._invocationManager, this, new actions.AccessibilityActionAction(actionName), traceDescription).execute();
172
+ return await new ActionInteraction(this._invocationManager, this._matcher, new actions.AccessibilityActionAction(actionName), traceDescription).execute();
176
173
  }
177
174
  }
178
175
 
@@ -14,7 +14,7 @@ function sanitize_matcher(matcher) {
14
14
  return originalMatcher.type ? originalMatcher.value : originalMatcher;
15
15
  }
16
16
  class DetoxAssertion {
17
- static assertMatcher(i, m) {
17
+ static assertMatcher(viewInteraction, viewMatcher) {
18
18
  return {
19
19
  target: {
20
20
  type: "Class",
@@ -23,15 +23,15 @@ class DetoxAssertion {
23
23
  method: "assertMatcher",
24
24
  args: [{
25
25
  type: "Invocation",
26
- value: i
26
+ value: viewInteraction
27
27
  }, {
28
28
  type: "Invocation",
29
- value: sanitize_matcher(m)
29
+ value: sanitize_matcher(viewMatcher)
30
30
  }]
31
31
  };
32
32
  }
33
33
 
34
- static assertNotVisible(i) {
34
+ static assertNotVisible(viewInteraction) {
35
35
  return {
36
36
  target: {
37
37
  type: "Class",
@@ -40,12 +40,12 @@ class DetoxAssertion {
40
40
  method: "assertNotVisible",
41
41
  args: [{
42
42
  type: "Invocation",
43
- value: i
43
+ value: viewInteraction
44
44
  }]
45
45
  };
46
46
  }
47
47
 
48
- static assertNotExists(i) {
48
+ static assertNotExists(viewInteraction) {
49
49
  return {
50
50
  target: {
51
51
  type: "Class",
@@ -54,12 +54,12 @@ class DetoxAssertion {
54
54
  method: "assertNotExists",
55
55
  args: [{
56
56
  type: "Invocation",
57
- value: i
57
+ value: viewInteraction
58
58
  }]
59
59
  };
60
60
  }
61
61
 
62
- static waitForAssertMatcher(i, m, timeoutSeconds) {
62
+ static waitForAssertMatcher(viewInteraction, viewMatcher, timeoutSeconds) {
63
63
  if (typeof timeoutSeconds !== "number") throw new Error("timeoutSeconds should be a number, but got " + (timeoutSeconds + (" (" + (typeof timeoutSeconds + ")"))));
64
64
  return {
65
65
  target: {
@@ -69,10 +69,10 @@ class DetoxAssertion {
69
69
  method: "waitForAssertMatcher",
70
70
  args: [{
71
71
  type: "Invocation",
72
- value: i
72
+ value: viewInteraction
73
73
  }, {
74
74
  type: "Invocation",
75
- value: sanitize_matcher(m)
75
+ value: sanitize_matcher(viewMatcher)
76
76
  }, {
77
77
  type: "Double",
78
78
  value: timeoutSeconds
@@ -80,7 +80,8 @@ class DetoxAssertion {
80
80
  };
81
81
  }
82
82
 
83
- static waitForAssertMatcherWithSearchAction(i, vm, searchAction, searchMatcher) {
83
+ static waitForAssertMatcherWithSearchAction(viewInteraction, viewMatcher, searchAction, searchMatcher
84
+ ) {
84
85
  return {
85
86
  target: {
86
87
  type: "Class",
@@ -89,13 +90,14 @@ class DetoxAssertion {
89
90
  method: "waitForAssertMatcherWithSearchAction",
90
91
  args: [{
91
92
  type: "Invocation",
92
- value: i
93
+ value: viewInteraction
93
94
  }, {
94
95
  type: "Invocation",
95
- value: sanitize_matcher(vm)
96
+ value: sanitize_matcher(viewMatcher)
96
97
  }, searchAction, {
97
98
  type: "Invocation",
98
- value: sanitize_matcher(searchMatcher)
99
+ value: sanitize_matcher(searchMatcher
100
+ )
99
101
  }]
100
102
  };
101
103
  }
@@ -5,9 +5,16 @@
5
5
  */
6
6
 
7
7
 
8
+ function sanitize_matcher(matcher) {
9
+ if (!matcher._call) {
10
+ return matcher;
11
+ }
8
12
 
13
+ const originalMatcher = typeof matcher._call === 'function' ? matcher._call() : matcher._call;
14
+ return originalMatcher.type ? originalMatcher.value : originalMatcher;
15
+ }
9
16
  class EspressoDetox {
10
- static perform(interaction, action) {
17
+ static perform(matcher, action) {
11
18
  return {
12
19
  target: {
13
20
  type: "Class",
@@ -16,7 +23,7 @@ class EspressoDetox {
16
23
  method: "perform",
17
24
  args: [{
18
25
  type: "Invocation",
19
- value: interaction
26
+ value: sanitize_matcher(matcher)
20
27
  }, action]
21
28
  };
22
29
  }
@@ -25,9 +25,9 @@ class Interaction {
25
25
  }
26
26
 
27
27
  class ActionInteraction extends Interaction {
28
- constructor(invocationManager, element, action, traceDescription) {
28
+ constructor(invocationManager, matcher, action, traceDescription) {
29
29
  super(invocationManager, traceDescription);
30
- this._call = EspressoDetoxApi.perform(call(element._call), action._call);
30
+ this._call = EspressoDetoxApi.perform(matcher, action._call);
31
31
  // TODO: move this.execute() here from the caller
32
32
  }
33
33
  }
@@ -48,7 +48,6 @@ class WaitForInteraction extends Interaction {
48
48
  super(invocationManager, expectTraceDescription);
49
49
  this._element = element;
50
50
  this._assertionMatcher = assertionMatcher;
51
- this._element._selectElementWithMatcher(this._element._originalMatcher);
52
51
  }
53
52
 
54
53
  async withTimeout(timeout) {
@@ -32,6 +32,7 @@ function composeLoggerConfig(opts) {
32
32
  if (!config) return acc;
33
33
  const { options } = config;
34
34
  return _.merge(acc, {
35
+ // @ts-ignore-line
35
36
  options: typeof options === 'function' ? options(acc) : options
36
37
  });
37
38
  },
@@ -1,13 +1,20 @@
1
- // @ts-nocheck
1
+ /**
2
+ * @typedef {import('./drivers/AllocationDriverBase').AllocationDriverBase} AllocationDriverBase
3
+ * @typedef {import('./drivers/AllocationDriverBase').DeallocOptions} DeallocOptions
4
+ * @typedef {import('../common/drivers/DeviceCookie').DeviceCookie} DeviceCookie
5
+ */
6
+
2
7
  const log = require('../../utils/logger').child({ cat: 'device,device-allocation' });
3
8
  const traceMethods = require('../../utils/traceMethods');
4
9
 
5
10
  class DeviceAllocator {
6
11
  /**
7
- * @param allocationDriver { AllocationDriverBase }
12
+ * @param {AllocationDriverBase} allocationDriver
8
13
  */
9
14
  constructor(allocationDriver) {
10
15
  this._driver = allocationDriver;
16
+ this._counter = 0;
17
+ this._ids = new Map();
11
18
  traceMethods(log, this, ['init', 'cleanup', 'emergencyCleanup']);
12
19
  }
13
20
 
@@ -21,38 +28,42 @@ class DeviceAllocator {
21
28
  }
22
29
 
23
30
  /**
24
- * @param deviceConfig { Object }
31
+ * @param {Detox.DetoxDeviceConfig} deviceConfig
25
32
  * @returns {Promise<DeviceCookie>}
26
33
  */
27
34
  async allocate(deviceConfig) {
28
- return await log.trace.complete({ data: deviceConfig, id: Math.random() }, 'allocate', async () => {
35
+ const tid = this._counter++;
36
+ return await log.trace.complete({ data: deviceConfig, id: tid }, 'allocate', async () => {
29
37
  const cookie = await this._driver.allocate(deviceConfig);
30
- log.debug({ event: undefined }, `settled on ${cookie}`);
38
+ log.debug({ data: cookie }, `settled on ${cookie.name || cookie.id}`);
39
+ this._ids.set(cookie.id, tid);
31
40
  return cookie;
32
41
  });
33
42
  }
34
43
 
35
44
  /**
36
- * @param {DeviceCookie} deviceCookie
45
+ * @param {DeviceCookie} cookie
37
46
  * @returns {Promise<DeviceCookie>}
38
47
  */
39
- async postAllocate(deviceCookie) {
40
- return await log.trace.complete({ data: deviceCookie, id: Math.random() }, `post-allocate: ${deviceCookie}`, async () => {
48
+ async postAllocate(cookie) {
49
+ const tid = this._ids.get(cookie.id);
50
+ return await log.trace.complete({ data: cookie, id: tid }, `post-allocate: ${cookie.id}`, async () => {
41
51
  const updatedCookie = typeof this._driver.postAllocate === 'function'
42
- ? await this._driver.postAllocate(deviceCookie)
52
+ ? await this._driver.postAllocate(cookie)
43
53
  : undefined;
44
54
 
45
- return updatedCookie || deviceCookie;
55
+ return updatedCookie || cookie;
46
56
  });
47
57
  }
48
58
 
49
59
  /**
50
- * @param cookie { DeviceCookie }
51
- * @param options { Partial<DeallocOptions> }
60
+ * @param {DeviceCookie} cookie
61
+ * @param {DeallocOptions} options
52
62
  * @returns {Promise<void>}
53
63
  */
54
64
  async free(cookie, options = {}) {
55
- await log.trace.complete({ data: options, id: Math.random() }, `free: ${cookie}`, async () => {
65
+ const tid = this._ids.get(cookie.id);
66
+ await log.trace.complete({ data: options, id: tid }, `free: ${cookie.id}`, async () => {
56
67
  await this._driver.free(cookie, options);
57
68
  });
58
69
  }
@@ -127,6 +127,9 @@ class DeviceRegistry {
127
127
  });
128
128
  }
129
129
 
130
+ /**
131
+ * @returns {Promise<DeviceList>}
132
+ */
130
133
  async readSessionDevices() {
131
134
  let devices;
132
135
  await this._lockfile.exclusively(() => {
@@ -0,0 +1,15 @@
1
+ /* eslint-disable import/no-unresolved,node/no-missing-import,node/no-unsupported-features/es-syntax */
2
+ import { DeviceCookie } from '../../common/drivers/DeviceCookie';
3
+
4
+ export interface DeallocOptions {
5
+ shutdown?: boolean;
6
+ }
7
+
8
+ export interface AllocationDriverBase {
9
+ init?(): Promise<void>;
10
+ allocate(deviceConfig: any): Promise<DeviceCookie>;
11
+ postAllocate?(deviceCookie: DeviceCookie): Promise<DeviceCookie | void>;
12
+ free(cookie: DeviceCookie, options: DeallocOptions): Promise<void>;
13
+ cleanup?(): Promise<void>;
14
+ emergencyCleanup?(): void;
15
+ }
@@ -1,15 +1,19 @@
1
- // @ts-nocheck
2
- const AttachedAndroidDeviceCookie = require('../../../../cookies/AttachedAndroidDeviceCookie');
3
- const AllocationDriverBase = require('../../AllocationDriverBase');
4
-
5
- class AttachedAndroidAllocDriver extends AllocationDriverBase {
1
+ /**
2
+ * @typedef {import('../../AllocationDriverBase').AllocationDriverBase} AllocationDriverBase
3
+ * @typedef {import('../../../../common/drivers/android/cookies').AndroidDeviceCookie} AndroidDeviceCookie
4
+ */
5
+
6
+ /**
7
+ * @implements {AllocationDriverBase}
8
+ */
9
+ class AttachedAndroidAllocDriver {
6
10
  /**
7
- * @param adb { ADB }
8
- * @param deviceRegistry { DeviceRegistry }
9
- * @param freeDeviceFinder { FreeDeviceFinder }
11
+ * @param {object} options
12
+ * @param {import('../../../../common/drivers/android/exec/ADB')} options.adb
13
+ * @param {import('../../../DeviceRegistry')} options.deviceRegistry
14
+ * @param {import('../FreeDeviceFinder')} options.freeDeviceFinder
10
15
  */
11
16
  constructor({ adb, deviceRegistry, freeDeviceFinder }) {
12
- super();
13
17
  this._adb = adb;
14
18
  this._deviceRegistry = deviceRegistry;
15
19
  this._freeDeviceFinder = freeDeviceFinder;
@@ -27,11 +31,11 @@ class AttachedAndroidAllocDriver extends AllocationDriverBase {
27
31
  const adbNamePattern = deviceConfig.device.adbName;
28
32
  const adbName = await this._deviceRegistry.registerDevice(() => this._freeDeviceFinder.findFreeDevice(adbNamePattern));
29
33
 
30
- return new AttachedAndroidDeviceCookie(adbName);
34
+ return { id: adbName, adbName };
31
35
  }
32
36
 
33
37
  /**
34
- * @param {AttachedAndroidDeviceCookie} deviceCookie
38
+ * @param {AndroidDeviceCookie} deviceCookie
35
39
  * @returns {Promise<void>}
36
40
  */
37
41
  async postAllocate(deviceCookie) {
@@ -43,7 +47,7 @@ class AttachedAndroidAllocDriver extends AllocationDriverBase {
43
47
  }
44
48
 
45
49
  /**
46
- * @param cookie { AttachedAndroidDeviceCookie }
50
+ * @param cookie { AndroidDeviceCookie }
47
51
  * @return {Promise<void>}
48
52
  */
49
53
  async free(cookie) {
@@ -1,13 +1,19 @@
1
+ /**
2
+ * @typedef {import('../../AllocationDriverBase').AllocationDriverBase} AllocationDriverBase
3
+ * @typedef {import('../../../../common/drivers/android/cookies').AndroidDeviceCookie} AndroidDeviceCookie
4
+ */
5
+
1
6
  const _ = require('lodash');
2
7
 
3
8
  const Deferred = require('../../../../../utils/Deferred');
4
9
  const log = require('../../../../../utils/logger').child({ cat: 'device,device-allocation' });
5
- const AndroidEmulatorCookie = require('../../../../cookies/AndroidEmulatorCookie');
6
- const AllocationDriverBase = require('../../AllocationDriverBase');
7
10
 
8
11
  const { patchAvdSkinConfig } = require('./patchAvdSkinConfig');
9
12
 
10
- class EmulatorAllocDriver extends AllocationDriverBase {
13
+ /**
14
+ * @implements {AllocationDriverBase}
15
+ */
16
+ class EmulatorAllocDriver {
11
17
  /**
12
18
  * @param {object} options
13
19
  * @param {import('../../../../common/drivers/android/exec/ADB')} options.adb
@@ -29,13 +35,6 @@ class EmulatorAllocDriver extends AllocationDriverBase {
29
35
  emulatorVersionResolver,
30
36
  emulatorLauncher
31
37
  }) {
32
- super();
33
-
34
- /** @type {Deferred} */
35
- this._deferredAllocation = Deferred.resolved(null);
36
- /** @type {Promise<unknown>} */
37
- this._pendingAllocation = Promise.resolve();
38
-
39
38
  this._adb = adb;
40
39
  this._avdValidator = avdValidator;
41
40
  this._deviceRegistry = deviceRegistry;
@@ -44,6 +43,7 @@ class EmulatorAllocDriver extends AllocationDriverBase {
44
43
  this._freeDeviceFinder = freeDeviceFinder;
45
44
  this._freePortFinder = freePortFinder;
46
45
  this._shouldShutdown = detoxConfig.behavior.cleanup.shutdownDevice;
46
+ this._fixAvdConfigIniSkinNameIfNeeded = _.memoize(this._fixAvdConfigIniSkinNameIfNeeded.bind(this));
47
47
  }
48
48
 
49
49
  async init() {
@@ -52,68 +52,45 @@ class EmulatorAllocDriver extends AllocationDriverBase {
52
52
 
53
53
  /**
54
54
  * @param deviceConfig
55
- * @returns {Promise<AndroidEmulatorCookie>}
55
+ * @returns {Promise<AndroidDeviceCookie>}
56
56
  */
57
57
  async allocate(deviceConfig) {
58
- await this._pendingAllocation.catch(() => { /* ignore previous errors */ });
59
- this._deferredAllocation = new Deferred();
60
- this._pendingAllocation = this._deviceRegistry.registerDevice(() => this._deferredAllocation.promise);
61
-
62
- try {
63
- return await this._doAllocate(deviceConfig);
64
- } catch (e) {
65
- this._deferredAllocation.reject(e);
66
- throw e;
67
- }
68
- }
69
-
70
- /**
71
- * @param deviceConfig
72
- * @returns {Promise<AndroidEmulatorCookie>}
73
- */
74
- async _doAllocate(deviceConfig) {
75
58
  const avdName = deviceConfig.device.avdName;
76
59
 
77
60
  await this._avdValidator.validate(avdName, deviceConfig.headless);
78
61
  await this._fixAvdConfigIniSkinNameIfNeeded(avdName, deviceConfig.headless);
79
62
 
80
- let adbName = await this._freeDeviceFinder.findFreeDevice(avdName);
81
- if (!adbName) {
82
- const port = await this._freePortFinder.findFreePort();
83
- adbName = `emulator-${port}`;
84
-
85
- await this._emulatorLauncher.launch({
86
- bootArgs: deviceConfig.bootArgs,
87
- gpuMode: deviceConfig.gpuMode,
88
- headless: deviceConfig.headless,
89
- readonly: deviceConfig.readonly,
90
- avdName,
91
- adbName,
92
- port,
93
- });
94
- }
95
-
96
- return new AndroidEmulatorCookie(adbName);
97
- }
98
-
99
- /**
100
- * @param {AndroidEmulatorCookie} deviceCookie
101
- */
102
- async postAllocate(deviceCookie) {
103
- try {
104
- await this._doPostAllocate(deviceCookie);
105
- this._deferredAllocation.resolve(deviceCookie.adbName);
106
- } catch (e) {
107
- this._deferredAllocation.reject(e);
108
- throw e;
109
- }
63
+ const adbName = await this._deviceRegistry.registerDevice(async () => {
64
+ let adbName = await this._freeDeviceFinder.findFreeDevice(avdName);
65
+ if (!adbName) {
66
+ const port = await this._freePortFinder.findFreePort();
67
+ adbName = `emulator-${port}`;
68
+
69
+ await this._emulatorLauncher.launch({
70
+ bootArgs: deviceConfig.bootArgs,
71
+ gpuMode: deviceConfig.gpuMode,
72
+ headless: deviceConfig.headless,
73
+ readonly: deviceConfig.readonly,
74
+ avdName,
75
+ adbName,
76
+ port,
77
+ });
78
+ }
79
+
80
+ return adbName;
81
+ });
82
+
83
+ return {
84
+ id: adbName,
85
+ adbName,
86
+ name: `${adbName} (${avdName})`,
87
+ };
110
88
  }
111
89
 
112
90
  /**
113
- * @param {AndroidEmulatorCookie} deviceCookie
114
- * @returns {Promise<void>}
91
+ * @param {AndroidDeviceCookie} deviceCookie
115
92
  */
116
- async _doPostAllocate(deviceCookie) {
93
+ async postAllocate(deviceCookie) {
117
94
  const { adbName } = deviceCookie;
118
95
 
119
96
  await this._emulatorLauncher.awaitEmulatorBoot(adbName);
@@ -123,7 +100,7 @@ class EmulatorAllocDriver extends AllocationDriverBase {
123
100
  }
124
101
 
125
102
  /**
126
- * @param cookie {AndroidEmulatorCookie}
103
+ * @param cookie {AndroidDeviceCookie}
127
104
  * @param options {Partial<import('../../AllocationDriverBase').DeallocOptions>}
128
105
  * @return {Promise<void>}
129
106
  */