diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index debd404d3..38c80bf6d 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -32,6 +32,7 @@ import org.openqa.selenium.MutableCapabilities; import org.openqa.selenium.OutputType; import org.openqa.selenium.SessionNotCreatedException; +import org.openqa.selenium.UnsupportedCommandException; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.remote.CapabilityType; import org.openqa.selenium.remote.DriverCommand; @@ -48,7 +49,9 @@ import java.net.URL; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import static io.appium.java_client.internal.CapabilityHelpers.APPIUM_PREFIX; import static io.appium.java_client.remote.MobileCapabilityType.AUTOMATION_NAME; @@ -64,6 +67,7 @@ public class AppiumDriver extends RemoteWebDriver implements ExecutesDriverScript, LogsEvents, HasBrowserCheck, + CanRememberExtensionPresence, HasSettings { private static final ErrorHandler errorHandler = new ErrorHandler(new ErrorCodesMobile(), true); @@ -71,6 +75,7 @@ public class AppiumDriver extends RemoteWebDriver implements private final URL remoteAddress; protected final RemoteLocationContext locationContext; private final ExecuteMethod executeMethod; + private final Set absentExtensionNames = new HashSet<>(); /** * Creates a new instance based on command {@code executor} and {@code capabilities}. @@ -327,4 +332,18 @@ public X convertFromPngBytes(byte[] png) { } }); } + + @Override + public AppiumDriver assertExtensionExists(String extName) { + if (absentExtensionNames.contains(extName)) { + throw new UnsupportedCommandException(); + } + return this; + } + + @Override + public AppiumDriver markExtensionAbsence(String extName) { + absentExtensionNames.add(extName); + return this; + } } diff --git a/src/main/java/io/appium/java_client/CanRememberExtensionPresence.java b/src/main/java/io/appium/java_client/CanRememberExtensionPresence.java new file mode 100644 index 000000000..36cd4b903 --- /dev/null +++ b/src/main/java/io/appium/java_client/CanRememberExtensionPresence.java @@ -0,0 +1,25 @@ +package io.appium.java_client; + +import org.openqa.selenium.UnsupportedCommandException; + +public interface CanRememberExtensionPresence { + /** + * Verifies if the given extension is not present in the list of absent extensions + * for the given driver instance. + * This API is designed for private usage. + * + * @param extName extension name. + * @return self instance for chaining. + * @throws UnsupportedCommandException if the extension is listed in the list of absents. + */ + ExecutesMethod assertExtensionExists(String extName); + + /** + * Marks the given extension as absent for the given driver instance. + * This API is designed for private usage. + * + * @param extName extension name. + * @return self instance for chaining. + */ + ExecutesMethod markExtensionAbsence(String extName); +} diff --git a/src/main/java/io/appium/java_client/HasAppStrings.java b/src/main/java/io/appium/java_client/HasAppStrings.java index d093e777f..439e08bcd 100644 --- a/src/main/java/io/appium/java_client/HasAppStrings.java +++ b/src/main/java/io/appium/java_client/HasAppStrings.java @@ -25,7 +25,7 @@ import static io.appium.java_client.MobileCommand.GET_STRINGS; import static io.appium.java_client.MobileCommand.prepareArguments; -public interface HasAppStrings extends ExecutesMethod { +public interface HasAppStrings extends ExecutesMethod, CanRememberExtensionPresence { /** * Get all defined Strings from an app for the default language. * See the documentation for 'mobile: getAppStrings' extension for more details. @@ -33,11 +33,12 @@ public interface HasAppStrings extends ExecutesMethod { * @return a map with localized strings defined in the app */ default Map getAppStringMap() { + final String extName = "mobile: getAppStrings"; try { - return CommandExecutionHelper.executeScript(this, "mobile: getAppStrings"); + return CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - return CommandExecutionHelper.execute(this, GET_STRINGS); + return CommandExecutionHelper.execute(markExtensionAbsence(extName), GET_STRINGS); } } @@ -49,14 +50,16 @@ default Map getAppStringMap() { * @return a map with localized strings defined in the app */ default Map getAppStringMap(String language) { + final String extName = "mobile: getAppStrings"; try { - return CommandExecutionHelper.executeScript(this, "mobile: getAppStrings", ImmutableMap.of( + return CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "language", language )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback return CommandExecutionHelper.execute( - this, new AbstractMap.SimpleEntry<>(GET_STRINGS, prepareArguments("language", language)) + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(GET_STRINGS, prepareArguments("language", language)) ); } } @@ -71,8 +74,9 @@ default Map getAppStringMap(String language) { * @return a map with localized strings defined in the app */ default Map getAppStringMap(String language, String stringFile) { + final String extName = "mobile: getAppStrings"; try { - return CommandExecutionHelper.executeScript(this, "mobile: getAppStrings", ImmutableMap.of( + return CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "language", language, "stringFile", stringFile )); @@ -81,7 +85,8 @@ default Map getAppStringMap(String language, String stringFile) String[] parameters = new String[]{"language", "stringFile"}; Object[] values = new Object[]{language, stringFile}; return CommandExecutionHelper.execute( - this, new AbstractMap.SimpleEntry<>(GET_STRINGS, prepareArguments(parameters, values)) + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(GET_STRINGS, prepareArguments(parameters, values)) ); } } diff --git a/src/main/java/io/appium/java_client/HasOnScreenKeyboard.java b/src/main/java/io/appium/java_client/HasOnScreenKeyboard.java index 322c849db..d54c4a91f 100644 --- a/src/main/java/io/appium/java_client/HasOnScreenKeyboard.java +++ b/src/main/java/io/appium/java_client/HasOnScreenKeyboard.java @@ -5,7 +5,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static io.appium.java_client.MobileCommand.isKeyboardShownCommand; -public interface HasOnScreenKeyboard extends ExecutesMethod { +public interface HasOnScreenKeyboard extends ExecutesMethod, CanRememberExtensionPresence { /** * Check if the on-screen keyboard is displayed. @@ -14,11 +14,14 @@ public interface HasOnScreenKeyboard extends ExecutesMethod { * @return true if keyboard is displayed. False otherwise */ default boolean isKeyboardShown() { + final String extName = "mobile: isKeyboardShown"; try { - return checkNotNull(CommandExecutionHelper.executeScript(this, "mobile: isKeyboardShown")); + return checkNotNull(CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName)); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - return checkNotNull(CommandExecutionHelper.execute(this, isKeyboardShownCommand())); + return checkNotNull( + CommandExecutionHelper.execute(markExtensionAbsence(extName), isKeyboardShownCommand()) + ); } } } diff --git a/src/main/java/io/appium/java_client/HidesKeyboard.java b/src/main/java/io/appium/java_client/HidesKeyboard.java index 6de1e0516..a6f522102 100644 --- a/src/main/java/io/appium/java_client/HidesKeyboard.java +++ b/src/main/java/io/appium/java_client/HidesKeyboard.java @@ -20,7 +20,7 @@ import static io.appium.java_client.MobileCommand.HIDE_KEYBOARD; -public interface HidesKeyboard extends ExecutesMethod { +public interface HidesKeyboard extends ExecutesMethod, CanRememberExtensionPresence { /** * Hides the keyboard if it is showing. @@ -30,11 +30,12 @@ public interface HidesKeyboard extends ExecutesMethod { * See the documentation for 'mobile: hideKeyboard' extension for more details. */ default void hideKeyboard() { + final String extName = "mobile: hideKeyboard"; try { - CommandExecutionHelper.executeScript(this, "mobile: hideKeyboard"); + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, HIDE_KEYBOARD); + CommandExecutionHelper.execute(markExtensionAbsence(extName), HIDE_KEYBOARD); } } } diff --git a/src/main/java/io/appium/java_client/HidesKeyboardWithKeyName.java b/src/main/java/io/appium/java_client/HidesKeyboardWithKeyName.java index c7e809911..35d7a7b0c 100644 --- a/src/main/java/io/appium/java_client/HidesKeyboardWithKeyName.java +++ b/src/main/java/io/appium/java_client/HidesKeyboardWithKeyName.java @@ -35,13 +35,14 @@ public interface HidesKeyboardWithKeyName extends HidesKeyboard { * keyboard. */ default void hideKeyboard(String keyName) { + final String extName = "mobile: hideKeyboard"; try { - CommandExecutionHelper.executeScript(this, "mobile: hideKeyboard", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "keys", ImmutableList.of(keyName) )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, hideKeyboardCommand(keyName)); + CommandExecutionHelper.execute(markExtensionAbsence(extName), hideKeyboardCommand(keyName)); } } diff --git a/src/main/java/io/appium/java_client/InteractsWithApps.java b/src/main/java/io/appium/java_client/InteractsWithApps.java index da39a0ded..45f1c285d 100644 --- a/src/main/java/io/appium/java_client/InteractsWithApps.java +++ b/src/main/java/io/appium/java_client/InteractsWithApps.java @@ -43,7 +43,7 @@ import static io.appium.java_client.MobileCommand.TERMINATE_APP; @SuppressWarnings({"rawtypes", "unchecked"}) -public interface InteractsWithApps extends ExecutesMethod { +public interface InteractsWithApps extends ExecutesMethod, CanRememberExtensionPresence { /** * Install an app on the mobile device. @@ -62,13 +62,14 @@ default void installApp(String appPath) { * the particular platform. */ default void installApp(String appPath, @Nullable BaseInstallApplicationOptions options) { + final String extName = "mobile: installApp"; try { Map args = ImmutableMap.builder() .put("app", appPath) .put("appPath", appPath) .putAll(Optional.ofNullable(options).map(BaseOptions::build).orElseGet(Collections::emptyMap)) .build(); - CommandExecutionHelper.executeScript(this, "mobile: installApp", args); + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, args); } catch (UnsupportedCommandException | InvalidArgumentException e) { // TODO: Remove the fallback Map args = ImmutableMap.builder() @@ -77,7 +78,9 @@ default void installApp(String appPath, @Nullable BaseInstallApplicationOptions (opts) -> ImmutableMap.of("options", opts.build()) ).orElseGet(ImmutableMap::of)) .build(); - CommandExecutionHelper.execute(this, new AbstractMap.SimpleEntry<>(INSTALL_APP, args)); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), new AbstractMap.SimpleEntry<>(INSTALL_APP, args) + ); } } @@ -88,9 +91,10 @@ default void installApp(String appPath, @Nullable BaseInstallApplicationOptions * @return True if app is installed, false otherwise. */ default boolean isAppInstalled(String bundleId) { + final String extName = "mobile: isAppInstalled"; try { return checkNotNull( - CommandExecutionHelper.executeScript(this, "mobile: isAppInstalled", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "bundleId", bundleId, "appId", bundleId )) @@ -98,8 +102,9 @@ default boolean isAppInstalled(String bundleId) { } catch (UnsupportedCommandException | InvalidArgumentException e) { // TODO: Remove the fallback return checkNotNull( - CommandExecutionHelper.execute(this, - new AbstractMap.SimpleEntry<>(IS_APP_INSTALLED, ImmutableMap.of("bundleId", bundleId)) + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(IS_APP_INSTALLED, ImmutableMap.of("bundleId", bundleId)) ) ); } @@ -114,13 +119,19 @@ default boolean isAppInstalled(String bundleId) { * Passing a negative value will switch to Home screen and return immediately. */ default void runAppInBackground(Duration duration) { + final String extName = "mobile: backgroundApp"; try { - CommandExecutionHelper.executeScript(this, "mobile: backgroundApp", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "seconds", duration.toMillis() / 1000.0 )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - execute(RUN_APP_IN_BACKGROUND, ImmutableMap.of("seconds", duration.toMillis() / 1000.0)); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(RUN_APP_IN_BACKGROUND, ImmutableMap.of( + "seconds", duration.toMillis() / 1000.0) + ) + ); } } @@ -143,6 +154,7 @@ default boolean removeApp(String bundleId) { * @return true if the uninstall was successful. */ default boolean removeApp(String bundleId, @Nullable BaseRemoveApplicationOptions options) { + final String extName = "mobile: removeApp"; try { Map args = ImmutableMap.builder() .put("bundleId", bundleId) @@ -150,7 +162,7 @@ default boolean removeApp(String bundleId, @Nullable BaseRemoveApplicationOption .putAll(Optional.ofNullable(options).map(BaseOptions::build).orElseGet(Collections::emptyMap)) .build(); return checkNotNull( - CommandExecutionHelper.executeScript(this, "mobile: removeApp", args) + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, args) ); } catch (UnsupportedCommandException | InvalidArgumentException e) { // TODO: Remove the fallback @@ -163,7 +175,8 @@ default boolean removeApp(String bundleId, @Nullable BaseRemoveApplicationOption //noinspection RedundantCast return checkNotNull( (Boolean) CommandExecutionHelper.execute( - this, new AbstractMap.SimpleEntry<>(REMOVE_APP, args) + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(REMOVE_APP, args) ) ); } @@ -188,13 +201,14 @@ default void activateApp(String bundleId) { * particular platform. */ default void activateApp(String bundleId, @Nullable BaseActivateApplicationOptions options) { + final String extName = "mobile: activateApp"; try { Map args = ImmutableMap.builder() .put("bundleId", bundleId) .put("appId", bundleId) .putAll(Optional.ofNullable(options).map(BaseOptions::build).orElseGet(Collections::emptyMap)) .build(); - CommandExecutionHelper.executeScript(this, "mobile: activateApp", args); + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, args); } catch (UnsupportedCommandException | InvalidArgumentException e) { // TODO: Remove the fallback Map args = ImmutableMap.builder() @@ -203,7 +217,9 @@ default void activateApp(String bundleId, @Nullable BaseActivateApplicationOptio (opts) -> ImmutableMap.of("options", opts.build()) ).orElseGet(ImmutableMap::of)) .build(); - CommandExecutionHelper.execute(this, new AbstractMap.SimpleEntry<>(ACTIVATE_APP, args)); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), new AbstractMap.SimpleEntry<>(ACTIVATE_APP, args) + ); } } @@ -214,21 +230,27 @@ default void activateApp(String bundleId, @Nullable BaseActivateApplicationOptio * @return one of possible {@link ApplicationState} values, */ default ApplicationState queryAppState(String bundleId) { + final String extName = "mobile: queryAppState"; try { return ApplicationState.ofCode( checkNotNull( - CommandExecutionHelper.executeScript(this, "mobile: queryAppState", ImmutableMap.of( - "bundleId", bundleId, - "appId", bundleId - )) + CommandExecutionHelper.executeScript( + assertExtensionExists(extName), + extName, ImmutableMap.of( + "bundleId", bundleId, + "appId", bundleId + ) + ) ) ); } catch (UnsupportedCommandException | InvalidArgumentException e) { // TODO: Remove the fallback return ApplicationState.ofCode( checkNotNull( - CommandExecutionHelper.execute(this, - new AbstractMap.SimpleEntry<>(QUERY_APP_STATE, ImmutableMap.of("bundleId", bundleId))) + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(QUERY_APP_STATE, ImmutableMap.of("bundleId", bundleId)) + ) ) ); } @@ -253,6 +275,7 @@ default boolean terminateApp(String bundleId) { * @return true if the app was running before and has been successfully stopped. */ default boolean terminateApp(String bundleId, @Nullable BaseTerminateApplicationOptions options) { + final String extName = "mobile: terminateApp"; try { Map args = ImmutableMap.builder() .put("bundleId", bundleId) @@ -260,7 +283,7 @@ default boolean terminateApp(String bundleId, @Nullable BaseTerminateApplication .putAll(Optional.ofNullable(options).map(BaseOptions::build).orElseGet(Collections::emptyMap)) .build(); return checkNotNull( - CommandExecutionHelper.executeScript(this, "mobile: terminateApp", args) + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, args) ); } catch (UnsupportedCommandException | InvalidArgumentException e) { // TODO: Remove the fallback @@ -273,7 +296,7 @@ default boolean terminateApp(String bundleId, @Nullable BaseTerminateApplication //noinspection RedundantCast return checkNotNull( (Boolean) CommandExecutionHelper.execute( - this, new AbstractMap.SimpleEntry<>(TERMINATE_APP, args) + markExtensionAbsence(extName), new AbstractMap.SimpleEntry<>(TERMINATE_APP, args) ) ); } diff --git a/src/main/java/io/appium/java_client/LocksDevice.java b/src/main/java/io/appium/java_client/LocksDevice.java index 6f3033e05..60ba88ffc 100644 --- a/src/main/java/io/appium/java_client/LocksDevice.java +++ b/src/main/java/io/appium/java_client/LocksDevice.java @@ -26,7 +26,7 @@ import static io.appium.java_client.MobileCommand.lockDeviceCommand; import static io.appium.java_client.MobileCommand.unlockDeviceCommand; -public interface LocksDevice extends ExecutesMethod { +public interface LocksDevice extends ExecutesMethod, CanRememberExtensionPresence { /** * This method locks a device. It will return silently if the device @@ -45,13 +45,14 @@ default void lockDevice() { * A negative/zero value will lock the device and return immediately. */ default void lockDevice(Duration duration) { + final String extName = "mobile: lock"; try { - CommandExecutionHelper.executeScript(this, "mobile: lock", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "seconds", duration.getSeconds() )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, lockDeviceCommand(duration)); + CommandExecutionHelper.execute(markExtensionAbsence(extName), lockDeviceCommand(duration)); } } @@ -60,15 +61,16 @@ default void lockDevice(Duration duration) { * is not locked. */ default void unlockDevice() { + final String extName = "mobile: unlock"; try { //noinspection ConstantConditions - if (!(Boolean) CommandExecutionHelper.executeScript(this, "mobile: isLocked")) { + if (!(Boolean) CommandExecutionHelper.executeScript(assertExtensionExists(extName), "mobile: isLocked")) { return; } - CommandExecutionHelper.executeScript(this, "mobile: unlock"); + CommandExecutionHelper.executeScript(this, extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, unlockDeviceCommand()); + CommandExecutionHelper.execute(markExtensionAbsence(extName), unlockDeviceCommand()); } } @@ -78,13 +80,16 @@ default void unlockDevice() { * @return true if the device is locked or false otherwise. */ default boolean isDeviceLocked() { + final String extName = "mobile: isLocked"; try { return checkNotNull( - CommandExecutionHelper.executeScript(this, "mobile: isLocked") + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName) ); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - return checkNotNull(CommandExecutionHelper.execute(this, getIsDeviceLockedCommand())); + return checkNotNull( + CommandExecutionHelper.execute(markExtensionAbsence(extName), getIsDeviceLockedCommand()) + ); } } } diff --git a/src/main/java/io/appium/java_client/android/AuthenticatesByFinger.java b/src/main/java/io/appium/java_client/android/AuthenticatesByFinger.java index a9ecf128f..178ec4206 100644 --- a/src/main/java/io/appium/java_client/android/AuthenticatesByFinger.java +++ b/src/main/java/io/appium/java_client/android/AuthenticatesByFinger.java @@ -1,13 +1,14 @@ package io.appium.java_client.android; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; import static io.appium.java_client.android.AndroidMobileCommandHelper.fingerPrintCommand; -public interface AuthenticatesByFinger extends ExecutesMethod { +public interface AuthenticatesByFinger extends ExecutesMethod, CanRememberExtensionPresence { /** * Authenticate users by using their finger print scans on supported emulators. @@ -15,13 +16,14 @@ public interface AuthenticatesByFinger extends ExecutesMethod { * @param fingerPrintId finger prints stored in Android Keystore system (from 1 to 10) */ default void fingerPrint(int fingerPrintId) { + final String extName = "mobile: fingerprint"; try { - CommandExecutionHelper.executeScript(this, "mobile: fingerprint", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "fingerprintId", fingerPrintId )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, fingerPrintCommand(fingerPrintId)); + CommandExecutionHelper.execute(markExtensionAbsence(extName), fingerPrintCommand(fingerPrintId)); } } } diff --git a/src/main/java/io/appium/java_client/android/CanReplaceElementValue.java b/src/main/java/io/appium/java_client/android/CanReplaceElementValue.java index eb81ba417..2b48a9e29 100644 --- a/src/main/java/io/appium/java_client/android/CanReplaceElementValue.java +++ b/src/main/java/io/appium/java_client/android/CanReplaceElementValue.java @@ -1,13 +1,16 @@ package io.appium.java_client.android; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import io.appium.java_client.MobileCommand; import org.openqa.selenium.UnsupportedCommandException; import org.openqa.selenium.remote.RemoteWebElement; -public interface CanReplaceElementValue extends ExecutesMethod { +import java.util.AbstractMap; + +public interface CanReplaceElementValue extends ExecutesMethod, CanRememberExtensionPresence { /** * Sends a text to the given element by replacing its previous content. * @@ -19,18 +22,22 @@ public interface CanReplaceElementValue extends ExecutesMethod { * off from the typed text). */ default void replaceElementValue(RemoteWebElement element, String value) { + final String extName = "mobile: replaceValue"; try { - CommandExecutionHelper.executeScript(this, "mobile: replaceValue", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "elementId", element.getId(), "text", value )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - this.execute(MobileCommand.REPLACE_VALUE, ImmutableMap.of( - "id", element.getId(), - "text", value, - "value", value - )); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(MobileCommand.REPLACE_VALUE, ImmutableMap.of( + "id", element.getId(), + "text", value, + "value", value + )) + ); } } } diff --git a/src/main/java/io/appium/java_client/android/HasAndroidDeviceDetails.java b/src/main/java/io/appium/java_client/android/HasAndroidDeviceDetails.java index bcdcf1fd4..3e230b3a3 100644 --- a/src/main/java/io/appium/java_client/android/HasAndroidDeviceDetails.java +++ b/src/main/java/io/appium/java_client/android/HasAndroidDeviceDetails.java @@ -1,5 +1,6 @@ package io.appium.java_client.android; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; @@ -9,7 +10,7 @@ import static io.appium.java_client.android.AndroidMobileCommandHelper.getDisplayDensityCommand; import static io.appium.java_client.android.AndroidMobileCommandHelper.getSystemBarsCommand; -public interface HasAndroidDeviceDetails extends ExecutesMethod { +public interface HasAndroidDeviceDetails extends ExecutesMethod, CanRememberExtensionPresence { /** Retrieve the display density of the Android device. @@ -17,11 +18,12 @@ public interface HasAndroidDeviceDetails extends ExecutesMethod { @return The density value in dpi */ default Long getDisplayDensity() { + final String extName = "mobile: getDisplayDensity"; try { - return CommandExecutionHelper.executeScript(this, "mobile: getDisplayDensity"); + return CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - return CommandExecutionHelper.execute(this, getDisplayDensityCommand()); + return CommandExecutionHelper.execute(markExtensionAbsence(extName), getDisplayDensityCommand()); } } @@ -31,11 +33,12 @@ default Long getDisplayDensity() { @return The map where keys are bar types and values are mappings of bar properties. */ default Map> getSystemBars() { + final String extName = "mobile: getSystemBars"; try { - return CommandExecutionHelper.executeScript(this, "mobile: getSystemBars"); + return CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - return CommandExecutionHelper.execute(this, getSystemBarsCommand()); + return CommandExecutionHelper.execute(markExtensionAbsence(extName), getSystemBarsCommand()); } } diff --git a/src/main/java/io/appium/java_client/android/HasNotifications.java b/src/main/java/io/appium/java_client/android/HasNotifications.java index c2e870031..0b7f7365b 100644 --- a/src/main/java/io/appium/java_client/android/HasNotifications.java +++ b/src/main/java/io/appium/java_client/android/HasNotifications.java @@ -1,22 +1,24 @@ package io.appium.java_client.android; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; import static io.appium.java_client.android.AndroidMobileCommandHelper.openNotificationsCommand; -public interface HasNotifications extends ExecutesMethod { +public interface HasNotifications extends ExecutesMethod, CanRememberExtensionPresence { /** * Opens notification drawer on the device under test. */ default void openNotifications() { + final String extName = "mobile: openNotifications"; try { - CommandExecutionHelper.executeScript(this, "mobile: openNotifications"); + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, openNotificationsCommand()); + CommandExecutionHelper.execute(markExtensionAbsence(extName), openNotificationsCommand()); } } } diff --git a/src/main/java/io/appium/java_client/android/StartsActivity.java b/src/main/java/io/appium/java_client/android/StartsActivity.java index 9291e5020..f1d538881 100644 --- a/src/main/java/io/appium/java_client/android/StartsActivity.java +++ b/src/main/java/io/appium/java_client/android/StartsActivity.java @@ -17,6 +17,7 @@ package io.appium.java_client.android; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; @@ -29,7 +30,7 @@ import static io.appium.java_client.MobileCommand.GET_CURRENT_PACKAGE; import static io.appium.java_client.android.AndroidMobileCommandHelper.startActivityCommand; -public interface StartsActivity extends ExecutesMethod { +public interface StartsActivity extends ExecutesMethod, CanRememberExtensionPresence { /** * This method should start arbitrary activity during a test. If the activity belongs to * another application, that application is started and the activity is opened. @@ -65,12 +66,14 @@ default void startActivity(Activity activity) { */ @Nullable default String currentActivity() { + final String extName = "mobile: getCurrentActivity"; try { - return CommandExecutionHelper.executeScript(this, "mobile: getCurrentActivity"); + return CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback return CommandExecutionHelper.execute( - this, new AbstractMap.SimpleEntry<>(CURRENT_ACTIVITY, ImmutableMap.of()) + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(CURRENT_ACTIVITY, ImmutableMap.of()) ); } } @@ -82,12 +85,14 @@ default String currentActivity() { */ @Nullable default String getCurrentPackage() { + final String extName = "mobile: getCurrentPackage"; try { - return CommandExecutionHelper.executeScript(this, "mobile: getCurrentPackage"); + return CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback return CommandExecutionHelper.execute( - this, new AbstractMap.SimpleEntry<>(GET_CURRENT_PACKAGE, ImmutableMap.of()) + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(GET_CURRENT_PACKAGE, ImmutableMap.of()) ); } } diff --git a/src/main/java/io/appium/java_client/android/SupportsGpsStateManagement.java b/src/main/java/io/appium/java_client/android/SupportsGpsStateManagement.java index 597c98193..14854412e 100644 --- a/src/main/java/io/appium/java_client/android/SupportsGpsStateManagement.java +++ b/src/main/java/io/appium/java_client/android/SupportsGpsStateManagement.java @@ -1,5 +1,6 @@ package io.appium.java_client.android; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; @@ -7,18 +8,19 @@ import static com.google.common.base.Preconditions.checkNotNull; import static io.appium.java_client.android.AndroidMobileCommandHelper.toggleLocationServicesCommand; -public interface SupportsGpsStateManagement extends ExecutesMethod { +public interface SupportsGpsStateManagement extends ExecutesMethod, CanRememberExtensionPresence { /** * Toggles GPS service state. * This method only works reliably since API 31 (Android 12). */ default void toggleLocationServices() { + final String extName = "mobile: toggleGps"; try { - CommandExecutionHelper.executeScript(this, "mobile: toggleGps"); + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, toggleLocationServicesCommand()); + CommandExecutionHelper.execute(markExtensionAbsence(extName), toggleLocationServicesCommand()); } } diff --git a/src/main/java/io/appium/java_client/android/SupportsNetworkStateManagement.java b/src/main/java/io/appium/java_client/android/SupportsNetworkStateManagement.java index 9fdbd23c9..8f4dfa246 100644 --- a/src/main/java/io/appium/java_client/android/SupportsNetworkStateManagement.java +++ b/src/main/java/io/appium/java_client/android/SupportsNetworkStateManagement.java @@ -1,6 +1,7 @@ package io.appium.java_client.android; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; @@ -12,22 +13,23 @@ import static io.appium.java_client.android.AndroidMobileCommandHelper.toggleDataCommand; import static io.appium.java_client.android.AndroidMobileCommandHelper.toggleWifiCommand; -public interface SupportsNetworkStateManagement extends ExecutesMethod { +public interface SupportsNetworkStateManagement extends ExecutesMethod, CanRememberExtensionPresence { /** * Toggles Wifi on and off. */ default void toggleWifi() { + final String extName = "mobile: setConnectivity"; try { Map result = checkNotNull( - CommandExecutionHelper.executeScript(this, "mobile: getConnectivity") + CommandExecutionHelper.executeScript(assertExtensionExists(extName), "mobile: getConnectivity") ); - CommandExecutionHelper.executeScript(this, "mobile: setConnectivity", ImmutableMap.of( + CommandExecutionHelper.executeScript(this, extName, ImmutableMap.of( "wifi", !((Boolean) result.get("wifi")) )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, toggleWifiCommand()); + CommandExecutionHelper.execute(markExtensionAbsence(extName), toggleWifiCommand()); } } @@ -36,16 +38,17 @@ default void toggleWifi() { * 6 and above 10. */ default void toggleAirplaneMode() { + final String extName = "mobile: setConnectivity"; try { Map result = checkNotNull( - CommandExecutionHelper.executeScript(this, "mobile: getConnectivity") + CommandExecutionHelper.executeScript(assertExtensionExists(extName), "mobile: getConnectivity") ); - CommandExecutionHelper.executeScript(this, "mobile: setConnectivity", ImmutableMap.of( + CommandExecutionHelper.executeScript(this, extName, ImmutableMap.of( "airplaneMode", !((Boolean) result.get("airplaneMode")) )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, toggleAirplaneCommand()); + CommandExecutionHelper.execute(markExtensionAbsence(extName), toggleAirplaneCommand()); } } @@ -54,16 +57,17 @@ default void toggleAirplaneMode() { * running Android version above 10. */ default void toggleData() { + final String extName = "mobile: setConnectivity"; try { Map result = checkNotNull( - CommandExecutionHelper.executeScript(this, "mobile: getConnectivity") + CommandExecutionHelper.executeScript(assertExtensionExists(extName), "mobile: getConnectivity") ); - CommandExecutionHelper.executeScript(this, "mobile: setConnectivity", ImmutableMap.of( + CommandExecutionHelper.executeScript(this, extName, ImmutableMap.of( "data", !((Boolean) result.get("data")) )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, toggleDataCommand()); + CommandExecutionHelper.execute(markExtensionAbsence(extName), toggleDataCommand()); } } } diff --git a/src/main/java/io/appium/java_client/android/SupportsSpecialEmulatorCommands.java b/src/main/java/io/appium/java_client/android/SupportsSpecialEmulatorCommands.java index 29cd6415e..025f00b05 100644 --- a/src/main/java/io/appium/java_client/android/SupportsSpecialEmulatorCommands.java +++ b/src/main/java/io/appium/java_client/android/SupportsSpecialEmulatorCommands.java @@ -1,10 +1,13 @@ package io.appium.java_client.android; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; +import java.util.AbstractMap; + import static io.appium.java_client.MobileCommand.GSM_CALL; import static io.appium.java_client.MobileCommand.GSM_SIGNAL; import static io.appium.java_client.MobileCommand.GSM_VOICE; @@ -13,7 +16,7 @@ import static io.appium.java_client.MobileCommand.POWER_CAPACITY; import static io.appium.java_client.MobileCommand.SEND_SMS; -public interface SupportsSpecialEmulatorCommands extends ExecutesMethod { +public interface SupportsSpecialEmulatorCommands extends ExecutesMethod, CanRememberExtensionPresence { /** * Emulate send SMS event on the connected emulator. @@ -22,17 +25,21 @@ public interface SupportsSpecialEmulatorCommands extends ExecutesMethod { * @param message The message content. */ default void sendSMS(String phoneNumber, String message) { + final String extName = "mobile: sendSms"; try { - CommandExecutionHelper.executeScript(this, "mobile: sendSms", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "phoneNumber", phoneNumber, "message", message )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - this.execute(SEND_SMS, ImmutableMap.of( - "phoneNumber", phoneNumber, - "message", message - )); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(SEND_SMS, ImmutableMap.of( + "phoneNumber", phoneNumber, + "message", message + )) + ); } } @@ -43,17 +50,21 @@ default void sendSMS(String phoneNumber, String message) { * @param gsmCallAction One of available {@link GsmCallActions} values. */ default void makeGsmCall(String phoneNumber, GsmCallActions gsmCallAction) { + final String extName = "mobile: gsmCall"; try { - CommandExecutionHelper.executeScript(this, "mobile: gsmCall", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "phoneNumber", phoneNumber, "action", gsmCallAction.toString().toLowerCase() )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - this.execute(GSM_CALL, ImmutableMap.of( - "phoneNumber", phoneNumber, - "action", gsmCallAction.toString().toLowerCase() - )); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(GSM_CALL, ImmutableMap.of( + "phoneNumber", phoneNumber, + "action", gsmCallAction.toString().toLowerCase() + )) + ); } } @@ -63,16 +74,20 @@ default void makeGsmCall(String phoneNumber, GsmCallActions gsmCallAction) { * @param gsmSignalStrength One of available {@link GsmSignalStrength} values. */ default void setGsmSignalStrength(GsmSignalStrength gsmSignalStrength) { + final String extName = "mobile: gsmSignal"; try { - CommandExecutionHelper.executeScript(this, "mobile: gsmSignal", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "strength", gsmSignalStrength.ordinal() )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - this.execute(GSM_SIGNAL, ImmutableMap.of( - "signalStrengh", gsmSignalStrength.ordinal(), - "signalStrength", gsmSignalStrength.ordinal() - )); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(GSM_SIGNAL, ImmutableMap.of( + "signalStrengh", gsmSignalStrength.ordinal(), + "signalStrength", gsmSignalStrength.ordinal() + )) + ); } } @@ -82,15 +97,19 @@ default void setGsmSignalStrength(GsmSignalStrength gsmSignalStrength) { * @param gsmVoiceState One of available {@link GsmVoiceState} values. */ default void setGsmVoice(GsmVoiceState gsmVoiceState) { + final String extName = "mobile: gsmVoice"; try { - CommandExecutionHelper.executeScript(this, "mobile: gsmVoice", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "state", gsmVoiceState.toString().toLowerCase() )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - this.execute(GSM_VOICE, ImmutableMap.of( - "state", gsmVoiceState.name().toLowerCase() - )); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(GSM_VOICE, ImmutableMap.of( + "state", gsmVoiceState.name().toLowerCase() + )) + ); } } @@ -100,15 +119,19 @@ default void setGsmVoice(GsmVoiceState gsmVoiceState) { * @param networkSpeed One of available {@link NetworkSpeed} values. */ default void setNetworkSpeed(NetworkSpeed networkSpeed) { + final String extName = "mobile: networkSpeed"; try { - CommandExecutionHelper.executeScript(this, "mobile: networkSpeed", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "speed", networkSpeed.toString().toLowerCase() )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - this.execute(NETWORK_SPEED, ImmutableMap.of( - "netspeed", networkSpeed.name().toLowerCase() - )); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(NETWORK_SPEED, ImmutableMap.of( + "netspeed", networkSpeed.name().toLowerCase() + )) + ); } } @@ -118,15 +141,19 @@ default void setNetworkSpeed(NetworkSpeed networkSpeed) { * @param percent Percentage value in range [0, 100]. */ default void setPowerCapacity(int percent) { + final String extName = "mobile: powerCapacity"; try { - CommandExecutionHelper.executeScript(this, "mobile: powerCapacity", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "percent", percent )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - this.execute(POWER_CAPACITY, ImmutableMap.of( - "percent", percent - )); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(POWER_CAPACITY, ImmutableMap.of( + "percent", percent + )) + ); } } @@ -136,15 +163,19 @@ default void setPowerCapacity(int percent) { * @param powerACState One of available {@link PowerACState} values. */ default void setPowerAC(PowerACState powerACState) { + final String extName = "mobile: powerAC"; try { - CommandExecutionHelper.executeScript(this, "mobile: powerAC", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "state", powerACState.toString().toLowerCase() )); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - this.execute(POWER_AC_STATE, ImmutableMap.of( - "state", powerACState.name().toLowerCase() - )); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(POWER_AC_STATE, ImmutableMap.of( + "state", powerACState.name().toLowerCase() + )) + ); } } diff --git a/src/main/java/io/appium/java_client/android/connection/HasNetworkConnection.java b/src/main/java/io/appium/java_client/android/connection/HasNetworkConnection.java index f77bf7d3a..0774c74a2 100644 --- a/src/main/java/io/appium/java_client/android/connection/HasNetworkConnection.java +++ b/src/main/java/io/appium/java_client/android/connection/HasNetworkConnection.java @@ -17,6 +17,7 @@ package io.appium.java_client.android.connection; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; @@ -27,7 +28,7 @@ import static io.appium.java_client.android.AndroidMobileCommandHelper.getNetworkConnectionCommand; import static io.appium.java_client.android.AndroidMobileCommandHelper.setConnectionCommand; -public interface HasNetworkConnection extends ExecutesMethod { +public interface HasNetworkConnection extends ExecutesMethod, CanRememberExtensionPresence { /** * Set the network connection of the device. @@ -36,8 +37,9 @@ public interface HasNetworkConnection extends ExecutesMethod { * @return Connection object, which represents the resulting state */ default ConnectionState setConnection(ConnectionState connection) { + final String extName = "mobile: setConnectivity"; try { - CommandExecutionHelper.executeScript(this, "mobile: setConnectivity", ImmutableMap.of( + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, ImmutableMap.of( "wifi", connection.isWiFiEnabled(), "data", connection.isDataEnabled(), "airplaneMode", connection.isAirplaneModeEnabled() @@ -47,7 +49,10 @@ default ConnectionState setConnection(ConnectionState connection) { // TODO: Remove the fallback return new ConnectionState( checkNotNull( - CommandExecutionHelper.execute(this, setConnectionCommand(connection.getBitMask())) + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + setConnectionCommand(connection.getBitMask()) + ) ) ); } @@ -59,9 +64,10 @@ default ConnectionState setConnection(ConnectionState connection) { * @return Connection object, which lets you to inspect the current status */ default ConnectionState getConnection() { + final String extName = "mobile: getConnectivity"; try { Map result = checkNotNull( - CommandExecutionHelper.executeScript(this, "mobile: getConnectivity") + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName) ); return new ConnectionState( ((boolean) result.get("wifi") ? ConnectionState.WIFI_MASK : 0) @@ -72,7 +78,10 @@ default ConnectionState getConnection() { // TODO: Remove the fallback return new ConnectionState( checkNotNull( - CommandExecutionHelper.execute(this, getNetworkConnectionCommand()) + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + getNetworkConnectionCommand() + ) ) ); } diff --git a/src/main/java/io/appium/java_client/android/nativekey/PressesKey.java b/src/main/java/io/appium/java_client/android/nativekey/PressesKey.java index 9584ff517..b262096c0 100644 --- a/src/main/java/io/appium/java_client/android/nativekey/PressesKey.java +++ b/src/main/java/io/appium/java_client/android/nativekey/PressesKey.java @@ -17,6 +17,7 @@ package io.appium.java_client.android.nativekey; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; @@ -27,7 +28,7 @@ import static io.appium.java_client.MobileCommand.LONG_PRESS_KEY_CODE; import static io.appium.java_client.MobileCommand.PRESS_KEY_CODE; -public interface PressesKey extends ExecutesMethod { +public interface PressesKey extends ExecutesMethod, CanRememberExtensionPresence { /** * Send a key event to the device under test. @@ -35,12 +36,15 @@ public interface PressesKey extends ExecutesMethod { * @param keyEvent The generated native key event */ default void pressKey(KeyEvent keyEvent) { + final String extName = "mobile: pressKey"; try { - CommandExecutionHelper.executeScript(this, "mobile: pressKey", keyEvent.build()); + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, keyEvent.build()); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, - new AbstractMap.SimpleEntry<>(PRESS_KEY_CODE, keyEvent.build())); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(PRESS_KEY_CODE, keyEvent.build()) + ); } } @@ -50,16 +54,19 @@ default void pressKey(KeyEvent keyEvent) { * @param keyEvent The generated native key event */ default void longPressKey(KeyEvent keyEvent) { + final String extName = "mobile: pressKey"; try { Map args = ImmutableMap.builder() .putAll(keyEvent.build()) .put("isLongPress", true) .build(); - CommandExecutionHelper.executeScript(this, "mobile: pressKey", args); + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName, args); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, - new AbstractMap.SimpleEntry<>(LONG_PRESS_KEY_CODE, keyEvent.build())); + CommandExecutionHelper.execute( + markExtensionAbsence(extName), + new AbstractMap.SimpleEntry<>(LONG_PRESS_KEY_CODE, keyEvent.build()) + ); } } } diff --git a/src/main/java/io/appium/java_client/ios/ShakesDevice.java b/src/main/java/io/appium/java_client/ios/ShakesDevice.java index 1f34ecbfa..57302ef8a 100644 --- a/src/main/java/io/appium/java_client/ios/ShakesDevice.java +++ b/src/main/java/io/appium/java_client/ios/ShakesDevice.java @@ -16,23 +16,25 @@ package io.appium.java_client.ios; +import io.appium.java_client.CanRememberExtensionPresence; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.ExecutesMethod; import org.openqa.selenium.UnsupportedCommandException; import static io.appium.java_client.ios.IOSMobileCommandHelper.shakeCommand; -public interface ShakesDevice extends ExecutesMethod { +public interface ShakesDevice extends ExecutesMethod, CanRememberExtensionPresence { /** * Simulate shaking the Simulator. This API does not work for real devices. */ default void shake() { + final String extName = "mobile: shake"; try { - CommandExecutionHelper.executeScript(this, "mobile: shake"); + CommandExecutionHelper.executeScript(assertExtensionExists(extName), extName); } catch (UnsupportedCommandException e) { // TODO: Remove the fallback - CommandExecutionHelper.execute(this, shakeCommand()); + CommandExecutionHelper.execute(markExtensionAbsence(extName), shakeCommand()); } } }