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
29 changes: 29 additions & 0 deletions src/main/java/io/appium/java_client/CommandExecutionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@

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,
Expand All @@ -37,4 +43,27 @@ private static <T> T handleResponse(Response response) {
}
return null;
}

public static <T> T executeScript(ExecutesMethod executesMethod, String scriptName) {
return executeScript(executesMethod, scriptName, null);
}

/**
* 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).
* @return Script execution result.
*/
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));
}
}
70 changes: 34 additions & 36 deletions src/main/java/io/appium/java_client/InteractsWithApps.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,17 @@
import io.appium.java_client.appmanagement.ApplicationState;
import io.appium.java_client.appmanagement.BaseActivateApplicationOptions;
import io.appium.java_client.appmanagement.BaseInstallApplicationOptions;
import io.appium.java_client.appmanagement.BaseOptions;
import io.appium.java_client.appmanagement.BaseRemoveApplicationOptions;
import io.appium.java_client.appmanagement.BaseTerminateApplicationOptions;

import javax.annotation.Nullable;
import java.time.Duration;
import java.util.AbstractMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

import static io.appium.java_client.MobileCommand.ACTIVATE_APP;
import static io.appium.java_client.MobileCommand.INSTALL_APP;
import static io.appium.java_client.MobileCommand.IS_APP_INSTALLED;
import static io.appium.java_client.MobileCommand.QUERY_APP_STATE;
import static io.appium.java_client.MobileCommand.REMOVE_APP;
import static io.appium.java_client.MobileCommand.RUN_APP_IN_BACKGROUND;
import static io.appium.java_client.MobileCommand.TERMINATE_APP;
import static io.appium.java_client.MobileCommand.prepareArguments;

@SuppressWarnings("rawtypes")
public interface InteractsWithApps extends ExecutesMethod {
Expand All @@ -56,12 +52,11 @@ default void installApp(String appPath) {
* the particular platform.
*/
default void installApp(String appPath, @Nullable BaseInstallApplicationOptions options) {
String[] parameters = options == null ? new String[]{"appPath"} :
new String[]{"appPath", "options"};
Object[] values = options == null ? new Object[]{appPath} :
new Object[]{appPath, options.build()};
CommandExecutionHelper.execute(this,
new AbstractMap.SimpleEntry<>(INSTALL_APP, prepareArguments(parameters, values)));
Map<String, Object> args = new HashMap<>();
args.put("app", appPath);
args.put("appPath", appPath);
Optional.ofNullable(options).map(BaseOptions::build).ifPresent(args::putAll);
CommandExecutionHelper.executeScript(this, "mobile: installApp", args);
}

/**
Expand All @@ -71,8 +66,10 @@ default void installApp(String appPath, @Nullable BaseInstallApplicationOptions
* @return True if app is installed, false otherwise.
*/
default boolean isAppInstalled(String bundleId) {
return CommandExecutionHelper.execute(this,
new AbstractMap.SimpleEntry<>(IS_APP_INSTALLED, prepareArguments("bundleId", bundleId)));
return CommandExecutionHelper.executeScript(this, "mobile: isAppInstalled", ImmutableMap.of(
"bundleId", bundleId,
"appId", bundleId
));
}

/**
Expand Down Expand Up @@ -106,12 +103,11 @@ default boolean removeApp(String bundleId) {
* @return true if the uninstall was successful.
*/
default boolean removeApp(String bundleId, @Nullable BaseRemoveApplicationOptions options) {
String[] parameters = options == null ? new String[]{"bundleId"} :
new String[]{"bundleId", "options"};
Object[] values = options == null ? new Object[]{bundleId} :
new Object[]{bundleId, options.build()};
return CommandExecutionHelper.execute(this,
new AbstractMap.SimpleEntry<>(REMOVE_APP, prepareArguments(parameters, values)));
Map<String, Object> args = new HashMap<>();
args.put("bundleId", bundleId);
args.put("appId", bundleId);
Optional.ofNullable(options).map(BaseOptions::build).ifPresent(args::putAll);
return CommandExecutionHelper.executeScript(this, "mobile: removeApp", args);
}

/**
Expand All @@ -133,12 +129,11 @@ default void activateApp(String bundleId) {
* particular platform.
*/
default void activateApp(String bundleId, @Nullable BaseActivateApplicationOptions options) {
String[] parameters = options == null ? new String[]{"bundleId"} :
new String[]{"bundleId", "options"};
Object[] values = options == null ? new Object[]{bundleId} :
new Object[]{bundleId, options.build()};
CommandExecutionHelper.execute(this,
new AbstractMap.SimpleEntry<>(ACTIVATE_APP, prepareArguments(parameters, values)));
Map<String, Object> args = new HashMap<>();
args.put("bundleId", bundleId);
args.put("appId", bundleId);
Optional.ofNullable(options).map(BaseOptions::build).ifPresent(args::putAll);
CommandExecutionHelper.executeScript(this, "mobile: activateApp", args);
}

/**
Expand All @@ -148,8 +143,12 @@ default void activateApp(String bundleId, @Nullable BaseActivateApplicationOptio
* @return one of possible {@link ApplicationState} values,
*/
default ApplicationState queryAppState(String bundleId) {
return ApplicationState.ofCode(CommandExecutionHelper.execute(this,
new AbstractMap.SimpleEntry<>(QUERY_APP_STATE, ImmutableMap.of("bundleId", bundleId))));
return ApplicationState.ofCode(
CommandExecutionHelper.executeScript(this, "mobile: queryAppState", ImmutableMap.of(
"bundleId", bundleId,
"appId", bundleId
))
);
}

/**
Expand All @@ -171,11 +170,10 @@ 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) {
String[] parameters = options == null ? new String[]{"bundleId"} :
new String[]{"bundleId", "options"};
Object[] values = options == null ? new Object[]{bundleId} :
new Object[]{bundleId, options.build()};
return CommandExecutionHelper.execute(this,
new AbstractMap.SimpleEntry<>(TERMINATE_APP, prepareArguments(parameters, values)));
Map<String, Object> args = new HashMap<>();
args.put("bundleId", bundleId);
args.put("appId", bundleId);
Optional.ofNullable(options).map(BaseOptions::build).ifPresent(args::putAll);
return CommandExecutionHelper.executeScript(this, "mobile: terminateApp", args);
Copy link
Copy Markdown
Member

@KazuCocoa KazuCocoa Apr 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, does this include for mac2 driver as well? Then, mac2 driver needs macos instead of mobile
https://github.com/appium/appium-mac2-driver#macos-terminateapp
(queryAppState etc as well)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, only AndroidDriver and IOSDriver implement this interface

}
}
61 changes: 61 additions & 0 deletions src/main/java/io/appium/java_client/MobileCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,83 +35,144 @@
/**
* The repository of mobile commands defined in the Mobile JSON
* wire protocol.
*
* Most of these commands are platform-specific obsolete things and should eventually be replaced with
* calls to corresponding `mobile:` extensions, so we don't abuse non-w3c APIs
*/
public class MobileCommand {
//General
@Deprecated
protected static final String RESET;
@Deprecated
protected static final String GET_STRINGS;
@Deprecated
public static final String SET_VALUE;
@Deprecated
protected static final String PULL_FILE;
@Deprecated
protected static final String PULL_FOLDER;
public static final String RUN_APP_IN_BACKGROUND;
@Deprecated
protected static final String PERFORM_TOUCH_ACTION;
@Deprecated
protected static final String PERFORM_MULTI_TOUCH;
@Deprecated
public static final String LAUNCH_APP;
@Deprecated
public static final String CLOSE_APP;
@Deprecated
protected static final String GET_DEVICE_TIME;
@Deprecated
protected static final String GET_SESSION;
protected static final String LOG_EVENT;
protected static final String GET_EVENTS;

//region Applications Management
@Deprecated
protected static final String IS_APP_INSTALLED;
@Deprecated
protected static final String INSTALL_APP;
@Deprecated
protected static final String ACTIVATE_APP;
@Deprecated
protected static final String QUERY_APP_STATE;
@Deprecated
protected static final String TERMINATE_APP;
@Deprecated
protected static final String REMOVE_APP;
//endregion

//region Clipboard
@Deprecated
public static final String GET_CLIPBOARD;
@Deprecated
public static final String SET_CLIPBOARD;
//endregion

@Deprecated
protected static final String GET_PERFORMANCE_DATA;
@Deprecated
protected static final String GET_SUPPORTED_PERFORMANCE_DATA_TYPES;

@Deprecated
public static final String START_RECORDING_SCREEN;
@Deprecated
public static final String STOP_RECORDING_SCREEN;

@Deprecated
protected static final String HIDE_KEYBOARD;
@Deprecated
protected static final String LOCK;
//iOS
@Deprecated
protected static final String SHAKE;
@Deprecated
protected static final String TOUCH_ID;
@Deprecated
protected static final String TOUCH_ID_ENROLLMENT;
//Android
@Deprecated
protected static final String CURRENT_ACTIVITY;
@Deprecated
protected static final String END_TEST_COVERAGE;
@Deprecated
protected static final String GET_DISPLAY_DENSITY;
@Deprecated
protected static final String GET_NETWORK_CONNECTION;
@Deprecated
protected static final String GET_SYSTEM_BARS;
@Deprecated
protected static final String IS_KEYBOARD_SHOWN;
@Deprecated
protected static final String IS_LOCKED;
@Deprecated
public static final String LONG_PRESS_KEY_CODE;
@Deprecated
protected static final String FINGER_PRINT;
@Deprecated
protected static final String OPEN_NOTIFICATIONS;
@Deprecated
public static final String PRESS_KEY_CODE;
@Deprecated
protected static final String PUSH_FILE;
@Deprecated
protected static final String SET_NETWORK_CONNECTION;
@Deprecated
protected static final String START_ACTIVITY;
@Deprecated
protected static final String TOGGLE_LOCATION_SERVICES;
@Deprecated
protected static final String UNLOCK;
@Deprecated
public static final String REPLACE_VALUE;
protected static final String GET_SETTINGS;
@Deprecated
protected static final String SET_SETTINGS;
@Deprecated
protected static final String GET_CURRENT_PACKAGE;
@Deprecated
protected static final String SEND_SMS;
@Deprecated
protected static final String GSM_CALL;
@Deprecated
protected static final String GSM_SIGNAL;
@Deprecated
protected static final String GSM_VOICE;
@Deprecated
protected static final String NETWORK_SPEED;
@Deprecated
protected static final String POWER_CAPACITY;
@Deprecated
protected static final String POWER_AC_STATE;
@Deprecated
protected static final String TOGGLE_WIFI;
@Deprecated
protected static final String TOGGLE_AIRPLANE_MODE;
@Deprecated
protected static final String TOGGLE_DATA;
protected static final String COMPARE_IMAGES;
protected static final String EXECUTE_DRIVER_SCRIPT;
@Deprecated
protected static final String GET_ALLSESSION;
protected static final String EXECUTE_GOOGLE_CDP_COMMAND;

Expand Down