appium-android-driver 5.14.7 → 6.0.1

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 (210) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/build/lib/commands/actions.d.ts +6 -224
  3. package/build/lib/commands/actions.d.ts.map +1 -1
  4. package/build/lib/commands/actions.js +306 -405
  5. package/build/lib/commands/actions.js.map +1 -1
  6. package/build/lib/commands/alert.d.ts +7 -9
  7. package/build/lib/commands/alert.d.ts.map +1 -1
  8. package/build/lib/commands/alert.js +24 -18
  9. package/build/lib/commands/alert.js.map +1 -1
  10. package/build/lib/commands/app-management.d.ts +7 -313
  11. package/build/lib/commands/app-management.d.ts.map +1 -1
  12. package/build/lib/commands/app-management.js +135 -293
  13. package/build/lib/commands/app-management.js.map +1 -1
  14. package/build/lib/commands/context.d.ts +8 -92
  15. package/build/lib/commands/context.d.ts.map +1 -1
  16. package/build/lib/commands/context.js +381 -439
  17. package/build/lib/commands/context.js.map +1 -1
  18. package/build/lib/commands/element.d.ts +8 -35
  19. package/build/lib/commands/element.d.ts.map +1 -1
  20. package/build/lib/commands/element.js +153 -136
  21. package/build/lib/commands/element.js.map +1 -1
  22. package/build/lib/commands/emu-console.d.ts +6 -48
  23. package/build/lib/commands/emu-console.d.ts.map +1 -1
  24. package/build/lib/commands/emu-console.js +19 -34
  25. package/build/lib/commands/emu-console.js.map +1 -1
  26. package/build/lib/commands/execute.d.ts +6 -5
  27. package/build/lib/commands/execute.d.ts.map +1 -1
  28. package/build/lib/commands/execute.js +77 -66
  29. package/build/lib/commands/execute.js.map +1 -1
  30. package/build/lib/commands/file-actions.d.ts +7 -128
  31. package/build/lib/commands/file-actions.d.ts.map +1 -1
  32. package/build/lib/commands/file-actions.js +183 -219
  33. package/build/lib/commands/file-actions.js.map +1 -1
  34. package/build/lib/commands/find.d.ts +8 -12
  35. package/build/lib/commands/find.d.ts.map +1 -1
  36. package/build/lib/commands/find.js +19 -23
  37. package/build/lib/commands/find.js.map +1 -1
  38. package/build/lib/commands/general.d.ts +9 -132
  39. package/build/lib/commands/general.d.ts.map +1 -1
  40. package/build/lib/commands/general.js +281 -312
  41. package/build/lib/commands/general.js.map +1 -1
  42. package/build/lib/commands/ime.d.ts +7 -10
  43. package/build/lib/commands/ime.d.ts.map +1 -1
  44. package/build/lib/commands/ime.js +47 -35
  45. package/build/lib/commands/ime.js.map +1 -1
  46. package/build/lib/commands/index.d.ts +27 -2
  47. package/build/lib/commands/index.d.ts.map +1 -1
  48. package/build/lib/commands/index.js +41 -19
  49. package/build/lib/commands/index.js.map +1 -1
  50. package/build/lib/commands/intent.d.ts +7 -417
  51. package/build/lib/commands/intent.d.ts.map +1 -1
  52. package/build/lib/commands/intent.js +104 -216
  53. package/build/lib/commands/intent.js.map +1 -1
  54. package/build/lib/commands/keyboard.d.ts +6 -5
  55. package/build/lib/commands/keyboard.d.ts.map +1 -1
  56. package/build/lib/commands/keyboard.js +16 -8
  57. package/build/lib/commands/keyboard.js.map +1 -1
  58. package/build/lib/commands/log.d.ts +7 -44
  59. package/build/lib/commands/log.d.ts.map +1 -1
  60. package/build/lib/commands/log.js +146 -108
  61. package/build/lib/commands/log.js.map +1 -1
  62. package/build/lib/commands/media-projection.d.ts +7 -143
  63. package/build/lib/commands/media-projection.d.ts.map +1 -1
  64. package/build/lib/commands/media-projection.js +113 -140
  65. package/build/lib/commands/media-projection.js.map +1 -1
  66. package/build/lib/commands/mixins.d.ts +740 -0
  67. package/build/lib/commands/mixins.d.ts.map +1 -0
  68. package/build/lib/commands/mixins.js +19 -0
  69. package/build/lib/commands/mixins.js.map +1 -0
  70. package/build/lib/commands/network.d.ts +7 -138
  71. package/build/lib/commands/network.d.ts.map +1 -1
  72. package/build/lib/commands/network.js +212 -254
  73. package/build/lib/commands/network.js.map +1 -1
  74. package/build/lib/commands/performance.d.ts +24 -70
  75. package/build/lib/commands/performance.d.ts.map +1 -1
  76. package/build/lib/commands/performance.js +144 -100
  77. package/build/lib/commands/performance.js.map +1 -1
  78. package/build/lib/commands/permissions.d.ts +8 -92
  79. package/build/lib/commands/permissions.d.ts.map +1 -1
  80. package/build/lib/commands/permissions.js +75 -87
  81. package/build/lib/commands/permissions.js.map +1 -1
  82. package/build/lib/commands/recordscreen.d.ts +7 -193
  83. package/build/lib/commands/recordscreen.d.ts.map +1 -1
  84. package/build/lib/commands/recordscreen.js +151 -182
  85. package/build/lib/commands/recordscreen.js.map +1 -1
  86. package/build/lib/commands/shell.d.ts +7 -7
  87. package/build/lib/commands/shell.d.ts.map +1 -1
  88. package/build/lib/commands/shell.js +40 -33
  89. package/build/lib/commands/shell.js.map +1 -1
  90. package/build/lib/commands/streamscreen.d.ts +9 -103
  91. package/build/lib/commands/streamscreen.d.ts.map +1 -1
  92. package/build/lib/commands/streamscreen.js +261 -218
  93. package/build/lib/commands/streamscreen.js.map +1 -1
  94. package/build/lib/commands/system-bars.d.ts +22 -90
  95. package/build/lib/commands/system-bars.d.ts.map +1 -1
  96. package/build/lib/commands/system-bars.js +76 -74
  97. package/build/lib/commands/system-bars.js.map +1 -1
  98. package/build/lib/commands/touch.d.ts +10 -29
  99. package/build/lib/commands/touch.d.ts.map +1 -1
  100. package/build/lib/commands/touch.js +301 -285
  101. package/build/lib/commands/touch.js.map +1 -1
  102. package/build/lib/commands/types.d.ts +978 -0
  103. package/build/lib/commands/types.d.ts.map +1 -0
  104. package/build/lib/commands/types.js +3 -0
  105. package/build/lib/commands/types.js.map +1 -0
  106. package/build/lib/constraints.d.ts +291 -0
  107. package/build/lib/constraints.d.ts.map +1 -0
  108. package/build/lib/{desired-caps.js → constraints.js} +103 -102
  109. package/build/lib/constraints.js.map +1 -0
  110. package/build/lib/driver.d.ts +68 -37
  111. package/build/lib/driver.d.ts.map +1 -1
  112. package/build/lib/driver.js +123 -80
  113. package/build/lib/driver.js.map +1 -1
  114. package/build/lib/helpers/android.d.ts +164 -0
  115. package/build/lib/helpers/android.d.ts.map +1 -0
  116. package/build/lib/helpers/android.js +819 -0
  117. package/build/lib/helpers/android.js.map +1 -0
  118. package/build/lib/helpers/index.d.ts +7 -0
  119. package/build/lib/helpers/index.d.ts.map +1 -0
  120. package/build/lib/helpers/index.js +29 -0
  121. package/build/lib/helpers/index.js.map +1 -0
  122. package/build/lib/helpers/types.d.ts +121 -0
  123. package/build/lib/helpers/types.d.ts.map +1 -0
  124. package/build/lib/helpers/types.js +3 -0
  125. package/build/lib/helpers/types.js.map +1 -0
  126. package/build/lib/helpers/unlock.d.ts +32 -0
  127. package/build/lib/helpers/unlock.d.ts.map +1 -0
  128. package/build/lib/helpers/unlock.js +273 -0
  129. package/build/lib/helpers/unlock.js.map +1 -0
  130. package/build/lib/helpers/webview.d.ts +74 -0
  131. package/build/lib/helpers/webview.d.ts.map +1 -0
  132. package/build/lib/helpers/webview.js +421 -0
  133. package/build/lib/helpers/webview.js.map +1 -0
  134. package/build/lib/index.d.ts +9 -0
  135. package/build/lib/index.d.ts.map +1 -0
  136. package/build/lib/index.js +37 -0
  137. package/build/lib/index.js.map +1 -0
  138. package/build/lib/method-map.d.ts +0 -8
  139. package/build/lib/method-map.d.ts.map +1 -1
  140. package/build/lib/method-map.js +63 -74
  141. package/build/lib/method-map.js.map +1 -1
  142. package/build/lib/stubs.d.ts +0 -1
  143. package/build/lib/stubs.d.ts.map +1 -1
  144. package/build/lib/stubs.js +1 -0
  145. package/build/lib/stubs.js.map +1 -1
  146. package/build/lib/utils.d.ts +1 -1
  147. package/build/lib/utils.d.ts.map +1 -1
  148. package/lib/commands/actions.js +351 -464
  149. package/lib/commands/alert.js +27 -17
  150. package/lib/commands/app-management.js +156 -314
  151. package/lib/commands/context.js +457 -441
  152. package/lib/commands/element.js +201 -157
  153. package/lib/commands/emu-console.js +25 -45
  154. package/lib/commands/execute.js +106 -90
  155. package/lib/commands/file-actions.js +222 -240
  156. package/lib/commands/find.ts +103 -0
  157. package/lib/commands/general.js +327 -339
  158. package/lib/commands/ime.js +50 -34
  159. package/lib/commands/{index.js → index.ts} +20 -24
  160. package/lib/commands/intent.js +108 -249
  161. package/lib/commands/keyboard.js +20 -8
  162. package/lib/commands/log.js +172 -116
  163. package/lib/commands/media-projection.js +134 -161
  164. package/lib/commands/mixins.ts +966 -0
  165. package/lib/commands/network.js +252 -281
  166. package/lib/commands/performance.js +203 -132
  167. package/lib/commands/permissions.js +108 -109
  168. package/lib/commands/recordscreen.js +212 -209
  169. package/lib/commands/shell.js +51 -40
  170. package/lib/commands/streamscreen.js +355 -289
  171. package/lib/commands/system-bars.js +92 -83
  172. package/lib/commands/touch.js +357 -294
  173. package/lib/commands/types.ts +1097 -0
  174. package/lib/{desired-caps.js → constraints.ts} +106 -103
  175. package/lib/{driver.js → driver.ts} +278 -132
  176. package/lib/helpers/android.ts +1143 -0
  177. package/lib/helpers/index.ts +6 -0
  178. package/lib/helpers/types.ts +134 -0
  179. package/lib/helpers/unlock.ts +329 -0
  180. package/lib/helpers/webview.ts +582 -0
  181. package/lib/index.ts +18 -0
  182. package/lib/method-map.js +87 -98
  183. package/lib/stubs.ts +0 -1
  184. package/package.json +26 -19
  185. package/build/index.js +0 -51
  186. package/build/lib/android-helpers.d.ts +0 -136
  187. package/build/lib/android-helpers.d.ts.map +0 -1
  188. package/build/lib/android-helpers.js +0 -855
  189. package/build/lib/android-helpers.js.map +0 -1
  190. package/build/lib/commands/coverage.d.ts +0 -5
  191. package/build/lib/commands/coverage.d.ts.map +0 -1
  192. package/build/lib/commands/coverage.js +0 -19
  193. package/build/lib/commands/coverage.js.map +0 -1
  194. package/build/lib/desired-caps.d.ts +0 -353
  195. package/build/lib/desired-caps.d.ts.map +0 -1
  196. package/build/lib/desired-caps.js.map +0 -1
  197. package/build/lib/unlock-helpers.d.ts +0 -38
  198. package/build/lib/unlock-helpers.d.ts.map +0 -1
  199. package/build/lib/unlock-helpers.js +0 -266
  200. package/build/lib/unlock-helpers.js.map +0 -1
  201. package/build/lib/webview-helpers.d.ts +0 -224
  202. package/build/lib/webview-helpers.d.ts.map +0 -1
  203. package/build/lib/webview-helpers.js +0 -528
  204. package/build/lib/webview-helpers.js.map +0 -1
  205. package/index.js +0 -24
  206. package/lib/android-helpers.js +0 -983
  207. package/lib/commands/coverage.js +0 -18
  208. package/lib/commands/find.js +0 -82
  209. package/lib/unlock-helpers.js +0 -278
  210. 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;