UNPKG

appium-android-driver

Version:

Android UiAutomator and Chrome support for Appium

222 lines 8.41 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 HELPER_APP_INSTALL_RETRIES = 3; const HELPER_APP_INSTALL_RETRY_DELAY_MS = 5000; /** * @this {import('../../driver').AndroidDriver} * @param {string} errMsg */ function requireEmulator(errMsg) { if (!this.isEmulator()) { throw this.log.errorWithException(errMsg); } } /** * @this {import('../../driver').AndroidDriver} * @param {string} networkSpeed * @returns {string} */ 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; } /** * @this {import('../../driver').AndroidDriver} * @returns {string[]} */ 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; } /** * @this {import('../../driver').AndroidDriver} * @param {ADB} adb * @returns {Promise<void>} */ 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) { this.log.debug(`Emulator '${avdName}' is not running: ${e.message}`); isEmulatorRunning = false; } const args = prepareAvdArgs.bind(this)(); if (isEmulatorRunning) { if (await image_injection_1.prepareEmulatorForImageInjection.bind(this)(/** @type {string} */ (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, }); } /** * @param {import('../../driver').AndroidDriverOpts?} [opts=null] * @returns {Promise<ADB>} */ async function createBaseADB(opts = null) { // 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, } = opts ?? {}; return await appium_adb_1.ADB.createADB({ adbPort, suppressKillServer, remoteAdbHost, clearDeviceLogsOnStart, adbExecTimeout, useKeystore, keystorePath, keystorePassword, keyAlias, keyPassword, remoteAppsCacheLimit, buildToolsVersion, allowOfflineDevices, allowDelayAdb, }); } /** * @this {import('../../driver').AndroidDriver} * @param {boolean} throwIfError * @returns {Promise<void>} */ 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) { if (throwIfError) { throw err; } this.log.warn(`Ignored error while installing '${io_appium_settings_1.path}': ` + `'${err.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; } const fixSettingsAppPermissionsForLegacyApis = async () => { if ((await this.adb.getApiLevel()) > 23) { return; } // Android 6- devices should have granted permissions // https://github.com/appium/appium/pull/11640#issuecomment-438260477 const perms = ['SET_ANIMATION_SCALE', 'CHANGE_CONFIGURATION', 'ACCESS_FINE_LOCATION']; this.log.info(`Granting permissions ${perms} to '${io_appium_settings_1.SETTINGS_HELPER_ID}'`); await this.adb.grantPermissions(io_appium_settings_1.SETTINGS_HELPER_ID, perms.map((x) => `android.permission.${x}`)); }; try { await bluebird_1.default.all([ this.settingsApp.adjustNotificationsPermissions(), this.settingsApp.adjustMediaProjectionServicePermissions(), fixSettingsAppPermissionsForLegacyApis(), ]); } catch (e) { this.log.debug(e.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) { this.log.debug(err.stack); if (throwIfError) { throw err; } } } /** * @deprecated * @this {import('../../driver').AndroidDriver} * @returns {Promise<string?>} */ 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; } /** * @this {import('../../driver').AndroidDriver} * @returns {Promise<void>} */ 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