appium-uiautomator2-driver 8.2.0 → 8.2.2

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 (94) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/lib/commands/actions.d.ts.map +1 -1
  3. package/build/lib/commands/actions.js.map +1 -1
  4. package/build/lib/commands/alert.d.ts.map +1 -1
  5. package/build/lib/commands/alert.js.map +1 -1
  6. package/build/lib/commands/app-management.d.ts.map +1 -1
  7. package/build/lib/commands/app-management.js.map +1 -1
  8. package/build/lib/commands/aut.d.ts.map +1 -1
  9. package/build/lib/commands/aut.js +1 -2
  10. package/build/lib/commands/aut.js.map +1 -1
  11. package/build/lib/commands/battery.d.ts.map +1 -1
  12. package/build/lib/commands/battery.js.map +1 -1
  13. package/build/lib/commands/element.d.ts +1 -1
  14. package/build/lib/commands/element.d.ts.map +1 -1
  15. package/build/lib/commands/element.js.map +1 -1
  16. package/build/lib/commands/find.d.ts.map +1 -1
  17. package/build/lib/commands/find.js.map +1 -1
  18. package/build/lib/commands/gestures.d.ts.map +1 -1
  19. package/build/lib/commands/gestures.js.map +1 -1
  20. package/build/lib/commands/keyboard.d.ts +1 -1
  21. package/build/lib/commands/keyboard.d.ts.map +1 -1
  22. package/build/lib/commands/keyboard.js.map +1 -1
  23. package/build/lib/commands/misc.d.ts.map +1 -1
  24. package/build/lib/commands/misc.js.map +1 -1
  25. package/build/lib/commands/screenshot.d.ts +1 -1
  26. package/build/lib/commands/screenshot.d.ts.map +1 -1
  27. package/build/lib/commands/screenshot.js +1 -3
  28. package/build/lib/commands/screenshot.js.map +1 -1
  29. package/build/lib/commands/viewport.d.ts.map +1 -1
  30. package/build/lib/commands/viewport.js.map +1 -1
  31. package/build/lib/commands/windows.d.ts.map +1 -1
  32. package/build/lib/commands/windows.js.map +1 -1
  33. package/build/lib/css/index.d.ts.map +1 -1
  34. package/build/lib/css/index.js.map +1 -1
  35. package/build/lib/css/ui-automator-emitter.d.ts.map +1 -1
  36. package/build/lib/css/ui-automator-emitter.js +1 -3
  37. package/build/lib/css/ui-automator-emitter.js.map +1 -1
  38. package/build/lib/doctor/optional-checks.d.ts.map +1 -1
  39. package/build/lib/doctor/optional-checks.js.map +1 -1
  40. package/build/lib/doctor/required-checks.d.ts.map +1 -1
  41. package/build/lib/doctor/required-checks.js.map +1 -1
  42. package/build/lib/driver.d.ts +6 -6
  43. package/build/lib/driver.d.ts.map +1 -1
  44. package/build/lib/driver.js +9 -20
  45. package/build/lib/driver.js.map +1 -1
  46. package/build/lib/logger.d.ts.map +1 -1
  47. package/build/lib/logger.js.map +1 -1
  48. package/build/lib/session-claim-handler.d.ts.map +1 -1
  49. package/build/lib/session-claim-handler.js +1 -1
  50. package/build/lib/session-claim-handler.js.map +1 -1
  51. package/build/lib/types.d.ts.map +1 -1
  52. package/build/lib/uiautomator2-server/core.d.ts +1 -1
  53. package/build/lib/uiautomator2-server/core.d.ts.map +1 -1
  54. package/build/lib/uiautomator2-server/core.js +8 -22
  55. package/build/lib/uiautomator2-server/core.js.map +1 -1
  56. package/build/lib/uiautomator2-server/session.d.ts.map +1 -1
  57. package/build/lib/uiautomator2-server/session.js +8 -6
  58. package/build/lib/uiautomator2-server/session.js.map +1 -1
  59. package/build/lib/utils/app.d.ts.map +1 -1
  60. package/build/lib/utils/app.js.map +1 -1
  61. package/build/lib/utils/mjpeg.d.ts.map +1 -1
  62. package/build/lib/utils/mjpeg.js +1 -1
  63. package/build/lib/utils/mjpeg.js.map +1 -1
  64. package/build/lib/utils/object.d.ts.map +1 -1
  65. package/build/lib/utils/object.js.map +1 -1
  66. package/lib/commands/actions.ts +4 -12
  67. package/lib/commands/alert.ts +2 -8
  68. package/lib/commands/app-management.ts +3 -4
  69. package/lib/commands/aut.ts +4 -10
  70. package/lib/commands/battery.ts +1 -5
  71. package/lib/commands/element.ts +15 -51
  72. package/lib/commands/find.ts +5 -6
  73. package/lib/commands/gestures.ts +5 -11
  74. package/lib/commands/keyboard.ts +10 -19
  75. package/lib/commands/misc.ts +3 -7
  76. package/lib/commands/screenshot.ts +8 -15
  77. package/lib/commands/viewport.ts +3 -10
  78. package/lib/commands/windows.ts +1 -5
  79. package/lib/css/index.ts +3 -5
  80. package/lib/css/ui-automator-emitter.ts +3 -9
  81. package/lib/doctor/optional-checks.ts +1 -1
  82. package/lib/doctor/required-checks.ts +1 -1
  83. package/lib/driver.ts +34 -61
  84. package/lib/logger.ts +1 -1
  85. package/lib/session-claim-handler.ts +21 -45
  86. package/lib/types.ts +2 -2
  87. package/lib/uiautomator2-server/core.ts +24 -60
  88. package/lib/uiautomator2-server/session.ts +13 -22
  89. package/lib/utils/app.ts +1 -0
  90. package/lib/utils/mjpeg.ts +8 -28
  91. package/lib/utils/object.ts +1 -4
  92. package/npm-shrinkwrap.json +74 -95
  93. package/package.json +21 -35
  94. package/scripts/reset.mjs +2 -8
@@ -1,6 +1,7 @@
1
1
  import {utils} from 'appium-android-driver';
2
2
  import {fs} from 'appium/support.js';
3
3
  import {SETTINGS_HELPER_ID} from 'io.appium.settings';
4
+
4
5
  import type {AndroidUiautomator2Driver} from '../driver.js';
5
6
  import {APKS_EXTENSION, APK_EXTENSION} from '../extensions.js';
6
7
  import {SERVER_PACKAGE_ID, SERVER_TEST_PACKAGE_ID} from '../uiautomator2-server/index.js';
@@ -17,10 +18,7 @@ export async function prepareSessionApp(this: AndroidUiautomator2Driver): Promis
17
18
  // assume is on the device and just launch via the appPackage
18
19
  this.log.info(`Starting '${this.opts.appPackage}' directly on the device`);
19
20
  } else {
20
- this.log.info(
21
- `Neither 'app' nor 'appPackage' was set. Starting UiAutomator2 ` +
22
- 'without the target application',
23
- );
21
+ this.log.info(`Neither 'app' nor 'appPackage' was set. Starting UiAutomator2 ` + 'without the target application');
24
22
  }
25
23
  }
26
24
 
@@ -49,9 +47,7 @@ export async function initAUT(this: AndroidUiautomator2Driver): Promise<void> {
49
47
  try {
50
48
  otherApps = utils.parseArray(this.opts.otherApps);
51
49
  } catch (e) {
52
- throw this.log.errorWithException(
53
- `Could not parse "otherApps" capability: ${(e as Error).message}`,
54
- );
50
+ throw this.log.errorWithException(`Could not parse "otherApps" capability: ${(e as Error).message}`);
55
51
  }
56
52
  otherApps = await Promise.all(
57
53
  otherApps.map((app) => this.helpers.configureApp(app, [APK_EXTENSION, APKS_EXTENSION])),
@@ -80,9 +76,7 @@ export async function initAUT(this: AndroidUiautomator2Driver): Promise<void> {
80
76
  }
81
77
  } else {
82
78
  if (this.opts.fullReset) {
83
- throw this.log.errorWithException(
84
- 'Full reset requires an app capability, use fastReset if app is not provided',
85
- );
79
+ throw this.log.errorWithException('Full reset requires an app capability, use fastReset if app is not provided');
86
80
  }
87
81
  this.log.debug('No app capability. Assuming it is already on the device');
88
82
  if (this.opts.fastReset && this.opts.appPackage) {
@@ -6,11 +6,7 @@ import type {BatteryInfo} from './types.js';
6
6
  * @returns Battery information including level (0.0-1.0) and state (charging, discharging, etc.).
7
7
  */
8
8
  export async function mobileGetBatteryInfo(this: AndroidUiautomator2Driver): Promise<BatteryInfo> {
9
- const result = (await this.uiautomator2.jwproxy.command(
10
- '/appium/device/battery_info',
11
- 'GET',
12
- {},
13
- )) as {
9
+ const result = (await this.uiautomator2.jwproxy.command('/appium/device/battery_info', 'GET', {})) as {
14
10
  status: BatteryInfo['state'];
15
11
  level: number;
16
12
  };
@@ -1,8 +1,9 @@
1
- import {PROTOCOLS} from 'appium/driver.js';
2
- import type {DoSetElementValueOpts} from 'appium-android-driver';
3
1
  import type {Element as AppiumElement, Position, Rect, Size} from '@appium/types';
4
- import type {AndroidUiautomator2Driver} from '../driver.js';
2
+ import type {DoSetElementValueOpts} from 'appium-android-driver';
5
3
  import type {Chromedriver} from 'appium-chromedriver';
4
+ import {PROTOCOLS} from 'appium/driver.js';
5
+
6
+ import type {AndroidUiautomator2Driver} from '../driver.js';
6
7
 
7
8
  /**
8
9
  * Gets the currently active element.
@@ -23,13 +24,7 @@ export async function getAttribute(
23
24
  attribute: string,
24
25
  elementId: string,
25
26
  ): Promise<string> {
26
- return String(
27
- await this.uiautomator2.jwproxy.command(
28
- `/element/${elementId}/attribute/${attribute}`,
29
- 'GET',
30
- {},
31
- ),
32
- );
27
+ return String(await this.uiautomator2.jwproxy.command(`/element/${elementId}/attribute/${attribute}`, 'GET', {}));
33
28
  }
34
29
 
35
30
  /**
@@ -37,10 +32,7 @@ export async function getAttribute(
37
32
  * @param elementId - ID of the element.
38
33
  * @returns True if the element is displayed, false otherwise.
39
34
  */
40
- export async function elementDisplayed(
41
- this: AndroidUiautomator2Driver,
42
- elementId: string,
43
- ): Promise<boolean> {
35
+ export async function elementDisplayed(this: AndroidUiautomator2Driver, elementId: string): Promise<boolean> {
44
36
  return toBool(await this.getAttribute('displayed', elementId));
45
37
  }
46
38
 
@@ -49,10 +41,7 @@ export async function elementDisplayed(
49
41
  * @param elementId - ID of the element.
50
42
  * @returns True if the element is enabled, false otherwise.
51
43
  */
52
- export async function elementEnabled(
53
- this: AndroidUiautomator2Driver,
54
- elementId: string,
55
- ): Promise<boolean> {
44
+ export async function elementEnabled(this: AndroidUiautomator2Driver, elementId: string): Promise<boolean> {
56
45
  return toBool(await this.getAttribute('enabled', elementId));
57
46
  }
58
47
 
@@ -61,10 +50,7 @@ export async function elementEnabled(
61
50
  * @param elementId - ID of the element.
62
51
  * @returns True if the element is selected, false otherwise.
63
52
  */
64
- export async function elementSelected(
65
- this: AndroidUiautomator2Driver,
66
- elementId: string,
67
- ): Promise<boolean> {
53
+ export async function elementSelected(this: AndroidUiautomator2Driver, elementId: string): Promise<boolean> {
68
54
  return toBool(await this.getAttribute('selected', elementId));
69
55
  }
70
56
 
@@ -74,11 +60,7 @@ export async function elementSelected(
74
60
  * @returns The element tag name.
75
61
  */
76
62
  export async function getName(this: AndroidUiautomator2Driver, elementId: string): Promise<string> {
77
- return (await this.uiautomator2.jwproxy.command(
78
- `/element/${elementId}/name`,
79
- 'GET',
80
- {},
81
- )) as string;
63
+ return (await this.uiautomator2.jwproxy.command(`/element/${elementId}/name`, 'GET', {})) as string;
82
64
  }
83
65
 
84
66
  /**
@@ -86,15 +68,8 @@ export async function getName(this: AndroidUiautomator2Driver, elementId: string
86
68
  * @param elementId - ID of the element.
87
69
  * @returns The element position coordinates (x, y).
88
70
  */
89
- export async function getLocation(
90
- this: AndroidUiautomator2Driver,
91
- elementId: string,
92
- ): Promise<Position> {
93
- return (await this.uiautomator2.jwproxy.command(
94
- `/element/${elementId}/location`,
95
- 'GET',
96
- {},
97
- )) as Position;
71
+ export async function getLocation(this: AndroidUiautomator2Driver, elementId: string): Promise<Position> {
72
+ return (await this.uiautomator2.jwproxy.command(`/element/${elementId}/location`, 'GET', {})) as Position;
98
73
  }
99
74
 
100
75
  /**
@@ -110,10 +85,7 @@ export async function getSize(this: AndroidUiautomator2Driver, elementId: string
110
85
  * Sets the value of an element using the upstream driver API.
111
86
  * @param params - Options containing the element ID and value to set.
112
87
  */
113
- export async function doSetElementValue(
114
- this: AndroidUiautomator2Driver,
115
- params: DoSetElementValueOpts,
116
- ): Promise<void> {
88
+ export async function doSetElementValue(this: AndroidUiautomator2Driver, params: DoSetElementValueOpts): Promise<void> {
117
89
  await this.uiautomator2.jwproxy.command(`/element/${params.elementId}/value`, 'POST', params);
118
90
  }
119
91
 
@@ -156,13 +128,8 @@ export async function click(this: AndroidUiautomator2Driver, element: string): P
156
128
  * @param element - ID of the element.
157
129
  * @returns Base64-encoded PNG screenshot of the element.
158
130
  */
159
- export async function getElementScreenshot(
160
- this: AndroidUiautomator2Driver,
161
- element: string,
162
- ): Promise<string> {
163
- return String(
164
- await this.uiautomator2.jwproxy.command(`/element/${element}/screenshot`, 'GET', {}),
165
- );
131
+ export async function getElementScreenshot(this: AndroidUiautomator2Driver, element: string): Promise<string> {
132
+ return String(await this.uiautomator2.jwproxy.command(`/element/${element}/screenshot`, 'GET', {}));
166
133
  }
167
134
 
168
135
  /**
@@ -178,10 +145,7 @@ export async function clear(this: AndroidUiautomator2Driver, elementId: string):
178
145
  * @param elementId - ID of the element.
179
146
  * @returns The element rectangle (x, y, width, height).
180
147
  */
181
- export async function getElementRect(
182
- this: AndroidUiautomator2Driver,
183
- elementId: string,
184
- ): Promise<Rect> {
148
+ export async function getElementRect(this: AndroidUiautomator2Driver, elementId: string): Promise<Rect> {
185
149
  if (!this.isWebContext()) {
186
150
  return (await this.uiautomator2.jwproxy.command(`/element/${elementId}/rect`, 'GET')) as Rect;
187
151
  }
@@ -1,6 +1,7 @@
1
- import {cssToNativeLocator} from '../css/index.js';
2
1
  import type {Element as AppiumElement} from '@appium/types';
3
2
  import type {FindElementOpts} from 'appium-android-driver';
3
+
4
+ import {cssToNativeLocator} from '../css/index.js';
4
5
  import type {AndroidUiautomator2Driver} from '../driver.js';
5
6
 
6
7
  // we override the xpath search for this first-visible-child selector, which
@@ -47,9 +48,7 @@ export async function doFindElementOrEls(
47
48
  this.opts.appPackage,
48
49
  ));
49
50
  }
50
- return (await uiautomator2.jwproxy.command(
51
- `/element${params.multiple ? 's' : ''}`,
52
- 'POST',
53
- params,
54
- )) as AppiumElement | AppiumElement[];
51
+ return (await uiautomator2.jwproxy.command(`/element${params.multiple ? 's' : ''}`, 'POST', params)) as
52
+ | AppiumElement
53
+ | AppiumElement[];
55
54
  }
@@ -1,8 +1,9 @@
1
+ import type {Element as AppiumElement, Position} from '@appium/types';
1
2
  import {errors} from 'appium/driver.js';
2
3
  import {util} from 'appium/support.js';
3
- import type {Element as AppiumElement, Position} from '@appium/types';
4
- import type {RelativeRect} from './types.js';
4
+
5
5
  import type {AndroidUiautomator2Driver} from '../driver.js';
6
+ import type {RelativeRect} from './types.js';
6
7
 
7
8
  /**
8
9
  * Performs a simple click/tap gesture.
@@ -247,9 +248,7 @@ export async function mobileScrollBackTo(
247
248
  elementToId?: string,
248
249
  ): Promise<void> {
249
250
  if (!elementId || !elementToId) {
250
- throw new errors.InvalidArgumentError(
251
- `Both elementId and elementToId arguments must be provided`,
252
- );
251
+ throw new errors.InvalidArgumentError(`Both elementId and elementToId arguments must be provided`);
253
252
  }
254
253
  await this.uiautomator2.jwproxy.command(
255
254
  `/appium/element/${util.unwrapElement(elementId)}/scroll_to/${util.unwrapElement(elementToId)}`,
@@ -290,12 +289,7 @@ function toPoint(x?: number, y?: number): Partial<Position> | undefined {
290
289
  return Number.isFinite(x) && Number.isFinite(y) ? {x, y} : undefined;
291
290
  }
292
291
 
293
- function toRect(
294
- left?: number,
295
- top?: number,
296
- width?: number,
297
- height?: number,
298
- ): RelativeRect | undefined {
292
+ function toRect(left?: number, top?: number, width?: number, height?: number): RelativeRect | undefined {
299
293
  return [left, top, width, height].some((v) => !Number.isFinite(v))
300
294
  ? undefined
301
295
  : ({left, top, width, height} as RelativeRect);
@@ -1,6 +1,7 @@
1
- import type {AndroidUiautomator2Driver} from '../driver.js';
2
1
  import type {SendKeysOpts} from 'appium-android-driver';
3
2
 
3
+ import type {AndroidUiautomator2Driver} from '../driver.js';
4
+
4
5
  /**
5
6
  * Presses a key code with optional metastate and flags.
6
7
  * @param keycode - Android key code to press.
@@ -57,16 +58,12 @@ export async function mobilePressKey(
57
58
  isLongPress: boolean = false,
58
59
  source?: number,
59
60
  ): Promise<void> {
60
- await this.uiautomator2.jwproxy.command(
61
- `/appium/device/${isLongPress ? 'long_' : ''}press_keycode`,
62
- 'POST',
63
- {
64
- keycode,
65
- metastate,
66
- flags,
67
- source,
68
- },
69
- );
61
+ await this.uiautomator2.jwproxy.command(`/appium/device/${isLongPress ? 'long_' : ''}press_keycode`, 'POST', {
62
+ keycode,
63
+ metastate,
64
+ flags,
65
+ source,
66
+ });
70
67
  }
71
68
 
72
69
  /**
@@ -75,10 +72,7 @@ export async function mobilePressKey(
75
72
  * @returns True if the input text has been successfully sent to adb.
76
73
  * @throws {errors.InvalidArgumentError} If the text argument is not provided.
77
74
  */
78
- export async function mobileType(
79
- this: AndroidUiautomator2Driver,
80
- text: string | number | boolean,
81
- ): Promise<boolean> {
75
+ export async function mobileType(this: AndroidUiautomator2Driver, text: string | number | boolean): Promise<boolean> {
82
76
  return await this.settingsApp.typeUnicode(String(text));
83
77
  }
84
78
 
@@ -86,10 +80,7 @@ export async function mobileType(
86
80
  * Sends keys to the current element.
87
81
  * @param params - Options containing the text to send and optional replace flag.
88
82
  */
89
- export async function doSendKeys(
90
- this: AndroidUiautomator2Driver,
91
- params: SendKeysOpts,
92
- ): Promise<void> {
83
+ export async function doSendKeys(this: AndroidUiautomator2Driver, params: SendKeysOpts): Promise<void> {
93
84
  await this.uiautomator2.jwproxy.command('/keys', 'POST', params);
94
85
  }
95
86
 
@@ -1,4 +1,5 @@
1
1
  import type {Orientation, StringRecord} from '@appium/types';
2
+
2
3
  import type {AndroidUiautomator2Driver} from '../driver.js';
3
4
 
4
5
  /**
@@ -21,10 +22,7 @@ export async function getOrientation(this: AndroidUiautomator2Driver): Promise<O
21
22
  * Sets the device orientation.
22
23
  * @param orientation - The desired orientation ('LANDSCAPE' or 'PORTRAIT').
23
24
  */
24
- export async function setOrientation(
25
- this: AndroidUiautomator2Driver,
26
- orientation: Orientation,
27
- ): Promise<void> {
25
+ export async function setOrientation(this: AndroidUiautomator2Driver, orientation: Orientation): Promise<void> {
28
26
  const normalizedOrientation = orientation.toUpperCase() as Orientation;
29
27
  await this.uiautomator2.jwproxy.command(`/orientation`, 'POST', {
30
28
  orientation: normalizedOrientation,
@@ -63,8 +61,6 @@ export async function mobileGetDeviceInfo(this: AndroidUiautomator2Driver): Prom
63
61
  /**
64
62
  * Resets the accessibility cache on the device.
65
63
  */
66
- export async function mobileResetAccessibilityCache(
67
- this: AndroidUiautomator2Driver,
68
- ): Promise<void> {
64
+ export async function mobileResetAccessibilityCache(this: AndroidUiautomator2Driver): Promise<void> {
69
65
  await this.uiautomator2.jwproxy.command('/appium/reset_ax_cache', 'POST', {});
70
66
  }
@@ -1,23 +1,21 @@
1
+ import type {StringRecord} from '@appium/types';
1
2
  import {imageUtil} from 'appium/support.js';
2
- import {isEmpty} from '../utils/index.js';
3
+
3
4
  import type {AndroidUiautomator2Driver} from '../driver.js';
5
+ import {isEmpty} from '../utils/index.js';
4
6
  import type {Screenshot} from './types.js';
5
- import type {StringRecord} from '@appium/types';
6
7
 
7
8
  // Matches SurfaceFlinger output format:
8
9
  // Physical: Display 4619827259835644672 (HWC display 0): port=0 pnpId=GGL displayName="EMU_display_0"
9
10
  // Virtual: Display 11529215049243506835 (Virtual display): displayName="Emulator 2D Display" uniqueId="..."
10
- const DISPLAY_PATTERN =
11
- /^Display\s+(\d+)\s+\((?:HWC\s+display\s+(\d+)|Virtual\s+display)\):.*?displayName="([^"]*)"/gm;
11
+ const DISPLAY_PATTERN = /^Display\s+(\d+)\s+\((?:HWC\s+display\s+(\d+)|Virtual\s+display)\):.*?displayName="([^"]*)"/gm;
12
12
 
13
13
  /**
14
14
  * Parses SurfaceFlinger display output to extract display information.
15
15
  * @param displaysInfo - The raw output from `adb shell dumpsys SurfaceFlinger --display-id`
16
16
  * @returns A record mapping display IDs to their information (without payload)
17
17
  */
18
- export function parseSurfaceFlingerDisplays(
19
- displaysInfo: string,
20
- ): Record<string, Partial<Screenshot>> {
18
+ export function parseSurfaceFlingerDisplays(displaysInfo: string): Record<string, Partial<Screenshot>> {
21
19
  const infos: Record<string, Partial<Screenshot>> = {};
22
20
  const lines = displaysInfo.split('\n');
23
21
 
@@ -30,9 +28,7 @@ export function parseSurfaceFlingerDisplays(
30
28
 
31
29
  // Determine if default: HWC display 0 is default, or first physical display if no HWC info
32
30
  const isDefault =
33
- hwcId !== undefined
34
- ? hwcId === '0'
35
- : !line.includes('Virtual') && Object.keys(infos).length === 0;
31
+ hwcId !== undefined ? hwcId === '0' : !line.includes('Virtual') && Object.keys(infos).length === 0;
36
32
 
37
33
  infos[matchedDisplayId] = {
38
34
  id: matchedDisplayId,
@@ -103,8 +99,7 @@ export async function mobileScreenshots(
103
99
  const toB64Screenshot = async (dispId: string): Promise<string> =>
104
100
  (await this.adb.takeScreenshot(dispId)).toString('base64');
105
101
 
106
- const displayIdStr: string | null =
107
- displayId == null || displayId === '' ? null : String(displayId);
102
+ const displayIdStr: string | null = displayId == null || displayId === '' ? null : String(displayId);
108
103
 
109
104
  if (displayIdStr) {
110
105
  if (!infos[displayIdStr]) {
@@ -121,9 +116,7 @@ export async function mobileScreenshots(
121
116
  };
122
117
  }
123
118
 
124
- const allInfos = Object.values(infos).filter(
125
- (info): info is Partial<Screenshot> & {id: string} => !!info?.id,
126
- );
119
+ const allInfos = Object.values(infos).filter((info): info is Partial<Screenshot> & {id: string} => !!info?.id);
127
120
  const screenshots = await Promise.all(allInfos.map((info) => toB64Screenshot(info.id)));
128
121
  for (let i = 0; i < allInfos.length; i++) {
129
122
  const info = allInfos[i];
@@ -1,4 +1,5 @@
1
1
  import type {Rect, Size} from '@appium/types';
2
+
2
3
  import type {AndroidUiautomator2Driver} from '../driver.js';
3
4
  import type {RelativeRect} from './types.js';
4
5
 
@@ -7,11 +8,7 @@ import type {RelativeRect} from './types.js';
7
8
  * @returns The status bar height in pixels.
8
9
  */
9
10
  export async function getStatusBarHeight(this: AndroidUiautomator2Driver): Promise<number> {
10
- const {statusBar} = (await this.uiautomator2.jwproxy.command(
11
- `/appium/device/system_bars`,
12
- 'GET',
13
- {},
14
- )) as {
11
+ const {statusBar} = (await this.uiautomator2.jwproxy.command(`/appium/device/system_bars`, 'GET', {})) as {
15
12
  statusBar: number;
16
13
  };
17
14
  return statusBar;
@@ -69,11 +66,7 @@ export async function getWindowRect(this: AndroidUiautomator2Driver): Promise<Re
69
66
  * @returns The display density value.
70
67
  */
71
68
  export async function getDisplayDensity(this: AndroidUiautomator2Driver): Promise<number> {
72
- return (await this.uiautomator2.jwproxy.command(
73
- '/appium/device/display_density',
74
- 'GET',
75
- {},
76
- )) as number;
69
+ return (await this.uiautomator2.jwproxy.command('/appium/device/display_density', 'GET', {})) as number;
77
70
  }
78
71
 
79
72
  /**
@@ -21,9 +21,5 @@ export async function mobileListWindows(
21
21
  * Gets a list of all displays available on the device.
22
22
  */
23
23
  export async function mobileListDisplays(this: AndroidUiautomator2Driver): Promise<DisplayInfo[]> {
24
- return (await this.uiautomator2.jwproxy.command(
25
- '/appium/list_displays',
26
- 'POST',
27
- {},
28
- )) as DisplayInfo[];
24
+ return (await this.uiautomator2.jwproxy.command('/appium/list_displays', 'POST', {})) as DisplayInfo[];
29
25
  }
package/lib/css/index.ts CHANGED
@@ -1,9 +1,10 @@
1
+ import type {CssTransformer, NativeLocator, StrategyKey} from '@appium/css-locator-to-native';
1
2
  import {errors} from 'appium/driver.js';
3
+
2
4
  import {memoize} from '../utils/index.js';
3
5
  import {UI_AUTOMATOR_EMITTER_KEY, UI_AUTOMATOR_STRATEGY} from './constants.js';
4
6
  import {ATTRIBUTE_SCHEMA} from './schema.js';
5
7
  import {UiAutomatorEmitter} from './ui-automator-emitter.js';
6
- import type {CssTransformer, NativeLocator, StrategyKey} from '@appium/css-locator-to-native';
7
8
 
8
9
  export {UI_AUTOMATOR_STRATEGY} from './constants.js';
9
10
 
@@ -29,10 +30,7 @@ const getTransformCss = memoize(async function loadTransformCss(): Promise<CssTr
29
30
  * @param appPackage - Optional application package used to qualify resource ids
30
31
  * @returns Native locator strategy name and selector string
31
32
  */
32
- export async function cssToNativeLocator(
33
- css: string,
34
- appPackage?: string | null,
35
- ): Promise<NativeLocator> {
33
+ export async function cssToNativeLocator(css: string, appPackage?: string | null): Promise<NativeLocator> {
36
34
  try {
37
35
  const transformCss = await getTransformCss();
38
36
  return transformCss(css, {appPackage});
@@ -1,10 +1,6 @@
1
+ import type {ParsedAttribute, ParsedRule, ParsedSelector, StrategyEmitter} from '@appium/css-locator-to-native';
2
+
1
3
  import {escapeRegExp} from '../utils/index.js';
2
- import type {
3
- ParsedAttribute,
4
- ParsedRule,
5
- ParsedSelector,
6
- StrategyEmitter,
7
- } from '@appium/css-locator-to-native';
8
4
 
9
5
  const BOOLEAN_ATTRS = new Set([
10
6
  'checkable',
@@ -136,9 +132,7 @@ export class UiAutomatorEmitter implements StrategyEmitter<UiAutomatorEmitterCon
136
132
  }
137
133
 
138
134
  function toSnakeCase(str: string): string {
139
- const tokens = str
140
- .split('-')
141
- .map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase());
135
+ const tokens = str.split('-').map((token) => token.charAt(0).toUpperCase() + token.slice(1).toLowerCase());
142
136
  const out = tokens.join('');
143
137
  return out.charAt(0).toLowerCase() + out.slice(1);
144
138
  }
@@ -1,5 +1,5 @@
1
- import {doctor} from 'appium-android-driver';
2
1
  import type {IDoctorCheck} from '@appium/types';
2
+ import {doctor} from 'appium-android-driver';
3
3
 
4
4
  export const optionalBundletoolCheck: IDoctorCheck = doctor.optionalBundletoolCheck;
5
5
  export const optionalGstreamerCheck: IDoctorCheck = doctor.optionalGstreamerCheck;
@@ -1,5 +1,5 @@
1
- import {doctor} from 'appium-android-driver';
2
1
  import type {IDoctorCheck} from '@appium/types';
2
+ import {doctor} from 'appium-android-driver';
3
3
 
4
4
  export const androidHomeCheck: IDoctorCheck = doctor.androidHomeCheck;
5
5
  export const javaHomeCheck: IDoctorCheck = doctor.javaHomeCheck;
package/lib/driver.ts CHANGED
@@ -12,30 +12,7 @@ import {DEFAULT_ADB_PORT, type ADB} from 'appium-adb';
12
12
  import {AndroidDriver, utils} from 'appium-android-driver';
13
13
  import {BaseDriver, DeviceSettings} from 'appium/driver.js';
14
14
  import {util} from 'appium/support.js';
15
- import UIAUTOMATOR2_CONSTRAINTS, {type Uiautomator2Constraints} from './constraints.js';
16
- import {newMethodMap} from './method-map.js';
17
- import {assignDefaults, memoize, MJpegStream} from './utils/index.js';
18
- import type {
19
- Uiautomator2Settings,
20
- Uiautomator2DeviceDetails,
21
- Uiautomator2DriverCaps,
22
- Uiautomator2DriverOpts,
23
- Uiautomator2StartSessionOpts,
24
- W3CUiautomator2DriverCaps,
25
- } from './types.js';
26
- import type {UiAutomator2Server} from './uiautomator2-server/index.js';
27
- import {
28
- allocateMjpegServerPort,
29
- allocateSystemPort,
30
- initServer,
31
- performExecution,
32
- performPostExecSetup,
33
- performPreExecSetup,
34
- releaseMjpegServerPort,
35
- releaseSystemPort,
36
- requireServer,
37
- startSession,
38
- } from './uiautomator2-server/index.js';
15
+
39
16
  import {
40
17
  mobileGetActionHistory,
41
18
  mobileScheduleAction,
@@ -86,14 +63,7 @@ import {
86
63
  mobileScrollGesture,
87
64
  mobileSwipeGesture,
88
65
  } from './commands/gestures.js';
89
- import {
90
- pressKeyCode,
91
- longPressKeyCode,
92
- mobilePressKey,
93
- mobileType,
94
- doSendKeys,
95
- keyevent,
96
- } from './commands/keyboard.js';
66
+ import {pressKeyCode, longPressKeyCode, mobilePressKey, mobileType, doSendKeys, keyevent} from './commands/keyboard.js';
97
67
  import {
98
68
  getPageSource,
99
69
  getOrientation,
@@ -103,7 +73,6 @@ import {
103
73
  mobileGetDeviceInfo,
104
74
  mobileResetAccessibilityCache,
105
75
  } from './commands/misc.js';
106
- import {mobileListWindows, mobileListDisplays} from './commands/windows.js';
107
76
  import {setUrl, mobileDeepLink, back} from './commands/navigation.js';
108
77
  import {
109
78
  mobileScreenshots,
@@ -120,8 +89,33 @@ import {
120
89
  getWindowSize,
121
90
  mobileViewPortRect,
122
91
  } from './commands/viewport.js';
92
+ import {mobileListWindows, mobileListDisplays} from './commands/windows.js';
93
+ import UIAUTOMATOR2_CONSTRAINTS, {type Uiautomator2Constraints} from './constraints.js';
123
94
  import {executeMethodMap} from './execute-method-map.js';
95
+ import {newMethodMap} from './method-map.js';
124
96
  import {sessionClaimHandler} from './session-claim-handler.js';
97
+ import type {
98
+ Uiautomator2Settings,
99
+ Uiautomator2DeviceDetails,
100
+ Uiautomator2DriverCaps,
101
+ Uiautomator2DriverOpts,
102
+ Uiautomator2StartSessionOpts,
103
+ W3CUiautomator2DriverCaps,
104
+ } from './types.js';
105
+ import type {UiAutomator2Server} from './uiautomator2-server/index.js';
106
+ import {
107
+ allocateMjpegServerPort,
108
+ allocateSystemPort,
109
+ initServer,
110
+ performExecution,
111
+ performPostExecSetup,
112
+ performPreExecSetup,
113
+ releaseMjpegServerPort,
114
+ releaseSystemPort,
115
+ requireServer,
116
+ startSession,
117
+ } from './uiautomator2-server/index.js';
118
+ import {assignDefaults, memoize, MJpegStream} from './utils/index.js';
125
119
 
126
120
  // NO_PROXY contains the paths that we never want to proxy to UiAutomator2 server.
127
121
  // TODO: Add the list of paths that we never want to proxy to UiAutomator2 server.
@@ -348,14 +342,7 @@ class AndroidUiautomator2Driver
348
342
 
349
343
  super(opts, shouldValidateCaps);
350
344
 
351
- this.locatorStrategies = [
352
- 'xpath',
353
- 'id',
354
- 'class name',
355
- 'accessibility id',
356
- 'css selector',
357
- '-android uiautomator',
358
- ];
345
+ this.locatorStrategies = ['xpath', 'id', 'class name', 'accessibility id', 'css selector', '-android uiautomator'];
359
346
  this.desiredCapConstraints = structuredClone(UIAUTOMATOR2_CONSTRAINTS);
360
347
  this.jwpProxyActive = false;
361
348
  this.jwpProxyAvoid = NO_PROXY;
@@ -442,9 +429,7 @@ class AndroidUiautomator2Driver
442
429
  try {
443
430
  activity = await this.adb.resolveLaunchableActivity(pkg);
444
431
  } catch (e) {
445
- this.log.warn(
446
- `Using the default ${pkg} activity ${activity}. Original error: ${(e as Error).message}`,
447
- );
432
+ this.log.warn(`Using the default ${pkg} activity ${activity}. Original error: ${(e as Error).message}`);
448
433
  }
449
434
  this.opts.appPackage = this.caps.appPackage = pkg;
450
435
  this.opts.appActivity = this.caps.appActivity = activity;
@@ -496,11 +481,7 @@ class AndroidUiautomator2Driver
496
481
  override async getSession(): Promise<SingularSessionData<Uiautomator2Constraints>> {
497
482
  const sessionData = await BaseDriver.prototype.getSession.call(this);
498
483
  this.log.debug('Getting session details from server to mix in');
499
- const uia2Data = (await this.requireUiautomator2().jwproxy.command(
500
- '/',
501
- 'GET',
502
- {},
503
- )) as StringRecord;
484
+ const uia2Data = (await this.requireUiautomator2().jwproxy.command('/', 'GET', {})) as StringRecord;
504
485
  return {...sessionData, ...uia2Data};
505
486
  }
506
487
 
@@ -560,8 +541,7 @@ class AndroidUiautomator2Driver
560
541
  if (this.opts.appPackage) {
561
542
  if (
562
543
  !this.isChromeSession &&
563
- ((!this.opts.dontStopAppOnReset && !this.opts.noReset) ||
564
- (this.opts.noReset && this.opts.shouldTerminateApp))
544
+ ((!this.opts.dontStopAppOnReset && !this.opts.noReset) || (this.opts.noReset && this.opts.shouldTerminateApp))
565
545
  ) {
566
546
  try {
567
547
  await this.adb.forceStop(this.opts.appPackage);
@@ -570,9 +550,7 @@ class AndroidUiautomator2Driver
570
550
  }
571
551
  }
572
552
  if (this.opts.fullReset && !this.opts.skipUninstall) {
573
- this.log.debug(
574
- `Capability 'fullReset' set to 'true', Uninstalling '${this.opts.appPackage}'`,
575
- );
553
+ this.log.debug(`Capability 'fullReset' set to 'true', Uninstalling '${this.opts.appPackage}'`);
576
554
  try {
577
555
  await this.adb.uninstallApk(this.opts.appPackage);
578
556
  } catch (err) {
@@ -647,10 +625,7 @@ class AndroidUiautomator2Driver
647
625
  this.jwpProxyAvoid = NO_PROXY;
648
626
  }
649
627
  if (this.opts.nativeWebScreenshot) {
650
- this.jwpProxyAvoid = [
651
- ...this.jwpProxyAvoid,
652
- ['GET', new RegExp('^/session/[^/]+/screenshot')],
653
- ];
628
+ this.jwpProxyAvoid = [...this.jwpProxyAvoid, ['GET', new RegExp('^/session/[^/]+/screenshot')]];
654
629
  }
655
630
 
656
631
  return this.jwpProxyAvoid;
@@ -672,9 +647,7 @@ class AndroidUiautomator2Driver
672
647
  }
673
648
 
674
649
  // needed to make the typechecker happy
675
- override async getAppiumSessionCapabilities(): Promise<
676
- SessionCapabilities<Uiautomator2Constraints>
677
- > {
650
+ override async getAppiumSessionCapabilities(): Promise<SessionCapabilities<Uiautomator2Constraints>> {
678
651
  return (await super.getAppiumSessionCapabilities()) as SessionCapabilities<Uiautomator2Constraints>;
679
652
  }
680
653