How to use prepareAvdArgs method in Appium Android Driver

Best JavaScript code snippet using appium-android-driver

android-helper-specs.js

Source:android-helper-specs.js Github

copy

Full Screen

...111 }));112 describe('prepareAvdArgs', withMocks({adb, helpers}, (mocks) => {113 it('should set the correct avdArgs', function () {114 let avdArgs = '-wipe-data';115 (prepareAvdArgs(adb, {avdArgs})).should.eql([avdArgs]);116 });117 it('should add headless arg', function () {118 let avdArgs = '-wipe-data';119 let args = prepareAvdArgs(adb, {isHeadless: true, avdArgs});120 args.should.eql(['-wipe-data', '-no-window']);121 });122 it('should add network speed arg', function () {123 let avdArgs = '-wipe-data';124 let args = prepareAvdArgs(adb, {networkSpeed: 'edge', avdArgs});125 args.should.eql(['-wipe-data', '-netspeed', 'edge']);126 mocks.adb.verify();127 });128 it('should not include empty avdArgs', function () {129 let avdArgs = '';130 let args = prepareAvdArgs(adb, {isHeadless: true, avdArgs});131 args.should.eql(['-no-window']);132 });133 }));134 describe('ensureNetworkSpeed', function () {135 it('should return value if network speed is valid', function () {136 adb.NETWORK_SPEED = {GSM: 'gsm'};137 ensureNetworkSpeed(adb, 'gsm').should.be.equal('gsm');138 });139 it('should return ADB.NETWORK_SPEED.FULL if network speed is invalid', function () {140 adb.NETWORK_SPEED = {FULL: 'full'};141 ensureNetworkSpeed(adb, 'invalid').should.be.equal('full');142 });143 });144 describe('ensureDeviceLocale', withMocks({adb}, (mocks) => {...

Full Screen

Full Screen

android-helpers.js

Source:android-helpers.js Github

copy

Full Screen

1import _ from 'lodash';2import path from 'path';3import { exec } from 'teen_process';4import { retry, retryInterval, waitForCondition } from 'asyncbox';5import logger from './logger';6import { fs, util } from 'appium-support';7import { path as settingsApkPath } from 'io.appium.settings';8import Bootstrap from './bootstrap';9import B from 'bluebird';10import ADB from 'appium-adb';11import {12 default as unlocker, PIN_UNLOCK, PASSWORD_UNLOCK,13 PATTERN_UNLOCK, FINGERPRINT_UNLOCK } from './unlock-helpers';14import { EOL } from 'os';15const PACKAGE_INSTALL_TIMEOUT = 90000; // milliseconds16const CHROME_BROWSER_PACKAGE_ACTIVITY = {17 chrome: {18 pkg: 'com.android.chrome',19 activity: 'com.google.android.apps.chrome.Main',20 },21 chromium: {22 pkg: 'org.chromium.chrome.shell',23 activity: '.ChromeShellActivity',24 },25 chromebeta: {26 pkg: 'com.chrome.beta',27 activity: 'com.google.android.apps.chrome.Main',28 },29 browser: {30 pkg: 'com.android.browser',31 activity: 'com.android.browser.BrowserActivity',32 },33 'chromium-browser': {34 pkg: 'org.chromium.chrome',35 activity: 'com.google.android.apps.chrome.Main',36 },37 'chromium-webview': {38 pkg: 'org.chromium.webview_shell',39 activity: 'org.chromium.webview_shell.WebViewBrowserActivity',40 },41 default: {42 pkg: 'com.android.chrome',43 activity: 'com.google.android.apps.chrome.Main',44 },45};46const SETTINGS_HELPER_PKG_ID = 'io.appium.settings';47const SETTINGS_HELPER_MAIN_ACTIVITY = '.Settings';48const SETTINGS_HELPER_UNLOCK_ACTIVITY = '.Unlock';49let helpers = {};50helpers.createBaseADB = async function createBaseADB (opts = {}) {51 // filter out any unwanted options sent in52 // this list should be updated as ADB takes more arguments53 const {54 adbPort,55 suppressKillServer,56 remoteAdbHost,57 clearDeviceLogsOnStart,58 adbExecTimeout,59 useKeystore,60 keystorePath,61 keystorePassword,62 keyAlias,63 keyPassword,64 remoteAppsCacheLimit,65 buildToolsVersion,66 } = opts;67 return await ADB.createADB({68 adbPort,69 suppressKillServer,70 remoteAdbHost,71 clearDeviceLogsOnStart,72 adbExecTimeout,73 useKeystore,74 keystorePath,75 keystorePassword,76 keyAlias,77 keyPassword,78 remoteAppsCacheLimit,79 buildToolsVersion,80 });81};82helpers.getJavaVersion = async function getJavaVersion (logVersion = true) {83 let stderr;84 try {85 ({stderr} = await exec('java', ['-version']));86 } catch (e) {87 throw new Error(`Could not get the Java version. Is Java installed? Original error: ${e.stderr}`);88 }89 const versionMatch = /(java|openjdk)\s+version.+?([0-9._]+)/i.exec(stderr);90 if (!versionMatch) {91 throw new Error(`Could not parse Java version. Is Java installed? Original output: ${stderr}`);92 }93 if (logVersion) {94 logger.info(`Java version is: ${versionMatch[2]}`);95 }96 return versionMatch[2];97};98helpers.prepareEmulator = async function prepareEmulator (adb, opts) {99 let {100 avd,101 avdArgs,102 language,103 locale,104 avdLaunchTimeout,105 avdReadyTimeout,106 } = opts;107 if (!avd) {108 throw new Error('Cannot launch AVD without AVD name');109 }110 let avdName = avd.replace('@', '');111 let runningAVD = await adb.getRunningAVD(avdName);112 if (runningAVD !== null) {113 if (avdArgs && avdArgs.toLowerCase().indexOf('-wipe-data') > -1) {114 logger.debug(`Killing '${avdName}' because it needs to be wiped at start.`);115 await adb.killEmulator(avdName);116 } else {117 logger.debug('Not launching AVD because it is already running.');118 return;119 }120 }121 avdArgs = this.prepareAVDArgs(opts, adb, avdArgs);122 await adb.launchAVD(avd, avdArgs, language, locale, avdLaunchTimeout,123 avdReadyTimeout);124};125helpers.prepareAVDArgs = function prepareAVDArgs (opts, adb, avdArgs) {126 let args = avdArgs ? [avdArgs] : [];127 if (!_.isUndefined(opts.networkSpeed)) {128 let networkSpeed = this.ensureNetworkSpeed(adb, opts.networkSpeed);129 args.push('-netspeed', networkSpeed);130 }131 if (opts.isHeadless) {132 args.push('-no-window');133 }134 return args.join(' ');135};136helpers.ensureNetworkSpeed = function ensureNetworkSpeed (adb, networkSpeed) {137 if (_.values(adb.NETWORK_SPEED).indexOf(networkSpeed) !== -1) {138 return networkSpeed;139 }140 logger.warn(`Wrong network speed param ${networkSpeed}, using default: full. Supported values: ${_.values(adb.NETWORK_SPEED)}`);141 return adb.NETWORK_SPEED.FULL;142};143/**144 * Set and ensure the locale name of the device under test.145 *146 * @param {Object} adb - The adb module instance.147 * @param {string} language - Language. The language field is case insensitive, but Locale always canonicalizes to lower case.148 * format: [a-zA-Z]{2,8}. e.g. en, ja : https://developer.android.com/reference/java/util/Locale.html149 * @param {string} country - Country. The country (region) field is case insensitive, but Locale always canonicalizes to upper case.150 * format: [a-zA-Z]{2} | [0-9]{3}. e.g. US, JP : https://developer.android.com/reference/java/util/Locale.html151 * @param {?string} script - Script. The script field is case insensitive but Locale always canonicalizes to title case.152 * format: [a-zA-Z]{4}. e.g. Hans in zh-Hans-CN : https://developer.android.com/reference/java/util/Locale.html153 * @throws {Error} If it failed to set locale properly154 */155helpers.ensureDeviceLocale = async function ensureDeviceLocale (adb, language, country, script = null) {156 if (!_.isString(language) && !_.isString(country)) {157 logger.warn(`setDeviceLanguageCountry requires language or country.`);158 logger.warn(`Got language: '${language}' and country: '${country}'`);159 return;160 }161 await adb.setDeviceLanguageCountry(language, country, script);162 if (!await adb.ensureCurrentLocale(language, country, script)) {163 const message = script ? `language: ${language}, country: ${country} and script: ${script}` : `language: ${language} and country: ${country}`;164 throw new Error(`Failed to set ${message}`);165 }166};167helpers.getDeviceInfoFromCaps = async function getDeviceInfoFromCaps (opts = {}) {168 // we can create a throwaway ADB instance here, so there is no dependency169 // on instantiating on earlier (at this point, we have no udid)170 // we can only use this ADB object for commands that would not be confused171 // if multiple devices are connected172 const adb = await helpers.createBaseADB(opts);173 let udid = opts.udid;174 let emPort = null;175 // a specific avd name was given. try to initialize with that176 if (opts.avd) {177 await helpers.prepareEmulator(adb, opts);178 udid = adb.curDeviceId;179 emPort = adb.emulatorPort;180 } else {181 // no avd given. lets try whatever's plugged in devices/emulators182 logger.info('Retrieving device list');183 let devices = await adb.getDevicesWithRetry();184 // udid was given, lets try to init with that device185 if (udid) {186 if (!_.includes(_.map(devices, 'udid'), udid)) {187 logger.errorAndThrow(`Device ${udid} was not in the list of connected devices`);188 }189 emPort = adb.getPortFromEmulatorString(udid);190 } else if (opts.platformVersion) {191 opts.platformVersion = `${opts.platformVersion}`.trim();192 // a platform version was given. lets try to find a device with the same os193 const platformVersion = util.coerceVersion(opts.platformVersion, false);194 if (!platformVersion) {195 logger.errorAndThrow(`The provided platform version value '${platformVersion}' ` +196 `cannot be coerced to a valid version number`);197 }198 logger.info(`Looking for a device with Android '${opts.platformVersion}'`);199 // in case we fail to find something, give the user a useful log that has200 // the device udids and os versions so they know what's available201 const availDevices = [];202 let partialMatchCandidate = null;203 const extractVersionDigits = (versionStr) => {204 const match = /(\d+)\.?(\d+)?/.exec(versionStr);205 return match ? match.slice(1) : [];206 };207 const [majorPlatformVersion, minorPlatformVersion] = extractVersionDigits(platformVersion);208 // first try started devices/emulators209 for (const device of devices) {210 // direct adb calls to the specific device211 await adb.setDeviceId(device.udid);212 const rawDeviceOS = await adb.getPlatformVersion();213 availDevices.push(`${device.udid} (${rawDeviceOS})`);214 const deviceOS = util.coerceVersion(rawDeviceOS, false);215 if (!deviceOS) {216 continue;217 }218 if (util.compareVersions(deviceOS, '==', platformVersion)) {219 // Got an exact match - proceed immediately220 udid = device.udid;221 break;222 }223 const [majorDeviceVersion, minorDeviceVersion] = extractVersionDigits(deviceOS);224 if ((!opts.platformVersion.includes('.') && majorPlatformVersion === majorDeviceVersion)225 || (majorPlatformVersion === majorDeviceVersion && minorPlatformVersion === minorDeviceVersion)) {226 // Got a partial match - make sure we consider the most recent227 // device version available on the host system228 if (partialMatchCandidate229 && util.compareVersions(deviceOS, '>', _.values(partialMatchCandidate)[0])230 || !partialMatchCandidate) {231 partialMatchCandidate = {[device.udid]: deviceOS};232 }233 }234 }235 if (!udid && partialMatchCandidate) {236 udid = _.keys(partialMatchCandidate)[0];237 await adb.setDeviceId(udid);238 }239 if (!udid) {240 // we couldn't find anything! quit241 logger.errorAndThrow(`Unable to find an active device or emulator ` +242 `with OS ${opts.platformVersion}. The following are available: ` +243 availDevices.join(', '));244 }245 emPort = adb.getPortFromEmulatorString(udid);246 } else {247 // a udid was not given, grab the first device we see248 udid = devices[0].udid;249 emPort = adb.getPortFromEmulatorString(udid);250 }251 }252 logger.info(`Using device: ${udid}`);253 return {udid, emPort};254};255// returns a new adb instance with deviceId set256helpers.createADB = async function createADB (opts = {}) {257 const {udid, emPort} = opts;258 const adb = await helpers.createBaseADB(opts);259 adb.setDeviceId(udid);260 if (emPort) {261 adb.setEmulatorPort(emPort);262 }263 return adb;264};265helpers.validatePackageActivityNames = function validatePackageActivityNames (opts) {266 for (const key of ['appPackage', 'appActivity', 'appWaitPackage', 'appWaitActivity']) {267 const name = opts[key];268 if (!name) {269 continue;270 }271 const match = /([^\w.*,])+/.exec(name);272 if (!match) {273 continue;274 }275 logger.warn(`Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.`);276 logger.warn(`Current value '${name}' has non-matching character at index ${match.index}: '${name.substring(0, match.index + 1)}'`);277 }278};279helpers.getLaunchInfo = async function getLaunchInfo (adb, opts) {280 let {app, appPackage, appActivity, appWaitPackage, appWaitActivity} = opts;281 if (!app) {282 logger.warn('No app sent in, not parsing package/activity');283 return;284 }285 this.validatePackageActivityNames(opts);286 if (appPackage && appActivity) {287 return;288 }289 logger.debug('Parsing package and activity from app manifest');290 let {apkPackage, apkActivity} =291 await adb.packageAndLaunchActivityFromManifest(app);292 if (apkPackage && !appPackage) {293 appPackage = apkPackage;294 }295 if (!appWaitPackage) {296 appWaitPackage = appPackage;297 }298 if (apkActivity && !appActivity) {299 appActivity = apkActivity;300 }301 if (!appWaitActivity) {302 appWaitActivity = appActivity;303 }304 logger.debug(`Parsed package and activity are: ${apkPackage}/${apkActivity}`);305 return {appPackage, appWaitPackage, appActivity, appWaitActivity};306};307helpers.resetApp = async function resetApp (adb, opts = {}) {308 const {309 app,310 appPackage,311 fastReset,312 fullReset,313 androidInstallTimeout = PACKAGE_INSTALL_TIMEOUT,314 autoGrantPermissions,315 allowTestPackages316 } = opts;317 if (!appPackage) {318 throw new Error("'appPackage' option is required");319 }320 const isInstalled = await adb.isAppInstalled(appPackage);321 if (isInstalled) {322 try {323 await adb.forceStop(appPackage);324 } catch (ign) {}325 // fullReset has priority over fastReset326 if (!fullReset && fastReset) {327 const output = await adb.clear(appPackage);328 if (_.isString(output) && output.toLowerCase().includes('failed')) {329 throw new Error(`Cannot clear the application data of '${appPackage}'. Original error: ${output}`);330 }331 // executing `shell pm clear` resets previously assigned application permissions as well332 if (autoGrantPermissions) {333 try {334 await adb.grantAllPermissions(appPackage);335 } catch (error) {336 logger.error(`Unable to grant permissions requested. Original error: ${error.message}`);337 }338 }339 logger.debug(`Performed fast reset on the installed '${appPackage}' application (stop and clear)`);340 return;341 }342 }343 if (!app) {344 throw new Error("'app' option is required for reinstall");345 }346 logger.debug(`Running full reset on '${appPackage}' (reinstall)`);347 if (isInstalled) {348 await adb.uninstallApk(appPackage);349 }350 await adb.install(app, {351 grantPermissions: autoGrantPermissions,352 timeout: androidInstallTimeout,353 allowTestPackages,354 });355};356helpers.installApk = async function installApk (adb, opts = {}) {357 const {358 app,359 appPackage,360 fastReset,361 fullReset,362 androidInstallTimeout = PACKAGE_INSTALL_TIMEOUT,363 autoGrantPermissions,364 allowTestPackages,365 enforceAppInstall,366 } = opts;367 if (!app || !appPackage) {368 throw new Error("'app' and 'appPackage' options are required");369 }370 if (fullReset) {371 await this.resetApp(adb, opts);372 return;373 }374 const {375 appState,376 wasUninstalled377 } = await adb.installOrUpgrade(app, appPackage, {378 grantPermissions: autoGrantPermissions,379 timeout: androidInstallTimeout,380 allowTestPackages,381 enforceCurrentBuild: enforceAppInstall,382 });383 // There is no need to reset the newly installed app384 const isInstalledOverExistingApp = !wasUninstalled385 && appState !== adb.APP_INSTALL_STATE.NOT_INSTALLED;386 if (fastReset && isInstalledOverExistingApp) {387 logger.info(`Performing fast reset on '${appPackage}'`);388 await this.resetApp(adb, opts);389 }390};391/**392 * Installs an array of apks393 * @param {ADB} adb Instance of Appium ADB object394 * @param {Object} opts Opts defined in driver.js395 */396helpers.installOtherApks = async function installOtherApks (otherApps, adb, opts) {397 let {398 androidInstallTimeout = PACKAGE_INSTALL_TIMEOUT,399 autoGrantPermissions,400 allowTestPackages401 } = opts;402 // Install all of the APK's asynchronously403 await B.all(otherApps.map((otherApp) => {404 logger.debug(`Installing app: ${otherApp}`);405 return adb.installOrUpgrade(otherApp, null, {406 grantPermissions: autoGrantPermissions,407 timeout: androidInstallTimeout,408 allowTestPackages,409 });410 }));411};412/**413 * Uninstall an array of packages414 * @param {ADB} adb Instance of Appium ADB object415 * @param {Array<string>} appPackages An array of package names to uninstall. If this includes `'*'`, uninstall all of 3rd party apps416 * @param {Array<string>} filterPackages An array of packages does not uninstall when `*` is provided as `appPackages`417 */418helpers.uninstallOtherPackages = async function uninstallOtherPackages (adb, appPackages, filterPackages = []) {419 if (appPackages.includes('*')) {420 logger.debug('Uninstall third party packages');421 appPackages = await this.getThirdPartyPackages(adb, filterPackages);422 }423 logger.debug(`Uninstalling packages: ${appPackages}`);424 await B.all(appPackages.map((appPackage) => adb.uninstallApk(appPackage)));425};426/**427 * Get third party packages filtered with `filterPackages`428 * @param {ADB} adb Instance of Appium ADB object429 * @param {Array<string>} filterPackages An array of packages does not uninstall when `*` is provided as `appPackages`430 * @returns {Array<string>} An array of installed third pary packages431 */432helpers.getThirdPartyPackages = async function getThirdPartyPackages (adb, filterPackages = []) {433 try {434 const packagesString = await adb.shell(['pm', 'list', 'packages', '-3']);435 const appPackagesArray = packagesString.trim().replace(/package:/g, '').split(EOL);436 logger.debug(`'${appPackagesArray}' filtered with '${filterPackages}'`);437 return _.difference(appPackagesArray, filterPackages);438 } catch (err) {439 logger.warn(`Unable to get packages with 'adb shell pm list packages -3': ${err.message}`);440 return [];441 }442};443helpers.initUnicodeKeyboard = async function initUnicodeKeyboard (adb) {444 logger.debug('Enabling Unicode keyboard support');445 // get the default IME so we can return back to it later if we want446 let defaultIME = await adb.defaultIME();447 logger.debug(`Unsetting previous IME ${defaultIME}`);448 const appiumIME = `${SETTINGS_HELPER_PKG_ID}/.UnicodeIME`;449 logger.debug(`Setting IME to '${appiumIME}'`);450 await adb.enableIME(appiumIME);451 await adb.setIME(appiumIME);452 return defaultIME;453};454helpers.setMockLocationApp = async function setMockLocationApp (adb, app) {455 try {456 if (await adb.getApiLevel() < 23) {457 await adb.shell(['settings', 'put', 'secure', 'mock_location', '1']);458 } else {459 await adb.shell(['appops', 'set', app, 'android:mock_location', 'allow']);460 }461 } catch (err) {462 logger.warn(`Unable to set mock location for app '${app}': ${err.message}`);463 }464};465helpers.installHelperApp = async function installHelperApp (adb, apkPath, packageId) {466 // Sometimes adb push or adb instal take more time than expected to install an app467 // e.g. https://github.com/appium/io.appium.settings/issues/40#issuecomment-476593174468 await retry(2, async function retryInstallHelperApp () {469 await adb.installOrUpgrade(apkPath, packageId, {grantPermissions: true});470 });471};472/**473 * Pushes and installs io.appium.settings app.474 * Throws an error if the setting app is required475 *476 * @param {Adb} adb - The adb module instance.477 * @param {boolean} throwError[false] - Whether throw error or not478 * @throws {Error} If throwError is true and something happens in installation step479 */480helpers.pushSettingsApp = async function pushSettingsApp (adb, throwError = false) {481 logger.debug('Pushing settings apk to device...');482 try {483 await helpers.installHelperApp(adb, settingsApkPath, SETTINGS_HELPER_PKG_ID, throwError);484 } catch (err) {485 if (throwError) {486 throw err;487 }488 logger.warn(`Ignored error while installing '${settingsApkPath}': ` +489 `'${err.message}'. Features that rely on this helper ` +490 'require the apk such as toggle WiFi and getting location ' +491 'will raise an error if you try to use them.');492 }493 // Reinstall will stop the settings helper process anyway, so494 // there is no need to continue if the application is still running495 if (await adb.processExists(SETTINGS_HELPER_PKG_ID)) {496 logger.debug(`${SETTINGS_HELPER_PKG_ID} is already running. ` +497 `There is no need to reset its permissions.`);498 return;499 }500 if (await adb.getApiLevel() <= 23) { // Android 6- devices should have granted permissions501 // https://github.com/appium/appium/pull/11640#issuecomment-438260477502 logger.info('Granting android.permission.SET_ANIMATION_SCALE, CHANGE_CONFIGURATION, ACCESS_FINE_LOCATION by pm grant');503 await adb.grantPermissions(SETTINGS_HELPER_PKG_ID, [504 'android.permission.SET_ANIMATION_SCALE',505 'android.permission.CHANGE_CONFIGURATION',506 'android.permission.ACCESS_FINE_LOCATION'507 ]);508 }509 // launch io.appium.settings app due to settings failing to be set510 // if the app is not launched prior to start the session on android 7+511 // see https://github.com/appium/appium/issues/8957512 try {513 await adb.startApp({514 pkg: SETTINGS_HELPER_PKG_ID,515 activity: SETTINGS_HELPER_MAIN_ACTIVITY,516 action: 'android.intent.action.MAIN',517 category: 'android.intent.category.LAUNCHER',518 stopApp: false,519 waitForLaunch: false,520 });521 await waitForCondition(async () => await adb.processExists(SETTINGS_HELPER_PKG_ID), {522 waitMs: 5000,523 intervalMs: 300,524 });525 } catch (err) {526 const message = `Failed to launch Appium Settings app: ${err.message}`;527 err.message = message;528 logger.warn(message);529 if (throwError) {530 throw err;531 }532 }533};534/**535 * Extracts string.xml and converts it to string.json and pushes536 * it to /data/local/tmp/string.json on for use of bootstrap537 * If app is not present to extract string.xml it deletes remote strings.json538 * If app does not have strings.xml we push an empty json object to remote539 *540 * @param {?string} language - Language abbreviation, for example 'fr'. The default language541 * is used if this argument is not defined.542 * @param {Object} adb - The adb module instance.543 * @param {Object} opts - Driver options dictionary.544 * @returns {Object} The dictionary, where string resource identifiers are keys545 * along with their corresponding values for the given language or an empty object546 * if no matching resources were extracted.547 */548helpers.pushStrings = async function pushStrings (language, adb, opts) {549 const remoteDir = '/data/local/tmp';550 const stringsJson = 'strings.json';551 const remoteFile = path.posix.resolve(remoteDir, stringsJson);552 // clean up remote string.json if present553 await adb.rimraf(remoteFile);554 let app;555 try {556 app = opts.app || await adb.pullApk(opts.appPackage, opts.tmpDir);557 } catch (err) {558 logger.info(`Failed to pull an apk from '${opts.appPackage}' to '${opts.tmpDir}'. Original error: ${err.message}`);559 }560 if (_.isEmpty(opts.appPackage) || !(await fs.exists(app))) {561 logger.debug(`No app or package specified. Returning empty strings`);562 return {};563 }564 const stringsTmpDir = path.resolve(opts.tmpDir, opts.appPackage);565 try {566 logger.debug('Extracting strings from apk', app, language, stringsTmpDir);567 const {apkStrings, localPath} = await adb.extractStringsFromApk(app, language, stringsTmpDir);568 await adb.push(localPath, remoteDir);569 return apkStrings;570 } catch (err) {571 logger.warn(`Could not get strings, continuing anyway. Original error: ${err.message}`);572 await adb.shell('echo', [`'{}' > ${remoteFile}`]);573 } finally {574 await fs.rimraf(stringsTmpDir);575 }576 return {};577};578helpers.unlockWithUIAutomation = async function unlockWithUIAutomation (driver, adb, unlockCapabilities) {579 let unlockType = unlockCapabilities.unlockType;580 if (!unlocker.isValidUnlockType(unlockType)) {581 throw new Error(`Invalid unlock type ${unlockType}`);582 }583 let unlockKey = unlockCapabilities.unlockKey;584 if (!unlocker.isValidKey(unlockType, unlockKey)) {585 throw new Error(`Missing unlockKey ${unlockKey} capability for unlockType ${unlockType}`);586 }587 const unlockMethod = {588 [PIN_UNLOCK]: unlocker.pinUnlock,589 [PASSWORD_UNLOCK]: unlocker.passwordUnlock,590 [PATTERN_UNLOCK]: unlocker.patternUnlock,591 [FINGERPRINT_UNLOCK]: unlocker.fingerprintUnlock592 }[unlockType];593 await unlockMethod(adb, driver, unlockCapabilities);594};595helpers.unlockWithHelperApp = async function unlockWithHelperApp (adb) {596 logger.info('Unlocking screen');597 // Unlock succeed with a couple of retries.598 let firstRun = true;599 await retry(3, async function launchHelper () {600 // To reduce a time to call adb.isScreenLocked() since `adb shell dumpsys window` is easy to hang adb commands601 if (firstRun) {602 firstRun = false;603 } else {604 try {605 if (!(await adb.isScreenLocked())) {606 return;607 }608 } catch (e) {609 logger.warn(`Error in isScreenLocked: ${e.message}`);610 logger.warn('"adb shell dumpsys window" command has timed out.');611 logger.warn('The reason of this timeout is the delayed adb response. Resetting adb server can improve it.');612 }613 }614 logger.info(`Launching ${SETTINGS_HELPER_UNLOCK_ACTIVITY}`);615 await adb.shell([616 'am', 'start',617 '-n', `${SETTINGS_HELPER_PKG_ID}/${SETTINGS_HELPER_UNLOCK_ACTIVITY}`,618 '-c', 'android.intent.category.LAUNCHER',619 '-a', 'android.intent.action.MAIN',620 '-f', '0x10200000',621 ]);622 await B.delay(1000);623 });624};625helpers.unlock = async function unlock (driver, adb, capabilities) {626 if (!(await adb.isScreenLocked())) {627 logger.info('Screen already unlocked, doing nothing');628 return;629 }630 logger.debug('Screen is locked, trying to unlock');631 if (_.isUndefined(capabilities.unlockType)) {632 logger.warn('Using app unlock, this is going to be deprecated!');633 await helpers.unlockWithHelperApp(adb);634 } else {635 await helpers.unlockWithUIAutomation(driver, adb, {unlockType: capabilities.unlockType, unlockKey: capabilities.unlockKey});636 await helpers.verifyUnlock(adb);637 }638};639helpers.verifyUnlock = async function verifyUnlock (adb) {640 await retryInterval(2, 1000, async () => {641 if (await adb.isScreenLocked()) {642 throw new Error('Screen did not unlock successfully, retrying');643 }644 logger.debug('Screen unlocked successfully');645 });646};647helpers.initDevice = async function initDevice (adb, opts) {648 if (opts.skipDeviceInitialization) {649 logger.info(`'skipDeviceInitialization' is set. Skipping device initialization.`);650 } else {651 await adb.waitForDevice();652 // pushSettingsApp required before calling ensureDeviceLocale for API Level 24+653 // Some feature such as location/wifi are not necessary for all users,654 // but they require the settings app. So, try to configure it while Appium655 // does not throw error even if they fail.656 const shouldThrowError = opts.language657 || opts.locale658 || opts.localeScript659 || opts.unicodeKeyboard660 || opts.disableWindowAnimation661 || !opts.skipUnlock;662 await helpers.pushSettingsApp(adb, shouldThrowError);663 }664 if (!opts.avd) {665 await helpers.setMockLocationApp(adb, SETTINGS_HELPER_PKG_ID);666 }667 if (opts.language || opts.locale) {668 await helpers.ensureDeviceLocale(adb, opts.language, opts.locale, opts.localeScript);669 }670 if (opts.skipLogcatCapture) {671 logger.info(`'skipLogcatCapture' is set. Skipping starting logcat capture.`);672 } else {673 await adb.startLogcat();674 }675 if (opts.unicodeKeyboard) {676 return await helpers.initUnicodeKeyboard(adb);677 }678};679helpers.removeNullProperties = function removeNullProperties (obj) {680 for (let key of _.keys(obj)) {681 if (_.isNull(obj[key]) || _.isUndefined(obj[key])) {682 delete obj[key];683 }684 }685};686helpers.truncateDecimals = function truncateDecimals (number, digits) {687 let multiplier = Math.pow(10, digits),688 adjustedNum = number * multiplier,689 truncatedNum = Math[adjustedNum < 0 ? 'ceil' : 'floor'](adjustedNum);690 return truncatedNum / multiplier;691};692helpers.isChromeBrowser = function isChromeBrowser (browser) {693 return _.includes(Object.keys(CHROME_BROWSER_PACKAGE_ACTIVITY), (browser || '').toLowerCase());694};695helpers.getChromePkg = function getChromePkg (browser) {696 return CHROME_BROWSER_PACKAGE_ACTIVITY[browser.toLowerCase()] || CHROME_BROWSER_PACKAGE_ACTIVITY.default;697};698helpers.removeAllSessionWebSocketHandlers = async function removeAllSessionWebSocketHandlers (server, sessionId) {699 if (!server || !_.isFunction(server.getWebSocketHandlers)) {700 return;701 }702 const activeHandlers = await server.getWebSocketHandlers(sessionId);703 for (const pathname of _.keys(activeHandlers)) {704 await server.removeWebSocketHandler(pathname);705 }706};707/**708 * Takes a desired capability and tries to JSON.parse it as an array,709 * and either returns the parsed array or a singleton array.710 *711 * @param {any} cap A desired capability712 */713helpers.parseArray = function parseArray (cap) {714 let parsedCaps;715 try {716 parsedCaps = JSON.parse(cap);717 } catch (ign) { }718 if (_.isArray(parsedCaps)) {719 return parsedCaps;720 } else if (_.isString(cap)) {721 return [cap];722 }723 throw new Error(`must provide a string or JSON Array; received ${cap}`);724};725/**726 * Validate desired capabilities. Returns true if capability is valid727 *728 * @param {*} cap A desired capability729 * @return {boolean} Returns true if the capability is valid730 * @throws {Error} If the caps has invalid capability731 */732helpers.validateDesiredCaps = function validateDesiredCaps (caps) {733 if (caps.browserName) {734 if (caps.app) {735 // warn if the capabilities have both `app` and `browser, although this is common with selenium grid736 logger.warn(`The desired capabilities should generally not include both an 'app' and a 'browserName'`);737 }738 if (caps.appPackage) {739 logger.errorAndThrow(`The desired should not include both of an 'appPackage' and a 'browserName'`);740 }741 }742 if (caps.uninstallOtherPackages) {743 try {744 this.parseArray(caps.uninstallOtherPackages);745 } catch (e) {746 logger.errorAndThrow(`Could not parse "uninstallOtherPackages" capability: ${e.message}`);747 }748 }749 return true;750};751helpers.bootstrap = Bootstrap;752helpers.unlocker = unlocker;753export { helpers, SETTINGS_HELPER_PKG_ID };...

Full Screen

Full Screen

ah1.js

Source:ah1.js Github

copy

Full Screen

1import _ from 'lodash';2import path from 'path';3import { exec } from 'teen_process';4import { retry, retryInterval } from 'asyncbox';5import logger from './logger';6import { fs } from 'appium-support';7import { path as unicodeIMEPath } from 'appium-android-ime';8import { path as settingsApkPath } from 'io.appium.settings';9import { path as unlockApkPath } from 'appium-unlock';10import Bootstrap from 'appium-android-bootstrap';11import B from 'bluebird';12import ADB from 'appium-adb';13import { default as unlocker, PIN_UNLOCK, PASSWORD_UNLOCK,14 PATTERN_UNLOCK, FINGERPRINT_UNLOCK } from './unlock-helpers';15const PACKAGE_INSTALL_TIMEOUT = 90000; // milliseconds16const CHROME_BROWSER_PACKAGE_ACTIVITY = {17 chrome: {18 pkg: 'com.android.chrome',19 activity: 'com.google.android.apps.chrome.Main',20 },21 chromium: {22 pkg: 'org.chromium.chrome.shell',23 activity: '.ChromeShellActivity',24 },25 chromebeta: {26 pkg: 'com.chrome.beta',27 activity: 'com.google.android.apps.chrome.Main',28 },29 browser: {30 pkg: 'com.android.browser',31 activity: 'com.android.browser.BrowserActivity',32 },33 'chromium-browser': {34 pkg: 'org.chromium.chrome',35 activity: 'com.google.android.apps.chrome.Main',36 },37 'chromium-webview': {38 pkg: 'org.chromium.webview_shell',39 activity: 'org.chromium.webview_shell.WebViewBrowserActivity',40 },41 default: {42 pkg: 'com.android.chrome',43 activity: 'com.google.android.apps.chrome.Main',44 },45};46const SETTINGS_HELPER_PKG_ID = 'io.appium.settings';47const SETTINGS_HELPER_PKG_ACTIVITY = ".Settings";48const UNLOCK_HELPER_PKG_ID = 'io.appium.unlock';49const UNLOCK_HELPER_PKG_ACTIVITY = ".Unlock";50const UNICODE_IME_PKG_ID = 'io.appium.android.ime';51let helpers = {};52helpers.createBaseADB = async function (opts = {}) {53 // filter out any unwanted options sent in54 // this list should be updated as ADB takes more arguments55 const {56 javaVersion,57 adbPort,58 suppressKillServer,59 remoteAdbHost,60 clearDeviceLogsOnStart,61 adbExecTimeout,62 } = opts;63 return await ADB.createADB({64 javaVersion,65 adbPort,66 suppressKillServer,67 remoteAdbHost,68 clearDeviceLogsOnStart,69 adbExecTimeout,70 });71};72helpers.parseJavaVersion = function (stderr) {73 let lines = stderr.split("\n");74 for (let line of lines) {75 if (new RegExp(/(java|openjdk) version/).test(line)) {76 return line.split(" ")[2].replace(/"/g, '');77 }78 }79 return null;80};81helpers.getJavaVersion = async function (logVersion = true) {82 let {stderr} = await exec('java', ['-version']);83 let javaVer = helpers.parseJavaVersion(stderr);84 if (javaVer === null) {85 throw new Error("Could not get the Java version. Is Java installed?");86 }87 if (logVersion) {88 logger.info(`Java version is: ${javaVer}`);89 }90 return javaVer;91};92helpers.prepareEmulator = async function (adb, opts) {93 let {avd, avdArgs, language, locale, avdLaunchTimeout,94 avdReadyTimeout} = opts;95 if (!avd) {96 throw new Error("Cannot launch AVD without AVD name");97 }98 let avdName = avd.replace('@', '');99 let runningAVD = await adb.getRunningAVD(avdName);100 if (runningAVD !== null) {101 if (avdArgs && avdArgs.toLowerCase().indexOf("-wipe-data") > -1) {102 logger.debug(`Killing '${avdName}' because it needs to be wiped at start.`);103 await adb.killEmulator(avdName);104 } else {105 logger.debug("Not launching AVD because it is already running.");106 return;107 }108 }109 avdArgs = this.prepareAVDArgs(opts, adb, avdArgs);110 await adb.launchAVD(avd, avdArgs, language, locale, avdLaunchTimeout,111 avdReadyTimeout);112};113helpers.prepareAVDArgs = function (opts, adb, avdArgs) {114 let args = avdArgs ? [avdArgs] : [];115 if (!_.isUndefined(opts.networkSpeed)) {116 let networkSpeed = this.ensureNetworkSpeed(adb, opts.networkSpeed);117 args.push('-netspeed', networkSpeed);118 }119 if (opts.isHeadless) {120 args.push('-no-window');121 }122 return args.join(' ');123};124helpers.ensureNetworkSpeed = function (adb, networkSpeed) {125 if (_.values(adb.NETWORK_SPEED).indexOf(networkSpeed) !== -1) {126 return networkSpeed;127 }128 logger.warn(`Wrong network speed param ${networkSpeed}, using default: full. Supported values: ${_.values(adb.NETWORK_SPEED)}`);129 return adb.NETWORK_SPEED.FULL;130};131helpers.ensureDeviceLocale = async function (adb, language, country) {132 if (!_.isString(language) && !_.isString(country)) {133 logger.warn(`setDeviceLanguageCountry requires language or country.`);134 logger.warn(`Got language: '${language}' and country: '${country}'`);135 return;136 }137 await adb.setDeviceLanguageCountry(language, country);138 if (!await adb.ensureCurrentLocale(language, country)) {139 throw new Error(`Failed to set language: ${language} and country: ${country}`);140 }141};142helpers.getDeviceInfoFromCaps = async function (opts = {}) {143 // we can create a throwaway ADB instance here, so there is no dependency144 // on instantiating on earlier (at this point, we have no udid)145 // we can only use this ADB object for commands that would not be confused146 // if multiple devices are connected147 const adb = await helpers.createBaseADB(opts);148 let udid = opts.udid;149 let emPort = null;150 // a specific avd name was given. try to initialize with that151 if (opts.avd) {152 await helpers.prepareEmulator(adb, opts);153 udid = adb.curDeviceId;154 emPort = adb.emulatorPort;155 } else {156 // no avd given. lets try whatever's plugged in devices/emulators157 logger.info("Retrieving device list");158 let devices = await adb.getDevicesWithRetry();159 // udid was given, lets try to init with that device160 if (udid) {161 if (!_.includes(_.map(devices, 'udid'), udid)) {162 logger.errorAndThrow(`Device ${udid} was not in the list ` +163 `of connected devices`);164 }165 emPort = adb.getPortFromEmulatorString(udid);166 } else if (opts.platformVersion) {167 opts.platformVersion = `${opts.platformVersion}`.trim();168 // a platform version was given. lets try to find a device with the same os169 logger.info(`Looking for a device with Android '${opts.platformVersion}'`);170 // in case we fail to find something, give the user a useful log that has171 // the device udids and os versions so they know what's available172 let availDevicesStr = [];173 // first try started devices/emulators174 for (let device of devices) {175 // direct adb calls to the specific device176 await adb.setDeviceId(device.udid);177 let deviceOS = await adb.getPlatformVersion();178 // build up our info string of available devices as we iterate179 availDevicesStr.push(`${device.udid} (${deviceOS})`);180 // we do a begins with check for implied wildcard matching181 // eg: 4 matches 4.1, 4.0, 4.1.3-samsung, etc182 if (deviceOS.indexOf(opts.platformVersion) === 0) {183 udid = device.udid;184 break;185 }186 }187 // we couldn't find anything! quit188 if (!udid) {189 logger.errorAndThrow(`Unable to find an active device or emulator ` +190 `with OS ${opts.platformVersion}. The following ` +191 `are available: ` + availDevicesStr.join(', '));192 }193 emPort = adb.getPortFromEmulatorString(udid);194 } else {195 // a udid was not given, grab the first device we see196 udid = devices[0].udid;197 emPort = adb.getPortFromEmulatorString(udid);198 }199 }200 logger.info(`Using device: ${udid}`);201 return {udid, emPort};202};203// returns a new adb instance with deviceId set204helpers.createADB = async function (opts = {}) {205 const {udid, emPort} = opts;206 const adb = await helpers.createBaseADB(opts);207 adb.setDeviceId(udid);208 if (emPort) {209 adb.setEmulatorPort(emPort);210 }211 return adb;212};213helpers.validatePackageActivityNames = function (opts) {214 for (const key of ['appPackage', 'appActivity', 'appWaitPackage', 'appWaitActivity']) {215 const name = opts[key];216 if (!name) {217 continue;218 }219 const match = /([^\w.*,])+/.exec(name);220 if (!match) {221 continue;222 }223 logger.warn(`Capability '${key}' is expected to only include latin letters, digits, underscore, dot, comma and asterisk characters.`);224 logger.warn(`Current value '${name}' has non-matching character at index ${match.index}: '${name.substring(0, match.index + 1)}'`);225 }226};227helpers.getLaunchInfo = async function (adb, opts) {228 let {app, appPackage, appActivity, appWaitPackage, appWaitActivity} = opts;229 if (!app) {230 logger.warn("No app sent in, not parsing package/activity");231 return;232 }233 this.validatePackageActivityNames(opts);234 if (appPackage && appActivity) {235 return;236 }237 logger.debug("Parsing package and activity from app manifest");238 let {apkPackage, apkActivity} =239 await adb.packageAndLaunchActivityFromManifest(app);240 if (apkPackage && !appPackage) {241 appPackage = apkPackage;242 }243 if (!appWaitPackage) {244 appWaitPackage = appPackage;245 }246 if (apkActivity && !appActivity) {247 appActivity = apkActivity;248 }249 if (!appWaitActivity) {250 appWaitActivity = appActivity;251 }252 logger.debug(`Parsed package and activity are: ${apkPackage}/${apkActivity}`);253 return {appPackage, appWaitPackage, appActivity, appWaitActivity};254};255helpers.resetApp = async function (adb, opts = {}) {256 const {257 app,258 appPackage,259 fastReset,260 fullReset,261 androidInstallTimeout = PACKAGE_INSTALL_TIMEOUT,262 autoGrantPermissions,263 allowTestPackages264 } = opts;265 if (!appPackage) {266 throw new Error("'appPackage' option is required");267 }268 const isInstalled = await adb.isAppInstalled(appPackage);269 if (isInstalled) {270 try {271 await adb.forceStop(appPackage);272 } catch (ign) {}273 // fullReset has priority over fastReset274 if (!fullReset && fastReset) {275 const output = await adb.clear(appPackage);276 if (_.isString(output) && output.toLowerCase().includes('failed')) {277 throw new Error(`Cannot clear the application data of '${appPackage}'. Original error: ${output}`);278 }279 // executing `shell pm clear` resets previously assigned application permissions as well280 if (autoGrantPermissions) {281 try {282 await adb.grantAllPermissions(appPackage);283 } catch (error) {284 logger.error(`Unable to grant permissions requested. Original error: ${error.message}`);285 }286 }287 logger.debug(`Performed fast reset on the installed '${appPackage}' application (stop and clear)`);288 return;289 }290 }291 if (!app) {292 throw new Error("'app' option is required for reinstall");293 }294 logger.debug(`Running full reset on '${appPackage}' (reinstall)`);295 if (isInstalled) {296 await adb.uninstallApk(appPackage);297 }298 await adb.install(app, {299 grantPermissions: autoGrantPermissions,300 timeout: androidInstallTimeout,301 allowTestPackages,302 });303};304helpers.installApk = async function (adb, opts = {}) {305 const {306 app,307 appPackage,308 fastReset,309 fullReset,310 androidInstallTimeout = PACKAGE_INSTALL_TIMEOUT,311 autoGrantPermissions,312 allowTestPackages313 } = opts;314 if (!app || !appPackage) {315 throw new Error("'app' and 'appPackage' options are required");316 }317 if (fullReset) {318 await this.resetApp(adb, opts);319 return;320 }321 // There is no need to reset the newly installed app322 const shouldPerformFastReset = fastReset && await adb.isAppInstalled(appPackage);323 await adb.installOrUpgrade(app, appPackage, {324 grantPermissions: autoGrantPermissions,325 timeout: androidInstallTimeout,326 allowTestPackages,327 });328 if (shouldPerformFastReset) {329 logger.info(`Performing fast reset on '${appPackage}'`);330 await this.resetApp(adb, opts);331 }332};333/**334 * Installs an array of apks335 * @param {ADB} adb Instance of Appium ADB object336 * @param {Object} opts Opts defined in driver.js337 */338helpers.installOtherApks = async function (otherApps, adb, opts) {339 let {340 androidInstallTimeout = PACKAGE_INSTALL_TIMEOUT,341 autoGrantPermissions,342 allowTestPackages343 } = opts;344 // Install all of the APK's asynchronously345 await B.all(otherApps.map((otherApp) => {346 logger.debug(`Installing app: ${otherApp}`);347 return adb.installOrUpgrade(otherApp, null, {348 grantPermissions: autoGrantPermissions,349 timeout: androidInstallTimeout,350 allowTestPackages,351 });352 }));353};354helpers.initUnicodeKeyboard = async function (adb) {355 logger.debug('Enabling Unicode keyboard support');356 logger.debug("Pushing unicode ime to device...");357 try {358 await adb.install(unicodeIMEPath, {replace: false});359 } catch (err) {360 logger.info(`Performing full reinstall of ${UNICODE_IME_PKG_ID} as a possible fix for: ${err.message}`);361 await adb.uninstallApk(UNICODE_IME_PKG_ID);362 await adb.install(unicodeIMEPath, {replace: false});363 }364 // get the default IME so we can return back to it later if we want365 let defaultIME = await adb.defaultIME();366 logger.debug(`Unsetting previous IME ${defaultIME}`);367 const appiumIME = `${UNICODE_IME_PKG_ID}/.UnicodeIME`;368 logger.debug(`Setting IME to '${appiumIME}'`);369 await adb.enableIME(appiumIME);370 await adb.setIME(appiumIME);371 return defaultIME;372};373helpers.setMockLocationApp = async function (adb, app) {374 try {375 if (await adb.getApiLevel() < 23) {376 await adb.shell(['settings', 'put', 'secure', 'mock_location', '1']);377 } else {378 await adb.shell(['appops', 'set', app, 'android:mock_location', 'allow']);379 }380 } catch (err) {381 logger.warn(`Unable to set mock location for app '${app}': ${err.message}`);382 }383};384helpers.installHelperApp = async function (adb, apkPath, packageId, appName) {385 try {386 await adb.installOrUpgrade(apkPath, packageId, {grantPermissions: true});387 } catch (err) {388 logger.warn(`Ignored error while installing Appium ${appName} helper: ` +389 `'${err.message}'. Manually uninstalling the application ` +390 `with package id '${packageId}' may help. Expect some Appium ` +391 `features may not work as expected unless this problem is ` +392 `fixed.`);393 }394};395helpers.pushSettingsApp = async function (adb, throwError = false) {396 logger.debug("Pushing settings apk to device...");397 await helpers.installHelperApp(adb, settingsApkPath, SETTINGS_HELPER_PKG_ID, 'Settings');398 // Reinstall will stop the settings helper process anyway, so399 // there is no need to continue if the application is still running400 if (await adb.processExists(SETTINGS_HELPER_PKG_ID)) {401 logger.debug(`${SETTINGS_HELPER_PKG_ID} is already running. ` +402 `There is no need to reset its permissions.`);403 return;404 }405 // lauch io.appium.settings app due to settings failing to be set406 // if the app is not launched prior to start the session on android 7+407 // see https://github.com/appium/appium/issues/8957408 try {409 await adb.startApp({410 pkg: SETTINGS_HELPER_PKG_ID,411 activity: SETTINGS_HELPER_PKG_ACTIVITY,412 action: "android.intent.action.MAIN",413 category: "android.intent.category.LAUNCHER",414 flags: "0x10200000",415 stopApp: false,416 });417 } catch (err) {418 logger.warn(`Failed to launch settings app: ${err.message}`);419 if (throwError) {420 throw err;421 }422 }423};424helpers.pushUnlock = async function (adb) {425 logger.debug("Pushing unlock helper app to device...");426 await helpers.installHelperApp(adb, unlockApkPath, UNLOCK_HELPER_PKG_ID, 'Unlock');427};428/**429 * Extracts string.xml and converts it to string.json and pushes430 * it to /data/local/tmp/string.json on for use of bootstrap431 * If app is not present to extract string.xml it deletes remote strings.json432 * If app does not have strings.xml we push an empty json object to remote433 *434 * @param {?string} language - Language abbreviation, for example 'fr'. The default language435 * is used if this argument is not defined.436 * @param {Object} adb - The adb mofdule instance.437 * @param {Object} opts - Driver options dictionary.438 * @returns {Object} The dictionary, where string resourtces identifiers are keys439 * along with their corresponding values for the given language or an empty object440 * if no matching resources were extracted.441 */442helpers.pushStrings = async function (language, adb, opts) {443 const remoteDir = '/data/local/tmp';444 const stringsJson = 'strings.json';445 const remoteFile = `${remoteDir}/${stringsJson}`;446 // clean up remote string.json if present447 await adb.rimraf(remoteFile);448 if (_.isEmpty(opts.appPackage) || !(await fs.exists(opts.app))) {449 return {};450 }451 const stringsTmpDir = path.resolve(opts.tmpDir, opts.appPackage);452 try {453 logger.debug('Extracting strings from apk', opts.app, language, stringsTmpDir);454 const {apkStrings, localPath} = await adb.extractStringsFromApk(opts.app, language, stringsTmpDir);455 await adb.push(localPath, remoteDir);456 return apkStrings;457 } catch (err) {458 logger.warn(`Could not get strings, continuing anyway. Original error: ${err.message}`);459 await adb.shell('echo', [`'{}' > ${remoteFile}`]);460 } finally {461 await fs.rimraf(stringsTmpDir);462 }463 return {};464};465helpers.unlockWithUIAutomation = async function (driver, adb, unlockCapabilities) {466 let unlockType = unlockCapabilities.unlockType;467 if (!unlocker.isValidUnlockType(unlockType)) {468 throw new Error(`Invalid unlock type ${unlockType}`);469 }470 let unlockKey = unlockCapabilities.unlockKey;471 if (!unlocker.isValidKey(unlockType, unlockKey)) {472 throw new Error(`Missing unlockKey ${unlockKey} capability for unlockType ${unlockType}`);473 }474 const unlockMethod = {475 [PIN_UNLOCK]: unlocker.pinUnlock,476 [PASSWORD_UNLOCK]: unlocker.passwordUnlock,477 [PATTERN_UNLOCK]: unlocker.patternUnlock,478 [FINGERPRINT_UNLOCK]: unlocker.fingerprintUnlock479 }[unlockType];480 await unlockMethod(adb, driver, unlockCapabilities);481};482helpers.unlockWithHelperApp = async function (adb) {483 logger.info("Unlocking screen");484 try {485 await adb.forceStop(UNLOCK_HELPER_PKG_ID);486 } catch (e) {487 // Sometimes we can see the below error, but we can ignore it.488 // [W3C] Encountered internal error running command: Error: Error executing adbExec. Original error: 'Command 'adb -P 5037 -s emulator-5554 shell am force-stop io.appium.unlock' timed out after 20000ms'; Stderr: ''; Code: 'null'489 logger.warn(`An error in unlockWithHelperApp: ${e.message}`);490 }491 let startOpts = {492 pkg: UNLOCK_HELPER_PKG_ID,493 activity: UNLOCK_HELPER_PKG_ACTIVITY,494 action: "android.intent.action.MAIN",495 category: "android.intent.category.LAUNCHER",496 flags: "0x10200000",497 stopApp: false,498 retry: false,499 waitDuration: 1000500 };501 // Unlock succeed with a couple of retries.502 let firstRun = true;503 await retry(3, async function () {504 // To reduce a time to call adb.isScreenLocked() since `adb shell dumpsys window` is easy to hang adb commands505 if (firstRun) {506 firstRun = false;507 } else {508 try {509 if (!(await adb.isScreenLocked())) {510 return;511 }512 } catch (e) {513 logger.warn(`Error in isScreenLocked: ${e.message}`);514 logger.warn("\"adb shell dumpsys window\" command has timed out.");515 logger.warn("The reason of this timeout is the delayed adb response. Resetting adb server can improve it.");516 }517 }518 logger.info(`Launching ${UNLOCK_HELPER_PKG_ID}`);519 // The command takes too much time so we should not call the command over twice continuously.520 await adb.startApp(startOpts);521 });522};523helpers.unlock = async function (driver, adb, capabilities) {524 if (!(await adb.isScreenLocked())) {525 logger.info("Screen already unlocked, doing nothing");526 return;527 }528 logger.debug("Screen is locked, trying to unlock");529 if (_.isUndefined(capabilities.unlockType)) {530 logger.warn("Using app unlock, this is going to be deprecated!");531 await helpers.unlockWithHelperApp(adb);532 } else {533 await helpers.unlockWithUIAutomation(driver, adb, {unlockType: capabilities.unlockType, unlockKey: capabilities.unlockKey});534 await helpers.verifyUnlock(adb);535 }536};537helpers.verifyUnlock = async function (adb) {538 await retryInterval(2, 1000, async () => {539 if (await adb.isScreenLocked()) {540 throw new Error("Screen did not unlock successfully, retrying");541 }542 logger.debug("Screen unlocked successfully");543 });544};545helpers.initDevice = async function (adb, opts) {546 await adb.waitForDevice();547 // pushSettingsApp required before calling ensureDeviceLocale for API Level 24+548 await helpers.pushSettingsApp(adb);549 if (!opts.avd) {550 await helpers.setMockLocationApp(adb, SETTINGS_HELPER_PKG_ID);551 }552 await helpers.ensureDeviceLocale(adb, opts.language, opts.locale);553 await adb.startLogcat();554 let defaultIME;555 if (opts.unicodeKeyboard) {556 defaultIME = await helpers.initUnicodeKeyboard(adb);557 }558 if (_.isUndefined(opts.unlockType)) {559 await helpers.pushUnlock(adb);560 }561 return defaultIME;562};563helpers.removeNullProperties = function (obj) {564 for (let key of _.keys(obj)) {565 if (_.isNull(obj[key]) || _.isUndefined(obj[key])) {566 delete obj[key];567 }568 }569};570helpers.truncateDecimals = function (number, digits) {571 let multiplier = Math.pow(10, digits),572 adjustedNum = number * multiplier,573 truncatedNum = Math[adjustedNum < 0 ? 'ceil' : 'floor'](adjustedNum);574 return truncatedNum / multiplier;575};576helpers.isChromeBrowser = function (browser) {577 return _.includes(Object.keys(CHROME_BROWSER_PACKAGE_ACTIVITY), (browser || '').toLowerCase());578};579helpers.getChromePkg = function (browser) {580 return CHROME_BROWSER_PACKAGE_ACTIVITY[browser.toLowerCase()] ||581 CHROME_BROWSER_PACKAGE_ACTIVITY.default;582};583helpers.removeAllSessionWebSocketHandlers = async function (server, sessionId) {584 if (!server || !_.isFunction(server.getWebSocketHandlers)) {585 return;586 }587 const activeHandlers = await server.getWebSocketHandlers(sessionId);588 for (const pathname of _.keys(activeHandlers)) {589 await server.removeWebSocketHandler(pathname);590 }591};592/**593 * Takes a desired capability and tries to JSON.parse it as an array,594 * and either returns the parsed array or a singleton array.595 *596 * @param {any} cap A desired capability597 */598helpers.parseArray = function (cap) {599 let parsedCaps;600 try {601 parsedCaps = JSON.parse(cap);602 } catch (ign) { }603 if (_.isArray(parsedCaps)) {604 return parsedCaps;605 } else if (_.isString(cap)) {606 return [cap];607 }608 throw new Error(`must provide a string or JSON Array; received ${cap}`);609};610helpers.validateDesiredCaps = function (caps) {611 // make sure that the capabilities have one of `app`, `appPackage` or `browser`612 if ((!caps.browserName || !this.isChromeBrowser(caps.browserName)) && !caps.app && !caps.appPackage) {613 logger.errorAndThrow('The desired capabilities must include either an app, appPackage or browserName');614 }615 if (caps.browserName) {616 if (caps.app) {617 // warn if the capabilities have both `app` and `browser, although this is common with selenium grid618 logger.warn('The desired capabilities should generally not include both an app and a browserName');619 }620 if (caps.appPackage) {621 logger.errorAndThrow(`The desired capabilities must include either 'appPackage' or 'browserName'`);622 }623 }624 return true;625};626helpers.bootstrap = Bootstrap;627helpers.unlocker = unlocker;...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const AndroidDriver = require('appium-android-driver').AndroidDriver;2const driver = new AndroidDriver();3const avdArgs = driver.prepareAvdArgs({avd: 'Nexus_5X_API_24'});4console.log(avdArgs);5const AndroidDriver = require('appium-android-driver').AndroidDriver;6const driver = new AndroidDriver();7const emulatorArgs = driver.prepareEmulatorArgs({avd: 'Nexus_5X_API_24'});8console.log(emulatorArgs);9const AndroidDriver = require('appium-android-driver').AndroidDriver;10const driver = new AndroidDriver();11const emulatorBinary = driver.prepareEmulatorBinary({avd: 'Nexus_5X_API_24'});12console.log(emulatorBinary);13const AndroidDriver = require('appium-android-driver').AndroidDriver;14const driver = new AndroidDriver();15const apiLevel = driver.getApiLevel();16console.log(apiLevel);17const AndroidDriver = require('appium-android-driver').AndroidDriver;18const driver = new AndroidDriver();19const avdName = driver.getAvdName();20console.log(avdName);21const AndroidDriver = require('appium-android-driver').AndroidDriver;22const driver = new AndroidDriver();23const avd = driver.getAvdFromCaps({avd: 'Nexus_5X_API_24'});24console.log(avd);25const AndroidDriver = require('appium-android-driver').AndroidDriver;

Full Screen

Using AI Code Generation

copy

Full Screen

1var AndroidDriver = require("appium-android-driver");2var androidDriver = new AndroidDriver();3var avdArgs = androidDriver.prepareAvdArgs({avd: "Nexus_5X_API_26"});4console.log(avdArgs);5var AndroidDriver = require("appium-android-driver");6var androidDriver = new AndroidDriver();7var emulatorArgs = androidDriver.prepareEmulatorArgs({avd: "Nexus_5X_API_26"});8console.log(emulatorArgs);9var AndroidDriver = require("appium-android-driver");10var androidDriver = new AndroidDriver();11var emulatorBinary = androidDriver.prepareEmulatorBinary();12console.log(emulatorBinary);13var AndroidDriver = require("appium-android-driver");14var androidDriver = new AndroidDriver();15var device = androidDriver.prepareDevice({avd: "Nexus_5X_API_26"});16console.log(device);17var AndroidDriver = require("appium-android-driver");18var androidDriver = new AndroidDriver();19var emulatorArgs = androidDriver.prepareEmulatorArgs({avd: "Nexus_5X_API_26"});20var emulatorBinary = androidDriver.prepareEmulatorBinary();21var device = androidDriver.prepareDevice({avd: "Nexus_5X_API_26"});22var avd = androidDriver.startAVD(emulatorBinary, emulatorArgs, device);23console.log(avd);

Full Screen

Using AI Code Generation

copy

Full Screen

1const AndroidDriver = require('appium-android-driver');2const avdArgs = AndroidDriver.prepareAvdArgs();3console.log(avdArgs);4const AndroidDriver = require('appium-android-driver');5const emulatorArgs = AndroidDriver.prepareEmulatorArgs();6console.log(emulatorArgs);7const AndroidDriver = require('appium-android-driver');8const emulatorBinary = AndroidDriver.prepareEmulatorBinary();9console.log(emulatorBinary);10const AndroidDriver = require('appium-android-driver');11const adb = AndroidDriver.prepareAdb();12console.log(adb);13const AndroidDriver = require('appium-android-driver');14const avd = AndroidDriver.prepareAvd();15console.log(avd);16const AndroidDriver = require('appium-android-driver');17const aapt = AndroidDriver.prepareAapt();18console.log(aapt);19const AndroidDriver = require('appium-android-driver');20const zipalign = AndroidDriver.prepareZipalign();21console.log(zipalign);22const AndroidDriver = require('appium-android-driver');23const selendroid = AndroidDriver.prepareSelendroid();24console.log(selendroid);25const AndroidDriver = require('appium-android-driver');26const keystore = AndroidDriver.prepareKeystore();27console.log(keystore);28const AndroidDriver = require('appium-android-driver');29const sign = AndroidDriver.prepareSign();30console.log(sign);31const AndroidDriver = require('appium-android-driver');

Full Screen

Using AI Code Generation

copy

Full Screen

1var AndroidDriver = require('appium-android-driver');2var driver = new AndroidDriver();3var avdArgs = driver.prepareAvdArgs({4});5console.log(avdArgs);6var AndroidDriver = require('appium-android-driver');7var driver = new AndroidDriver();8var emulatorBinaryArgs = driver.prepareEmulatorBinaryArgs({9});10console.log(emulatorBinaryArgs);11var AndroidDriver = require('appium-android-driver');12var driver = new AndroidDriver();13var emulatorArgs = driver.prepareEmulatorArgs({14});15console.log(emulatorArgs);16var AndroidDriver = require('appium-android-driver');17var driver = new AndroidDriver();18var emulatorLaunch = driver.prepareEmulatorLaunch({19});20console.log(emulatorLaunch);21var AndroidDriver = require('appium-android-driver');22var driver = new AndroidDriver();23var emulatorBinary = driver.prepareEmulatorBinary({24});25console.log(emulatorBinary);26var AndroidDriver = require('appium-android-driver');27var driver = new AndroidDriver();28var avdName = driver.prepareAvdName({29});30console.log(avdName);

Full Screen

Using AI Code Generation

copy

Full Screen

1const AndroidDriver = require('appium-android-driver').AndroidDriver;2const driver = new AndroidDriver();3const avdArgs = driver.prepareAvdArgs({app: 'app.apk', avd: 'Nexus_5X_API_24'});4console.log(avdArgs);5const AndroidDriver = require('appium-android-driver').AndroidDriver;6const driver = new AndroidDriver();7const emulatorArgs = driver.prepareEmulatorArgs({app: 'app.apk', avd: 'Nexus_5X_API_24'});8console.log(emulatorArgs);9const AndroidDriver = require('appium-android-driver').AndroidDriver;10const driver = new AndroidDriver();11const emulatorBinary = driver.prepareEmulatorBinary({avd: 'Nexus_5X_API_24'});12console.log(emulatorBinary);13const AndroidDriver = require('appium-android-driver').AndroidDriver;14const driver = new AndroidDriver();15const emulatorBinary = driver.prepareAvdBinary({avd: 'Nexus_5X_API_24'});16console.log(emulatorBinary);17const AndroidDriver = require('appium-android-driver').AndroidDriver;18const driver = new AndroidDriver();19const avdFromCaps = driver.prepareAvdFromCaps({avd: 'Nexus_5X_API_24'});20console.log(avdFromCaps);21const AndroidDriver = require('appium-android-driver').AndroidDriver;

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Appium Android Driver automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful