Skip to content

Commit bdcce0b

Browse files
chore: Improve type declarations (#925)
1 parent be7ba46 commit bdcce0b

File tree

4 files changed

+65
-107
lines changed

4 files changed

+65
-107
lines changed

lib/commands/general.js

+4-17
Original file line numberDiff line numberDiff line change
@@ -122,22 +122,12 @@ commands.mobileBackgroundApp = async function mobileBackgroundApp (opts = {}) {
122122
return await this.background(seconds);
123123
};
124124

125-
/**
126-
* @typedef {Object} DeviceInfo
127-
* @property {string} apiVersion
128-
* @property {string} platformVersion
129-
* @property {string} manufacturer
130-
* @property {string} model
131-
* @property {string} realDisplaySize
132-
* @property {string} displayDensity
133-
*/
134-
135125
/**
136126
* @this {import('../driver').EspressoDriver}
137-
* @returns {Promise<DeviceInfo>}
127+
* @returns {Promise<import('../types').DeviceInfo>}
138128
*/
139129
commands.mobileGetDeviceInfo = async function mobileGetDeviceInfo () {
140-
return /** @type {DeviceInfo} */ (await this.espresso.jwproxy.command('/appium/device/info', 'GET'));
130+
return /** @type {import('../types').DeviceInfo} */ (await this.espresso.jwproxy.command('/appium/device/info', 'GET'));
141131
};
142132

143133
/**
@@ -473,11 +463,8 @@ commands.startActivity = async function startActivity (
473463
) {
474464
// intentAction, intentCategory, intentFlags, optionalIntentArguments, dontStopAppOnReset
475465
// parameters are not supported by Espresso
476-
/** @type {string} */
477-
// @ts-ignore This should always be defined
478-
const pkg = appPackage || this.caps.appPackage;
479-
/** @type {string} */
480-
const appWaitPkg = appWaitPackage || pkg;
466+
const pkg = /** @type {string} */ (appPackage || this.caps.appPackage);
467+
const appWaitPkg = /** @type {string} */ (appWaitPackage || pkg);
481468
const appAct = qualifyActivityName(appActivity, pkg);
482469
const appWaitAct = qualifyActivityName(appWaitActivity || appAct, appWaitPkg);
483470
this.log.debug(`Starting activity '${appActivity}' for package '${appPackage}'`);

lib/desired-caps.js lib/constraints.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { commonCapConstraints } from 'appium-android-driver';
1+
import {Constraints} from '@appium/types';
2+
import {commonCapConstraints} from 'appium-android-driver';
23

3-
const espressoCapConstraints = {
4+
export const ESPRESSO_CONSTRAINTS = {
45
systemPort: {
56
isNumber: true
67
},
@@ -34,9 +35,7 @@ const espressoCapConstraints = {
3435
appLocale: {
3536
isObject: true,
3637
},
37-
};
38-
39-
export const desiredCapConstraints = {
4038
...commonCapConstraints,
41-
...espressoCapConstraints,
42-
};
39+
} as const satisfies Constraints;
40+
41+
export type EspressoConstraints = typeof ESPRESSO_CONSTRAINTS;

lib/driver.js

+28-83
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { DEFAULT_ADB_PORT } from 'appium-adb';
1313
import {
1414
androidHelpers, SETTINGS_HELPER_PKG_ID, AndroidDriver
1515
} from 'appium-android-driver';
16-
import { desiredCapConstraints } from './desired-caps';
16+
import { ESPRESSO_CONSTRAINTS } from './constraints';
1717
import { findAPortNotInUse } from 'portscanner';
1818
import { retryInterval } from 'asyncbox';
1919
import { qualifyActivityName, getPackageInfo } from './utils';
@@ -133,8 +133,21 @@ const APK_EXT = '.apk';
133133
const AAB_EXT = '.aab';
134134
const SUPPORTED_EXTENSIONS = [APK_EXT, AAB_EXT];
135135

136+
/**
137+
* @satisfies {import('@appium/types').ExternalDriver<
138+
* import('./constraints').EspressoConstraints,
139+
* string,
140+
* import('@appium/types').StringRecord
141+
* >}
142+
*/
136143
class EspressoDriver extends AndroidDriver {
137144

145+
/** @type {import('./types').EspressoDriverOpts} */
146+
opts;
147+
148+
/** @type {import('./types').EspressoDriverCaps} */
149+
caps;
150+
138151
/** @type {EspressoRunner} */
139152
espresso;
140153

@@ -144,22 +157,21 @@ class EspressoDriver extends AndroidDriver {
144157
// `shell` overwrites adb.shell, so remove
145158
delete opts.shell;
146159

147-
// @ts-ignore Options are ok
148-
super(opts, shouldValidateCaps);
160+
super(/** @type {import('@appium/types').InitialOpts} */ (opts), shouldValidateCaps);
149161
this.locatorStrategies = [
150162
'id',
151163
'class name',
152164
'accessibility id',
153165
];
154-
this.desiredCapConstraints = desiredCapConstraints;
166+
this.desiredCapConstraints = ESPRESSO_CONSTRAINTS;
155167
this.jwpProxyAvoid = NO_PROXY;
156168

157169
this.settings = new DeviceSettings({}, this.onSettingsUpdate.bind(this));
158170

159-
this.chromedriver = null;
171+
this.chromedriver = undefined;
160172
}
161173

162-
// @ts-ignore it's ok
174+
// @ts-ignore it's ok to not care about exact args
163175
async createSession (...args) {
164176
try {
165177
// @ts-ignore it's ok to not care about exact args
@@ -200,24 +212,18 @@ class EspressoDriver extends AndroidDriver {
200212
}
201213
}
202214

203-
// @ts-ignore TODO: Make it typed
204-
if (this.opts.reboot) {
205-
this.setAvdFromCapabilities(caps);
206-
this.addWipeDataToAvdArgs();
207-
}
208-
209-
// @ts-ignore TODO: Make it typed
210215
this.opts.systemPort = this.opts.systemPort
211216
|| await findAPortNotInUse(SYSTEM_PORT_RANGE[0], SYSTEM_PORT_RANGE[1]);
212217
this.opts.adbPort = this.opts.adbPort || DEFAULT_ADB_PORT;
213218
// get device udid for this session
214219
const {udid, emPort} = await helpers.getDeviceInfoFromCaps(this.opts);
215220
this.opts.udid = udid;
216-
// @ts-ignore TODO: Make it typed
217-
this.opts.emPort = emPort;
218221
// now that we know our java version and device info, we can create our
219222
// ADB instance
220-
this.adb = await androidHelpers.createADB(this.opts);
223+
this.adb = await androidHelpers.createADB({
224+
...this.opts,
225+
emPort,
226+
});
221227

222228
if (this.opts.app) {
223229
// find and copy, or download and unzip an app url or path
@@ -295,7 +301,6 @@ class EspressoDriver extends AndroidDriver {
295301
const hasApkExt = (appPath) => _.endsWith(_.toLower(appPath), APK_EXT);
296302
const hasAabExt = (appPath) => _.endsWith(_.toLower(appPath), AAB_EXT);
297303
const extractUniversalApk = async (shouldExtract, appPath) =>
298-
// @ts-ignore extractUniversalApk is there
299304
shouldExtract ? appPath : await this.adb.extractUniversalApk(appPath);
300305

301306
let pathInCache = null;
@@ -353,32 +358,6 @@ class EspressoDriver extends AndroidDriver {
353358
return {};
354359
}
355360

356-
// TODO this method is duplicated from uiautomator2-driver; consolidate
357-
setAvdFromCapabilities (caps) {
358-
if (this.opts.avd) {
359-
this.log.info('avd name defined, ignoring device name and platform version');
360-
} else {
361-
if (!caps.deviceName) {
362-
this.log.errorAndThrow('avd or deviceName should be specified when reboot option is enables');
363-
}
364-
if (!caps.platformVersion) {
365-
this.log.errorAndThrow('avd or platformVersion should be specified when reboot option is enabled');
366-
}
367-
let avdDevice = caps.deviceName.replace(/[^a-zA-Z0-9_.]/g, '-');
368-
this.opts.avd = `${avdDevice}__${caps.platformVersion}`;
369-
}
370-
}
371-
372-
// TODO this method is duplicated from uiautomator2-driver; consolidate
373-
addWipeDataToAvdArgs () {
374-
if (!this.opts.avdArgs) {
375-
this.opts.avdArgs = '-wipe-data';
376-
// @ts-ignore This check will work
377-
} else if (!_.includes(this.opts.avdArgs, '-wipe-data')) {
378-
this.opts.avdArgs += ' -wipe-data';
379-
}
380-
}
381-
382361
// TODO much of this logic is duplicated from uiautomator2
383362
async startEspressoSession () {
384363
const {manifestPayload} = await getPackageInfo();
@@ -396,13 +375,11 @@ class EspressoDriver extends AndroidDriver {
396375
// and get it onto our 'opts' object so we use it from now on
397376
Object.assign(this.opts, appInfo);
398377
} else {
399-
// @ts-ignore This is ok
400378
appInfo = this.opts;
401379
}
402380

403381
// start an avd, set the language/locale, pick an emulator, etc...
404382
// TODO with multiple devices we'll need to parameterize this
405-
// @ts-ignore This is ok
406383
await helpers.initDevice(this.adb, this.opts);
407384

408385
// https://github.com/appium/appium-espresso-driver/issues/72
@@ -411,16 +388,13 @@ class EspressoDriver extends AndroidDriver {
411388

412389
// set actual device name, udid
413390
this.caps.deviceName = this.adb.curDeviceId;
414-
// @ts-ignore This is ok
415-
this.caps.deviceUDID = this.opts.udid;
391+
this.caps.deviceUDID = /** @type {string} */ (this.opts.udid);
416392

417393
// set up the modified espresso server etc
418394
this.initEspressoServer();
419395
// Further prepare the device by forwarding the espresso port
420-
// @ts-ignore TODO: Make the module to .ts
421396
this.log.debug(`Forwarding Espresso Server port ${DEVICE_PORT} to ${this.opts.systemPort}`);
422-
// @ts-ignore TODO: Make the module to .ts
423-
await this.adb.forwardPort(this.opts.systemPort, DEVICE_PORT);
397+
await this.adb.forwardPort(/** @type {number} */ (this.opts.systemPort), DEVICE_PORT);
424398

425399
if (!this.opts.skipUnlock) {
426400
// unlock the device to prepare it for testing
@@ -517,64 +491,45 @@ class EspressoDriver extends AndroidDriver {
517491
realDisplaySize,
518492
displayDensity,
519493
} = await this.mobileGetDeviceInfo();
520-
// @ts-ignore TODO: Make the module to .ts
521494
this.caps.deviceApiLevel = parseInt(apiVersion, 10);
522495
this.caps.platformVersion = platformVersion;
523-
// @ts-ignore TODO: Make the module to .ts
524496
this.caps.deviceScreenSize = realDisplaySize;
525-
// @ts-ignore TODO: Make the module to .ts
526497
this.caps.deviceScreenDensity = displayDensity;
527-
// @ts-ignore TODO: Make the module to .ts
528498
this.caps.deviceModel = model;
529-
// @ts-ignore TODO: Make the module to .ts
530499
this.caps.deviceManufacturer = manufacturer;
531500
}
532501

533502
initEspressoServer () {
534503
// now that we have package and activity, we can create an instance of
535504
// espresso with the appropriate data
536505
this.espresso = new EspressoRunner(this.log, {
537-
// @ts-ignore TODO: Make the module to .ts
506+
// @ts-ignore TODO: Is .host a legacy property?
538507
host: this.opts.remoteAdbHost || this.opts.host || '127.0.0.1',
539-
// @ts-ignore TODO: Make the module to .ts
540508
systemPort: this.opts.systemPort,
541509
devicePort: DEVICE_PORT,
542510
adb: this.adb,
543511
apk: this.opts.app,
544512
tmpDir: this.opts.tmpDir,
545513
appPackage: this.opts.appPackage,
546514
appActivity: this.opts.appActivity,
547-
// @ts-ignore TODO: Make the module to .ts
548515
forceEspressoRebuild: !!this.opts.forceEspressoRebuild,
549-
// @ts-ignore TODO: Make the module to .ts
550516
espressoBuildConfig: this.opts.espressoBuildConfig,
551-
// @ts-ignore TODO: Make the module to .ts
552517
showGradleLog: !!this.opts.showGradleLog,
553-
// @ts-ignore TODO: Make the module to .ts
554518
serverLaunchTimeout: this.opts.espressoServerLaunchTimeout,
555519
androidInstallTimeout: this.opts.androidInstallTimeout,
556-
// @ts-ignore TODO: Make the module to .ts
557520
skipServerInstallation: this.opts.skipServerInstallation,
558521
useKeystore: this.opts.useKeystore,
559522
keystorePath: this.opts.keystorePath,
560523
keystorePassword: this.opts.keystorePassword,
561524
keyAlias: this.opts.keyAlias,
562525
keyPassword: this.opts.keyPassword,
563-
// @ts-ignore TODO: Make the module to .ts
564526
disableSuppressAccessibilityService: this.opts.disableSuppressAccessibilityService,
565527
});
566528
this.proxyReqRes = this.espresso.proxyReqRes.bind(this.espresso);
567529
this.proxyCommand = this.espresso.proxyCommand.bind(this.espresso);
568530
}
569531

570-
// TODO this method is mostly duplicated from uiautomator2
571532
async initAUT () {
572-
// set the localized strings for the current language from the apk
573-
// TODO: incorporate changes from appium#5308 which fix a race cond-
574-
// ition bug in old appium and need to be replicated here
575-
// this.apkStrings[this.opts.language] = await androidHelpers.pushStrings(
576-
// this.opts.language, this.adb, this.opts);
577-
578533
// Uninstall any uninstallOtherPackages which were specified in caps
579534
if (this.opts.uninstallOtherPackages) {
580535
await helpers.uninstallOtherPackages(
@@ -600,7 +555,6 @@ class EspressoDriver extends AndroidDriver {
600555
if (this.opts.app) {
601556
await helpers.installApk(this.adb, this.opts);
602557
}
603-
// @ts-ignore TODO: Make the module to .ts
604558
if (this.opts.skipServerInstallation) {
605559
this.log.debug('skipServerInstallation capability is set. Not installig espresso-server ');
606560
} else {
@@ -665,22 +619,14 @@ class EspressoDriver extends AndroidDriver {
665619
await this.adb.uninstallApk(/** @type {string} */ (this.opts.appPackage));
666620
}
667621
await this.adb.stopLogcat();
668-
// @ts-ignore TODO: Make the module to .ts
669-
if (this.opts.reboot && this.opts.avd) {
670-
let avdName = this.opts.avd.replace('@', '');
671-
this.log.debug(`closing emulator '${avdName}'`);
672-
await this.adb.killEmulator(avdName);
673-
}
674622
if (await this.adb.getApiLevel() >= 28) { // Android P
675623
this.log.info('Restoring hidden api policy to the device default configuration');
676624
await this.adb.setDefaultHiddenApiPolicy(!!this.opts.ignoreHiddenApiPolicyError);
677625
}
678626
}
679627
await super.deleteSession();
680-
// @ts-ignore TODO: Make the module to .ts
681-
if (this.opts.systemPort !== undefined) {
628+
if (this.opts.systemPort) {
682629
try {
683-
// @ts-ignore TODO: Make the module to .ts
684630
await this.adb.removePortForward(this.opts.systemPort);
685631
} catch (error) {
686632
this.log.warn(`Unable to remove port forward '${error.message}'`);
@@ -723,8 +669,7 @@ class EspressoDriver extends AndroidDriver {
723669
}
724670

725671
get appOnDevice () {
726-
// @ts-ignore appPackage should always be defined
727-
return !this.opts.app && this.helpers.isPackageOrBundle(this.opts.appPackage);
672+
return !this.opts.app && this.helpers.isPackageOrBundle(/** @type {string} */ (this.opts.appPackage));
728673
}
729674

730675
/**
@@ -733,7 +678,7 @@ class EspressoDriver extends AndroidDriver {
733678
* @returns {void}
734679
*/
735680
suspendChromedriverProxy () {
736-
this.chromedriver = null;
681+
this.chromedriver = undefined;
737682
this.proxyReqRes = this.espresso.proxyReqRes.bind(this.espresso);
738683
this.proxyCommand = this.espresso.proxyCommand.bind(this.espresso);
739684
this.jwpProxyActive = true;

lib/types.ts

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type {DriverCaps, DriverOpts, W3CDriverCaps} from '@appium/types';
2+
import type {EspressoConstraints} from './constraints';
3+
4+
export type EspressoDriverOpts = DriverOpts<EspressoConstraints>;
5+
6+
export type W3CEspressoDriverCaps = W3CDriverCaps<EspressoConstraints>;
7+
8+
export interface DeviceInfo {
9+
apiVersion: string;
10+
platformVersion: string;
11+
manufacturer: string;
12+
model: string;
13+
realDisplaySize: string;
14+
displayDensity: number;
15+
}
16+
17+
export interface DeviceInfoCaps {
18+
deviceApiLevel: number;
19+
platformVersion: string;
20+
deviceScreenSize: string;
21+
deviceModel: string;
22+
deviceManufacturer: string;
23+
deviceScreenDensity: number;
24+
deviceUDID: string;
25+
}
26+
27+
export type EspressoDriverCaps = DriverCaps<EspressoConstraints> & DeviceInfoCaps;

0 commit comments

Comments
 (0)