UNPKG

appium-android-driver

Version:

Android UiAutomator and Chrome support for Appium

222 lines 8.23 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.requireEmulator = requireEmulator; exports.ensureNetworkSpeed = ensureNetworkSpeed; exports.prepareAvdArgs = prepareAvdArgs; exports.prepareEmulator = prepareEmulator; exports.createBaseADB = createBaseADB; exports.pushSettingsApp = pushSettingsApp; exports.initUnicodeKeyboard = initUnicodeKeyboard; exports.hideKeyboardCompletely = hideKeyboardCompletely; const lodash_1 = __importDefault(require("lodash")); const support_1 = require("@appium/support"); const appium_adb_1 = require("appium-adb"); const asyncbox_1 = require("asyncbox"); const io_appium_settings_1 = require("io.appium.settings"); const bluebird_1 = __importDefault(require("bluebird")); const image_injection_1 = require("../image-injection"); const utils_1 = require("../../utils"); const HELPER_APP_INSTALL_RETRIES = 3; const HELPER_APP_INSTALL_RETRY_DELAY_MS = 5000; /** * Requires that the current device is an emulator, throwing an error if not. * * @param errMsg - Error message to throw if not an emulator * @throws {Error} If the device is not an emulator */ function requireEmulator(errMsg) { if (!this.isEmulator()) { throw this.log.errorWithException(errMsg); } } /** * Ensures the network speed value is valid, returning the default if not. * * @param networkSpeed - The network speed value to validate * @returns The validated network speed value */ function ensureNetworkSpeed(networkSpeed) { if (networkSpeed.toUpperCase() in this.adb.NETWORK_SPEED) { return networkSpeed; } this.log.warn(`Wrong network speed param '${networkSpeed}', using default: ${this.adb.NETWORK_SPEED.FULL}. ` + `Supported values: ${lodash_1.default.values(this.adb.NETWORK_SPEED)}`); return this.adb.NETWORK_SPEED.FULL; } /** * Prepares AVD arguments based on options. * * @returns An array of AVD arguments */ function prepareAvdArgs() { const { networkSpeed, isHeadless, avdArgs } = this.opts; const result = []; if (avdArgs) { if (lodash_1.default.isArray(avdArgs)) { result.push(...avdArgs); } else { result.push(...support_1.util.shellParse(`${avdArgs}`)); } } if (networkSpeed) { result.push('-netspeed', ensureNetworkSpeed.bind(this)(networkSpeed)); } if (isHeadless) { result.push('-no-window'); } return result; } /** * Prepares and launches an emulator with the specified AVD name. * * @param adb - The ADB instance to use */ async function prepareEmulator(adb) { const { avd, avdEnv: env, language, locale: country, avdLaunchTimeout: launchTimeout, avdReadyTimeout: readyTimeout, } = this.opts; if (!avd) { throw new Error('Cannot launch AVD without AVD name'); } const avdName = avd.replace('@', ''); let isEmulatorRunning = true; try { // This API implicitly modifies curDeviceId and emulatorPort properties of the adb instance await adb.getRunningAVDWithRetry(avdName, 5000); } catch (e) { const err = e; this.log.debug(`Emulator '${avdName}' is not running: ${err.message}`); isEmulatorRunning = false; } const args = prepareAvdArgs.bind(this)(); if (isEmulatorRunning) { if (await image_injection_1.prepareEmulatorForImageInjection.bind(this)(adb.sdkRoot) || args.includes('-wipe-data')) { this.log.debug(`Killing '${avdName}'`); await adb.killEmulator(avdName); } else { this.log.debug('Not launching AVD because it is already running.'); return; } } await adb.launchAVD(avd, { args, env, language, country, launchTimeout, readyTimeout, }); } /** * Creates a base ADB instance with options from driver configuration. * * @returns A configured ADB instance */ async function createBaseADB() { // filter out any unwanted options sent in // this list should be updated as ADB takes more arguments const { adbPort, suppressKillServer, remoteAdbHost, clearDeviceLogsOnStart, adbExecTimeout, useKeystore, keystorePath, keystorePassword, keyAlias, keyPassword, remoteAppsCacheLimit, buildToolsVersion, allowOfflineDevices, allowDelayAdb, adbListenAllNetwork, } = this.opts ?? {}; if (adbListenAllNetwork) { this.assertFeatureEnabled(utils_1.ADB_LISTEN_ALL_NETWORK_FEATURE); } return await appium_adb_1.ADB.createADB({ adbPort, suppressKillServer, remoteAdbHost, clearDeviceLogsOnStart, adbExecTimeout, useKeystore, keystorePath, keystorePassword, keyAlias, keyPassword, remoteAppsCacheLimit, buildToolsVersion, allowOfflineDevices, allowDelayAdb, listenAllNetwork: adbListenAllNetwork, }); } /** * Pushes and installs the settings app on the device. * * @param throwIfError - Whether to throw an error if installation fails */ async function pushSettingsApp(throwIfError) { this.log.debug('Pushing settings apk to the device...'); try { // Sometimes adb push or adb instal take more time than expected to install an app // e.g. https://github.com/appium/io.appium.settings/issues/40#issuecomment-476593174 await (0, asyncbox_1.retryInterval)(HELPER_APP_INSTALL_RETRIES, HELPER_APP_INSTALL_RETRY_DELAY_MS, async () => await this.adb.installOrUpgrade(io_appium_settings_1.path, io_appium_settings_1.SETTINGS_HELPER_ID, { grantPermissions: true, })); } catch (err) { const error = err; if (throwIfError) { throw error; } this.log.warn(`Ignored error while installing '${io_appium_settings_1.path}': ` + `'${error.message}'. Features that rely on this helper ` + 'require the apk such as toggle WiFi and getting location ' + 'will raise an error if you try to use them.'); } // Reinstall would stop the settings helper process anyway, so // there is no need to continue if the application is still running if (await this.settingsApp.isRunningInForeground()) { this.log.debug(`${io_appium_settings_1.SETTINGS_HELPER_ID} is already running. ` + `There is no need to reset its permissions.`); return; } try { await bluebird_1.default.all([ this.settingsApp.adjustNotificationsPermissions(), this.settingsApp.adjustMediaProjectionServicePermissions(), ]); } catch (e) { const err = e; this.log.debug(err.stack); } // launch io.appium.settings app due to settings failing to be set // if the app is not launched prior to start the session on android 7+ // see https://github.com/appium/appium/issues/8957 try { await this.settingsApp.requireRunning({ timeout: this.isEmulator() ? 30000 : 5000, }); } catch (err) { const error = err; this.log.debug(error.stack); if (throwIfError) { throw error; } } } /** * @deprecated */ async function initUnicodeKeyboard() { this.log.debug('Enabling Unicode keyboard support'); // get the default IME so we can return back to it later if we want const defaultIME = await this.adb.defaultIME(); this.log.debug(`Unsetting previous IME ${defaultIME}`); this.log.debug(`Setting IME to '${io_appium_settings_1.UNICODE_IME}'`); await this.adb.enableIME(io_appium_settings_1.UNICODE_IME); await this.adb.setIME(io_appium_settings_1.UNICODE_IME); return defaultIME; } /** * Hides the on-screen keyboard completely by setting an empty IME. */ async function hideKeyboardCompletely() { this.log.debug(`Hiding the on-screen keyboard by setting IME to '${io_appium_settings_1.EMPTY_IME}'`); await this.adb.enableIME(io_appium_settings_1.EMPTY_IME); await this.adb.setIME(io_appium_settings_1.EMPTY_IME); } //# sourceMappingURL=utils.js.map