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