appium-android-driver
Version:
Android UiAutomator and Chrome support for Appium
346 lines • 11.6 kB
JavaScript
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
;