appium-android-driver 5.14.7 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/build/index.d.ts +282 -0
  2. package/build/index.d.ts.map +1 -0
  3. package/build/index.js.map +1 -0
  4. package/build/lib/commands/actions.d.ts +6 -224
  5. package/build/lib/commands/actions.d.ts.map +1 -1
  6. package/build/lib/commands/actions.js +306 -405
  7. package/build/lib/commands/actions.js.map +1 -1
  8. package/build/lib/commands/alert.d.ts +7 -9
  9. package/build/lib/commands/alert.d.ts.map +1 -1
  10. package/build/lib/commands/alert.js +24 -18
  11. package/build/lib/commands/alert.js.map +1 -1
  12. package/build/lib/commands/app-management.d.ts +7 -313
  13. package/build/lib/commands/app-management.d.ts.map +1 -1
  14. package/build/lib/commands/app-management.js +135 -293
  15. package/build/lib/commands/app-management.js.map +1 -1
  16. package/build/lib/commands/context.d.ts +8 -92
  17. package/build/lib/commands/context.d.ts.map +1 -1
  18. package/build/lib/commands/context.js +381 -439
  19. package/build/lib/commands/context.js.map +1 -1
  20. package/build/lib/commands/element.d.ts +8 -35
  21. package/build/lib/commands/element.d.ts.map +1 -1
  22. package/build/lib/commands/element.js +153 -136
  23. package/build/lib/commands/element.js.map +1 -1
  24. package/build/lib/commands/emu-console.d.ts +6 -48
  25. package/build/lib/commands/emu-console.d.ts.map +1 -1
  26. package/build/lib/commands/emu-console.js +19 -34
  27. package/build/lib/commands/emu-console.js.map +1 -1
  28. package/build/lib/commands/execute.d.ts +6 -5
  29. package/build/lib/commands/execute.d.ts.map +1 -1
  30. package/build/lib/commands/execute.js +77 -66
  31. package/build/lib/commands/execute.js.map +1 -1
  32. package/build/lib/commands/file-actions.d.ts +7 -128
  33. package/build/lib/commands/file-actions.d.ts.map +1 -1
  34. package/build/lib/commands/file-actions.js +183 -219
  35. package/build/lib/commands/file-actions.js.map +1 -1
  36. package/build/lib/commands/find.d.ts +8 -12
  37. package/build/lib/commands/find.d.ts.map +1 -1
  38. package/build/lib/commands/find.js +19 -23
  39. package/build/lib/commands/find.js.map +1 -1
  40. package/build/lib/commands/general.d.ts +9 -132
  41. package/build/lib/commands/general.d.ts.map +1 -1
  42. package/build/lib/commands/general.js +281 -312
  43. package/build/lib/commands/general.js.map +1 -1
  44. package/build/lib/commands/ime.d.ts +7 -10
  45. package/build/lib/commands/ime.d.ts.map +1 -1
  46. package/build/lib/commands/ime.js +47 -35
  47. package/build/lib/commands/ime.js.map +1 -1
  48. package/build/lib/commands/index.d.ts +27 -2
  49. package/build/lib/commands/index.d.ts.map +1 -1
  50. package/build/lib/commands/index.js +41 -19
  51. package/build/lib/commands/index.js.map +1 -1
  52. package/build/lib/commands/intent.d.ts +7 -417
  53. package/build/lib/commands/intent.d.ts.map +1 -1
  54. package/build/lib/commands/intent.js +104 -216
  55. package/build/lib/commands/intent.js.map +1 -1
  56. package/build/lib/commands/keyboard.d.ts +6 -5
  57. package/build/lib/commands/keyboard.d.ts.map +1 -1
  58. package/build/lib/commands/keyboard.js +16 -8
  59. package/build/lib/commands/keyboard.js.map +1 -1
  60. package/build/lib/commands/log.d.ts +7 -44
  61. package/build/lib/commands/log.d.ts.map +1 -1
  62. package/build/lib/commands/log.js +146 -108
  63. package/build/lib/commands/log.js.map +1 -1
  64. package/build/lib/commands/media-projection.d.ts +7 -143
  65. package/build/lib/commands/media-projection.d.ts.map +1 -1
  66. package/build/lib/commands/media-projection.js +113 -140
  67. package/build/lib/commands/media-projection.js.map +1 -1
  68. package/build/lib/commands/mixins.d.ts +740 -0
  69. package/build/lib/commands/mixins.d.ts.map +1 -0
  70. package/build/lib/commands/mixins.js +19 -0
  71. package/build/lib/commands/mixins.js.map +1 -0
  72. package/build/lib/commands/network.d.ts +7 -138
  73. package/build/lib/commands/network.d.ts.map +1 -1
  74. package/build/lib/commands/network.js +212 -254
  75. package/build/lib/commands/network.js.map +1 -1
  76. package/build/lib/commands/performance.d.ts +24 -70
  77. package/build/lib/commands/performance.d.ts.map +1 -1
  78. package/build/lib/commands/performance.js +144 -100
  79. package/build/lib/commands/performance.js.map +1 -1
  80. package/build/lib/commands/permissions.d.ts +8 -92
  81. package/build/lib/commands/permissions.d.ts.map +1 -1
  82. package/build/lib/commands/permissions.js +75 -87
  83. package/build/lib/commands/permissions.js.map +1 -1
  84. package/build/lib/commands/recordscreen.d.ts +7 -193
  85. package/build/lib/commands/recordscreen.d.ts.map +1 -1
  86. package/build/lib/commands/recordscreen.js +151 -182
  87. package/build/lib/commands/recordscreen.js.map +1 -1
  88. package/build/lib/commands/shell.d.ts +7 -7
  89. package/build/lib/commands/shell.d.ts.map +1 -1
  90. package/build/lib/commands/shell.js +40 -33
  91. package/build/lib/commands/shell.js.map +1 -1
  92. package/build/lib/commands/streamscreen.d.ts +9 -103
  93. package/build/lib/commands/streamscreen.d.ts.map +1 -1
  94. package/build/lib/commands/streamscreen.js +261 -218
  95. package/build/lib/commands/streamscreen.js.map +1 -1
  96. package/build/lib/commands/system-bars.d.ts +22 -90
  97. package/build/lib/commands/system-bars.d.ts.map +1 -1
  98. package/build/lib/commands/system-bars.js +76 -74
  99. package/build/lib/commands/system-bars.js.map +1 -1
  100. package/build/lib/commands/touch.d.ts +10 -29
  101. package/build/lib/commands/touch.d.ts.map +1 -1
  102. package/build/lib/commands/touch.js +301 -285
  103. package/build/lib/commands/touch.js.map +1 -1
  104. package/build/lib/commands/types.d.ts +978 -0
  105. package/build/lib/commands/types.d.ts.map +1 -0
  106. package/build/lib/commands/types.js +3 -0
  107. package/build/lib/commands/types.js.map +1 -0
  108. package/build/lib/constraints.d.ts +291 -0
  109. package/build/lib/constraints.d.ts.map +1 -0
  110. package/build/lib/constraints.js +300 -0
  111. package/build/lib/constraints.js.map +1 -0
  112. package/build/lib/driver.d.ts +68 -37
  113. package/build/lib/driver.d.ts.map +1 -1
  114. package/build/lib/driver.js +123 -80
  115. package/build/lib/driver.js.map +1 -1
  116. package/build/lib/helpers/android.d.ts +164 -0
  117. package/build/lib/helpers/android.d.ts.map +1 -0
  118. package/build/lib/helpers/android.js +819 -0
  119. package/build/lib/helpers/android.js.map +1 -0
  120. package/build/lib/helpers/index.d.ts +7 -0
  121. package/build/lib/helpers/index.d.ts.map +1 -0
  122. package/build/lib/helpers/index.js +29 -0
  123. package/build/lib/helpers/index.js.map +1 -0
  124. package/build/lib/helpers/types.d.ts +121 -0
  125. package/build/lib/helpers/types.d.ts.map +1 -0
  126. package/build/lib/helpers/types.js +3 -0
  127. package/build/lib/helpers/types.js.map +1 -0
  128. package/build/lib/helpers/unlock.d.ts +32 -0
  129. package/build/lib/helpers/unlock.d.ts.map +1 -0
  130. package/build/lib/helpers/unlock.js +273 -0
  131. package/build/lib/helpers/unlock.js.map +1 -0
  132. package/build/lib/helpers/webview.d.ts +74 -0
  133. package/build/lib/helpers/webview.d.ts.map +1 -0
  134. package/build/lib/helpers/webview.js +421 -0
  135. package/build/lib/helpers/webview.js.map +1 -0
  136. package/build/lib/index.d.ts +9 -0
  137. package/build/lib/index.d.ts.map +1 -0
  138. package/build/lib/index.js +37 -0
  139. package/build/lib/index.js.map +1 -0
  140. package/build/lib/method-map.d.ts +0 -8
  141. package/build/lib/method-map.d.ts.map +1 -1
  142. package/build/lib/method-map.js +63 -74
  143. package/build/lib/method-map.js.map +1 -1
  144. package/build/lib/stubs.d.ts +0 -1
  145. package/build/lib/stubs.d.ts.map +1 -1
  146. package/build/lib/stubs.js +1 -0
  147. package/build/lib/stubs.js.map +1 -1
  148. package/build/lib/utils.d.ts +1 -1
  149. package/build/lib/utils.d.ts.map +1 -1
  150. package/lib/commands/actions.js +351 -464
  151. package/lib/commands/alert.js +27 -17
  152. package/lib/commands/app-management.js +156 -314
  153. package/lib/commands/context.js +457 -441
  154. package/lib/commands/element.js +201 -157
  155. package/lib/commands/emu-console.js +25 -45
  156. package/lib/commands/execute.js +106 -90
  157. package/lib/commands/file-actions.js +222 -240
  158. package/lib/commands/find.ts +103 -0
  159. package/lib/commands/general.js +327 -339
  160. package/lib/commands/ime.js +50 -34
  161. package/lib/commands/{index.js → index.ts} +20 -24
  162. package/lib/commands/intent.js +108 -249
  163. package/lib/commands/keyboard.js +20 -8
  164. package/lib/commands/log.js +172 -116
  165. package/lib/commands/media-projection.js +134 -161
  166. package/lib/commands/mixins.ts +966 -0
  167. package/lib/commands/network.js +252 -281
  168. package/lib/commands/performance.js +203 -132
  169. package/lib/commands/permissions.js +108 -109
  170. package/lib/commands/recordscreen.js +212 -209
  171. package/lib/commands/shell.js +51 -40
  172. package/lib/commands/streamscreen.js +355 -289
  173. package/lib/commands/system-bars.js +92 -83
  174. package/lib/commands/touch.js +357 -294
  175. package/lib/commands/types.ts +1097 -0
  176. package/lib/{desired-caps.js → constraints.ts} +106 -103
  177. package/lib/{driver.js → driver.ts} +278 -132
  178. package/lib/helpers/android.ts +1143 -0
  179. package/lib/helpers/index.ts +6 -0
  180. package/lib/helpers/types.ts +134 -0
  181. package/lib/helpers/unlock.ts +329 -0
  182. package/lib/helpers/webview.ts +582 -0
  183. package/lib/index.ts +18 -0
  184. package/lib/method-map.js +87 -98
  185. package/lib/stubs.ts +0 -1
  186. package/package.json +27 -20
  187. package/index.js +0 -24
  188. package/lib/android-helpers.js +0 -983
  189. package/lib/commands/coverage.js +0 -18
  190. package/lib/commands/find.js +0 -82
  191. package/lib/unlock-helpers.js +0 -278
  192. package/lib/webview-helpers.js +0 -602
@@ -1,168 +1,212 @@
1
- import androidHelpers from '../android-helpers';
2
- import { retryInterval } from 'asyncbox';
3
- import { util } from '@appium/support';
1
+ // @ts-check
4
2
 
5
-
6
- let commands = {}, helpers = {}, extensions = {};
7
-
8
- commands.getAttribute = async function getAttribute (attribute, elementId) {
9
- let p = {attribute, elementId};
10
- return await this.bootstrap.sendAction('element:getAttribute', p);
11
- };
12
-
13
- commands.getName = async function getName (elementId) {
14
- return await this.getAttribute('className', elementId);
15
- };
16
-
17
- commands.elementDisplayed = async function elementDisplayed (elementId) {
18
- return await this.getAttribute('displayed', elementId) === 'true';
19
- };
20
-
21
- commands.elementEnabled = async function elementEnabled (elementId) {
22
- return await this.getAttribute('enabled', elementId) === 'true';
23
- };
24
-
25
- commands.elementSelected = async function elementSelected (elementId) {
26
- return await this.getAttribute('selected', elementId) === 'true';
27
- };
28
-
29
- helpers.setElementValue = async function setElementValue (keys, elementId, replace = false) {
30
- let text = keys;
31
- if (keys instanceof Array) {
32
- text = keys.join('');
33
- }
34
-
35
- let params = {
36
- elementId,
37
- text,
38
- replace,
39
- unicodeKeyboard: this.opts.unicodeKeyboard
40
- };
41
-
42
- return await this.doSetElementValue(params);
43
- };
3
+ import {AndroidHelpers as androidHelpers} from '../helpers';
4
+ import {mixin} from './mixins';
5
+ import {retryInterval} from 'asyncbox';
6
+ import {util} from '@appium/support';
44
7
 
45
8
  /**
46
- * Reason for isolating doSetElementValue from setElementValue is for reusing setElementValue
47
- * across android-drivers (like appium-uiautomator2-driver) and to avoid code duplication.
48
- * Other android-drivers (like appium-uiautomator2-driver) need to override doSetElementValue
49
- * to facilitate setElementValue.
9
+ * @type {import('./mixins').ElementMixin & ThisType<import('../driver').AndroidDriver>}
10
+ * @satisfies {import('@appium/types').ExternalDriver}
50
11
  */
51
- helpers.doSetElementValue = async function doSetElementValue (params) {
52
- return await this.bootstrap.sendAction('element:setText', params);
53
- };
54
-
55
- commands.setValue = async function setValue (keys, elementId) {
56
- return await this.setElementValue(keys, elementId, false);
57
- };
58
-
59
- commands.replaceValue = async function replaceValue (keys, elementId) {
60
- return await this.setElementValue(keys, elementId, true);
61
- };
62
-
63
- commands.setValueImmediate = async function setValueImmediate (keys, elementId) {
64
- let text = keys;
65
- if (keys instanceof Array) {
66
- text = keys.join('');
67
- }
68
-
69
- // first, make sure we are focused on the element
70
- await this.click(elementId);
71
-
72
- // then send through adb
73
- await this.adb.inputText(text);
74
- };
75
-
76
- commands.getText = async function getText (elementId) {
77
- return await this.bootstrap.sendAction('element:getText', {elementId});
78
- };
79
-
80
- commands.clear = async function clear (elementId) {
81
- let text = (await this.getText(elementId)) || '';
82
- let length = text.length;
83
- if (length === 0) {
84
- // if length is zero there are two possibilities:
85
- // 1. there is nothing in the text field
86
- // 2. it is a password field
87
- // since there is little overhead to the adb call, delete 100 elements
88
- // if we get zero, just in case it is #2
89
- length = 100;
90
- }
91
- await this.click(elementId);
92
- this.log.debug(`Sending up to ${length} clear characters to device`);
93
- return await retryInterval(5, 500, async () => {
94
- let remainingLength = length;
95
- while (remainingLength > 0) {
96
- let lengthToSend = remainingLength < 50 ? remainingLength : 50;
97
- this.log.debug(`Sending ${lengthToSend} clear characters to device`);
98
- await this.adb.clearTextField(lengthToSend);
99
- remainingLength -= lengthToSend;
12
+ const ElementMixin = {
13
+ async getAttribute(attribute, elementId) {
14
+ let p = {attribute, elementId};
15
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
16
+ 'element:getAttribute',
17
+ p
18
+ );
19
+ },
20
+
21
+ async getName(elementId) {
22
+ return await this.getAttribute('className', elementId);
23
+ },
24
+
25
+ async elementDisplayed(elementId) {
26
+ return (await this.getAttribute('displayed', elementId)) === 'true';
27
+ },
28
+
29
+ async elementEnabled(elementId) {
30
+ return (await this.getAttribute('enabled', elementId)) === 'true';
31
+ },
32
+
33
+ async elementSelected(elementId) {
34
+ return (await this.getAttribute('selected', elementId)) === 'true';
35
+ },
36
+
37
+ async setElementValue(keys, elementId, replace = false) {
38
+ let text = keys;
39
+ if (keys instanceof Array) {
40
+ text = keys.join('');
100
41
  }
101
- });
102
- };
103
-
104
- commands.click = async function click (elementId) {
105
- return await this.bootstrap.sendAction('element:click', {elementId});
106
- };
107
-
108
- commands.getLocation = async function getLocation (elementId) {
109
- return await this.bootstrap.sendAction('element:getLocation', {elementId});
110
- };
111
-
112
- commands.getLocationInView = async function getLocationInView (elementId) {
113
- return await this.getLocation(elementId);
114
- };
115
-
116
- commands.getSize = async function getSize (elementId) {
117
- return await this.bootstrap.sendAction('element:getSize', {elementId});
118
- };
119
-
120
- commands.getElementRect = async function getElementRect (elementId) {
121
- return await this.bootstrap.sendAction('element:getRect', {elementId});
122
- };
123
-
124
- commands.touchLongClick = async function touchLongClick (elementId, x, y, duration) {
125
- let params = {elementId, x, y, duration};
126
- androidHelpers.removeNullProperties(params);
127
- return await this.bootstrap.sendAction('element:touchLongClick', params);
128
- };
129
-
130
- commands.touchDown = async function touchDown (elementId, x, y) {
131
- let params = {elementId, x, y};
132
- androidHelpers.removeNullProperties(params);
133
- return await this.bootstrap.sendAction('element:touchDown', params);
134
- };
135
42
 
136
- commands.touchUp = async function touchUp (elementId, x, y) {
137
- let params = {elementId, x, y};
138
- androidHelpers.removeNullProperties(params);
139
- return await this.bootstrap.sendAction('element:touchUp', params);
140
- };
43
+ let params = {
44
+ elementId,
45
+ text: String(text),
46
+ replace,
47
+ unicodeKeyboard: this.opts.unicodeKeyboard,
48
+ };
49
+
50
+ return await this.doSetElementValue(params);
51
+ },
52
+
53
+ /**
54
+ * Reason for isolating doSetElementValue from setElementValue is for reusing setElementValue
55
+ * across android-drivers (like appium-uiautomator2-driver) and to avoid code duplication.
56
+ * Other android-drivers (like appium-uiautomator2-driver) need to override doSetElementValue
57
+ * to facilitate setElementValue.
58
+ */
59
+ async doSetElementValue(params) {
60
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
61
+ 'element:setText',
62
+ params
63
+ );
64
+ },
65
+
66
+ async setValue(keys, elementId) {
67
+ return await this.setElementValue(keys, elementId, false);
68
+ },
69
+
70
+ async replaceValue(keys, elementId) {
71
+ return await this.setElementValue(keys, elementId, true);
72
+ },
73
+
74
+ async setValueImmediate(keys, elementId) {
75
+ let text = keys;
76
+ if (keys instanceof Array) {
77
+ text = keys.join('');
78
+ }
141
79
 
142
- commands.touchMove = async function touchMove (elementId, x, y) {
143
- let params = {elementId, x, y};
144
- androidHelpers.removeNullProperties(params);
145
- return await this.bootstrap.sendAction('element:touchMove', params);
80
+ // first, make sure we are focused on the element
81
+ await this.click(elementId);
82
+
83
+ // then send through adb
84
+ await /** @type {ADB} */ (this.adb).inputText(/** @type {string} */ (text));
85
+ },
86
+
87
+ async getText(elementId) {
88
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:getText', {
89
+ elementId,
90
+ });
91
+ },
92
+
93
+ async clear(elementId) {
94
+ let text = (await this.getText(elementId)) || '';
95
+ let length = text.length;
96
+ if (length === 0) {
97
+ // if length is zero there are two possibilities:
98
+ // 1. there is nothing in the text field
99
+ // 2. it is a password field
100
+ // since there is little overhead to the adb call, delete 100 elements
101
+ // if we get zero, just in case it is #2
102
+ length = 100;
103
+ }
104
+ await this.click(elementId);
105
+ this.log.debug(`Sending up to ${length} clear characters to device`);
106
+ await retryInterval(5, 500, async () => {
107
+ let remainingLength = length;
108
+ while (remainingLength > 0) {
109
+ let lengthToSend = remainingLength < 50 ? remainingLength : 50;
110
+ this.log.debug(`Sending ${lengthToSend} clear characters to device`);
111
+ await /** @type {ADB} */ (this.adb).clearTextField(lengthToSend);
112
+ remainingLength -= lengthToSend;
113
+ }
114
+ });
115
+ },
116
+
117
+ async click(elementId) {
118
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:click', {
119
+ elementId,
120
+ });
121
+ },
122
+
123
+ async getLocation(elementId) {
124
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
125
+ 'element:getLocation',
126
+ {elementId}
127
+ );
128
+ },
129
+
130
+ async getLocationInView(elementId) {
131
+ return await this.getLocation(elementId);
132
+ },
133
+
134
+ async getSize(elementId) {
135
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:getSize', {
136
+ elementId,
137
+ });
138
+ },
139
+
140
+ async getElementRect(elementId) {
141
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:getRect', {
142
+ elementId,
143
+ });
144
+ },
145
+
146
+ async touchLongClick(elementId, x, y, duration) {
147
+ let params = {elementId, x, y, duration};
148
+ androidHelpers.removeNullProperties(params);
149
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
150
+ 'element:touchLongClick',
151
+ params
152
+ );
153
+ },
154
+
155
+ async touchDown(elementId, x, y) {
156
+ let params = {elementId, x, y};
157
+ androidHelpers.removeNullProperties(params);
158
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
159
+ 'element:touchDown',
160
+ params
161
+ );
162
+ },
163
+
164
+ async touchUp(elementId, x, y) {
165
+ let params = {elementId, x, y};
166
+ androidHelpers.removeNullProperties(params);
167
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
168
+ 'element:touchUp',
169
+ params
170
+ );
171
+ },
172
+
173
+ async touchMove(elementId, x, y) {
174
+ let params = {elementId, x, y};
175
+ androidHelpers.removeNullProperties(params);
176
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction(
177
+ 'element:touchMove',
178
+ params
179
+ );
180
+ },
181
+
182
+ async complexTap(tapCount, touchCount, duration, x, y) {
183
+ return await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('click', {x, y});
184
+ },
185
+
186
+ async tap(elementId = null, x = null, y = null, count = 1) {
187
+ if (!util.hasValue(elementId) && !util.hasValue(x) && !util.hasValue(y)) {
188
+ throw new Error(`Either element to tap or both absolute coordinates should be defined`);
189
+ }
190
+ for (let i = 0; i < count; i++) {
191
+ if (util.hasValue(elementId)) {
192
+ // FIXME: bootstrap ignores relative coordinates
193
+ await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('element:click', {
194
+ elementId,
195
+ x,
196
+ y,
197
+ });
198
+ } else {
199
+ await /** @type {AndroidBootstrap} */ (this.bootstrap).sendAction('click', {x, y});
200
+ }
201
+ }
202
+ },
146
203
  };
147
204
 
148
- commands.complexTap = async function complexTap (tapCount, touchCount, duration, x, y) {
149
- return await this.bootstrap.sendAction('click', {x, y});
150
- };
205
+ mixin(ElementMixin);
151
206
 
152
- commands.tap = async function (elementId = null, x = null, y = null, count = 1) {
153
- if (!util.hasValue(elementId) && !util.hasValue(x) && !util.hasValue(y)) {
154
- throw new Error(`Either element to tap or both absolute coordinates should be defined`);
155
- }
156
- for (let i = 0; i < count; i++) {
157
- if (util.hasValue(elementId)) {
158
- // FIXME: bootstrap ignores relative coordinates
159
- await this.bootstrap.sendAction('element:click', {elementId, x, y});
160
- } else {
161
- await this.bootstrap.sendAction('click', {x, y});
162
- }
163
- }
164
- };
207
+ export default ElementMixin;
165
208
 
166
- Object.assign(extensions, commands, helpers);
167
- export { commands, helpers };
168
- export default extensions;
209
+ /**
210
+ * @typedef {import('../bootstrap').AndroidBootstrap} AndroidBootstrap
211
+ * @typedef {import('appium-adb').ADB} ADB
212
+ */
@@ -1,51 +1,31 @@
1
- import { errors } from 'appium/driver';
1
+ // @ts-check
2
2
 
3
- const EMU_CONSOLE_FEATURE = 'emulator_console';
4
-
5
- const commands = {};
6
-
7
- /**
8
- * @typedef {Object} ExecOptions
9
- * @property {!Array<string>|string} command - The actual command to execute. See
10
- * https://developer.android.com/studio/run/emulator-console for more details
11
- * on available commands
12
- * @property {number} execTimeout [60000] A timeout used to wait for a server
13
- * reply to the given command in milliseconds
14
- * @property {number} connTimeout [5000] Console connection timeout in milliseconds
15
- * @property {number} initTimeout [5000] Telnet console initialization timeout
16
- * in milliseconds (the time between the connection happens and the command prompt
17
- * is available)
18
- */
3
+ import {mixin} from './mixins';
4
+ import {errors} from 'appium/driver';
19
5
 
6
+ const EMU_CONSOLE_FEATURE = 'emulator_console';
20
7
  /**
21
- * Executes a command through emulator telnet console interface and returns its output.
22
- * The `emulator_console` server feature must be enabled in order to use this method.
23
- *
24
- * @param {ExecOptions} opts
25
- * @returns {string} The command output
26
- * @throws {Error} If there was an error while connecting to the Telnet console
27
- * or if the given command returned non-OK response
8
+ * @type {import('./mixins').EmulatorConsoleMixin & ThisType<import('../driver').AndroidDriver>}
9
+ * @satisfies {import('@appium/types').ExternalDriver}
28
10
  */
29
- commands.mobileExecEmuConsoleCommand = async function mobileExecEmuConsoleCommand (opts = {}) {
30
- this.ensureFeatureEnabled(EMU_CONSOLE_FEATURE);
31
-
32
- const {
33
- command,
34
- execTimeout,
35
- connTimeout,
36
- initTimeout,
37
- } = opts;
38
-
39
- if (!command) {
40
- throw new errors.InvalidArgumentError(`The 'command' argument is mandatory`);
41
- }
42
-
43
- return await this.adb.execEmuConsoleCommand(command, {
44
- execTimeout,
45
- connTimeout,
46
- initTimeout,
47
- });
11
+ const EmulatorConsoleMixin = {
12
+ async mobileExecEmuConsoleCommand(opts) {
13
+ this.ensureFeatureEnabled(EMU_CONSOLE_FEATURE);
14
+
15
+ const {command, execTimeout, connTimeout, initTimeout} = opts;
16
+
17
+ if (!command) {
18
+ throw new errors.InvalidArgumentError(`The 'command' argument is mandatory`);
19
+ }
20
+
21
+ return await /** @type {import('appium-adb').ADB} */ (this.adb).execEmuConsoleCommand(command, {
22
+ execTimeout,
23
+ connTimeout,
24
+ initTimeout,
25
+ });
26
+ },
48
27
  };
49
28
 
50
- export { commands };
51
- export default commands;
29
+ mixin(EmulatorConsoleMixin);
30
+
31
+ export default EmulatorConsoleMixin;
@@ -1,95 +1,111 @@
1
+ // @ts-check
2
+
1
3
  import _ from 'lodash';
2
4
  import {errors, PROTOCOLS} from 'appium/driver';
3
-
4
- const extensions = {};
5
-
6
- extensions.execute = async function execute(script, args) {
7
- if (script.match(/^mobile:/)) {
8
- this.log.info(`Executing native command '${script}'`);
9
- script = script.replace(/^mobile:/, '').trim();
10
- return await this.executeMobile(script, _.isArray(args) ? args[0] : args);
11
- }
12
- if (!this.isWebContext()) {
13
- throw new errors.NotImplementedError();
14
- }
15
- const endpoint =
16
- this.chromedriver.jwproxy.downstreamProtocol === PROTOCOLS.MJSONWP
17
- ? '/execute'
18
- : '/execute/sync';
19
- return await this.chromedriver.jwproxy.command(endpoint, 'POST', {
20
- script,
21
- args,
22
- });
5
+ import {mixin} from './mixins';
6
+
7
+ /**
8
+ * @type {import('./mixins').ExecuteMixin & ThisType<import('../driver').AndroidDriver>}
9
+ * @satisfies {import('@appium/types').ExternalDriver}
10
+ */
11
+ const ExecuteMixin = {
12
+ async execute(script, args) {
13
+ if (script.match(/^mobile:/)) {
14
+ this.log.info(`Executing native command '${script}'`);
15
+ script = script.replace(/^mobile:/, '').trim();
16
+ return await this.executeMobile(
17
+ script,
18
+ _.isArray(args) ? /** @type {import('@appium/types').StringRecord} */ (args[0]) : args
19
+ );
20
+ }
21
+ if (!this.isWebContext()) {
22
+ throw new errors.NotImplementedError();
23
+ }
24
+ const endpoint =
25
+ /** @type {import('appium-chromedriver').Chromedriver} */ (this.chromedriver).jwproxy
26
+ .downstreamProtocol === PROTOCOLS.MJSONWP
27
+ ? '/execute'
28
+ : '/execute/sync';
29
+ return await /** @type {import('appium-chromedriver').Chromedriver} */ (
30
+ this.chromedriver
31
+ ).jwproxy.command(endpoint, 'POST', {
32
+ script,
33
+ args,
34
+ });
35
+ },
36
+
37
+ async executeMobile(mobileCommand, opts = {}) {
38
+ const mobileCommandsMapping = {
39
+ shell: 'mobileShell',
40
+
41
+ execEmuConsoleCommand: 'mobileExecEmuConsoleCommand',
42
+
43
+ startLogsBroadcast: 'mobileStartLogsBroadcast',
44
+ stopLogsBroadcast: 'mobileStopLogsBroadcast',
45
+
46
+ changePermissions: 'mobileChangePermissions',
47
+ getPermissions: 'mobileGetPermissions',
48
+
49
+ performEditorAction: 'mobilePerformEditorAction',
50
+
51
+ sensorSet: 'sensorSet',
52
+
53
+ getDeviceTime: 'mobileGetDeviceTime',
54
+
55
+ startScreenStreaming: 'mobileStartScreenStreaming',
56
+ stopScreenStreaming: 'mobileStopScreenStreaming',
57
+
58
+ getNotifications: 'mobileGetNotifications',
59
+
60
+ listSms: 'mobileListSms',
61
+
62
+ pushFile: 'mobilePushFile',
63
+ pullFile: 'mobilePullFile',
64
+ pullFolder: 'mobilePullFolder',
65
+ deleteFile: 'mobileDeleteFile',
66
+
67
+ isAppInstalled: 'mobileIsAppInstalled',
68
+ queryAppState: 'mobileQueryAppState',
69
+ activateApp: 'mobileActivateApp',
70
+ removeApp: 'mobileRemoveApp',
71
+ terminateApp: 'mobileTerminateApp',
72
+ installApp: 'mobileInstallApp',
73
+ clearApp: 'mobileClearApp',
74
+
75
+ startService: 'mobileStartService',
76
+ stopService: 'mobileStopService',
77
+ startActivity: 'mobileStartActivity',
78
+ broadcast: 'mobileBroadcast',
79
+
80
+ getContexts: 'mobileGetContexts',
81
+
82
+ lock: 'mobileLock',
83
+ unlock: 'mobileUnlock',
84
+
85
+ refreshGpsCache: 'mobileRefreshGpsCache',
86
+
87
+ startMediaProjectionRecording: 'mobileStartMediaProjectionRecording',
88
+ isMediaProjectionRecordingRunning: 'mobileIsMediaProjectionRecordingRunning',
89
+ stopMediaProjectionRecording: 'mobileStopMediaProjectionRecording',
90
+
91
+ getConnectivity: 'mobileGetConnectivity',
92
+ setConnectivity: 'mobileSetConnectivity',
93
+
94
+ hideKeyboard: 'hideKeyboard',
95
+ isKeyboardShown: 'isKeyboardShown',
96
+ };
97
+
98
+ if (!_.has(mobileCommandsMapping, mobileCommand)) {
99
+ throw new errors.UnknownCommandError(
100
+ `Unknown mobile command "${mobileCommand}". ` +
101
+ `Only ${_.keys(mobileCommandsMapping)} commands are supported.`
102
+ );
103
+ }
104
+ // @ts-expect-error fine for now until we replace with execute methods
105
+ return await this[mobileCommandsMapping[mobileCommand]](opts);
106
+ },
23
107
  };
24
108
 
25
- extensions.executeMobile = async function executeMobile(mobileCommand, opts = {}) {
26
- const mobileCommandsMapping = {
27
- shell: 'mobileShell',
28
-
29
- execEmuConsoleCommand: 'mobileExecEmuConsoleCommand',
30
-
31
- startLogsBroadcast: 'mobileStartLogsBroadcast',
32
- stopLogsBroadcast: 'mobileStopLogsBroadcast',
33
-
34
- changePermissions: 'mobileChangePermissions',
35
- getPermissions: 'mobileGetPermissions',
36
-
37
- performEditorAction: 'mobilePerformEditorAction',
38
-
39
- sensorSet: 'sensorSet',
40
-
41
- getDeviceTime: 'mobileGetDeviceTime',
42
-
43
- startScreenStreaming: 'mobileStartScreenStreaming',
44
- stopScreenStreaming: 'mobileStopScreenStreaming',
45
-
46
- getNotifications: 'mobileGetNotifications',
47
-
48
- listSms: 'mobileListSms',
49
-
50
- pushFile: 'mobilePushFile',
51
- pullFile: 'mobilePullFile',
52
- pullFolder: 'mobilePullFolder',
53
- deleteFile: 'mobileDeleteFile',
54
-
55
- isAppInstalled: 'mobileIsAppInstalled',
56
- queryAppState: 'mobileQueryAppState',
57
- activateApp: 'mobileActivateApp',
58
- removeApp: 'mobileRemoveApp',
59
- terminateApp: 'mobileTerminateApp',
60
- installApp: 'mobileInstallApp',
61
- clearApp: 'mobileClearApp',
62
-
63
- startService: 'mobileStartService',
64
- stopService: 'mobileStopService',
65
- startActivity: 'mobileStartActivity',
66
- broadcast: 'mobileBroadcast',
67
-
68
- getContexts: 'mobileGetContexts',
69
-
70
- lock: 'mobileLock',
71
- unlock: 'mobileUnlock',
72
-
73
- refreshGpsCache: 'mobileRefreshGpsCache',
74
-
75
- startMediaProjectionRecording: 'mobileStartMediaProjectionRecording',
76
- isMediaProjectionRecordingRunning: 'mobileIsMediaProjectionRecordingRunning',
77
- stopMediaProjectionRecording: 'mobileStopMediaProjectionRecording',
78
-
79
- getConnectivity: 'mobileGetConnectivity',
80
- setConnectivity: 'mobileSetConnectivity',
81
-
82
- hideKeyboard: 'hideKeyboard',
83
- isKeyboardShown: 'isKeyboardShown',
84
- };
85
-
86
- if (!_.has(mobileCommandsMapping, mobileCommand)) {
87
- throw new errors.UnknownCommandError(
88
- `Unknown mobile command "${mobileCommand}". ` +
89
- `Only ${_.keys(mobileCommandsMapping)} commands are supported.`
90
- );
91
- }
92
- return await this[mobileCommandsMapping[mobileCommand]](opts);
93
- };
109
+ mixin(ExecuteMixin);
94
110
 
95
- export default extensions;
111
+ export default ExecuteMixin;