appium-uiautomator2-driver 6.7.6 → 6.7.8

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 (91) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/lib/commands/actions.d.ts +26 -29
  3. package/build/lib/commands/actions.d.ts.map +1 -1
  4. package/build/lib/commands/actions.js +19 -27
  5. package/build/lib/commands/actions.js.map +1 -1
  6. package/build/lib/commands/alert.d.ts +14 -22
  7. package/build/lib/commands/alert.d.ts.map +1 -1
  8. package/build/lib/commands/alert.js +8 -19
  9. package/build/lib/commands/alert.js.map +1 -1
  10. package/build/lib/commands/app-management.d.ts +7 -10
  11. package/build/lib/commands/app-management.d.ts.map +1 -1
  12. package/build/lib/commands/app-management.js +4 -14
  13. package/build/lib/commands/app-management.js.map +1 -1
  14. package/build/lib/commands/battery.d.ts +4 -5
  15. package/build/lib/commands/battery.d.ts.map +1 -1
  16. package/build/lib/commands/battery.js +4 -9
  17. package/build/lib/commands/battery.js.map +1 -1
  18. package/build/lib/commands/clipboard.d.ts +9 -13
  19. package/build/lib/commands/clipboard.d.ts.map +1 -1
  20. package/build/lib/commands/clipboard.js +7 -14
  21. package/build/lib/commands/clipboard.js.map +1 -1
  22. package/build/lib/commands/element.d.ts +29 -0
  23. package/build/lib/commands/element.d.ts.map +1 -1
  24. package/build/lib/commands/element.js +29 -0
  25. package/build/lib/commands/element.js.map +1 -1
  26. package/build/lib/commands/find.d.ts +13 -9
  27. package/build/lib/commands/find.d.ts.map +1 -1
  28. package/build/lib/commands/find.js +4 -16
  29. package/build/lib/commands/find.js.map +1 -1
  30. package/build/lib/commands/gestures.d.ts +63 -0
  31. package/build/lib/commands/gestures.d.ts.map +1 -1
  32. package/build/lib/commands/gestures.js +63 -0
  33. package/build/lib/commands/gestures.js.map +1 -1
  34. package/build/lib/commands/keyboard.d.ts +30 -41
  35. package/build/lib/commands/keyboard.d.ts.map +1 -1
  36. package/build/lib/commands/keyboard.js +22 -37
  37. package/build/lib/commands/keyboard.js.map +1 -1
  38. package/build/lib/commands/misc.d.ts +4 -0
  39. package/build/lib/commands/misc.d.ts.map +1 -1
  40. package/build/lib/commands/misc.js +4 -0
  41. package/build/lib/commands/misc.js.map +1 -1
  42. package/build/lib/commands/navigation.d.ts +11 -16
  43. package/build/lib/commands/navigation.d.ts.map +1 -1
  44. package/build/lib/commands/navigation.js +9 -17
  45. package/build/lib/commands/navigation.js.map +1 -1
  46. package/build/lib/commands/viewport.d.ts +23 -22
  47. package/build/lib/commands/viewport.d.ts.map +1 -1
  48. package/build/lib/commands/viewport.js +17 -24
  49. package/build/lib/commands/viewport.js.map +1 -1
  50. package/build/lib/doctor/optional-checks.d.ts +4 -4
  51. package/build/lib/doctor/optional-checks.d.ts.map +1 -1
  52. package/build/lib/doctor/optional-checks.js.map +1 -1
  53. package/build/lib/doctor/required-checks.d.ts +5 -21
  54. package/build/lib/doctor/required-checks.d.ts.map +1 -1
  55. package/build/lib/doctor/required-checks.js.map +1 -1
  56. package/build/lib/index.d.ts +4 -0
  57. package/build/lib/index.d.ts.map +1 -0
  58. package/build/{index.js → lib/index.js} +1 -1
  59. package/build/lib/index.js.map +1 -0
  60. package/build/tsconfig.tsbuildinfo +1 -1
  61. package/lib/commands/actions.ts +95 -0
  62. package/lib/commands/alert.ts +46 -0
  63. package/lib/commands/app-management.ts +25 -0
  64. package/lib/commands/battery.ts +19 -0
  65. package/lib/commands/clipboard.ts +29 -0
  66. package/lib/commands/element.ts +29 -0
  67. package/lib/commands/find.ts +48 -0
  68. package/lib/commands/gestures.ts +63 -0
  69. package/lib/commands/keyboard.ts +102 -0
  70. package/lib/commands/misc.ts +4 -0
  71. package/lib/commands/navigation.ts +32 -0
  72. package/lib/commands/viewport.ts +78 -0
  73. package/lib/doctor/optional-checks.ts +7 -0
  74. package/lib/doctor/required-checks.ts +8 -0
  75. package/{index.js → lib/index.ts} +2 -1
  76. package/npm-shrinkwrap.json +2 -2
  77. package/package.json +3 -7
  78. package/build/index.d.ts +0 -4
  79. package/build/index.d.ts.map +0 -1
  80. package/build/index.js.map +0 -1
  81. package/lib/commands/actions.js +0 -107
  82. package/lib/commands/alert.js +0 -63
  83. package/lib/commands/app-management.js +0 -32
  84. package/lib/commands/battery.js +0 -23
  85. package/lib/commands/clipboard.js +0 -37
  86. package/lib/commands/find.js +0 -47
  87. package/lib/commands/keyboard.js +0 -108
  88. package/lib/commands/navigation.js +0 -33
  89. package/lib/commands/viewport.js +0 -100
  90. package/lib/doctor/optional-checks.js +0 -5
  91. package/lib/doctor/required-checks.js +0 -6
@@ -0,0 +1,95 @@
1
+ import type {StringRecord} from '@appium/types';
2
+ import type {AndroidUiautomator2Driver} from '../driver';
3
+ import type {ActionResult} from './types';
4
+
5
+ /**
6
+ * Schedules a recurring action to be performed at specified intervals.
7
+ * @param name - Unique name for the scheduled action.
8
+ * @param steps - Array of action steps to be executed.
9
+ * @param maxPass - Maximum number of successful executions before stopping.
10
+ * @param maxFail - Maximum number of failed executions before stopping.
11
+ * @param times - Total number of times to execute the action.
12
+ * @param intervalMs - Interval in milliseconds between action executions.
13
+ * @param maxHistoryItems - Maximum number of history items to keep.
14
+ * @returns The result of scheduling the action.
15
+ */
16
+ export async function mobileScheduleAction(
17
+ this: AndroidUiautomator2Driver,
18
+ name: string,
19
+ steps: StringRecord[],
20
+ maxPass?: number,
21
+ maxFail?: number,
22
+ times?: number,
23
+ intervalMs?: number,
24
+ maxHistoryItems?: number,
25
+ ): Promise<any> {
26
+ return await this.uiautomator2.jwproxy.command('/appium/schedule_action', 'POST', {
27
+ name,
28
+ steps,
29
+ maxFail,
30
+ maxPass,
31
+ times,
32
+ intervalMs,
33
+ maxHistoryItems,
34
+ });
35
+ }
36
+
37
+ /**
38
+ * Gets the execution history for a scheduled action.
39
+ * @param name - Name of the scheduled action.
40
+ * @returns The action execution history containing repeats and step results.
41
+ */
42
+ export async function mobileGetActionHistory(
43
+ this: AndroidUiautomator2Driver,
44
+ name: string,
45
+ ): Promise<ActionResult> {
46
+ return (await this.uiautomator2.jwproxy.command('/appium/action_history', 'POST', {name})) as ActionResult;
47
+ }
48
+
49
+ /**
50
+ * Unschedules a previously scheduled action.
51
+ * @param name - Name of the scheduled action to unschedule.
52
+ * @returns The result of unscheduling the action.
53
+ */
54
+ export async function mobileUnscheduleAction(
55
+ this: AndroidUiautomator2Driver,
56
+ name: string,
57
+ ): Promise<any> {
58
+ return await this.uiautomator2.jwproxy.command('/appium/unschedule_action', 'POST', {name});
59
+ }
60
+
61
+ /**
62
+ * Performs a sequence of actions.
63
+ * @param actions - Array of action objects to perform. Pointer actions are automatically converted to touch type.
64
+ */
65
+ export async function performActions(
66
+ this: AndroidUiautomator2Driver,
67
+ actions: StringRecord[],
68
+ ): Promise<void> {
69
+ // This is mandatory, since Selenium API uses MOUSE as the default pointer type
70
+ const preprocessedActions = actions.map((action) =>
71
+ Object.assign(
72
+ {},
73
+ action,
74
+ action.type === 'pointer'
75
+ ? {
76
+ parameters: {
77
+ pointerType: 'touch',
78
+ },
79
+ }
80
+ : {}
81
+ )
82
+ );
83
+ this.log.debug(`Preprocessed actions: ${JSON.stringify(preprocessedActions, null, ' ')}`);
84
+ await this.uiautomator2.jwproxy.command('/actions', 'POST', {
85
+ actions: preprocessedActions,
86
+ });
87
+ }
88
+
89
+ /**
90
+ * Releases all currently pressed keys and buttons.
91
+ */
92
+ export async function releaseActions(this: AndroidUiautomator2Driver): Promise<void> {
93
+ this.log.info('On this platform, releaseActions is a no-op');
94
+ }
95
+
@@ -0,0 +1,46 @@
1
+ import type {AndroidUiautomator2Driver} from '../driver';
2
+
3
+ /**
4
+ * Gets the text of the currently displayed alert.
5
+ * @returns The alert text as a string.
6
+ */
7
+ export async function getAlertText(this: AndroidUiautomator2Driver): Promise<string> {
8
+ return String(await this.uiautomator2.jwproxy.command('/alert/text', 'GET', {}));
9
+ }
10
+
11
+ /**
12
+ * Accepts the currently displayed alert.
13
+ * @param buttonLabel - Optional label of the button to click. If not provided, the button will be detected automatically.
14
+ */
15
+ export async function mobileAcceptAlert(
16
+ this: AndroidUiautomator2Driver,
17
+ buttonLabel?: string,
18
+ ): Promise<void> {
19
+ await this.uiautomator2.jwproxy.command('/alert/accept', 'POST', {buttonLabel});
20
+ }
21
+
22
+ /**
23
+ * Accepts the currently displayed alert (W3C endpoint).
24
+ */
25
+ export async function postAcceptAlert(this: AndroidUiautomator2Driver): Promise<void> {
26
+ await this.mobileAcceptAlert();
27
+ }
28
+
29
+ /**
30
+ * Dismisses the currently displayed alert.
31
+ * @param buttonLabel - Optional label of the button to click. If not provided, the button will be detected automatically.
32
+ */
33
+ export async function mobileDismissAlert(
34
+ this: AndroidUiautomator2Driver,
35
+ buttonLabel?: string,
36
+ ): Promise<void> {
37
+ await this.uiautomator2.jwproxy.command('/alert/dismiss', 'POST', {buttonLabel});
38
+ }
39
+
40
+ /**
41
+ * Dismisses the currently displayed alert (W3C endpoint).
42
+ */
43
+ export async function postDismissAlert(this: AndroidUiautomator2Driver): Promise<void> {
44
+ await this.mobileDismissAlert();
45
+ }
46
+
@@ -0,0 +1,25 @@
1
+ import _ from 'lodash';
2
+ import B from 'bluebird';
3
+ import {errors} from 'appium/driver';
4
+ import {APK_EXTENSION} from '../extensions';
5
+ import type {AndroidUiautomator2Driver} from '../driver';
6
+ import type {InstallOptions} from './types';
7
+
8
+ /**
9
+ * Installs multiple APKs with `install-multiple` option.
10
+ * @param apks - Array of APK file paths or URLs to install.
11
+ * @param options - Optional installation options (allowTestPackages, useSdcard, grantPermissions, etc.).
12
+ * @throws {errors.InvalidArgumentError} If the apks array is empty or invalid.
13
+ */
14
+ export async function mobileInstallMultipleApks(
15
+ this: AndroidUiautomator2Driver,
16
+ apks: string[],
17
+ options?: InstallOptions,
18
+ ): Promise<void> {
19
+ if (!_.isArray(apks) || _.isEmpty(apks)) {
20
+ throw new errors.InvalidArgumentError('No apks are given to install');
21
+ }
22
+ const configuredApks = await B.all(apks.map((app) => this.helpers.configureApp(app, [APK_EXTENSION])));
23
+ await this.adb.installMultipleApks(configuredApks, options);
24
+ }
25
+
@@ -0,0 +1,19 @@
1
+ import type {AndroidUiautomator2Driver} from '../driver';
2
+ import type {BatteryInfo} from './types';
3
+
4
+ /**
5
+ * Reads the battery information from the device under test.
6
+ * @returns Battery information including level (0.0-1.0) and state (charging, discharging, etc.).
7
+ */
8
+ export async function mobileGetBatteryInfo(this: AndroidUiautomator2Driver): Promise<BatteryInfo> {
9
+ const result = (await this.uiautomator2.jwproxy.command('/appium/device/battery_info', 'GET', {})) as {
10
+ status: BatteryInfo['state'];
11
+ level: number;
12
+ };
13
+ const batteryInfo = result as any;
14
+ // Give it the same name as in iOS
15
+ batteryInfo.state = result.status;
16
+ delete batteryInfo.status;
17
+ return batteryInfo as BatteryInfo;
18
+ }
19
+
@@ -0,0 +1,29 @@
1
+ import type {AndroidUiautomator2Driver} from '../driver';
2
+
3
+ /**
4
+ * Gets the clipboard content as a base64-encoded string.
5
+ * @returns Base64-encoded clipboard content, or an empty string if the clipboard is empty.
6
+ */
7
+ export async function getClipboard(this: AndroidUiautomator2Driver): Promise<string> {
8
+ return String(
9
+ (await this.adb.getApiLevel()) < 29
10
+ ? await this.uiautomator2.jwproxy.command('/appium/device/get_clipboard', 'POST', {})
11
+ : await this.settingsApp.getClipboard()
12
+ );
13
+ }
14
+
15
+ /**
16
+ * Sets the clipboard content.
17
+ * @param content - Base64-encoded clipboard payload.
18
+ * @param contentType - Content type. Only 'plaintext' is supported. Defaults to 'plaintext'.
19
+ * @param label - Optional label to identify the current clipboard payload.
20
+ */
21
+ export async function setClipboard(
22
+ this: AndroidUiautomator2Driver,
23
+ content: string,
24
+ contentType: 'plaintext' = 'plaintext',
25
+ label?: string,
26
+ ): Promise<void> {
27
+ await this.uiautomator2.jwproxy.command('/appium/device/set_clipboard', 'POST', {content, contentType, label});
28
+ }
29
+
@@ -8,6 +8,7 @@ import type {Chromedriver} from 'appium-chromedriver';
8
8
 
9
9
  /**
10
10
  * Gets the currently active element.
11
+ * @returns The currently active element.
11
12
  */
12
13
  export async function active(this: AndroidUiautomator2Driver): Promise<AppiumElement> {
13
14
  return (await this.uiautomator2.jwproxy.command('/element/active', 'GET')) as AppiumElement;
@@ -15,6 +16,9 @@ export async function active(this: AndroidUiautomator2Driver): Promise<AppiumEle
15
16
 
16
17
  /**
17
18
  * Gets an element attribute value.
19
+ * @param attribute - Name of the attribute to retrieve.
20
+ * @param elementId - ID of the element.
21
+ * @returns The attribute value as a string.
18
22
  */
19
23
  export async function getAttribute(this: AndroidUiautomator2Driver, attribute: string, elementId: string): Promise<string> {
20
24
  return String(await this.uiautomator2.jwproxy.command(`/element/${elementId}/attribute/${attribute}`, 'GET', {}));
@@ -22,6 +26,8 @@ export async function getAttribute(this: AndroidUiautomator2Driver, attribute: s
22
26
 
23
27
  /**
24
28
  * Returns whether the element is displayed.
29
+ * @param elementId - ID of the element.
30
+ * @returns True if the element is displayed, false otherwise.
25
31
  */
26
32
  export async function elementDisplayed(this: AndroidUiautomator2Driver, elementId: string): Promise<boolean> {
27
33
  return toBool(await this.getAttribute('displayed', elementId));
@@ -29,6 +35,8 @@ export async function elementDisplayed(this: AndroidUiautomator2Driver, elementI
29
35
 
30
36
  /**
31
37
  * Returns whether the element is enabled.
38
+ * @param elementId - ID of the element.
39
+ * @returns True if the element is enabled, false otherwise.
32
40
  */
33
41
  export async function elementEnabled(this: AndroidUiautomator2Driver, elementId: string): Promise<boolean> {
34
42
  return toBool(await this.getAttribute('enabled', elementId));
@@ -36,6 +44,8 @@ export async function elementEnabled(this: AndroidUiautomator2Driver, elementId:
36
44
 
37
45
  /**
38
46
  * Returns whether the element is selected.
47
+ * @param elementId - ID of the element.
48
+ * @returns True if the element is selected, false otherwise.
39
49
  */
40
50
  export async function elementSelected(this: AndroidUiautomator2Driver, elementId: string): Promise<boolean> {
41
51
  return toBool(await this.getAttribute('selected', elementId));
@@ -43,6 +53,8 @@ export async function elementSelected(this: AndroidUiautomator2Driver, elementId
43
53
 
44
54
  /**
45
55
  * Gets the element tag name.
56
+ * @param elementId - ID of the element.
57
+ * @returns The element tag name.
46
58
  */
47
59
  export async function getName(this: AndroidUiautomator2Driver, elementId: string): Promise<string> {
48
60
  return (await this.uiautomator2.jwproxy.command(`/element/${elementId}/name`, 'GET', {})) as string;
@@ -50,6 +62,8 @@ export async function getName(this: AndroidUiautomator2Driver, elementId: string
50
62
 
51
63
  /**
52
64
  * Gets the element location.
65
+ * @param elementId - ID of the element.
66
+ * @returns The element position coordinates (x, y).
53
67
  */
54
68
  export async function getLocation(this: AndroidUiautomator2Driver, elementId: string): Promise<Position> {
55
69
  return (await this.uiautomator2.jwproxy.command(`/element/${elementId}/location`, 'GET', {})) as Position;
@@ -57,6 +71,8 @@ export async function getLocation(this: AndroidUiautomator2Driver, elementId: st
57
71
 
58
72
  /**
59
73
  * Gets the element size.
74
+ * @param elementId - ID of the element.
75
+ * @returns The element size (width, height).
60
76
  */
61
77
  export async function getSize(this: AndroidUiautomator2Driver, elementId: string): Promise<Size> {
62
78
  return (await this.uiautomator2.jwproxy.command(`/element/${elementId}/size`, 'GET', {})) as Size;
@@ -64,6 +80,7 @@ export async function getSize(this: AndroidUiautomator2Driver, elementId: string
64
80
 
65
81
  /**
66
82
  * Sets the value of an element using the upstream driver API.
83
+ * @param params - Options containing the element ID and value to set.
67
84
  */
68
85
  export async function doSetElementValue(this: AndroidUiautomator2Driver, params: DoSetElementValueOpts): Promise<void> {
69
86
  await this.uiautomator2.jwproxy.command(`/element/${params.elementId}/value`, 'POST', params);
@@ -71,6 +88,8 @@ export async function doSetElementValue(this: AndroidUiautomator2Driver, params:
71
88
 
72
89
  /**
73
90
  * Sends text to an element without replacement.
91
+ * @param keys - Text to send, either as a string or array of strings (which will be joined).
92
+ * @param elementId - ID of the element.
74
93
  */
75
94
  export async function setValueImmediate(
76
95
  this: AndroidUiautomator2Driver,
@@ -86,6 +105,8 @@ export async function setValueImmediate(
86
105
 
87
106
  /**
88
107
  * Gets the element text.
108
+ * @param elementId - ID of the element.
109
+ * @returns The element text content.
89
110
  */
90
111
  export async function getText(this: AndroidUiautomator2Driver, elementId: string): Promise<string> {
91
112
  return String(await this.uiautomator2.jwproxy.command(`/element/${elementId}/text`, 'GET', {}));
@@ -93,6 +114,7 @@ export async function getText(this: AndroidUiautomator2Driver, elementId: string
93
114
 
94
115
  /**
95
116
  * Clicks the given element.
117
+ * @param element - ID of the element to click.
96
118
  */
97
119
  export async function click(this: AndroidUiautomator2Driver, element: string): Promise<void> {
98
120
  await this.uiautomator2.jwproxy.command(`/element/${element}/click`, 'POST', {element});
@@ -100,6 +122,8 @@ export async function click(this: AndroidUiautomator2Driver, element: string): P
100
122
 
101
123
  /**
102
124
  * Takes a screenshot of the element.
125
+ * @param element - ID of the element.
126
+ * @returns Base64-encoded PNG screenshot of the element.
103
127
  */
104
128
  export async function getElementScreenshot(this: AndroidUiautomator2Driver, element: string): Promise<string> {
105
129
  return String(await this.uiautomator2.jwproxy.command(`/element/${element}/screenshot`, 'GET', {}));
@@ -107,6 +131,7 @@ export async function getElementScreenshot(this: AndroidUiautomator2Driver, elem
107
131
 
108
132
  /**
109
133
  * Clears the element text.
134
+ * @param elementId - ID of the element to clear.
110
135
  */
111
136
  export async function clear(this: AndroidUiautomator2Driver, elementId: string): Promise<void> {
112
137
  await this.uiautomator2.jwproxy.command(`/element/${elementId}/clear`, 'POST', {elementId});
@@ -114,6 +139,8 @@ export async function clear(this: AndroidUiautomator2Driver, elementId: string):
114
139
 
115
140
  /**
116
141
  * Gets the element rectangle.
142
+ * @param elementId - ID of the element.
143
+ * @returns The element rectangle (x, y, width, height).
117
144
  */
118
145
  export async function getElementRect(this: AndroidUiautomator2Driver, elementId: string): Promise<Rect> {
119
146
  if (!this.isWebContext()) {
@@ -133,6 +160,8 @@ export async function getElementRect(this: AndroidUiautomator2Driver, elementId:
133
160
 
134
161
  /**
135
162
  * Replaces the element text.
163
+ * @param elementId - ID of the element.
164
+ * @param text - Text to replace the current element value with.
136
165
  */
137
166
  export async function mobileReplaceElementValue(
138
167
  this: AndroidUiautomator2Driver,
@@ -0,0 +1,48 @@
1
+ import {CssConverter} from '../css-converter';
2
+ import type {Element as AppiumElement} from '@appium/types';
3
+ import type {FindElementOpts} from 'appium-android-driver';
4
+ import type {AndroidUiautomator2Driver} from '../driver';
5
+
6
+ // we override the xpath search for this first-visible-child selector, which
7
+ // looks like /*[@firstVisible="true"]
8
+ const MAGIC_FIRST_VIS_CHILD_SEL = /\/\*\[@firstVisible ?= ?('|")true\1\]/;
9
+
10
+ const MAGIC_SCROLLABLE_SEL = /\/\/\*\[@scrollable ?= ?('|")true\1\]/;
11
+ const MAGIC_SCROLLABLE_BY = 'new UiSelector().scrollable(true)';
12
+
13
+ /**
14
+ * Overrides helpers.doFindElementOrEls functionality of appium-android-driver.
15
+ * Handles special xpath selectors and CSS selector conversion.
16
+ * @param params - Element finding options including strategy, selector, context, and multiple flag.
17
+ * @returns A single element if `params.multiple` is false, or an array of elements if true.
18
+ */
19
+ export async function doFindElementOrEls(
20
+ this: AndroidUiautomator2Driver,
21
+ params: FindElementOpts & {multiple: true},
22
+ ): Promise<AppiumElement[]>;
23
+ export async function doFindElementOrEls(
24
+ this: AndroidUiautomator2Driver,
25
+ params: FindElementOpts & {multiple: false},
26
+ ): Promise<AppiumElement>;
27
+ export async function doFindElementOrEls(
28
+ this: AndroidUiautomator2Driver,
29
+ params: FindElementOpts,
30
+ ): Promise<AppiumElement | AppiumElement[]> {
31
+ const uiautomator2 = this.uiautomator2;
32
+ if (params.strategy === 'xpath' && MAGIC_FIRST_VIS_CHILD_SEL.test(params.selector)) {
33
+ const elementId = params.context;
34
+ return (await uiautomator2.jwproxy.command(`/appium/element/${elementId}/first_visible`, 'GET', {})) as AppiumElement;
35
+ }
36
+ if (params.strategy === 'xpath' && MAGIC_SCROLLABLE_SEL.test(params.selector)) {
37
+ params.strategy = '-android uiautomator';
38
+ params.selector = MAGIC_SCROLLABLE_BY;
39
+ }
40
+ if (params.strategy === 'css selector') {
41
+ params.strategy = '-android uiautomator';
42
+ params.selector = new CssConverter(params.selector, this.opts.appPackage).toUiAutomatorSelector();
43
+ }
44
+ return (await uiautomator2.jwproxy.command(`/element${params.multiple ? 's' : ''}`, 'POST', params)) as
45
+ | AppiumElement
46
+ | AppiumElement[];
47
+ }
48
+
@@ -7,6 +7,9 @@ import type {AndroidUiautomator2Driver} from '../driver';
7
7
 
8
8
  /**
9
9
  * Performs a simple click/tap gesture.
10
+ * @param elementId - Optional element to use as the origin for the click. If not provided, uses screen coordinates.
11
+ * @param x - Optional X offset from the element origin or screen.
12
+ * @param y - Optional Y offset from the element origin or screen.
10
13
  */
11
14
  export async function mobileClickGesture(
12
15
  this: AndroidUiautomator2Driver,
@@ -22,6 +25,10 @@ export async function mobileClickGesture(
22
25
 
23
26
  /**
24
27
  * Performs a long click with an optional duration.
28
+ * @param elementId - Optional element to use as the origin for the long click.
29
+ * @param x - Optional X offset from the element origin or screen.
30
+ * @param y - Optional Y offset from the element origin or screen.
31
+ * @param duration - Optional duration of the long press in milliseconds.
25
32
  */
26
33
  export async function mobileLongClickGesture(
27
34
  this: AndroidUiautomator2Driver,
@@ -39,6 +46,9 @@ export async function mobileLongClickGesture(
39
46
 
40
47
  /**
41
48
  * Performs a double-click gesture.
49
+ * @param elementId - Optional element to use as the origin for the double click.
50
+ * @param x - Optional X offset from the element origin or screen.
51
+ * @param y - Optional Y offset from the element origin or screen.
42
52
  */
43
53
  export async function mobileDoubleClickGesture(
44
54
  this: AndroidUiautomator2Driver,
@@ -54,6 +64,12 @@ export async function mobileDoubleClickGesture(
54
64
 
55
65
  /**
56
66
  * Drags from a start point to an end point.
67
+ * @param elementId - Optional element to use as the origin for the drag.
68
+ * @param startX - X coordinate of the drag start point.
69
+ * @param startY - Y coordinate of the drag start point.
70
+ * @param endX - X coordinate of the drag end point.
71
+ * @param endY - Y coordinate of the drag end point.
72
+ * @param speed - Optional speed of the drag gesture.
57
73
  */
58
74
  export async function mobileDragGesture(
59
75
  this: AndroidUiautomator2Driver,
@@ -74,6 +90,14 @@ export async function mobileDragGesture(
74
90
 
75
91
  /**
76
92
  * Performs a fling gesture and reports if further scrolling is possible.
93
+ * @param direction - Direction of the fling ('up', 'down', 'left', 'right').
94
+ * @param elementId - Optional element to use as the origin for the fling.
95
+ * @param left - Optional left coordinate of the fling area.
96
+ * @param top - Optional top coordinate of the fling area.
97
+ * @param width - Optional width of the fling area.
98
+ * @param height - Optional height of the fling area.
99
+ * @param speed - Optional speed of the fling gesture.
100
+ * @returns True if further scrolling is possible, false otherwise.
77
101
  */
78
102
  export async function mobileFlingGesture(
79
103
  this: AndroidUiautomator2Driver,
@@ -95,6 +119,13 @@ export async function mobileFlingGesture(
95
119
 
96
120
  /**
97
121
  * Performs a pinch-close gesture.
122
+ * @param percent - Percentage of the pinch (0-100).
123
+ * @param elementId - Optional element to use as the origin for the pinch.
124
+ * @param left - Optional left coordinate of the pinch area.
125
+ * @param top - Optional top coordinate of the pinch area.
126
+ * @param width - Optional width of the pinch area.
127
+ * @param height - Optional height of the pinch area.
128
+ * @param speed - Optional speed of the pinch gesture.
98
129
  */
99
130
  export async function mobilePinchCloseGesture(
100
131
  this: AndroidUiautomator2Driver,
@@ -116,6 +147,13 @@ export async function mobilePinchCloseGesture(
116
147
 
117
148
  /**
118
149
  * Performs a pinch-open gesture.
150
+ * @param percent - Percentage of the pinch (0-100).
151
+ * @param elementId - Optional element to use as the origin for the pinch.
152
+ * @param left - Optional left coordinate of the pinch area.
153
+ * @param top - Optional top coordinate of the pinch area.
154
+ * @param width - Optional width of the pinch area.
155
+ * @param height - Optional height of the pinch area.
156
+ * @param speed - Optional speed of the pinch gesture.
119
157
  */
120
158
  export async function mobilePinchOpenGesture(
121
159
  this: AndroidUiautomator2Driver,
@@ -137,6 +175,14 @@ export async function mobilePinchOpenGesture(
137
175
 
138
176
  /**
139
177
  * Performs a swipe gesture for the given direction and percent.
178
+ * @param direction - Direction of the swipe ('up', 'down', 'left', 'right').
179
+ * @param percent - Percentage of the swipe distance (0-100).
180
+ * @param elementId - Optional element to use as the origin for the swipe.
181
+ * @param left - Optional left coordinate of the swipe area.
182
+ * @param top - Optional top coordinate of the swipe area.
183
+ * @param width - Optional width of the swipe area.
184
+ * @param height - Optional height of the swipe area.
185
+ * @param speed - Optional speed of the swipe gesture.
140
186
  */
141
187
  export async function mobileSwipeGesture(
142
188
  this: AndroidUiautomator2Driver,
@@ -160,6 +206,15 @@ export async function mobileSwipeGesture(
160
206
 
161
207
  /**
162
208
  * Performs a scroll gesture and reports if further scrolling is possible.
209
+ * @param direction - Direction of the scroll ('up', 'down', 'left', 'right').
210
+ * @param percent - Percentage of the scroll distance (0-100).
211
+ * @param elementId - Optional element to use as the origin for the scroll.
212
+ * @param left - Optional left coordinate of the scroll area.
213
+ * @param top - Optional top coordinate of the scroll area.
214
+ * @param width - Optional width of the scroll area.
215
+ * @param height - Optional height of the scroll area.
216
+ * @param speed - Optional speed of the scroll gesture.
217
+ * @returns True if further scrolling is possible, false otherwise.
163
218
  */
164
219
  export async function mobileScrollGesture(
165
220
  this: AndroidUiautomator2Driver,
@@ -183,6 +238,9 @@ export async function mobileScrollGesture(
183
238
 
184
239
  /**
185
240
  * Scrolls a scrollable element until a target element becomes visible.
241
+ * @param elementId - ID of the scrollable element.
242
+ * @param elementToId - ID of the target element to scroll to.
243
+ * @throws {errors.InvalidArgumentError} If either elementId or elementToId is not provided.
186
244
  */
187
245
  export async function mobileScrollBackTo(
188
246
  this: AndroidUiautomator2Driver,
@@ -201,6 +259,11 @@ export async function mobileScrollBackTo(
201
259
 
202
260
  /**
203
261
  * Scrolls until an element located by the given strategy is visible.
262
+ * @param strategy - Locator strategy to use (e.g., 'id', 'xpath', 'class name').
263
+ * @param selector - Selector string for the element to find.
264
+ * @param elementId - Optional element to use as the origin for scrolling.
265
+ * @param maxSwipes - Optional maximum number of swipes to perform.
266
+ * @throws {errors.InvalidArgumentError} If either strategy or selector is not provided.
204
267
  */
205
268
  export async function mobileScroll(
206
269
  this: AndroidUiautomator2Driver,
@@ -0,0 +1,102 @@
1
+ import {errors} from 'appium/driver';
2
+ import _ from 'lodash';
3
+ import type {AndroidUiautomator2Driver} from '../driver';
4
+ import type {SendKeysOpts} from 'appium-android-driver';
5
+
6
+ /**
7
+ * Presses a key code with optional metastate and flags.
8
+ * @param keycode - Android key code to press.
9
+ * @param metastate - Optional meta state modifier keys.
10
+ * @param flags - Optional flags for the key event.
11
+ */
12
+ export async function pressKeyCode(
13
+ this: AndroidUiautomator2Driver,
14
+ keycode: string | number,
15
+ metastate?: number,
16
+ flags?: number,
17
+ ): Promise<void> {
18
+ await this.uiautomator2.jwproxy.command('/appium/device/press_keycode', 'POST', {
19
+ keycode,
20
+ metastate,
21
+ flags,
22
+ });
23
+ }
24
+
25
+ /**
26
+ * Long presses a key code with optional metastate and flags.
27
+ * @param keycode - Android key code to long press.
28
+ * @param metastate - Meta state modifier keys.
29
+ * @param flags - Optional flags for the key event.
30
+ */
31
+ export async function longPressKeyCode(
32
+ this: AndroidUiautomator2Driver,
33
+ keycode: string | number,
34
+ metastate: number,
35
+ flags?: number,
36
+ ): Promise<void> {
37
+ await this.uiautomator2.jwproxy.command('/appium/device/long_press_keycode', 'POST', {
38
+ keycode,
39
+ metastate,
40
+ flags,
41
+ });
42
+ }
43
+
44
+ /**
45
+ * Presses a key code with optional metastate, flags, and long press support.
46
+ * @param keycode - Android key code to press.
47
+ * @param metastate - Optional meta state modifier keys.
48
+ * @param flags - Optional flags for the key event.
49
+ * @param isLongPress - Whether to perform a long press. Defaults to false.
50
+ */
51
+ export async function mobilePressKey(
52
+ this: AndroidUiautomator2Driver,
53
+ keycode: number,
54
+ metastate?: number,
55
+ flags?: string,
56
+ isLongPress: boolean = false,
57
+ ): Promise<void> {
58
+ await this.uiautomator2.jwproxy.command(`/appium/device/${isLongPress ? 'long_' : ''}press_keycode`, 'POST', {
59
+ keycode,
60
+ metastate,
61
+ flags,
62
+ });
63
+ }
64
+
65
+ /**
66
+ * Types the given Unicode string. The focus should already be on the destination input field.
67
+ * @param text - Text to type. Can be a string, number, or boolean.
68
+ * @returns True if the input text has been successfully sent to adb.
69
+ * @throws {errors.InvalidArgumentError} If the text argument is not provided.
70
+ */
71
+ export async function mobileType(
72
+ this: AndroidUiautomator2Driver,
73
+ text: string | number | boolean,
74
+ ): Promise<boolean> {
75
+ if (_.isUndefined(text)) {
76
+ throw new errors.InvalidArgumentError(`The 'text' argument is mandatory`);
77
+ }
78
+ return await this.settingsApp.typeUnicode(String(text));
79
+ }
80
+
81
+ /**
82
+ * Sends keys to the current element.
83
+ * @param params - Options containing the text to send and optional replace flag.
84
+ */
85
+ export async function doSendKeys(this: AndroidUiautomator2Driver, params: SendKeysOpts): Promise<void> {
86
+ await this.uiautomator2.jwproxy.command('/keys', 'POST', params);
87
+ }
88
+
89
+ /**
90
+ * Sends a key event to the device.
91
+ * @param keycode - Android key code to send.
92
+ * @param metastate - Optional meta state (ignored in this implementation).
93
+ */
94
+ export async function keyevent(
95
+ this: AndroidUiautomator2Driver,
96
+ keycode: string | number,
97
+ metastate?: number,
98
+ ): Promise<void> {
99
+ this.log.debug(`Ignoring metastate ${metastate}`);
100
+ await this.adb.keyevent(keycode);
101
+ }
102
+
@@ -3,6 +3,7 @@ import type {AndroidUiautomator2Driver} from '../driver';
3
3
 
4
4
  /**
5
5
  * Retrieves the current page source.
6
+ * @returns The XML page source of the current screen.
6
7
  */
7
8
  export async function getPageSource(this: AndroidUiautomator2Driver): Promise<string> {
8
9
  return String(await this.uiautomator2.jwproxy.command('/source', 'GET', {}));
@@ -10,6 +11,7 @@ export async function getPageSource(this: AndroidUiautomator2Driver): Promise<st
10
11
 
11
12
  /**
12
13
  * Gets the current device orientation.
14
+ * @returns The current device orientation ('LANDSCAPE' or 'PORTRAIT').
13
15
  */
14
16
  export async function getOrientation(this: AndroidUiautomator2Driver): Promise<Orientation> {
15
17
  return (await this.uiautomator2.jwproxy.command(`/orientation`, 'GET', {})) as Orientation;
@@ -17,6 +19,7 @@ export async function getOrientation(this: AndroidUiautomator2Driver): Promise<O
17
19
 
18
20
  /**
19
21
  * Sets the device orientation.
22
+ * @param orientation - The desired orientation ('LANDSCAPE' or 'PORTRAIT').
20
23
  */
21
24
  export async function setOrientation(
22
25
  this: AndroidUiautomator2Driver,
@@ -49,6 +52,7 @@ export function suspendChromedriverProxy(this: AndroidUiautomator2Driver): void
49
52
 
50
53
  /**
51
54
  * Retrieves device info via the UIA2 server.
55
+ * @returns Device information as a string record.
52
56
  */
53
57
  export async function mobileGetDeviceInfo(this: AndroidUiautomator2Driver): Promise<StringRecord> {
54
58
  return (await this.uiautomator2.jwproxy.command('/appium/device/info', 'GET')) as StringRecord;