diff --git a/src/main/java/io/appium/java_client/MobileCommand.java b/src/main/java/io/appium/java_client/MobileCommand.java index c58997068..bba0a77aa 100644 --- a/src/main/java/io/appium/java_client/MobileCommand.java +++ b/src/main/java/io/appium/java_client/MobileCommand.java @@ -85,6 +85,13 @@ public class MobileCommand { protected static final String GET_SETTINGS; protected static final String SET_SETTINGS; protected static final String GET_CURRENT_PACKAGE; + protected static final String SEND_SMS; + protected static final String GSM_CALL; + protected static final String GSM_SIGNAL; + protected static final String GSM_VOICE; + protected static final String NETWORK_SPEED; + protected static final String POWER_CAPACITY; + protected static final String POWER_AC_STATE; public static final Map commandRepository; @@ -137,6 +144,13 @@ public class MobileCommand { GET_SETTINGS = "getSettings"; SET_SETTINGS = "setSettings"; GET_CURRENT_PACKAGE = "getCurrentPackage"; + SEND_SMS = "sendSMS"; + GSM_CALL = "gsmCall"; + GSM_SIGNAL = "gsmSignal"; + GSM_VOICE = "gsmVoice"; + NETWORK_SPEED = "networkSpeed"; + POWER_CAPACITY = "powerCapacity"; + POWER_AC_STATE = "powerAC"; commandRepository = new HashMap<>(); commandRepository.put(RESET, postC("/session/:sessionId/appium/app/reset")); @@ -198,6 +212,13 @@ public class MobileCommand { commandRepository.put(UNLOCK, postC("/session/:sessionId/appium/device/unlock")); commandRepository.put(REPLACE_VALUE, postC("/session/:sessionId/appium/element/:id/replace_value")); commandRepository.put(GET_CURRENT_PACKAGE, getC("/session/:sessionId/appium/device/current_package")); + commandRepository.put(SEND_SMS, postC("/session/:sessionId/appium/device/send_sms")); + commandRepository.put(GSM_CALL, postC("/session/:sessionId/appium/device/gsm_call")); + commandRepository.put(GSM_SIGNAL, postC("/session/:sessionId/appium/device/gsm_signal")); + commandRepository.put(GSM_VOICE, postC("/session/:sessionId/appium/device/gsm_voice")); + commandRepository.put(NETWORK_SPEED, postC("/session/:sessionId/appium/device/network_speed")); + commandRepository.put(POWER_CAPACITY, postC("/session/:sessionId/appium/device/power_capacity")); + commandRepository.put(POWER_AC_STATE, postC("/session/:sessionId/appium/device/power_ac")); } /** diff --git a/src/main/java/io/appium/java_client/android/AndroidDriver.java b/src/main/java/io/appium/java_client/android/AndroidDriver.java index 8b822337d..d676cfb93 100644 --- a/src/main/java/io/appium/java_client/android/AndroidDriver.java +++ b/src/main/java/io/appium/java_client/android/AndroidDriver.java @@ -51,7 +51,8 @@ public class AndroidDriver extends AppiumDriver implements PressesKeyCode, HasNetworkConnection, PushesFiles, StartsActivity, FindsByAndroidUIAutomator, LocksDevice, HasAndroidSettings, HasDeviceDetails, - HasSupportedPerformanceDataType, AuthenticatesByFinger, CanRecordScreen { + HasSupportedPerformanceDataType, AuthenticatesByFinger, + CanRecordScreen, SupportsSpecialEmulatorCommands { private static final String ANDROID_PLATFORM = MobilePlatform.ANDROID; @@ -175,5 +176,4 @@ public void openNotifications() { public void toggleLocationServices() { CommandExecutionHelper.execute(this, toggleLocationServicesCommand()); } - } diff --git a/src/main/java/io/appium/java_client/android/AndroidMobileCommandHelper.java b/src/main/java/io/appium/java_client/android/AndroidMobileCommandHelper.java index c82c324a4..5066ce2a6 100644 --- a/src/main/java/io/appium/java_client/android/AndroidMobileCommandHelper.java +++ b/src/main/java/io/appium/java_client/android/AndroidMobileCommandHelper.java @@ -291,4 +291,109 @@ public class AndroidMobileCommandHelper extends MobileCommand { return new AbstractMap.SimpleEntry<>( REPLACE_VALUE, prepareArguments(parameters, values)); } + + /** + * This method forms a {@link Map} of parameters for the element + * value replacement. It is used against input elements + * + * @param phoneNumber The phone number of message sender + * @param message The message content + * + * @return a key-value pair. The key is the command name. The value is a {@link Map} command arguments. + */ + public static Map.Entry> sendSMSCommand( + String phoneNumber, String message) { + ImmutableMap parameters = ImmutableMap + .builder().put("phoneNumber", phoneNumber) + .put("message", message) + .build(); + + return new AbstractMap.SimpleEntry<>(SEND_SMS, parameters); + } + + /** + * This method forms a {@link Map} of parameters for the element + * value replacement. It is used against input elements + * + * @param phoneNumber The phone number of message sender + * @param gsmCallActions One of available GSM call actions + * + * @return a key-value pair. The key is the command name. The value is a {@link Map} command arguments. + */ + public static Map.Entry> gsmCallCommand( + String phoneNumber, GsmCallActions gsmCallActions) { + String[] parameters = new String[] {"phoneNumber", "action"}; + Object[] values = new Object[]{phoneNumber, gsmCallActions.name().toLowerCase()}; + return new AbstractMap.SimpleEntry<>(GSM_CALL, prepareArguments(parameters, values)); + } + + /** + * This method forms a {@link Map} of parameters for the element + * value replacement. It is used against input elements + * + * @param gsmSignalStrength One of available GSM signal strength + * + * @return a key-value pair. The key is the command name. The value is a {@link Map} command arguments. + */ + public static Map.Entry> gsmSignalStrengthCommand( + GsmSignalStrength gsmSignalStrength) { + return new AbstractMap.SimpleEntry<>(GSM_SIGNAL, + prepareArguments("signalStrengh", gsmSignalStrength.ordinal())); + } + + /** + * This method forms a {@link Map} of parameters for the element + * value replacement. It is used against input elements + * + * @param gsmVoiceState One of available GSM voice state + * + * @return a key-value pair. The key is the command name. The value is a {@link Map} command arguments. + */ + public static Map.Entry> gsmVoiceCommand( + GsmVoiceState gsmVoiceState) { + return new AbstractMap.SimpleEntry<>(GSM_VOICE, + prepareArguments("state", gsmVoiceState.name().toLowerCase())); + } + + /** + * This method forms a {@link Map} of parameters for the element + * value replacement. It is used against input elements + * + * @param networkSpeed One of possible NETWORK_SPEED values + * + * @return a key-value pair. The key is the command name. The value is a {@link Map} command arguments. + */ + public static Map.Entry> networkSpeedCommand( + NetworkSpeed networkSpeed) { + return new AbstractMap.SimpleEntry<>(NETWORK_SPEED, + prepareArguments("netspeed", networkSpeed.name().toLowerCase())); + } + + /** + * This method forms a {@link Map} of parameters for the element + * value replacement. It is used against input elements + * + * @param percent A number in range [0, 4] + * + * @return a key-value pair. The key is the command name. The value is a {@link Map} command arguments. + */ + public static Map.Entry> powerCapacityCommand( + int percent) { + return new AbstractMap.SimpleEntry<>(POWER_CAPACITY, + prepareArguments("percent", percent)); + } + + /** + * This method forms a {@link Map} of parameters for the element + * value replacement. It is used against input elements + * + * @param powerACState One of available power AC state + * + * @return a key-value pair. The key is the command name. The value is a {@link Map} command arguments. + */ + public static Map.Entry> powerACCommand( + PowerACState powerACState) { + return new AbstractMap.SimpleEntry<>(POWER_AC_STATE, + prepareArguments("state", powerACState.name().toLowerCase())); + } } diff --git a/src/main/java/io/appium/java_client/android/GsmCallActions.java b/src/main/java/io/appium/java_client/android/GsmCallActions.java new file mode 100644 index 000000000..443d85a09 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/GsmCallActions.java @@ -0,0 +1,5 @@ +package io.appium.java_client.android; + +public enum GsmCallActions { + CALL, ACCEPT, CANCEL, HOLD +} diff --git a/src/main/java/io/appium/java_client/android/GsmSignalStrength.java b/src/main/java/io/appium/java_client/android/GsmSignalStrength.java new file mode 100644 index 000000000..a73513df2 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/GsmSignalStrength.java @@ -0,0 +1,5 @@ +package io.appium.java_client.android; + +public enum GsmSignalStrength { + NONE_OR_UNKNOWN, POOR, MODERATE, GOOD, GREAT +} diff --git a/src/main/java/io/appium/java_client/android/GsmVoiceState.java b/src/main/java/io/appium/java_client/android/GsmVoiceState.java new file mode 100644 index 000000000..e92cde951 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/GsmVoiceState.java @@ -0,0 +1,5 @@ +package io.appium.java_client.android; + +public enum GsmVoiceState { + ON, OFF, DENIED, SEARCHING, ROAMING, HOME, UNREGISTERED +} diff --git a/src/main/java/io/appium/java_client/android/NetworkSpeed.java b/src/main/java/io/appium/java_client/android/NetworkSpeed.java new file mode 100644 index 000000000..64cdc513d --- /dev/null +++ b/src/main/java/io/appium/java_client/android/NetworkSpeed.java @@ -0,0 +1,5 @@ +package io.appium.java_client.android; + +public enum NetworkSpeed { + GSM, SCSD, GPRS, EDGE, UMTS, HSDPA, LTE, EVDO, FULL +} diff --git a/src/main/java/io/appium/java_client/android/PowerACState.java b/src/main/java/io/appium/java_client/android/PowerACState.java new file mode 100644 index 000000000..ab845c925 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/PowerACState.java @@ -0,0 +1,5 @@ +package io.appium.java_client.android; + +public enum PowerACState { + ON, OFF +} diff --git a/src/main/java/io/appium/java_client/android/SupportsSpecialEmulatorCommands.java b/src/main/java/io/appium/java_client/android/SupportsSpecialEmulatorCommands.java new file mode 100644 index 000000000..9da6dfaec --- /dev/null +++ b/src/main/java/io/appium/java_client/android/SupportsSpecialEmulatorCommands.java @@ -0,0 +1,81 @@ +package io.appium.java_client.android; + +import static io.appium.java_client.android.AndroidMobileCommandHelper.gsmCallCommand; +import static io.appium.java_client.android.AndroidMobileCommandHelper.gsmSignalStrengthCommand; +import static io.appium.java_client.android.AndroidMobileCommandHelper.gsmVoiceCommand; +import static io.appium.java_client.android.AndroidMobileCommandHelper.networkSpeedCommand; +import static io.appium.java_client.android.AndroidMobileCommandHelper.powerACCommand; +import static io.appium.java_client.android.AndroidMobileCommandHelper.powerCapacityCommand; +import static io.appium.java_client.android.AndroidMobileCommandHelper.sendSMSCommand; + +import io.appium.java_client.CommandExecutionHelper; +import io.appium.java_client.ExecutesMethod; + +public interface SupportsSpecialEmulatorCommands extends ExecutesMethod { + + /** + * Emulate send SMS event on the connected emulator. + * + * @param phoneNumber The phone number of message sender. + * @param message The message content. + */ + default void sendSMS(String phoneNumber, String message) { + CommandExecutionHelper.execute(this, sendSMSCommand(phoneNumber, message)); + } + + /** + * Emulate GSM call event on the connected emulator. + * + * @param phoneNumber The phone number of the caller. + * @param gsmCallActions One of available {@link GsmCallActions} values. + */ + default void makeGsmCall(String phoneNumber, GsmCallActions gsmCallActions) { + CommandExecutionHelper.execute(this, gsmCallCommand(phoneNumber, gsmCallActions)); + } + + /** + * Emulate GSM signal strength change event on the connected emulator. + * + * @param gsmSignalStrength One of available {@link GsmSignalStrength} values. + */ + default void setGsmSignalStrength(GsmSignalStrength gsmSignalStrength) { + CommandExecutionHelper.execute(this, gsmSignalStrengthCommand(gsmSignalStrength)); + } + + /** + * Emulate GSM voice event on the connected emulator. + * + * @param gsmVoiceState One of available {@link GsmVoiceState} values. + */ + default void setGsmVoice(GsmVoiceState gsmVoiceState) { + CommandExecutionHelper.execute(this, gsmVoiceCommand(gsmVoiceState)); + } + + /** + * Emulate network speed change event on the connected emulator. + * + * @param networkSpeed One of available {@link NetworkSpeed} values. + */ + default void setNetworkSpeed(NetworkSpeed networkSpeed) { + CommandExecutionHelper.execute(this, networkSpeedCommand(networkSpeed)); + } + + /** + * Emulate power capacity change on the connected emulator. + * + * @param percent Percentage value in range [0, 100]. + */ + default void setPowerCapacity(int percent) { + CommandExecutionHelper.execute(this, powerCapacityCommand(percent)); + } + + /** + * Emulate power state change on the connected emulator. + * + * @param powerACState One of available {@link PowerACState} values. + */ + default void setPowerAC(PowerACState powerACState) { + CommandExecutionHelper.execute(this, powerACCommand(powerACState)); + } + +} diff --git a/src/test/java/io/appium/java_client/android/AndroidDriverTest.java b/src/test/java/io/appium/java_client/android/AndroidDriverTest.java index acbf1adb2..91292742e 100644 --- a/src/test/java/io/appium/java_client/android/AndroidDriverTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidDriverTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; @@ -37,6 +38,56 @@ public class AndroidDriverTest extends BaseAndroidTest { + @Test public void sendSMSTest() { + try { + driver.sendSMS("11111111", "call"); + } catch (Exception e) { + fail("method works only in emulators"); + } + } + + @Test public void gsmCallTest() { + try { + driver.makeGsmCall("11111111", GsmCallActions.CALL); + driver.makeGsmCall("11111111", GsmCallActions.ACCEPT); + } catch (Exception e) { + fail("method works only in emulators"); + } + } + + @Test public void gsmSignalStrengthTest() { + try { + driver.setGsmSignalStrength(GsmSignalStrength.GREAT); + } catch (Exception e) { + fail("method works only in emulators"); + } + } + + @Test public void gsmVoiceTest() { + try { + driver.setGsmVoice(GsmVoiceState.OFF); + } catch (Exception e) { + fail("method works only in emulators"); + } + } + + @Test public void networkSpeedTest() { + try { + driver.setNetworkSpeed(NetworkSpeed.EDGE); + } catch (Exception e) { + fail("method works only in emulators"); + } + } + + @Test public void powerTest() { + try { + driver.setPowerCapacity(100); + driver.setPowerAC(PowerACState.OFF); + } catch (Exception e) { + fail("method works only in emulators"); + } + } + @Test public void getDeviceTimeTest() { String time = driver.getDeviceTime(); assertTrue(time.length() == 28);