Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions src/main/java/io/appium/java_client/CommandExecutionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,32 +16,37 @@

package io.appium.java_client;

import com.google.common.collect.ImmutableMap;
import org.openqa.selenium.remote.Response;

import javax.annotation.Nullable;
import java.util.AbstractMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static org.openqa.selenium.remote.DriverCommand.EXECUTE_SCRIPT;

public final class CommandExecutionHelper {

public static <T> T execute(ExecutesMethod executesMethod,
Map.Entry<String, Map<String, ?>> keyValuePair) {
@Nullable
public static <T> T execute(
ExecutesMethod executesMethod, Map.Entry<String, Map<String, ?>> keyValuePair
) {
return handleResponse(executesMethod.execute(keyValuePair.getKey(), keyValuePair.getValue()));
}

@Nullable
public static <T> T execute(ExecutesMethod executesMethod, String command) {
return handleResponse(executesMethod.execute(command));
}

@Nullable
private static <T> T handleResponse(Response response) {
//noinspection unchecked
return response == null ? null : (T) response.getValue();
}

@Nullable
public static <T> T executeScript(ExecutesMethod executesMethod, String scriptName) {
return executeScript(executesMethod, scriptName, null);
}
Expand All @@ -50,18 +55,17 @@ public static <T> T executeScript(ExecutesMethod executesMethod, String scriptNa
* Simplifies arguments preparation for the script execution command.
*
* @param executesMethod Method executor instance.
* @param scriptName Extension script name.
* @param args Extension script arguments (if present).
* @param scriptName Extension script name.
* @param args Extension script arguments (if present).
* @return Script execution result.
*/
@Nullable
public static <T> T executeScript(
ExecutesMethod executesMethod, String scriptName, @Nullable Map<String, Object> args
) {
Map<String, Object> payload = new HashMap<>();
payload.put("script", scriptName);
if (args != null) {
payload.put("args", args.isEmpty() ? Collections.emptyList() : Collections.singletonList(args));
}
return execute(executesMethod, new AbstractMap.SimpleEntry<>(EXECUTE_SCRIPT, payload));
return execute(executesMethod, new AbstractMap.SimpleEntry<>(EXECUTE_SCRIPT, ImmutableMap.of(
"script", scriptName,
"args", (args == null || args.isEmpty()) ? Collections.emptyList() : Collections.singletonList(args)
)));
}
}
46 changes: 37 additions & 9 deletions src/main/java/io/appium/java_client/HasAppStrings.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

package io.appium.java_client;

import com.google.common.collect.ImmutableMap;
import org.openqa.selenium.UnsupportedCommandException;

import java.util.AbstractMap;
import java.util.Map;

Expand All @@ -25,37 +28,62 @@
public interface HasAppStrings extends ExecutesMethod {
/**
* Get all defined Strings from an app for the default language.
* See the documentation for 'mobile: getAppStrings' extension for more details.
*
* @return a map with localized strings defined in the app
*/
default Map<String, String> getAppStringMap() {
return CommandExecutionHelper.execute(this, GET_STRINGS);
try {
return CommandExecutionHelper.executeScript(this, "mobile: getAppStrings");
} catch (UnsupportedCommandException e) {
// TODO: Remove the fallback
return CommandExecutionHelper.execute(this, GET_STRINGS);
}
}

/**
* Get all defined Strings from an app for the specified language.
* See the documentation for 'mobile: getAppStrings' extension for more details.
*
* @param language strings language code
* @return a map with localized strings defined in the app
*/
default Map<String, String> getAppStringMap(String language) {
return CommandExecutionHelper.execute(this, new AbstractMap.SimpleEntry<>(GET_STRINGS,
prepareArguments("language", language)));
try {
return CommandExecutionHelper.executeScript(this, "mobile: getAppStrings", ImmutableMap.of(
"language", language
));
} catch (UnsupportedCommandException e) {
// TODO: Remove the fallback
return CommandExecutionHelper.execute(
this, new AbstractMap.SimpleEntry<>(GET_STRINGS, prepareArguments("language", language))
);
}
}

/**
* Get all defined Strings from an app for the specified language and
* strings filename.
* strings filename. See the documentation for 'mobile: getAppStrings'
* extension for more details.
*
* @param language strings language code
* @param stringFile strings filename
* @param stringFile strings filename. Ignored on Android
* @return a map with localized strings defined in the app
*/
default Map<String, String> 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)));
try {
return CommandExecutionHelper.executeScript(this, "mobile: getAppStrings", ImmutableMap.of(
"language", language,
"stringFile", stringFile
));
} catch (UnsupportedCommandException e) {
// TODO: Remove the fallback
String[] parameters = new String[]{"language", "stringFile"};
Object[] values = new Object[]{language, stringFile};
return CommandExecutionHelper.execute(
this, new AbstractMap.SimpleEntry<>(GET_STRINGS, prepareArguments(parameters, values))
);
}
}

}
12 changes: 4 additions & 8 deletions src/main/java/io/appium/java_client/HasBrowserCheck.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package io.appium.java_client;

import com.google.common.collect.ImmutableMap;
import io.appium.java_client.internal.CapabilityHelpers;
import org.openqa.selenium.ContextAware;
import org.openqa.selenium.HasCapabilities;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.CapabilityType;

import java.util.Collections;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.commons.lang3.StringUtils.containsIgnoreCase;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.openqa.selenium.remote.DriverCommand.EXECUTE_SCRIPT;

public interface HasBrowserCheck extends ExecutesMethod, HasCapabilities {
/**
Expand All @@ -24,10 +21,9 @@ default boolean isBrowser() {
CapabilityType.BROWSER_NAME, String.class);
if (!isBlank(browserName)) {
try {
return (boolean) execute(EXECUTE_SCRIPT, ImmutableMap.of(
"script", "return !!window.navigator;",
"args", Collections.emptyList()
)).getValue();
return checkNotNull(
CommandExecutionHelper.executeScript(this, "return !!window.navigator;")
);
} catch (WebDriverException ign) {
// ignore
}
Expand Down
13 changes: 11 additions & 2 deletions src/main/java/io/appium/java_client/HasOnScreenKeyboard.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
package io.appium.java_client;

import org.openqa.selenium.UnsupportedCommandException;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.appium.java_client.MobileCommand.isKeyboardShownCommand;

public interface HasOnScreenKeyboard extends ExecutesMethod {

/**
* Check if the keyboard is displayed.
* Check if the on-screen keyboard is displayed.
* See the documentation for 'mobile: isKeyboardShown' extension for more details.
*
* @return true if keyboard is displayed. False otherwise
*/
default boolean isKeyboardShown() {
return CommandExecutionHelper.execute(this, isKeyboardShownCommand());
try {
return checkNotNull(CommandExecutionHelper.executeScript(this, "mobile: isKeyboardShown"));
} catch (UnsupportedCommandException e) {
// TODO: Remove the fallback
return checkNotNull(CommandExecutionHelper.execute(this, isKeyboardShownCommand()));
}
}
}
13 changes: 12 additions & 1 deletion src/main/java/io/appium/java_client/HidesKeyboard.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,25 @@

package io.appium.java_client;

import org.openqa.selenium.UnsupportedCommandException;

import static io.appium.java_client.MobileCommand.HIDE_KEYBOARD;

public interface HidesKeyboard extends ExecutesMethod {

/**
* Hides the keyboard if it is showing.
* If the on-screen keyboard does not have any dedicated button that
* hides it then an error is going to be thrown. In such case you must emulate
* same actions an app user would do to hide the keyboard.
* See the documentation for 'mobile: hideKeyboard' extension for more details.
*/
default void hideKeyboard() {
execute(HIDE_KEYBOARD);
try {
CommandExecutionHelper.executeScript(this, "mobile: hideKeyboard");
} catch (UnsupportedCommandException e) {
// TODO: Remove the fallback
CommandExecutionHelper.execute(this, HIDE_KEYBOARD);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,33 @@

package io.appium.java_client;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.openqa.selenium.UnsupportedCommandException;

import static io.appium.java_client.MobileCommand.hideKeyboardCommand;

public interface HidesKeyboardWithKeyName extends HidesKeyboard {

/**
* Hides the keyboard by pressing the button specified by keyName if it is
* showing.
* showing. If the on-screen keyboard does not have any dedicated button that
* hides it then an error is going to be thrown. In such case you must emulate
* same actions an app user would do to hide the keyboard.
* See the documentation for 'mobile: hideKeyboard' extension for more details.
*
* @param keyName The button pressed by the mobile driver to attempt hiding the
* keyboard.
*/
default void hideKeyboard(String keyName) {
CommandExecutionHelper.execute(this, hideKeyboardCommand(keyName));
try {
CommandExecutionHelper.executeScript(this, "mobile: hideKeyboard", ImmutableMap.of(
"keys", ImmutableList.of(keyName)
));
} catch (UnsupportedCommandException e) {
// TODO: Remove the fallback
CommandExecutionHelper.execute(this, hideKeyboardCommand(keyName));
}
}

/**
Expand All @@ -39,7 +53,9 @@ default void hideKeyboard(String keyName) {
* @param strategy HideKeyboardStrategy.
* @param keyName a String, representing the text displayed on the button of the
* keyboard you want to press. For example: "Done".
* @deprecated This API is deprecated and will be removed in the future.
*/
@Deprecated
default void hideKeyboard(String strategy, String keyName) {
CommandExecutionHelper.execute(this, hideKeyboardCommand(strategy, keyName));
}
Expand Down
17 changes: 13 additions & 4 deletions src/main/java/io/appium/java_client/InteractsWithApps.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.Map;
import java.util.Optional;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.appium.java_client.MobileCommand.RUN_APP_IN_BACKGROUND;

@SuppressWarnings("rawtypes")
Expand Down Expand Up @@ -66,10 +67,12 @@ default void installApp(String appPath, @Nullable BaseInstallApplicationOptions
* @return True if app is installed, false otherwise.
*/
default boolean isAppInstalled(String bundleId) {
return CommandExecutionHelper.executeScript(this, "mobile: isAppInstalled", ImmutableMap.of(
return checkNotNull(
CommandExecutionHelper.executeScript(this, "mobile: isAppInstalled", ImmutableMap.of(
"bundleId", bundleId,
"appId", bundleId
));
))
);
}

/**
Expand Down Expand Up @@ -107,7 +110,9 @@ default boolean removeApp(String bundleId, @Nullable BaseRemoveApplicationOption
args.put("bundleId", bundleId);
args.put("appId", bundleId);
Optional.ofNullable(options).map(BaseOptions::build).ifPresent(args::putAll);
return CommandExecutionHelper.executeScript(this, "mobile: removeApp", args);
return checkNotNull(
CommandExecutionHelper.executeScript(this, "mobile: removeApp", args)
);
}

/**
Expand Down Expand Up @@ -144,10 +149,12 @@ default void activateApp(String bundleId, @Nullable BaseActivateApplicationOptio
*/
default ApplicationState queryAppState(String bundleId) {
return ApplicationState.ofCode(
checkNotNull(
CommandExecutionHelper.executeScript(this, "mobile: queryAppState", ImmutableMap.of(
"bundleId", bundleId,
"appId", bundleId
))
)
);
}

Expand All @@ -174,6 +181,8 @@ default boolean terminateApp(String bundleId, @Nullable BaseTerminateApplication
args.put("bundleId", bundleId);
args.put("appId", bundleId);
Optional.ofNullable(options).map(BaseOptions::build).ifPresent(args::putAll);
return CommandExecutionHelper.executeScript(this, "mobile: terminateApp", args);
return checkNotNull(
CommandExecutionHelper.executeScript(this, "mobile: terminateApp", args)
);
}
}
14 changes: 10 additions & 4 deletions src/main/java/io/appium/java_client/PullsFiles.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.nio.charset.StandardCharsets;
import java.util.Base64;

import static com.google.common.base.Preconditions.checkNotNull;

public interface PullsFiles extends ExecutesMethod {

/**
Expand All @@ -36,9 +38,11 @@ public interface PullsFiles extends ExecutesMethod {
* @return A byte array of Base64 encoded data.
*/
default byte[] pullFile(String remotePath) {
String base64String = CommandExecutionHelper.executeScript(this, "mobile: pullFile", ImmutableMap.of(
String base64String = checkNotNull(
CommandExecutionHelper.executeScript(this, "mobile: pullFile", ImmutableMap.of(
"remotePath", remotePath
));
))
);
return Base64.getDecoder().decode(base64String.getBytes(StandardCharsets.UTF_8));
}

Expand All @@ -55,9 +59,11 @@ default byte[] pullFile(String remotePath) {
* @return A byte array of Base64 encoded zip archive data.
*/
default byte[] pullFolder(String remotePath) {
String base64String = CommandExecutionHelper.executeScript(this, "mobile: pullFolder", ImmutableMap.of(
String base64String = checkNotNull(
CommandExecutionHelper.executeScript(this, "mobile: pullFolder", ImmutableMap.of(
"remotePath", remotePath
));
))
);
return Base64.getDecoder().decode(base64String.getBytes(StandardCharsets.UTF_8));
}

Expand Down
Loading