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.
- package/CHANGELOG.md +6 -0
- package/build/lib/adb.d.ts +11 -11
- package/build/lib/adb.d.ts.map +1 -1
- package/build/lib/adb.js +9 -9
- package/build/lib/adb.js.map +1 -1
- package/build/lib/logcat.d.ts +1 -1
- package/build/lib/logcat.d.ts.map +1 -1
- package/build/lib/logcat.js +4 -14
- package/build/lib/logcat.js.map +1 -1
- package/build/lib/tools/aab-utils.d.ts.map +1 -1
- package/build/lib/tools/aab-utils.js +4 -4
- package/build/lib/tools/aab-utils.js.map +1 -1
- package/build/lib/tools/android-manifest.d.ts.map +1 -1
- package/build/lib/tools/android-manifest.js +4 -7
- package/build/lib/tools/android-manifest.js.map +1 -1
- package/build/lib/tools/apk-signing.d.ts.map +1 -1
- package/build/lib/tools/apk-signing.js +9 -11
- package/build/lib/tools/apk-signing.js.map +1 -1
- package/build/lib/tools/apk-utils.d.ts.map +1 -1
- package/build/lib/tools/apk-utils.js +19 -38
- package/build/lib/tools/apk-utils.js.map +1 -1
- package/build/lib/tools/apks-utils.d.ts.map +1 -1
- package/build/lib/tools/apks-utils.js +3 -3
- package/build/lib/tools/apks-utils.js.map +1 -1
- package/build/lib/tools/app-commands.d.ts.map +1 -1
- package/build/lib/tools/app-commands.js +11 -15
- package/build/lib/tools/app-commands.js.map +1 -1
- package/build/lib/tools/device-settings.d.ts.map +1 -1
- package/build/lib/tools/device-settings.js +6 -17
- package/build/lib/tools/device-settings.js.map +1 -1
- package/build/lib/tools/emulator-commands.d.ts.map +1 -1
- package/build/lib/tools/emulator-commands.js +6 -8
- package/build/lib/tools/emulator-commands.js.map +1 -1
- package/build/lib/tools/fs-commands.d.ts +1 -1
- package/build/lib/tools/fs-commands.d.ts.map +1 -1
- package/build/lib/tools/fs-commands.js.map +1 -1
- package/build/lib/tools/general-commands.d.ts.map +1 -1
- package/build/lib/tools/general-commands.js +3 -5
- package/build/lib/tools/general-commands.js.map +1 -1
- package/build/lib/tools/keyboard-commands.d.ts.map +1 -1
- package/build/lib/tools/keyboard-commands.js +1 -1
- package/build/lib/tools/keyboard-commands.js.map +1 -1
- package/build/lib/tools/lockmgmt.d.ts.map +1 -1
- package/build/lib/tools/lockmgmt.js +4 -10
- package/build/lib/tools/lockmgmt.js.map +1 -1
- package/build/lib/tools/logcat-commands.d.ts.map +1 -1
- package/build/lib/tools/logcat-commands.js.map +1 -1
- package/build/lib/tools/network-commands.d.ts.map +1 -1
- package/build/lib/tools/network-commands.js.map +1 -1
- package/build/lib/tools/process-commands.d.ts.map +1 -1
- package/build/lib/tools/process-commands.js +1 -1
- package/build/lib/tools/process-commands.js.map +1 -1
- package/build/lib/tools/system-calls.d.ts.map +1 -1
- package/build/lib/tools/system-calls.js +15 -11
- package/build/lib/tools/system-calls.js.map +1 -1
- package/build/lib/tools/types.d.ts.map +1 -1
- package/build/lib/utils/helpers/index.d.ts +1 -1
- package/build/lib/utils/helpers/index.d.ts.map +1 -1
- package/build/lib/utils/helpers/index.js +1 -1
- package/build/lib/utils/helpers/index.js.map +1 -1
- package/build/lib/utils/helpers/install.d.ts.map +1 -1
- package/build/lib/utils/helpers/install.js.map +1 -1
- package/build/lib/utils/helpers/manifest.d.ts.map +1 -1
- package/build/lib/utils/helpers/manifest.js.map +1 -1
- package/build/lib/utils/helpers/resource.d.ts.map +1 -1
- package/build/lib/utils/helpers/resource.js +1 -2
- package/build/lib/utils/helpers/resource.js.map +1 -1
- package/build/lib/utils/helpers/sdk.d.ts.map +1 -1
- package/build/lib/utils/helpers/sdk.js +1 -1
- package/build/lib/utils/helpers/sdk.js.map +1 -1
- package/build/lib/utils/index.d.ts +1 -1
- package/build/lib/utils/index.d.ts.map +1 -1
- package/build/lib/utils/index.js +1 -1
- package/build/lib/utils/index.js.map +1 -1
- package/build/lib/utils/lodash/core.d.ts.map +1 -1
- package/build/lib/utils/lodash/core.js.map +1 -1
- package/lib/adb.ts +14 -13
- package/lib/logcat.ts +9 -23
- package/lib/tools/aab-utils.ts +9 -15
- package/lib/tools/android-manifest.ts +12 -28
- package/lib/tools/apk-signing.ts +16 -41
- package/lib/tools/apk-utils.ts +27 -82
- package/lib/tools/apks-utils.ts +10 -21
- package/lib/tools/app-commands.ts +31 -95
- package/lib/tools/device-settings.ts +15 -48
- package/lib/tools/emulator-commands.ts +13 -38
- package/lib/tools/fs-commands.ts +3 -1
- package/lib/tools/general-commands.ts +6 -13
- package/lib/tools/keyboard-commands.ts +2 -1
- package/lib/tools/lockmgmt.ts +12 -42
- package/lib/tools/logcat-commands.ts +1 -1
- package/lib/tools/network-commands.ts +4 -11
- package/lib/tools/process-commands.ts +4 -11
- package/lib/tools/system-calls.ts +59 -137
- package/lib/tools/types.ts +4 -8
- package/lib/utils/helpers/index.ts +1 -6
- package/lib/utils/helpers/install.ts +2 -4
- package/lib/utils/helpers/manifest.ts +4 -11
- package/lib/utils/helpers/resource.ts +5 -9
- package/lib/utils/helpers/sdk.ts +5 -9
- package/lib/utils/index.ts +2 -1
- package/lib/utils/lodash/core.ts +3 -9
- package/package.json +36 -46
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
1
3
|
import {fs, tempDir, util, system} from '@appium/support';
|
|
2
|
-
import {log} from '../logger.js';
|
|
3
4
|
import {waitForCondition} from 'asyncbox';
|
|
4
|
-
import path from 'node:path';
|
|
5
|
-
import type {ADB} from '../adb.js';
|
|
6
5
|
import type {ExecError} from 'teen_process';
|
|
6
|
+
|
|
7
|
+
import type {ADB} from '../adb.js';
|
|
8
|
+
import {log} from '../logger.js';
|
|
7
9
|
import {defaults, intersectionWith} from '../utils/index.js';
|
|
8
10
|
import type {
|
|
9
11
|
StringRecord,
|
|
@@ -82,9 +84,7 @@ export async function resolveLaunchableActivity(
|
|
|
82
84
|
const names = parseLaunchableActivityNames(stdout);
|
|
83
85
|
if (util.isEmpty(names)) {
|
|
84
86
|
log.debug(stdout);
|
|
85
|
-
throw new Error(
|
|
86
|
-
`Unable to resolve the launchable activity of '${pkg}'. Is it installed on the device?`,
|
|
87
|
-
);
|
|
87
|
+
throw new Error(`Unable to resolve the launchable activity of '${pkg}'. Is it installed on the device?`);
|
|
88
88
|
}
|
|
89
89
|
if (names.length === 1) {
|
|
90
90
|
return names[0];
|
|
@@ -108,20 +108,15 @@ export async function resolveLaunchableActivity(
|
|
|
108
108
|
await fs.rimraf(tmpRoot);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
const {stdout, stderr} = await this.shell(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
outputFormat: this.EXEC_OUTPUT_FORMAT.FULL,
|
|
115
|
-
},
|
|
116
|
-
);
|
|
111
|
+
const {stdout, stderr} = await this.shell(['cmd', 'package', 'resolve-activity', '--brief', pkg], {
|
|
112
|
+
outputFormat: this.EXEC_OUTPUT_FORMAT.FULL,
|
|
113
|
+
});
|
|
117
114
|
for (const line of (stdout || '').split('\n').map((x) => x.trim())) {
|
|
118
115
|
if (this.isValidClass(line)) {
|
|
119
116
|
return line;
|
|
120
117
|
}
|
|
121
118
|
}
|
|
122
|
-
throw new Error(
|
|
123
|
-
`Unable to resolve the launchable activity of '${pkg}'. Original error: ${stderr || stdout}`,
|
|
124
|
-
);
|
|
119
|
+
throw new Error(`Unable to resolve the launchable activity of '${pkg}'. Original error: ${stderr || stdout}`);
|
|
125
120
|
}
|
|
126
121
|
|
|
127
122
|
/**
|
|
@@ -193,10 +188,7 @@ export async function grantAllPermissions(this: ADB, pkg: string, apk?: string):
|
|
|
193
188
|
//avoiding logging error stack, as calling library function would have logged
|
|
194
189
|
log.warn(`Ran into problem getting target SDK version; ignoring...`);
|
|
195
190
|
}
|
|
196
|
-
if (
|
|
197
|
-
apiLevel >= MIN_API_LEVEL_WITH_PERMS_SUPPORT &&
|
|
198
|
-
targetSdk >= MIN_API_LEVEL_WITH_PERMS_SUPPORT
|
|
199
|
-
) {
|
|
191
|
+
if (apiLevel >= MIN_API_LEVEL_WITH_PERMS_SUPPORT && targetSdk >= MIN_API_LEVEL_WITH_PERMS_SUPPORT) {
|
|
200
192
|
/**
|
|
201
193
|
* If the device is running Android 6.0(API 23) or higher, and your app's target SDK is 23 or higher:
|
|
202
194
|
* The app has to list the permissions in the manifest.
|
|
@@ -234,11 +226,7 @@ export async function grantAllPermissions(this: ADB, pkg: string, apk?: string):
|
|
|
234
226
|
* @param permissions - The list of permissions to be granted.
|
|
235
227
|
* @throws {Error} If there was an error while changing permissions.
|
|
236
228
|
*/
|
|
237
|
-
export async function grantPermissions(
|
|
238
|
-
this: ADB,
|
|
239
|
-
pkg: string,
|
|
240
|
-
permissions: string[],
|
|
241
|
-
): Promise<void> {
|
|
229
|
+
export async function grantPermissions(this: ADB, pkg: string, permissions: string[]): Promise<void> {
|
|
242
230
|
// As it consumes more time for granting each permission,
|
|
243
231
|
// trying to grant all permission by forming equivalent command.
|
|
244
232
|
// Also, it is necessary to split long commands into chunks, since the maximum length of
|
|
@@ -317,11 +305,7 @@ export async function getGrantedPermissions(
|
|
|
317
305
|
* _dumpsys package_ command. It may speed up the method execution.
|
|
318
306
|
* @returns The list of denied permissions or an empty list.
|
|
319
307
|
*/
|
|
320
|
-
export async function getDeniedPermissions(
|
|
321
|
-
this: ADB,
|
|
322
|
-
pkg: string,
|
|
323
|
-
cmdOutput: string | null = null,
|
|
324
|
-
): Promise<string[]> {
|
|
308
|
+
export async function getDeniedPermissions(this: ADB, pkg: string, cmdOutput: string | null = null): Promise<string[]> {
|
|
325
309
|
log.debug('Retrieving denied permissions');
|
|
326
310
|
const stdout = cmdOutput || (await this.shell(['dumpsys', 'package', pkg]));
|
|
327
311
|
return extractMatchingPermissions(stdout, ['install', 'runtime'], false);
|
|
@@ -335,11 +319,7 @@ export async function getDeniedPermissions(
|
|
|
335
319
|
* _dumpsys package_ command. It may speed up the method execution.
|
|
336
320
|
* @returns The list of requested permissions or an empty list.
|
|
337
321
|
*/
|
|
338
|
-
export async function getReqPermissions(
|
|
339
|
-
this: ADB,
|
|
340
|
-
pkg: string,
|
|
341
|
-
cmdOutput: string | null = null,
|
|
342
|
-
): Promise<string[]> {
|
|
322
|
+
export async function getReqPermissions(this: ADB, pkg: string, cmdOutput: string | null = null): Promise<string[]> {
|
|
343
323
|
log.debug('Retrieving requested permissions');
|
|
344
324
|
const stdout = cmdOutput || (await this.shell(['dumpsys', 'package', pkg]));
|
|
345
325
|
return extractMatchingPermissions(stdout, ['requested']);
|
|
@@ -379,10 +359,7 @@ export async function getPackageInfo(this: ADB, pkg: string): Promise<AppInfo> {
|
|
|
379
359
|
return result;
|
|
380
360
|
}
|
|
381
361
|
|
|
382
|
-
const installedPattern = new RegExp(
|
|
383
|
-
`^\\s*Package\\s+\\[${util.escapeRegExp(pkg)}\\][^:]+:$`,
|
|
384
|
-
'm',
|
|
385
|
-
);
|
|
362
|
+
const installedPattern = new RegExp(`^\\s*Package\\s+\\[${util.escapeRegExp(pkg)}\\][^:]+:$`, 'm');
|
|
386
363
|
result.isInstalled = installedPattern.test(stdout);
|
|
387
364
|
if (!result.isInstalled) {
|
|
388
365
|
return result;
|
|
@@ -489,11 +466,7 @@ export async function activateApp(this: ADB, appId: string): Promise<void> {
|
|
|
489
466
|
* @param opts - Options for checking installation
|
|
490
467
|
* @returns True if the package is installed.
|
|
491
468
|
*/
|
|
492
|
-
export async function isAppInstalled(
|
|
493
|
-
this: ADB,
|
|
494
|
-
pkg: string,
|
|
495
|
-
opts: IsAppInstalledOptions = {},
|
|
496
|
-
): Promise<boolean> {
|
|
469
|
+
export async function isAppInstalled(this: ADB, pkg: string, opts: IsAppInstalledOptions = {}): Promise<boolean> {
|
|
497
470
|
const {user} = opts;
|
|
498
471
|
|
|
499
472
|
log.debug(`Getting install status for ${pkg}`);
|
|
@@ -549,10 +522,7 @@ export async function listInstalledPackages(
|
|
|
549
522
|
} catch (e) {
|
|
550
523
|
const error = e as ExecError;
|
|
551
524
|
// https://github.com/appium/appium-uiautomator2-driver/issues/810
|
|
552
|
-
if (
|
|
553
|
-
(error.stderr || error.stdout || error.message)?.includes('access user') &&
|
|
554
|
-
util.isEmpty(user)
|
|
555
|
-
) {
|
|
525
|
+
if ((error.stderr || error.stdout || error.message)?.includes('access user') && util.isEmpty(user)) {
|
|
556
526
|
stdout = await this.shell([...cmd, '--user', '0']);
|
|
557
527
|
} else {
|
|
558
528
|
throw e;
|
|
@@ -636,24 +606,17 @@ export async function startApp(this: ADB, startAppOptions: StartAppOptions): Pro
|
|
|
636
606
|
|
|
637
607
|
const apiLevel = await this.getApiLevel();
|
|
638
608
|
const cmd = buildStartCmd(options, apiLevel);
|
|
639
|
-
const intentName = `${options.action}${
|
|
640
|
-
options.optionalIntentArguments ? ' ' + options.optionalIntentArguments : ''
|
|
641
|
-
}`;
|
|
609
|
+
const intentName = `${options.action}${options.optionalIntentArguments ? ' ' + options.optionalIntentArguments : ''}`;
|
|
642
610
|
try {
|
|
643
611
|
const shellOpts: {timeout?: number} = {};
|
|
644
|
-
if (
|
|
645
|
-
options.waitDuration !== undefined &&
|
|
646
|
-
Number.isInteger(options.waitDuration) &&
|
|
647
|
-
options.waitDuration >= 0
|
|
648
|
-
) {
|
|
612
|
+
if (options.waitDuration !== undefined && Number.isInteger(options.waitDuration) && options.waitDuration >= 0) {
|
|
649
613
|
shellOpts.timeout = options.waitDuration;
|
|
650
614
|
}
|
|
651
615
|
const stdout = await this.shell(cmd, shellOpts);
|
|
652
616
|
if (stdout.includes('Error: Activity class') && stdout.includes('does not exist')) {
|
|
653
617
|
if (options.retry && options.activity && !options.activity.startsWith('.')) {
|
|
654
618
|
log.debug(
|
|
655
|
-
`We tried to start an activity that doesn't exist,
|
|
656
|
-
`retrying with '.${options.activity}' activity name`,
|
|
619
|
+
`We tried to start an activity that doesn't exist, retrying with '.${options.activity}' activity name`,
|
|
657
620
|
);
|
|
658
621
|
options.activity = `.${options.activity}`;
|
|
659
622
|
options.retry = false;
|
|
@@ -722,10 +685,9 @@ export async function getFocusedPackageAndActivity(this: ADB): Promise<PackageAc
|
|
|
722
685
|
stdout = await this.dumpWindows();
|
|
723
686
|
} catch (e) {
|
|
724
687
|
const error = e as Error;
|
|
725
|
-
throw new Error(
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
);
|
|
688
|
+
throw new Error(`Could not retrieve the currently focused package and activity. Original error: ${error.message}`, {
|
|
689
|
+
cause: e,
|
|
690
|
+
});
|
|
729
691
|
}
|
|
730
692
|
|
|
731
693
|
const nullFocusedAppRe = /^\s*mFocusedApp=null/m;
|
|
@@ -735,10 +697,7 @@ export async function getFocusedPackageAndActivity(this: ADB): Promise<PackageAc
|
|
|
735
697
|
'mg',
|
|
736
698
|
);
|
|
737
699
|
const nullCurrentFocusRe = /^\s*mCurrentFocus=null/m;
|
|
738
|
-
const currentFocusAppRe = new RegExp(
|
|
739
|
-
'^\\s*mCurrentFocus.+\\{.+\\s([^\\s\\/]+)\\/([^\\s]+)\\b',
|
|
740
|
-
'mg',
|
|
741
|
-
);
|
|
700
|
+
const currentFocusAppRe = new RegExp('^\\s*mCurrentFocus.+\\{.+\\s([^\\s\\/]+)\\/([^\\s]+)\\b', 'mg');
|
|
742
701
|
|
|
743
702
|
const focusedAppCandidates: PackageActivityInfo[] = [];
|
|
744
703
|
const currentFocusAppCandidates: PackageActivityInfo[] = [];
|
|
@@ -848,8 +807,7 @@ export async function waitForActivityOrNot(
|
|
|
848
807
|
);
|
|
849
808
|
const possibleActivityNames = [...possibleActivityNamesSet];
|
|
850
809
|
const possibleActivityPatterns = possibleActivityNames.map(
|
|
851
|
-
(actName) =>
|
|
852
|
-
new RegExp(`^${actName.replace(/\./g, '\\.').replace(/\*/g, '.*?').replace(/\$/g, '\\$')}$`),
|
|
810
|
+
(actName) => new RegExp(`^${actName.replace(/\./g, '\\.').replace(/\*/g, '.*?').replace(/\$/g, '\\$')}$`),
|
|
853
811
|
);
|
|
854
812
|
log.debug(
|
|
855
813
|
`Expected activity name patterns to ${waitForStop ? 'not ' : ''}be focused within ${waitMs}ms: ` +
|
|
@@ -874,15 +832,12 @@ export async function waitForActivityOrNot(
|
|
|
874
832
|
);
|
|
875
833
|
log.debug(`Focused fully qualified activity name: ${fullyQualifiedActivity}`);
|
|
876
834
|
const isFound =
|
|
877
|
-
allPackages.includes(appPackage) &&
|
|
878
|
-
possibleActivityPatterns.some((p) => p.test(fullyQualifiedActivity));
|
|
835
|
+
allPackages.includes(appPackage) && possibleActivityPatterns.some((p) => p.test(fullyQualifiedActivity));
|
|
879
836
|
if ((!waitForStop && isFound) || (waitForStop && !isFound)) {
|
|
880
837
|
return true;
|
|
881
838
|
}
|
|
882
839
|
}
|
|
883
|
-
log.debug(
|
|
884
|
-
'None of the expected package/activity combinations matched to the currently focused one. Retrying',
|
|
885
|
-
);
|
|
840
|
+
log.debug('None of the expected package/activity combinations matched to the currently focused one. Retrying');
|
|
886
841
|
return false;
|
|
887
842
|
};
|
|
888
843
|
|
|
@@ -909,12 +864,7 @@ export async function waitForActivityOrNot(
|
|
|
909
864
|
* @param waitMs - Number of milliseconds to wait before timeout occurs.
|
|
910
865
|
* @throws {Error} If timeout happens.
|
|
911
866
|
*/
|
|
912
|
-
export async function waitForActivity(
|
|
913
|
-
this: ADB,
|
|
914
|
-
pkg: string,
|
|
915
|
-
act: string,
|
|
916
|
-
waitMs: number = 20000,
|
|
917
|
-
): Promise<void> {
|
|
867
|
+
export async function waitForActivity(this: ADB, pkg: string, act: string, waitMs: number = 20000): Promise<void> {
|
|
918
868
|
await this.waitForActivityOrNot(pkg, act, false, waitMs);
|
|
919
869
|
}
|
|
920
870
|
|
|
@@ -927,12 +877,7 @@ export async function waitForActivity(
|
|
|
927
877
|
* @param waitMs - Number of milliseconds to wait before timeout occurs.
|
|
928
878
|
* @throws {Error} If timeout happens.
|
|
929
879
|
*/
|
|
930
|
-
export async function waitForNotActivity(
|
|
931
|
-
this: ADB,
|
|
932
|
-
pkg: string,
|
|
933
|
-
act: string,
|
|
934
|
-
waitMs: number = 20000,
|
|
935
|
-
): Promise<void> {
|
|
880
|
+
export async function waitForNotActivity(this: ADB, pkg: string, act: string, waitMs: number = 20000): Promise<void> {
|
|
936
881
|
await this.waitForActivityOrNot(pkg, act, true, waitMs);
|
|
937
882
|
}
|
|
938
883
|
|
|
@@ -945,17 +890,8 @@ export async function waitForNotActivity(
|
|
|
945
890
|
* @returns The actual command line array
|
|
946
891
|
*/
|
|
947
892
|
export function buildStartCmd(startAppOptions: StartCmdOptions, apiLevel: number): string[] {
|
|
948
|
-
const {
|
|
949
|
-
|
|
950
|
-
waitForLaunch,
|
|
951
|
-
pkg,
|
|
952
|
-
activity,
|
|
953
|
-
action,
|
|
954
|
-
category,
|
|
955
|
-
stopApp,
|
|
956
|
-
flags,
|
|
957
|
-
optionalIntentArguments,
|
|
958
|
-
} = startAppOptions;
|
|
893
|
+
const {user, waitForLaunch, pkg, activity, action, category, stopApp, flags, optionalIntentArguments} =
|
|
894
|
+
startAppOptions;
|
|
959
895
|
const cmd = ['am', apiLevel < 26 ? 'start' : 'start-activity'];
|
|
960
896
|
if (util.hasValue(user)) {
|
|
961
897
|
cmd.push('--user', `${user}`);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {log} from '../logger.js';
|
|
2
|
-
import {retryInterval} from 'asyncbox';
|
|
3
1
|
import {util} from '@appium/support';
|
|
2
|
+
import {retryInterval} from 'asyncbox';
|
|
3
|
+
import type {ExecError} from 'teen_process';
|
|
4
|
+
|
|
4
5
|
import type {ADB} from '../adb.js';
|
|
6
|
+
import {log} from '../logger.js';
|
|
5
7
|
import type {SetPropOpts} from './types.js';
|
|
6
|
-
import type {ExecError} from 'teen_process';
|
|
7
8
|
|
|
8
9
|
const ANIMATION_SCALE_KEYS = [
|
|
9
10
|
'animator_duration_scale',
|
|
@@ -41,12 +42,7 @@ export async function getDeviceProperty(this: ADB, property: string): Promise<st
|
|
|
41
42
|
*
|
|
42
43
|
* @throws If _setprop_ utility fails to change property value.
|
|
43
44
|
*/
|
|
44
|
-
export async function setDeviceProperty(
|
|
45
|
-
this: ADB,
|
|
46
|
-
prop: string,
|
|
47
|
-
val: string,
|
|
48
|
-
opts: SetPropOpts = {},
|
|
49
|
-
): Promise<void> {
|
|
45
|
+
export async function setDeviceProperty(this: ADB, prop: string, val: string, opts: SetPropOpts = {}): Promise<void> {
|
|
50
46
|
const {privileged = true} = opts;
|
|
51
47
|
log.debug(`Setting device property '${prop}' to '${val}'`);
|
|
52
48
|
await this.shell(['setprop', prop, val], {
|
|
@@ -148,11 +144,7 @@ export async function getScreenDensity(this: ADB): Promise<number | null> {
|
|
|
148
144
|
* @param proxyHost - The host name of the proxy.
|
|
149
145
|
* @param proxyPort - The port number to be set.
|
|
150
146
|
*/
|
|
151
|
-
export async function setHttpProxy(
|
|
152
|
-
this: ADB,
|
|
153
|
-
proxyHost: string,
|
|
154
|
-
proxyPort: string | number,
|
|
155
|
-
): Promise<void> {
|
|
147
|
+
export async function setHttpProxy(this: ADB, proxyHost: string, proxyPort: string | number): Promise<void> {
|
|
156
148
|
const proxy = `${proxyHost}:${proxyPort}`;
|
|
157
149
|
if (typeof proxyHost === 'undefined') {
|
|
158
150
|
throw new Error(`Call to setHttpProxy method with undefined proxy_host: ${proxy}`);
|
|
@@ -246,7 +238,7 @@ export async function getPlatformVersion(this: ADB): Promise<string> {
|
|
|
246
238
|
return await this.getDeviceProperty('ro.build.version.release');
|
|
247
239
|
} catch (e) {
|
|
248
240
|
const err = e as Error;
|
|
249
|
-
throw new Error(`Error getting device platform version.
|
|
241
|
+
throw new Error(`Error getting device platform version. Original error: ${err.message}`, {
|
|
250
242
|
cause: e,
|
|
251
243
|
});
|
|
252
244
|
}
|
|
@@ -269,9 +261,7 @@ export async function getLocationProviders(this: ADB): Promise<string[]> {
|
|
|
269
261
|
}
|
|
270
262
|
|
|
271
263
|
// To emulate the legacy behavior
|
|
272
|
-
return (await this.shell(['cmd', 'location', 'is-location-enabled'])).includes('true')
|
|
273
|
-
? ['gps']
|
|
274
|
-
: [];
|
|
264
|
+
return (await this.shell(['cmd', 'location', 'is-location-enabled'])).includes('true') ? ['gps'] : [];
|
|
275
265
|
}
|
|
276
266
|
|
|
277
267
|
/**
|
|
@@ -314,24 +304,15 @@ export async function toggleGPSLocationProvider(this: ADB, enabled: boolean): Pr
|
|
|
314
304
|
* @throws If there was an error and ignoreError was true while executing 'adb shell settings put global'
|
|
315
305
|
* command on the device under test.
|
|
316
306
|
*/
|
|
317
|
-
export async function setHiddenApiPolicy(
|
|
318
|
-
this: ADB,
|
|
319
|
-
value: number | string,
|
|
320
|
-
ignoreError = false,
|
|
321
|
-
): Promise<void> {
|
|
307
|
+
export async function setHiddenApiPolicy(this: ADB, value: number | string, ignoreError = false): Promise<void> {
|
|
322
308
|
try {
|
|
323
|
-
await this.shell(
|
|
324
|
-
HIDDEN_API_POLICY_KEYS.map((k) => `settings put global ${k} ${value}`).join(';'),
|
|
325
|
-
);
|
|
309
|
+
await this.shell(HIDDEN_API_POLICY_KEYS.map((k) => `settings put global ${k} ${value}`).join(';'));
|
|
326
310
|
} catch (e) {
|
|
327
311
|
const err = e as Error;
|
|
328
312
|
if (!ignoreError) {
|
|
329
313
|
throw decorateWriteSecureSettingsException(err);
|
|
330
314
|
}
|
|
331
|
-
log.info(
|
|
332
|
-
`Failed to set setting keys '${HIDDEN_API_POLICY_KEYS}' to '${value}'. ` +
|
|
333
|
-
`Original error: ${err.message}`,
|
|
334
|
-
);
|
|
315
|
+
log.info(`Failed to set setting keys '${HIDDEN_API_POLICY_KEYS}' to '${value}'. Original error: ${err.message}`);
|
|
335
316
|
}
|
|
336
317
|
}
|
|
337
318
|
|
|
@@ -532,9 +513,7 @@ export async function addToDeviceIdleWhitelist(this: ADB, ...packages: string[])
|
|
|
532
513
|
return false;
|
|
533
514
|
}
|
|
534
515
|
|
|
535
|
-
log.info(
|
|
536
|
-
`Adding ${util.pluralize('package', packages.length)} ${JSON.stringify(packages)} to Doze whitelist`,
|
|
537
|
-
);
|
|
516
|
+
log.info(`Adding ${util.pluralize('package', packages.length)} ${JSON.stringify(packages)} to Doze whitelist`);
|
|
538
517
|
await this.shellChunks((pkg) => ['dumpsys', 'deviceidle', 'whitelist', `+${pkg}`], packages);
|
|
539
518
|
return true;
|
|
540
519
|
}
|
|
@@ -592,9 +571,7 @@ export async function setNfcOn(this: ADB, on: boolean): Promise<void> {
|
|
|
592
571
|
const output = stderr || stdout;
|
|
593
572
|
log.debug(output);
|
|
594
573
|
if (output.includes('null NfcAdapter')) {
|
|
595
|
-
throw new Error(
|
|
596
|
-
`Cannot turn ${on ? 'on' : 'off'} the NFC adapter. Does the device under test have it?`,
|
|
597
|
-
);
|
|
574
|
+
throw new Error(`Cannot turn ${on ? 'on' : 'off'} the NFC adapter. Does the device under test have it?`);
|
|
598
575
|
}
|
|
599
576
|
}
|
|
600
577
|
|
|
@@ -609,15 +586,7 @@ export async function setNfcOn(this: ADB, on: boolean): Promise<void> {
|
|
|
609
586
|
* @param on - True to broadcast enable and false to broadcast disable.
|
|
610
587
|
*/
|
|
611
588
|
export async function broadcastAirplaneMode(this: ADB, on: boolean): Promise<void> {
|
|
612
|
-
const args = [
|
|
613
|
-
'am',
|
|
614
|
-
'broadcast',
|
|
615
|
-
'-a',
|
|
616
|
-
'android.intent.action.AIRPLANE_MODE',
|
|
617
|
-
'--ez',
|
|
618
|
-
'state',
|
|
619
|
-
on ? 'true' : 'false',
|
|
620
|
-
];
|
|
589
|
+
const args = ['am', 'broadcast', '-a', 'android.intent.action.AIRPLANE_MODE', '--ez', 'state', on ? 'true' : 'false'];
|
|
621
590
|
try {
|
|
622
591
|
await this.shell(args);
|
|
623
592
|
} catch (e) {
|
|
@@ -666,9 +635,7 @@ export async function isDataOn(this: ADB): Promise<boolean> {
|
|
|
666
635
|
*/
|
|
667
636
|
export async function isAnimationOn(this: ADB): Promise<boolean> {
|
|
668
637
|
return (
|
|
669
|
-
await Promise.all(
|
|
670
|
-
ANIMATION_SCALE_KEYS.map(async (k) => (await this.getSetting('global', k)) !== '0.0'),
|
|
671
|
-
)
|
|
638
|
+
await Promise.all(ANIMATION_SCALE_KEYS.map(async (k) => (await this.getSetting('global', k)) !== '0.0'))
|
|
672
639
|
).includes(true);
|
|
673
640
|
}
|
|
674
641
|
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {log} from '../logger.js';
|
|
2
1
|
import net from 'node:net';
|
|
3
|
-
import {util, fs} from '@appium/support';
|
|
4
2
|
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
import {util, fs} from '@appium/support';
|
|
5
5
|
import * as ini from 'ini';
|
|
6
|
+
|
|
6
7
|
import type {ADB} from '../adb.js';
|
|
8
|
+
import {log} from '../logger.js';
|
|
7
9
|
import type {
|
|
8
10
|
EmuInfo,
|
|
9
11
|
EmuVersionInfo,
|
|
@@ -72,8 +74,7 @@ export async function rotate(this: ADB): Promise<void> {
|
|
|
72
74
|
export async function powerAC(this: ADB, state: PowerAcStates = 'on'): Promise<void> {
|
|
73
75
|
if (!(Object.values(this.POWER_AC_STATES) as string[]).includes(state)) {
|
|
74
76
|
throw new TypeError(
|
|
75
|
-
`Wrong power AC state sent '${state}'.
|
|
76
|
-
`Supported values: ${Object.values(this.POWER_AC_STATES)}]`,
|
|
77
|
+
`Wrong power AC state sent '${state}'. Supported values: ${Object.values(this.POWER_AC_STATES)}]`,
|
|
77
78
|
);
|
|
78
79
|
}
|
|
79
80
|
await this.adbExecEmu(['power', 'ac', state]);
|
|
@@ -88,9 +89,7 @@ export async function powerAC(this: ADB, state: PowerAcStates = 'on'): Promise<v
|
|
|
88
89
|
*/
|
|
89
90
|
export async function sensorSet(this: ADB, sensor: string, value: Sensors): Promise<void> {
|
|
90
91
|
if (!(Object.values(this.SENSORS) as string[]).includes(sensor)) {
|
|
91
|
-
throw new TypeError(
|
|
92
|
-
`Unsupported sensor sent '${sensor}'. ` + `Supported values: ${Object.values(this.SENSORS)}]`,
|
|
93
|
-
);
|
|
92
|
+
throw new TypeError(`Unsupported sensor sent '${sensor}'. Supported values: ${Object.values(this.SENSORS)}]`);
|
|
94
93
|
}
|
|
95
94
|
if (value == null) {
|
|
96
95
|
throw new TypeError(
|
|
@@ -130,11 +129,7 @@ export async function powerOFF(this: ADB): Promise<void> {
|
|
|
130
129
|
* @param message - The message content.
|
|
131
130
|
* @throws If phone number has invalid format.
|
|
132
131
|
*/
|
|
133
|
-
export async function sendSMS(
|
|
134
|
-
this: ADB,
|
|
135
|
-
phoneNumber: string | number,
|
|
136
|
-
message = '',
|
|
137
|
-
): Promise<void> {
|
|
132
|
+
export async function sendSMS(this: ADB, phoneNumber: string | number, message = ''): Promise<void> {
|
|
138
133
|
if (!message) {
|
|
139
134
|
throw new TypeError('SMS message must not be empty');
|
|
140
135
|
}
|
|
@@ -152,11 +147,7 @@ export async function sendSMS(
|
|
|
152
147
|
* @throws If phone number has invalid format.
|
|
153
148
|
* @throws If _action_ value is invalid.
|
|
154
149
|
*/
|
|
155
|
-
export async function gsmCall(
|
|
156
|
-
this: ADB,
|
|
157
|
-
phoneNumber: string | number,
|
|
158
|
-
action: GsmCallActions,
|
|
159
|
-
): Promise<void> {
|
|
150
|
+
export async function gsmCall(this: ADB, phoneNumber: string | number, action: GsmCallActions): Promise<void> {
|
|
160
151
|
if (!Object.values(this.GSM_CALL_ACTIONS).includes(action)) {
|
|
161
152
|
throw new TypeError(
|
|
162
153
|
`Invalid gsm action param ${action}. Supported values: ${Object.values(this.GSM_CALL_ACTIONS)}`,
|
|
@@ -211,9 +202,7 @@ export async function gsmVoice(this: ADB, state: GsmVoiceStates = 'on'): Promise
|
|
|
211
202
|
export async function networkSpeed(this: ADB, speed: NetworkSpeed = 'full'): Promise<void> {
|
|
212
203
|
// network speed <speed> allows you to set the network speed emulation.
|
|
213
204
|
if (!Object.values(this.NETWORK_SPEED).includes(speed)) {
|
|
214
|
-
throw new Error(
|
|
215
|
-
`Invalid network speed param ${speed}. Supported values: ${Object.values(this.NETWORK_SPEED)}`,
|
|
216
|
-
);
|
|
205
|
+
throw new Error(`Invalid network speed param ${speed}. Supported values: ${Object.values(this.NETWORK_SPEED)}`);
|
|
217
206
|
}
|
|
218
207
|
await this.adbExecEmu(['network', 'speed', speed]);
|
|
219
208
|
}
|
|
@@ -259,12 +248,7 @@ export async function execEmuConsoleCommand(
|
|
|
259
248
|
|
|
260
249
|
return await new Promise<string>((resolve, reject) => {
|
|
261
250
|
const connTimeoutObj = setTimeout(
|
|
262
|
-
() =>
|
|
263
|
-
reject(
|
|
264
|
-
new Error(
|
|
265
|
-
`Cannot connect to the Emulator console at ${host}:${port} ` + `after ${connTimeout}ms`,
|
|
266
|
-
),
|
|
267
|
-
),
|
|
251
|
+
() => reject(new Error(`Cannot connect to the Emulator console at ${host}:${port} after ${connTimeout}ms`)),
|
|
268
252
|
connTimeout,
|
|
269
253
|
);
|
|
270
254
|
let execTimeoutObj: NodeJS.Timeout;
|
|
@@ -274,12 +258,7 @@ export async function execEmuConsoleCommand(
|
|
|
274
258
|
|
|
275
259
|
client.once('error', (e) => {
|
|
276
260
|
clearTimeout(connTimeoutObj);
|
|
277
|
-
reject(
|
|
278
|
-
new Error(
|
|
279
|
-
`Cannot connect to the Emulator console at ${host}:${port}. ` +
|
|
280
|
-
`Original error: ${e.message}`,
|
|
281
|
-
),
|
|
282
|
-
);
|
|
261
|
+
reject(new Error(`Cannot connect to the Emulator console at ${host}:${port}. Original error: ${e.message}`));
|
|
283
262
|
});
|
|
284
263
|
|
|
285
264
|
client.once('connect', () => {
|
|
@@ -440,9 +419,7 @@ async function listEmulators(): Promise<EmuInfo[]> {
|
|
|
440
419
|
}
|
|
441
420
|
|
|
442
421
|
if (avdsRoot) {
|
|
443
|
-
log.warn(
|
|
444
|
-
`The value of the ANDROID_AVD_HOME environment variable '${avdsRoot}' is not an existing directory`,
|
|
445
|
-
);
|
|
422
|
+
log.warn(`The value of the ANDROID_AVD_HOME environment variable '${avdsRoot}' is not an existing directory`);
|
|
446
423
|
}
|
|
447
424
|
|
|
448
425
|
const prefsRoot = await getAndroidPrefsRoot();
|
|
@@ -490,9 +467,7 @@ async function getAndroidPrefsRoot(): Promise<string | null> {
|
|
|
490
467
|
}
|
|
491
468
|
|
|
492
469
|
if (location) {
|
|
493
|
-
log.warn(
|
|
494
|
-
`The value of the ANDROID_EMULATOR_HOME environment variable '${location}' is not an existing directory`,
|
|
495
|
-
);
|
|
470
|
+
log.warn(`The value of the ANDROID_EMULATOR_HOME environment variable '${location}' is not an existing directory`);
|
|
496
471
|
}
|
|
497
472
|
|
|
498
473
|
const home = process.env.HOME || process.env.USERPROFILE;
|
package/lib/tools/fs-commands.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {log} from '../logger.js';
|
|
2
1
|
import {fs, util} from '@appium/support';
|
|
3
2
|
import {SubProcess, exec, type ExecError} from 'teen_process';
|
|
3
|
+
|
|
4
4
|
import type {ADB} from '../adb.js';
|
|
5
|
-
import
|
|
5
|
+
import {log} from '../logger.js';
|
|
6
6
|
import {memoize} from '../utils/index.js';
|
|
7
|
+
import type {ScreenrecordOptions, StringRecord} from './types.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Get the path to adb executable amd assign it
|
|
@@ -191,11 +192,7 @@ export async function bugreport(this: ADB, timeout: number = 120000): Promise<st
|
|
|
191
192
|
* @param options - Screenrecord options
|
|
192
193
|
* @returns screenrecord process, which can be then controlled by the client code
|
|
193
194
|
*/
|
|
194
|
-
export function screenrecord(
|
|
195
|
-
this: ADB,
|
|
196
|
-
destination: string,
|
|
197
|
-
options: ScreenrecordOptions = {},
|
|
198
|
-
): SubProcess {
|
|
195
|
+
export function screenrecord(this: ADB, destination: string, options: ScreenrecordOptions = {}): SubProcess {
|
|
199
196
|
const cmd: string[] = ['screenrecord'];
|
|
200
197
|
const {videoSize, bitRate, timeLimit, bugReport} = options;
|
|
201
198
|
if (util.hasValue(videoSize)) {
|
|
@@ -293,10 +290,7 @@ export async function isIncrementalInstallSupported(this: ADB): Promise<boolean>
|
|
|
293
290
|
if (!binary) {
|
|
294
291
|
return false;
|
|
295
292
|
}
|
|
296
|
-
return (
|
|
297
|
-
util.compareVersions(`${binary.version}`, '>=', '30.0.1') &&
|
|
298
|
-
(await this.listFeatures()).includes('abb_exec')
|
|
299
|
-
);
|
|
293
|
+
return util.compareVersions(`${binary.version}`, '>=', '30.0.1') && (await this.listFeatures()).includes('abb_exec');
|
|
300
294
|
}
|
|
301
295
|
|
|
302
296
|
/**
|
|
@@ -329,8 +323,7 @@ export async function takeScreenshot(this: ADB, displayId?: number | string): Pr
|
|
|
329
323
|
outputStr = typeof stdout === 'string' ? stdout : stdout.toString('utf-8');
|
|
330
324
|
}
|
|
331
325
|
throw new Error(
|
|
332
|
-
`Screenshot of the ${displayDescr} failed.
|
|
333
|
-
`Code: '${err.code ?? 'unknown'}', output: '${outputStr}'`,
|
|
326
|
+
`Screenshot of the ${displayDescr} failed. Code: '${err.code ?? 'unknown'}', output: '${outputStr}'`,
|
|
334
327
|
{cause: e},
|
|
335
328
|
);
|
|
336
329
|
}
|