diff --git a/java/client/src/org/openqa/selenium/chrome/BUILD.bazel b/java/client/src/org/openqa/selenium/chrome/BUILD.bazel index 0dd525c9ec8bb..8bb78571dfa4d 100644 --- a/java/client/src/org/openqa/selenium/chrome/BUILD.bazel +++ b/java/client/src/org/openqa/selenium/chrome/BUILD.bazel @@ -19,5 +19,6 @@ java_export( "//java/client/src/org/openqa/selenium/json", "//java/client/src/org/openqa/selenium/remote", "//java/client/src/org/openqa/selenium/remote/http", + artifact("com.google.guava:guava"), ], ) diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeDriver.java b/java/client/src/org/openqa/selenium/chrome/ChromeDriver.java index 80ac9637162fc..c8f2e71473792 100644 --- a/java/client/src/org/openqa/selenium/chrome/ChromeDriver.java +++ b/java/client/src/org/openqa/selenium/chrome/ChromeDriver.java @@ -136,7 +136,7 @@ public ChromeDriver(Capabilities capabilities) { * @see #ChromeDriver(ChromeDriverService, ChromeOptions) */ public ChromeDriver(ChromeOptions options) { - this(ChromeDriverService.createDefaultService(), options); + this(ChromeDriverService.createServiceWithConfig(options), options); } /** diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeDriverLogLevel.java b/java/client/src/org/openqa/selenium/chrome/ChromeDriverLogLevel.java new file mode 100644 index 0000000000000..d817fdbfc2725 --- /dev/null +++ b/java/client/src/org/openqa/selenium/chrome/ChromeDriverLogLevel.java @@ -0,0 +1,51 @@ +package org.openqa.selenium.chrome; + +import com.google.common.collect.ImmutableMap; + +import java.util.Map; +import java.util.logging.Level; + +/** + * + * Log levels defined by ChromeDriver + */ +public enum ChromeDriverLogLevel { + ALL, + INFO, + DEBUG, + WARNING, + SEVERE, + OFF; + + private static final Map logLevelToChromeLevelMap + = new ImmutableMap.Builder() + .put(Level.ALL, ALL) + .put(Level.FINEST, DEBUG) + .put(Level.FINER, DEBUG) + .put(Level.FINE, DEBUG) + .put(Level.INFO, INFO) + .put(Level.WARNING, WARNING) + .put(Level.SEVERE, SEVERE) + .put(Level.OFF, OFF) + .build(); + + @Override + public String toString() { + return super.toString().toLowerCase(); + } + + public static ChromeDriverLogLevel fromString(String text) { + if (text != null) { + for (ChromeDriverLogLevel b : ChromeDriverLogLevel.values()) { + if (text.equalsIgnoreCase(b.toString())) { + return b; + } + } + } + return null; + } + + public static ChromeDriverLogLevel fromLevel(Level level) { + return logLevelToChromeLevelMap.getOrDefault(level, ALL); + } +} diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeDriverService.java b/java/client/src/org/openqa/selenium/chrome/ChromeDriverService.java index 6d4ddd30a23d3..f927bd310cc19 100644 --- a/java/client/src/org/openqa/selenium/chrome/ChromeDriverService.java +++ b/java/client/src/org/openqa/selenium/chrome/ChromeDriverService.java @@ -20,18 +20,16 @@ import static java.util.Collections.unmodifiableList; import com.google.auto.service.AutoService; - -import org.openqa.selenium.Capabilities; -import org.openqa.selenium.WebDriverException; -import org.openqa.selenium.remote.BrowserType; -import org.openqa.selenium.remote.service.DriverService; - import java.io.File; import java.io.IOException; import java.time.Duration; import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.WebDriverException; +import org.openqa.selenium.remote.BrowserType; +import org.openqa.selenium.remote.service.DriverService; /** * Manages the life and death of a ChromeDriver server. @@ -121,6 +119,20 @@ public static ChromeDriverService createDefaultService() { return new Builder().build(); } + /** + * Configures and returns a new {@link ChromeDriverService} using the supplied configuration. In + * this configuration, the service will use the chromedriver executable identified by the + * {@link #CHROME_DRIVER_EXE_PROPERTY} system property. Each service created by this method will + * be configured to use a free port on the current system. + * + * @return A new ChromeDriverService using the supplied configuration from {@link ChromeOptions}. + */ + public static ChromeDriverService createServiceWithConfig(ChromeOptions options) { + return new Builder() + .withLogLevel(options.getLogLevel()) + .build(); + } + /** * Builder used to configure new {@link ChromeDriverService} instances. */ @@ -132,6 +144,7 @@ public static class Builder extends DriverService.Builder< private boolean verbose = Boolean.getBoolean(CHROME_DRIVER_VERBOSE_LOG_PROPERTY); private boolean silent = Boolean.getBoolean(CHROME_DRIVER_SILENT_OUTPUT_PROPERTY); private String whitelistedIps = System.getProperty(CHROME_DRIVER_WHITELISTED_IPS_PROPERTY); + private ChromeDriverLogLevel logLevel = null; @Override public int score(Capabilities capabilities) { @@ -170,6 +183,17 @@ public Builder withVerbose(boolean verbose) { return this; } + /** + * Configures the driver server verbosity. + * + * @param logLevel {@link ChromeDriverLogLevel} for desired log level output. + * @return A self reference. + */ + public Builder withLogLevel(ChromeDriverLogLevel logLevel) { + this.logLevel = logLevel; + return this; + } + /** * Configures the driver server for silent output. * @@ -210,6 +234,14 @@ protected List createArgs() { } } + if (logLevel != null) { + withLogLevel(logLevel); + withVerbose(false); + } + if (verbose) { + withLogLevel(ChromeDriverLogLevel.ALL); + } + List args = new ArrayList<>(); args.add(String.format("--port=%d", getPort())); @@ -219,8 +251,8 @@ protected List createArgs() { if (appendLog) { args.add("--append-log"); } - if (verbose) { - args.add("--verbose"); + if (logLevel != null) { + args.add(String.format("--log-level=%s", logLevel.toString().toUpperCase())); } if (silent) { args.add("--silent"); diff --git a/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java b/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java index 6a132a3bf0e0d..9ca405c1ea326 100644 --- a/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java +++ b/java/client/src/org/openqa/selenium/chrome/ChromeOptions.java @@ -17,6 +17,7 @@ package org.openqa.selenium.chrome; +import java.util.Objects; import org.openqa.selenium.Capabilities; import org.openqa.selenium.chromium.ChromiumOptions; import org.openqa.selenium.remote.BrowserType; @@ -49,9 +50,20 @@ public class ChromeOptions extends ChromiumOptions { * object. */ public static final String CAPABILITY = "goog:chromeOptions"; + private ChromeDriverLogLevel logLevel; public ChromeOptions() { + super(CapabilityType.BROWSER_NAME, BrowserType.CHROME, CAPABILITY); } + public ChromeOptions setLogLevel(ChromeDriverLogLevel logLevel){ + this.logLevel = Objects.requireNonNull(logLevel, "Log level must be set"); + return this; + } + + public ChromeDriverLogLevel getLogLevel(){ + return logLevel; + } + } diff --git a/java/client/test/org/openqa/selenium/chrome/ChromeOptionsTest.java b/java/client/test/org/openqa/selenium/chrome/ChromeOptionsTest.java index efa014c4b75f7..c162356021171 100644 --- a/java/client/test/org/openqa/selenium/chrome/ChromeOptionsTest.java +++ b/java/client/test/org/openqa/selenium/chrome/ChromeOptionsTest.java @@ -17,12 +17,14 @@ package org.openqa.selenium.chrome; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -import org.junit.Test; +import static org.openqa.selenium.chrome.ChromeDriverLogLevel.OFF; +import static org.openqa.selenium.chrome.ChromeDriverLogLevel.SEVERE; import java.util.List; import java.util.Map; +import org.junit.Test; public class ChromeOptionsTest { @@ -45,5 +47,11 @@ public void optionsAsMapShouldBeImmutable() { .isThrownBy(() -> args.add("-help")); } + @Test + public void canBuildLogLevelFromStringRepresentation() { + assertThat(ChromeDriverLogLevel.fromString("off")).isEqualTo(OFF); + assertThat(ChromeDriverLogLevel.fromString("SEVERE")).isEqualTo(SEVERE); + } + } diff --git a/java/client/test/org/openqa/selenium/testing/drivers/TestChromeDriver.java b/java/client/test/org/openqa/selenium/testing/drivers/TestChromeDriver.java index 0722d58357b3a..94f611ec396c3 100644 --- a/java/client/test/org/openqa/selenium/testing/drivers/TestChromeDriver.java +++ b/java/client/test/org/openqa/selenium/testing/drivers/TestChromeDriver.java @@ -20,6 +20,7 @@ import org.openqa.selenium.Capabilities; import org.openqa.selenium.OutputType; import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeDriverLogLevel; import org.openqa.selenium.chrome.ChromeDriverService; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.remote.DriverCommand; @@ -48,10 +49,11 @@ private static ChromeDriverService getService() { try { Path logFile = Files.createTempFile("chromedriver", ".log"); ChromeDriverService service = new ChromeDriverService.Builder() - .withVerbose(true) + .withLogLevel(ChromeDriverLogLevel.ALL) .withLogFile(logFile.toFile()) .build(); LOG.info("chromedriver will log to " + logFile); + LOG.info("chromedriver will use log level " + ChromeDriverLogLevel.ALL.toString().toUpperCase()); service.start(); // Fugly. Runtime.getRuntime().addShutdownHook(new Thread(service::stop));