UNPKG

appium-uiautomator2-driver

Version:
133 lines (125 loc) 5.35 kB
import {utils} from 'appium-android-driver'; import {fs} from 'appium/support'; import {SETTINGS_HELPER_ID} from 'io.appium.settings'; import type {AndroidUiautomator2Driver} from '../driver'; import {APKS_EXTENSION, APK_EXTENSION} from '../extensions'; import {SERVER_PACKAGE_ID, SERVER_TEST_PACKAGE_ID} from '../uiautomator2-server'; import {signApp} from '../utils'; /** Configures the app capability and validates the APK path before session start. */ export async function prepareSessionApp(this: AndroidUiautomator2Driver): Promise<void> { if (this.opts.app) { // find and copy, or download and unzip an app url or path this.opts.app = await this.helpers.configureApp(this.opts.app, [APK_EXTENSION, APKS_EXTENSION]); await this.checkAppPresent(); } else if (this.opts.appPackage) { // the app isn't an actual app file but rather something we want to // assume is on the device and just launch via the appPackage this.log.info(`Starting '${this.opts.appPackage}' directly on the device`); } else { this.log.info( `Neither 'app' nor 'appPackage' was set. Starting UiAutomator2 ` + 'without the target application', ); } } /** Verifies that the app APK path from capabilities exists on the host. */ export async function checkAppPresent(this: AndroidUiautomator2Driver): Promise<void> { this.log.debug('Checking whether app is actually present'); if (!this.opts.app || !(await fs.exists(this.opts.app))) { throw this.log.errorWithException(`Could not find app apk at '${this.opts.app}'`); } } /** Installs and prepares the application under test on the device. */ export async function initAUT(this: AndroidUiautomator2Driver): Promise<void> { // Uninstall any uninstallOtherPackages which were specified in caps if (this.opts.uninstallOtherPackages) { await this.uninstallOtherPackages(utils.parseArray(this.opts.uninstallOtherPackages), [ SETTINGS_HELPER_ID, SERVER_PACKAGE_ID, SERVER_TEST_PACKAGE_ID, ]); } // Install any "otherApps" that were specified in caps if (this.opts.otherApps) { let otherApps; try { otherApps = utils.parseArray(this.opts.otherApps); } catch (e) { throw this.log.errorWithException( `Could not parse "otherApps" capability: ${(e as Error).message}`, ); } otherApps = await Promise.all( otherApps.map((app) => this.helpers.configureApp(app, [APK_EXTENSION, APKS_EXTENSION])), ); await this.installOtherApks(otherApps); } if (this.opts.app && this.opts.appPackage) { const adb = this.requireAdb(); const appPackage = this.opts.appPackage; if ((this.opts.noReset && !(await adb.isAppInstalled(appPackage))) || !this.opts.noReset) { if ( !this.opts.noSign && !(await adb.checkApkCert(this.opts.app, { requireDefaultCert: false, })) ) { await signApp(adb, this.opts.app); } if (!this.opts.skipUninstall) { await adb.uninstallApk(appPackage); } await this.installAUT(); } else { this.log.debug('noReset has been requested and the app is already installed. Doing nothing'); } } else { if (this.opts.fullReset) { throw this.log.errorWithException( 'Full reset requires an app capability, use fastReset if app is not provided', ); } this.log.debug('No app capability. Assuming it is already on the device'); if (this.opts.fastReset && this.opts.appPackage) { await this.resetAUT(); } } } /** Launches the application under test according to session capabilities. */ export async function ensureAppStarts(this: AndroidUiautomator2Driver): Promise<void> { const adb = this.requireAdb(); const appPackage = this.opts.appPackage; const appActivity = this.opts.appActivity; if (!appPackage) { throw this.log.errorWithException('appPackage capability is required to start the application'); } // make sure we have an activity and package to wait for const appWaitPackage = this.opts.appWaitPackage || appPackage; const appWaitActivity = this.opts.appWaitActivity || appActivity; this.log.info( `Starting '${appPackage}${appActivity ? '/' + appActivity : ''}` + `and waiting for '${appWaitPackage}${appWaitActivity ? '/' + appWaitActivity : ''}'`, ); if (this.opts.noReset && !this.opts.forceAppLaunch && (await adb.processExists(appPackage))) { this.log.info( `'${appPackage}' is already running and noReset is enabled. ` + `Set forceAppLaunch capability to true if the app must be forcefully restarted on session startup.`, ); return; } await adb.startApp({ pkg: appPackage, activity: appActivity, action: this.opts.intentAction || 'android.intent.action.MAIN', category: this.opts.intentCategory || 'android.intent.category.LAUNCHER', flags: this.opts.intentFlags || '0x10200000', // FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED waitPkg: this.opts.appWaitPackage, waitActivity: this.opts.appWaitActivity, waitForLaunch: this.opts.appWaitForLaunch, waitDuration: this.opts.appWaitDuration, optionalIntentArguments: this.opts.optionalIntentArguments, stopApp: this.opts.forceAppLaunch || !this.opts.dontStopAppOnReset, retry: true, user: this.opts.userProfile, }); }