Skip to content

Commit c5fd09a

Browse files
committed
[grid] Enabling detectDrivers original behaviour.
When Selenium Manager was integrated to the Java bindings, Grid implicitly started using it, saving users time because they did not need to configure drivers on the Node host machine anymore. This seemed ideal but made things harder for advanced users who were configuring through the different flags for drivers. For example, a user with a Windows machine, may not want to use `IEDriverServer`. This change introduces a new boolean flag `--selenium-manager` set to `true` by default. When enabled, Selenium Manager will be used to configure all the possible drivers on the host machine. When disabled, the Node startup will only look for drivers that are already present on the host machine. This is only being implemented in Java because Grid has that special use case. When using the bindings, users will continue to pass the driver location or leave it on the `PATH`to avoid Selenium Manager. Fixes #11697
1 parent 3b16504 commit c5fd09a

17 files changed

+183
-41
lines changed

java/src/org/openqa/selenium/WebDriverInfo.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,18 @@ public interface WebDriverInfo {
6666
* that even though the driver classes might be present in Java, it would make no sense to attempt
6767
* to instantiate the driver itself.
6868
*
69-
* @return Whether or not the prerequisites required for this {@link WebDriver} are present.
69+
* @return Whether the prerequisites required for this {@link WebDriver} are present.
7070
*/
7171
boolean isAvailable();
7272

73+
/**
74+
* Checks whether the browser driver is already present on the host machine. Different from
75+
* {@link #isAvailable()} which uses Selenium Manager to obtain the driver when not present.
76+
*
77+
* @return Whether the browser driver is present on the host machine.
78+
*/
79+
boolean isPresent();
80+
7381
/**
7482
* Some browsers require all the resources of the current system in order to run (for example,
7583
* Safari on iOS) and so do not support multiple simultaneous sessions on the same system. Other

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,14 @@ public boolean isAvailable() {
7171
}
7272
}
7373

74+
@Override
75+
public boolean isPresent() {
76+
return ChromeDriverService.isPresent();
77+
}
78+
7479
@Override
7580
public Optional<WebDriver> createDriver(Capabilities capabilities)
76-
throws SessionNotCreatedException {
81+
throws SessionNotCreatedException {
7782
if (!isAvailable() || !isSupporting(capabilities)) {
7883
return Optional.empty();
7984
}

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,27 +159,40 @@ public static ChromeDriverService createDefaultService() {
159159
@Deprecated
160160
public static ChromeDriverService createServiceWithConfig(ChromeOptions options) {
161161
ChromeDriverLogLevel oldLevel = options.getLogLevel();
162-
ChromiumDriverLogLevel level = (oldLevel == null) ? null : ChromiumDriverLogLevel.fromString(oldLevel.toString());
162+
ChromiumDriverLogLevel level = (oldLevel == null) ? null :
163+
ChromiumDriverLogLevel.fromString(oldLevel.toString());
163164
return new Builder()
164165
.withLogLevel(level)
165166
.build();
166167
}
167168

169+
/**
170+
* Checks if the browser driver binary is already present. Grid uses this method to show
171+
* the available browsers and drivers, hence its visibility.
172+
*
173+
* @return Whether the browser driver path was found.
174+
*/
175+
static boolean isPresent() {
176+
return findExePath("chromedriver", CHROME_DRIVER_EXE_PROPERTY) != null;
177+
}
178+
168179
/**
169180
* Builder used to configure new {@link ChromeDriverService} instances.
170181
*/
171182
@AutoService(DriverService.Builder.class)
172183
public static class Builder extends DriverService.Builder<
173-
ChromeDriverService, ChromeDriverService.Builder> {
184+
ChromeDriverService, ChromeDriverService.Builder> {
174185

175186
private boolean disableBuildCheck = Boolean.getBoolean(CHROME_DRIVER_DISABLE_BUILD_CHECK);
176187
private boolean readableTimestamp = Boolean.getBoolean(CHROME_DRIVER_READABLE_TIMESTAMP);
177188
private boolean appendLog = Boolean.getBoolean(CHROME_DRIVER_APPEND_LOG_PROPERTY);
178189
private boolean verbose = Boolean.getBoolean(CHROME_DRIVER_VERBOSE_LOG_PROPERTY);
179190
private boolean silent = Boolean.getBoolean(CHROME_DRIVER_SILENT_OUTPUT_PROPERTY);
180191
private String allowedListIps = System.getProperty(CHROME_DRIVER_ALLOWED_IPS_PROPERTY,
181-
System.getProperty(CHROME_DRIVER_WHITELISTED_IPS_PROPERTY));
182-
private ChromiumDriverLogLevel logLevel = ChromiumDriverLogLevel.fromString(System.getProperty(CHROME_DRIVER_LOG_LEVEL_PROPERTY));
192+
System.getProperty(
193+
CHROME_DRIVER_WHITELISTED_IPS_PROPERTY));
194+
private ChromiumDriverLogLevel logLevel = ChromiumDriverLogLevel
195+
.fromString(System.getProperty(CHROME_DRIVER_LOG_LEVEL_PROPERTY));
183196

184197
@Override
185198
public int score(Capabilities capabilities) {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,19 @@ public boolean isAvailable() {
7272
}
7373
}
7474

75+
@Override
76+
public boolean isPresent() {
77+
return EdgeDriverService.isPresent();
78+
}
79+
7580
@Override
7681
public int getMaximumSimultaneousSessions() {
7782
return Runtime.getRuntime().availableProcessors();
7883
}
7984

8085
@Override
8186
public Optional<WebDriver> createDriver(Capabilities capabilities)
82-
throws SessionNotCreatedException {
87+
throws SessionNotCreatedException {
8388
if (!isAvailable() || !isSupporting(capabilities)) {
8489
return Optional.empty();
8590
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@ public static EdgeDriverService createDefaultService() {
122122
return new Builder().build();
123123
}
124124

125+
/**
126+
* Checks if the browser driver binary is already present. Grid uses this method to show
127+
* the available browsers and drivers, hence its visibility.
128+
*
129+
* @return Whether the browser driver path was found.
130+
*/
131+
static boolean isPresent() {
132+
return findExePath("msedgedriver", EDGE_DRIVER_EXE_PROPERTY) != null;
133+
}
134+
135+
125136
/**
126137
* Builder used to configure new {@link EdgeDriverService} instances.
127138
*/

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,6 @@
1717

1818
package org.openqa.selenium.firefox;
1919

20-
import static org.openqa.selenium.remote.Browser.FIREFOX;
21-
import static org.openqa.selenium.remote.CapabilityType.BROWSER_NAME;
22-
2320
import com.google.auto.service.AutoService;
2421

2522
import org.openqa.selenium.Capabilities;
@@ -31,6 +28,9 @@
3128

3229
import java.util.Optional;
3330

31+
import static org.openqa.selenium.remote.Browser.FIREFOX;
32+
import static org.openqa.selenium.remote.CapabilityType.BROWSER_NAME;
33+
3434
@AutoService(WebDriverInfo.class)
3535
public class GeckoDriverInfo implements WebDriverInfo {
3636

@@ -76,14 +76,19 @@ public boolean isAvailable() {
7676
}
7777
}
7878

79+
@Override
80+
public boolean isPresent() {
81+
return GeckoDriverService.isPresent();
82+
}
83+
7984
@Override
8085
public int getMaximumSimultaneousSessions() {
8186
return Runtime.getRuntime().availableProcessors();
8287
}
8388

8489
@Override
8590
public Optional<WebDriver> createDriver(Capabilities capabilities)
86-
throws SessionNotCreatedException {
91+
throws SessionNotCreatedException {
8792
if (!isAvailable()) {
8893
return Optional.empty();
8994
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,16 @@ public static GeckoDriverService createDefaultService() {
101101
}
102102

103103
/**
104+
* Checks if the browser driver binary is already present. Grid uses this method to show
105+
* the available browsers and drivers, hence its visibility.
104106
*
107+
* @return Whether the browser driver path was found.
108+
*/
109+
static boolean isPresent() {
110+
return findExePath("geckodriver", GECKO_DRIVER_EXE_PROPERTY) != null;
111+
}
112+
113+
/**
105114
* @param caps Capabilities instance
106115
* @return default GeckoDriverService
107116
*/

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_REGISTER_CYCLE;
4444
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_REGISTER_PERIOD;
4545
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_SESSION_TIMEOUT;
46+
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_USE_SELENIUM_MANAGER;
4647
import static org.openqa.selenium.grid.node.config.NodeOptions.DEFAULT_VNC_ENV_VAR;
4748
import static org.openqa.selenium.grid.node.config.NodeOptions.NODE_SECTION;
4849
import static org.openqa.selenium.grid.node.config.NodeOptions.OVERRIDE_MAX_SESSIONS;
@@ -83,6 +84,14 @@ public class NodeFlags implements HasRoles {
8384
@ConfigValue(section = NODE_SECTION, name = "detect-drivers", example = "true")
8485
public Boolean autoconfigure = DEFAULT_DETECT_DRIVERS;
8586

87+
@Parameter(
88+
names = {"--selenium-manager"}, arity = 1,
89+
description = "When drivers are not available on the current system, fallback to, " +
90+
"Selenium Manager. Drivers will be downloaded the first time a session " +
91+
"request for the given browser is processed.")
92+
@ConfigValue(section = NODE_SECTION, name = "selenium-manager", example = "true")
93+
public Boolean useSeleniumManager = DEFAULT_USE_SELENIUM_MANAGER;
94+
8695
@Parameter(
8796
names = {"-I", "--driver-implementation"},
8897
description = "Drivers that should be checked. If specified, will skip autoconfiguration. " +

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

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public class NodeOptions {
7474
public static final boolean DEFAULT_ENABLE_BIDI = true;
7575
static final String NODE_SECTION = "node";
7676
static final boolean DEFAULT_DETECT_DRIVERS = true;
77+
static final boolean DEFAULT_USE_SELENIUM_MANAGER = true;
7778
static final boolean OVERRIDE_MAX_SESSIONS = false;
7879
static final String DEFAULT_VNC_ENV_VAR = "SE_START_XVFB";
7980
static final int DEFAULT_NO_VNC_PORT = 7900;
@@ -511,11 +512,25 @@ private Map<WebDriverInfo, Collection<SessionFactory>> discoverDrivers(
511512
// We don't expect duplicates, but they're fine
512513
List<WebDriverInfo> infos =
513514
StreamSupport.stream(ServiceLoader.load(WebDriverInfo.class).spliterator(), false)
514-
.filter(WebDriverInfo::isAvailable)
515+
.filter(WebDriverInfo::isPresent)
515516
.sorted(Comparator.comparing(info -> info.getDisplayName().toLowerCase()))
516517
.collect(Collectors.toList());
517518

518-
LOG.log(Level.INFO, "Discovered {0} driver(s)", infos.size());
519+
LOG.log(Level.INFO, "Driver(s) already present on the host: {0}", infos.size());
520+
521+
if (config.getBool(NODE_SECTION, "selenium-manager").orElse(DEFAULT_USE_SELENIUM_MANAGER)) {
522+
List<String> present = infos.stream()
523+
.map(WebDriverInfo::getDisplayName)
524+
.collect(Collectors.toList());
525+
List<WebDriverInfo> driversSM =
526+
StreamSupport.stream(ServiceLoader.load(WebDriverInfo.class).spliterator(), false)
527+
.filter(WebDriverInfo::isAvailable)
528+
.filter(info -> !present.contains(info.getDisplayName()))
529+
.sorted(Comparator.comparing(info -> info.getDisplayName().toLowerCase()))
530+
.collect(Collectors.toList());
531+
LOG.log(Level.INFO, "Driver(s) available through Selenium Manager: {0}", driversSM.size());
532+
infos.addAll(driversSM);
533+
}
519534

520535
// Same
521536
List<DriverService.Builder<?, ?>> builders = new ArrayList<>();
@@ -563,14 +578,19 @@ public boolean isSupportingCdp() {
563578

564579
@Override
565580
public boolean isSupportingBiDi() {
566-
return detectedDriver.isSupportingBiDi();
581+
return detectedDriver.isSupportingBiDi();
567582
}
568583

569584
@Override
570585
public boolean isAvailable() {
571586
return detectedDriver.isAvailable();
572587
}
573588

589+
@Override
590+
public boolean isPresent() {
591+
return detectedDriver.isPresent();
592+
}
593+
574594
@Override
575595
public int getMaximumSimultaneousSessions() {
576596
return detectedDriver.getMaximumSimultaneousSessions();
@@ -625,9 +645,10 @@ private void report(Map.Entry<WebDriverInfo, Collection<SessionFactory>> entry)
625645
}
626646

627647
LOG.info(String.format(
628-
"Adding %s for %s %d times",
648+
"Adding %s for %s %d times (%s)",
629649
entry.getKey().getDisplayName(),
630650
caps.toString().replaceAll("\\s+", " "),
631-
entry.getValue().size()));
651+
entry.getValue().size(),
652+
entry.getKey().isPresent() ? "Host" : "SM"));
632653
}
633654
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,19 @@ public boolean isAvailable() {
7474
}
7575
}
7676

77+
@Override
78+
public boolean isPresent() {
79+
return InternetExplorerDriverService.isPresent();
80+
}
81+
7782
@Override
7883
public int getMaximumSimultaneousSessions() {
7984
return 1;
8085
}
8186

8287
@Override
8388
public Optional<WebDriver> createDriver(Capabilities capabilities)
84-
throws SessionNotCreatedException {
89+
throws SessionNotCreatedException {
8590
if (!isAvailable()) {
8691
return Optional.empty();
8792
}

0 commit comments

Comments
 (0)