|
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