UNPKG

appium-android-driver

Version:

Android UiAutomator and Chrome support for Appium

346 lines 13.4 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', ]; /** * Starts an Android activity. * * @deprecated Use {@link mobileStartActivity} instead. * @param appPackage The package name of the application to start. * @param appActivity The activity name to start. * @param appWaitPackage The package name to wait for. Defaults to `appPackage` if not provided. * @param appWaitActivity The activity name to wait for. Defaults to `appActivity` if not provided. * @param intentAction The intent action to use. * @param intentCategory The intent category to use. * @param intentFlags The intent flags to use. * @param optionalIntentArguments Optional intent arguments. * @param dontStopAppOnReset If `true`, does not stop the app on reset. If not provided, uses the capability value. * @returns Promise that resolves when the activity is started. */ 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; } const 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); } /** * Starts an Android activity using the activity manager. * * @param 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 stop Set it to `true` to force stop the target * app before starting the activity. `false` by default. * @param 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 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 display The display identifier to launch the activity into. * @param user The user ID for which the activity is started. * @param intent The name of the activity intent to start, for example * `com.some.package.name/.YourActivitySubClassName`. * @param action Action name. * @param pkg Package name. * @param uri Unified resource identifier. * @param mimeType Mime type. * @param identifier Optional identifier. * @param component Component name. * @param categories One or more category names. * @param extras Optional intent arguments. Must be represented as array of arrays, * where each subarray item contains two or three string items: value type, key name and the value itself. * See {@link IntentOpts} for supported value types. * @param flags Intent startup-specific flags as a hexadecimal string. * @returns Promise that resolves to the command output string. */ async function mobileStartActivity(wait, stop, windowingMode, activityType, display, user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) { const cmd = [ 'am', '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); } /** * Sends a broadcast intent to the Android system. * * @param receiverPermission Require receiver to hold the given permission. * @param allowBackgroundActivityStarts Whether the receiver may start activities even if in the background. * @param user The user ID for which the broadcast is sent. * The `current` alias assumes the current user ID. `all` by default. * @param intent The name of the activity intent to broadcast, for example * `com.some.package.name/.YourServiceSubClassName`. * @param action Action name. * @param pkg Package name. * @param uri Unified resource identifier. * @param mimeType Mime type. * @param identifier Optional identifier. * @param component Component name. * @param categories One or more category names. * @param extras Optional intent arguments. Must be represented as array of arrays, * where each subarray item contains two or three string items: value type, key name and the value itself. * See {@link IntentOpts} for supported value types. * @param flags Intent startup-specific flags as a hexadecimal string. * @returns Promise that resolves to the command output 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); } /** * Starts an Android service. * * @param 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 user The user ID for which the service is started. * The `current` user id is used by default. * @param intent The name of the activity intent to start, for example * `com.some.package.name/.YourServiceSubClassName`. * @param action Action name. * @param pkg Package name. * @param uri Unified resource identifier. * @param mimeType Mime type. * @param identifier Optional identifier. * @param component Component name. * @param categories One or more category names. * @param extras Optional intent arguments. Must be represented as array of arrays, * where each subarray item contains two or three string items: value type, key name and the value itself. * See {@link IntentOpts} for supported value types. * @param flags Intent startup-specific flags as a hexadecimal string. * @returns Promise that resolves to the command output string. */ async function mobileStartService(foreground, user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) { const cmd = ['am']; 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); } /** * Stops an Android service. * * @param user The user ID for which the service is stopped. * @param intent The name of the activity intent to stop, for example * `com.some.package.name/.YourServiceSubClassName`. * @param action Action name. * @param pkg Package name. * @param uri Unified resource identifier. * @param mimeType Mime type. * @param identifier Optional identifier. * @param component Component name. * @param categories One or more category names. * @param extras Optional intent arguments. Must be represented as array of arrays, * where each subarray item contains two or three string items: value type, key name and the value itself. * See {@link IntentOpts} for supported value types. * @param flags Intent startup-specific flags as a hexadecimal string. * @returns Promise that resolves to the command output string. * If the service was already stopped, returns the error message. */ async function mobileStopService(user, intent, action, pkg, uri, mimeType, identifier, component, categories, extras, flags) { const cmd = [ 'am', '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 const err = e; if (err.code === 255 && err.stderr?.includes('Service stopped')) { return err.stderr; } throw e; } } // #region Internal helpers 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 (!SUPPORTED_EXTRA_TYPES.includes(type)) { throw new driver_1.errors.InvalidArgumentError(`Extra argument type '${type}' is not known. ` + `Supported intent argument types are: ${SUPPORTED_EXTRA_TYPES.join(', ')}`); } 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 //# sourceMappingURL=intent.js.map