appium-adb 16.0.0 → 16.0.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 (103) hide show
  1. package/CHANGELOG.md +19 -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 -50
@@ -1,12 +1,14 @@
1
- import {log} from '../logger.js';
1
+ import crypto from 'node:crypto';
2
2
  import path from 'node:path';
3
+
3
4
  import {fs, tempDir, util} from '@appium/support';
4
- import {LRUCache} from 'lru-cache';
5
5
  import AsyncLock from 'async-lock';
6
- import crypto from 'node:crypto';
6
+ import {LRUCache} from 'lru-cache';
7
+
7
8
  import type {ADB} from '../adb.js';
8
- import type {ApkCreationOptions, StringRecord} from './types.js';
9
+ import {log} from '../logger.js';
9
10
  import {unzipFile} from '../utils/index.js';
11
+ import type {ApkCreationOptions, StringRecord} from './types.js';
10
12
 
11
13
  const AAB_CACHE = new LRUCache<string, string>({
12
14
  max: 10,
@@ -21,9 +23,7 @@ process.on('exit', () => {
21
23
  }
22
24
 
23
25
  const paths = [...AAB_CACHE.values()];
24
- log.debug(
25
- `Performing cleanup of ${paths.length} cached .aab ` + util.pluralize('package', paths.length),
26
- );
26
+ log.debug(`Performing cleanup of ${paths.length} cached .aab ` + util.pluralize('package', paths.length));
27
27
  for (const appPath of paths) {
28
28
  try {
29
29
  // Asynchronous calls are not supported in onExit handler
@@ -45,11 +45,7 @@ process.on('exit', () => {
45
45
  * by default.
46
46
  * @throws {Error} If there was an error while creating the universal .apk
47
47
  */
48
- export async function extractUniversalApk(
49
- this: ADB,
50
- aabPath: string,
51
- opts: ApkCreationOptions = {},
52
- ): Promise<string> {
48
+ export async function extractUniversalApk(this: ADB, aabPath: string, opts: ApkCreationOptions = {}): Promise<string> {
53
49
  if (!(await fs.exists(aabPath))) {
54
50
  throw new Error(`The file at '${aabPath}' either does not exist or is not accessible`);
55
51
  }
@@ -65,9 +61,7 @@ export async function extractUniversalApk(
65
61
  let cacheHash = aabHash;
66
62
  if (keystore) {
67
63
  if (!(await fs.exists(keystore))) {
68
- throw new Error(
69
- `The keystore file at '${keystore}' either does not exist ` + `or is not accessible`,
70
- );
64
+ throw new Error(`The keystore file at '${keystore}' either does not exist or is not accessible`);
71
65
  }
72
66
  if (!keystorePassword || !keyAlias || !keyPassword) {
73
67
  throw new Error(
@@ -1,10 +1,12 @@
1
- import {exec} from 'teen_process';
2
- import {log} from '../logger.js';
3
- import {fs, zip, tempDir, util} from '@appium/support';
4
1
  import path from 'node:path';
2
+
3
+ import {fs, zip, tempDir, util} from '@appium/support';
4
+ import {exec} from 'teen_process';
5
+
5
6
  import type {ADB} from '../adb.js';
6
- import type {APKInfo, PlatformInfo, StringRecord} from './types.js';
7
+ import {log} from '../logger.js';
7
8
  import {APKS_EXTENSION, readPackageManifest, unzipFile} from '../utils/index.js';
9
+ import type {APKInfo, PlatformInfo, StringRecord} from './types.js';
8
10
 
9
11
  /**
10
12
  * Extract package and main activity name from application manifest.
@@ -14,10 +16,7 @@ import {APKS_EXTENSION, readPackageManifest, unzipFile} from '../utils/index.js'
14
16
  * @throws {error} If there was an error while getting the data from the given
15
17
  * application package.
16
18
  */
17
- export async function packageAndLaunchActivityFromManifest(
18
- this: ADB,
19
- appPath: string,
20
- ): Promise<APKInfo> {
19
+ export async function packageAndLaunchActivityFromManifest(this: ADB, appPath: string): Promise<APKInfo> {
21
20
  if (appPath.endsWith(APKS_EXTENSION)) {
22
21
  appPath = await this.extractBaseApk(appPath);
23
22
  }
@@ -48,10 +47,7 @@ export async function targetSdkVersionFromManifest(this: ADB, appPath: string):
48
47
 
49
48
  const {targetSdkVersion} = await readPackageManifest.bind(this)(appPath);
50
49
  if (!targetSdkVersion) {
51
- throw new Error(
52
- `Cannot extract targetSdkVersion of '${originalAppPath}'. Does ` +
53
- `the package manifest define it?`,
54
- );
50
+ throw new Error(`Cannot extract targetSdkVersion of '${originalAppPath}'. Does the package manifest define it?`);
55
51
  }
56
52
  return targetSdkVersion;
57
53
  }
@@ -71,9 +67,7 @@ export async function targetSdkVersionUsingPKG(
71
67
  ): Promise<number> {
72
68
  const stdout = cmdOutput || (await this.shell(['dumpsys', 'package', pkg]));
73
69
  const targetSdkVersionMatch = new RegExp(/targetSdk=([^\s\s]+)/g).exec(stdout);
74
- return targetSdkVersionMatch && targetSdkVersionMatch.length >= 2
75
- ? parseInt(targetSdkVersionMatch[1], 10)
76
- : 0;
70
+ return targetSdkVersionMatch && targetSdkVersionMatch.length >= 2 ? parseInt(targetSdkVersionMatch[1], 10) : 0;
77
71
  }
78
72
 
79
73
  /**
@@ -93,9 +87,7 @@ export async function compileManifest(
93
87
  ): Promise<void> {
94
88
  const {platform, platformPath} = await getAndroidPlatformAndPath(this.sdkRoot as string);
95
89
  if (!platform || !platformPath) {
96
- throw new Error(
97
- 'Cannot compile the manifest. The required platform does not exist (API level >= 17)',
98
- );
90
+ throw new Error('Cannot compile the manifest. The required platform does not exist (API level >= 17)');
99
91
  }
100
92
  const resultPath = `${manifest}.apk`;
101
93
  const androidJarPath = path.resolve(platformPath, 'android.jar');
@@ -169,12 +161,7 @@ export async function compileManifest(
169
161
  * @param dstApk - Full path to the resulting package.
170
162
  * The file will be overridden if it already exists.
171
163
  */
172
- export async function insertManifest(
173
- this: ADB,
174
- manifest: string,
175
- srcApk: string,
176
- dstApk: string,
177
- ): Promise<void> {
164
+ export async function insertManifest(this: ADB, manifest: string, srcApk: string, dstApk: string): Promise<void> {
178
165
  log.debug(`Inserting manifest '${manifest}', src: '${srcApk}', dst: '${dstApk}'`);
179
166
  await zip.assertValidZip(srcApk);
180
167
  await unzipFile(`${manifest}.apk`);
@@ -221,10 +208,7 @@ export async function insertManifest(
221
208
  * @param appPath - The full path to .apk(s) package.
222
209
  * @return True if the manifest requires Internet access permission.
223
210
  */
224
- export async function hasInternetPermissionFromManifest(
225
- this: ADB,
226
- appPath: string,
227
- ): Promise<boolean> {
211
+ export async function hasInternetPermissionFromManifest(this: ADB, appPath: string): Promise<boolean> {
228
212
  log.debug(`Checking if '${appPath}' requires internet access permission in the manifest`);
229
213
  if (appPath.endsWith(APKS_EXTENSION)) {
230
214
  appPath = await this.extractBaseApk(appPath);
@@ -1,12 +1,14 @@
1
1
  import _fs from 'node:fs';
2
- import {exec, type ExecError} from 'teen_process';
3
2
  import path from 'node:path';
4
- import {log} from '../logger.js';
3
+
5
4
  import {tempDir, system, mkdirp, fs, util, zip} from '@appium/support';
6
5
  import {LRUCache} from 'lru-cache';
6
+ import {exec, type ExecError} from 'teen_process';
7
+
7
8
  import type {ADB} from '../adb.js';
8
- import type {StringRecord, SignedAppCacheValue, CertCheckOptions, KeystoreHash} from './types.js';
9
+ import {log} from '../logger.js';
9
10
  import {APKS_EXTENSION, getJavaForOs, getJavaHome, getResourcePath} from '../utils/index.js';
11
+ import type {StringRecord, SignedAppCacheValue, CertCheckOptions, KeystoreHash} from './types.js';
10
12
 
11
13
  const DEFAULT_PRIVATE_KEY = path.join('keys', 'testkey.pk8');
12
14
  const DEFAULT_CERTIFICATE = path.join('keys', 'testkey.x509.pem');
@@ -134,11 +136,7 @@ export async function signWithCustomCert(this: ADB, apk: string): Promise<void>
134
136
  } else {
135
137
  log.debug(`'${apk}' does not need to be unsigned`);
136
138
  }
137
- const jarsigner = path.resolve(
138
- await getJavaHome(),
139
- 'bin',
140
- `jarsigner${system.isWindows() ? '.exe' : ''}`,
141
- );
139
+ const jarsigner = path.resolve(await getJavaHome(), 'bin', `jarsigner${system.isWindows() ? '.exe' : ''}`);
142
140
  const fullCmd: string[] = [
143
141
  jarsigner,
144
142
  '-sigalg',
@@ -158,11 +156,9 @@ export async function signWithCustomCert(this: ADB, apk: string): Promise<void>
158
156
  await exec(fullCmd[0], fullCmd.slice(1));
159
157
  } catch (e) {
160
158
  const execErr = e as ExecError;
161
- throw new Error(
162
- `Could not sign with custom certificate. ` +
163
- `Original error: ${execErr.stderr || execErr.message}`,
164
- {cause: e},
165
- );
159
+ throw new Error(`Could not sign with custom certificate. Original error: ${execErr.stderr || execErr.message}`, {
160
+ cause: e,
161
+ });
166
162
  }
167
163
  }
168
164
  }
@@ -239,10 +235,7 @@ export async function zipAlignApk(this: ADB, apk: string): Promise<boolean> {
239
235
  if (await fs.exists(alignedApk)) {
240
236
  await fs.unlink(alignedApk);
241
237
  }
242
- throw new Error(
243
- `zipAlignApk failed. Original error: ${err.message || (err as ExecError).stderr}`,
244
- {cause: e},
245
- );
238
+ throw new Error(`zipAlignApk failed. Original error: ${err.message || (err as ExecError).stderr}`, {cause: e});
246
239
  }
247
240
  }
248
241
 
@@ -253,11 +246,7 @@ export async function zipAlignApk(this: ADB, apk: string): Promise<boolean> {
253
246
  * @param opts - Certificate checking options
254
247
  * @returns True if given application is already signed.
255
248
  */
256
- export async function checkApkCert(
257
- this: ADB,
258
- appPath: string,
259
- opts: CertCheckOptions = {},
260
- ): Promise<boolean> {
249
+ export async function checkApkCert(this: ADB, appPath: string, opts: CertCheckOptions = {}): Promise<boolean> {
261
250
  log.debug(`Checking app cert for ${appPath}`);
262
251
  if (!(await fs.exists(appPath))) {
263
252
  log.debug(`'${appPath}' does not exist`);
@@ -299,15 +288,9 @@ export async function checkApkCert(
299
288
  const output = await this.executeApksigner(['verify', '--print-certs', actualAppPath]);
300
289
  const hasMatch = hashMatches(output, expected);
301
290
  if (hasMatch) {
302
- log.info(
303
- `'${actualAppPath}' is signed with the ` +
304
- `${this.useKeystore ? 'keystore' : 'default'} certificate`,
305
- );
291
+ log.info(`'${actualAppPath}' is signed with the ${this.useKeystore ? 'keystore' : 'default'} certificate`);
306
292
  } else {
307
- log.info(
308
- `'${actualAppPath}' is signed with a ` +
309
- `non-${this.useKeystore ? 'keystore' : 'default'} certificate`,
310
- );
293
+ log.info(`'${actualAppPath}' is signed with a non-${this.useKeystore ? 'keystore' : 'default'} certificate`);
311
294
  }
312
295
  const isSigned = (!this.useKeystore && !requireDefaultCert) || hasMatch;
313
296
  if (isSigned) {
@@ -339,10 +322,7 @@ export async function checkApkCert(
339
322
  log.warn(`Assuming '${actualAppPath}' is already signed and continuing anyway`);
340
323
  return true;
341
324
  }
342
- throw new Error(
343
- `Cannot verify the signature of '${actualAppPath}'. ` + `Original error: ${errMsg}`,
344
- {cause: err},
345
- );
325
+ throw new Error(`Cannot verify the signature of '${actualAppPath}'. Original error: ${errMsg}`, {cause: err});
346
326
  }
347
327
  }
348
328
 
@@ -354,11 +334,7 @@ export async function checkApkCert(
354
334
  */
355
335
  export async function getKeystoreHash(this: ADB): Promise<KeystoreHash> {
356
336
  log.debug(`Getting hash of the '${this.keystorePath}' keystore`);
357
- const keytool = path.resolve(
358
- await getJavaHome(),
359
- 'bin',
360
- `keytool${system.isWindows() ? '.exe' : ''}`,
361
- );
337
+ const keytool = path.resolve(await getJavaHome(), 'bin', `keytool${system.isWindows() ? '.exe' : ''}`);
362
338
  if (!(await fs.exists(keytool))) {
363
339
  throw new Error(`The keytool utility cannot be found at '${keytool}'`);
364
340
  }
@@ -394,8 +370,7 @@ export async function getKeystoreHash(this: ADB): Promise<KeystoreHash> {
394
370
  } catch (e) {
395
371
  const err = e as ExecError;
396
372
  throw new Error(
397
- `Cannot get the hash of '${this.keystorePath}' keystore. ` +
398
- `Original error: ${err.stderr || err.message}`,
373
+ `Cannot get the hash of '${this.keystorePath}' keystore. Original error: ${err.stderr || err.message}`,
399
374
  {cause: e},
400
375
  );
401
376
  }
@@ -1,11 +1,13 @@
1
- import {exec, type ExecError} from 'teen_process';
2
- import {log} from '../logger.js';
1
+ import os from 'node:os';
3
2
  import path from 'node:path';
3
+
4
4
  import {fs, util, mkdirp, timing} from '@appium/support';
5
- import * as semver from 'semver';
6
- import os from 'node:os';
7
5
  import {LRUCache} from 'lru-cache';
6
+ import * as semver from 'semver';
7
+ import {exec, type ExecError} from 'teen_process';
8
+
8
9
  import type {ADB} from '../adb.js';
10
+ import {log} from '../logger.js';
9
11
  import {
10
12
  APKS_EXTENSION,
11
13
  APK_INSTALL_TIMEOUT,
@@ -38,11 +40,7 @@ export const REMOTE_CACHE_ROOT = '/data/local/tmp/appium_cache';
38
40
  * @returns True if the package was found on the device and
39
41
  * successfully uninstalled.
40
42
  */
41
- export async function uninstallApk(
42
- this: ADB,
43
- pkg: string,
44
- options: UninstallOptions = {},
45
- ): Promise<boolean> {
43
+ export async function uninstallApk(this: ADB, pkg: string, options: UninstallOptions = {}): Promise<boolean> {
46
44
  log.debug(`Uninstalling ${pkg}`);
47
45
  if (!options.skipInstallCheck && !(await this.isAppInstalled(pkg))) {
48
46
  log.info(`${pkg} was not uninstalled, because it was not present on the device`);
@@ -98,11 +96,7 @@ export async function installFromDevicePath(
98
96
  * @returns Full path to the cached apk on the remote file system
99
97
  * @throws if there was a failure while caching the app
100
98
  */
101
- export async function cacheApk(
102
- this: ADB,
103
- apkPath: string,
104
- options: CachingOptions = {},
105
- ): Promise<string> {
99
+ export async function cacheApk(this: ADB, apkPath: string, options: CachingOptions = {}): Promise<string> {
106
100
  const appHash = await fs.hash(apkPath);
107
101
  const remotePath = path.posix.join(REMOTE_CACHE_ROOT, `${appHash}.apk`);
108
102
  const remoteCachedFiles: string[] = [];
@@ -110,21 +104,12 @@ export async function cacheApk(
110
104
  try {
111
105
  const errorMarker = '_ERROR_';
112
106
  let lsOutput: string | null = null;
113
- if (
114
- this._areExtendedLsOptionsSupported === true ||
115
- typeof this._areExtendedLsOptionsSupported !== 'boolean'
116
- ) {
107
+ if (this._areExtendedLsOptionsSupported === true || typeof this._areExtendedLsOptionsSupported !== 'boolean') {
117
108
  lsOutput = await this.shell([`ls -t -1 ${REMOTE_CACHE_ROOT} 2>&1 || echo ${errorMarker}`]);
118
109
  }
119
- if (
120
- typeof lsOutput !== 'string' ||
121
- (lsOutput.includes(errorMarker) && !lsOutput.includes(REMOTE_CACHE_ROOT))
122
- ) {
110
+ if (typeof lsOutput !== 'string' || (lsOutput.includes(errorMarker) && !lsOutput.includes(REMOTE_CACHE_ROOT))) {
123
111
  if (typeof this._areExtendedLsOptionsSupported !== 'boolean') {
124
- log.debug(
125
- 'The current Android API does not support extended ls options. ' +
126
- 'Defaulting to no-options call',
127
- );
112
+ log.debug('The current Android API does not support extended ls options. Defaulting to no-options call');
128
113
  }
129
114
  lsOutput = await this.shell([`ls ${REMOTE_CACHE_ROOT} 2>&1 || echo ${errorMarker}`]);
130
115
  this._areExtendedLsOptionsSupported = false;
@@ -206,11 +191,7 @@ export async function cacheApk(
206
191
  * @param options - The set of installation options.
207
192
  * @throws If an unexpected error happens during install.
208
193
  */
209
- export async function install(
210
- this: ADB,
211
- appPath: string,
212
- options: InstallOptions = {},
213
- ): Promise<void> {
194
+ export async function install(this: ADB, appPath: string, options: InstallOptions = {}): Promise<void> {
214
195
  if (appPath.endsWith(APKS_EXTENSION)) {
215
196
  return await this.installApks(appPath, options);
216
197
  }
@@ -218,8 +199,7 @@ export async function install(
218
199
  options = cloneDeep(options);
219
200
  defaults(options, {
220
201
  replace: true,
221
- timeout:
222
- this.adbExecTimeout === DEFAULT_ADB_EXEC_TIMEOUT ? APK_INSTALL_TIMEOUT : this.adbExecTimeout,
202
+ timeout: this.adbExecTimeout === DEFAULT_ADB_EXEC_TIMEOUT ? APK_INSTALL_TIMEOUT : this.adbExecTimeout,
223
203
  timeoutCapName: 'androidInstallTimeout',
224
204
  });
225
205
 
@@ -237,9 +217,7 @@ export async function install(
237
217
  try {
238
218
  const timer = new timing.Timer().start();
239
219
  const output = await this.adbExec(installCmd, installOpts);
240
- log.info(
241
- `The installation of '${path.basename(appPath)}' took ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`,
242
- );
220
+ log.info(`The installation of '${path.basename(appPath)}' took ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
243
221
  log.debug(`Install command stdout: ${util.truncateString(output, {length: 300})}`);
244
222
  if (/\[INSTALL[A-Z_]+FAILED[A-Z_]+\]/.test(output)) {
245
223
  if (this.isTestPackageOnlyError(output)) {
@@ -283,11 +261,7 @@ export async function getApplicationInstallState(
283
261
  return this.APP_INSTALL_STATE.UNKNOWN;
284
262
  }
285
263
 
286
- const {
287
- versionCode: pkgVersionCode,
288
- versionName: pkgVersionNameStr,
289
- isInstalled,
290
- } = await this.getPackageInfo(pkg);
264
+ const {versionCode: pkgVersionCode, versionName: pkgVersionNameStr, isInstalled} = await this.getPackageInfo(pkg);
291
265
  if (!isInstalled) {
292
266
  log.debug(`App '${appPath}' is not installed`);
293
267
  return this.APP_INSTALL_STATE.NOT_INSTALLED;
@@ -375,10 +349,7 @@ export async function installOrUpgrade(
375
349
  if ('name' in apkInfo) {
376
350
  pkg = apkInfo.name;
377
351
  } else {
378
- log.warn(
379
- `Cannot determine the package name of '${appPath}'. ` +
380
- `Continuing with the install anyway`,
381
- );
352
+ log.warn(`Cannot determine the package name of '${appPath}'. Continuing with the install anyway`);
382
353
  }
383
354
  }
384
355
 
@@ -431,9 +402,7 @@ export async function installOrUpgrade(
431
402
  await this.install(appPath, {...options, replace: true});
432
403
  } catch (err) {
433
404
  const error = err as Error;
434
- log.warn(
435
- `Cannot install/upgrade '${pkg}' because of '${error.message}'. Trying full reinstall`,
436
- );
405
+ log.warn(`Cannot install/upgrade '${pkg}' because of '${error.message}'. Trying full reinstall`);
437
406
  await uninstallPackage();
438
407
  await this.install(appPath, {...options, replace: false});
439
408
  }
@@ -472,11 +441,7 @@ export async function extractStringsFromApk(
472
441
 
473
442
  configMarker = await formatConfigMarker(
474
443
  async () => {
475
- const {stdout} = await exec((this.binaries as StringRecord).aapt as string, [
476
- 'd',
477
- 'configurations',
478
- appPath,
479
- ]);
444
+ const {stdout} = await exec((this.binaries as StringRecord).aapt as string, ['d', 'configurations', appPath]);
480
445
  return util.uniq(stdout.split(os.EOL));
481
446
  },
482
447
  language,
@@ -492,20 +457,13 @@ export async function extractStringsFromApk(
492
457
  apkStrings = parseAaptStrings(stdout, configMarker);
493
458
  } catch (e) {
494
459
  const err = e as ExecError;
495
- log.debug(
496
- 'Cannot extract resources using aapt. Trying aapt2. ' +
497
- `Original error: ${err.stderr || err.message}`,
498
- );
460
+ log.debug(`Cannot extract resources using aapt. Trying aapt2. Original error: ${err.stderr || err.message}`);
499
461
 
500
462
  await this.initAapt2();
501
463
 
502
464
  configMarker = await formatConfigMarker(
503
465
  async () => {
504
- const {stdout} = await exec((this.binaries as StringRecord).aapt2 as string, [
505
- 'd',
506
- 'configurations',
507
- appPath,
508
- ]);
466
+ const {stdout} = await exec((this.binaries as StringRecord).aapt2 as string, ['d', 'configurations', appPath]);
509
467
  return util.uniq(stdout.split(os.EOL));
510
468
  },
511
469
  language,
@@ -513,18 +471,13 @@ export async function extractStringsFromApk(
513
471
  );
514
472
 
515
473
  try {
516
- const {stdout} = await exec((this.binaries as StringRecord).aapt2 as string, [
517
- 'd',
518
- 'resources',
519
- appPath,
520
- ]);
474
+ const {stdout} = await exec((this.binaries as StringRecord).aapt2 as string, ['d', 'resources', appPath]);
521
475
  apkStrings = parseAapt2Strings(stdout, configMarker);
522
476
  } catch (e) {
523
477
  const error = e as Error;
524
- throw new Error(
525
- `Cannot extract resources from '${originalAppPath}'. ` + `Original error: ${error.message}`,
526
- {cause: e},
527
- );
478
+ throw new Error(`Cannot extract resources from '${originalAppPath}'. Original error: ${error.message}`, {
479
+ cause: e,
480
+ });
528
481
  }
529
482
  }
530
483
 
@@ -673,9 +626,7 @@ export function parseAapt2Strings(rawOutput: string, configMarker: string): Stri
673
626
  lineIndex = idx;
674
627
  if (typeof content === 'string') {
675
628
  apkStrings[currentResourceId] = [
676
- ...(Array.isArray(apkStrings[currentResourceId])
677
- ? apkStrings[currentResourceId]
678
- : []),
629
+ ...(Array.isArray(apkStrings[currentResourceId]) ? apkStrings[currentResourceId] : []),
679
630
  content,
680
631
  ];
681
632
  }
@@ -796,14 +747,8 @@ async function formatConfigMarker(
796
747
  const configs = await configsGetter();
797
748
  log.debug(`Resource configurations: ${JSON.stringify(configs)}`);
798
749
  // Assume the 'en' configuration is the default one
799
- if (
800
- configMarker.toLowerCase().startsWith('en') &&
801
- !configs.some((x) => x.trim() === configMarker)
802
- ) {
803
- log.debug(
804
- `Resource configuration name '${configMarker}' is unknown. ` +
805
- `Replacing it with '${defaultMarker}'`,
806
- );
750
+ if (configMarker.toLowerCase().startsWith('en') && !configs.some((x) => x.trim() === configMarker)) {
751
+ log.debug(`Resource configuration name '${configMarker}' is unknown. Replacing it with '${defaultMarker}'`);
807
752
  configMarker = defaultMarker;
808
753
  } else {
809
754
  log.debug(`Selected configuration: '${configMarker}'`);
@@ -1,12 +1,14 @@
1
- import {exec} from 'teen_process';
2
- import {log} from '../logger.js';
3
1
  import path from 'node:path';
2
+
4
3
  import {fs, tempDir, util} from '@appium/support';
5
- import {LRUCache} from 'lru-cache';
6
4
  import AsyncLock from 'async-lock';
5
+ import {LRUCache} from 'lru-cache';
6
+ import {exec} from 'teen_process';
7
+
7
8
  import type {ADB} from '../adb.js';
8
- import type {InstallMultipleApksOptions, InstallApksOptions, StringRecord} from './types.js';
9
+ import {log} from '../logger.js';
9
10
  import {APK_INSTALL_TIMEOUT, buildInstallArgs, getJavaForOs, unzipFile} from '../utils/index.js';
11
+ import type {InstallMultipleApksOptions, InstallApksOptions, StringRecord} from './types.js';
10
12
 
11
13
  const BASE_APK = 'base-master.apk';
12
14
  const LANGUAGE_APK = (lang: string) => `base-${lang}.apk`;
@@ -24,9 +26,7 @@ process.on('exit', () => {
24
26
  }
25
27
 
26
28
  const paths = [...APKS_CACHE.values()];
27
- log.debug(
28
- `Performing cleanup of ${paths.length} cached .apks ` + util.pluralize('package', paths.length),
29
- );
29
+ log.debug(`Performing cleanup of ${paths.length} cached .apks ` + util.pluralize('package', paths.length));
30
30
  for (const appPath of paths) {
31
31
  try {
32
32
  // Asynchronous calls are not supported in onExit handler
@@ -125,11 +125,7 @@ export async function installMultipleApks(
125
125
  * @param options - Installation options
126
126
  * @throws {Error} If the .apks bundle cannot be installed
127
127
  */
128
- export async function installApks(
129
- this: ADB,
130
- apks: string,
131
- options: InstallApksOptions = {},
132
- ): Promise<void> {
128
+ export async function installApks(this: ADB, apks: string, options: InstallApksOptions = {}): Promise<void> {
133
129
  const {grantPermissions, allowTestPackages, timeout} = options;
134
130
 
135
131
  const args: string[] = [
@@ -147,10 +143,7 @@ export async function installApks(
147
143
  args.push('--allow-test-only');
148
144
  }
149
145
  const tasks: Promise<any>[] = [
150
- this.execBundletool(
151
- args,
152
- `Cannot install '${path.basename(apks)}' to the device ${this.curDeviceId}`,
153
- ),
146
+ this.execBundletool(args, `Cannot install '${path.basename(apks)}' to the device ${this.curDeviceId}`),
154
147
  ];
155
148
  if (grantPermissions) {
156
149
  tasks.push(this.getApkInfo(apks));
@@ -184,11 +177,7 @@ export async function extractBaseApk(this: ADB, apks: string): Promise<string> {
184
177
  * if language split is not enabled for the bundle.
185
178
  * @throws {Error} If there was an error while extracting/finding the file
186
179
  */
187
- export async function extractLanguageApk(
188
- this: ADB,
189
- apks: string,
190
- language: string | null = null,
191
- ): Promise<string> {
180
+ export async function extractLanguageApk(this: ADB, apks: string, language: string | null = null): Promise<string> {
192
181
  if (language) {
193
182
  try {
194
183
  return await extractFromApks(apks, ['splits', LANGUAGE_APK(language)]);