Skip to content

Commit 5af08a1

Browse files
fix: Properly translate desiredCapabilities into a command line argument (#1337)
1 parent 85e806a commit 5af08a1

File tree

2 files changed

+18
-80
lines changed

2 files changed

+18
-80
lines changed

src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java

Lines changed: 12 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,15 @@
2323
import com.google.common.collect.ImmutableList;
2424
import com.google.common.collect.ImmutableMap;
2525

26-
import io.appium.java_client.remote.AndroidMobileCapabilityType;
27-
import io.appium.java_client.remote.MobileCapabilityType;
26+
import com.google.gson.Gson;
27+
import com.google.gson.GsonBuilder;
2828
import io.appium.java_client.service.local.flags.ServerArgument;
2929

3030
import org.apache.commons.io.IOUtils;
3131
import org.apache.commons.lang3.StringUtils;
3232
import org.apache.commons.lang3.SystemUtils;
3333
import org.apache.commons.validator.routines.InetAddressValidator;
3434
import org.openqa.selenium.Capabilities;
35-
import org.openqa.selenium.Platform;
3635
import org.openqa.selenium.os.ExecutableFinder;
3736
import org.openqa.selenium.remote.BrowserType;
3837
import org.openqa.selenium.remote.DesiredCapabilities;
@@ -54,7 +53,6 @@
5453
import java.util.concurrent.TimeUnit;
5554
import java.util.function.Function;
5655

57-
5856
public final class AppiumServiceBuilder
5957
extends DriverService.Builder<AppiumDriverLocalService, AppiumServiceBuilder> {
6058

@@ -73,8 +71,6 @@ public final class AppiumServiceBuilder
7371
private static final String NODE_PATH = "NODE_BINARY_PATH";
7472

7573
public static final String BROADCAST_IP_ADDRESS = "0.0.0.0";
76-
private static final List<String> PATH_CAPABILITIES = ImmutableList.of(AndroidMobileCapabilityType.KEYSTORE_PATH,
77-
AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, MobileCapabilityType.APP);
7874
private static final Path APPIUM_PATH_SUFFIX = Paths.get("appium", "build", "lib", "main.js");
7975
public static final int DEFAULT_APPIUM_PORT = 4723;
8076
private final Map<String, String> serverArguments = new HashMap<>();
@@ -300,79 +296,15 @@ private void loadPathToMainScript() {
300296
this.appiumJS = findMainScript();
301297
}
302298

303-
private String parseCapabilitiesIfWindows() {
304-
String result = StringUtils.EMPTY;
305-
306-
if (capabilities != null) {
307-
Map<String, ?> capabilitiesMap = capabilities.asMap();
308-
Set<? extends Map.Entry<String, ?>> entries = capabilitiesMap.entrySet();
309-
310-
for (Map.Entry<String, ?> entry : entries) {
311-
Object value = entry.getValue();
312-
313-
if (value == null) {
314-
continue;
315-
}
316-
317-
if (String.class.isAssignableFrom(value.getClass())) {
318-
if (PATH_CAPABILITIES.contains(entry.getKey())) {
319-
value = "\\\"" + String.valueOf(value).replace("\\", "/") + "\\\"";
320-
} else {
321-
value = "\\\"" + value + "\\\"";
322-
}
323-
} else {
324-
value = String.valueOf(value);
325-
}
326-
327-
String key = "\\\"" + entry.getKey() + "\\\"";
328-
if (StringUtils.isBlank(result)) {
329-
result = key + ": " + value;
330-
} else {
331-
result = result + ", " + key + ": " + value;
332-
}
333-
}
334-
}
335-
336-
return "{" + result + "}";
337-
}
338-
339-
private String parseCapabilitiesIfUNIX() {
340-
String result = StringUtils.EMPTY;
341-
342-
if (capabilities != null) {
343-
Map<String, ?> capabilitiesMap = capabilities.asMap();
344-
Set<? extends Map.Entry<String, ?>> entries = capabilitiesMap.entrySet();
345-
346-
for (Map.Entry<String, ?> entry : entries) {
347-
Object value = entry.getValue();
348-
349-
if (value == null) {
350-
continue;
351-
}
352-
353-
if (String.class.isAssignableFrom(value.getClass())) {
354-
value = "\"" + value + "\"";
355-
} else {
356-
value = String.valueOf(value);
357-
}
358-
359-
String key = "\"" + entry.getKey() + "\"";
360-
if (StringUtils.isBlank(result)) {
361-
result = key + ": " + value;
362-
} else {
363-
result = result + ", " + key + ": " + value;
364-
}
365-
}
366-
}
367-
368-
return "{" + result + "}";
369-
}
370-
371-
private String parseCapabilities() {
372-
if (Platform.getCurrent().is(Platform.WINDOWS)) {
373-
return parseCapabilitiesIfWindows();
374-
}
375-
return parseCapabilitiesIfUNIX();
299+
private String capabilitiesToCmdlineArg() {
300+
Gson gson = new GsonBuilder()
301+
.disableHtmlEscaping()
302+
.serializeNulls()
303+
.create();
304+
// Selenium internally uses org.apache.commons.exec.CommandLine
305+
// which has the following known bug in its arguments parser:
306+
// https://issues.apache.org/jira/browse/EXEC-54
307+
return gson.toJson(capabilities.asMap());
376308
}
377309

378310
@Override
@@ -418,7 +350,7 @@ protected ImmutableList<String> createArgs() {
418350

419351
if (capabilities != null) {
420352
argList.add("--default-capabilities");
421-
argList.add(parseCapabilities());
353+
argList.add(capabilitiesToCmdlineArg());
422354
}
423355

424356
return new ImmutableList.Builder<String>().addAll(argList).build();

src/test/java/io/appium/java_client/service/local/ServerBuilderTest.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import static org.junit.Assert.assertThat;
2929
import static org.junit.Assert.assertTrue;
3030

31+
import com.google.common.collect.ImmutableMap;
3132
import io.github.bonigarcia.wdm.WebDriverManager;
3233
import org.junit.After;
3334
import org.junit.BeforeClass;
@@ -178,6 +179,11 @@ public void checkAbilityToStartServiceUsingCapabilitiesAndFlags() {
178179
caps.setCapability(APP_PACKAGE, "io.appium.android.apis");
179180
caps.setCapability(APP_ACTIVITY, ".view.WebView1");
180181
caps.setCapability(APP, app.getAbsolutePath());
182+
caps.setCapability("winPath", "C:\\selenium\\app.apk");
183+
caps.setCapability("unixPath", "/selenium/app.apk");
184+
caps.setCapability("quotes", "\"'");
185+
caps.setCapability("goog:chromeOptions",
186+
ImmutableMap.of("env", ImmutableMap.of("test", "value"), "val2", 0));
181187
caps.setCapability(CHROMEDRIVER_EXECUTABLE, chromeManager.getBinaryPath());
182188

183189
service = new AppiumServiceBuilder()

0 commit comments

Comments
 (0)