diff --git a/pom.xml b/pom.xml
index 0e8c8e7..9317c21 100644
--- a/pom.xml
+++ b/pom.xml
@@ -97,6 +97,7 @@
2.2
2.12.1
0.4.2
+ 2.0.2
1.3.0
2.7
0.8.5
@@ -219,6 +220,18 @@
4.1.2
compile
+
+ org.powermock
+ powermock-module-junit4
+ ${powermock.version}
+ test
+
+
+ org.powermock
+ powermock-api-mockito2
+ ${powermock.version}
+ test
+
diff --git a/src/main/java/uk/co/evoco/webdriver/configuration/WebDriverConfig.java b/src/main/java/uk/co/evoco/webdriver/configuration/WebDriverConfig.java
index fa6f01e..0d52e3d 100644
--- a/src/main/java/uk/co/evoco/webdriver/configuration/WebDriverConfig.java
+++ b/src/main/java/uk/co/evoco/webdriver/configuration/WebDriverConfig.java
@@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.openqa.selenium.json.Json;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -25,6 +26,7 @@ public class WebDriverConfig {
private GridConfig gridConfig;
private RunType runType;
private Map browserPreferences;
+ private ObjectNode chromeLoggingPreferences;
private TolerantActionExceptions tolerantActionExceptions;
private MetricsConfig metricsConfig;
private boolean takeScreenshotOnError;
@@ -162,6 +164,19 @@ public ObjectNode getBrowserPreferences(BrowserType browserType) {
.orElse(JsonNodeFactory.instance.objectNode());
}
+ /**
+ *
+ * @return the ChromeLoggingPreferences configuration
+ */
+ public Optional getChromeLoggingPreferences() {
+ return Optional.ofNullable(chromeLoggingPreferences)
+ .map(configObject -> configObject.retain("logLevel"))
+ .filter(s -> !s.isEmpty())
+ .map(logLevelNode -> logLevelNode.get("logLevel").asText())
+ .stream()
+ .findFirst();
+ }
+
/**
*
* @param browserPreferences the configuration properties for the various browsers supported by the webdriver
@@ -171,6 +186,15 @@ public void setBrowserPreferences(Map browserPreferences) {
this.browserPreferences = browserPreferences;
}
+ /**
+ *
+ * @param chromeLoggingPreferences the configuration logging level for the various browsers supported by the webdriver
+ */
+ @JsonProperty("chromeLoggingPreferences")
+ public void setChromeLoggingPreferences(ObjectNode chromeLoggingPreferences) {
+ this.chromeLoggingPreferences = chromeLoggingPreferences;
+ }
+
/**
*
* @return the run type
diff --git a/src/main/java/uk/co/evoco/webdriver/configuration/driver/ConfiguredChromeDriver.java b/src/main/java/uk/co/evoco/webdriver/configuration/driver/ConfiguredChromeDriver.java
index 3e6cb2f..acefbb8 100644
--- a/src/main/java/uk/co/evoco/webdriver/configuration/driver/ConfiguredChromeDriver.java
+++ b/src/main/java/uk/co/evoco/webdriver/configuration/driver/ConfiguredChromeDriver.java
@@ -5,26 +5,40 @@
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
+import org.openqa.selenium.logging.LogType;
+import org.openqa.selenium.logging.LoggingPreferences;
+import org.openqa.selenium.remote.CapabilityType;
+import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import uk.co.evoco.tests.BaseAbstractTest;
import uk.co.evoco.webdriver.configuration.BrowserType;
import uk.co.evoco.webdriver.configuration.TestConfigHelper;
-import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.logging.Level;
public class ConfiguredChromeDriver implements ConfiguredDriver {
+ private static final Logger logger = LoggerFactory.getLogger(ConfiguredChromeDriver.class);
+
/**
*
*
* @return WebDriver representing RemoteWebDriver grid
*/
public WebDriver getRemoteDriver() throws IOException {
+ ChromeOptions chromeOptions = this.getOptions();
+ LoggingPreferences loggingOptions = this.getLoggerPrefs();
+ DesiredCapabilities capabilities = DesiredCapabilities.chrome();
+ capabilities.setCapability("goog:loggingPrefs", loggingOptions);
+ chromeOptions.merge(capabilities);
return new RemoteWebDriver(
- TestConfigHelper.get().getGridConfig().getGridUrl(), this.getOptions());
+ TestConfigHelper.get().getGridConfig().getGridUrl(), chromeOptions);
}
/**
@@ -33,10 +47,16 @@ public WebDriver getRemoteDriver() throws IOException {
* @throws IOException if log directory doesn't exist
*/
public WebDriver getLocalDriver() throws IOException {
+ ChromeOptions chromeOptions = this.getOptions();
+ LoggingPreferences loggingOptions = this.getLoggerPrefs();
+ DesiredCapabilities capabilities = DesiredCapabilities.chrome();
+ capabilities.setCapability("goog:loggingPrefs", loggingOptions);
+ chromeOptions.merge(capabilities);
+
createLogDirectory();
System.setProperty("webdriver.chrome.logfile", "logs/chrome-driver.log");
WebDriverManager.chromedriver().setup();
- return new ChromeDriver(this.getOptions());
+ return new ChromeDriver(chromeOptions);
}
/**
@@ -68,8 +88,42 @@ public ChromeOptions getOptions() throws IOException {
}
}
}
+
+ if(!getLoggerPrefs().getLevel(LogType.PERFORMANCE).getName().equals("OFF")) {
+ Map perfLogPrefs = new HashMap<>();
+ perfLogPrefs.put("traceCategories", "browser,devtools.timeline,devtools");
+ chromeOptions.setExperimentalOption("perfLoggingPrefs", perfLogPrefs);
+ }
+
chromeOptions.setExperimentalOption("prefs", chromePrefs);
chromeOptions.setHeadless(TestConfigHelper.get().isHeadless());
return chromeOptions;
}
+
+ public LoggingPreferences getLoggerPrefs() {
+ LoggingPreferences loggingPreferences = new LoggingPreferences();
+ TestConfigHelper.get()
+ .getChromeLoggingPreferences()
+ .ifPresent(logLevel -> {
+ try {
+ System.setProperty("webdriver.chrome.verboseLogging", "true");
+ loggingPreferences.enable(LogType.PERFORMANCE, parseLogLevel(logLevel));
+ loggingPreferences.enable(LogType.BROWSER, parseLogLevel(logLevel));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ });
+
+ return loggingPreferences;
+ }
+
+ private Level parseLogLevel(String logLevel) {
+ try {
+ return Level.parse(logLevel);
+ }
+ catch (IllegalArgumentException exception) {
+ logger.warn("Incorrect Level provided so performance logging set to OFF");
+ return Level.OFF;
+ }
+ }
}
diff --git a/src/test/java/uk/co/evoco/webdriver/configuration/WebDriverConfigTests.java b/src/test/java/uk/co/evoco/webdriver/configuration/WebDriverConfigTests.java
index 5a5fd48..82c8634 100644
--- a/src/test/java/uk/co/evoco/webdriver/configuration/WebDriverConfigTests.java
+++ b/src/test/java/uk/co/evoco/webdriver/configuration/WebDriverConfigTests.java
@@ -10,6 +10,7 @@
import java.io.IOException;
import java.net.MalformedURLException;
+import java.util.Optional;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -51,7 +52,7 @@ public void testGetBrowserPreferencesReturnsAnEmptyNodeIfSpecifiedBrowserTypeIsN
public void testGetBrowserPreferencesReturnsTheCorrectBrowserOptions() throws JsonProcessingException {
String preferenceKey = "browser.download.dir";
String preferenceValue = "docs/chrome/";
- String inputConfigJson = String.format("{ \"browserPreferences\": { \"chrome\": {\"%s\": \"%s\"}}}", preferenceKey, preferenceValue);
+ String inputConfigJson = String.format("{ \"browserPreferences\": { \"chrome\": {\"%s\": \"%s\"} }}", preferenceKey, preferenceValue);
WebDriverConfig webDriverConfig = JsonUtils.fromString(inputConfigJson, WebDriverConfig.class);
JsonNode actualPreferences = webDriverConfig.getBrowserPreferences(BrowserType.CHROME);
@@ -75,6 +76,50 @@ public void testGetBrowserPropertiesReturnsTheCorrectBrowserOptionsIrrespectiveO
assertThat(actualPreferences, is(expectedPreferences));
}
+ @Test
+ public void testGetLoggingPreferencesGetsTheRightOptions() throws IOException {
+ WebDriverConfig webDriverConfig = JsonUtils.fromFile(
+ ClassLoader.getSystemResourceAsStream("fixtures/sample-config-with-chrome-logging-preferences.json"),
+ WebDriverConfig.class);
+
+ assertThat(webDriverConfig.getChromeLoggingPreferences(), is(Optional.of("ALL")));
+ }
+
+ @Test
+ public void testWrongLogKeyReturnsEmptyOptional() throws IOException {
+ String logKey = "wrongLogKey";
+ String logValue = "ALL";
+ String inputConfigJson = String.format("{ \"chromeLoggingPreferences\": {\"%s\": \"%s\"}}}", logKey, logValue);
+
+ WebDriverConfig webDriverConfig = JsonUtils.fromString(inputConfigJson, WebDriverConfig.class);
+
+ Optional actualPreferences = webDriverConfig.getChromeLoggingPreferences();
+ assertThat(actualPreferences, is(Optional.empty()));
+ }
+
+ @Test
+ public void testBlankLogLevelAndValueReturnsEmptyOptional() throws IOException {
+ String logKey = "";
+ String logValue = "";
+ String inputConfigJson = String.format("{ \"chromeLoggingPreferences\": {\"%s\": \"%s\"}}}", logKey, logValue);
+
+ WebDriverConfig webDriverConfig = JsonUtils.fromString(inputConfigJson, WebDriverConfig.class);
+
+ Optional actualPreferences = webDriverConfig.getChromeLoggingPreferences();
+ assertThat(actualPreferences, is(Optional.empty()));
+ }
+
+ @Test
+ public void testMultipleLogLevelsReturnsFirstElement() throws IOException {
+
+ String inputConfigJson = "{ \"chromeLoggingPreferences\": {\"logLevel\": \"All\", \"logLevel\": \"FINE\"}}}";
+
+ WebDriverConfig webDriverConfig = JsonUtils.fromString(inputConfigJson, WebDriverConfig.class);
+
+ Optional actualPreferences = webDriverConfig.getChromeLoggingPreferences();
+ assertThat(actualPreferences, is(Optional.of("FINE")));
+ }
+
@Test
public void testConstructionFromJsonFileWithBadBaseUrlFails() {
assertThrows(JsonMappingException.class, () -> {
diff --git a/src/test/java/uk/co/evoco/webdriver/configuration/driver/ConfiguredChromeDriverTests.java b/src/test/java/uk/co/evoco/webdriver/configuration/driver/ConfiguredChromeDriverTests.java
index b051e04..9a1aade 100644
--- a/src/test/java/uk/co/evoco/webdriver/configuration/driver/ConfiguredChromeDriverTests.java
+++ b/src/test/java/uk/co/evoco/webdriver/configuration/driver/ConfiguredChromeDriverTests.java
@@ -2,29 +2,48 @@
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
+import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.support.events.EventFiringWebDriver;
+import org.powermock.api.mockito.PowerMockito;
+import uk.co.evoco.webdriver.configuration.TestConfigHelper;
+import uk.co.evoco.webdriver.configuration.WebDriverConfig;
import java.io.File;
import java.io.IOException;
+import java.lang.reflect.Field;
import java.util.Map;
+import java.util.Optional;
+import java.util.logging.Level;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class ConfiguredChromeDriverTests {
+ @Mock
+ WebDriverConfig webDriverConfigMock = mock(WebDriverConfig.class);
+
@Test
- public void testReturnsLocalWebDriver() throws IOException {
+ public void testReturnsLocalWebDriver() throws IOException, IllegalAccessException {
+ Field testConfigHelperStaticVariable = PowerMockito.field(TestConfigHelper.class, "testConfigHelper");
+ testConfigHelperStaticVariable.set(TestConfigHelper.class, null);
+
ConfiguredDriver configuredChromeDriver = new ConfiguredChromeDriver();
WebDriver webDriver = configuredChromeDriver.getDriver(FileUtils.getTempDirectory());
assertThat(webDriver, instanceOf(EventFiringWebDriver.class));
}
@Test
- public void testGetOptionsReturnsOptionsIncludedInChromeConfig() throws IOException {
+ public void testGetOptionsReturnsOptionsIncludedInChromeConfig() throws IOException, IllegalAccessException {
+ Field testConfigHelperStaticVariable = PowerMockito.field(TestConfigHelper.class, "testConfigHelper");
+ testConfigHelperStaticVariable.set(TestConfigHelper.class, null);
+
ConfiguredChromeDriver configuredChromeDriver = new ConfiguredChromeDriver();
Map chromeOptions = getOptions(configuredChromeDriver.getOptions());
String expectedFileDownLoadPath = new File("run-generated-files/chrome/downloads").getCanonicalPath();
@@ -33,8 +52,45 @@ public void testGetOptionsReturnsOptionsIncludedInChromeConfig() throws IOExcept
assertThat(chromeOptions.get("safebrowsing.enabled"), is(true));
}
+ @Test
+ public void testGetLoggingPreferencesReturnsEnabledLogLevel() throws Exception {
+
+ Optional mockConfigReturn = Optional.of("FINE");
+ mockTestConfig();
+ when(webDriverConfigMock.getChromeLoggingPreferences()).thenReturn(mockConfigReturn);
+
+
+ ConfiguredChromeDriver configuredChromeDriver = new ConfiguredChromeDriver();
+ LoggingPreferences loggingPreferences = configuredChromeDriver.getLoggerPrefs();
+
+ Level googleChromeLoggingPreferences = loggingPreferences.getLevel("performance");
+
+ assertThat(googleChromeLoggingPreferences, is(Level.FINE));
+ }
+
+ @Test
+ public void testEmptyLoggingPreferencesReturnsOffLevel() throws IllegalAccessException {
+ Optional mockConfigReturn = Optional.of("");
+ mockTestConfig();
+ when(webDriverConfigMock.getChromeLoggingPreferences()).thenReturn(mockConfigReturn);
+
+ ConfiguredChromeDriver configuredChromeDriver = new ConfiguredChromeDriver();
+ LoggingPreferences loggingPreferences = configuredChromeDriver.getLoggerPrefs();
+
+ Level googleChromeLoggingPreferences = loggingPreferences.getLevel("performance");
+
+ assertThat(googleChromeLoggingPreferences, is(Level.OFF));
+ }
+
private Map getOptions(ChromeOptions options) {
Map googleChromeOptions = (Map) options.asMap().get("goog:chromeOptions");
return (Map) googleChromeOptions.get("prefs");
}
+
+ private void mockTestConfig() throws IllegalAccessException {
+ Field testConfigHelperStaticVariable = PowerMockito.field(TestConfigHelper.class, "testConfigHelper");
+ testConfigHelperStaticVariable.set(TestConfigHelper.class, mock(TestConfigHelper.class));
+ Field webdriverConfigStaticVariable = PowerMockito.field(TestConfigHelper.class, "webDriverConfig");
+ webdriverConfigStaticVariable.set(TestConfigHelper.class, webDriverConfigMock);
+ }
}
diff --git a/src/test/java/uk/co/evoco/webdriver/utils/ChromeDriverPreferenceTests.java b/src/test/java/uk/co/evoco/webdriver/utils/ChromeDriverPreferenceTests.java
index 66352d6..84fc736 100644
--- a/src/test/java/uk/co/evoco/webdriver/utils/ChromeDriverPreferenceTests.java
+++ b/src/test/java/uk/co/evoco/webdriver/utils/ChromeDriverPreferenceTests.java
@@ -3,10 +3,15 @@
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.*;
import org.openqa.selenium.By;
+import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.logging.LogType;
+import org.powermock.api.mockito.PowerMockito;
+import uk.co.evoco.webdriver.configuration.TestConfigHelper;
import uk.co.evoco.webdriver.configuration.driver.ConfiguredChromeDriver;
import java.io.File;
+import java.lang.reflect.Field;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -17,8 +22,8 @@ public class ChromeDriverPreferenceTests {
private static EmbeddedJetty embeddedJetty;
private WebDriver webDriver;
- @BeforeAll
- public static void webDriverSetup() throws Exception {
+ @BeforeEach
+ public void webDriverSetup() throws Exception {
embeddedJetty = new EmbeddedJetty();
embeddedJetty.start();
baseUrl = "http://localhost:" + embeddedJetty.getPort() + "/index.html";
@@ -36,13 +41,27 @@ public void testChromeBrowserPreferencesApplied() throws Exception {
new File(expectedFile).exists(), is(true));
}
- @AfterEach
- public void tearDown() {
- this.webDriver.quit();
+ @Test
+ public void testChromeBrowserLoggingPreferencesApplied() throws Exception {
+ Field testConfigHelperStaticVariable = PowerMockito.field(TestConfigHelper.class, "testConfigHelper");
+ testConfigHelperStaticVariable.set(TestConfigHelper.class, null);
+
+ System.setProperty("config", "fixtures/sample-config-with-chrome-logging-preferences.json");
+ assertThat(System.getProperty("config"), is("fixtures/sample-config-with-chrome-logging-preferences.json"));
+ webDriver = new ConfiguredChromeDriver().getDriver(FileUtils.getTempDirectory());
+ webDriver.get(baseUrl);
+ webDriver.findElement(By.xpath("//a[text()='clickHereToDownLoadAFile']"));
+ try {
+ Assertions.assertTrue(webDriver.manage().logs().get(LogType.PERFORMANCE).getAll().size() > 0);
+ } catch (InvalidArgumentException e) {
+ Assertions.fail("There are no Performance Logs that have been found");
+ }
}
- @AfterAll
- public static void webDriverTearDown() throws Exception {
+
+ @AfterEach
+ public void tearDown() throws Exception {
+ this.webDriver.quit();
System.setProperty("config", "DEFAULT");
embeddedJetty.stop();
}
diff --git a/src/test/resources/fixtures/sample-config-with-chrome-logging-preferences.json b/src/test/resources/fixtures/sample-config-with-chrome-logging-preferences.json
new file mode 100644
index 0000000..43d4ab4
--- /dev/null
+++ b/src/test/resources/fixtures/sample-config-with-chrome-logging-preferences.json
@@ -0,0 +1,42 @@
+{
+ "browser": "chrome",
+ "baseUrl": "https://www.google.com",
+ "timeout": "30",
+ "headless": true,
+ "runType": "LOCAL",
+ "takeScreenshotOnError": true,
+ "testConfig": {
+ "sample": "sample text"
+ },
+ "gridConfig": {
+ "url": "http://localhost:4444/wd/hub"
+ },
+ "browserPreferences": {
+ "chrome": {
+ "profile.default_content_settings.popups": 0,
+ "download.default_directory": "run-generated-files/chrome/downloads",
+ "safebrowsing.enabled": true
+ }
+ },
+ "chromeLoggingPreferences": {
+ "logLevel": "ALL"
+ },
+ "tolerantActionExceptions": {
+ "waitTimeoutInSeconds": 5,
+ "exceptionsToHandle": [
+ "StaleElementReferenceException",
+ "ElementClickInterceptedException",
+ "ElementNotInteractableException"
+ ]
+ },
+ "metrics": {
+ "jmx": {
+ "enabled": false
+ },
+ "graphite": {
+ "enabled": false,
+ "host": "localhost",
+ "port": 2003
+ }
+ }
+}
\ No newline at end of file