appium-android-driver 7.8.2 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/build/lib/commands/app-management.d.ts +129 -5
- package/build/lib/commands/app-management.d.ts.map +1 -1
- package/build/lib/commands/app-management.js +433 -128
- package/build/lib/commands/app-management.js.map +1 -1
- package/build/lib/commands/appearance.d.ts +17 -4
- package/build/lib/commands/appearance.d.ts.map +1 -1
- package/build/lib/commands/appearance.js +32 -33
- package/build/lib/commands/appearance.js.map +1 -1
- package/build/lib/commands/context/cache.d.ts +19 -0
- package/build/lib/commands/context/cache.d.ts.map +1 -0
- package/build/lib/commands/context/cache.js +32 -0
- package/build/lib/commands/context/cache.js.map +1 -0
- package/build/lib/commands/context/exports.d.ts +141 -0
- package/build/lib/commands/context/exports.d.ts.map +1 -0
- package/build/lib/commands/context/exports.js +351 -0
- package/build/lib/commands/context/exports.js.map +1 -0
- package/build/lib/commands/context/helpers.d.ts +98 -0
- package/build/lib/commands/context/helpers.d.ts.map +1 -0
- package/build/lib/commands/context/helpers.js +715 -0
- package/build/lib/commands/context/helpers.js.map +1 -0
- package/build/lib/commands/device/common.d.ts +23 -0
- package/build/lib/commands/device/common.d.ts.map +1 -0
- package/build/lib/commands/device/common.js +230 -0
- package/build/lib/commands/device/common.js.map +1 -0
- package/build/lib/commands/device/emulator-actions.d.ts +114 -0
- package/build/lib/commands/device/emulator-actions.d.ts.map +1 -0
- package/build/lib/commands/device/emulator-actions.js +197 -0
- package/build/lib/commands/device/emulator-actions.js.map +1 -0
- package/build/lib/commands/device/emulator-console.d.ts +7 -0
- package/build/lib/commands/device/emulator-console.d.ts.map +1 -0
- package/build/lib/commands/device/emulator-console.js +24 -0
- package/build/lib/commands/device/emulator-console.js.map +1 -0
- package/build/lib/commands/device/utils.d.ts +50 -0
- package/build/lib/commands/device/utils.d.ts.map +1 -0
- package/build/lib/commands/device/utils.js +238 -0
- package/build/lib/commands/device/utils.js.map +1 -0
- package/build/lib/commands/deviceidle.d.ts +8 -5
- package/build/lib/commands/deviceidle.d.ts.map +1 -1
- package/build/lib/commands/deviceidle.js +31 -37
- package/build/lib/commands/deviceidle.js.map +1 -1
- package/build/lib/commands/element.d.ts +99 -5
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +152 -116
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/execute.d.ts +12 -4
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +83 -78
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/file-actions.d.ts +42 -5
- package/build/lib/commands/file-actions.d.ts.map +1 -1
- package/build/lib/commands/file-actions.js +230 -194
- package/build/lib/commands/file-actions.js.map +1 -1
- package/build/lib/commands/find.d.ts +5 -4
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +7 -10
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/geolocation.d.ts +45 -0
- package/build/lib/commands/geolocation.d.ts.map +1 -0
- package/build/lib/commands/geolocation.js +182 -0
- package/build/lib/commands/geolocation.js.map +1 -0
- package/build/lib/commands/ime.d.ts +25 -5
- package/build/lib/commands/ime.d.ts.map +1 -1
- package/build/lib/commands/ime.js +59 -42
- package/build/lib/commands/ime.js.map +1 -1
- package/build/lib/commands/intent.d.ts +56 -5
- package/build/lib/commands/intent.d.ts.map +1 -1
- package/build/lib/commands/intent.js +135 -83
- package/build/lib/commands/intent.js.map +1 -1
- package/build/lib/commands/keyboard.d.ts +58 -4
- package/build/lib/commands/keyboard.d.ts.map +1 -1
- package/build/lib/commands/keyboard.js +119 -17
- package/build/lib/commands/keyboard.js.map +1 -1
- package/build/lib/commands/lock/exports.d.ts +301 -0
- package/build/lib/commands/lock/exports.d.ts.map +1 -0
- package/build/lib/commands/lock/exports.js +121 -0
- package/build/lib/commands/lock/exports.js.map +1 -0
- package/build/lib/commands/lock/helpers.d.ts +349 -0
- package/build/lib/commands/lock/helpers.d.ts.map +1 -0
- package/build/lib/commands/lock/helpers.js +375 -0
- package/build/lib/commands/lock/helpers.js.map +1 -0
- package/build/lib/commands/log.d.ts +59 -5
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +150 -140
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/media-projection.d.ts +16 -5
- package/build/lib/commands/media-projection.d.ts.map +1 -1
- package/build/lib/commands/media-projection.js +69 -58
- package/build/lib/commands/media-projection.js.map +1 -1
- package/build/lib/commands/memory.d.ts +9 -5
- package/build/lib/commands/memory.d.ts.map +1 -1
- package/build/lib/commands/memory.js +19 -24
- package/build/lib/commands/memory.js.map +1 -1
- package/build/lib/commands/misc.d.ts +42 -0
- package/build/lib/commands/misc.d.ts.map +1 -0
- package/build/lib/commands/misc.js +100 -0
- package/build/lib/commands/misc.js.map +1 -0
- package/build/lib/commands/network.d.ts +61 -5
- package/build/lib/commands/network.d.ts.map +1 -1
- package/build/lib/commands/network.js +196 -189
- package/build/lib/commands/network.js.map +1 -1
- package/build/lib/commands/performance.d.ts +67 -27
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/performance.js +105 -80
- package/build/lib/commands/performance.js.map +1 -1
- package/build/lib/commands/permissions.d.ts +12 -6
- package/build/lib/commands/permissions.d.ts.map +1 -1
- package/build/lib/commands/permissions.js +65 -62
- package/build/lib/commands/permissions.js.map +1 -1
- package/build/lib/commands/recordscreen.d.ts +44 -5
- package/build/lib/commands/recordscreen.d.ts.map +1 -1
- package/build/lib/commands/recordscreen.js +131 -126
- package/build/lib/commands/recordscreen.js.map +1 -1
- package/build/lib/commands/resources.d.ts +16 -0
- package/build/lib/commands/resources.d.ts.map +1 -0
- package/build/lib/commands/resources.js +91 -0
- package/build/lib/commands/resources.js.map +1 -0
- package/build/lib/commands/shell.d.ts +8 -5
- package/build/lib/commands/shell.d.ts.map +1 -1
- package/build/lib/commands/shell.js +29 -33
- package/build/lib/commands/shell.js.map +1 -1
- package/build/lib/commands/streamscreen.d.ts +34 -6
- package/build/lib/commands/streamscreen.d.ts.map +1 -1
- package/build/lib/commands/streamscreen.js +166 -162
- package/build/lib/commands/streamscreen.js.map +1 -1
- package/build/lib/commands/system-bars.d.ts +18 -13
- package/build/lib/commands/system-bars.d.ts.map +1 -1
- package/build/lib/commands/system-bars.js +68 -64
- package/build/lib/commands/system-bars.js.map +1 -1
- package/build/lib/commands/time.d.ts +14 -0
- package/build/lib/commands/time.d.ts.map +1 -0
- package/build/lib/commands/time.js +39 -0
- package/build/lib/commands/time.js.map +1 -0
- package/build/lib/commands/touch.d.ts +99 -6
- package/build/lib/commands/touch.d.ts.map +1 -1
- package/build/lib/commands/touch.js +399 -280
- package/build/lib/commands/touch.js.map +1 -1
- package/build/lib/commands/types.d.ts +115 -3
- package/build/lib/commands/types.d.ts.map +1 -1
- package/build/lib/doctor/checks.d.ts.map +1 -1
- package/build/lib/doctor/checks.js +4 -4
- package/build/lib/doctor/checks.js.map +1 -1
- package/build/lib/driver.d.ts +224 -27
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +232 -7
- package/build/lib/driver.js.map +1 -1
- package/build/lib/index.d.ts +1 -4
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/index.js +1 -13
- package/build/lib/index.js.map +1 -1
- package/build/lib/logger.js.map +1 -1
- package/build/lib/method-map.d.ts +0 -23
- package/build/lib/method-map.d.ts.map +1 -1
- package/build/lib/method-map.js +0 -11
- package/build/lib/method-map.js.map +1 -1
- package/build/lib/utils.d.ts +12 -0
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +38 -2
- package/build/lib/utils.js.map +1 -1
- package/lib/commands/app-management.js +470 -145
- package/lib/commands/appearance.js +29 -36
- package/lib/commands/context/cache.js +29 -0
- package/lib/commands/context/exports.js +379 -0
- package/lib/commands/context/helpers.js +802 -0
- package/lib/commands/device/common.js +264 -0
- package/lib/commands/device/emulator-actions.js +194 -0
- package/lib/commands/device/emulator-console.js +24 -0
- package/lib/commands/device/utils.js +285 -0
- package/lib/commands/deviceidle.js +31 -44
- package/lib/commands/element.js +149 -142
- package/lib/commands/execute.js +86 -87
- package/lib/commands/file-actions.js +249 -222
- package/lib/commands/find.ts +13 -19
- package/lib/commands/geolocation.js +179 -0
- package/lib/commands/ime.js +53 -45
- package/lib/commands/intent.js +149 -91
- package/lib/commands/keyboard.js +114 -17
- package/lib/commands/lock/exports.js +139 -0
- package/lib/commands/lock/helpers.js +379 -0
- package/lib/commands/log.js +170 -166
- package/lib/commands/media-projection.js +75 -70
- package/lib/commands/memory.js +17 -29
- package/lib/commands/misc.js +94 -0
- package/lib/commands/network.js +209 -223
- package/lib/commands/performance.js +88 -73
- package/lib/commands/permissions.js +83 -84
- package/lib/commands/recordscreen.js +171 -170
- package/lib/commands/resources.js +96 -0
- package/lib/commands/shell.js +28 -42
- package/lib/commands/streamscreen.js +207 -206
- package/lib/commands/system-bars.js +76 -77
- package/lib/commands/time.js +36 -0
- package/lib/commands/touch.js +442 -346
- package/lib/commands/types.ts +142 -10
- package/lib/doctor/checks.js +24 -16
- package/lib/driver.ts +454 -12
- package/lib/index.ts +1 -13
- package/lib/logger.js +1 -1
- package/lib/method-map.js +0 -11
- package/lib/utils.js +40 -3
- package/package.json +1 -1
- package/build/lib/commands/actions.d.ts +0 -8
- package/build/lib/commands/actions.d.ts.map +0 -1
- package/build/lib/commands/actions.js +0 -207
- package/build/lib/commands/actions.js.map +0 -1
- package/build/lib/commands/alert.d.ts +0 -8
- package/build/lib/commands/alert.d.ts.map +0 -1
- package/build/lib/commands/alert.js +0 -29
- package/build/lib/commands/alert.js.map +0 -1
- package/build/lib/commands/context.d.ts +0 -10
- package/build/lib/commands/context.d.ts.map +0 -1
- package/build/lib/commands/context.js +0 -431
- package/build/lib/commands/context.js.map +0 -1
- package/build/lib/commands/emu-console.d.ts +0 -7
- package/build/lib/commands/emu-console.d.ts.map +0 -1
- package/build/lib/commands/emu-console.js +0 -27
- package/build/lib/commands/emu-console.js.map +0 -1
- package/build/lib/commands/general.d.ts +0 -9
- package/build/lib/commands/general.d.ts.map +0 -1
- package/build/lib/commands/general.js +0 -293
- package/build/lib/commands/general.js.map +0 -1
- package/build/lib/commands/index.d.ts +0 -28
- package/build/lib/commands/index.d.ts.map +0 -1
- package/build/lib/commands/index.js +0 -57
- package/build/lib/commands/index.js.map +0 -1
- package/build/lib/commands/mixins.d.ts +0 -747
- package/build/lib/commands/mixins.d.ts.map +0 -1
- package/build/lib/commands/mixins.js +0 -19
- package/build/lib/commands/mixins.js.map +0 -1
- package/build/lib/helpers/android.d.ts +0 -163
- package/build/lib/helpers/android.d.ts.map +0 -1
- package/build/lib/helpers/android.js +0 -818
- package/build/lib/helpers/android.js.map +0 -1
- package/build/lib/helpers/index.d.ts +0 -7
- package/build/lib/helpers/index.d.ts.map +0 -1
- package/build/lib/helpers/index.js +0 -29
- package/build/lib/helpers/index.js.map +0 -1
- package/build/lib/helpers/types.d.ts +0 -122
- package/build/lib/helpers/types.d.ts.map +0 -1
- package/build/lib/helpers/types.js +0 -3
- package/build/lib/helpers/types.js.map +0 -1
- package/build/lib/helpers/unlock.d.ts +0 -32
- package/build/lib/helpers/unlock.d.ts.map +0 -1
- package/build/lib/helpers/unlock.js +0 -273
- package/build/lib/helpers/unlock.js.map +0 -1
- package/build/lib/helpers/webview.d.ts +0 -74
- package/build/lib/helpers/webview.d.ts.map +0 -1
- package/build/lib/helpers/webview.js +0 -442
- package/build/lib/helpers/webview.js.map +0 -1
- package/lib/commands/actions.js +0 -244
- package/lib/commands/alert.js +0 -34
- package/lib/commands/context.js +0 -507
- package/lib/commands/emu-console.js +0 -31
- package/lib/commands/general.js +0 -343
- package/lib/commands/index.ts +0 -54
- package/lib/commands/mixins.ts +0 -976
- package/lib/helpers/android.ts +0 -1153
- package/lib/helpers/index.ts +0 -6
- package/lib/helpers/types.ts +0 -136
- package/lib/helpers/unlock.ts +0 -329
- package/lib/helpers/webview.ts +0 -604
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import {fs, tempDir} from '@appium/support';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import B from 'bluebird';
|
|
5
|
+
import {SETTINGS_HELPER_ID} from 'io.appium.settings';
|
|
6
|
+
import {getThirdPartyPackages} from './app-management';
|
|
7
|
+
|
|
8
|
+
// The value close to zero, but not zero, is needed
|
|
9
|
+
// to trick JSON generation and send a float value instead of an integer,
|
|
10
|
+
// This allows strictly-typed clients, like Java, to properly
|
|
11
|
+
// parse it. Otherwise float 0.0 is always represented as integer 0 in JS.
|
|
12
|
+
// The value must not be greater than DBL_EPSILON (https://opensource.apple.com/source/Libc/Libc-498/include/float.h)
|
|
13
|
+
const GEO_EPSILON = Number.MIN_VALUE;
|
|
14
|
+
const MOCK_APP_IDS_STORE = '/data/local/tmp/mock_apps.json';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @this {import('../driver').AndroidDriver}
|
|
18
|
+
* @param {import('@appium/types').Location} location
|
|
19
|
+
* @returns {Promise<import('@appium/types').Location>}
|
|
20
|
+
*/
|
|
21
|
+
export async function setGeoLocation(location) {
|
|
22
|
+
await this.settingsApp.setGeoLocation(location, this.isEmulator());
|
|
23
|
+
try {
|
|
24
|
+
return await this.getGeoLocation();
|
|
25
|
+
} catch (e) {
|
|
26
|
+
this.log.warn(
|
|
27
|
+
`Could not get the current geolocation info: ${/** @type {Error} */ (e).message}`,
|
|
28
|
+
);
|
|
29
|
+
this.log.warn(`Returning the default zero'ed values`);
|
|
30
|
+
return {
|
|
31
|
+
latitude: GEO_EPSILON,
|
|
32
|
+
longitude: GEO_EPSILON,
|
|
33
|
+
altitude: GEO_EPSILON,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Sends an async request to refresh the GPS cache.
|
|
40
|
+
*
|
|
41
|
+
* This feature only works if the device under test has Google Play Services
|
|
42
|
+
* installed. In case the vanilla LocationManager is used the device API level
|
|
43
|
+
* must be at version 30 (Android R) or higher.
|
|
44
|
+
*
|
|
45
|
+
* @this {import('../driver').AndroidDriver}
|
|
46
|
+
* @param {import('./types').GpsCacheRefreshOpts} [opts={}]
|
|
47
|
+
* @returns {Promise<void>}
|
|
48
|
+
*/
|
|
49
|
+
export async function mobileRefreshGpsCache(opts = {}) {
|
|
50
|
+
const {timeoutMs} = opts;
|
|
51
|
+
await this.settingsApp.refreshGeoLocationCache(timeoutMs);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @this {import('../driver').AndroidDriver}
|
|
56
|
+
* @returns {Promise<import('@appium/types').Location>}
|
|
57
|
+
*/
|
|
58
|
+
export async function getGeoLocation() {
|
|
59
|
+
const {latitude, longitude, altitude} = await this.settingsApp.getGeoLocation();
|
|
60
|
+
return {
|
|
61
|
+
latitude: parseFloat(String(latitude)) || GEO_EPSILON,
|
|
62
|
+
longitude: parseFloat(String(longitude)) || GEO_EPSILON,
|
|
63
|
+
altitude: parseFloat(String(altitude)) || GEO_EPSILON,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @this {import('../driver').AndroidDriver}
|
|
69
|
+
* @returns {Promise<boolean>}
|
|
70
|
+
*/
|
|
71
|
+
export async function isLocationServicesEnabled() {
|
|
72
|
+
return (await this.adb.getLocationProviders()).includes('gps');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @this {import('../driver').AndroidDriver}
|
|
77
|
+
* @returns {Promise<void>}
|
|
78
|
+
*/
|
|
79
|
+
export async function toggleLocationServices() {
|
|
80
|
+
this.log.info('Toggling location services');
|
|
81
|
+
const isGpsEnabled = await this.isLocationServicesEnabled();
|
|
82
|
+
this.log.debug(
|
|
83
|
+
`Current GPS state: ${isGpsEnabled}. ` +
|
|
84
|
+
`The service is going to be ${isGpsEnabled ? 'disabled' : 'enabled'}`,
|
|
85
|
+
);
|
|
86
|
+
await this.adb.toggleGPSLocationProvider(!isGpsEnabled);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// #region Internal helpers
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @this {import('../driver').AndroidDriver}
|
|
93
|
+
* @param {string} appId
|
|
94
|
+
* @returns {Promise<void>}
|
|
95
|
+
*/
|
|
96
|
+
export async function setMockLocationApp(appId) {
|
|
97
|
+
try {
|
|
98
|
+
if ((await this.adb.getApiLevel()) < 23) {
|
|
99
|
+
await this.adb.shell(['settings', 'put', 'secure', 'mock_location', '1']);
|
|
100
|
+
} else {
|
|
101
|
+
await this.adb.shell(['appops', 'set', appId, 'android:mock_location', 'allow']);
|
|
102
|
+
}
|
|
103
|
+
} catch (err) {
|
|
104
|
+
this.log.warn(`Unable to set mock location for app '${appId}': ${err.message}`);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
try {
|
|
108
|
+
/** @type {string[]} */
|
|
109
|
+
let pkgIds = [];
|
|
110
|
+
if (await this.adb.fileExists(MOCK_APP_IDS_STORE)) {
|
|
111
|
+
try {
|
|
112
|
+
pkgIds = JSON.parse(await this.adb.shell(['cat', MOCK_APP_IDS_STORE]));
|
|
113
|
+
} catch (ign) {}
|
|
114
|
+
}
|
|
115
|
+
if (pkgIds.includes(appId)) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
pkgIds.push(appId);
|
|
119
|
+
const tmpRoot = await tempDir.openDir();
|
|
120
|
+
const srcPath = path.posix.join(tmpRoot, path.posix.basename(MOCK_APP_IDS_STORE));
|
|
121
|
+
try {
|
|
122
|
+
await fs.writeFile(srcPath, JSON.stringify(pkgIds), 'utf8');
|
|
123
|
+
await this.adb.push(srcPath, MOCK_APP_IDS_STORE);
|
|
124
|
+
} finally {
|
|
125
|
+
await fs.rimraf(tmpRoot);
|
|
126
|
+
}
|
|
127
|
+
} catch (e) {
|
|
128
|
+
this.log.warn(`Unable to persist mock location app id '${appId}': ${e.message}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @this {import('../driver').AndroidDriver}
|
|
134
|
+
* @returns {Promise<void>}
|
|
135
|
+
*/
|
|
136
|
+
export async function resetMockLocation() {
|
|
137
|
+
try {
|
|
138
|
+
if ((await this.adb.getApiLevel()) < 23) {
|
|
139
|
+
await this.adb.shell(['settings', 'put', 'secure', 'mock_location', '0']);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const thirdPartyPkgIdsPromise = getThirdPartyPackages.bind(this)();
|
|
144
|
+
let pkgIds = [];
|
|
145
|
+
if (await this.adb.fileExists(MOCK_APP_IDS_STORE)) {
|
|
146
|
+
try {
|
|
147
|
+
pkgIds = JSON.parse(await this.adb.shell(['cat', MOCK_APP_IDS_STORE]));
|
|
148
|
+
} catch (ign) {}
|
|
149
|
+
}
|
|
150
|
+
const thirdPartyPkgIds = await thirdPartyPkgIdsPromise;
|
|
151
|
+
// Only include currently installed packages
|
|
152
|
+
const resultPkgs = _.intersection(pkgIds, thirdPartyPkgIds);
|
|
153
|
+
if (_.size(resultPkgs) <= 1) {
|
|
154
|
+
await this.adb.shell([
|
|
155
|
+
'appops',
|
|
156
|
+
'set',
|
|
157
|
+
resultPkgs[0] ?? SETTINGS_HELPER_ID,
|
|
158
|
+
'android:mock_location',
|
|
159
|
+
'deny',
|
|
160
|
+
]);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
this.log.debug(`Resetting mock_location permission for the following apps: ${resultPkgs}`);
|
|
165
|
+
await B.all(
|
|
166
|
+
resultPkgs.map((pkgId) =>
|
|
167
|
+
(async () => {
|
|
168
|
+
try {
|
|
169
|
+
await this.adb.shell(['appops', 'set', pkgId, 'android:mock_location', 'deny']);
|
|
170
|
+
} catch (ign) {}
|
|
171
|
+
})(),
|
|
172
|
+
),
|
|
173
|
+
);
|
|
174
|
+
} catch (err) {
|
|
175
|
+
this.log.warn(`Unable to reset mock location: ${err.message}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// #endregion Internal helpers
|
package/lib/commands/ime.js
CHANGED
|
@@ -1,56 +1,64 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
import {mixin} from './mixins';
|
|
4
1
|
import {errors} from 'appium/driver';
|
|
5
2
|
|
|
6
3
|
/**
|
|
7
|
-
* @
|
|
8
|
-
* @
|
|
4
|
+
* @this {import('../driver').AndroidDriver}
|
|
5
|
+
* @returns {Promise<boolean>}
|
|
9
6
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
},
|
|
16
|
-
|
|
17
|
-
async availableIMEEngines() {
|
|
18
|
-
this.log.debug('Retrieving available IMEs');
|
|
19
|
-
let engines = await this.adb.availableIMEs();
|
|
20
|
-
this.log.debug(`Engines: ${JSON.stringify(engines)}`);
|
|
21
|
-
return engines;
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
async getActiveIMEEngine() {
|
|
25
|
-
this.log.debug('Retrieving current default IME');
|
|
26
|
-
return String(await this.adb.defaultIME());
|
|
27
|
-
},
|
|
7
|
+
export async function isIMEActivated() {
|
|
8
|
+
// eslint-disable-line require-await
|
|
9
|
+
// IME is always activated on Android devices
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
28
12
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
},
|
|
13
|
+
/**
|
|
14
|
+
* @this {import('../driver').AndroidDriver}
|
|
15
|
+
* @returns {Promise<string[]>}
|
|
16
|
+
*/
|
|
17
|
+
export async function availableIMEEngines() {
|
|
18
|
+
this.log.debug('Retrieving available IMEs');
|
|
19
|
+
let engines = await this.adb.availableIMEs();
|
|
20
|
+
this.log.debug(`Engines: ${JSON.stringify(engines)}`);
|
|
21
|
+
return engines;
|
|
22
|
+
}
|
|
40
23
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
};
|
|
24
|
+
/**
|
|
25
|
+
* @this {import('../driver').AndroidDriver}
|
|
26
|
+
* @returns {Promise<string>}
|
|
27
|
+
*/
|
|
28
|
+
export async function getActiveIMEEngine() {
|
|
29
|
+
this.log.debug('Retrieving current default IME');
|
|
30
|
+
return String(await this.adb.defaultIME());
|
|
31
|
+
}
|
|
50
32
|
|
|
51
|
-
|
|
33
|
+
/**
|
|
34
|
+
* @this {import('../driver').AndroidDriver}
|
|
35
|
+
* @param {string} imeId
|
|
36
|
+
* @returns {Promise<void>}
|
|
37
|
+
*/
|
|
38
|
+
export async function activateIMEEngine(imeId) {
|
|
39
|
+
this.log.debug(`Attempting to activate IME ${imeId}`);
|
|
40
|
+
let availableEngines = await this.adb.availableIMEs();
|
|
41
|
+
if (availableEngines.indexOf(imeId) === -1) {
|
|
42
|
+
this.log.debug('IME not found, failing');
|
|
43
|
+
throw new errors.IMENotAvailableError();
|
|
44
|
+
}
|
|
45
|
+
this.log.debug('Found installed IME, attempting to activate');
|
|
46
|
+
await this.adb.enableIME(imeId);
|
|
47
|
+
await this.adb.setIME(imeId);
|
|
48
|
+
}
|
|
52
49
|
|
|
53
|
-
|
|
50
|
+
/**
|
|
51
|
+
* @this {import('../driver').AndroidDriver}
|
|
52
|
+
* @returns {Promise<void>}
|
|
53
|
+
*/
|
|
54
|
+
export async function deactivateIMEEngine() {
|
|
55
|
+
let currentEngine = await this.getActiveIMEEngine();
|
|
56
|
+
// XXX: this allowed 'null' to be passed into `adb.shell`
|
|
57
|
+
if (currentEngine) {
|
|
58
|
+
this.log.debug(`Attempting to deactivate ${currentEngine}`);
|
|
59
|
+
await this.adb.disableIME(currentEngine);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
54
62
|
|
|
55
63
|
/**
|
|
56
64
|
* @typedef {import('appium-adb').ADB} ADB
|
package/lib/commands/intent.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
import {mixin} from './mixins';
|
|
4
1
|
import _ from 'lodash';
|
|
5
2
|
import {errors} from 'appium/driver';
|
|
3
|
+
import {util} from '@appium/support';
|
|
6
4
|
|
|
7
5
|
const NO_VALUE_ARG_TYPE = 'sn';
|
|
8
6
|
const SUPPORTED_EXTRA_TYPES = [
|
|
@@ -25,6 +23,150 @@ const SUPPORTED_EXTRA_TYPES = [
|
|
|
25
23
|
];
|
|
26
24
|
const API_LEVEL_ANDROID_8 = 26;
|
|
27
25
|
|
|
26
|
+
/**
|
|
27
|
+
* @deprecated
|
|
28
|
+
* @this {import('../driver').AndroidDriver}
|
|
29
|
+
* @param {string} appPackage
|
|
30
|
+
* @param {string} appActivity
|
|
31
|
+
* @param {string} [appWaitPackage]
|
|
32
|
+
* @param {string} [appWaitActivity]
|
|
33
|
+
* @param {string} [intentAction]
|
|
34
|
+
* @param {string} [intentCategory]
|
|
35
|
+
* @param {string} [intentFlags]
|
|
36
|
+
* @param {string} [optionalIntentArguments]
|
|
37
|
+
* @param {boolean} [dontStopAppOnReset]
|
|
38
|
+
* @returns {Promise<void>}
|
|
39
|
+
*/
|
|
40
|
+
export async function startActivity(
|
|
41
|
+
appPackage,
|
|
42
|
+
appActivity,
|
|
43
|
+
appWaitPackage,
|
|
44
|
+
appWaitActivity,
|
|
45
|
+
intentAction,
|
|
46
|
+
intentCategory,
|
|
47
|
+
intentFlags,
|
|
48
|
+
optionalIntentArguments,
|
|
49
|
+
dontStopAppOnReset,
|
|
50
|
+
) {
|
|
51
|
+
this.log.debug(`Starting package '${appPackage}' and activity '${appActivity}'`);
|
|
52
|
+
|
|
53
|
+
// dontStopAppOnReset is both an argument here, and a desired capability
|
|
54
|
+
// if the argument is set, use it, otherwise use the cap
|
|
55
|
+
if (!util.hasValue(dontStopAppOnReset)) {
|
|
56
|
+
dontStopAppOnReset = !!this.opts.dontStopAppOnReset;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** @type {import('appium-adb').StartAppOptions} */
|
|
60
|
+
let args = {
|
|
61
|
+
pkg: appPackage,
|
|
62
|
+
activity: appActivity,
|
|
63
|
+
waitPkg: appWaitPackage || appPackage,
|
|
64
|
+
waitActivity: appWaitActivity || appActivity,
|
|
65
|
+
action: intentAction,
|
|
66
|
+
category: intentCategory,
|
|
67
|
+
flags: intentFlags,
|
|
68
|
+
optionalIntentArguments,
|
|
69
|
+
stopApp: !dontStopAppOnReset,
|
|
70
|
+
};
|
|
71
|
+
this._cachedActivityArgs = this._cachedActivityArgs || {};
|
|
72
|
+
this._cachedActivityArgs[`${args.waitPkg}/${args.waitActivity}`] = args;
|
|
73
|
+
await this.adb.startApp(args);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @this {import('../driver').AndroidDriver}
|
|
78
|
+
* @param {import('./types').StartActivityOpts} [opts={}]
|
|
79
|
+
* @returns {Promise<string>}
|
|
80
|
+
*/
|
|
81
|
+
export async function mobileStartActivity(opts = {}) {
|
|
82
|
+
const {user, wait, stop, windowingMode, activityType, display} = opts;
|
|
83
|
+
const cmd = [
|
|
84
|
+
'am',
|
|
85
|
+
(await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8 ? 'start' : 'start-activity',
|
|
86
|
+
];
|
|
87
|
+
if (!_.isNil(user)) {
|
|
88
|
+
cmd.push('--user', String(user));
|
|
89
|
+
}
|
|
90
|
+
if (wait) {
|
|
91
|
+
cmd.push('-W');
|
|
92
|
+
}
|
|
93
|
+
if (stop) {
|
|
94
|
+
cmd.push('-S');
|
|
95
|
+
}
|
|
96
|
+
if (!_.isNil(windowingMode)) {
|
|
97
|
+
cmd.push('--windowingMode', String(windowingMode));
|
|
98
|
+
}
|
|
99
|
+
if (!_.isNil(activityType)) {
|
|
100
|
+
cmd.push('--activityType', String(activityType));
|
|
101
|
+
}
|
|
102
|
+
if (!_.isNil(display)) {
|
|
103
|
+
cmd.push('--display', String(display));
|
|
104
|
+
}
|
|
105
|
+
cmd.push(...parseIntentSpec(opts));
|
|
106
|
+
return await this.adb.shell(cmd);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @this {import('../driver').AndroidDriver}
|
|
111
|
+
* @param {import('./types').BroadcastOpts} [opts={}]
|
|
112
|
+
* @returns {Promise<string>}
|
|
113
|
+
*/
|
|
114
|
+
export async function mobileBroadcast(opts = {}) {
|
|
115
|
+
const {user, receiverPermission, allowBackgroundActivityStarts} = opts;
|
|
116
|
+
const cmd = ['am', 'broadcast'];
|
|
117
|
+
if (!_.isNil(user)) {
|
|
118
|
+
cmd.push('--user', String(user));
|
|
119
|
+
}
|
|
120
|
+
if (receiverPermission) {
|
|
121
|
+
cmd.push('--receiver-permission', receiverPermission);
|
|
122
|
+
}
|
|
123
|
+
if (allowBackgroundActivityStarts) {
|
|
124
|
+
cmd.push('--allow-background-activity-starts');
|
|
125
|
+
}
|
|
126
|
+
cmd.push(...parseIntentSpec(opts));
|
|
127
|
+
return await this.adb.shell(cmd);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @this {import('../driver').AndroidDriver}
|
|
132
|
+
* @param {import('./types').StartServiceOpts} [opts={}]
|
|
133
|
+
* @returns {Promise<string>}
|
|
134
|
+
*/
|
|
135
|
+
export async function mobileStartService(opts = {}) {
|
|
136
|
+
const {user, foreground} = opts;
|
|
137
|
+
const cmd = ['am'];
|
|
138
|
+
if ((await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8) {
|
|
139
|
+
cmd.push('startservice');
|
|
140
|
+
} else {
|
|
141
|
+
cmd.push(foreground ? 'start-foreground-service' : 'start-service');
|
|
142
|
+
}
|
|
143
|
+
if (!_.isNil(user)) {
|
|
144
|
+
cmd.push('--user', String(user));
|
|
145
|
+
}
|
|
146
|
+
cmd.push(...parseIntentSpec(opts));
|
|
147
|
+
return await this.adb.shell(cmd);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @this {import('../driver').AndroidDriver}
|
|
152
|
+
* @param {import('./types').StopServiceOpts} [opts={}]
|
|
153
|
+
* @returns {Promise<string>}
|
|
154
|
+
*/
|
|
155
|
+
export async function mobileStopService(opts = {}) {
|
|
156
|
+
const {user} = opts;
|
|
157
|
+
const cmd = [
|
|
158
|
+
'am',
|
|
159
|
+
(await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8 ? 'stopservice' : 'stop-service',
|
|
160
|
+
];
|
|
161
|
+
if (!_.isNil(user)) {
|
|
162
|
+
cmd.push('--user', String(user));
|
|
163
|
+
}
|
|
164
|
+
cmd.push(...parseIntentSpec(opts));
|
|
165
|
+
return await this.adb.shell(cmd);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// #region Internal helpers
|
|
169
|
+
|
|
28
170
|
/**
|
|
29
171
|
*
|
|
30
172
|
* @param {import('./types').IntentOpts} opts
|
|
@@ -73,12 +215,12 @@ function parseIntentSpec(opts = {}) {
|
|
|
73
215
|
if (!_.includes(SUPPORTED_EXTRA_TYPES, type)) {
|
|
74
216
|
throw new errors.InvalidArgumentError(
|
|
75
217
|
`Extra argument type '${type}' is not known. ` +
|
|
76
|
-
`Supported intent argument types are: ${SUPPORTED_EXTRA_TYPES}
|
|
218
|
+
`Supported intent argument types are: ${SUPPORTED_EXTRA_TYPES}`,
|
|
77
219
|
);
|
|
78
220
|
}
|
|
79
221
|
if (_.isEmpty(key) || (_.isString(key) && _.trim(key) === '')) {
|
|
80
222
|
throw new errors.InvalidArgumentError(
|
|
81
|
-
`Extra argument's key in '${JSON.stringify(item)}' must be a valid string identifier
|
|
223
|
+
`Extra argument's key in '${JSON.stringify(item)}' must be a valid string identifier`,
|
|
82
224
|
);
|
|
83
225
|
}
|
|
84
226
|
if (type === NO_VALUE_ARG_TYPE) {
|
|
@@ -86,7 +228,7 @@ function parseIntentSpec(opts = {}) {
|
|
|
86
228
|
} else if (_.isUndefined(value)) {
|
|
87
229
|
throw new errors.InvalidArgumentError(
|
|
88
230
|
`Intent argument type '${type}' in '${JSON.stringify(item)}' requires a ` +
|
|
89
|
-
`valid value to be provided
|
|
231
|
+
`valid value to be provided`,
|
|
90
232
|
);
|
|
91
233
|
} else {
|
|
92
234
|
resultArgs.push(`--e${type}`, key, value);
|
|
@@ -99,91 +241,7 @@ function parseIntentSpec(opts = {}) {
|
|
|
99
241
|
return resultArgs;
|
|
100
242
|
}
|
|
101
243
|
|
|
102
|
-
|
|
103
|
-
* @type {import('./mixins').ActivityMixin & ThisType<import('../driver').AndroidDriver>}
|
|
104
|
-
* @satisfies {import('@appium/types').ExternalDriver}
|
|
105
|
-
*/
|
|
106
|
-
const ActivityMixin = {
|
|
107
|
-
async mobileStartActivity(opts = {}) {
|
|
108
|
-
const {user, wait, stop, windowingMode, activityType, display} = opts;
|
|
109
|
-
const cmd = [
|
|
110
|
-
'am',
|
|
111
|
-
(await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8
|
|
112
|
-
? 'start'
|
|
113
|
-
: 'start-activity',
|
|
114
|
-
];
|
|
115
|
-
if (!_.isNil(user)) {
|
|
116
|
-
cmd.push('--user', String(user));
|
|
117
|
-
}
|
|
118
|
-
if (wait) {
|
|
119
|
-
cmd.push('-W');
|
|
120
|
-
}
|
|
121
|
-
if (stop) {
|
|
122
|
-
cmd.push('-S');
|
|
123
|
-
}
|
|
124
|
-
if (!_.isNil(windowingMode)) {
|
|
125
|
-
cmd.push('--windowingMode', String(windowingMode));
|
|
126
|
-
}
|
|
127
|
-
if (!_.isNil(activityType)) {
|
|
128
|
-
cmd.push('--activityType', String(activityType));
|
|
129
|
-
}
|
|
130
|
-
if (!_.isNil(display)) {
|
|
131
|
-
cmd.push('--display', String(display));
|
|
132
|
-
}
|
|
133
|
-
cmd.push(...parseIntentSpec(opts));
|
|
134
|
-
return await this.adb.shell(cmd);
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
async mobileBroadcast(opts = {}) {
|
|
138
|
-
const {user, receiverPermission, allowBackgroundActivityStarts} = opts;
|
|
139
|
-
const cmd = ['am', 'broadcast'];
|
|
140
|
-
if (!_.isNil(user)) {
|
|
141
|
-
cmd.push('--user', String(user));
|
|
142
|
-
}
|
|
143
|
-
if (receiverPermission) {
|
|
144
|
-
cmd.push('--receiver-permission', receiverPermission);
|
|
145
|
-
}
|
|
146
|
-
if (allowBackgroundActivityStarts) {
|
|
147
|
-
cmd.push('--allow-background-activity-starts');
|
|
148
|
-
}
|
|
149
|
-
cmd.push(...parseIntentSpec(opts));
|
|
150
|
-
return await this.adb.shell(cmd);
|
|
151
|
-
},
|
|
152
|
-
|
|
153
|
-
async mobileStartService(opts = {}) {
|
|
154
|
-
const {user, foreground} = opts;
|
|
155
|
-
const cmd = ['am'];
|
|
156
|
-
if ((await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8) {
|
|
157
|
-
cmd.push('startservice');
|
|
158
|
-
} else {
|
|
159
|
-
cmd.push(foreground ? 'start-foreground-service' : 'start-service');
|
|
160
|
-
}
|
|
161
|
-
if (!_.isNil(user)) {
|
|
162
|
-
cmd.push('--user', String(user));
|
|
163
|
-
}
|
|
164
|
-
cmd.push(...parseIntentSpec(opts));
|
|
165
|
-
return await this.adb.shell(cmd);
|
|
166
|
-
},
|
|
167
|
-
|
|
168
|
-
async mobileStopService(opts = {}) {
|
|
169
|
-
const {user} = opts;
|
|
170
|
-
const cmd = [
|
|
171
|
-
'am',
|
|
172
|
-
(await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8
|
|
173
|
-
? 'stopservice'
|
|
174
|
-
: 'stop-service',
|
|
175
|
-
];
|
|
176
|
-
if (!_.isNil(user)) {
|
|
177
|
-
cmd.push('--user', String(user));
|
|
178
|
-
}
|
|
179
|
-
cmd.push(...parseIntentSpec(opts));
|
|
180
|
-
return await this.adb.shell(cmd);
|
|
181
|
-
},
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
mixin(ActivityMixin);
|
|
185
|
-
|
|
186
|
-
export default ActivityMixin;
|
|
244
|
+
// #endregion
|
|
187
245
|
|
|
188
246
|
/**
|
|
189
247
|
* @typedef {import('appium-adb').ADB} ADB
|