appium-uiautomator2-driver 2.29.11 → 2.31.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 (135) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/index.d.ts +4 -0
  3. package/build/index.d.ts.map +1 -0
  4. package/build/index.js +8 -15
  5. package/build/index.js.map +1 -0
  6. package/build/lib/commands/actions.d.ts +2 -0
  7. package/build/lib/commands/actions.d.ts.map +1 -0
  8. package/build/lib/commands/actions.js +67 -62
  9. package/build/lib/commands/actions.js.map +1 -1
  10. package/build/lib/commands/alert.d.ts +2 -0
  11. package/build/lib/commands/alert.d.ts.map +1 -0
  12. package/build/lib/commands/alert.js +28 -26
  13. package/build/lib/commands/alert.js.map +1 -1
  14. package/build/lib/commands/app-strings.d.ts +3 -0
  15. package/build/lib/commands/app-strings.d.ts.map +1 -0
  16. package/build/lib/commands/app-strings.js +86 -57
  17. package/build/lib/commands/app-strings.js.map +1 -1
  18. package/build/lib/commands/battery.d.ts +2 -0
  19. package/build/lib/commands/battery.d.ts.map +1 -0
  20. package/build/lib/commands/battery.js +26 -16
  21. package/build/lib/commands/battery.js.map +1 -1
  22. package/build/lib/commands/element.d.ts +2 -0
  23. package/build/lib/commands/element.d.ts.map +1 -0
  24. package/build/lib/commands/element.js +140 -159
  25. package/build/lib/commands/element.js.map +1 -1
  26. package/build/lib/commands/find.d.ts +2 -0
  27. package/build/lib/commands/find.d.ts.map +1 -0
  28. package/build/lib/commands/find.js +39 -25
  29. package/build/lib/commands/find.js.map +1 -1
  30. package/build/lib/commands/general.d.ts +4 -0
  31. package/build/lib/commands/general.d.ts.map +1 -0
  32. package/build/lib/commands/general.js +209 -215
  33. package/build/lib/commands/general.js.map +1 -1
  34. package/build/lib/commands/gestures.d.ts +2 -0
  35. package/build/lib/commands/gestures.d.ts.map +1 -0
  36. package/build/lib/commands/gestures.js +206 -193
  37. package/build/lib/commands/gestures.js.map +1 -1
  38. package/build/lib/commands/index.d.ts +2 -0
  39. package/build/lib/commands/index.d.ts.map +1 -0
  40. package/build/lib/commands/index.js +13 -22
  41. package/build/lib/commands/index.js.map +1 -1
  42. package/build/lib/commands/mixins.d.ts +87 -0
  43. package/build/lib/commands/mixins.d.ts.map +1 -0
  44. package/build/lib/commands/mixins.js +26 -0
  45. package/build/lib/commands/mixins.js.map +1 -0
  46. package/build/lib/commands/screenshot.d.ts +2 -0
  47. package/build/lib/commands/screenshot.d.ts.map +1 -0
  48. package/build/lib/commands/screenshot.js +77 -62
  49. package/build/lib/commands/screenshot.js.map +1 -1
  50. package/build/lib/commands/touch.d.ts +2 -0
  51. package/build/lib/commands/touch.d.ts.map +1 -0
  52. package/build/lib/commands/touch.js +48 -38
  53. package/build/lib/commands/touch.js.map +1 -1
  54. package/build/lib/commands/types.d.ts +452 -0
  55. package/build/lib/commands/types.d.ts.map +1 -0
  56. package/build/lib/commands/types.js +3 -0
  57. package/build/lib/commands/types.js.map +1 -0
  58. package/build/lib/commands/viewport.d.ts +2 -0
  59. package/build/lib/commands/viewport.d.ts.map +1 -0
  60. package/build/lib/commands/viewport.js +37 -35
  61. package/build/lib/commands/viewport.js.map +1 -1
  62. package/build/lib/constraints.d.ts +325 -0
  63. package/build/lib/constraints.d.ts.map +1 -0
  64. package/build/lib/constraints.js +51 -0
  65. package/build/lib/constraints.js.map +1 -0
  66. package/build/lib/css-converter.d.ts +45 -0
  67. package/build/lib/css-converter.d.ts.map +1 -0
  68. package/build/lib/css-converter.js +272 -175
  69. package/build/lib/css-converter.js.map +1 -1
  70. package/build/lib/driver.d.ts +904 -0
  71. package/build/lib/driver.d.ts.map +1 -0
  72. package/build/lib/driver.js +726 -485
  73. package/build/lib/driver.js.map +1 -1
  74. package/build/lib/execute-method-map.d.ts +477 -0
  75. package/build/lib/execute-method-map.d.ts.map +1 -0
  76. package/build/lib/execute-method-map.js +542 -0
  77. package/build/lib/execute-method-map.js.map +1 -0
  78. package/build/lib/extensions.d.ts +3 -0
  79. package/build/lib/extensions.d.ts.map +1 -0
  80. package/build/lib/extensions.js +7 -9
  81. package/build/lib/extensions.js.map +1 -1
  82. package/build/lib/helpers.d.ts +7 -0
  83. package/build/lib/helpers.d.ts.map +1 -0
  84. package/build/lib/helpers.js +36 -29
  85. package/build/lib/helpers.js.map +1 -1
  86. package/build/lib/logger.d.ts +3 -0
  87. package/build/lib/logger.d.ts.map +1 -0
  88. package/build/lib/logger.js +5 -10
  89. package/build/lib/logger.js.map +1 -1
  90. package/build/lib/method-map.d.ts +389 -0
  91. package/build/lib/method-map.d.ts.map +1 -0
  92. package/build/lib/method-map.js +11 -17
  93. package/build/lib/method-map.js.map +1 -1
  94. package/build/lib/types.d.ts +44 -0
  95. package/build/lib/types.d.ts.map +1 -0
  96. package/build/lib/types.js +3 -0
  97. package/build/lib/types.js.map +1 -0
  98. package/build/lib/uiautomator2.d.ts +45 -0
  99. package/build/lib/uiautomator2.d.ts.map +1 -0
  100. package/build/lib/uiautomator2.js +340 -299
  101. package/build/lib/uiautomator2.js.map +1 -1
  102. package/build/lib/utils.d.ts +10 -0
  103. package/build/lib/utils.d.ts.map +1 -0
  104. package/build/lib/utils.js +23 -16
  105. package/build/lib/utils.js.map +1 -1
  106. package/build/tsconfig.tsbuildinfo +1 -0
  107. package/index.js +5 -3
  108. package/lib/commands/actions.js +115 -101
  109. package/lib/commands/alert.js +36 -44
  110. package/lib/commands/app-strings.js +79 -58
  111. package/lib/commands/battery.js +27 -28
  112. package/lib/commands/element.js +231 -134
  113. package/lib/commands/find.js +40 -21
  114. package/lib/commands/general.js +262 -336
  115. package/lib/commands/gestures.js +252 -366
  116. package/lib/commands/index.js +11 -31
  117. package/lib/commands/mixins.ts +169 -0
  118. package/lib/commands/screenshot.js +80 -76
  119. package/lib/commands/touch.js +64 -31
  120. package/lib/commands/types.ts +473 -0
  121. package/lib/commands/viewport.js +43 -31
  122. package/lib/constraints.ts +53 -0
  123. package/lib/css-converter.js +9 -1
  124. package/lib/{driver.js → driver.ts} +374 -239
  125. package/lib/execute-method-map.ts +573 -0
  126. package/lib/method-map.ts +11 -0
  127. package/lib/types.ts +57 -0
  128. package/lib/uiautomator2.js +21 -2
  129. package/lib/utils.js +2 -2
  130. package/npm-shrinkwrap.json +395 -528
  131. package/package.json +96 -70
  132. package/build/lib/desired-caps.js +0 -71
  133. package/build/lib/desired-caps.js.map +0 -1
  134. package/lib/desired-caps.js +0 -70
  135. package/lib/method-map.js +0 -11
@@ -1,144 +1,241 @@
1
- import _ from 'lodash';
2
- import { util } from 'appium/support';
3
- import { PROTOCOLS, W3C_ELEMENT_KEY } from 'appium/driver';
4
- import { requireArgs } from '../utils';
1
+ // @ts-check
5
2
 
6
- let commands = {}, helpers = {}, extensions = {};
3
+ import B from 'bluebird';
4
+ import _ from 'lodash';
5
+ import {util} from 'appium/support';
6
+ import {PROTOCOLS, W3C_ELEMENT_KEY} from 'appium/driver';
7
+ import {requireArgs} from '../utils';
8
+ import {mixin} from './mixins';
7
9
 
8
- function toBool (s) {
9
- return _.isString(s) ? (s.toLowerCase() === 'true') : !!s;
10
+ /**
11
+ * @param {any} s
12
+ * @returns {boolean}
13
+ */
14
+ function toBool(s) {
15
+ return _.isString(s) ? s.toLowerCase() === 'true' : !!s;
10
16
  }
11
17
 
12
- commands.active = async function active () {
13
- return await this.uiautomator2.jwproxy.command('/element/active', 'GET');
14
- };
15
-
16
- commands.getAttribute = async function (attribute, elementId) {
17
- return await this.uiautomator2.jwproxy.command(`/element/${elementId}/attribute/${attribute}`, 'GET', {});
18
- };
19
-
20
- commands.elementDisplayed = async function (elementId) {
21
- return toBool(await this.getAttribute('displayed', elementId));
22
- };
23
-
24
- commands.elementEnabled = async function (elementId) {
25
- return toBool(await this.getAttribute('enabled', elementId));
26
- };
27
-
28
- commands.elementSelected = async function (elementId) {
29
- return toBool(await this.getAttribute('selected', elementId));
30
- };
31
-
32
- commands.getName = async function (elementId) {
33
- return await this.uiautomator2.jwproxy.command(`/element/${elementId}/name`, 'GET', {});
34
- };
35
-
36
- commands.getLocation = async function (elementId) {
37
- return await this.uiautomator2.jwproxy.command(`/element/${elementId}/location`, 'GET', {});
38
- };
39
-
40
- commands.getSize = async function (elementId) {
41
- return await this.uiautomator2.jwproxy.command(`/element/${elementId}/size`, 'GET', {});
42
- };
43
-
44
- commands.touchLongClick = async function (element, x, y, duration) {
45
- let params = {element, x, y, duration};
46
- return await this.uiautomator2.jwproxy.command(`/touch/longclick`, 'POST', {params});
47
- };
48
-
49
- commands.touchDown = async function (element, x, y) {
50
- let params = {element, x, y};
51
- return await this.uiautomator2.jwproxy.command(`/touch/down`, 'POST', {params});
52
- };
53
-
54
- commands.touchUp = async function (element, x, y) {
55
- let params = {element, x, y};
56
- return await this.uiautomator2.jwproxy.command(`/touch/up`, 'POST', {params});
57
- };
58
-
59
- commands.touchMove = async function (element, x, y) {
60
- let params = {element, x, y};
61
- return await this.uiautomator2.jwproxy.command(`/touch/move`, 'POST', {params});
62
- };
63
-
64
- helpers.doSetElementValue = async function (params) {
65
- return await this.uiautomator2.jwproxy.command(`/element/${params.elementId}/value`, 'POST', params);
66
- };
67
-
68
- commands.setValueImmediate = async function (keys, elementId) {
69
- return await this.uiautomator2.jwproxy.command(`/element/${elementId}/value`, 'POST', {
70
- elementId,
71
- text: _.isArray(keys) ? keys.join('') : keys,
72
- replace: false
73
- });
74
- };
75
-
76
- commands.getText = async function (elementId) {
77
- return await this.uiautomator2.jwproxy.command(`/element/${elementId}/text`, 'GET', {});
78
- };
79
-
80
- commands.click = async function (element) {
81
- return await this.uiautomator2.jwproxy.command(`/element/${element}/click`, 'POST', {element});
82
- };
83
-
84
- commands.getElementScreenshot = async function (element) {
85
- return await this.uiautomator2.jwproxy.command(`/element/${element}/screenshot`, 'GET', {});
86
- };
87
-
88
- commands.tap = async function (elementId = null, x = null, y = null, count = 1) {
89
- const areCoordinatesDefined = util.hasValue(x) && util.hasValue(y);
90
- if (!util.hasValue(elementId) && !areCoordinatesDefined) {
91
- throw new Error(`Either element id to tap or both absolute coordinates should be defined`);
92
- }
93
-
94
- for (let i = 0; i < count; i++) {
95
- if (util.hasValue(elementId) && !areCoordinatesDefined) {
96
- // we are either tapping on the default location of the element
97
- // or an offset from the top left corner
98
- await this.uiautomator2.jwproxy.command(`/element/${elementId}/click`, 'POST');
99
- } else {
100
- await this.uiautomator2.jwproxy.command(`/appium/tap`, 'POST', {
101
- x, y,
102
- [W3C_ELEMENT_KEY]: elementId,
103
- });
18
+ /**
19
+ * @type {import('./mixins').UIA2ElementMixin}
20
+ * @satisfies {import('@appium/types').ExternalDriver}
21
+ */
22
+ const ElementMixin = {
23
+ async active() {
24
+ return /** @type {import('@appium/types').Element} */ (
25
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
26
+ '/element/active',
27
+ 'GET'
28
+ )
29
+ );
30
+ },
31
+ async getAttribute(attribute, elementId) {
32
+ return String(
33
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
34
+ `/element/${elementId}/attribute/${attribute}`,
35
+ 'GET',
36
+ {}
37
+ )
38
+ );
39
+ },
40
+ async elementDisplayed(elementId) {
41
+ return toBool(await this.getAttribute('displayed', elementId));
42
+ },
43
+ async elementEnabled(elementId) {
44
+ return toBool(await this.getAttribute('enabled', elementId));
45
+ },
46
+ async elementSelected(elementId) {
47
+ return toBool(await this.getAttribute('selected', elementId));
48
+ },
49
+ async getName(elementId) {
50
+ return /** @type {string} */ (
51
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
52
+ `/element/${elementId}/name`,
53
+ 'GET',
54
+ {}
55
+ )
56
+ );
57
+ },
58
+ async getLocation(elementId) {
59
+ return /** @type {import('@appium/types').Position} */ (
60
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
61
+ `/element/${elementId}/location`,
62
+ 'GET',
63
+ {}
64
+ )
65
+ );
66
+ },
67
+ async getSize(elementId) {
68
+ return /** @type {import('@appium/types').Size} */ (
69
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
70
+ `/element/${elementId}/size`,
71
+ 'GET',
72
+ {}
73
+ )
74
+ );
75
+ },
76
+ async touchLongClick(element, x, y, duration) {
77
+ let params = {element, x, y, duration};
78
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
79
+ `/touch/longclick`,
80
+ 'POST',
81
+ {params}
82
+ );
83
+ },
84
+ async touchDown(element, x, y) {
85
+ let params = {element, x, y};
86
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
87
+ `/touch/down`,
88
+ 'POST',
89
+ {params}
90
+ );
91
+ },
92
+ async touchUp(element, x, y) {
93
+ let params = {element, x, y};
94
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
95
+ `/touch/up`,
96
+ 'POST',
97
+ {params}
98
+ );
99
+ },
100
+ async touchMove(element, x, y) {
101
+ let params = {element, x, y};
102
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
103
+ `/touch/move`,
104
+ 'POST',
105
+ {params}
106
+ );
107
+ },
108
+ async doSetElementValue(params) {
109
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
110
+ `/element/${params.elementId}/value`,
111
+ 'POST',
112
+ params
113
+ );
114
+ },
115
+ async setValueImmediate(keys, elementId) {
116
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
117
+ `/element/${elementId}/value`,
118
+ 'POST',
119
+ {
120
+ elementId,
121
+ text: _.isArray(keys) ? keys.join('') : keys,
122
+ replace: false,
123
+ }
124
+ );
125
+ },
126
+ async getText(elementId) {
127
+ return String(
128
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
129
+ `/element/${elementId}/text`,
130
+ 'GET',
131
+ {}
132
+ )
133
+ );
134
+ },
135
+ async click(element) {
136
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
137
+ `/element/${element}/click`,
138
+ 'POST',
139
+ {element}
140
+ );
141
+ },
142
+ async getElementScreenshot(element) {
143
+ return String(
144
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
145
+ `/element/${element}/screenshot`,
146
+ 'GET',
147
+ {}
148
+ )
149
+ );
150
+ },
151
+
152
+ async tap(elementId = null, x = null, y = null, count = 1) {
153
+ const areCoordinatesDefined = util.hasValue(x) && util.hasValue(y);
154
+ if (!util.hasValue(elementId) && !areCoordinatesDefined) {
155
+ throw new Error(`Either element id to tap or both absolute coordinates should be defined`);
104
156
  }
105
- }
106
- };
107
157
 
108
- commands.clear = async function (elementId) {
109
- return await this.uiautomator2.jwproxy.command(`/element/${elementId}/clear`, 'POST', {elementId});
110
- };
111
-
112
- commands.getElementRect = async function (elementId) {
113
- if (this.isWebContext()) {
114
- this.log.debug(`Detected downstream chromedriver protocol: ${this.chromedriver.jwproxy.downstreamProtocol}`);
115
- if (this.chromedriver.jwproxy.downstreamProtocol === PROTOCOLS.MJSONWP) {
116
- const {x, y} = await this.chromedriver.jwproxy.command(`/element/${elementId}/location`, 'GET');
117
- const {width, height} = await this.chromedriver.jwproxy.command(`/element/${elementId}/size`, 'GET');
118
- return {x, y, width, height};
158
+ for (let i = 0; i < count; i++) {
159
+ if (util.hasValue(elementId) && !areCoordinatesDefined) {
160
+ // we are either tapping on the default location of the element
161
+ // or an offset from the top left corner
162
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
163
+ `/element/${elementId}/click`,
164
+ 'POST'
165
+ );
166
+ } else {
167
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
168
+ `/appium/tap`,
169
+ 'POST',
170
+ {
171
+ x,
172
+ y,
173
+ [W3C_ELEMENT_KEY]: elementId,
174
+ }
175
+ );
176
+ }
119
177
  }
120
- return await this.chromedriver.jwproxy.command(`/element/${elementId}/rect`, 'GET');
121
- }
122
- return await this.uiautomator2.jwproxy.command(`/element/${elementId}/rect`, 'GET');
123
- };
124
-
125
- /**
126
- * @typedef {Object} ReplaceValueOptions
127
- * @property {string} elementId The id of the element whose content will be replaced
128
- * @property {string} text The actual text to set
129
- */
178
+ },
179
+
180
+ async clear(elementId) {
181
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
182
+ `/element/${elementId}/clear`,
183
+ 'POST',
184
+ {
185
+ elementId,
186
+ }
187
+ );
188
+ },
189
+
190
+ async getElementRect(elementId) {
191
+ const chromedriver = /** @type {import('appium-chromedriver').default} */ (this.chromedriver);
192
+ if (this.isWebContext()) {
193
+ this.log.debug(
194
+ `Detected downstream chromedriver protocol: ${chromedriver.jwproxy.downstreamProtocol}`
195
+ );
196
+ if (chromedriver.jwproxy.downstreamProtocol === PROTOCOLS.MJSONWP) {
197
+ const [{x, y}, {width, height}] =
198
+ /** @type {[import('@appium/types').Position, import('@appium/types').Size]} */ (
199
+ await B.all([
200
+ chromedriver.jwproxy.command(`/element/${elementId}/location`, 'GET'),
201
+ chromedriver.jwproxy.command(`/element/${elementId}/size`, 'GET'),
202
+ ])
203
+ );
204
+ return {x, y, width, height};
205
+ }
206
+ return /** @type {import('@appium/types').Rect} */ (
207
+ await chromedriver.jwproxy.command(`/element/${elementId}/rect`, 'GET')
208
+ );
209
+ }
210
+ return /** @type {import('@appium/types').Rect} */ (
211
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
212
+ `/element/${elementId}/rect`,
213
+ 'GET'
214
+ )
215
+ );
216
+ },
217
+
218
+ /**
219
+ * Sends text to the given element by replacing its previous content
220
+ *
221
+ * @param {import('./types').ReplaceValueOptions} opts
222
+ * @throws {Error} If there was a faulre while setting the text
223
+ */
224
+ async mobileReplaceElementValue(opts) {
225
+ const {elementId, text} = requireArgs(['elementId', 'text'], opts);
226
+ await /** @type {UiAutomator2Server} */ (this.uiautomator2).jwproxy.command(
227
+ `/element/${elementId}/value`,
228
+ 'POST',
229
+ {
230
+ text,
231
+ replace: true,
232
+ }
233
+ );
234
+ },
235
+ };
236
+
237
+ mixin(ElementMixin);
130
238
 
131
239
  /**
132
- * Sends text to the given element by replacing its previous content
133
- *
134
- * @param {ReplaceValueOptions} opts
135
- * @throws {Error} If there was a faulre while setting the text
240
+ * @typedef {import('../uiautomator2').UiAutomator2Server} UiAutomator2Server
136
241
  */
137
- commands.mobileReplaceElementValue = async function mobileReplaceElementValue (opts = {}) {
138
- const {elementId, text} = requireArgs(['elementId', 'text'], opts);
139
- return await this.uiautomator2.jwproxy.command(`/element/${elementId}/value`, 'POST', {text, replace: true});
140
- };
141
-
142
- Object.assign(extensions, commands, helpers);
143
- export { commands, helpers };
144
- export default extensions;
@@ -1,6 +1,7 @@
1
- import CssConverter from '../css-converter';
1
+ // @ts-check
2
2
 
3
- const helpers = {};
3
+ import CssConverter from '../css-converter';
4
+ import {mixin} from './mixins';
4
5
 
5
6
  // we override the xpath search for this first-visible-child selector, which
6
7
  // looks like /*[@firstVisible="true"]
@@ -10,25 +11,43 @@ const MAGIC_SCROLLABLE_SEL = /\/\/\*\[@scrollable ?= ?('|")true\1\]/;
10
11
  const MAGIC_SCROLLABLE_BY = 'new UiSelector().scrollable(true)';
11
12
 
12
13
  /**
13
- * Overriding helpers.doFindElementOrEls functionality of appium-android-driver,
14
- * this.element initialized in find.js of appium-android-drive.
14
+ * @type {import('./mixins').UIA2FindMixin}
15
+ * @satisfies {import('@appium/types').ExternalDriver}
15
16
  */
16
- helpers.doFindElementOrEls = async function (params) {
17
- if (params.strategy === 'xpath' && MAGIC_FIRST_VIS_CHILD_SEL.test(params.selector)) {
18
- let elementId = params.context;
19
- return await this.uiautomator2.jwproxy.command(`/appium/element/${elementId}/first_visible`, 'GET', {});
20
- }
21
- if (params.strategy === 'xpath' && MAGIC_SCROLLABLE_SEL.test(params.selector)) {
22
- params.strategy = '-android uiautomator';
23
- params.selector = MAGIC_SCROLLABLE_BY;
24
- }
25
- if (params.strategy === 'css selector') {
26
- params.strategy = '-android uiautomator';
27
- params.selector = new CssConverter(params.selector, this.opts.appPackage)
28
- .toUiAutomatorSelector();
29
- }
30
- return await this.uiautomator2.jwproxy.command(`/element${params.multiple ? 's' : ''}`, 'POST', params);
17
+ const FindMixin = {
18
+ /**
19
+ * @privateRemarks Overriding helpers.doFindElementOrEls functionality of appium-android-driver,
20
+ * this.element initialized in find.js of appium-android-drive.
21
+ */
22
+ async doFindElementOrEls(params) {
23
+ const uiautomator2 = /** @type {import('../uiautomator2').UiAutomator2Server} */ (
24
+ this.uiautomator2
25
+ );
26
+ if (params.strategy === 'xpath' && MAGIC_FIRST_VIS_CHILD_SEL.test(params.selector)) {
27
+ let elementId = params.context;
28
+ return /** @type {Element} */ (
29
+ await uiautomator2.jwproxy.command(`/appium/element/${elementId}/first_visible`, 'GET', {})
30
+ );
31
+ }
32
+ if (params.strategy === 'xpath' && MAGIC_SCROLLABLE_SEL.test(params.selector)) {
33
+ params.strategy = '-android uiautomator';
34
+ params.selector = MAGIC_SCROLLABLE_BY;
35
+ }
36
+ if (params.strategy === 'css selector') {
37
+ params.strategy = '-android uiautomator';
38
+ params.selector = new CssConverter(
39
+ params.selector,
40
+ this.opts.appPackage
41
+ ).toUiAutomatorSelector();
42
+ }
43
+ return /** @type {Element|Element[]} */ (
44
+ await uiautomator2.jwproxy.command(`/element${params.multiple ? 's' : ''}`, 'POST', params)
45
+ );
46
+ },
31
47
  };
32
48
 
33
- export { helpers };
34
- export default helpers;
49
+ mixin(FindMixin);
50
+
51
+ /**
52
+ * @typedef {import('@appium/types').Element} Element
53
+ */