appium-adb 14.3.1 → 14.3.3

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 +13 -0
  2. package/build/lib/adb.d.ts +9 -9
  3. package/build/lib/adb.d.ts.map +1 -1
  4. package/build/lib/adb.js +61 -61
  5. package/build/lib/adb.js.map +1 -1
  6. package/build/lib/helpers.d.ts +2 -2
  7. package/build/lib/helpers.d.ts.map +1 -1
  8. package/build/lib/helpers.js +5 -5
  9. package/build/lib/helpers.js.map +1 -1
  10. package/build/lib/index.d.ts +8 -0
  11. package/build/lib/index.d.ts.map +1 -0
  12. package/build/{index.js → lib/index.js} +4 -4
  13. package/build/lib/index.js.map +1 -0
  14. package/build/lib/logcat.d.ts.map +1 -1
  15. package/build/lib/logcat.js +1 -1
  16. package/build/lib/logcat.js.map +1 -1
  17. package/build/lib/tools/aab-utils.d.ts +2 -2
  18. package/build/lib/tools/aab-utils.d.ts.map +1 -1
  19. package/build/lib/tools/aab-utils.js +10 -10
  20. package/build/lib/tools/aab-utils.js.map +1 -1
  21. package/build/lib/tools/android-manifest.d.ts +2 -2
  22. package/build/lib/tools/android-manifest.d.ts.map +1 -1
  23. package/build/lib/tools/android-manifest.js +27 -27
  24. package/build/lib/tools/android-manifest.js.map +1 -1
  25. package/build/lib/tools/apk-signing.d.ts +2 -2
  26. package/build/lib/tools/apk-signing.d.ts.map +1 -1
  27. package/build/lib/tools/apk-signing.js +34 -34
  28. package/build/lib/tools/apk-signing.js.map +1 -1
  29. package/build/lib/tools/apk-utils.d.ts +2 -2
  30. package/build/lib/tools/apk-utils.d.ts.map +1 -1
  31. package/build/lib/tools/apk-utils.js +76 -76
  32. package/build/lib/tools/apk-utils.js.map +1 -1
  33. package/build/lib/tools/apks-utils.d.ts +2 -2
  34. package/build/lib/tools/apks-utils.d.ts.map +1 -1
  35. package/build/lib/tools/apks-utils.js +58 -58
  36. package/build/lib/tools/apks-utils.js.map +1 -1
  37. package/build/lib/tools/app-commands.d.ts +13 -13
  38. package/build/lib/tools/app-commands.d.ts.map +1 -1
  39. package/build/lib/tools/app-commands.js +36 -38
  40. package/build/lib/tools/app-commands.js.map +1 -1
  41. package/build/lib/tools/device-settings.d.ts +2 -2
  42. package/build/lib/tools/device-settings.d.ts.map +1 -1
  43. package/build/lib/tools/device-settings.js +27 -27
  44. package/build/lib/tools/device-settings.js.map +1 -1
  45. package/build/lib/tools/emulator-commands.d.ts +2 -2
  46. package/build/lib/tools/emulator-commands.d.ts.map +1 -1
  47. package/build/lib/tools/emulator-commands.js +47 -47
  48. package/build/lib/tools/emulator-commands.js.map +1 -1
  49. package/build/lib/tools/fs-commands.d.ts +1 -1
  50. package/build/lib/tools/fs-commands.d.ts.map +1 -1
  51. package/build/lib/tools/fs-commands.js +3 -3
  52. package/build/lib/tools/fs-commands.js.map +1 -1
  53. package/build/lib/tools/general-commands.d.ts +2 -2
  54. package/build/lib/tools/general-commands.d.ts.map +1 -1
  55. package/build/lib/tools/general-commands.js +7 -7
  56. package/build/lib/tools/general-commands.js.map +1 -1
  57. package/build/lib/tools/keyboard-commands.d.ts +2 -2
  58. package/build/lib/tools/keyboard-commands.d.ts.map +1 -1
  59. package/build/lib/tools/keyboard-commands.js +3 -3
  60. package/build/lib/tools/keyboard-commands.js.map +1 -1
  61. package/build/lib/tools/lockmgmt.d.ts +1 -1
  62. package/build/lib/tools/lockmgmt.d.ts.map +1 -1
  63. package/build/lib/tools/lockmgmt.js +78 -78
  64. package/build/lib/tools/lockmgmt.js.map +1 -1
  65. package/build/lib/tools/logcat-commands.d.ts +2 -2
  66. package/build/lib/tools/logcat-commands.d.ts.map +1 -1
  67. package/build/lib/tools/network-commands.d.ts +2 -2
  68. package/build/lib/tools/network-commands.d.ts.map +1 -1
  69. package/build/lib/tools/network-commands.js +10 -10
  70. package/build/lib/tools/network-commands.js.map +1 -1
  71. package/build/lib/tools/process-commands.d.ts +1 -1
  72. package/build/lib/tools/process-commands.d.ts.map +1 -1
  73. package/build/lib/tools/process-commands.js +10 -10
  74. package/build/lib/tools/process-commands.js.map +1 -1
  75. package/build/lib/tools/system-calls.d.ts +8 -8
  76. package/build/lib/tools/system-calls.d.ts.map +1 -1
  77. package/build/lib/tools/system-calls.js +81 -83
  78. package/build/lib/tools/system-calls.js.map +1 -1
  79. package/lib/adb.ts +69 -69
  80. package/lib/helpers.ts +3 -3
  81. package/lib/index.ts +8 -0
  82. package/lib/logcat.ts +4 -6
  83. package/lib/tools/aab-utils.ts +4 -4
  84. package/lib/tools/android-manifest.ts +4 -4
  85. package/lib/tools/apk-signing.ts +4 -4
  86. package/lib/tools/apk-utils.ts +41 -41
  87. package/lib/tools/apks-utils.ts +53 -53
  88. package/lib/tools/app-commands.ts +15 -19
  89. package/lib/tools/device-settings.ts +16 -16
  90. package/lib/tools/emulator-commands.ts +53 -53
  91. package/lib/tools/fs-commands.ts +5 -5
  92. package/lib/tools/general-commands.ts +3 -3
  93. package/lib/tools/keyboard-commands.ts +3 -3
  94. package/lib/tools/lockmgmt.ts +84 -84
  95. package/lib/tools/logcat-commands.ts +2 -2
  96. package/lib/tools/network-commands.ts +3 -3
  97. package/lib/tools/process-commands.ts +2 -2
  98. package/lib/tools/system-calls.ts +13 -17
  99. package/package.json +4 -6
  100. package/build/index.d.ts +0 -8
  101. package/build/index.d.ts.map +0 -1
  102. package/build/index.js.map +0 -1
  103. package/index.ts +0 -8
@@ -1,14 +1,14 @@
1
1
  import {exec} from 'teen_process';
2
- import {log} from '../logger.js';
2
+ import {log} from '../logger';
3
3
  import path from 'node:path';
4
4
  import _ from 'lodash';
5
5
  import {fs, tempDir, util} from '@appium/support';
6
6
  import {LRUCache} from 'lru-cache';
7
- import {getJavaForOs, unzipFile, buildInstallArgs, APK_INSTALL_TIMEOUT} from '../helpers.js';
7
+ import {getJavaForOs, unzipFile, buildInstallArgs, APK_INSTALL_TIMEOUT} from '../helpers';
8
8
  import AsyncLock from 'async-lock';
9
9
  import B from 'bluebird';
10
- import type {ADB} from '../adb.js';
11
- import type {InstallMultipleApksOptions, InstallApksOptions, StringRecord} from './types.js';
10
+ import type {ADB} from '../adb';
11
+ import type {InstallMultipleApksOptions, InstallApksOptions, StringRecord} from './types';
12
12
 
13
13
  const BASE_APK = 'base-master.apk';
14
14
  const LANGUAGE_APK = (lang: string) => `base-${lang}.apk`;
@@ -39,55 +39,6 @@ process.on('exit', () => {
39
39
  }
40
40
  });
41
41
 
42
- /**
43
- * Extracts the particular apks package into a temporary folder,
44
- * finds and returns the full path to the file contained in this apk.
45
- * The resulting temporary path, where the .apks file has been extracted,
46
- * will be stored into the internal LRU cache for better performance.
47
- *
48
- * @param apks - The full path to the .apks file
49
- * @param dstPath - The relative path to the destination file,
50
- * which is going to be extracted, where each path component is an array item
51
- * @returns Full path to the extracted file
52
- * @throws {Error} If the requested item does not exist in the extracted archive or the provides
53
- * apks file is not a valid bundle
54
- */
55
- async function extractFromApks(apks: string, dstPath: string | string[]): Promise<string> {
56
- const normalizedDstPath = _.isArray(dstPath) ? dstPath : [dstPath];
57
-
58
- return await APKS_CACHE_GUARD.acquire(apks, async () => {
59
- // It might be that the original file has been replaced,
60
- // so we need to keep the hash sums instead of the actual file paths
61
- // as caching keys
62
- const apksHash = await fs.hash(apks);
63
- log.debug(`Calculated '${apks}' hash: ${apksHash}`);
64
-
65
- if (APKS_CACHE.has(apksHash)) {
66
- const cachedRoot = APKS_CACHE.get(apksHash);
67
- if (cachedRoot) {
68
- const resultPath = path.resolve(cachedRoot, ...normalizedDstPath);
69
- if (await fs.exists(resultPath)) {
70
- return resultPath;
71
- }
72
- }
73
- APKS_CACHE.delete(apksHash);
74
- }
75
-
76
- const tmpRoot = await tempDir.openDir();
77
- log.debug(`Unpacking application bundle at '${apks}' to '${tmpRoot}'`);
78
- await unzipFile(apks, tmpRoot);
79
- const resultPath = path.resolve(tmpRoot, ...normalizedDstPath);
80
- if (!(await fs.exists(resultPath))) {
81
- throw new Error(
82
- `${normalizedDstPath.join(path.sep)} cannot be found in '${apks}' bundle. ` +
83
- `Does the archive contain a valid application bundle?`,
84
- );
85
- }
86
- APKS_CACHE.set(apksHash, tmpRoot);
87
- return resultPath;
88
- });
89
- }
90
-
91
42
  /**
92
43
  * Executes bundletool utility with given arguments and returns the actual stdout
93
44
  *
@@ -275,3 +226,52 @@ export async function extractLanguageApk(
275
226
  export function isTestPackageOnlyError(output: string): boolean {
276
227
  return /\[INSTALL_FAILED_TEST_ONLY\]/.test(output);
277
228
  }
229
+
230
+ /**
231
+ * Extracts the particular apks package into a temporary folder,
232
+ * finds and returns the full path to the file contained in this apk.
233
+ * The resulting temporary path, where the .apks file has been extracted,
234
+ * will be stored into the internal LRU cache for better performance.
235
+ *
236
+ * @param apks - The full path to the .apks file
237
+ * @param dstPath - The relative path to the destination file,
238
+ * which is going to be extracted, where each path component is an array item
239
+ * @returns Full path to the extracted file
240
+ * @throws {Error} If the requested item does not exist in the extracted archive or the provides
241
+ * apks file is not a valid bundle
242
+ */
243
+ async function extractFromApks(apks: string, dstPath: string | string[]): Promise<string> {
244
+ const normalizedDstPath = _.isArray(dstPath) ? dstPath : [dstPath];
245
+
246
+ return await APKS_CACHE_GUARD.acquire(apks, async () => {
247
+ // It might be that the original file has been replaced,
248
+ // so we need to keep the hash sums instead of the actual file paths
249
+ // as caching keys
250
+ const apksHash = await fs.hash(apks);
251
+ log.debug(`Calculated '${apks}' hash: ${apksHash}`);
252
+
253
+ if (APKS_CACHE.has(apksHash)) {
254
+ const cachedRoot = APKS_CACHE.get(apksHash);
255
+ if (cachedRoot) {
256
+ const resultPath = path.resolve(cachedRoot, ...normalizedDstPath);
257
+ if (await fs.exists(resultPath)) {
258
+ return resultPath;
259
+ }
260
+ }
261
+ APKS_CACHE.delete(apksHash);
262
+ }
263
+
264
+ const tmpRoot = await tempDir.openDir();
265
+ log.debug(`Unpacking application bundle at '${apks}' to '${tmpRoot}'`);
266
+ await unzipFile(apks, tmpRoot);
267
+ const resultPath = path.resolve(tmpRoot, ...normalizedDstPath);
268
+ if (!(await fs.exists(resultPath))) {
269
+ throw new Error(
270
+ `${normalizedDstPath.join(path.sep)} cannot be found in '${apks}' bundle. ` +
271
+ `Does the archive contain a valid application bundle?`,
272
+ );
273
+ }
274
+ APKS_CACHE.set(apksHash, tmpRoot);
275
+ return resultPath;
276
+ });
277
+ }
@@ -1,9 +1,9 @@
1
1
  import _ from 'lodash';
2
2
  import {fs, tempDir, util, system} from '@appium/support';
3
- import {log} from '../logger.js';
3
+ import {log} from '../logger';
4
4
  import {waitForCondition} from 'asyncbox';
5
5
  import path from 'node:path';
6
- import type {ADB} from '../adb.js';
6
+ import type {ADB} from '../adb';
7
7
  import type {ExecError} from 'teen_process';
8
8
  import type {
9
9
  StringRecord,
@@ -16,7 +16,7 @@ import type {
16
16
  PackageActivityInfo,
17
17
  ListInstalledPackagesOptions,
18
18
  ListInstalledPackagesResult,
19
- } from './types.js';
19
+ } from './types';
20
20
 
21
21
  // Constants
22
22
  export const APP_INSTALL_STATE: StringRecord<InstallState> = {
@@ -35,6 +35,18 @@ const LAUNCHER_CATEGORY = 'android.intent.category.LAUNCHER';
35
35
 
36
36
  // Public methods
37
37
 
38
+ export interface StartCmdOptions {
39
+ user?: number | string;
40
+ waitForLaunch?: boolean;
41
+ pkg?: string;
42
+ activity?: string;
43
+ action?: string;
44
+ category?: string;
45
+ stopApp?: boolean;
46
+ flags?: string;
47
+ optionalIntentArguments?: string;
48
+ }
49
+
38
50
  /**
39
51
  * Verify whether the given argument is a
40
52
  * valid class name.
@@ -1159,8 +1171,6 @@ export async function isAppRunning(this: ADB, pkg: string): Promise<boolean> {
1159
1171
  return !_.isEmpty(await this.listAppProcessIds(pkg));
1160
1172
  }
1161
1173
 
1162
- // Private methods
1163
-
1164
1174
  /**
1165
1175
  * Parses optional intent arguments from a string.
1166
1176
  *
@@ -1235,17 +1245,3 @@ function escapeShellArg(arg: string): string {
1235
1245
  }
1236
1246
  return arg.replace(/&/g, '\\&');
1237
1247
  }
1238
-
1239
- // Type definitions
1240
-
1241
- export interface StartCmdOptions {
1242
- user?: number | string;
1243
- waitForLaunch?: boolean;
1244
- pkg?: string;
1245
- activity?: string;
1246
- action?: string;
1247
- category?: string;
1248
- stopApp?: boolean;
1249
- flags?: string;
1250
- optionalIntentArguments?: string;
1251
- }
@@ -1,10 +1,10 @@
1
- import {log} from '../logger.js';
1
+ import {log} from '../logger';
2
2
  import _ from 'lodash';
3
3
  import {retryInterval} from 'asyncbox';
4
4
  import {util} from '@appium/support';
5
5
  import B from 'bluebird';
6
- import type {ADB} from '../adb.js';
7
- import type {SetPropOpts} from './types.js';
6
+ import type {ADB} from '../adb';
7
+ import type {SetPropOpts} from './types';
8
8
  import type {ExecError} from 'teen_process';
9
9
 
10
10
  const ANIMATION_SCALE_KEYS = [
@@ -288,19 +288,6 @@ export async function toggleGPSLocationProvider(this: ADB, enabled: boolean): Pr
288
288
  await this.shell(['cmd', 'location', 'set-location-enabled', enabled ? 'true' : 'false']);
289
289
  }
290
290
 
291
- /**
292
- * Decorates an exception message with a solution link
293
- *
294
- * @param e The error object to be decorated
295
- * @returns Either the same error or the decorated one
296
- */
297
- function decorateWriteSecureSettingsException(e: Error): Error {
298
- if (_.includes(e.message, 'requires:android.permission.WRITE_SECURE_SETTINGS')) {
299
- e.message = `Check https://github.com/appium/appium/issues/13802 for throubleshooting. ${e.message}`;
300
- }
301
- return e;
302
- }
303
-
304
291
  /**
305
292
  * Set hidden api policy to manage access to non-SDK APIs.
306
293
  * https://developer.android.com/preview/restrictions-non-sdk-interfaces
@@ -715,6 +702,19 @@ export async function getScreenOrientation(this: ADB): Promise<number | null> {
715
702
 
716
703
  // #region Private functions
717
704
 
705
+ /**
706
+ * Decorates an exception message with a solution link
707
+ *
708
+ * @param e The error object to be decorated
709
+ * @returns Either the same error or the decorated one
710
+ */
711
+ function decorateWriteSecureSettingsException(e: Error): Error {
712
+ if (_.includes(e.message, 'requires:android.permission.WRITE_SECURE_SETTINGS')) {
713
+ e.message = `Check https://github.com/appium/appium/issues/13802 for throubleshooting. ${e.message}`;
714
+ }
715
+ return e;
716
+ }
717
+
718
718
  /**
719
719
  * Reads SurfaceOrientation in dumpsys output
720
720
  *
@@ -1,11 +1,11 @@
1
- import {log} from '../logger.js';
1
+ import {log} from '../logger';
2
2
  import _ from 'lodash';
3
3
  import net from 'node:net';
4
4
  import {util, fs} from '@appium/support';
5
5
  import B from 'bluebird';
6
6
  import path from 'node:path';
7
7
  import * as ini from 'ini';
8
- import type {ADB} from '../adb.js';
8
+ import type {ADB} from '../adb';
9
9
  import type {
10
10
  EmuInfo,
11
11
  EmuVersionInfo,
@@ -17,57 +17,7 @@ import type {
17
17
  GsmVoiceStates,
18
18
  NetworkSpeed,
19
19
  ExecTelnetOptions,
20
- } from './types.js';
21
-
22
- /**
23
- * Retrieves the list of available Android emulators
24
- *
25
- * @returns
26
- */
27
- async function listEmulators(): Promise<EmuInfo[]> {
28
- let avdsRoot = process.env.ANDROID_AVD_HOME;
29
- if (await dirExists(avdsRoot ?? '')) {
30
- return await getAvdConfigPaths(avdsRoot as string);
31
- }
32
-
33
- if (avdsRoot) {
34
- log.warn(
35
- `The value of the ANDROID_AVD_HOME environment variable '${avdsRoot}' is not an existing directory`,
36
- );
37
- }
38
-
39
- const prefsRoot = await getAndroidPrefsRoot();
40
- if (!prefsRoot) {
41
- return [];
42
- }
43
-
44
- avdsRoot = path.resolve(prefsRoot, 'avd');
45
- if (!(await dirExists(avdsRoot))) {
46
- log.debug(`Virtual devices config root '${avdsRoot}' is not an existing directory`);
47
- return [];
48
- }
49
-
50
- return await getAvdConfigPaths(avdsRoot);
51
- }
52
-
53
- /**
54
- * Get configuration paths of all virtual devices
55
- *
56
- * @param avdsRoot Path to the directory that contains the AVD .ini files
57
- * @returns
58
- */
59
- async function getAvdConfigPaths(avdsRoot: string): Promise<EmuInfo[]> {
60
- const configs = await fs.glob('*.ini', {
61
- cwd: avdsRoot,
62
- absolute: true,
63
- });
64
- return configs
65
- .map((confPath) => {
66
- const avdName = path.basename(confPath).split('.').slice(0, -1).join('.');
67
- return {name: avdName, config: confPath};
68
- })
69
- .filter(({name}) => _.trim(name));
70
- }
20
+ } from './types';
71
21
 
72
22
  /**
73
23
  * Check the emulator state.
@@ -480,6 +430,56 @@ export async function sendTelnetCommand(this: ADB, command: string): Promise<str
480
430
 
481
431
  // #region Private functions
482
432
 
433
+ /**
434
+ * Retrieves the list of available Android emulators
435
+ *
436
+ * @returns
437
+ */
438
+ async function listEmulators(): Promise<EmuInfo[]> {
439
+ let avdsRoot = process.env.ANDROID_AVD_HOME;
440
+ if (await dirExists(avdsRoot ?? '')) {
441
+ return await getAvdConfigPaths(avdsRoot as string);
442
+ }
443
+
444
+ if (avdsRoot) {
445
+ log.warn(
446
+ `The value of the ANDROID_AVD_HOME environment variable '${avdsRoot}' is not an existing directory`,
447
+ );
448
+ }
449
+
450
+ const prefsRoot = await getAndroidPrefsRoot();
451
+ if (!prefsRoot) {
452
+ return [];
453
+ }
454
+
455
+ avdsRoot = path.resolve(prefsRoot, 'avd');
456
+ if (!(await dirExists(avdsRoot))) {
457
+ log.debug(`Virtual devices config root '${avdsRoot}' is not an existing directory`);
458
+ return [];
459
+ }
460
+
461
+ return await getAvdConfigPaths(avdsRoot);
462
+ }
463
+
464
+ /**
465
+ * Get configuration paths of all virtual devices
466
+ *
467
+ * @param avdsRoot Path to the directory that contains the AVD .ini files
468
+ * @returns
469
+ */
470
+ async function getAvdConfigPaths(avdsRoot: string): Promise<EmuInfo[]> {
471
+ const configs = await fs.glob('*.ini', {
472
+ cwd: avdsRoot,
473
+ absolute: true,
474
+ });
475
+ return configs
476
+ .map((confPath) => {
477
+ const avdName = path.basename(confPath).split('.').slice(0, -1).join('.');
478
+ return {name: avdName, config: confPath};
479
+ })
480
+ .filter(({name}) => _.trim(name));
481
+ }
482
+
483
483
  /**
484
484
  * Retrieves the full path to the Android preferences root
485
485
  *
@@ -1,12 +1,8 @@
1
1
  import _ from 'lodash';
2
2
  import path from 'node:path';
3
- import type {ADB} from '../adb.js';
3
+ import type {ADB} from '../adb';
4
4
  import type {TeenProcessExecOptions} from 'teen_process';
5
5
 
6
- function shellEscapeSingleQuotes(str: string): string {
7
- return str.replace(/'/g, "'\\''");
8
- }
9
-
10
6
  /**
11
7
  * Verify whether a remote path exists on the device under test.
12
8
  *
@@ -132,3 +128,7 @@ export async function pull(
132
128
  export async function mkdir(this: ADB, remotePath: string): Promise<string> {
133
129
  return await this.shell([`mkdir -p -- '${shellEscapeSingleQuotes(remotePath)}'`]);
134
130
  }
131
+
132
+ function shellEscapeSingleQuotes(str: string): string {
133
+ return str.replace(/'/g, "'\\''");
134
+ }
@@ -1,9 +1,9 @@
1
- import {log} from '../logger.js';
1
+ import {log} from '../logger';
2
2
  import _ from 'lodash';
3
3
  import {fs, util} from '@appium/support';
4
4
  import {SubProcess, exec, type ExecError} from 'teen_process';
5
- import type {ADB} from '../adb.js';
6
- import type {ScreenrecordOptions, StringRecord} from './types.js';
5
+ import type {ADB} from '../adb';
6
+ import type {ScreenrecordOptions, StringRecord} from './types';
7
7
 
8
8
  /**
9
9
  * Get the path to adb executable amd assign it
@@ -1,8 +1,8 @@
1
- import {log} from '../logger.js';
1
+ import {log} from '../logger';
2
2
  import {waitForCondition} from 'asyncbox';
3
3
  import B from 'bluebird';
4
- import type {ADB} from '../adb.js';
5
- import type {KeyboardState} from './types.js';
4
+ import type {ADB} from '../adb';
5
+ import type {KeyboardState} from './types';
6
6
 
7
7
  const KEYCODE_ESC = 111;
8
8
  const KEYCODE_BACK = 4;
@@ -1,8 +1,8 @@
1
- import {log} from '../logger.js';
1
+ import {log} from '../logger';
2
2
  import _ from 'lodash';
3
3
  import B from 'bluebird';
4
4
  import {waitForCondition} from 'asyncbox';
5
- import type {ADB} from '../adb.js';
5
+ import type {ADB} from '../adb';
6
6
 
7
7
  const CREDENTIAL_CANNOT_BE_NULL_OR_EMPTY_ERROR = `Credential can't be null or empty`;
8
8
  const CREDENTIAL_DID_NOT_MATCH_ERROR = `didn't match`;
@@ -11,51 +11,6 @@ const KEYCODE_POWER = 26;
11
11
  const KEYCODE_WAKEUP = 224; // works over API Level 20
12
12
  const HIDE_KEYBOARD_WAIT_TIME = 100;
13
13
 
14
- /**
15
- * @param verb
16
- * @param oldCredential
17
- * @param args
18
- */
19
- function buildCommand(
20
- verb: string,
21
- oldCredential: string | null = null,
22
- ...args: string[]
23
- ): string[] {
24
- const cmd = ['locksettings', verb];
25
- if (oldCredential && !_.isEmpty(oldCredential)) {
26
- cmd.push('--old', oldCredential);
27
- }
28
- if (!_.isEmpty(args)) {
29
- cmd.push(...args);
30
- }
31
- return cmd;
32
- }
33
-
34
- /**
35
- * Performs swipe up gesture on the screen
36
- *
37
- * @param windowDumpsys The output of `adb shell dumpsys window` command
38
- * @throws {Error} If the display size cannot be retrieved
39
- */
40
- async function swipeUp(this: ADB, windowDumpsys: string): Promise<void> {
41
- const dimensionsMatch = /init=(\d+)x(\d+)/.exec(windowDumpsys);
42
- if (!dimensionsMatch) {
43
- throw new Error('Cannot retrieve the display size');
44
- }
45
- const displayWidth = parseInt(dimensionsMatch[1], 10);
46
- const displayHeight = parseInt(dimensionsMatch[2], 10);
47
- const x0 = displayWidth / 2;
48
- const y0 = (displayHeight / 5) * 4;
49
- const x1 = x0;
50
- const y1 = displayHeight / 5;
51
- await this.shell([
52
- 'input',
53
- 'touchscreen',
54
- 'swipe',
55
- ...[x0, y0, x1, y1].map((c) => `${Math.trunc(c)}`),
56
- ]);
57
- }
58
-
59
14
  /**
60
15
  * Check whether the device supports lock settings management with `locksettings`
61
16
  * command line tool. This tool has been added to Android toolset since API 27 Oreo
@@ -323,8 +278,90 @@ export async function lock(this: ADB): Promise<void> {
323
278
  }
324
279
  }
325
280
 
281
+ /**
282
+ * Checks mShowingLockscreen or mDreamingLockscreen in dumpsys output to determine
283
+ * if lock screen is showing
284
+ *
285
+ * A note: `adb shell dumpsys trust` performs better while detecting the locked screen state
286
+ * in comparison to `adb dumpsys window` output parsing.
287
+ * But the trust command does not work for `Swipe` unlock pattern.
288
+ *
289
+ * In some Android devices (Probably around Android 10+), `mShowingLockscreen` and `mDreamingLockscreen`
290
+ * do not work to detect lock status. Instead, keyguard preferences helps to detect the lock condition.
291
+ * Some devices such as Android TV do not have keyguard, so we should keep
292
+ * screen condition as this primary method.
293
+ *
294
+ * @param dumpsys - The output of dumpsys window command.
295
+ * @return True if lock screen is showing.
296
+ */
297
+ export function isShowingLockscreen(dumpsys: string): boolean {
298
+ return (
299
+ _.some(['mShowingLockscreen=true', 'mDreamingLockscreen=true'], (x) => dumpsys.includes(x)) ||
300
+ // `mIsShowing` and `mInputRestricted` are `true` in lock condition. `false` is unlock condition.
301
+ _.every([/KeyguardStateMonitor[\n\s]+mIsShowing=true/, /\s+mInputRestricted=true/], (x) =>
302
+ x.test(dumpsys),
303
+ )
304
+ );
305
+ }
306
+
307
+ /**
308
+ * Checks screenState has SCREEN_STATE_OFF in dumpsys output to determine
309
+ * possible lock screen.
310
+ *
311
+ * @param dumpsys - The output of dumpsys window command.
312
+ * @return True if lock screen is showing.
313
+ */
314
+ export function isScreenStateOff(dumpsys: string): boolean {
315
+ return /\s+screenState=SCREEN_STATE_OFF/i.test(dumpsys);
316
+ }
317
+
326
318
  // #region Private functions
327
319
 
320
+ /**
321
+ * @param verb
322
+ * @param oldCredential
323
+ * @param args
324
+ */
325
+ function buildCommand(
326
+ verb: string,
327
+ oldCredential: string | null = null,
328
+ ...args: string[]
329
+ ): string[] {
330
+ const cmd = ['locksettings', verb];
331
+ if (oldCredential && !_.isEmpty(oldCredential)) {
332
+ cmd.push('--old', oldCredential);
333
+ }
334
+ if (!_.isEmpty(args)) {
335
+ cmd.push(...args);
336
+ }
337
+ return cmd;
338
+ }
339
+
340
+ /**
341
+ * Performs swipe up gesture on the screen
342
+ *
343
+ * @param windowDumpsys The output of `adb shell dumpsys window` command
344
+ * @throws {Error} If the display size cannot be retrieved
345
+ */
346
+ async function swipeUp(this: ADB, windowDumpsys: string): Promise<void> {
347
+ const dimensionsMatch = /init=(\d+)x(\d+)/.exec(windowDumpsys);
348
+ if (!dimensionsMatch) {
349
+ throw new Error('Cannot retrieve the display size');
350
+ }
351
+ const displayWidth = parseInt(dimensionsMatch[1], 10);
352
+ const displayHeight = parseInt(dimensionsMatch[2], 10);
353
+ const x0 = displayWidth / 2;
354
+ const y0 = (displayHeight / 5) * 4;
355
+ const x1 = x0;
356
+ const y1 = displayHeight / 5;
357
+ await this.shell([
358
+ 'input',
359
+ 'touchscreen',
360
+ 'swipe',
361
+ ...[x0, y0, x1, y1].map((c) => `${Math.trunc(c)}`),
362
+ ]);
363
+ }
364
+
328
365
  /**
329
366
  * Checks mScreenOnFully in dumpsys output to determine if screen is showing
330
367
  * Default is true.
@@ -365,41 +402,4 @@ function isInDozingMode(dumpsys: string): boolean {
365
402
  return /^[\s\w]+wakefulness[^=]*=Dozing$/im.test(dumpsys);
366
403
  }
367
404
 
368
- /**
369
- * Checks mShowingLockscreen or mDreamingLockscreen in dumpsys output to determine
370
- * if lock screen is showing
371
- *
372
- * A note: `adb shell dumpsys trust` performs better while detecting the locked screen state
373
- * in comparison to `adb dumpsys window` output parsing.
374
- * But the trust command does not work for `Swipe` unlock pattern.
375
- *
376
- * In some Android devices (Probably around Android 10+), `mShowingLockscreen` and `mDreamingLockscreen`
377
- * do not work to detect lock status. Instead, keyguard preferences helps to detect the lock condition.
378
- * Some devices such as Android TV do not have keyguard, so we should keep
379
- * screen condition as this primary method.
380
- *
381
- * @param dumpsys - The output of dumpsys window command.
382
- * @return True if lock screen is showing.
383
- */
384
- export function isShowingLockscreen(dumpsys: string): boolean {
385
- return (
386
- _.some(['mShowingLockscreen=true', 'mDreamingLockscreen=true'], (x) => dumpsys.includes(x)) ||
387
- // `mIsShowing` and `mInputRestricted` are `true` in lock condition. `false` is unlock condition.
388
- _.every([/KeyguardStateMonitor[\n\s]+mIsShowing=true/, /\s+mInputRestricted=true/], (x) =>
389
- x.test(dumpsys),
390
- )
391
- );
392
- }
393
-
394
- /**
395
- * Checks screenState has SCREEN_STATE_OFF in dumpsys output to determine
396
- * possible lock screen.
397
- *
398
- * @param dumpsys - The output of dumpsys window command.
399
- * @return True if lock screen is showing.
400
- */
401
- export function isScreenStateOff(dumpsys: string): boolean {
402
- return /\s+screenState=SCREEN_STATE_OFF/i.test(dumpsys);
403
- }
404
-
405
405
  // #endregion
@@ -1,7 +1,7 @@
1
1
  import _ from 'lodash';
2
2
  import {Logcat} from '../logcat';
3
- import type {ADB} from '../adb.js';
4
- import type {LogcatOpts, LogEntry, LogcatListener} from './types.js';
3
+ import type {ADB} from '../adb';
4
+ import type {LogcatOpts, LogEntry, LogcatListener} from './types';
5
5
 
6
6
  /**
7
7
  * Start the logcat process to gather logs.
@@ -1,8 +1,8 @@
1
1
  import {EOL} from 'node:os';
2
2
  import _ from 'lodash';
3
- import {log} from '../logger.js';
4
- import type {ADB} from '../adb.js';
5
- import type {PortFamily, PortInfo} from './types.js';
3
+ import {log} from '../logger';
4
+ import type {ADB} from '../adb';
5
+ import type {PortFamily, PortInfo} from './types';
6
6
 
7
7
  /**
8
8
  * Get TCP port forwarding with adb on the device under test.
@@ -1,8 +1,8 @@
1
1
  import _ from 'lodash';
2
- import {log} from '../logger.js';
2
+ import {log} from '../logger';
3
3
  import B from 'bluebird';
4
4
  import type {ExecError} from 'teen_process';
5
- import type {ADB} from '../adb.js';
5
+ import type {ADB} from '../adb';
6
6
 
7
7
  const PID_COLUMN_TITLE: string = 'PID';
8
8
  const PROCESS_NAME_COLUMN_TITLE: string = 'NAME';