UNPKG

appium-android-driver

Version:

Android UiAutomator and Chrome support for Appium

243 lines 10.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNetworkConnection = getNetworkConnection; exports.isWifiOn = isWifiOn; exports.mobileSetConnectivity = mobileSetConnectivity; exports.mobileGetConnectivity = mobileGetConnectivity; exports.setNetworkConnection = setNetworkConnection; exports.setWifiState = setWifiState; exports.setDataState = setDataState; exports.toggleData = toggleData; exports.toggleWiFi = toggleWiFi; exports.toggleFlightMode = toggleFlightMode; const lodash_1 = __importDefault(require("lodash")); const driver_1 = require("appium/driver"); const support_1 = require("@appium/support"); const bluebird_1 = __importDefault(require("bluebird")); const AIRPLANE_MODE_MASK = 0b001; const WIFI_MASK = 0b010; const DATA_MASK = 0b100; const WIFI_KEY_NAME = 'wifi'; const DATA_KEY_NAME = 'data'; const AIRPLANE_MODE_KEY_NAME = 'airplaneMode'; const SUPPORTED_SERVICE_NAMES = [ WIFI_KEY_NAME, DATA_KEY_NAME, AIRPLANE_MODE_KEY_NAME, ]; /** * Gets the current network connection state. * * @returns Promise that resolves to a number representing the network connection state. * The value is a bitmask where: * - Bit 0 (0b001) = Airplane mode * - Bit 1 (0b010) = Wi-Fi * - Bit 2 (0b100) = Data connection */ async function getNetworkConnection() { this.log.info('Getting network connection'); const airplaneModeOn = await this.adb.isAirplaneModeOn(); let connection = airplaneModeOn ? AIRPLANE_MODE_MASK : 0; // no need to check anything else if we are in airplane mode if (!airplaneModeOn) { const wifiOn = await this.isWifiOn(); connection |= wifiOn ? WIFI_MASK : 0; const dataOn = await this.adb.isDataOn(); connection |= dataOn ? DATA_MASK : 0; } return connection; } /** * Checks if Wi-Fi is enabled. * * @returns Promise that resolves to `true` if Wi-Fi is enabled, `false` otherwise. */ async function isWifiOn() { return await this.adb.isWifiOn(); } /** * Sets the connectivity state for Wi-Fi, data, and/or airplane mode. * * @since Android 12 (only real devices, emulators work in all APIs) * @param wifi Either to enable or disable Wi-Fi. * An unset value means to not change the state for the given service. * @param data Either to enable or disable mobile data connection. * An unset value means to not change the state for the given service. * @param airplaneMode Either to enable to disable the Airplane Mode. * An unset value means to not change the state for the given service. * @returns Promise that resolves when the connectivity state is set. * @throws {errors.InvalidArgumentError} If none of the options are provided. */ async function mobileSetConnectivity(wifi, data, airplaneMode) { if (lodash_1.default.every([wifi, data, airplaneMode], lodash_1.default.isUndefined)) { throw new driver_1.errors.InvalidArgumentError(`Either one of ${JSON.stringify(SUPPORTED_SERVICE_NAMES)} options must be provided`); } const services = [ [wifi, WIFI_KEY_NAME], [data, DATA_KEY_NAME], [airplaneMode, AIRPLANE_MODE_KEY_NAME], ].reduce((acc, [value, key]) => { if (!lodash_1.default.isUndefined(value)) { acc.push(key); } return acc; }, []); const currentState = await this.mobileGetConnectivity(services); const setters = []; if (!lodash_1.default.isUndefined(wifi) && currentState.wifi !== Boolean(wifi)) { setters.push(this.setWifiState(wifi)); } if (!lodash_1.default.isUndefined(data) && currentState.data !== Boolean(data)) { setters.push(this.setDataState(data)); } if (!lodash_1.default.isUndefined(airplaneMode) && currentState.airplaneMode !== Boolean(airplaneMode)) { setters.push(async () => { await this.adb.setAirplaneMode(airplaneMode); if ((await this.adb.getApiLevel()) < 30) { await this.adb.broadcastAirplaneMode(airplaneMode); } }); } if (!lodash_1.default.isEmpty(setters)) { await bluebird_1.default.all(setters); } } /** * Gets the connectivity state for one or more services. * * @param services One or more services to get the connectivity for. * @returns Promise that resolves to an object containing the connectivity state for the requested services. * @throws {errors.InvalidArgumentError} If any of the provided service names are not supported. */ async function mobileGetConnectivity(services = SUPPORTED_SERVICE_NAMES) { const svcs = lodash_1.default.castArray(services); const unsupportedServices = lodash_1.default.difference(svcs, SUPPORTED_SERVICE_NAMES); if (!lodash_1.default.isEmpty(unsupportedServices)) { throw new driver_1.errors.InvalidArgumentError(`${support_1.util.pluralize('Service name', unsupportedServices.length, false)} ${unsupportedServices} ` + `${unsupportedServices.length === 1 ? 'is' : 'are'} not known. Only the following services are ` + `suported: ${SUPPORTED_SERVICE_NAMES}`); } const statePromises = { wifi: bluebird_1.default.resolve(svcs.includes(WIFI_KEY_NAME) ? this.adb.isWifiOn() : undefined), data: bluebird_1.default.resolve(svcs.includes(DATA_KEY_NAME) ? this.adb.isDataOn() : undefined), airplaneMode: bluebird_1.default.resolve(svcs.includes(AIRPLANE_MODE_KEY_NAME) ? this.adb.isAirplaneModeOn() : undefined), }; await bluebird_1.default.all(lodash_1.default.values(statePromises)); return lodash_1.default.reduce(statePromises, (state, v, k) => lodash_1.default.isUndefined(v.value()) ? state : { ...state, [k]: Boolean(v.value()) }, {}); } /** * Sets the network connection state using a bitmask. * * @since Android 12 (only real devices, emulators work in all APIs) * @param type A number representing the desired network connection state. * The value is a bitmask where: * - Bit 0 (0b001) = Airplane mode * - Bit 1 (0b010) = Wi-Fi * - Bit 2 (0b100) = Data connection * @returns Promise that resolves to the current network connection state after the change. */ async function setNetworkConnection(type) { this.log.info('Setting network connection'); // decode the input const shouldEnableAirplaneMode = (type & AIRPLANE_MODE_MASK) !== 0; const shouldEnableWifi = (type & WIFI_MASK) !== 0; const shouldEnableDataConnection = (type & DATA_MASK) !== 0; const currentState = await this.getNetworkConnection(); const isAirplaneModeEnabled = (currentState & AIRPLANE_MODE_MASK) !== 0; const isWiFiEnabled = (currentState & WIFI_MASK) !== 0; const isDataEnabled = (currentState & DATA_MASK) !== 0; if (shouldEnableAirplaneMode !== isAirplaneModeEnabled) { await this.adb.setAirplaneMode(shouldEnableAirplaneMode); if ((await this.adb.getApiLevel()) < 30) { await this.adb.broadcastAirplaneMode(shouldEnableAirplaneMode); } } else { this.log.info(`Not changing airplane mode, since it is already ${shouldEnableAirplaneMode ? 'enabled' : 'disabled'}`); } if (shouldEnableWifi === isWiFiEnabled && shouldEnableDataConnection === isDataEnabled) { this.log.info('Not changing data connection/Wi-Fi states, since they are already set to expected values'); if (await this.adb.isAirplaneModeOn()) { return AIRPLANE_MODE_MASK | currentState; } return ~AIRPLANE_MODE_MASK & currentState; } if (shouldEnableWifi !== isWiFiEnabled) { await this.setWifiState(shouldEnableWifi); } else { this.log.info(`Not changing Wi-Fi state, since it is already ` + `${shouldEnableWifi ? 'enabled' : 'disabled'}`); } if (shouldEnableAirplaneMode) { this.log.info('Not changing data connection state, because airplane mode is enabled'); } else if (shouldEnableDataConnection === isDataEnabled) { this.log.info(`Not changing data connection state, since it is already ` + `${shouldEnableDataConnection ? 'enabled' : 'disabled'}`); } else { await this.setDataState(shouldEnableDataConnection); } return await this.getNetworkConnection(); } /** * Sets the Wi-Fi state. * * @since Android 12 (only real devices, emulators work in all APIs) * @param isOn `true` to enable Wi-Fi, `false` to disable it. * @returns Promise that resolves when the Wi-Fi state is set. */ async function setWifiState(isOn) { await this.settingsApp.setWifiState(isOn, this.isEmulator()); } /** * Sets the mobile data connection state. * * @since Android 12 (only real devices, emulators work in all APIs) * @param isOn `true` to enable mobile data, `false` to disable it. * @returns Promise that resolves when the data connection state is set. */ async function setDataState(isOn) { await this.settingsApp.setDataState(isOn, this.isEmulator()); } /** * Toggles the mobile data connection state. * * @since Android 12 (only real devices, emulators work in all APIs) * @returns Promise that resolves when the data connection state is toggled. */ async function toggleData() { const isOn = await this.adb.isDataOn(); this.log.info(`Turning network data ${!isOn ? 'on' : 'off'}`); await this.setDataState(!isOn); } /** * Toggles the Wi-Fi state. * * @since Android 12 (only real devices, emulators work in all APIs) * @returns Promise that resolves when the Wi-Fi state is toggled. */ async function toggleWiFi() { const isOn = await this.adb.isWifiOn(); this.log.info(`Turning WiFi ${!isOn ? 'on' : 'off'}`); await this.setWifiState(!isOn); } /** * Toggles the airplane mode state. * * @since Android 12 (only real devices, emulators work in all APIs) * @returns Promise that resolves when the airplane mode state is toggled. */ async function toggleFlightMode() { const flightMode = !(await this.adb.isAirplaneModeOn()); this.log.info(`Turning flight mode ${flightMode ? 'on' : 'off'}`); await this.adb.setAirplaneMode(flightMode); if ((await this.adb.getApiLevel()) < 30) { await this.adb.broadcastAirplaneMode(flightMode); } } //# sourceMappingURL=network.js.map