|
33 | 33 | import java.util.Map;
|
34 | 34 | import java.util.Set;
|
35 | 35 |
|
| 36 | +import static com.google.common.base.Preconditions.checkArgument; |
| 37 | +import static io.appium.java_client.remote.MobileCapabilityType.*; |
36 | 38 | import static io.appium.java_client.MobileCommand.*;
|
37 | 39 |
|
38 | 40 | public class AppiumDriver extends RemoteWebDriver implements MobileDriver, ContextAware, Rotatable, FindsByIosUIAutomation,
|
@@ -81,6 +83,7 @@ public AppiumDriver(URL remoteAddress, Capabilities desiredCapabilities){
|
81 | 83 | .put(OPEN_NOTIFICATIONS, postC("/session/:sessionId/appium/device/open_notifications"))
|
82 | 84 | .put(GET_NETWORK_CONNECTION, getC("/session/:sessionId/network_connection"))
|
83 | 85 | .put(SET_NETWORK_CONNECTION, postC("/session/:sessionId/network_connection"))
|
| 86 | + .put(START_ACTIVITY, postC("/session/:sessionId/appium/device/start_activity")) |
84 | 87 | ;
|
85 | 88 | ImmutableMap<String, CommandInfo> mobileCommands = builder.build();
|
86 | 89 |
|
@@ -168,6 +171,46 @@ public String currentActivity() {
|
168 | 171 | Response response = execute(CURRENT_ACTIVITY);
|
169 | 172 | return response.getValue().toString();
|
170 | 173 | }
|
| 174 | + |
| 175 | + /** |
| 176 | + * Launches an arbitrary activity during a test. If the activity belongs to |
| 177 | + * another application, that application is started and the activity is opened. |
| 178 | + * |
| 179 | + * This is an Android-only method. |
| 180 | + * @param appPackage The package containing the activity. [Required] |
| 181 | + * @param appActivity The activity to start. [Required] |
| 182 | + * @param appWaitPackage Automation will begin after this package starts. [Optional] |
| 183 | + * @param appWaitActivity Automation will begin after this activity starts. [Optional] |
| 184 | + * @example |
| 185 | + * driver.startActivity("com.foo.bar", ".MyActivity", null, null); |
| 186 | + */ |
| 187 | + public void startActivity(String appPackage, String appActivity, String appWaitPackage, String appWaitActivity) |
| 188 | + throws IllegalArgumentException { |
| 189 | + |
| 190 | + checkArgument((_isNotNullOrEmpty(appPackage) && _isNotNullOrEmpty(appActivity)), |
| 191 | + String.format("'%s' and '%s' are required.", APP_PACKAGE, APP_ACTIVITY)); |
| 192 | + |
| 193 | + appWaitPackage = _isNotNullOrEmpty(appWaitPackage) ? appWaitPackage : ""; |
| 194 | + appWaitActivity = _isNotNullOrEmpty(appWaitActivity) ? appWaitActivity : ""; |
| 195 | + |
| 196 | + ImmutableMap<String, String> parameters = ImmutableMap.of(APP_PACKAGE, appPackage, |
| 197 | + APP_ACTIVITY, appActivity, |
| 198 | + APP_WAIT_PACKAGE, appWaitPackage, |
| 199 | + APP_WAIT_ACTIVITY, appWaitActivity); |
| 200 | + |
| 201 | + execute(START_ACTIVITY, parameters); |
| 202 | + } |
| 203 | + |
| 204 | + /** |
| 205 | + * Checks if a string is null, empty, or whitespace. |
| 206 | + * |
| 207 | + * @param str String to check. |
| 208 | + * |
| 209 | + * @return True if str is not null or empty. |
| 210 | + */ |
| 211 | + private static boolean _isNotNullOrEmpty(String str) { |
| 212 | + return str != null && !str.isEmpty() && str.trim().length() > 0; |
| 213 | + } |
171 | 214 |
|
172 | 215 | /**
|
173 | 216 | *
|
@@ -229,7 +272,7 @@ public void hideKeyboard() {
|
229 | 272 | */
|
230 | 273 | public void hideKeyboard(String strategy, String keyName) {
|
231 | 274 | ImmutableMap<String, String> parameters = ImmutableMap.of("strategy", strategy);
|
232 |
| - if (keyName != null) { |
| 275 | + if (_isNotNullOrEmpty(keyName)) { |
233 | 276 | parameters = parameters.of("key", keyName);
|
234 | 277 | }
|
235 | 278 |
|
@@ -574,7 +617,7 @@ public void setNetworkConnection(NetworkConnectionSetting connection) {
|
574 | 617 |
|
575 | 618 | @Override
|
576 | 619 | public WebDriver context(String name) {
|
577 |
| - if (name == null) { |
| 620 | + if (_isNotNullOrEmpty(name)) { |
578 | 621 | throw new IllegalArgumentException("Must supply a context name");
|
579 | 622 | }
|
580 | 623 |
|
|
0 commit comments