Skip to content

Add performance logging through config #86

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
<hamcrest.version>2.2</hamcrest.version>
<jackson.version>2.12.1</jackson.version>
<mockneat.version>0.4.2</mockneat.version>
<powermock.version>2.0.2</powermock.version>
<dwp.formatvalidation.nino>1.3.0</dwp.formatvalidation.nino>
<versions.maven.plugin.version>2.7</versions.maven.plugin.version>
<jacoco.maven.plugin.version>0.8.5</jacoco.maven.plugin.version>
Expand Down Expand Up @@ -219,6 +220,18 @@
<version>4.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>${powermock.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<reporting>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -25,6 +26,7 @@ public class WebDriverConfig {
private GridConfig gridConfig;
private RunType runType;
private Map<String, ObjectNode> browserPreferences;
private ObjectNode chromeLoggingPreferences;
private TolerantActionExceptions tolerantActionExceptions;
private MetricsConfig metricsConfig;
private boolean takeScreenshotOnError;
Expand Down Expand Up @@ -162,6 +164,19 @@ public ObjectNode getBrowserPreferences(BrowserType browserType) {
.orElse(JsonNodeFactory.instance.objectNode());
}

/**
*
* @return the ChromeLoggingPreferences configuration
*/
public Optional<String> 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
Expand All @@ -171,6 +186,15 @@ public void setBrowserPreferences(Map<String, ObjectNode> 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -68,8 +88,42 @@ public ChromeOptions getOptions() throws IOException {
}
}
}

if(!getLoggerPrefs().getLevel(LogType.PERFORMANCE).getName().equals("OFF")) {
Map<String, Object> 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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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<String> 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<String> 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<String> actualPreferences = webDriverConfig.getChromeLoggingPreferences();
assertThat(actualPreferences, is(Optional.of("FINE")));
}

@Test
public void testConstructionFromJsonFileWithBadBaseUrlFails() {
assertThrows(JsonMappingException.class, () -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Object> chromeOptions = getOptions(configuredChromeDriver.getOptions());
String expectedFileDownLoadPath = new File("run-generated-files/chrome/downloads").getCanonicalPath();
Expand All @@ -33,8 +52,45 @@ public void testGetOptionsReturnsOptionsIncludedInChromeConfig() throws IOExcept
assertThat(chromeOptions.get("safebrowsing.enabled"), is(true));
}

@Test
public void testGetLoggingPreferencesReturnsEnabledLogLevel() throws Exception {

Optional<String> 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<String> 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<String, Object> getOptions(ChromeOptions options) {
Map<String, Object> googleChromeOptions = (Map<String, Object>) options.asMap().get("goog:chromeOptions");
return (Map<String, Object>) 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);
}
}
Loading