appium-android-driver 12.6.6 → 12.7.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 (143) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/lib/commands/app-management.d.ts +10 -0
  3. package/build/lib/commands/app-management.d.ts.map +1 -1
  4. package/build/lib/commands/app-management.js +21 -4
  5. package/build/lib/commands/app-management.js.map +1 -1
  6. package/build/lib/commands/appearance.d.ts.map +1 -1
  7. package/build/lib/commands/appearance.js.map +1 -1
  8. package/build/lib/commands/bidi/models.d.ts.map +1 -1
  9. package/build/lib/commands/bidi/models.js.map +1 -1
  10. package/build/lib/commands/bidi/types.js +0 -1
  11. package/build/lib/commands/bidi/types.js.map +1 -1
  12. package/build/lib/commands/bluetooth.d.ts +1 -1
  13. package/build/lib/commands/bluetooth.d.ts.map +1 -1
  14. package/build/lib/commands/bluetooth.js.map +1 -1
  15. package/build/lib/commands/context/exports.d.ts.map +1 -1
  16. package/build/lib/commands/context/exports.js.map +1 -1
  17. package/build/lib/commands/context/helpers.d.ts.map +1 -1
  18. package/build/lib/commands/context/helpers.js +1 -2
  19. package/build/lib/commands/context/helpers.js.map +1 -1
  20. package/build/lib/commands/device/common.d.ts.map +1 -1
  21. package/build/lib/commands/device/common.js +2 -3
  22. package/build/lib/commands/device/common.js.map +1 -1
  23. package/build/lib/commands/device/emulator-actions.d.ts.map +1 -1
  24. package/build/lib/commands/device/emulator-actions.js.map +1 -1
  25. package/build/lib/commands/device/utils.d.ts.map +1 -1
  26. package/build/lib/commands/device/utils.js +2 -2
  27. package/build/lib/commands/device/utils.js.map +1 -1
  28. package/build/lib/commands/deviceidle.d.ts +1 -1
  29. package/build/lib/commands/deviceidle.d.ts.map +1 -1
  30. package/build/lib/commands/deviceidle.js.map +1 -1
  31. package/build/lib/commands/element.d.ts.map +1 -1
  32. package/build/lib/commands/element.js +1 -1
  33. package/build/lib/commands/element.js.map +1 -1
  34. package/build/lib/commands/execute.d.ts.map +1 -1
  35. package/build/lib/commands/execute.js +1 -2
  36. package/build/lib/commands/execute.js.map +1 -1
  37. package/build/lib/commands/file-actions.d.ts.map +1 -1
  38. package/build/lib/commands/file-actions.js.map +1 -1
  39. package/build/lib/commands/geolocation.d.ts.map +1 -1
  40. package/build/lib/commands/geolocation.js.map +1 -1
  41. package/build/lib/commands/gestures.d.ts.map +1 -1
  42. package/build/lib/commands/gestures.js.map +1 -1
  43. package/build/lib/commands/image-injection.d.ts.map +1 -1
  44. package/build/lib/commands/image-injection.js.map +1 -1
  45. package/build/lib/commands/ime.d.ts.map +1 -1
  46. package/build/lib/commands/ime.js.map +1 -1
  47. package/build/lib/commands/intent.d.ts.map +1 -1
  48. package/build/lib/commands/intent.js +2 -8
  49. package/build/lib/commands/intent.js.map +1 -1
  50. package/build/lib/commands/keyboard.d.ts.map +1 -1
  51. package/build/lib/commands/keyboard.js.map +1 -1
  52. package/build/lib/commands/legacy.d.ts.map +1 -1
  53. package/build/lib/commands/legacy.js.map +1 -1
  54. package/build/lib/commands/lock/exports.d.ts.map +1 -1
  55. package/build/lib/commands/lock/exports.js.map +1 -1
  56. package/build/lib/commands/lock/helpers.d.ts.map +1 -1
  57. package/build/lib/commands/lock/helpers.js.map +1 -1
  58. package/build/lib/commands/log.d.ts.map +1 -1
  59. package/build/lib/commands/log.js +5 -3
  60. package/build/lib/commands/log.js.map +1 -1
  61. package/build/lib/commands/misc.d.ts.map +1 -1
  62. package/build/lib/commands/misc.js.map +1 -1
  63. package/build/lib/commands/network.d.ts.map +1 -1
  64. package/build/lib/commands/network.js +1 -1
  65. package/build/lib/commands/network.js.map +1 -1
  66. package/build/lib/commands/nfc.d.ts.map +1 -1
  67. package/build/lib/commands/nfc.js.map +1 -1
  68. package/build/lib/commands/performance.d.ts.map +1 -1
  69. package/build/lib/commands/performance.js.map +1 -1
  70. package/build/lib/commands/permissions.d.ts +4 -4
  71. package/build/lib/commands/permissions.d.ts.map +1 -1
  72. package/build/lib/commands/permissions.js +1 -3
  73. package/build/lib/commands/permissions.js.map +1 -1
  74. package/build/lib/commands/recordscreen.d.ts.map +1 -1
  75. package/build/lib/commands/recordscreen.js.map +1 -1
  76. package/build/lib/commands/resources.js +3 -4
  77. package/build/lib/commands/resources.js.map +1 -1
  78. package/build/lib/commands/shell.d.ts.map +1 -1
  79. package/build/lib/commands/streamscreen.js.map +1 -1
  80. package/build/lib/commands/system-bars.d.ts.map +1 -1
  81. package/build/lib/commands/system-bars.js +4 -4
  82. package/build/lib/commands/system-bars.js.map +1 -1
  83. package/build/lib/commands/time.d.ts.map +1 -1
  84. package/build/lib/commands/time.js.map +1 -1
  85. package/build/lib/constraints.js +2 -2
  86. package/build/lib/driver.d.ts +8 -1
  87. package/build/lib/driver.d.ts.map +1 -1
  88. package/build/lib/driver.js +1 -0
  89. package/build/lib/driver.js.map +1 -1
  90. package/build/lib/execute-method-map.d.ts +6 -0
  91. package/build/lib/execute-method-map.d.ts.map +1 -1
  92. package/build/lib/execute-method-map.js +38 -64
  93. package/build/lib/execute-method-map.js.map +1 -1
  94. package/build/lib/method-map.js +54 -54
  95. package/build/lib/utils.d.ts.map +1 -1
  96. package/build/lib/utils.js.map +1 -1
  97. package/lib/commands/app-management.ts +54 -30
  98. package/lib/commands/appearance.ts +1 -4
  99. package/lib/commands/bidi/models.ts +12 -10
  100. package/lib/commands/bidi/types.ts +1 -1
  101. package/lib/commands/bluetooth.ts +3 -7
  102. package/lib/commands/context/cache.ts +0 -1
  103. package/lib/commands/context/exports.ts +3 -14
  104. package/lib/commands/context/helpers.ts +7 -8
  105. package/lib/commands/device/common.ts +51 -52
  106. package/lib/commands/device/emulator-actions.ts +15 -34
  107. package/lib/commands/device/emulator-console.ts +0 -1
  108. package/lib/commands/device/utils.ts +4 -3
  109. package/lib/commands/deviceidle.ts +1 -2
  110. package/lib/commands/element.ts +10 -38
  111. package/lib/commands/execute.ts +3 -5
  112. package/lib/commands/file-actions.ts +4 -17
  113. package/lib/commands/geolocation.ts +21 -39
  114. package/lib/commands/gestures.ts +1 -5
  115. package/lib/commands/image-injection.ts +9 -8
  116. package/lib/commands/ime.ts +5 -17
  117. package/lib/commands/intent.ts +58 -57
  118. package/lib/commands/keyboard.ts +6 -21
  119. package/lib/commands/legacy.ts +4 -11
  120. package/lib/commands/lock/exports.ts +4 -2
  121. package/lib/commands/lock/helpers.ts +4 -1
  122. package/lib/commands/log.ts +15 -25
  123. package/lib/commands/media-projection.ts +0 -1
  124. package/lib/commands/memory.ts +0 -1
  125. package/lib/commands/misc.ts +6 -20
  126. package/lib/commands/network.ts +9 -28
  127. package/lib/commands/nfc.ts +2 -6
  128. package/lib/commands/performance.ts +2 -8
  129. package/lib/commands/permissions.ts +10 -9
  130. package/lib/commands/recordscreen.ts +16 -18
  131. package/lib/commands/resources.ts +6 -7
  132. package/lib/commands/shell.ts +1 -1
  133. package/lib/commands/streamscreen.ts +2 -7
  134. package/lib/commands/system-bars.ts +32 -38
  135. package/lib/commands/time.ts +3 -10
  136. package/lib/constraints.ts +2 -2
  137. package/lib/doctor/checks.ts +0 -1
  138. package/lib/doctor/utils.ts +0 -1
  139. package/lib/driver.ts +9 -20
  140. package/lib/execute-method-map.ts +38 -64
  141. package/lib/method-map.ts +56 -57
  142. package/lib/utils.ts +5 -6
  143. package/package.json +4 -3
@@ -1,4 +1,4 @@
1
- import { errors } from 'appium/driver';
1
+ import {errors} from 'appium/driver';
2
2
  import type {AndroidDriver} from '../driver';
3
3
 
4
4
  const ISSUE_URL = 'https://github.com/appium/appium/issues/15807';
@@ -9,9 +9,7 @@ const ISSUE_URL = 'https://github.com/appium/appium/issues/15807';
9
9
  * @returns Promise that resolves when the app is launched.
10
10
  * @throws {errors.UnsupportedOperationError} This API is not supported anymore.
11
11
  */
12
- export async function launchApp(
13
- this: AndroidDriver,
14
- ): Promise<void> {
12
+ export async function launchApp(this: AndroidDriver): Promise<void> {
15
13
  throw new errors.UnsupportedOperationError(`This API is not supported anymore. See ${ISSUE_URL}`);
16
14
  }
17
15
 
@@ -21,9 +19,7 @@ export async function launchApp(
21
19
  * @returns Promise that resolves when the app is closed.
22
20
  * @throws {errors.UnsupportedOperationError} This API is not supported anymore.
23
21
  */
24
- export async function closeApp(
25
- this: AndroidDriver,
26
- ): Promise<void> {
22
+ export async function closeApp(this: AndroidDriver): Promise<void> {
27
23
  throw new errors.UnsupportedOperationError(`This API is not supported anymore. See ${ISSUE_URL}`);
28
24
  }
29
25
 
@@ -33,9 +29,6 @@ export async function closeApp(
33
29
  * @returns Promise that resolves when the app is reset.
34
30
  * @throws {errors.UnsupportedOperationError} This API is not supported anymore.
35
31
  */
36
- export async function reset(
37
- this: AndroidDriver,
38
- ): Promise<void> {
32
+ export async function reset(this: AndroidDriver): Promise<void> {
39
33
  throw new errors.UnsupportedOperationError(`This API is not supported anymore. See ${ISSUE_URL}`);
40
34
  }
41
-
@@ -127,7 +127,10 @@ export async function unlockWithOptions(
127
127
  credentialType: toCredentialType(unlockType as UnlockType),
128
128
  });
129
129
  } else {
130
- const unlockMethodMap: Record<string, (this: AndroidDriver, caps: AndroidDriverCaps) => Promise<void>> = {
130
+ const unlockMethodMap: Record<
131
+ string,
132
+ (this: AndroidDriver, caps: AndroidDriverCaps) => Promise<void>
133
+ > = {
131
134
  [PIN_UNLOCK]: pinUnlock,
132
135
  [PIN_UNLOCK_KEY_EVENT]: pinUnlockWithKeyEvent,
133
136
  [PASSWORD_UNLOCK]: passwordUnlock,
@@ -144,4 +147,3 @@ export async function unlockWithOptions(
144
147
  }
145
148
 
146
149
  // #endregion
147
-
@@ -331,7 +331,10 @@ export function getPatternActions(
331
331
  * @param timeoutMs - Optional timeout in milliseconds (default: 2000)
332
332
  * @throws {Error} If the device fails to unlock within the timeout
333
333
  */
334
- export async function verifyUnlock(this: AndroidDriver, timeoutMs: number | null = null): Promise<void> {
334
+ export async function verifyUnlock(
335
+ this: AndroidDriver,
336
+ timeoutMs: number | null = null,
337
+ ): Promise<void> {
335
338
  try {
336
339
  await waitForCondition(async () => !(await this.adb.isScreenLocked()), {
337
340
  waitMs: timeoutMs ?? 2000,
@@ -12,9 +12,9 @@ import {
12
12
  nativeLogEntryToSeleniumEntry,
13
13
  type LogEntry,
14
14
  } from '../utils';
15
- import { NATIVE_WIN } from './context/helpers';
16
- import { BIDI_EVENT_NAME } from './bidi/constants';
17
- import { makeLogEntryAddedEvent } from './bidi/models';
15
+ import {NATIVE_WIN} from './context/helpers';
16
+ import {BIDI_EVENT_NAME} from './bidi/constants';
17
+ import {makeLogEntryAddedEvent} from './bidi/models';
18
18
  import type {AndroidDriver} from '../driver';
19
19
 
20
20
  export const supportedLogTypes = {
@@ -49,9 +49,7 @@ export const supportedLogTypes = {
49
49
  *
50
50
  * @returns Promise that resolves when the logcat broadcasting websocket is started.
51
51
  */
52
- export async function mobileStartLogsBroadcast(
53
- this: AndroidDriver,
54
- ): Promise<void> {
52
+ export async function mobileStartLogsBroadcast(this: AndroidDriver): Promise<void> {
55
53
  const server = this.server as AppiumServer;
56
54
  const pathname = WEBSOCKET_ENDPOINT(this.sessionId as string);
57
55
  if (!_.isEmpty(await server.getWebSocketHandlers(pathname))) {
@@ -113,9 +111,7 @@ export async function mobileStartLogsBroadcast(
113
111
  *
114
112
  * @returns Promise that resolves when the logcat broadcasting websocket is stopped.
115
113
  */
116
- export async function mobileStopLogsBroadcast(
117
- this: AndroidDriver,
118
- ): Promise<void> {
114
+ export async function mobileStopLogsBroadcast(this: AndroidDriver): Promise<void> {
119
115
  const pathname = WEBSOCKET_ENDPOINT(this.sessionId as string);
120
116
  const server = this.server as AppiumServer;
121
117
  if (_.isEmpty(await server.getWebSocketHandlers(pathname))) {
@@ -134,13 +130,14 @@ export async function mobileStopLogsBroadcast(
134
130
  *
135
131
  * @returns Promise that resolves to an array of log type names.
136
132
  */
137
- export async function getLogTypes(
138
- this: AndroidDriver,
139
- ): Promise<string[]> {
133
+ export async function getLogTypes(this: AndroidDriver): Promise<string[]> {
140
134
  // XXX why doesn't `super` work here?
141
135
  const nativeLogTypes = await BaseDriver.prototype.getLogTypes.call(this);
142
136
  if (this.isWebContext()) {
143
- const webLogTypes = await (this.chromedriver as Chromedriver).jwproxy.command('/log/types', 'GET') as string[];
137
+ const webLogTypes = (await (this.chromedriver as Chromedriver).jwproxy.command(
138
+ '/log/types',
139
+ 'GET',
140
+ )) as string[];
144
141
  return [...nativeLogTypes, ...webLogTypes];
145
142
  }
146
143
  return nativeLogTypes;
@@ -161,12 +158,7 @@ export function assignBiDiLogListener<EE extends EventEmitter>(
161
158
  logEmitter: EE,
162
159
  properties: BiDiListenerProperties,
163
160
  ): [EE, LogListener] {
164
- const {
165
- type,
166
- context = NATIVE_WIN,
167
- srcEventName = 'output',
168
- entryTransformer,
169
- } = properties;
161
+ const {type, context = NATIVE_WIN, srcEventName = 'output', entryTransformer} = properties;
170
162
  const listener: LogListener = (logEntry: LogEntry) => {
171
163
  const finalEntry = entryTransformer ? entryTransformer(logEntry) : logEntry;
172
164
  this.eventEmitter.emit(BIDI_EVENT_NAME, makeLogEntryAddedEvent(finalEntry, context, type));
@@ -181,12 +173,11 @@ export function assignBiDiLogListener<EE extends EventEmitter>(
181
173
  * @param logType The type of logs to retrieve.
182
174
  * @returns Promise that resolves to the logs for the specified type.
183
175
  */
184
- export async function getLog(
185
- this: AndroidDriver,
186
- logType: string,
187
- ): Promise<any> {
176
+ export async function getLog(this: AndroidDriver, logType: string): Promise<any> {
188
177
  if (this.isWebContext() && !_.keys(this.supportedLogTypes).includes(logType)) {
189
- return await (this.chromedriver as Chromedriver).jwproxy.command('/log', 'POST', {type: logType});
178
+ return await (this.chromedriver as Chromedriver).jwproxy.command('/log', 'POST', {
179
+ type: logType,
180
+ });
190
181
  }
191
182
  return await BaseDriver.prototype.getLog.call(this, logType);
192
183
  }
@@ -212,4 +203,3 @@ export interface BiDiListenerProperties {
212
203
  }
213
204
 
214
205
  export type LogListener = (logEntry: LogEntry) => any;
215
-
@@ -198,4 +198,3 @@ interface UploadOptions {
198
198
  formFields?: FormFields;
199
199
  uploadTimeout?: number;
200
200
  }
201
-
@@ -26,4 +26,3 @@ export async function mobileSendTrimMemory(
26
26
 
27
27
  await this.adb.shell(['am', 'send-trim-memory', pkg, level]);
28
28
  }
29
-
@@ -9,9 +9,7 @@ import type {SmsListResult, ListSmsOpts} from './types';
9
9
  * @returns Promise that resolves to the window size (width, height).
10
10
  * @throws {errors.NotImplementedError} This method is not implemented.
11
11
  */
12
- export async function getWindowSize(
13
- this: AndroidDriver,
14
- ): Promise<Size> {
12
+ export async function getWindowSize(this: AndroidDriver): Promise<Size> {
15
13
  throw new errors.NotImplementedError('Not implemented');
16
14
  }
17
15
 
@@ -20,9 +18,7 @@ export async function getWindowSize(
20
18
  *
21
19
  * @returns Promise that resolves to the window rectangle.
22
20
  */
23
- export async function getWindowRect(
24
- this: AndroidDriver,
25
- ): Promise<Rect> {
21
+ export async function getWindowRect(this: AndroidDriver): Promise<Rect> {
26
22
  const {width, height} = await this.getWindowSize();
27
23
  return {
28
24
  width,
@@ -41,10 +37,7 @@ export async function getWindowRect(
41
37
  * @param uri The Android URI to navigate to.
42
38
  * @returns Promise that resolves when the URI is opened.
43
39
  */
44
- export async function setUrl(
45
- this: AndroidDriver,
46
- uri: string,
47
- ): Promise<void> {
40
+ export async function setUrl(this: AndroidDriver, uri: string): Promise<void> {
48
41
  await this.adb.startUri(uri, this.opts.appPackage as string);
49
42
  }
50
43
 
@@ -54,9 +47,7 @@ export async function setUrl(
54
47
  * @returns Promise that resolves to the display density value.
55
48
  * @throws {Error} If the display density cannot be retrieved.
56
49
  */
57
- export async function getDisplayDensity(
58
- this: AndroidDriver,
59
- ): Promise<number> {
50
+ export async function getDisplayDensity(this: AndroidDriver): Promise<number> {
60
51
  // first try the property for devices
61
52
  let out = await this.adb.shell(['getprop', 'ro.sf.lcd_density']);
62
53
  if (out) {
@@ -85,9 +76,7 @@ export async function getDisplayDensity(
85
76
  *
86
77
  * @returns Promise that resolves to an object containing notification information.
87
78
  */
88
- export async function mobileGetNotifications(
89
- this: AndroidDriver,
90
- ): Promise<StringRecord> {
79
+ export async function mobileGetNotifications(this: AndroidDriver): Promise<StringRecord> {
91
80
  return await this.settingsApp.getNotifications();
92
81
  }
93
82
 
@@ -110,9 +99,6 @@ export async function mobileListSms(
110
99
  * @returns Promise that resolves when the notifications panel is opened.
111
100
  * @throws {errors.NotImplementedError} This method is not implemented.
112
101
  */
113
- export async function openNotifications(
114
- this: AndroidDriver,
115
- ): Promise<void> {
102
+ export async function openNotifications(this: AndroidDriver): Promise<void> {
116
103
  throw new errors.NotImplementedError('Not implemented');
117
104
  }
118
-
@@ -26,9 +26,7 @@ const SUPPORTED_SERVICE_NAMES: ServiceType[] = [
26
26
  * - Bit 1 (0b010) = Wi-Fi
27
27
  * - Bit 2 (0b100) = Data connection
28
28
  */
29
- export async function getNetworkConnection(
30
- this: AndroidDriver,
31
- ): Promise<number> {
29
+ export async function getNetworkConnection(this: AndroidDriver): Promise<number> {
32
30
  this.log.info('Getting network connection');
33
31
  const airplaneModeOn = await this.adb.isAirplaneModeOn();
34
32
  let connection = airplaneModeOn ? AIRPLANE_MODE_MASK : 0;
@@ -49,9 +47,7 @@ export async function getNetworkConnection(
49
47
  *
50
48
  * @returns Promise that resolves to `true` if Wi-Fi is enabled, `false` otherwise.
51
49
  */
52
- export async function isWifiOn(
53
- this: AndroidDriver,
54
- ): Promise<boolean> {
50
+ export async function isWifiOn(this: AndroidDriver): Promise<boolean> {
55
51
  return await this.adb.isWifiOn();
56
52
  }
57
53
 
@@ -148,7 +144,7 @@ export async function mobileGetConnectivity(
148
144
  await B.all(_.values(statePromises));
149
145
  return _.reduce(
150
146
  statePromises,
151
- (state, v, k) => _.isUndefined(v.value()) ? state : {...state, [k]: Boolean(v.value())},
147
+ (state, v, k) => (_.isUndefined(v.value()) ? state : {...state, [k]: Boolean(v.value())}),
152
148
  {} as GetConnectivityResult,
153
149
  );
154
150
  }
@@ -164,10 +160,7 @@ export async function mobileGetConnectivity(
164
160
  * - Bit 2 (0b100) = Data connection
165
161
  * @returns Promise that resolves to the current network connection state after the change.
166
162
  */
167
- export async function setNetworkConnection(
168
- this: AndroidDriver,
169
- type: number,
170
- ): Promise<number> {
163
+ export async function setNetworkConnection(this: AndroidDriver, type: number): Promise<number> {
171
164
  this.log.info('Setting network connection');
172
165
  // decode the input
173
166
  const shouldEnableAirplaneMode = (type & AIRPLANE_MODE_MASK) !== 0;
@@ -232,10 +225,7 @@ export async function setNetworkConnection(
232
225
  * @param isOn `true` to enable Wi-Fi, `false` to disable it.
233
226
  * @returns Promise that resolves when the Wi-Fi state is set.
234
227
  */
235
- export async function setWifiState(
236
- this: AndroidDriver,
237
- isOn: boolean,
238
- ): Promise<void> {
228
+ export async function setWifiState(this: AndroidDriver, isOn: boolean): Promise<void> {
239
229
  await this.settingsApp.setWifiState(isOn, this.isEmulator());
240
230
  }
241
231
 
@@ -246,10 +236,7 @@ export async function setWifiState(
246
236
  * @param isOn `true` to enable mobile data, `false` to disable it.
247
237
  * @returns Promise that resolves when the data connection state is set.
248
238
  */
249
- export async function setDataState(
250
- this: AndroidDriver,
251
- isOn: boolean,
252
- ): Promise<void> {
239
+ export async function setDataState(this: AndroidDriver, isOn: boolean): Promise<void> {
253
240
  await this.settingsApp.setDataState(isOn, this.isEmulator());
254
241
  }
255
242
 
@@ -259,9 +246,7 @@ export async function setDataState(
259
246
  * @since Android 12 (only real devices, emulators work in all APIs)
260
247
  * @returns Promise that resolves when the data connection state is toggled.
261
248
  */
262
- export async function toggleData(
263
- this: AndroidDriver,
264
- ): Promise<void> {
249
+ export async function toggleData(this: AndroidDriver): Promise<void> {
265
250
  const isOn = await this.adb.isDataOn();
266
251
  this.log.info(`Turning network data ${!isOn ? 'on' : 'off'}`);
267
252
  await this.setDataState(!isOn);
@@ -273,9 +258,7 @@ export async function toggleData(
273
258
  * @since Android 12 (only real devices, emulators work in all APIs)
274
259
  * @returns Promise that resolves when the Wi-Fi state is toggled.
275
260
  */
276
- export async function toggleWiFi(
277
- this: AndroidDriver,
278
- ): Promise<void> {
261
+ export async function toggleWiFi(this: AndroidDriver): Promise<void> {
279
262
  const isOn = await this.adb.isWifiOn();
280
263
  this.log.info(`Turning WiFi ${!isOn ? 'on' : 'off'}`);
281
264
  await this.setWifiState(!isOn);
@@ -287,9 +270,7 @@ export async function toggleWiFi(
287
270
  * @since Android 12 (only real devices, emulators work in all APIs)
288
271
  * @returns Promise that resolves when the airplane mode state is toggled.
289
272
  */
290
- export async function toggleFlightMode(
291
- this: AndroidDriver,
292
- ): Promise<void> {
273
+ export async function toggleFlightMode(this: AndroidDriver): Promise<void> {
293
274
  const flightMode = !(await this.adb.isAirplaneModeOn());
294
275
  this.log.info(`Turning flight mode ${flightMode ? 'on' : 'off'}`);
295
276
  await this.adb.setAirplaneMode(flightMode);
@@ -17,10 +17,7 @@ const SUPPORTED_ACTIONS = {
17
17
  * or there was a failure while performing the action.
18
18
  * @throws {errors.InvalidArgumentError} If the action is not one of the supported actions.
19
19
  */
20
- export async function mobileNfc(
21
- this: AndroidDriver,
22
- action: NfcAction,
23
- ): Promise<void> {
20
+ export async function mobileNfc(this: AndroidDriver, action: NfcAction): Promise<void> {
24
21
  switch (action) {
25
22
  case SUPPORTED_ACTIONS.ENABLE:
26
23
  await this.adb.setNfcOn(true);
@@ -30,8 +27,7 @@ export async function mobileNfc(
30
27
  break;
31
28
  default:
32
29
  throw new errors.InvalidArgumentError(
33
- `You must provide a valid 'action' argument. Supported actions are: ${_.values(SUPPORTED_ACTIONS)}`
30
+ `You must provide a valid 'action' argument. Supported actions are: ${_.values(SUPPORTED_ACTIONS)}`,
34
31
  );
35
32
  }
36
33
  }
37
-
@@ -67,9 +67,7 @@ const RETRY_PAUSE_MS = 1000;
67
67
  * @returns An array of supported performance data type names.
68
68
  * The possible values are: 'cpuinfo', 'memoryinfo', 'batteryinfo', 'networkinfo'.
69
69
  */
70
- export async function getPerformanceDataTypes(
71
- this: AndroidDriver,
72
- ): Promise<PerformanceDataType[]> {
70
+ export async function getPerformanceDataTypes(this: AndroidDriver): Promise<PerformanceDataType[]> {
73
71
  return _.keys(SUPPORTED_PERFORMANCE_DATA_TYPES) as PerformanceDataType[];
74
72
  }
75
73
 
@@ -525,10 +523,7 @@ export async function getCPUInfo(
525
523
  * and the second row contains the battery level as a string (0-100).
526
524
  * @throws {Error} If battery data cannot be retrieved or parsed.
527
525
  */
528
- export async function getBatteryInfo(
529
- this: AndroidDriver,
530
- retries: number = 2,
531
- ): Promise<any[][]> {
526
+ export async function getBatteryInfo(this: AndroidDriver, retries: number = 2): Promise<any[][]> {
532
527
  return (await retryInterval(retries, RETRY_PAUSE_MS, async () => {
533
528
  const cmd = ['dumpsys', 'battery', '|', 'grep', 'level'];
534
529
  const data = await this.adb.shell(cmd);
@@ -545,4 +540,3 @@ export async function getBatteryInfo(
545
540
  }
546
541
 
547
542
  // #endregion
548
-
@@ -57,9 +57,7 @@ export async function mobileChangePermissions(
57
57
  target: PermissionTarget = PERMISSION_TARGET.PM,
58
58
  ): Promise<void> {
59
59
  appPackage ??= this.opts.appPackage;
60
- action ??= _.toLower(target) === PERMISSION_TARGET.APPOPS
61
- ? APPOPS_ACTION.ALLOW
62
- : PM_ACTION.GRANT;
60
+ action ??= _.toLower(target) === PERMISSION_TARGET.APPOPS ? APPOPS_ACTION.ALLOW : PM_ACTION.GRANT;
63
61
  if (_.isNil(permissions)) {
64
62
  throw new errors.InvalidArgumentError(`'permissions' argument is required`);
65
63
  }
@@ -69,7 +67,11 @@ export async function mobileChangePermissions(
69
67
 
70
68
  switch (_.toLower(target)) {
71
69
  case PERMISSION_TARGET.PM:
72
- return await changePermissionsViaPm.bind(this)(permissions, appPackage, _.toLower(action) as PMAction);
70
+ return await changePermissionsViaPm.bind(this)(
71
+ permissions,
72
+ appPackage,
73
+ _.toLower(action) as PMAction,
74
+ );
73
75
  case PERMISSION_TARGET.APPOPS:
74
76
  this.assertFeatureEnabled(ADB_SHELL_FEATURE);
75
77
  return await changePermissionsViaAppops.bind(this)(
@@ -185,8 +187,7 @@ async function changePermissionsViaAppops(
185
187
 
186
188
  // #endregion
187
189
 
188
- type PMAction = typeof PM_ACTION[keyof typeof PM_ACTION];
189
- type AppOpsAction = typeof APPOPS_ACTION[keyof typeof APPOPS_ACTION];
190
- type PermissionTarget = typeof PERMISSION_TARGET[keyof typeof PERMISSION_TARGET];
191
- type PermissionsType = typeof PERMISSIONS_TYPE[keyof typeof PERMISSIONS_TYPE];
192
-
190
+ type PMAction = (typeof PM_ACTION)[keyof typeof PM_ACTION];
191
+ type AppOpsAction = (typeof APPOPS_ACTION)[keyof typeof APPOPS_ACTION];
192
+ type PermissionTarget = (typeof PERMISSION_TARGET)[keyof typeof PERMISSION_TARGET];
193
+ type PermissionsType = (typeof PERMISSIONS_TYPE)[keyof typeof PERMISSIONS_TYPE];
@@ -6,7 +6,11 @@ import path from 'node:path';
6
6
  import {exec} from 'teen_process';
7
7
  import type {AndroidDriver} from '../driver';
8
8
  import type {ADB} from 'appium-adb';
9
- import type {StartScreenRecordingOpts, StopScreenRecordingOpts, ScreenRecordingProperties} from './types';
9
+ import type {
10
+ StartScreenRecordingOpts,
11
+ StopScreenRecordingOpts,
12
+ ScreenRecordingProperties,
13
+ } from './types';
10
14
 
11
15
  const RETRY_PAUSE = 300;
12
16
  const RETRY_TIMEOUT = 5000;
@@ -135,10 +139,7 @@ export async function stopRecordingScreen(
135
139
 
136
140
  if (props.recordingProcess?.isRunning) {
137
141
  try {
138
- await props.recordingProcess.stop(
139
- 'SIGINT',
140
- PROCESS_SHUTDOWN_TIMEOUT,
141
- );
142
+ await props.recordingProcess.stop('SIGINT', PROCESS_SHUTDOWN_TIMEOUT);
142
143
  } catch {
143
144
  throw this.log.errorWithException(
144
145
  `Unable to stop screen recording within ${PROCESS_SHUTDOWN_TIMEOUT}ms`,
@@ -160,7 +161,7 @@ export async function stopRecordingScreen(
160
161
  for (const pathOnDevice of props.records) {
161
162
  const relativePath = path.resolve(tmpRoot, path.posix.basename(pathOnDevice));
162
163
  localRecords.push(relativePath);
163
- await this.adb.pull(pathOnDevice, relativePath, { timeout: ADB_PULL_TIMEOUT });
164
+ await this.adb.pull(pathOnDevice, relativePath, {timeout: ADB_PULL_TIMEOUT});
164
165
  await this.adb.rimraf(pathOnDevice);
165
166
  }
166
167
  let resultFilePath = _.last(localRecords) as string;
@@ -295,10 +296,7 @@ async function scheduleScreenRecord(
295
296
  recordingProperties.recordingProcess = recordingProc;
296
297
  }
297
298
 
298
- async function mergeScreenRecords(
299
- this: AndroidDriver,
300
- mediaFiles: string[],
301
- ): Promise<string> {
299
+ async function mergeScreenRecords(this: AndroidDriver, mediaFiles: string[]): Promise<string> {
302
300
  try {
303
301
  await fs.which(FFMPEG_BINARY);
304
302
  } catch {
@@ -330,17 +328,17 @@ async function terminateBackgroundScreenRecording(adb: ADB, force = true): Promi
330
328
 
331
329
  try {
332
330
  await adb.shell(['kill', force ? '-15' : '-2', ...screenrecordPids.map(String)]);
333
- await waitForCondition(async () => _.isEmpty(await adb.getProcessIdsByName(SCREENRECORD_BINARY)), {
334
- waitMs: PROCESS_SHUTDOWN_TIMEOUT,
335
- intervalMs: 500,
336
- });
331
+ await waitForCondition(
332
+ async () => _.isEmpty(await adb.getProcessIdsByName(SCREENRECORD_BINARY)),
333
+ {
334
+ waitMs: PROCESS_SHUTDOWN_TIMEOUT,
335
+ intervalMs: 500,
336
+ },
337
+ );
337
338
  return true;
338
339
  } catch (err) {
339
- throw new Error(
340
- `Unable to stop the background screen recording: ${(err as Error).message}`,
341
- );
340
+ throw new Error(`Unable to stop the background screen recording: ${(err as Error).message}`);
342
341
  }
343
342
  }
344
343
 
345
344
  // #endregion
346
-
@@ -111,17 +111,16 @@ async function fetchLocaleSuggestions(
111
111
  country?: string,
112
112
  ): Promise<Locale[]> {
113
113
  const supportedLocales = await this.settingsApp.listSupportedLocales();
114
- const suggestedLocales = supportedLocales
115
- .filter((locale) =>
116
- _.toLower(language) === _.toLower(locale.language)
117
- || _.toLower(country) === _.toLower(locale.country)
118
- );
114
+ const suggestedLocales = supportedLocales.filter(
115
+ (locale) =>
116
+ _.toLower(language) === _.toLower(locale.language) ||
117
+ _.toLower(country) === _.toLower(locale.country),
118
+ );
119
119
  return _.isEmpty(suggestedLocales) ? supportedLocales : suggestedLocales;
120
120
  }
121
121
 
122
122
  function toLocaleAbbr({language, country, script}: Locale): string {
123
- return `${language}_${country}${script ? ('-' + script) : ''}`;
123
+ return `${language}_${country}${script ? '-' + script : ''}`;
124
124
  }
125
125
 
126
126
  // #endregion
127
-
@@ -31,7 +31,7 @@ export async function mobileShell<T extends boolean>(
31
31
  args: string[] = [],
32
32
  timeout: number = 20000,
33
33
  includeStderr?: T,
34
- ): Promise<T extends true ? { stdout: string; stderr: string; } : string> {
34
+ ): Promise<T extends true ? {stdout: string; stderr: string} : string> {
35
35
  this.assertFeatureEnabled(ADB_SHELL_FEATURE);
36
36
 
37
37
  if (!_.isString(command)) {
@@ -404,9 +404,7 @@ async function initDeviceStreamingProc(
404
404
  });
405
405
  } catch (e) {
406
406
  throw log.errorWithException(
407
- `Cannot start the screen streaming process. Original error: ${
408
- (e as Error).message
409
- }`,
407
+ `Cannot start the screen streaming process. Original error: ${(e as Error).message}`,
410
408
  );
411
409
  } finally {
412
410
  deviceStreaming.stderr.removeListener('data', errorsListener);
@@ -491,9 +489,7 @@ async function initGstreamerPipeline(
491
489
  } catch (e) {
492
490
  didFail = true;
493
491
  throw log.errorWithException(
494
- `Cannot start the screen streaming pipeline. Original error: ${
495
- (e as Error).message
496
- }`,
492
+ `Cannot start the screen streaming pipeline. Original error: ${(e as Error).message}`,
497
493
  );
498
494
  } finally {
499
495
  if (!logPipelineDetails || didFail) {
@@ -517,4 +513,3 @@ function extractRemoteAddress(req: http.IncomingMessage): string {
517
513
  }
518
514
 
519
515
  // #endregion
520
-
@@ -28,16 +28,12 @@ const DEFAULT_WINDOW_PROPERTIES: WindowProperties = {
28
28
  * @returns Promise that resolves to an object containing statusBar and navigationBar properties.
29
29
  * @throws {Error} If system bars details cannot be retrieved or parsed.
30
30
  */
31
- export async function getSystemBars(
32
- this: AndroidDriver,
33
- ): Promise<StringRecord> {
31
+ export async function getSystemBars(this: AndroidDriver): Promise<StringRecord> {
34
32
  let stdout: string;
35
33
  try {
36
34
  stdout = await this.adb.shell(['dumpsys', 'window', 'windows']);
37
35
  } catch (e) {
38
- throw new Error(
39
- `Cannot retrieve system bars details. Original error: ${(e as Error).message}`,
40
- );
36
+ throw new Error(`Cannot retrieve system bars details. Original error: ${(e as Error).message}`);
41
37
  }
42
38
  return parseWindows.bind(this)(stdout);
43
39
  }
@@ -57,27 +53,27 @@ export async function mobilePerformStatusBarCommand(
57
53
  command: StatusBarCommand,
58
54
  component?: string,
59
55
  ): Promise<string> {
60
- const toStatusBarCommandCallable = (
61
- cmd: string,
62
- argsCallable?: () => string[] | string,
63
- ) => async (): Promise<string> =>
64
- await this.adb.shell([
65
- 'cmd',
66
- 'statusbar',
67
- cmd,
68
- ...(argsCallable ? _.castArray(argsCallable()) : []),
69
- ]);
56
+ const toStatusBarCommandCallable =
57
+ (cmd: string, argsCallable?: () => string[] | string) => async (): Promise<string> =>
58
+ await this.adb.shell([
59
+ 'cmd',
60
+ 'statusbar',
61
+ cmd,
62
+ ...(argsCallable ? _.castArray(argsCallable()) : []),
63
+ ]);
70
64
  const tileCommandArgsCallable = () => component as string;
71
65
  const statusBarCommands = _.fromPairs(
72
- ([
73
- ['expandNotifications', ['expand-notifications']],
74
- ['expandSettings', ['expand-settings']],
75
- ['collapse', ['collapse']],
76
- ['addTile', ['add-tile', tileCommandArgsCallable]],
77
- ['removeTile', ['remove-tile', tileCommandArgsCallable]],
78
- ['clickTile', ['click-tile', tileCommandArgsCallable]],
79
- ['getStatusIcons', ['get-status-icons']],
80
- ] as const).map(([name, args]) => [name, toStatusBarCommandCallable(args[0], args[1])]),
66
+ (
67
+ [
68
+ ['expandNotifications', ['expand-notifications']],
69
+ ['expandSettings', ['expand-settings']],
70
+ ['collapse', ['collapse']],
71
+ ['addTile', ['add-tile', tileCommandArgsCallable]],
72
+ ['removeTile', ['remove-tile', tileCommandArgsCallable]],
73
+ ['clickTile', ['click-tile', tileCommandArgsCallable]],
74
+ ['getStatusIcons', ['get-status-icons']],
75
+ ] as const
76
+ ).map(([name, args]) => [name, toStatusBarCommandCallable(args[0], args[1])]),
81
77
  ) as Record<StatusBarCommand, () => Promise<string>>;
82
78
 
83
79
  const action = statusBarCommands[command];
@@ -135,10 +131,7 @@ export function parseWindowProperties(
135
131
  * and values are corresponding WindowProperties objects
136
132
  * @throws {Error} If no window properties could be parsed
137
133
  */
138
- export function parseWindows(
139
- this: AndroidDriver,
140
- lines: string,
141
- ): SystemBarsResult {
134
+ export function parseWindows(this: AndroidDriver, lines: string): SystemBarsResult {
142
135
  const windows: StringRecord<string[]> = {};
143
136
  let currentWindowName: string | null = null;
144
137
  for (const line of lines.split('\n').map(_.trimEnd)) {
@@ -165,21 +158,23 @@ export function parseWindows(
165
158
  const result: SystemBarsResult = {};
166
159
  for (const [name, props] of _.toPairs(windows)) {
167
160
  if (
168
- name.startsWith(STATUS_BAR_WINDOW_NAME_PREFIX)
169
- || props.some((line: string) => STATUS_BAR_TYPE_PATTERN.test(line))
161
+ name.startsWith(STATUS_BAR_WINDOW_NAME_PREFIX) ||
162
+ props.some((line: string) => STATUS_BAR_TYPE_PATTERN.test(line))
170
163
  ) {
171
164
  result.statusBar = parseWindowProperties.bind(this)(name, props);
172
165
  } else if (
173
- name.startsWith(NAVIGATION_BAR_WINDOW_NAME_PREFIX)
174
- || props.some((line: string) => NAVIGATION_BAR_TYPE_PATTERN.test(line))
166
+ name.startsWith(NAVIGATION_BAR_WINDOW_NAME_PREFIX) ||
167
+ props.some((line: string) => NAVIGATION_BAR_TYPE_PATTERN.test(line))
175
168
  ) {
176
169
  result.navigationBar = parseWindowProperties.bind(this)(name, props);
177
170
  }
178
171
  }
179
- const unmatchedWindows = ([
180
- ['statusBar', STATUS_BAR_WINDOW_NAME_PREFIX],
181
- ['navigationBar', NAVIGATION_BAR_WINDOW_NAME_PREFIX],
182
- ] as const).filter(([name]) => _.isNil(result[name as keyof SystemBarsResult]));
172
+ const unmatchedWindows = (
173
+ [
174
+ ['statusBar', STATUS_BAR_WINDOW_NAME_PREFIX],
175
+ ['navigationBar', NAVIGATION_BAR_WINDOW_NAME_PREFIX],
176
+ ] as const
177
+ ).filter(([name]) => _.isNil(result[name as keyof SystemBarsResult]));
183
178
  for (const [window, namePrefix] of unmatchedWindows) {
184
179
  this.log.info(
185
180
  `No windows have been found whose title matches to ` +
@@ -197,4 +192,3 @@ interface SystemBarsResult {
197
192
  statusBar?: WindowProperties;
198
193
  navigationBar?: WindowProperties;
199
194
  }
200
-