Skip to content

Commit 7c54398

Browse files
authored
[java] Add browser output from Selenium Manager to options (#12424)
1 parent 86f7b57 commit 7c54398

File tree

13 files changed

+147
-36
lines changed

13 files changed

+147
-36
lines changed

java/src/org/openqa/selenium/chrome/ChromeDriver.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.openqa.selenium.chromium.ChromiumDriver;
2626
import org.openqa.selenium.chromium.ChromiumDriverCommandExecutor;
2727
import org.openqa.selenium.internal.Require;
28+
import org.openqa.selenium.manager.SeleniumManagerOutput.Result;
2829
import org.openqa.selenium.remote.CommandInfo;
2930
import org.openqa.selenium.remote.RemoteWebDriver;
3031
import org.openqa.selenium.remote.RemoteWebDriverBuilder;
@@ -95,8 +96,9 @@ private static ChromeDriverCommandExecutor generateExecutor(
9596
Require.nonNull("Driver options", options);
9697
Require.nonNull("Driver clientConfig", clientConfig);
9798
if (service.getExecutable() == null) {
98-
String path = DriverFinder.getPath(service, options);
99-
service.setExecutable(path);
99+
Result result = DriverFinder.getPath(service, options);
100+
service.setExecutable(result.getDriverPath());
101+
options.setBinary(result.getBrowserPath());
100102
}
101103
return new ChromeDriverCommandExecutor(service, clientConfig);
102104
}

java/src/org/openqa/selenium/edge/EdgeDriver.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import org.openqa.selenium.chromium.ChromiumDriver;
2424
import org.openqa.selenium.chromium.ChromiumDriverCommandExecutor;
2525
import org.openqa.selenium.internal.Require;
26+
import org.openqa.selenium.manager.SeleniumManagerOutput;
27+
import org.openqa.selenium.manager.SeleniumManagerOutput.Result;
2628
import org.openqa.selenium.remote.CommandInfo;
2729
import org.openqa.selenium.remote.RemoteWebDriver;
2830
import org.openqa.selenium.remote.RemoteWebDriverBuilder;
@@ -67,8 +69,9 @@ private static EdgeDriverCommandExecutor generateExecutor(
6769
Require.nonNull("Driver options", options);
6870
Require.nonNull("Driver clientConfig", clientConfig);
6971
if (service.getExecutable() == null) {
70-
String path = DriverFinder.getPath(service, options);
71-
service.setExecutable(path);
72+
Result result = DriverFinder.getPath(service, options);
73+
service.setExecutable(result.getDriverPath());
74+
options.setBinary(result.getBrowserPath());
7275
}
7376
return new EdgeDriverCommandExecutor(service, clientConfig);
7477
}

java/src/org/openqa/selenium/firefox/FirefoxDriver.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@
5050
import org.openqa.selenium.html5.SessionStorage;
5151
import org.openqa.selenium.html5.WebStorage;
5252
import org.openqa.selenium.internal.Require;
53+
import org.openqa.selenium.manager.SeleniumManagerOutput;
54+
import org.openqa.selenium.manager.SeleniumManagerOutput.Result;
5355
import org.openqa.selenium.remote.CommandInfo;
5456
import org.openqa.selenium.remote.FileDetector;
5557
import org.openqa.selenium.remote.RemoteWebDriver;
@@ -137,8 +139,9 @@ private static FirefoxDriverCommandExecutor generateExecutor(
137139
Require.nonNull("Driver options", options);
138140
Require.nonNull("Driver clientConfig", clientConfig);
139141
if (service.getExecutable() == null) {
140-
String path = DriverFinder.getPath(service, options);
141-
service.setExecutable(path);
142+
Result result = DriverFinder.getPath(service, options);
143+
service.setExecutable(result.getDriverPath());
144+
options.setBinary(result.getBrowserPath());
142145
}
143146
return new FirefoxDriverCommandExecutor(service, clientConfig);
144147
}

java/src/org/openqa/selenium/grid/node/config/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@ java_library(
1111
],
1212
deps = [
1313
"//java:auto-service",
14-
"//java/src/org/openqa/selenium/chromium",
1514
"//java/src/org/openqa/selenium/grid/config",
1615
"//java/src/org/openqa/selenium/grid/data",
1716
"//java/src/org/openqa/selenium/grid/node",
1817
"//java/src/org/openqa/selenium/json",
18+
"//java/src/org/openqa/selenium/manager",
1919
"//java/src/org/openqa/selenium/remote",
2020
artifact("com.beust:jcommander"),
2121
artifact("com.google.guava:guava"),

java/src/org/openqa/selenium/grid/node/config/DriverServiceSessionFactory.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
import java.net.URL;
2727
import java.time.Duration;
2828
import java.time.Instant;
29+
import java.util.Arrays;
2930
import java.util.HashMap;
31+
import java.util.List;
3032
import java.util.Map;
3133
import java.util.Optional;
3234
import java.util.Set;
@@ -48,6 +50,7 @@
4850
import org.openqa.selenium.grid.node.SessionFactory;
4951
import org.openqa.selenium.internal.Either;
5052
import org.openqa.selenium.internal.Require;
53+
import org.openqa.selenium.manager.SeleniumManagerOutput.Result;
5154
import org.openqa.selenium.net.HostIdentifier;
5255
import org.openqa.selenium.net.NetworkUtils;
5356
import org.openqa.selenium.remote.Command;
@@ -58,6 +61,7 @@
5861
import org.openqa.selenium.remote.SessionId;
5962
import org.openqa.selenium.remote.http.ClientConfig;
6063
import org.openqa.selenium.remote.http.HttpClient;
64+
import org.openqa.selenium.remote.service.DriverFinder;
6165
import org.openqa.selenium.remote.service.DriverService;
6266
import org.openqa.selenium.remote.tracing.AttributeKey;
6367
import org.openqa.selenium.remote.tracing.EventAttribute;
@@ -134,6 +138,13 @@ public Either<WebDriverException, ActiveSession> apply(CreateSessionRequest sess
134138
AttributeKey.LOGGER_CLASS.getKey(), EventAttribute.setValue(this.getClass().getName()));
135139

136140
DriverService service = builder.build();
141+
if (service.getExecutable() == null) {
142+
Result result = DriverFinder.getPath(service, capabilities);
143+
service.setExecutable(result.getDriverPath());
144+
if (result.getBrowserPath() != null) {
145+
capabilities = setBrowserBinary(capabilities, result.getBrowserPath());
146+
}
147+
}
137148
try {
138149
service.start();
139150

@@ -327,4 +338,27 @@ private String getHost() {
327338
return HostIdentifier.getHostName();
328339
}
329340
}
341+
342+
private Capabilities setBrowserBinary(Capabilities options, String browserPath) {
343+
List<String> vendorOptionsCapabilities =
344+
Arrays.asList("moz:firefoxOptions", "goog:chromeOptions", "ms:edgeOptions");
345+
for (String vendorOptionsCapability : vendorOptionsCapabilities) {
346+
if (options.asMap().containsKey(vendorOptionsCapability)) {
347+
try {
348+
@SuppressWarnings("unchecked")
349+
Map<String, Object> vendorOptions =
350+
(Map<String, Object>) options.getCapability(vendorOptionsCapability);
351+
vendorOptions.put("binary", browserPath);
352+
return new PersistentCapabilities(options)
353+
.setCapability(vendorOptionsCapability, vendorOptions);
354+
} catch (Exception e) {
355+
LOG.warning(
356+
String.format(
357+
"Exception while setting the browser binary path. %s: %s",
358+
options, e.getMessage()));
359+
}
360+
}
361+
}
362+
return options;
363+
}
330364
}

java/src/org/openqa/selenium/ie/InternetExplorerDriver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public InternetExplorerDriver(
133133
service = InternetExplorerDriverService.createDefaultService();
134134
}
135135
if (service.getExecutable() == null) {
136-
String path = DriverFinder.getPath(service, options);
136+
String path = DriverFinder.getPath(service, options).getDriverPath();
137137
service.setExecutable(path);
138138
}
139139
if (clientConfig == null) {

java/src/org/openqa/selenium/manager/SeleniumManager.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.openqa.selenium.WebDriverException;
4242
import org.openqa.selenium.json.Json;
4343
import org.openqa.selenium.json.JsonException;
44+
import org.openqa.selenium.manager.SeleniumManagerOutput.Result;
4445

4546
/**
4647
* This implementation is still in beta, and may change.
@@ -100,7 +101,7 @@ public static SeleniumManager getInstance() {
100101
* @param command the file and arguments to execute.
101102
* @return the standard output of the execution.
102103
*/
103-
private static String runCommand(String... command) {
104+
private static Result runCommand(String... command) {
104105
LOG.fine(String.format("Executing Process: %s", Arrays.toString(command)));
105106
String output;
106107
int code;
@@ -118,12 +119,12 @@ private static String runCommand(String... command) {
118119
} catch (Exception e) {
119120
throw new WebDriverException("Failed to run command: " + Arrays.toString(command), e);
120121
}
121-
SeleniumManagerJsonOutput jsonOutput = null;
122+
SeleniumManagerOutput jsonOutput = null;
122123
JsonException failedToParse = null;
123124
String dump = output;
124125
if (!output.isEmpty()) {
125126
try {
126-
jsonOutput = new Json().toType(output, SeleniumManagerJsonOutput.class);
127+
jsonOutput = new Json().toType(output, SeleniumManagerOutput.class);
127128
jsonOutput.logs.forEach(
128129
logged -> {
129130
if (logged.level.equalsIgnoreCase(WARN)) {
@@ -147,12 +148,12 @@ private static String runCommand(String... command) {
147148
+ "\n"
148149
+ dump,
149150
failedToParse);
150-
} else if (failedToParse != null) {
151+
} else if (failedToParse != null || jsonOutput == null) {
151152
throw new WebDriverException(
152153
"Failed to parse json output, executed: " + Arrays.toString(command) + "\n" + dump,
153154
failedToParse);
154155
}
155-
return jsonOutput.result.message;
156+
return jsonOutput.result;
156157
}
157158

158159
/**
@@ -223,7 +224,7 @@ private String getBrowserBinary(Capabilities options) {
223224
* @param options Browser Options instance.
224225
* @return the location of the driver.
225226
*/
226-
public String getDriverPath(Capabilities options, boolean offline) {
227+
public Result getDriverPath(Capabilities options, boolean offline) {
227228
File binaryFile = getBinary();
228229
if (binaryFile == null) {
229230
return null;
@@ -265,9 +266,12 @@ public String getDriverPath(Capabilities options, boolean offline) {
265266
}
266267
}
267268

268-
String path = runCommand(commandList.toArray(new String[0]));
269-
LOG.fine(String.format("Using driver at location: %s", path));
270-
return path;
269+
Result result = runCommand(commandList.toArray(new String[0]));
270+
LOG.fine(
271+
String.format(
272+
"Using driver at location: %s, browser at location %s",
273+
result.getDriverPath(), result.getBrowserPath()));
274+
return result;
271275
}
272276

273277
private Level getLogLevel() {

java/src/org/openqa/selenium/manager/SeleniumManagerJsonOutput.java renamed to java/src/org/openqa/selenium/manager/SeleniumManagerOutput.java

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@
1616
// under the License.
1717
package org.openqa.selenium.manager;
1818

19+
import org.openqa.selenium.json.JsonInput;
20+
1921
import java.util.List;
2022

21-
public class SeleniumManagerJsonOutput {
23+
public class SeleniumManagerOutput {
2224

2325
public List<Log> logs;
2426
public Result result;
@@ -72,6 +74,19 @@ public void setMessage(String message) {
7274
public static class Result {
7375
public int code;
7476
public String message;
77+
public String driverPath;
78+
public String browserPath;
79+
80+
public Result(String driverPath) {
81+
this.driverPath = driverPath;
82+
}
83+
84+
public Result(int code, String message, String driverPath, String browserPath) {
85+
this.code = code;
86+
this.message = message;
87+
this.driverPath = driverPath;
88+
this.browserPath = browserPath;
89+
}
7590

7691
public int getCode() {
7792
return code;
@@ -88,5 +103,56 @@ public String getMessage() {
88103
public void setMessage(String message) {
89104
this.message = message;
90105
}
106+
107+
public String getDriverPath() {
108+
return driverPath;
109+
}
110+
111+
public void setDriverPath(String driverPath) {
112+
this.driverPath = driverPath;
113+
}
114+
115+
public String getBrowserPath() {
116+
return browserPath;
117+
}
118+
119+
public void setBrowserPath(String browserPath) {
120+
this.browserPath = browserPath;
121+
}
122+
123+
public static Result fromJson(JsonInput input) {
124+
int code = 0;
125+
String message = null;
126+
String driverPath = null;
127+
String browserPath = null;
128+
129+
input.beginObject();
130+
while (input.hasNext()) {
131+
switch (input.nextName()) {
132+
case "code":
133+
code = input.read(Integer.class);
134+
break;
135+
136+
case "message":
137+
message = input.read(String.class);
138+
break;
139+
140+
case "driver_path":
141+
driverPath = input.read(String.class);
142+
break;
143+
144+
case "browser_path":
145+
browserPath = input.read(String.class);
146+
break;
147+
148+
default:
149+
input.skipValue();
150+
break;
151+
}
152+
}
153+
input.endObject();
154+
155+
return new Result(code, message, driverPath, browserPath);
156+
}
91157
}
92158
}

java/src/org/openqa/selenium/remote/service/DriverFinder.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,37 @@
44
import org.openqa.selenium.Capabilities;
55
import org.openqa.selenium.internal.Require;
66
import org.openqa.selenium.manager.SeleniumManager;
7+
import org.openqa.selenium.manager.SeleniumManagerOutput.Result;
78
import org.openqa.selenium.remote.NoSuchDriverException;
89

910
public class DriverFinder {
1011

11-
public static String getPath(DriverService service, Capabilities options) {
12+
public static Result getPath(DriverService service, Capabilities options) {
1213
return getPath(service, options, false);
1314
}
1415

15-
public static String getPath(DriverService service, Capabilities options, boolean offline) {
16+
public static Result getPath(DriverService service, Capabilities options, boolean offline) {
1617
Require.nonNull("Browser options", options);
17-
String exePath = System.getProperty(service.getDriverProperty());
18+
Result result = new Result(System.getProperty(service.getDriverProperty()));
1819

19-
if (exePath == null) {
20+
if (result.getDriverPath() == null) {
2021
try {
21-
exePath = SeleniumManager.getInstance().getDriverPath(options, offline);
22+
result = SeleniumManager.getInstance().getDriverPath(options, offline);
2223
} catch (Exception e) {
2324
throw new NoSuchDriverException(String.format("Unable to obtain: %s", options), e);
2425
}
2526
}
2627

2728
String message;
28-
if (exePath == null) {
29+
if (result.getDriverPath() == null) {
2930
message = String.format("Unable to locate or obtain %s", service.getDriverName());
30-
} else if (!new File(exePath).exists()) {
31-
message = String.format("%s located at %s, but invalid", service.getDriverName(), exePath);
32-
} else if (!new File(exePath).canExecute()) {
31+
} else if (!new File(result.getDriverPath()).exists()) {
32+
message = String.format("%s located at %s, but invalid", service.getDriverName(), result.getDriverPath());
33+
} else if (!new File(result.getDriverPath()).canExecute()) {
3334
message =
34-
String.format("%s located at %s, cannot be executed", service.getDriverName(), exePath);
35+
String.format("%s located at %s, cannot be executed", service.getDriverName(), result.getDriverPath());
3536
} else {
36-
return exePath;
37+
return result;
3738
}
3839

3940
throw new NoSuchDriverException(message);

java/src/org/openqa/selenium/remote/service/DriverService.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,6 @@ public void start() throws IOException {
194194
if (process != null) {
195195
return;
196196
}
197-
if (this.executable == null) {
198-
if (getDefaultDriverOptions().getBrowserName().isEmpty()) {
199-
throw new WebDriverException("Driver executable is null and browser name is not set.");
200-
}
201-
this.executable = DriverFinder.getPath(this, getDefaultDriverOptions());
202-
}
203197
LOG.fine(String.format("Starting driver at %s with %s", this.executable, this.args));
204198
process = new CommandLine(this.executable, args.toArray(new String[] {}));
205199
process.setEnvironmentVariables(environment);

0 commit comments

Comments
 (0)