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