appium-android-driver 5.14.0-alpha.0 → 5.14.0-alpha2
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 +14 -0
- package/build/index.d.ts +282 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +34 -20
- package/build/index.js.map +1 -0
- package/build/lib/android-helpers.d.ts +136 -0
- package/build/lib/android-helpers.d.ts.map +1 -0
- package/build/lib/android-helpers.js +855 -0
- package/build/lib/android-helpers.js.map +1 -0
- package/build/lib/bootstrap.d.ts +2 -2
- package/build/lib/commands/actions.d.ts.map +1 -1
- package/build/lib/commands/actions.js +4 -0
- package/build/lib/commands/actions.js.map +1 -1
- package/build/lib/commands/context.js +1 -1
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/coverage.d.ts +5 -0
- package/build/lib/commands/coverage.d.ts.map +1 -0
- package/build/lib/commands/coverage.js +19 -0
- package/build/lib/commands/coverage.js.map +1 -0
- package/build/lib/commands/execute.d.ts.map +1 -1
- package/build/lib/commands/execute.js +4 -3
- package/build/lib/commands/execute.js.map +1 -1
- package/build/lib/commands/find.d.ts +4 -1
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +1 -0
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/index.d.ts +27 -47
- package/build/lib/commands/index.d.ts.map +1 -1
- package/build/lib/commands/index.js.map +1 -1
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +2 -2
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/mixins.d.ts +11 -6
- package/build/lib/commands/mixins.d.ts.map +1 -1
- package/build/lib/commands/mixins.js.map +1 -1
- package/build/lib/commands/performance.d.ts +4 -4
- package/build/lib/commands/performance.d.ts.map +1 -1
- package/build/lib/commands/types.d.ts +8 -1
- package/build/lib/commands/types.d.ts.map +1 -1
- package/build/lib/constraints.d.ts +289 -384
- package/build/lib/constraints.d.ts.map +1 -1
- package/build/lib/constraints.js +2 -9
- package/build/lib/constraints.js.map +1 -1
- package/build/lib/desired-caps.d.ts +353 -0
- package/build/lib/desired-caps.d.ts.map +1 -0
- package/build/lib/desired-caps.js +299 -0
- package/build/lib/desired-caps.js.map +1 -0
- package/build/lib/driver.d.ts +50 -403
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +67 -127
- package/build/lib/driver.js.map +1 -1
- package/build/lib/helpers/android.d.ts +11 -11
- package/build/lib/helpers/android.d.ts.map +1 -1
- package/build/lib/helpers/android.js.map +1 -1
- package/build/lib/helpers/unlock.d.ts +2 -1
- package/build/lib/helpers/unlock.d.ts.map +1 -1
- package/build/lib/helpers/unlock.js.map +1 -1
- package/build/lib/index.d.ts +9 -0
- package/build/lib/index.d.ts.map +1 -0
- package/build/lib/index.js +37 -0
- package/build/lib/index.js.map +1 -0
- package/build/lib/uiautomator.d.ts +6 -6
- package/build/lib/unlock-helpers.d.ts +38 -0
- package/build/lib/unlock-helpers.d.ts.map +1 -0
- package/build/lib/unlock-helpers.js +266 -0
- package/build/lib/unlock-helpers.js.map +1 -0
- package/build/lib/webview-helpers.d.ts +223 -0
- package/build/lib/webview-helpers.d.ts.map +1 -0
- package/build/lib/webview-helpers.js +530 -0
- package/build/lib/webview-helpers.js.map +1 -0
- package/lib/commands/actions.js +5 -0
- package/lib/commands/context.js +1 -1
- package/lib/commands/execute.js +7 -3
- package/lib/commands/find.ts +2 -0
- package/lib/commands/{index.js → index.ts} +2 -0
- package/lib/commands/log.js +6 -4
- package/lib/commands/mixins.ts +11 -7
- package/lib/commands/types.ts +9 -1
- package/lib/{constraints.js → constraints.ts} +6 -9
- package/lib/{driver.js → driver.ts} +143 -183
- package/lib/helpers/android.ts +31 -14
- package/lib/helpers/unlock.ts +2 -1
- package/lib/index.ts +18 -0
- package/package.json +14 -14
- package/build/lib/commands/mixin.d.ts +0 -3
- package/build/lib/commands/mixin.d.ts.map +0 -1
- package/build/lib/commands/mixin.js +0 -6
- package/build/lib/commands/mixin.js.map +0 -1
|
@@ -1,23 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
2
2
|
|
|
3
|
-
import {BaseDriver, DeviceSettings} from 'appium/driver';
|
|
4
|
-
import desiredConstraints from './constraints';
|
|
5
|
-
|
|
6
|
-
import {newMethodMap} from './method-map';
|
|
7
|
-
import {helpers, ensureNetworkSpeed, SETTINGS_HELPER_PKG_ID} from './helpers';
|
|
8
|
-
import _ from 'lodash';
|
|
9
|
-
import {DEFAULT_ADB_PORT} from 'appium-adb';
|
|
10
3
|
import {fs, tempDir, util} from '@appium/support';
|
|
4
|
+
import type {
|
|
5
|
+
DefaultCreateSessionResult,
|
|
6
|
+
DriverCaps,
|
|
7
|
+
DriverData,
|
|
8
|
+
DriverOpts,
|
|
9
|
+
ExternalDriver,
|
|
10
|
+
InitialOpts,
|
|
11
|
+
RouteMatcher,
|
|
12
|
+
StringRecord,
|
|
13
|
+
W3CDriverCaps,
|
|
14
|
+
} from '@appium/types';
|
|
15
|
+
import ADB, {DEFAULT_ADB_PORT} from 'appium-adb';
|
|
16
|
+
import type {default as AppiumChromedriver} from 'appium-chromedriver';
|
|
17
|
+
import {BaseDriver, DeviceSettings} from 'appium/driver';
|
|
11
18
|
import {retryInterval} from 'asyncbox';
|
|
12
|
-
import {SharedPrefsBuilder} from 'shared-preferences-builder';
|
|
13
19
|
import B from 'bluebird';
|
|
20
|
+
import _ from 'lodash';
|
|
21
|
+
import {SharedPrefsBuilder} from 'shared-preferences-builder';
|
|
22
|
+
import AndroidBootstrap from './bootstrap';
|
|
23
|
+
import ANDROID_DRIVER_CONSTRAINTS, {AndroidDriverConstraints} from './constraints';
|
|
24
|
+
import {SETTINGS_HELPER_PKG_ID, ensureNetworkSpeed, helpers} from './helpers';
|
|
25
|
+
import {newMethodMap} from './method-map';
|
|
14
26
|
|
|
15
27
|
const APP_EXTENSION = '.apk';
|
|
16
28
|
const DEVICE_PORT = 4724;
|
|
17
29
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
30
|
+
/**
|
|
31
|
+
* This is a set of methods and paths that we never want to proxy to
|
|
32
|
+
* Chromedriver
|
|
33
|
+
**/
|
|
34
|
+
const NO_PROXY: RouteMatcher[] = [
|
|
21
35
|
['POST', new RegExp('^/session/[^/]+/context')],
|
|
22
36
|
['GET', new RegExp('^/session/[^/]+/context')],
|
|
23
37
|
['POST', new RegExp('^/session/[^/]+/appium')],
|
|
@@ -30,67 +44,57 @@ const NO_PROXY = /** @type {import('@appium/types').RouteMatcher[]} */ ([
|
|
|
30
44
|
['POST', new RegExp('^/session/[^/]+/execute/sync')],
|
|
31
45
|
['GET', new RegExp('^/session/[^/]+/network_connection')],
|
|
32
46
|
['POST', new RegExp('^/session/[^/]+/network_connection')],
|
|
33
|
-
]
|
|
47
|
+
];
|
|
34
48
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
* @typedef {typeof desiredConstraints} AndroidDriverConstraints
|
|
39
|
-
*/
|
|
49
|
+
export type AndroidDriverCaps = DriverCaps<AndroidDriverConstraints>;
|
|
50
|
+
export type W3CAndroidDriverCaps = W3CDriverCaps<AndroidDriverConstraints>;
|
|
51
|
+
export type AndroidDriverOpts = DriverOpts<AndroidDriverConstraints>;
|
|
40
52
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
53
|
+
export interface AndroidSettings {
|
|
54
|
+
ignoreUnimportantViews: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type AndroidDriverCreateResult = [string, AndroidDriverCaps];
|
|
58
|
+
type AndroidExternalDriver = ExternalDriver<AndroidDriverConstraints>;
|
|
59
|
+
class AndroidDriver<
|
|
60
|
+
Settings extends AndroidSettings = AndroidSettings,
|
|
61
|
+
CreateResult = AndroidDriverCreateResult
|
|
62
|
+
>
|
|
63
|
+
extends BaseDriver<AndroidDriverConstraints, StringRecord, Settings, CreateResult>
|
|
64
|
+
implements ExternalDriver<AndroidDriverConstraints, string, StringRecord, Settings, CreateResult>
|
|
65
|
+
{
|
|
46
66
|
static newMethodMap = newMethodMap;
|
|
67
|
+
jwpProxyAvoid: RouteMatcher[];
|
|
47
68
|
|
|
48
|
-
|
|
49
|
-
* @type {typeof NO_PROXY}
|
|
50
|
-
*/
|
|
51
|
-
jwpProxyAvoid;
|
|
69
|
+
bootstrap?: AndroidBootstrap;
|
|
52
70
|
|
|
53
|
-
|
|
54
|
-
* @type {import('./bootstrap').AndroidBootstrap | undefined}
|
|
55
|
-
*/
|
|
56
|
-
bootstrap;
|
|
71
|
+
adb?: ADB;
|
|
57
72
|
|
|
58
|
-
|
|
59
|
-
adb;
|
|
73
|
+
unlocker: typeof helpers.unlocker;
|
|
60
74
|
|
|
61
|
-
|
|
62
|
-
unlocker;
|
|
75
|
+
apkStrings: StringRecord<StringRecord<string>>;
|
|
63
76
|
|
|
64
|
-
|
|
65
|
-
apkStrings;
|
|
77
|
+
proxyReqRes?: (...args: any) => any;
|
|
66
78
|
|
|
67
|
-
|
|
68
|
-
* @type {((...args: any) => any) | undefined}
|
|
69
|
-
*/
|
|
70
|
-
proxyReqRes;
|
|
79
|
+
contexts?: string[];
|
|
71
80
|
|
|
72
|
-
|
|
73
|
-
* @type {string[]|undefined}
|
|
74
|
-
*/
|
|
75
|
-
contexts;
|
|
81
|
+
sessionChromedrivers: StringRecord<AppiumChromedriver>;
|
|
76
82
|
|
|
77
|
-
|
|
78
|
-
sessionChromedrivers;
|
|
83
|
+
chromedriver?: AppiumChromedriver;
|
|
79
84
|
|
|
80
|
-
|
|
81
|
-
|
|
85
|
+
proxyCommand?: AndroidExternalDriver['proxyCommand'];
|
|
86
|
+
jwpProxyActive: boolean;
|
|
87
|
+
curContext: string;
|
|
82
88
|
|
|
83
|
-
|
|
84
|
-
* @type {AndroidExternalDriver['proxyCommand']|undefined}
|
|
85
|
-
*/
|
|
86
|
-
proxyCommand;
|
|
89
|
+
useUnlockHelperApp?: boolean;
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
defaultIME?: string;
|
|
92
|
+
|
|
93
|
+
_wasWindowAnimationDisabled?: boolean;
|
|
94
|
+
|
|
95
|
+
opts: AndroidDriverOpts;
|
|
96
|
+
|
|
97
|
+
constructor(opts: InitialOpts = {} as InitialOpts, shouldValidateCaps = true) {
|
|
94
98
|
super(opts, shouldValidateCaps);
|
|
95
99
|
|
|
96
100
|
this.locatorStrategies = [
|
|
@@ -100,37 +104,39 @@ class AndroidDriver extends BaseDriver {
|
|
|
100
104
|
'accessibility id',
|
|
101
105
|
'-android uiautomator',
|
|
102
106
|
];
|
|
103
|
-
this.desiredCapConstraints =
|
|
107
|
+
this.desiredCapConstraints = _.cloneDeep(ANDROID_DRIVER_CONSTRAINTS);
|
|
104
108
|
this.sessionChromedrivers = {};
|
|
105
109
|
this.jwpProxyActive = false;
|
|
106
110
|
this.jwpProxyAvoid = _.clone(NO_PROXY);
|
|
107
111
|
this.settings = new DeviceSettings(
|
|
108
|
-
{ignoreUnimportantViews: false},
|
|
112
|
+
{ignoreUnimportantViews: false} as Settings,
|
|
109
113
|
this.onSettingsUpdate.bind(this)
|
|
110
114
|
);
|
|
111
|
-
this.chromedriver = null;
|
|
112
115
|
this.apkStrings = {};
|
|
113
116
|
this.unlocker = helpers.unlocker;
|
|
114
117
|
|
|
115
118
|
this.curContext = this.defaultContextName();
|
|
119
|
+
this.opts = opts as AndroidDriverOpts;
|
|
116
120
|
}
|
|
117
121
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
* @returns {Promise<[string, AndroidDriverCaps]>}
|
|
125
|
-
*/
|
|
126
|
-
async createSession(w3cCaps1, w3cCaps2, w3cCaps3, driverData) {
|
|
122
|
+
async createSession(
|
|
123
|
+
w3cCaps1: W3CAndroidDriverCaps,
|
|
124
|
+
w3cCaps2?: W3CAndroidDriverCaps,
|
|
125
|
+
w3cCaps3?: W3CAndroidDriverCaps,
|
|
126
|
+
driverData?: DriverData[]
|
|
127
|
+
): Promise<CreateResult> {
|
|
127
128
|
// the whole createSession flow is surrounded in a try-catch statement
|
|
128
129
|
// if creating a session fails at any point, we teardown everything we
|
|
129
130
|
// set up before throwing the error.
|
|
130
131
|
try {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
const [sessionId, caps] = (await super.createSession(
|
|
133
|
+
w3cCaps1,
|
|
134
|
+
w3cCaps2,
|
|
135
|
+
w3cCaps3,
|
|
136
|
+
driverData
|
|
137
|
+
)) as DefaultCreateSessionResult<AndroidDriverConstraints>;
|
|
138
|
+
|
|
139
|
+
const serverDetails = {
|
|
134
140
|
platform: 'LINUX',
|
|
135
141
|
webStorageEnabled: false,
|
|
136
142
|
takesScreenshot: true,
|
|
@@ -145,7 +151,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
145
151
|
this.caps = Object.assign(serverDetails, this.caps);
|
|
146
152
|
|
|
147
153
|
// assigning defaults
|
|
148
|
-
|
|
154
|
+
const defaultOpts = {
|
|
149
155
|
action: 'android.intent.action.MAIN',
|
|
150
156
|
category: 'android.intent.category.LAUNCHER',
|
|
151
157
|
flags: '0x10200000',
|
|
@@ -157,18 +163,10 @@ class AndroidDriver extends BaseDriver {
|
|
|
157
163
|
bootstrapPort: DEVICE_PORT,
|
|
158
164
|
androidInstallTimeout: 90000,
|
|
159
165
|
};
|
|
160
|
-
_.defaults(this.opts, defaultOpts);
|
|
161
|
-
this.useUnlockHelperApp = _.isUndefined(this.caps.unlockType);
|
|
162
166
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
if (this.opts.fullReset === true) {
|
|
168
|
-
this.opts.noReset = false;
|
|
169
|
-
}
|
|
170
|
-
this.opts.fastReset = !this.opts.fullReset && !this.opts.noReset;
|
|
171
|
-
this.opts.skipUninstall = this.opts.fastReset || this.opts.noReset;
|
|
167
|
+
this.opts = {...defaultOpts, ...this.opts};
|
|
168
|
+
|
|
169
|
+
this.useUnlockHelperApp = _.isUndefined(this.caps.unlockType);
|
|
172
170
|
|
|
173
171
|
if (this.isChromeSession) {
|
|
174
172
|
helpers.adjustBrowserSessionCaps(this.opts);
|
|
@@ -184,7 +182,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
184
182
|
}
|
|
185
183
|
|
|
186
184
|
// get device udid for this session
|
|
187
|
-
|
|
185
|
+
const {udid, emPort} = await helpers.getDeviceInfoFromCaps(this.opts);
|
|
188
186
|
this.opts.udid = udid;
|
|
189
187
|
// @ts-expect-error do not put arbitrary properties on opts
|
|
190
188
|
this.opts.emPort = emPort;
|
|
@@ -192,7 +190,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
192
190
|
// set up an instance of ADB
|
|
193
191
|
this.adb = await helpers.createADB({
|
|
194
192
|
udid: this.opts.udid,
|
|
195
|
-
// @ts-expect-error
|
|
193
|
+
// @ts-expect-error: unknown
|
|
196
194
|
emPort: this.opts.emPort,
|
|
197
195
|
adbPort: this.opts.adbPort,
|
|
198
196
|
suppressKillServer: this.opts.suppressKillServer,
|
|
@@ -255,7 +253,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
255
253
|
}
|
|
256
254
|
|
|
257
255
|
await this.startAndroidSession(this.opts);
|
|
258
|
-
return [sessionId, this.caps];
|
|
256
|
+
return [sessionId, this.caps] as CreateResult;
|
|
259
257
|
} catch (e) {
|
|
260
258
|
// ignoring delete session exception if any and throw the real error
|
|
261
259
|
// that happened while creating the session.
|
|
@@ -270,11 +268,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
270
268
|
return helpers.isEmulator(this.adb, this.opts);
|
|
271
269
|
}
|
|
272
270
|
|
|
273
|
-
|
|
274
|
-
*
|
|
275
|
-
* @param {AndroidDriverCaps} caps
|
|
276
|
-
*/
|
|
277
|
-
setAvdFromCapabilities(caps) {
|
|
271
|
+
setAvdFromCapabilities(caps: AndroidDriverCaps) {
|
|
278
272
|
if (this.opts.avd) {
|
|
279
273
|
this.log.info('avd name defined, ignoring device name and platform version');
|
|
280
274
|
} else {
|
|
@@ -282,13 +276,15 @@ class AndroidDriver extends BaseDriver {
|
|
|
282
276
|
this.log.errorAndThrow(
|
|
283
277
|
'avd or deviceName should be specified when reboot option is enables'
|
|
284
278
|
);
|
|
279
|
+
throw new Error(); // unreachable
|
|
285
280
|
}
|
|
286
281
|
if (!caps.platformVersion) {
|
|
287
282
|
this.log.errorAndThrow(
|
|
288
283
|
'avd or platformVersion should be specified when reboot option is enabled'
|
|
289
284
|
);
|
|
285
|
+
throw new Error(); // unreachable
|
|
290
286
|
}
|
|
291
|
-
|
|
287
|
+
const avdDevice = caps.deviceName.replace(/[^a-zA-Z0-9_.]/g, '-');
|
|
292
288
|
this.opts.avd = `${avdDevice}__${caps.platformVersion}`;
|
|
293
289
|
}
|
|
294
290
|
}
|
|
@@ -303,36 +299,27 @@ class AndroidDriver extends BaseDriver {
|
|
|
303
299
|
}
|
|
304
300
|
|
|
305
301
|
get isChromeSession() {
|
|
306
|
-
return helpers.isChromeBrowser(this.opts.browserName);
|
|
302
|
+
return helpers.isChromeBrowser(String(this.opts.browserName));
|
|
307
303
|
}
|
|
308
304
|
|
|
309
|
-
|
|
310
|
-
*
|
|
311
|
-
* @param {string} key
|
|
312
|
-
* @param {any} value
|
|
313
|
-
*/
|
|
314
|
-
async onSettingsUpdate(key, value) {
|
|
305
|
+
async onSettingsUpdate(key: keyof Settings, value: any) {
|
|
315
306
|
if (key === 'ignoreUnimportantViews') {
|
|
316
307
|
await this.setCompressedLayoutHierarchy(value);
|
|
317
308
|
}
|
|
318
309
|
}
|
|
319
310
|
|
|
320
|
-
/**
|
|
321
|
-
*
|
|
322
|
-
* @param {AndroidDriverOpts} [opts]
|
|
323
|
-
*/
|
|
324
311
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
325
|
-
async startAndroidSession(opts) {
|
|
312
|
+
async startAndroidSession(opts: AndroidDriverOpts) {
|
|
326
313
|
this.log.info(`Starting Android session`);
|
|
327
|
-
|
|
314
|
+
|
|
328
315
|
// set up the device to run on (real or emulator, etc)
|
|
329
|
-
this.defaultIME = await helpers.initDevice(adb
|
|
316
|
+
this.defaultIME = (await helpers.initDevice(this.adb!, this.opts)) as string;
|
|
330
317
|
|
|
331
318
|
// set actual device name, udid, platform version, screen size, model and manufacturer details.
|
|
332
|
-
this.caps.deviceName =
|
|
319
|
+
this.caps.deviceName = this.adb!.curDeviceId as string;
|
|
333
320
|
// @ts-expect-error do not put arbitrary properties on caps
|
|
334
321
|
this.caps.deviceUDID = this.opts.udid;
|
|
335
|
-
this.caps.platformVersion = await adb
|
|
322
|
+
this.caps.platformVersion = await this.adb!.getPlatformVersion();
|
|
336
323
|
// @ts-expect-error do not put arbitrary properties on caps
|
|
337
324
|
this.caps.deviceScreenSize = await this.adb.getScreenSize();
|
|
338
325
|
// @ts-expect-error do not put arbitrary properties on caps
|
|
@@ -341,18 +328,18 @@ class AndroidDriver extends BaseDriver {
|
|
|
341
328
|
this.caps.deviceManufacturer = await this.adb.getManufacturer();
|
|
342
329
|
|
|
343
330
|
if (this.opts.disableWindowAnimation) {
|
|
344
|
-
if (await adb
|
|
345
|
-
if ((await adb
|
|
331
|
+
if (await this.adb!.isAnimationOn()) {
|
|
332
|
+
if ((await this.adb!.getApiLevel()) >= 28) {
|
|
346
333
|
// API level 28 is Android P
|
|
347
334
|
// Don't forget to reset the relaxing in delete session
|
|
348
335
|
this.log.warn('Relaxing hidden api policy to manage animation scale');
|
|
349
|
-
await adb
|
|
336
|
+
await this.adb!.setHiddenApiPolicy('1', !!this.opts.ignoreHiddenApiPolicyError);
|
|
350
337
|
}
|
|
351
338
|
|
|
352
339
|
this.log.info(
|
|
353
340
|
'Disabling window animation as it is requested by "disableWindowAnimation" capability'
|
|
354
341
|
);
|
|
355
|
-
await adb
|
|
342
|
+
await this.adb!.setAnimationState(false);
|
|
356
343
|
this._wasWindowAnimationDisabled = true;
|
|
357
344
|
} else {
|
|
358
345
|
this.log.info('Window animation is already disabled');
|
|
@@ -364,7 +351,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
364
351
|
|
|
365
352
|
// start UiAutomator
|
|
366
353
|
const bootstrap = (this.bootstrap = new helpers.bootstrap(
|
|
367
|
-
adb
|
|
354
|
+
this.adb!,
|
|
368
355
|
this.opts.bootstrapPort,
|
|
369
356
|
// @ts-expect-error do not put arbitrary properties on opts
|
|
370
357
|
this.opts.websocket
|
|
@@ -380,7 +367,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
380
367
|
await bootstrap.onUnexpectedShutdown;
|
|
381
368
|
} catch (err) {
|
|
382
369
|
if (!bootstrap.ignoreUnexpectedShutdown) {
|
|
383
|
-
await this.startUnexpectedShutdown(
|
|
370
|
+
await this.startUnexpectedShutdown(err as Error);
|
|
384
371
|
}
|
|
385
372
|
}
|
|
386
373
|
})();
|
|
@@ -392,13 +379,15 @@ class AndroidDriver extends BaseDriver {
|
|
|
392
379
|
'Checking for lockscreen presence. ' +
|
|
393
380
|
`This could be skipped by setting the 'appium:skipUnlock' capability to true.`
|
|
394
381
|
);
|
|
395
|
-
await helpers.unlock(this, adb
|
|
382
|
+
await helpers.unlock(this as any, this.adb!, this.caps);
|
|
396
383
|
}
|
|
397
384
|
|
|
398
385
|
// Set CompressedLayoutHierarchy on the device based on current settings object
|
|
399
386
|
// this has to happen _after_ bootstrap is initialized
|
|
400
387
|
if (this.opts.ignoreUnimportantViews) {
|
|
401
|
-
await this.settings.update({
|
|
388
|
+
await this.settings.update({
|
|
389
|
+
ignoreUnimportantViews: this.opts.ignoreUnimportantViews,
|
|
390
|
+
} as Settings);
|
|
402
391
|
}
|
|
403
392
|
|
|
404
393
|
if (this.isChromeSession) {
|
|
@@ -422,8 +411,8 @@ class AndroidDriver extends BaseDriver {
|
|
|
422
411
|
|
|
423
412
|
async initAutoWebview() {
|
|
424
413
|
if (this.opts.autoWebview) {
|
|
425
|
-
|
|
426
|
-
|
|
414
|
+
const viewName = this.defaultWebviewName();
|
|
415
|
+
const timeout = this.opts.autoWebviewTimeout || 2000;
|
|
427
416
|
|
|
428
417
|
this.log.info(`Setting auto webview to context '${viewName}' with timeout ${timeout}ms`);
|
|
429
418
|
|
|
@@ -435,11 +424,10 @@ class AndroidDriver extends BaseDriver {
|
|
|
435
424
|
}
|
|
436
425
|
|
|
437
426
|
async initAUT() {
|
|
438
|
-
const adb = /** @type {ADB} */ (this.adb);
|
|
439
427
|
// populate appPackage, appActivity, appWaitPackage, appWaitActivity,
|
|
440
428
|
// and the device being used
|
|
441
429
|
// in the opts and caps (so it gets back to the user on session creation)
|
|
442
|
-
|
|
430
|
+
const launchInfo = await helpers.getLaunchInfo(this.adb!, this.opts);
|
|
443
431
|
Object.assign(this.opts, launchInfo);
|
|
444
432
|
Object.assign(this.caps, launchInfo);
|
|
445
433
|
|
|
@@ -448,7 +436,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
448
436
|
helpers.validateDesiredCaps(this.opts);
|
|
449
437
|
// Only SETTINGS_HELPER_PKG_ID package is used by UIA1
|
|
450
438
|
await helpers.uninstallOtherPackages(
|
|
451
|
-
adb
|
|
439
|
+
this.adb!,
|
|
452
440
|
helpers.parseArray(this.opts.uninstallOtherPackages),
|
|
453
441
|
[SETTINGS_HELPER_PKG_ID]
|
|
454
442
|
);
|
|
@@ -457,19 +445,17 @@ class AndroidDriver extends BaseDriver {
|
|
|
457
445
|
// Install any "otherApps" that were specified in caps
|
|
458
446
|
if (this.opts.otherApps) {
|
|
459
447
|
/** @type {string[]} */
|
|
460
|
-
let otherApps;
|
|
448
|
+
let otherApps: string[];
|
|
461
449
|
try {
|
|
462
450
|
otherApps = helpers.parseArray(this.opts.otherApps);
|
|
463
451
|
} catch (e) {
|
|
464
|
-
this.log.errorAndThrow(
|
|
465
|
-
`Could not parse "otherApps" capability: ${/** @type {Error} */ (e).message}`
|
|
466
|
-
);
|
|
452
|
+
this.log.errorAndThrow(`Could not parse "otherApps" capability: ${(e as Error).message}`);
|
|
467
453
|
return; // unreachable
|
|
468
454
|
}
|
|
469
455
|
otherApps = await B.all(
|
|
470
456
|
otherApps.map((app) => this.helpers.configureApp(app, APP_EXTENSION))
|
|
471
457
|
);
|
|
472
|
-
await helpers.installOtherApks(otherApps, adb
|
|
458
|
+
await helpers.installOtherApks(otherApps, this.adb!, this.opts);
|
|
473
459
|
}
|
|
474
460
|
|
|
475
461
|
// install app
|
|
@@ -481,17 +467,17 @@ class AndroidDriver extends BaseDriver {
|
|
|
481
467
|
}
|
|
482
468
|
this.log.debug('No app capability. Assuming it is already on the device');
|
|
483
469
|
if (this.opts.fastReset) {
|
|
484
|
-
await helpers.resetApp(adb
|
|
470
|
+
await helpers.resetApp(this.adb!, this.opts);
|
|
485
471
|
}
|
|
486
472
|
return;
|
|
487
473
|
}
|
|
488
474
|
if (!this.opts.skipUninstall) {
|
|
489
|
-
await adb
|
|
475
|
+
await this.adb!.uninstallApk(this.opts.appPackage!);
|
|
490
476
|
}
|
|
491
|
-
await helpers.installApk(adb
|
|
477
|
+
await helpers.installApk(this.adb!, this.opts);
|
|
492
478
|
const apkStringsForLanguage = await helpers.pushStrings(
|
|
493
479
|
this.opts.language,
|
|
494
|
-
|
|
480
|
+
this.adb!,
|
|
495
481
|
this.opts
|
|
496
482
|
);
|
|
497
483
|
if (this.opts.language) {
|
|
@@ -515,29 +501,17 @@ class AndroidDriver extends BaseDriver {
|
|
|
515
501
|
|
|
516
502
|
async checkPackagePresent() {
|
|
517
503
|
this.log.debug('Checking whether package is present on the device');
|
|
518
|
-
if (
|
|
519
|
-
!(await /** @type {ADB} */ (this.adb).shell([
|
|
520
|
-
'pm',
|
|
521
|
-
'list',
|
|
522
|
-
'packages',
|
|
523
|
-
String(this.opts.appPackage),
|
|
524
|
-
]))
|
|
525
|
-
) {
|
|
504
|
+
if (!(await this.adb!.shell(['pm', 'list', 'packages', String(this.opts.appPackage)]))) {
|
|
526
505
|
this.log.errorAndThrow(`Could not find package ${this.opts.appPackage} on the device`);
|
|
527
506
|
}
|
|
528
507
|
}
|
|
529
508
|
|
|
530
|
-
// Set CompressedLayoutHierarchy on the device
|
|
531
509
|
/**
|
|
532
|
-
*
|
|
533
|
-
* @param
|
|
534
|
-
* @privateRemarks FIXME: unknown type
|
|
510
|
+
* Set CompressedLayoutHierarchy on the device
|
|
511
|
+
* @privateRemarks FIXME: unknown param type
|
|
535
512
|
*/
|
|
536
|
-
async setCompressedLayoutHierarchy(compress) {
|
|
537
|
-
await
|
|
538
|
-
'compressedLayoutHierarchy',
|
|
539
|
-
{compressLayout: compress}
|
|
540
|
-
);
|
|
513
|
+
async setCompressedLayoutHierarchy(compress: any) {
|
|
514
|
+
await this.bootstrap!.sendAction('compressedLayoutHierarchy', {compressLayout: compress});
|
|
541
515
|
}
|
|
542
516
|
|
|
543
517
|
async deleteSession() {
|
|
@@ -549,10 +523,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
549
523
|
}
|
|
550
524
|
} catch (ign) {}
|
|
551
525
|
|
|
552
|
-
await helpers.removeAllSessionWebSocketHandlers(
|
|
553
|
-
/** @type {import('@appium/types').AppiumServer} */ (this.server),
|
|
554
|
-
/** @type {string} */ (this.sessionId)
|
|
555
|
-
);
|
|
526
|
+
await helpers.removeAllSessionWebSocketHandlers(this.server!, this.sessionId!);
|
|
556
527
|
|
|
557
528
|
await this.mobileStopScreenStreaming();
|
|
558
529
|
|
|
@@ -566,11 +537,11 @@ class AndroidDriver extends BaseDriver {
|
|
|
566
537
|
await this.adb?.setIME(this.defaultIME);
|
|
567
538
|
}
|
|
568
539
|
if (!this.isChromeSession && !this.opts.dontStopAppOnReset) {
|
|
569
|
-
await this.adb?.forceStop(
|
|
540
|
+
await this.adb?.forceStop(this.opts.appPackage!);
|
|
570
541
|
}
|
|
571
542
|
await this.adb?.goToHome();
|
|
572
543
|
if (this.opts.fullReset && !this.opts.skipUninstall && !this.appOnDevice) {
|
|
573
|
-
await this.adb?.uninstallApk(
|
|
544
|
+
await this.adb?.uninstallApk(this.opts.appPackage!);
|
|
574
545
|
}
|
|
575
546
|
await this.bootstrap.shutdown();
|
|
576
547
|
this.bootstrap = undefined;
|
|
@@ -597,7 +568,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
597
568
|
// @ts-expect-error do not put arbitrary properties on opts
|
|
598
569
|
if (this.opts.reboot) {
|
|
599
570
|
// @ts-expect-error do not put arbitrary properties on opts
|
|
600
|
-
|
|
571
|
+
const avdName = this.opts.avd.replace('@', '');
|
|
601
572
|
this.log.debug(`closing emulator '${avdName}'`);
|
|
602
573
|
await this.adb?.killEmulator(avdName);
|
|
603
574
|
}
|
|
@@ -608,28 +579,28 @@ class AndroidDriver extends BaseDriver {
|
|
|
608
579
|
* @param {AndroidDriverOpts} [opts]
|
|
609
580
|
*/
|
|
610
581
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
611
|
-
async setSharedPreferences(opts) {
|
|
612
|
-
|
|
582
|
+
async setSharedPreferences(opts: AndroidDriverOpts) {
|
|
583
|
+
const sharedPrefs = this.opts.sharedPreferences!;
|
|
613
584
|
this.log.info('Trying to set shared preferences');
|
|
614
|
-
|
|
585
|
+
const name = sharedPrefs.name;
|
|
615
586
|
if (_.isUndefined(name)) {
|
|
616
587
|
this.log.warn(
|
|
617
588
|
`Skipping setting Shared preferences, name is undefined: ${JSON.stringify(sharedPrefs)}`
|
|
618
589
|
);
|
|
619
590
|
return false;
|
|
620
591
|
}
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
592
|
+
const remotePath = `/data/data/${this.opts.appPackage}/shared_prefs`;
|
|
593
|
+
const remoteFile = `${remotePath}/${name}.xml`;
|
|
594
|
+
const localPath = `/tmp/${name}.xml`;
|
|
595
|
+
const builder = this.getPrefsBuilder();
|
|
625
596
|
builder.build(sharedPrefs.prefs);
|
|
626
597
|
this.log.info(`Creating temporary shared preferences: ${localPath}`);
|
|
627
598
|
builder.toFile(localPath);
|
|
628
599
|
this.log.info(`Creating shared_prefs remote folder: ${remotePath}`);
|
|
629
|
-
|
|
630
|
-
await adb
|
|
600
|
+
|
|
601
|
+
await this.adb!.shell(['mkdir', '-p', remotePath]);
|
|
631
602
|
this.log.info(`Pushing shared_prefs to ${remoteFile}`);
|
|
632
|
-
await adb
|
|
603
|
+
await this.adb!.push(localPath, remoteFile);
|
|
633
604
|
try {
|
|
634
605
|
this.log.info(`Trying to remove shared preferences temporary file`);
|
|
635
606
|
if (await fs.exists(localPath)) {
|
|
@@ -653,7 +624,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
653
624
|
* @param {any} caps
|
|
654
625
|
* @returns {caps is AndroidDriverCaps}
|
|
655
626
|
*/
|
|
656
|
-
validateDesiredCaps(caps) {
|
|
627
|
+
validateDesiredCaps(caps: any): caps is AndroidDriverCaps {
|
|
657
628
|
if (!super.validateDesiredCaps(caps)) {
|
|
658
629
|
return false;
|
|
659
630
|
}
|
|
@@ -673,7 +644,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
673
644
|
*
|
|
674
645
|
* @param {string} sessionId
|
|
675
646
|
*/
|
|
676
|
-
proxyActive(sessionId) {
|
|
647
|
+
proxyActive(sessionId: string) {
|
|
677
648
|
super.proxyActive(sessionId);
|
|
678
649
|
|
|
679
650
|
return this.jwpProxyActive;
|
|
@@ -683,7 +654,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
683
654
|
*
|
|
684
655
|
* @param {string} sessionId
|
|
685
656
|
*/
|
|
686
|
-
getProxyAvoidList(sessionId) {
|
|
657
|
+
getProxyAvoidList(sessionId: string) {
|
|
687
658
|
super.getProxyAvoidList(sessionId);
|
|
688
659
|
|
|
689
660
|
return this.jwpProxyAvoid;
|
|
@@ -693,7 +664,7 @@ class AndroidDriver extends BaseDriver {
|
|
|
693
664
|
*
|
|
694
665
|
* @param {string} sessionId
|
|
695
666
|
*/
|
|
696
|
-
canProxy(sessionId) {
|
|
667
|
+
canProxy(sessionId: string) {
|
|
697
668
|
super.canProxy(sessionId);
|
|
698
669
|
|
|
699
670
|
// this will change depending on ChromeDriver status
|
|
@@ -701,16 +672,5 @@ class AndroidDriver extends BaseDriver {
|
|
|
701
672
|
}
|
|
702
673
|
}
|
|
703
674
|
|
|
704
|
-
export {AndroidDriver};
|
|
705
675
|
export {commands as androidCommands} from './commands';
|
|
706
|
-
|
|
707
|
-
/**
|
|
708
|
-
* @typedef {import('@appium/types').ExternalDriver<AndroidDriverConstraints>} AndroidExternalDriver
|
|
709
|
-
* @typedef {import('@appium/types').DriverOpts<AndroidDriverConstraints>} AndroidDriverOpts
|
|
710
|
-
* @typedef {import('appium-adb').ADB} ADB
|
|
711
|
-
*/
|
|
712
|
-
|
|
713
|
-
/**
|
|
714
|
-
* @template [T=any]
|
|
715
|
-
* @typedef {import('@appium/types').StringRecord<T>} StringRecord
|
|
716
|
-
*/
|
|
676
|
+
export {AndroidDriver};
|