UNPKG

io.appium.settings

Version:
168 lines 7.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SettingsApp = void 0; const logger_1 = require("./logger"); const asyncbox_1 = require("asyncbox"); const constants_1 = require("./constants"); const animation_1 = require("./commands/animation"); const bluetooth_1 = require("./commands/bluetooth"); const clipboard_1 = require("./commands/clipboard"); const geolocation_1 = require("./commands/geolocation"); const locale_1 = require("./commands/locale"); const media_1 = require("./commands/media"); const network_1 = require("./commands/network"); const notifications_1 = require("./commands/notifications"); const sms_1 = require("./commands/sms"); const typing_1 = require("./commands/typing"); const media_projection_1 = require("./commands/media-projection"); class SettingsApp { adb; log; constructor(opts) { this.adb = opts.adb; this.log = logger_1.log; } /** * Ensures that Appium Settings helper application is running * and starts it if necessary * * @param opts Startup options * @throws {Error} If Appium Settings has failed to start * @returns Self instance for chaining */ async requireRunning(opts = {}) { const { timeout = 5000, shouldRestoreCurrentApp = false, forceRestart = false, } = opts; if (forceRestart) { await this.adb.forceStop(constants_1.SETTINGS_HELPER_ID); } else if (await this.isRunningInForeground()) { return this; } this.log.debug(logger_1.LOG_PREFIX, 'Starting Appium Settings app'); let appPackage; if (shouldRestoreCurrentApp) { try { const result = await this.adb.getFocusedPackageAndActivity(); appPackage = result.appPackage ?? undefined; } catch (e) { this.log.warn(logger_1.LOG_PREFIX, `The current application can not be restored: ${e.message}`); } } await this.adb.startApp({ pkg: constants_1.SETTINGS_HELPER_ID, activity: constants_1.SETTINGS_HELPER_MAIN_ACTIVITY, action: 'android.intent.action.MAIN', category: 'android.intent.category.LAUNCHER', stopApp: false, waitForLaunch: false, }); try { await (0, asyncbox_1.waitForCondition)(async () => await this.isRunningInForeground(), { waitMs: timeout, intervalMs: 300, }); if (shouldRestoreCurrentApp && appPackage) { try { await this.adb.activateApp(appPackage); } catch (e) { logger_1.log.warn(`The current application can not be restored: ${e.message}`); } } return this; } catch { throw new Error(`Appium Settings app is not running after ${timeout}ms`); } } /** * If the io.appium.settings package has running foreground service. * * @throws {Error} If the method gets an error in the adb shell execution * @returns Return true if the device Settings app has a service running in foreground */ async isRunningInForeground() { // 'dumpsys activity services <package>' had slightly better performance // than 'dumpsys activity services' and parsing the foreground apps. const output = await this.adb.shell(['dumpsys', 'activity', 'services', constants_1.SETTINGS_HELPER_ID]); return output.includes('isForeground=true'); } /** * Performs broadcast and verifies the result of it * * @param args Arguments passed to the `am broadcast` command * @param action The exception message in case of broadcast failure * @param requireRunningApp Whether to run a check for a running Appium Settings app * @returns The broadcast output * @throws {Error} If the broadcast fails */ async checkBroadcast(args, action, requireRunningApp = true) { if (requireRunningApp) { await this.requireRunning({ shouldRestoreCurrentApp: true }); } const output = await this.adb.shell([ 'am', 'broadcast', ...args, ]); if (!output.includes('result=-1')) { this.log.debug(logger_1.LOG_PREFIX, output); const error = new Error(`Cannot execute the '${action}' action. Check the logcat output for more details.`); error.output = output; throw error; } return output; } /** * Parses the output in JSON format retrieved from * the corresponding Appium Settings broadcast calls * * @param output The actual command output * @param entityName The name of the entity which is going to be parsed * @returns The parsed JSON object * @throws {Error} If the output cannot be parsed as a valid JSON */ _parseJsonData(output, entityName) { if (!/\bresult=-1\b/.test(output) || !/\bdata="/.test(output)) { this.log.debug(logger_1.LOG_PREFIX, output); throw new Error(`Cannot retrieve ${entityName} from the device. ` + 'Check the server log for more details'); } const match = /\bdata="(.+)",?/.exec(output); if (!match) { this.log.debug(logger_1.LOG_PREFIX, output); throw new Error(`Cannot parse ${entityName} from the command output. ` + 'Check the server log for more details'); } const jsonStr = match[1].trim(); try { return JSON.parse(jsonStr); } catch { logger_1.log.debug(jsonStr); throw new Error(`Cannot parse ${entityName} from the resulting data string. ` + 'Check the server log for more details'); } } setAnimationState = animation_1.setAnimationState; setBluetoothState = bluetooth_1.setBluetoothState; unpairAllBluetoothDevices = bluetooth_1.unpairAllBluetoothDevices; getClipboard = clipboard_1.getClipboard; setGeoLocation = geolocation_1.setGeoLocation; getGeoLocation = geolocation_1.getGeoLocation; refreshGeoLocationCache = geolocation_1.refreshGeoLocationCache; listSupportedLocales = locale_1.listSupportedLocales; setDeviceLocale = locale_1.setDeviceLocale; scanMedia = media_1.scanMedia; setDataState = network_1.setDataState; setWifiState = network_1.setWifiState; getNotifications = notifications_1.getNotifications; adjustNotificationsPermissions = notifications_1.adjustNotificationsPermissions; getSmsList = sms_1.getSmsList; performEditorAction = typing_1.performEditorAction; typeUnicode = typing_1.typeUnicode; makeMediaProjectionRecorder = media_projection_1.makeMediaProjectionRecorder; adjustMediaProjectionServicePermissions = media_projection_1.adjustMediaProjectionServicePermissions; } exports.SettingsApp = SettingsApp; //# sourceMappingURL=client.js.map