appium-adb 16.0.0 → 16.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/build/lib/adb.d.ts +11 -11
  3. package/build/lib/adb.d.ts.map +1 -1
  4. package/build/lib/adb.js +9 -9
  5. package/build/lib/adb.js.map +1 -1
  6. package/build/lib/logcat.d.ts +1 -1
  7. package/build/lib/logcat.d.ts.map +1 -1
  8. package/build/lib/logcat.js +4 -14
  9. package/build/lib/logcat.js.map +1 -1
  10. package/build/lib/tools/aab-utils.d.ts.map +1 -1
  11. package/build/lib/tools/aab-utils.js +4 -4
  12. package/build/lib/tools/aab-utils.js.map +1 -1
  13. package/build/lib/tools/android-manifest.d.ts.map +1 -1
  14. package/build/lib/tools/android-manifest.js +4 -7
  15. package/build/lib/tools/android-manifest.js.map +1 -1
  16. package/build/lib/tools/apk-signing.d.ts.map +1 -1
  17. package/build/lib/tools/apk-signing.js +9 -11
  18. package/build/lib/tools/apk-signing.js.map +1 -1
  19. package/build/lib/tools/apk-utils.d.ts.map +1 -1
  20. package/build/lib/tools/apk-utils.js +19 -38
  21. package/build/lib/tools/apk-utils.js.map +1 -1
  22. package/build/lib/tools/apks-utils.d.ts.map +1 -1
  23. package/build/lib/tools/apks-utils.js +3 -3
  24. package/build/lib/tools/apks-utils.js.map +1 -1
  25. package/build/lib/tools/app-commands.d.ts.map +1 -1
  26. package/build/lib/tools/app-commands.js +11 -15
  27. package/build/lib/tools/app-commands.js.map +1 -1
  28. package/build/lib/tools/device-settings.d.ts.map +1 -1
  29. package/build/lib/tools/device-settings.js +6 -17
  30. package/build/lib/tools/device-settings.js.map +1 -1
  31. package/build/lib/tools/emulator-commands.d.ts.map +1 -1
  32. package/build/lib/tools/emulator-commands.js +6 -8
  33. package/build/lib/tools/emulator-commands.js.map +1 -1
  34. package/build/lib/tools/fs-commands.d.ts +1 -1
  35. package/build/lib/tools/fs-commands.d.ts.map +1 -1
  36. package/build/lib/tools/fs-commands.js.map +1 -1
  37. package/build/lib/tools/general-commands.d.ts.map +1 -1
  38. package/build/lib/tools/general-commands.js +3 -5
  39. package/build/lib/tools/general-commands.js.map +1 -1
  40. package/build/lib/tools/keyboard-commands.d.ts.map +1 -1
  41. package/build/lib/tools/keyboard-commands.js +1 -1
  42. package/build/lib/tools/keyboard-commands.js.map +1 -1
  43. package/build/lib/tools/lockmgmt.d.ts.map +1 -1
  44. package/build/lib/tools/lockmgmt.js +4 -10
  45. package/build/lib/tools/lockmgmt.js.map +1 -1
  46. package/build/lib/tools/logcat-commands.d.ts.map +1 -1
  47. package/build/lib/tools/logcat-commands.js.map +1 -1
  48. package/build/lib/tools/network-commands.d.ts.map +1 -1
  49. package/build/lib/tools/network-commands.js.map +1 -1
  50. package/build/lib/tools/process-commands.d.ts.map +1 -1
  51. package/build/lib/tools/process-commands.js +1 -1
  52. package/build/lib/tools/process-commands.js.map +1 -1
  53. package/build/lib/tools/system-calls.d.ts.map +1 -1
  54. package/build/lib/tools/system-calls.js +15 -11
  55. package/build/lib/tools/system-calls.js.map +1 -1
  56. package/build/lib/tools/types.d.ts.map +1 -1
  57. package/build/lib/utils/helpers/index.d.ts +1 -1
  58. package/build/lib/utils/helpers/index.d.ts.map +1 -1
  59. package/build/lib/utils/helpers/index.js +1 -1
  60. package/build/lib/utils/helpers/index.js.map +1 -1
  61. package/build/lib/utils/helpers/install.d.ts.map +1 -1
  62. package/build/lib/utils/helpers/install.js.map +1 -1
  63. package/build/lib/utils/helpers/manifest.d.ts.map +1 -1
  64. package/build/lib/utils/helpers/manifest.js.map +1 -1
  65. package/build/lib/utils/helpers/resource.d.ts.map +1 -1
  66. package/build/lib/utils/helpers/resource.js +1 -2
  67. package/build/lib/utils/helpers/resource.js.map +1 -1
  68. package/build/lib/utils/helpers/sdk.d.ts.map +1 -1
  69. package/build/lib/utils/helpers/sdk.js +1 -1
  70. package/build/lib/utils/helpers/sdk.js.map +1 -1
  71. package/build/lib/utils/index.d.ts +1 -1
  72. package/build/lib/utils/index.d.ts.map +1 -1
  73. package/build/lib/utils/index.js +1 -1
  74. package/build/lib/utils/index.js.map +1 -1
  75. package/build/lib/utils/lodash/core.d.ts.map +1 -1
  76. package/build/lib/utils/lodash/core.js.map +1 -1
  77. package/lib/adb.ts +14 -13
  78. package/lib/logcat.ts +9 -23
  79. package/lib/tools/aab-utils.ts +9 -15
  80. package/lib/tools/android-manifest.ts +12 -28
  81. package/lib/tools/apk-signing.ts +16 -41
  82. package/lib/tools/apk-utils.ts +27 -82
  83. package/lib/tools/apks-utils.ts +10 -21
  84. package/lib/tools/app-commands.ts +31 -95
  85. package/lib/tools/device-settings.ts +15 -48
  86. package/lib/tools/emulator-commands.ts +13 -38
  87. package/lib/tools/fs-commands.ts +3 -1
  88. package/lib/tools/general-commands.ts +6 -13
  89. package/lib/tools/keyboard-commands.ts +2 -1
  90. package/lib/tools/lockmgmt.ts +12 -42
  91. package/lib/tools/logcat-commands.ts +1 -1
  92. package/lib/tools/network-commands.ts +4 -11
  93. package/lib/tools/process-commands.ts +4 -11
  94. package/lib/tools/system-calls.ts +59 -137
  95. package/lib/tools/types.ts +4 -8
  96. package/lib/utils/helpers/index.ts +1 -6
  97. package/lib/utils/helpers/install.ts +2 -4
  98. package/lib/utils/helpers/manifest.ts +4 -11
  99. package/lib/utils/helpers/resource.ts +5 -9
  100. package/lib/utils/helpers/sdk.ts +5 -9
  101. package/lib/utils/index.ts +2 -1
  102. package/lib/utils/lodash/core.ts +3 -9
  103. package/package.json +36 -46
@@ -1,7 +1,8 @@
1
- import {log} from '../logger.js';
1
+ import {util} from '@appium/support';
2
2
  import {sleep, waitForCondition} from 'asyncbox';
3
+
3
4
  import type {ADB} from '../adb.js';
4
- import {util} from '@appium/support';
5
+ import {log} from '../logger.js';
5
6
 
6
7
  const CREDENTIAL_CANNOT_BE_NULL_OR_EMPTY_ERROR = `Credential can't be null or empty`;
7
8
  const CREDENTIAL_DID_NOT_MATCH_ERROR = `didn't match`;
@@ -24,10 +25,7 @@ export async function isLockManagementSupported(this: ADB): Promise<boolean> {
24
25
  output = await this.shell([`locksettings help && echo ${passFlag}`]);
25
26
  } catch {}
26
27
  this._isLockManagementSupported = output.includes(passFlag);
27
- log.debug(
28
- `Extended lock settings management is ` +
29
- `${this._isLockManagementSupported ? '' : 'not '}supported`,
30
- );
28
+ log.debug(`Extended lock settings management is ${this._isLockManagementSupported ? '' : 'not '}supported`);
31
29
  }
32
30
  return this._isLockManagementSupported as boolean;
33
31
  }
@@ -44,10 +42,7 @@ export async function isLockManagementSupported(this: ADB): Promise<boolean> {
44
42
  * @return True if the given credential matches to the device's one
45
43
  * @throws {Error} If the verification faces an unexpected error
46
44
  */
47
- export async function verifyLockCredential(
48
- this: ADB,
49
- credential: string | null = null,
50
- ): Promise<boolean> {
45
+ export async function verifyLockCredential(this: ADB, credential: string | null = null): Promise<boolean> {
51
46
  try {
52
47
  const {stdout, stderr} = await this.shell(buildCommand('verify', credential), {
53
48
  outputFormat: this.EXEC_OUTPUT_FORMAT.FULL,
@@ -55,11 +50,7 @@ export async function verifyLockCredential(
55
50
  if (stdout?.includes('verified successfully')) {
56
51
  return true;
57
52
  }
58
- if (
59
- [`didn't match`, CREDENTIAL_CANNOT_BE_NULL_OR_EMPTY_ERROR].some((x) =>
60
- (stderr || stdout)?.includes(x),
61
- )
62
- ) {
53
+ if ([`didn't match`, CREDENTIAL_CANNOT_BE_NULL_OR_EMPTY_ERROR].some((x) => (stderr || stdout)?.includes(x))) {
63
54
  return false;
64
55
  }
65
56
  throw new Error(stderr || stdout);
@@ -88,19 +79,12 @@ export async function verifyLockCredential(
88
79
  * null/empty value assumes the device has no lock currently set.
89
80
  * @throws {Error} If operation faces an unexpected error
90
81
  */
91
- export async function clearLockCredential(
92
- this: ADB,
93
- credential: string | null = null,
94
- ): Promise<void> {
82
+ export async function clearLockCredential(this: ADB, credential: string | null = null): Promise<void> {
95
83
  try {
96
84
  const {stdout, stderr} = await this.shell(buildCommand('clear', credential), {
97
85
  outputFormat: this.EXEC_OUTPUT_FORMAT.FULL,
98
86
  });
99
- if (
100
- !['user has no password', 'Lock credential cleared'].some((x) =>
101
- (stderr || stdout)?.includes(x),
102
- )
103
- ) {
87
+ if (!['user has no password', 'Lock credential cleared'].some((x) => (stderr || stdout)?.includes(x))) {
104
88
  throw new Error(stderr || stdout);
105
89
  }
106
90
  } catch (e) {
@@ -141,10 +125,7 @@ export async function isLockEnabled(this: ADB): Promise<boolean> {
141
125
  }
142
126
  throw new Error(stderr || stdout);
143
127
  } catch (e) {
144
- throw new Error(
145
- `Cannot check if device lock is enabled. Original error: ${(e as Error).message}`,
146
- {cause: e},
147
- );
128
+ throw new Error(`Cannot check if device lock is enabled. Original error: ${(e as Error).message}`, {cause: e});
148
129
  }
149
130
  }
150
131
 
@@ -301,9 +282,7 @@ export function isShowingLockscreen(dumpsys: string): boolean {
301
282
  return (
302
283
  ['mShowingLockscreen=true', 'mDreamingLockscreen=true'].some((x) => dumpsys.includes(x)) ||
303
284
  // `mIsShowing` and `mInputRestricted` are `true` in lock condition. `false` is unlock condition.
304
- [/KeyguardStateMonitor[\n\s]+mIsShowing=true/, /\s+mInputRestricted=true/].every((x) =>
305
- x.test(dumpsys),
306
- )
285
+ [/KeyguardStateMonitor[\n\s]+mIsShowing=true/, /\s+mInputRestricted=true/].every((x) => x.test(dumpsys))
307
286
  );
308
287
  }
309
288
 
@@ -325,11 +304,7 @@ export function isScreenStateOff(dumpsys: string): boolean {
325
304
  * @param oldCredential
326
305
  * @param args
327
306
  */
328
- function buildCommand(
329
- verb: string,
330
- oldCredential: string | null = null,
331
- ...args: string[]
332
- ): string[] {
307
+ function buildCommand(verb: string, oldCredential: string | null = null, ...args: string[]): string[] {
333
308
  const cmd = ['locksettings', verb];
334
309
  if (oldCredential && !util.isEmpty(oldCredential)) {
335
310
  cmd.push('--old', oldCredential);
@@ -357,12 +332,7 @@ async function swipeUp(this: ADB, windowDumpsys: string): Promise<void> {
357
332
  const y0 = (displayHeight / 5) * 4;
358
333
  const x1 = x0;
359
334
  const y1 = displayHeight / 5;
360
- await this.shell([
361
- 'input',
362
- 'touchscreen',
363
- 'swipe',
364
- ...[x0, y0, x1, y1].map((c) => `${Math.trunc(c)}`),
365
- ]);
335
+ await this.shell(['input', 'touchscreen', 'swipe', ...[x0, y0, x1, y1].map((c) => `${Math.trunc(c)}`)]);
366
336
  }
367
337
 
368
338
  /**
@@ -1,5 +1,5 @@
1
- import {Logcat} from '../logcat.js';
2
1
  import type {ADB} from '../adb.js';
2
+ import {Logcat} from '../logcat.js';
3
3
  import type {LogcatOpts, LogEntry, LogcatListener} from './types.js';
4
4
 
5
5
  /**
@@ -1,6 +1,7 @@
1
1
  import {EOL} from 'node:os';
2
- import {log} from '../logger.js';
2
+
3
3
  import type {ADB} from '../adb.js';
4
+ import {log} from '../logger.js';
4
5
  import type {PortFamily, PortInfo} from './types.js';
5
6
 
6
7
  /**
@@ -21,11 +22,7 @@ export async function getForwardList(this: ADB): Promise<string[]> {
21
22
  * @param systemPort - The number of the local system port.
22
23
  * @param devicePort - The number of the remote device port.
23
24
  */
24
- export async function forwardPort(
25
- this: ADB,
26
- systemPort: string | number,
27
- devicePort: string | number,
28
- ): Promise<void> {
25
+ export async function forwardPort(this: ADB, systemPort: string | number, devicePort: string | number): Promise<void> {
29
26
  log.debug(`Forwarding system: ${systemPort} to device: ${devicePort}`);
30
27
  await this.adbExec(['forward', `tcp:${systemPort}`, `tcp:${devicePort}`]);
31
28
  }
@@ -61,11 +58,7 @@ export async function getReverseList(this: ADB): Promise<string[]> {
61
58
  * @param devicePort - The number of the remote device port.
62
59
  * @param systemPort - The number of the local system port.
63
60
  */
64
- export async function reversePort(
65
- this: ADB,
66
- devicePort: string | number,
67
- systemPort: string | number,
68
- ): Promise<void> {
61
+ export async function reversePort(this: ADB, devicePort: string | number, systemPort: string | number): Promise<void> {
69
62
  log.debug(`Forwarding device: ${devicePort} to system: ${systemPort}`);
70
63
  await this.adbExec(['reverse', `tcp:${devicePort}`, `tcp:${systemPort}`]);
71
64
  }
@@ -1,7 +1,8 @@
1
- import {log} from '../logger.js';
2
1
  import {util} from '@appium/support';
3
2
  import type {ExecError} from 'teen_process';
3
+
4
4
  import type {ADB} from '../adb.js';
5
+ import {log} from '../logger.js';
5
6
 
6
7
  const PID_COLUMN_TITLE: string = 'PID';
7
8
  const PROCESS_NAME_COLUMN_TITLE: string = 'NAME';
@@ -118,11 +119,7 @@ export async function getProcessIdsByName(this: ADB, name: string): Promise<numb
118
119
  * @param signal - The signal to send to the process. Default is 'SIGTERM' ('15').
119
120
  * @throws {Error} If the processes cannot be killed.
120
121
  */
121
- export async function killProcessesByName(
122
- this: ADB,
123
- name: string,
124
- signal: string = 'SIGTERM',
125
- ): Promise<void> {
122
+ export async function killProcessesByName(this: ADB, name: string, signal: string = 'SIGTERM'): Promise<void> {
126
123
  try {
127
124
  log.debug(`Attempting to kill all ${name} processes`);
128
125
  const pids: number[] = await this.getProcessIdsByName(name);
@@ -148,11 +145,7 @@ export async function killProcessesByName(
148
145
  * @param signal - The signal to send to the process. Default is 'SIGTERM' ('15').
149
146
  * @throws {Error} If the process cannot be killed.
150
147
  */
151
- export async function killProcessByPID(
152
- this: ADB,
153
- pid: string | number,
154
- signal: string = 'SIGTERM',
155
- ): Promise<void> {
148
+ export async function killProcessByPID(this: ADB, pid: string | number, signal: string = 'SIGTERM'): Promise<void> {
156
149
  log.debug(`Attempting to kill process ${pid}`);
157
150
  const noProcessFlag: string = 'No such process';
158
151
  try {
@@ -1,18 +1,14 @@
1
1
  import path from 'node:path';
2
- import {log} from '../logger.js';
2
+
3
3
  import {system, fs, util, tempDir, timing} from '@appium/support';
4
- import {exec, SubProcess} from 'teen_process';
5
- import type {ExecError, TeenProcessExecResult} from 'teen_process';
6
4
  import {asyncmap, retry, retryInterval, sleep, waitForCondition} from 'asyncbox';
7
5
  import * as semver from 'semver';
6
+ import {exec, SubProcess} from 'teen_process';
7
+ import type {ExecError, TeenProcessExecResult} from 'teen_process';
8
+
8
9
  import type {ADB} from '../adb.js';
9
- import {
10
- DEFAULT_ADB_EXEC_TIMEOUT,
11
- cloneDeep,
12
- getSdkRootFromEnv,
13
- memoize,
14
- zip,
15
- } from '../utils/index.js';
10
+ import {log} from '../logger.js';
11
+ import {DEFAULT_ADB_EXEC_TIMEOUT, cloneDeep, getSdkRootFromEnv, memoize, zip} from '../utils/index.js';
16
12
  import type {
17
13
  ConnectedDevicesOptions,
18
14
  Device,
@@ -87,9 +83,7 @@ function _getBinaryNameForOS(binaryName: string): string {
87
83
  * @returns Array of possible binary location paths
88
84
  */
89
85
  function getSdkBinaryLocationCandidates(sdkRoot: string, fullBinaryName: string): string[] {
90
- return SDK_BINARY_ROOTS.map((x) =>
91
- path.resolve(sdkRoot, ...(Array.isArray(x) ? x : [x]), fullBinaryName),
92
- );
86
+ return SDK_BINARY_ROOTS.map((x) => path.resolve(sdkRoot, ...(Array.isArray(x) ? x : [x]), fullBinaryName));
93
87
  }
94
88
 
95
89
  /**
@@ -235,10 +229,7 @@ export async function getConnectedDevices(
235
229
  * @returns Array of connected devices
236
230
  * @throws {Error} If adb devices command fails or returns unexpected output
237
231
  */
238
- export async function getConnectedDevices(
239
- this: ADB,
240
- opts?: ConnectedDevicesOptions,
241
- ): Promise<Device[]>;
232
+ export async function getConnectedDevices(this: ADB, opts?: ConnectedDevicesOptions): Promise<Device[]>;
242
233
  export async function getConnectedDevices(
243
234
  this: ADB,
244
235
  opts: ConnectedDevicesOptions = {},
@@ -339,9 +330,7 @@ export async function getDevicesWithRetry(this: ADB, timeoutMs: number = 20000):
339
330
  } catch (err: unknown) {
340
331
  const error = err as Error;
341
332
  log.debug(error.stack);
342
- log.warn(
343
- `Got an unexpected error while fetching connected devices list: ${error.message}`,
344
- );
333
+ log.warn(`Got an unexpected error while fetching connected devices list: ${error.message}`);
345
334
  }
346
335
 
347
336
  try {
@@ -426,33 +415,27 @@ export async function killServer(this: ADB): Promise<void> {
426
415
  *
427
416
  * @returns True if token was reset successfully, false otherwise
428
417
  */
429
- export const resetTelnetAuthToken = memoize(
430
- async function resetTelnetAuthToken(): Promise<boolean> {
431
- // The methods is used to remove telnet auth token
432
- //
433
- const homeFolderPath = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'];
434
- if (!homeFolderPath) {
435
- log.warn(
436
- `Cannot find the path to user home folder. Ignoring resetting of emulator's telnet authentication token`,
437
- );
438
- return false;
439
- }
440
- const dstPath = path.resolve(homeFolderPath, '.emulator_console_auth_token');
441
- log.debug(
442
- `Overriding ${dstPath} with an empty string to avoid telnet authentication for emulator commands`,
418
+ export const resetTelnetAuthToken = memoize(async function resetTelnetAuthToken(): Promise<boolean> {
419
+ // The methods is used to remove telnet auth token
420
+ //
421
+ const homeFolderPath = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'];
422
+ if (!homeFolderPath) {
423
+ log.warn(`Cannot find the path to user home folder. Ignoring resetting of emulator's telnet authentication token`);
424
+ return false;
425
+ }
426
+ const dstPath = path.resolve(homeFolderPath, '.emulator_console_auth_token');
427
+ log.debug(`Overriding ${dstPath} with an empty string to avoid telnet authentication for emulator commands`);
428
+ try {
429
+ await fs.writeFile(dstPath, '');
430
+ } catch (e: unknown) {
431
+ const error = e as Error;
432
+ log.warn(
433
+ `Error ${error.message} while resetting the content of ${dstPath}. Ignoring resetting of emulator's telnet authentication token`,
443
434
  );
444
- try {
445
- await fs.writeFile(dstPath, '');
446
- } catch (e: unknown) {
447
- const error = e as Error;
448
- log.warn(
449
- `Error ${error.message} while resetting the content of ${dstPath}. Ignoring resetting of emulator's telnet authentication token`,
450
- );
451
- return false;
452
- }
453
- return true;
454
- },
455
- );
435
+ return false;
436
+ }
437
+ return true;
438
+ });
456
439
 
457
440
  /**
458
441
  * Execute the given emulator command using _adb emu_ tool.
@@ -494,16 +477,8 @@ export async function adbExec(
494
477
  * @returns Command stdout
495
478
  * @throws {Error} If command execution fails or timeout is exceeded
496
479
  */
497
- export async function adbExec(
498
- this: ADB,
499
- cmd: string | string[],
500
- opts?: AdbExecOptions,
501
- ): Promise<string>;
502
- export async function adbExec(
503
- this: ADB,
504
- cmd: string | string[],
505
- opts?: AdbExecOptions,
506
- ): Promise<string | ExecResult> {
480
+ export async function adbExec(this: ADB, cmd: string | string[], opts?: AdbExecOptions): Promise<string>;
481
+ export async function adbExec(this: ADB, cmd: string | string[], opts?: AdbExecOptions): Promise<string | ExecResult> {
507
482
  if (!cmd) {
508
483
  throw new Error('You need to pass in a command to adbExec()');
509
484
  }
@@ -607,16 +582,8 @@ export async function shell(
607
582
  * @returns Command stdout
608
583
  * @throws {Error} If command execution fails
609
584
  */
610
- export async function shell(
611
- this: ADB,
612
- cmd: string | string[],
613
- opts?: ShellExecOptions,
614
- ): Promise<string>;
615
- export async function shell(
616
- this: ADB,
617
- cmd: string | string[],
618
- opts?: ShellExecOptions,
619
- ): Promise<string | ExecResult> {
585
+ export async function shell(this: ADB, cmd: string | string[], opts?: ShellExecOptions): Promise<string>;
586
+ export async function shell(this: ADB, cmd: string | string[], opts?: ShellExecOptions): Promise<string | ExecResult> {
620
587
  const {privileged} = opts ?? {};
621
588
 
622
589
  const cmdArr = Array.isArray(cmd) ? cmd : [cmd];
@@ -703,10 +670,7 @@ export async function getConnectedEmulators(
703
670
  * @returns Array of connected emulator devices
704
671
  * @throws {Error} If error occurs while getting emulators
705
672
  */
706
- export async function getConnectedEmulators(
707
- this: ADB,
708
- opts?: ConnectedDevicesOptions,
709
- ): Promise<Device[]>;
673
+ export async function getConnectedEmulators(this: ADB, opts?: ConnectedDevicesOptions): Promise<Device[]>;
710
674
  export async function getConnectedEmulators(
711
675
  this: ADB,
712
676
  opts: ConnectedDevicesOptions = {},
@@ -898,9 +862,7 @@ export async function killEmulator(
898
862
  }
899
863
  }
900
864
  await this.adbExec(['emu', 'kill']);
901
- log.debug(
902
- `Waiting up to ${timeout}ms until the emulator '${avdName ? avdName : this.curDeviceId}' is killed`,
903
- );
865
+ log.debug(`Waiting up to ${timeout}ms until the emulator '${avdName ? avdName : this.curDeviceId}' is killed`);
904
866
  try {
905
867
  await waitForCondition(
906
868
  async () => {
@@ -934,23 +896,10 @@ export async function killEmulator(
934
896
  * @returns The SubProcess instance for the launched emulator
935
897
  * @throws {Error} If emulator fails to launch or boot
936
898
  */
937
- export async function launchAVD(
938
- this: ADB,
939
- avdName: string,
940
- opts: AvdLaunchOptions = {},
941
- ): Promise<SubProcess> {
942
- const {
943
- args = [],
944
- env = {},
945
- language,
946
- country,
947
- launchTimeout = 60000,
948
- readyTimeout = 60000,
949
- retryTimes = 1,
950
- } = opts;
899
+ export async function launchAVD(this: ADB, avdName: string, opts: AvdLaunchOptions = {}): Promise<SubProcess> {
900
+ const {args = [], env = {}, language, country, launchTimeout = 60000, readyTimeout = 60000, retryTimes = 1} = opts;
951
901
  log.debug(
952
- `Launching Emulator with AVD ${avdName}, launchTimeout ` +
953
- `${launchTimeout}ms and readyTimeout ${readyTimeout}ms`,
902
+ `Launching Emulator with AVD ${avdName}, launchTimeout ${launchTimeout}ms and readyTimeout ${readyTimeout}ms`,
954
903
  );
955
904
  const emulatorBinaryPath = await this.getSdkBinaryPath('emulator');
956
905
  let processedAvdName = avdName;
@@ -990,7 +939,11 @@ export async function launchAVD(
990
939
  }
991
940
 
992
941
  if (!util.isEmpty(args)) {
993
- launchArgs.push(...(Array.isArray(args) ? args : util.shellParse(`${args}`)));
942
+ launchArgs.push(
943
+ ...(Array.isArray(args)
944
+ ? args
945
+ : util.shellParse(`${args}`).filter((token): token is string => typeof token === 'string')),
946
+ );
994
947
  }
995
948
 
996
949
  log.debug(`Running '${emulatorBinaryPath}' with args: ${util.quote(launchArgs)}`);
@@ -1005,14 +958,9 @@ export async function launchAVD(
1005
958
  proc.on(`line-${streamName}`, (line: string) => log.debug(`[AVD OUTPUT] ${line}`));
1006
959
  }
1007
960
  proc.on('die', (code: number | null, signal: string | null) => {
1008
- log.warn(
1009
- `Emulator avd ${processedAvdName} exited with code ${code}${signal ? `, signal ${signal}` : ''}`,
1010
- );
961
+ log.warn(`Emulator avd ${processedAvdName} exited with code ${code}${signal ? `, signal ${signal}` : ''}`);
1011
962
  });
1012
- await retry(
1013
- retryTimes,
1014
- async () => await this.getRunningAVDWithRetry(processedAvdName, launchTimeout),
1015
- );
963
+ await retry(retryTimes, async () => await this.getRunningAVDWithRetry(processedAvdName, launchTimeout));
1016
964
  // At this point we have deviceId already assigned
1017
965
  const timer = new timing.Timer().start();
1018
966
  if (isDelayAdbFeatureEnabled) {
@@ -1020,10 +968,9 @@ export async function launchAVD(
1020
968
  await this.adbExec(['wait-for-device'], {timeout: readyTimeout});
1021
969
  } catch (e: unknown) {
1022
970
  const error = e as ExecError;
1023
- throw new Error(
1024
- `'${processedAvdName}' Emulator has failed to boot: ${error.stderr || error.message}`,
1025
- {cause: e},
1026
- );
971
+ throw new Error(`'${processedAvdName}' Emulator has failed to boot: ${error.stderr || error.message}`, {
972
+ cause: e,
973
+ });
1027
974
  }
1028
975
  }
1029
976
  await this.waitForEmulatorReady(Math.trunc(readyTimeout - timer.getDuration().asMilliSeconds));
@@ -1104,10 +1051,7 @@ export async function waitForEmulatorReady(this: ADB, timeoutMs: number = 20000)
1104
1051
 
1105
1052
  const servicesOutput = await this.shell(['service', 'list']);
1106
1053
  services = servicesOutput;
1107
- if (
1108
- !servicesOutput ||
1109
- !requiredServicesRe.every((pattern) => pattern.test(servicesOutput))
1110
- ) {
1054
+ if (!servicesOutput || !requiredServicesRe.every((pattern) => pattern.test(servicesOutput))) {
1111
1055
  log.debug(`Running services: ${servicesOutput}`);
1112
1056
  return false;
1113
1057
  }
@@ -1194,10 +1138,7 @@ export async function waitForDevice(this: ADB, appDeviceReadyTimeout: number = 3
1194
1138
  * @param retries - Number of retry attempts (default: 90)
1195
1139
  * @throws {Error} If reboot fails or device is not ready after reboot
1196
1140
  */
1197
- export async function reboot(
1198
- this: ADB,
1199
- retries: number = DEFAULT_ADB_REBOOT_RETRIES,
1200
- ): Promise<void> {
1141
+ export async function reboot(this: ADB, retries: number = DEFAULT_ADB_REBOOT_RETRIES): Promise<void> {
1201
1142
  // Get root access so we can run the next shell commands which require root access
1202
1143
  const {wasAlreadyRooted} = await this.root();
1203
1144
  try {
@@ -1255,11 +1196,7 @@ export async function changeUserPrivileges(this: ADB, isElevated: boolean): Prom
1255
1196
  const error = err as ExecError;
1256
1197
  // Check the output of the stdErr to see if there's any clues that show that the device went offline
1257
1198
  // and if it did go offline, restart ADB
1258
- if (
1259
- ['closed', 'device offline', 'timeout expired'].some((x) =>
1260
- (error.stderr || '').toLowerCase().includes(x),
1261
- )
1262
- ) {
1199
+ if (['closed', 'device offline', 'timeout expired'].some((x) => (error.stderr || '').toLowerCase().includes(x))) {
1263
1200
  log.warn(`Attempt to ${cmd} caused ADB to think the device went offline`);
1264
1201
  try {
1265
1202
  await this.reconnect();
@@ -1298,9 +1235,7 @@ export async function changeUserPrivileges(this: ADB, isElevated: boolean): Prom
1298
1235
  } catch (err: unknown) {
1299
1236
  const error = err as ExecError;
1300
1237
  const {stderr = '', message} = error;
1301
- log.warn(
1302
- `Unable to ${cmd} adb daemon. Original error: '${message}'. Stderr: '${stderr}'. Continuing.`,
1303
- );
1238
+ log.warn(`Unable to ${cmd} adb daemon. Original error: '${message}'. Stderr: '${stderr}'. Continuing.`);
1304
1239
  return {isSuccessful: false, wasAlreadyRooted};
1305
1240
  }
1306
1241
  }
@@ -1356,11 +1291,9 @@ export async function installMitmCertificate(this: ADB, cert: Buffer | string):
1356
1291
  log.debug(`Got certificate hash: ${certHash}`);
1357
1292
  log.debug('Preparing certificate content');
1358
1293
  const {stdout: stdoutBuff1} = await exec(openSsl, ['x509', '-in', srcCert], {isBuffer: true});
1359
- const {stdout: stdoutBuff2} = await exec(
1360
- openSsl,
1361
- ['x509', '-in', srcCert, '-text', '-fingerprint', '-noout'],
1362
- {isBuffer: true},
1363
- );
1294
+ const {stdout: stdoutBuff2} = await exec(openSsl, ['x509', '-in', srcCert, '-text', '-fingerprint', '-noout'], {
1295
+ isBuffer: true,
1296
+ });
1364
1297
  const dstCertContent = Buffer.concat([stdoutBuff1, stdoutBuff2]);
1365
1298
  const dstCert = path.resolve(tmpRoot, `${certHash}.0`);
1366
1299
  await fs.writeFile(dstCert, dstCertContent);
@@ -1392,10 +1325,7 @@ export async function installMitmCertificate(this: ADB, cert: Buffer | string):
1392
1325
  * @returns True if certificate is installed, false otherwise
1393
1326
  * @throws {Error} If certificate hash cannot be retrieved
1394
1327
  */
1395
- export async function isMitmCertificateInstalled(
1396
- this: ADB,
1397
- cert: Buffer | string,
1398
- ): Promise<boolean> {
1328
+ export async function isMitmCertificateInstalled(this: ADB, cert: Buffer | string): Promise<boolean> {
1399
1329
  const openSsl = await getOpenSslForOs();
1400
1330
 
1401
1331
  const tmpRoot = await tempDir.openDir();
@@ -1431,11 +1361,7 @@ export async function isMitmCertificateInstalled(
1431
1361
  * @param args - Array of arguments to process
1432
1362
  * @throws {Error} If argument transformer returns invalid result or command execution fails
1433
1363
  */
1434
- export async function shellChunks(
1435
- this: ADB,
1436
- argTransformer: (x: string) => string[],
1437
- args: string[],
1438
- ): Promise<void> {
1364
+ export async function shellChunks(this: ADB, argTransformer: (x: string) => string[], args: string[]): Promise<void> {
1439
1365
  const commands: string[][] = [];
1440
1366
  let cmdChunk: string[] = [];
1441
1367
  for (const arg of args) {
@@ -1506,9 +1432,7 @@ export function toAvdLocaleArgs(language: string | null, country: string | null)
1506
1432
  * @param sdkRoot - The Android SDK root directory path
1507
1433
  * @returns Array of build-tools directory paths (newest first)
1508
1434
  */
1509
- export const getBuildToolsDirs = memoize(async function getBuildToolsDirs(
1510
- sdkRoot: string,
1511
- ): Promise<string[]> {
1435
+ export const getBuildToolsDirs = memoize(async function getBuildToolsDirs(sdkRoot: string): Promise<string[]> {
1512
1436
  let buildToolsDirs = await fs.glob('*/', {
1513
1437
  cwd: path.resolve(sdkRoot, 'build-tools'),
1514
1438
  absolute: true,
@@ -1531,9 +1455,7 @@ export const getBuildToolsDirs = memoize(async function getBuildToolsDirs(
1531
1455
  );
1532
1456
  buildToolsDirs = pairs.sort((a, b) => (a[0] < b[0] ? 1 : -1)).map((pair) => pair[1]);
1533
1457
  }
1534
- log.info(
1535
- `Found ${buildToolsDirs.length} 'build-tools' folders under '${sdkRoot}' (newest first):`,
1536
- );
1458
+ log.info(`Found ${buildToolsDirs.length} 'build-tools' folders under '${sdkRoot}' (newest first):`);
1537
1459
  for (const dir of buildToolsDirs) {
1538
1460
  log.info(` ${dir}`);
1539
1461
  }
@@ -732,14 +732,10 @@ export interface RootResult {
732
732
  }
733
733
 
734
734
  export type Sensors = (typeof emuConstants.SENSORS)[keyof typeof emuConstants.SENSORS];
735
- export type NetworkSpeed =
736
- (typeof emuConstants.NETWORK_SPEED)[keyof typeof emuConstants.NETWORK_SPEED];
737
- export type GsmVoiceStates =
738
- (typeof emuConstants.GSM_VOICE_STATES)[keyof typeof emuConstants.GSM_VOICE_STATES];
739
- export type GsmCallActions =
740
- (typeof emuConstants.GSM_CALL_ACTIONS)[keyof typeof emuConstants.GSM_CALL_ACTIONS];
741
- export type PowerAcStates =
742
- (typeof emuConstants.POWER_AC_STATES)[keyof typeof emuConstants.POWER_AC_STATES];
735
+ export type NetworkSpeed = (typeof emuConstants.NETWORK_SPEED)[keyof typeof emuConstants.NETWORK_SPEED];
736
+ export type GsmVoiceStates = (typeof emuConstants.GSM_VOICE_STATES)[keyof typeof emuConstants.GSM_VOICE_STATES];
737
+ export type GsmCallActions = (typeof emuConstants.GSM_CALL_ACTIONS)[keyof typeof emuConstants.GSM_CALL_ACTIONS];
738
+ export type PowerAcStates = (typeof emuConstants.POWER_AC_STATES)[keyof typeof emuConstants.POWER_AC_STATES];
743
739
 
744
740
  export interface PlatformInfo {
745
741
  /**
@@ -1,9 +1,4 @@
1
- export {
2
- APKS_EXTENSION,
3
- APK_EXTENSION,
4
- APK_INSTALL_TIMEOUT,
5
- DEFAULT_ADB_EXEC_TIMEOUT,
6
- } from './constants.js';
1
+ export {APKS_EXTENSION, APK_EXTENSION, APK_INSTALL_TIMEOUT, DEFAULT_ADB_EXEC_TIMEOUT} from './constants.js';
7
2
  export {buildInstallArgs, type BuildInstallArgsOptions} from './install.js';
8
3
  export {readPackageManifest} from './manifest.js';
9
4
  export {getResourcePath, unzipFile} from './resource.js';
@@ -1,4 +1,5 @@
1
1
  import {util} from '@appium/support';
2
+
2
3
  import {log} from '../../logger.js';
3
4
 
4
5
  export interface BuildInstallArgsOptions {
@@ -16,10 +17,7 @@ export interface BuildInstallArgsOptions {
16
17
  * @param options - Install options mapped to adb flags
17
18
  * @returns A list of install flags
18
19
  */
19
- export function buildInstallArgs(
20
- apiLevel: number,
21
- options: BuildInstallArgsOptions = {},
22
- ): string[] {
20
+ export function buildInstallArgs(apiLevel: number, options: BuildInstallArgsOptions = {}): string[] {
23
21
  const result: string[] = [];
24
22
 
25
23
  if (!util.hasValue(options.replace) || options.replace) {
@@ -1,7 +1,8 @@
1
1
  import {util} from '@appium/support';
2
2
  import {exec, type ExecError} from 'teen_process';
3
- import {log} from '../../logger.js';
3
+
4
4
  import type {ADB} from '../../adb.js';
5
+ import {log} from '../../logger.js';
5
6
  import type {ApkManifest} from '../../tools/types.js';
6
7
 
7
8
  /**
@@ -34,22 +35,14 @@ export async function readPackageManifest(this: ADB, apkPath: string): Promise<A
34
35
  throw new Error(`${prefix}. ${suffix}`, {cause: e});
35
36
  }
36
37
 
37
- const extractValue = (
38
- line: string,
39
- propPattern: RegExp,
40
- valueTransformer: ((x: string) => any) | null,
41
- ): any => {
38
+ const extractValue = (line: string, propPattern: RegExp, valueTransformer: ((x: string) => any) | null): any => {
42
39
  const match = propPattern.exec(line);
43
40
  if (match) {
44
41
  return valueTransformer ? valueTransformer(match[1]) : match[1];
45
42
  }
46
43
  return undefined;
47
44
  };
48
- const extractArray = (
49
- line: string,
50
- propPattern: RegExp,
51
- valueTransformer: ((x: string) => any) | null,
52
- ): any[] => {
45
+ const extractArray = (line: string, propPattern: RegExp, valueTransformer: ((x: string) => any) | null): any[] => {
53
46
  let match: RegExpExecArray | null;
54
47
  const resultArray: any[] = [];
55
48
  while ((match = propPattern.exec(line))) {
@@ -1,18 +1,17 @@
1
1
  import path from 'node:path';
2
2
  import {fileURLToPath} from 'node:url';
3
+
3
4
  import {fs, zip, util} from '@appium/support';
5
+
4
6
  import {log} from '../../logger.js';
5
7
  import {MODULE_NAME} from './constants.js';
6
8
 
7
- export const getResourcePath = util.memoize(async function getResourcePath(
8
- relPath: string,
9
- ): Promise<string> {
9
+ export const getResourcePath = util.memoize(async function getResourcePath(relPath: string): Promise<string> {
10
10
  const moduleRoot = await getModuleRoot();
11
11
  const resultPath = path.resolve(moduleRoot, relPath);
12
12
  if (!(await fs.exists(resultPath))) {
13
13
  throw new Error(
14
- `Cannot find the resource '${relPath}' under the '${moduleRoot}' ` +
15
- `folder of ${MODULE_NAME} Node.js module`,
14
+ `Cannot find the resource '${relPath}' under the '${moduleRoot}' folder of ${MODULE_NAME} Node.js module`,
16
15
  );
17
16
  }
18
17
  return resultPath;
@@ -24,10 +23,7 @@ export const getResourcePath = util.memoize(async function getResourcePath(
24
23
  * @param zipPath - Source zip file path
25
24
  * @param dstRoot - Destination directory. Defaults to zip parent directory
26
25
  */
27
- export async function unzipFile(
28
- zipPath: string,
29
- dstRoot: string = path.dirname(zipPath),
30
- ): Promise<void> {
26
+ export async function unzipFile(zipPath: string, dstRoot: string = path.dirname(zipPath)): Promise<void> {
31
27
  log.debug(`Unzipping '${zipPath}' to '${dstRoot}'`);
32
28
  await zip.assertValidZip(zipPath);
33
29
  await zip.extractAllTo(zipPath, dstRoot);