|
25 | 25 |
|
26 | 26 | import com.google.gson.Gson;
|
27 | 27 | import com.google.gson.GsonBuilder;
|
| 28 | +import io.appium.java_client.remote.AndroidMobileCapabilityType; |
| 29 | +import io.appium.java_client.remote.MobileCapabilityType; |
28 | 30 | import io.appium.java_client.service.local.flags.ServerArgument;
|
29 | 31 |
|
30 | 32 | import org.apache.commons.io.IOUtils;
|
31 | 33 | import org.apache.commons.lang3.StringUtils;
|
32 | 34 | import org.apache.commons.lang3.SystemUtils;
|
33 | 35 | import org.apache.commons.validator.routines.InetAddressValidator;
|
34 | 36 | import org.openqa.selenium.Capabilities;
|
| 37 | +import org.openqa.selenium.Platform; |
35 | 38 | import org.openqa.selenium.os.ExecutableFinder;
|
36 | 39 | import org.openqa.selenium.remote.BrowserType;
|
37 | 40 | import org.openqa.selenium.remote.DesiredCapabilities;
|
@@ -78,6 +81,7 @@ public final class AppiumServiceBuilder
|
78 | 81 | private File node;
|
79 | 82 | private String ipAddress = BROADCAST_IP_ADDRESS;
|
80 | 83 | private DesiredCapabilities capabilities;
|
| 84 | + private boolean autoQuoteCapabilitiesOnWindows = false; |
81 | 85 | private static final Function<File, String> APPIUM_JS_NOT_EXIST_ERROR = (fullPath) -> String.format(
|
82 | 86 | "The main Appium script does not exist at '%s'", fullPath.getAbsolutePath());
|
83 | 87 | private static final Function<File, String> NODE_JS_NOT_EXIST_ERROR = (fullPath) ->
|
@@ -239,6 +243,21 @@ public AppiumServiceBuilder withCapabilities(DesiredCapabilities capabilities) {
|
239 | 243 | return this;
|
240 | 244 | }
|
241 | 245 |
|
| 246 | + /** |
| 247 | + * Adds a desired capabilities. |
| 248 | + * |
| 249 | + * @param capabilities is an instance of {@link DesiredCapabilities}. |
| 250 | + * @param autoQuoteCapabilitiesOnWindows automatically escape quote all |
| 251 | + * capabilities when calling appium. |
| 252 | + * This is required on windows systems only. |
| 253 | + * @return the self-reference. |
| 254 | + */ |
| 255 | + public AppiumServiceBuilder withCapabilities(DesiredCapabilities capabilities, |
| 256 | + boolean autoQuoteCapabilitiesOnWindows) { |
| 257 | + this.autoQuoteCapabilitiesOnWindows = autoQuoteCapabilitiesOnWindows; |
| 258 | + return withCapabilities(capabilities); |
| 259 | + } |
| 260 | + |
242 | 261 | /**
|
243 | 262 | * Sets an executable appium.js.
|
244 | 263 | *
|
@@ -296,7 +315,49 @@ private void loadPathToMainScript() {
|
296 | 315 | this.appiumJS = findMainScript();
|
297 | 316 | }
|
298 | 317 |
|
| 318 | + private String parseCapabilitiesIfWindows() { |
| 319 | + String result = StringUtils.EMPTY; |
| 320 | + final List<String> pathCapabilities = ImmutableList.of(AndroidMobileCapabilityType.KEYSTORE_PATH, |
| 321 | + AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, MobileCapabilityType.APP); |
| 322 | + |
| 323 | + if (capabilities != null) { |
| 324 | + Map<String, ?> capabilitiesMap = capabilities.asMap(); |
| 325 | + Set<? extends Map.Entry<String, ?>> entries = capabilitiesMap.entrySet(); |
| 326 | + |
| 327 | + for (Map.Entry<String, ?> entry : entries) { |
| 328 | + Object value = entry.getValue(); |
| 329 | + |
| 330 | + if (value == null) { |
| 331 | + continue; |
| 332 | + } |
| 333 | + |
| 334 | + if (value instanceof String) { |
| 335 | + String valueString = (String) value; |
| 336 | + if (pathCapabilities.contains(entry.getKey())) { |
| 337 | + value = "\\\"" + valueString.replace("\\", "/") + "\\\""; |
| 338 | + } else { |
| 339 | + value = "\\\"" + valueString + "\\\""; |
| 340 | + } |
| 341 | + } else { |
| 342 | + value = String.valueOf(value); |
| 343 | + } |
| 344 | + |
| 345 | + String key = "\\\"" + entry.getKey() + "\\\""; |
| 346 | + if (StringUtils.isBlank(result)) { |
| 347 | + result = key + ": " + value; |
| 348 | + } else { |
| 349 | + result = result + ", " + key + ": " + value; |
| 350 | + } |
| 351 | + } |
| 352 | + } |
| 353 | + |
| 354 | + return "{" + result + "}"; |
| 355 | + } |
| 356 | + |
299 | 357 | private String capabilitiesToCmdlineArg() {
|
| 358 | + if (autoQuoteCapabilitiesOnWindows && Platform.getCurrent().is(Platform.WINDOWS)) { |
| 359 | + return parseCapabilitiesIfWindows(); |
| 360 | + } |
300 | 361 | Gson gson = new GsonBuilder()
|
301 | 362 | .disableHtmlEscaping()
|
302 | 363 | .serializeNulls()
|
|
0 commit comments