|
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,48 @@ private void loadPathToMainScript() { |
296 | 315 | this.appiumJS = findMainScript(); |
297 | 316 | } |
298 | 317 |
|
| 318 | + private String parseCapabilitiesIfWindows() { |
| 319 | + StringBuilder result = new StringBuilder(); |
| 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 (result.length() > 0) { |
| 347 | + result.append(", "); |
| 348 | + } |
| 349 | + result.append(key).append(": ").append(value); |
| 350 | + } |
| 351 | + } |
| 352 | + |
| 353 | + return "{" + result.toString() + "}"; |
| 354 | + } |
| 355 | + |
299 | 356 | private String capabilitiesToCmdlineArg() { |
| 357 | + if (autoQuoteCapabilitiesOnWindows && Platform.getCurrent().is(Platform.WINDOWS)) { |
| 358 | + return parseCapabilitiesIfWindows(); |
| 359 | + } |
300 | 360 | Gson gson = new GsonBuilder() |
301 | 361 | .disableHtmlEscaping() |
302 | 362 | .serializeNulls() |
|
0 commit comments