UNPKG

appium-android-driver

Version:

Android UiAutomator and Chrome support for Appium

346 lines 11.6 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.startActivity = startActivity; exports.mobileStartActivity = mobileStartActivity; exports.mobileBroadcast = mobileBroadcast; exports.mobileStartService = mobileStartService; exports.mobileStopService = mobileStopService; const lodash_1 = __importDefault(require("lodash")); const driver_1 = require("appium/driver"); const support_1 = require("@appium/support"); const NO_VALUE_ARG_TYPE = 'sn'; const SUPPORTED_EXTRA_TYPES = [ 's', NO_VALUE_ARG_TYPE, 'z', 'i', 'l', 'f', 'u', 'cn', 'ia', 'ial', 'la', 'lal', 'fa', 'fal', 'sa', 'sal', ]; const API_LEVEL_ANDROID_8 = 26; /** * @deprecated * @this {import('../driver').AndroidDriver} * @param {string} appPackage * @param {string} appActivity * @param {string} [appWaitPackage] * @param {string} [appWaitActivity] * @param {string} [intentAction] * @param {string} [intentCategory] * @param {string} [intentFlags] * @param {string} [optionalIntentArguments] * @param {boolean} [dontStopAppOnReset] * @returns {Promise<void>} */ async function startActivity(appPackage, appActivity, appWaitPackage, appWaitActivity, intentAction, intentCategory, intentFlags, optionalIntentArguments, dontStopAppOnReset) { this.log.debug(`Starting package '${appPackage}' and activity '${appActivity}'`); // dontStopAppOnReset is both an argument here, and a desired capability // if the argument is set, use it, otherwise use the cap if (!support_1.util.hasValue(dontStopAppOnReset)) { dontStopAppOnReset = !!this.opts.dontStopAppOnReset; } /** @type {import('appium-adb').StartAppOptions} */ let args = { pkg: appPackage, activity: appActivity, waitPkg: appWaitPackage || appPackage, waitActivity: appWaitActivity || appActivity, action: intentAction, category: intentCategory, flags: intentFlags, optionalIntentArguments, stopApp: !dontStopAppOnReset, }; this._cachedActivityArgs = this._cachedActivityArgs || {}; this._cachedActivityArgs[`${args.waitPkg}/${args.waitActivity}`] = args; await this.adb.startApp(args); } /** * @this {import('../driver').AndroidDriver} * @param {boolean} [wait] Set it to `true` if you want to block the method call * until the activity manager's process returns the control to the system. * false by default. * @param {boolean} [stop] Set it to `true` to force stop the target * app before starting the activity * false by default. * @param {string | number} [windowingMode] The windowing mode to launch the activity into. * Check * https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/WindowConfiguration.java * for more details on possible windowing modes (constants starting with * `WINDOWING_MODE_`). * @param {string | number} [activityType] The activity type to launch the activity as. * Check https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/WindowConfiguration.java * for more details on possible activity types (constants starting with `ACTIVITY_TYPE_`). * @param {number | string} [display] The display identifier to launch the activity into. * @param {string} [user] * @param {string} [intent] * @param {string} [action] * @param {string} [pkg] * @param {string} [uri] * @param {string} [mimeType] * @param {string} [identifier] * @param {string} [component] * @param {string | string[]} [categories] * @param {string[][]} [extras] * @param {string} [flags] * @returns {Promise<string>} */ async function mobileStartActivity(wait, stop, windowingMode, activityType, display, user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) { const cmd = [ 'am', (await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8 ? 'start' : 'start-activity', ]; if (!lodash_1.default.isNil(user)) { cmd.push('--user', String(user)); } if (wait) { cmd.push('-W'); } if (stop) { cmd.push('-S'); } if (!lodash_1.default.isNil(windowingMode)) { cmd.push('--windowingMode', String(windowingMode)); } if (!lodash_1.default.isNil(activityType)) { cmd.push('--activityType', String(activityType)); } if (!lodash_1.default.isNil(display)) { cmd.push('--display', String(display)); } cmd.push(...parseIntentSpec({ intent, action, package: pkg, uri, mimeType, identifier, component, categories, extras, flags, })); return await this.adb.shell(cmd); } /** * @this {import('../driver').AndroidDriver} * @param {string | number} [user] The user ID for which the broadcast is sent. * The `current` alias assumes the current user ID. * `all` by default. * @param {string} [receiverPermission] Require receiver to hold the given permission. * @param {boolean} [allowBackgroundActivityStarts] Whether the receiver may start activities even if in the background. * @param {string} [intent] * @param {string} [action] * @param {string} [pkg] * @param {string} [uri] * @param {string} [mimeType] * @param {string} [identifier] * @param {string} [component] * @param {string | string[]} [categories] * @param {string[][]} [extras] * @param {string} [flags] * @returns {Promise<string>} */ async function mobileBroadcast(receiverPermission, allowBackgroundActivityStarts, user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) { const cmd = ['am', 'broadcast']; if (!lodash_1.default.isNil(user)) { cmd.push('--user', String(user)); } if (receiverPermission) { cmd.push('--receiver-permission', receiverPermission); } if (allowBackgroundActivityStarts) { cmd.push('--allow-background-activity-starts'); } cmd.push(...parseIntentSpec({ intent, action, package: pkg, uri, mimeType, identifier, component, categories, extras, flags, })); return await this.adb.shell(cmd); } /** * @this {import('../driver').AndroidDriver} * @param {boolean} [foreground] Set it to `true` if your service must be started as foreground service. * This option is ignored if the API level of the device under test is below * 26 (Android 8). * @param {string} [user] * @param {string} [intent] * @param {string} [action] * @param {string} [pkg] * @param {string} [uri] * @param {string} [mimeType] * @param {string} [identifier] * @param {string} [component] * @param {string | string[]} [categories] * @param {string[][]} [extras] * @param {string} [flags] * @returns {Promise<string>} */ async function mobileStartService(foreground, user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) { const cmd = ['am']; if ((await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8) { cmd.push('startservice'); } else { cmd.push(foreground ? 'start-foreground-service' : 'start-service'); } if (!lodash_1.default.isNil(user)) { cmd.push('--user', String(user)); } cmd.push(...parseIntentSpec({ intent, action, package: pkg, uri, mimeType, identifier, component, categories, extras, flags, })); return await this.adb.shell(cmd); } /** * @this {import('../driver').AndroidDriver} * @param {string} [user] * @param {string} [intent] * @param {string} [action] * @param {string} [pkg] * @param {string} [uri] * @param {string} [mimeType] * @param {string} [identifier] * @param {string} [component] * @param {string | string[]} [categories] * @param {string[][]} [extras] * @param {string} [flags] * @returns {Promise<string>} */ async function mobileStopService(user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) { const cmd = [ 'am', (await this.adb.getApiLevel()) < API_LEVEL_ANDROID_8 ? 'stopservice' : 'stop-service', ]; if (!lodash_1.default.isNil(user)) { cmd.push('--user', String(user)); } cmd.push(...parseIntentSpec({ intent, action, package: pkg, uri, mimeType, identifier, component, categories, extras, flags, })); try { return await this.adb.shell(cmd); } catch (e) { // https://github.com/appium/appium-uiautomator2-driver/issues/792 if (e.code === 255 && e.stderr?.includes('Service stopped')) { return e.stderr; } throw e; } } // #region Internal helpers /** * * @param {import('./types').IntentOpts} opts * @returns {string[]} */ function parseIntentSpec(opts = {}) { const { intent, action, uri, mimeType, identifier, categories, component, extras, flags } = opts; const resultArgs = []; if (intent) { resultArgs.push(intent); } if (action) { resultArgs.push('-a', action); } if (uri) { resultArgs.push('-d', uri); } if (mimeType) { resultArgs.push('-t', mimeType); } if (!lodash_1.default.isNil(identifier)) { resultArgs.push('-i', identifier); } if (categories) { if (lodash_1.default.isArray(categories)) { resultArgs.push(...lodash_1.default.flatMap(categories.map((cName) => ['-c', cName]))); } else { resultArgs.push('-c', categories); } } if (component) { resultArgs.push('-n', component); } if (opts.package) { resultArgs.push('-p', opts.package); } if (extras) { if (!lodash_1.default.isArray(extras)) { throw new driver_1.errors.InvalidArgumentError(`'extras' must be an array`); } for (const item of extras) { if (!lodash_1.default.isArray(item)) { throw new driver_1.errors.InvalidArgumentError(`Extra argument '${item}' must be an array`); } const [type, key, value] = item; if (!lodash_1.default.includes(SUPPORTED_EXTRA_TYPES, type)) { throw new driver_1.errors.InvalidArgumentError(`Extra argument type '${type}' is not known. ` + `Supported intent argument types are: ${SUPPORTED_EXTRA_TYPES}`); } if (lodash_1.default.isEmpty(key) || (lodash_1.default.isString(key) && lodash_1.default.trim(key) === '')) { throw new driver_1.errors.InvalidArgumentError(`Extra argument's key in '${JSON.stringify(item)}' must be a valid string identifier`); } if (type === NO_VALUE_ARG_TYPE) { resultArgs.push(`--e${type}`, key); } else if (lodash_1.default.isUndefined(value)) { throw new driver_1.errors.InvalidArgumentError(`Intent argument type '${type}' in '${JSON.stringify(item)}' requires a ` + `valid value to be provided`); } else { resultArgs.push(`--e${type}`, key, value); } } } if (flags) { resultArgs.push('-f', flags); } return resultArgs; } // #endregion /** * @typedef {import('appium-adb').ADB} ADB */ //# sourceMappingURL=intent.js.map