diff --git a/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/DriverLogLevel.java b/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/DriverLogLevel.java new file mode 100644 index 00000000..94e46512 --- /dev/null +++ b/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/DriverLogLevel.java @@ -0,0 +1,33 @@ +/** + * MIT License + * + * Copyright (c) 2023 Chorus BDD Organisation. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.chorusbdd.chorus.selenium.config; + +public enum DriverLogLevel { + ALL, + INFO, + DEBUG, + WARNING, + SEVERE, + OFF; +} diff --git a/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/SeleniumConfig.java b/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/SeleniumConfig.java index 41cd6acf..e628a47d 100644 --- a/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/SeleniumConfig.java +++ b/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/SeleniumConfig.java @@ -49,4 +49,6 @@ public interface SeleniumConfig extends NamedConfigBean { String getRemoteWebDriverBrowserType(); String getRemoteWebDriverURL(); + + DriverLogLevel getLogLevel(); } diff --git a/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/SeleniumConfigBean.java b/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/SeleniumConfigBean.java index e5f9657d..22175d7c 100644 --- a/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/SeleniumConfigBean.java +++ b/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/config/SeleniumConfigBean.java @@ -44,8 +44,8 @@ public class SeleniumConfigBean implements SeleniumConfig { private String chromeArgs; private String edgeArgs; private String remoteWebDriverURL; - private String remoteWebDriverBrowserType; + private DriverLogLevel driverLogLevel; public String getConfigName() { return configName; @@ -183,6 +183,22 @@ public void checkValid() { } } + @Override + public DriverLogLevel getLogLevel() { + return driverLogLevel; + } + + @ConfigProperty( + name = "driverLogLevel", + description = "Desired log level for the selenium web driver, an attempt will be made to configure this level if the driver supports it", + defaultValue = "OFF", + mandatory = false, + order = 60 + ) + public void setDriverLogLevel(DriverLogLevel driverLogLevel) { + this.driverLogLevel = driverLogLevel; + } + private void checkRemoteWebDriverProperites() { checkNotNullAndNotEmpty(remoteWebDriverURL, "remoteWebDriverURL"); checkNotNullAndNotEmpty(remoteWebDriverBrowserType, "remoteWebDriverBrowserType"); diff --git a/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/manager/DefaultWebDriverFactory.java b/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/manager/DefaultWebDriverFactory.java index 3613be99..56c8eaa0 100644 --- a/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/manager/DefaultWebDriverFactory.java +++ b/extensions/chorus-selenium/src/main/java/org/chorusbdd/chorus/selenium/manager/DefaultWebDriverFactory.java @@ -23,25 +23,35 @@ */ package org.chorusbdd.chorus.selenium.manager; +import org.chorusbdd.chorus.logging.ChorusLog; +import org.chorusbdd.chorus.logging.ChorusLogFactory; +import org.chorusbdd.chorus.selenium.config.DriverLogLevel; import org.chorusbdd.chorus.selenium.config.SeleniumConfig; import org.chorusbdd.chorus.util.ChorusException; import org.openqa.selenium.Platform; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeDriverService; import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.chromium.ChromiumDriverLogLevel; import org.openqa.selenium.edge.EdgeDriver; +import org.openqa.selenium.edge.EdgeDriverService; import org.openqa.selenium.edge.EdgeOptions; import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.RemoteWebDriver; import java.net.MalformedURLException; import java.net.URL; +import java.util.logging.Level; + /** * Created by nickebbutt on 12/02/2018. */ public class DefaultWebDriverFactory implements WebDriverFactory { - + + private final ChorusLog log = ChorusLogFactory.getLog(DefaultWebDriverFactory.class); + @Override public WebDriver createWebDriver(SeleniumConfig seleniumConfig) { WebDriver result; @@ -54,20 +64,23 @@ public WebDriver createWebDriver(SeleniumConfig seleniumConfig) { // File logFile = new File(feature.getFeatureDir().toString(), "selenium.log"); // System.setProperty("webdriver.chrome.logfile", logFile.toString()); - setSpecialSilenceChromeDriverSysProperty(); + ChromiumDriverLogLevel chromeLogLevel = getLogLevel(seleniumConfig); + ChromeDriverService chromeDriverService = new ChromeDriverService.Builder().withLogLevel(chromeLogLevel).build(); ChromeOptions chromeOptions = new ChromeOptions(); - + //Setting this prevents 'Error: Loading of unpacked extensions is disabled by the administrator' which pops up a warning dialog //if starting chrome on an OS where the admin has disabled browser plugins/extensions chromeOptions.setExperimentalOption("useAutomationExtension", false); seleniumConfig.getChromeArgs().map(s -> s.split(" ")).ifPresent(chromeOptions::addArguments); - result = new ChromeDriver(chromeOptions); + result = new ChromeDriver(chromeDriverService, chromeOptions); break; case EDGE: + ChromiumDriverLogLevel edgelogLevel = getLogLevel(seleniumConfig); + EdgeDriverService edgeDriverService = new EdgeDriverService.Builder().withLoglevel(edgelogLevel).build(); EdgeOptions edgeOptions = new EdgeOptions(); seleniumConfig.getEdgeArgs().map(s -> s.split(" ")).ifPresent(edgeOptions::addArguments); - result = new EdgeDriver(edgeOptions); + result = new EdgeDriver(edgeDriverService, edgeOptions); break; case REMOTE_WEB_DRIVER: DesiredCapabilities capabilities = new DesiredCapabilities( @@ -76,8 +89,11 @@ public WebDriver createWebDriver(SeleniumConfig seleniumConfig) { Platform.ANY //can't configure platform yet ); capabilities.setJavascriptEnabled(true); + Level logLevel = getJavaInfoLogLevel(seleniumConfig); URL url = getRemoteWebDriverURL(seleniumConfig.getRemoteWebDriverURL()); - result = new RemoteWebDriver(url, capabilities);; + RemoteWebDriver remoteWebDriver = new RemoteWebDriver(url, capabilities); + remoteWebDriver.setLogLevel(logLevel); + result = remoteWebDriver;; break; default: throw new ChorusException("SeleniumDriverType " + seleniumConfig.getDriverType() + " is not supported"); @@ -85,6 +101,28 @@ public WebDriver createWebDriver(SeleniumConfig seleniumConfig) { return result; } + private Level getJavaInfoLogLevel(SeleniumConfig seleniumConfig) { + DriverLogLevel logLevel = seleniumConfig.getLogLevel(); + Level level; + try { + level = Level.parse(logLevel.name()); + } catch (IllegalArgumentException e) { + log.warn("The log level " + logLevel + " was not supported by the selenium driver, will be defaulted to OFF"); + level = Level.OFF; + } + return level; + } + + private ChromiumDriverLogLevel getLogLevel(SeleniumConfig seleniumConfig) { + DriverLogLevel logLevel = seleniumConfig.getLogLevel(); + ChromiumDriverLogLevel result = ChromiumDriverLogLevel.fromString(logLevel.name()); + if (result == null) { + log.warn("The log level " + logLevel + " was not supported by the selenium driver, will be defaulted to OFF"); + result = ChromiumDriverLogLevel.OFF; + } + return result; + } + private URL getRemoteWebDriverURL(String url) { try { return new URL(url); @@ -93,8 +131,4 @@ private URL getRemoteWebDriverURL(String url) { } } - //Before creating a ChromeDriver set this to silence the verbose output - private void setSpecialSilenceChromeDriverSysProperty() { - System.setProperty("webdriver.chrome.silentOutput", "true"); - } } diff --git a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/chromedriver/chromeDriver.feature b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/chromedriver/chromeDriver.feature index 04ea7aaf..f1551d20 100644 --- a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/chromedriver/chromeDriver.feature +++ b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/chromedriver/chromeDriver.feature @@ -9,5 +9,6 @@ Uses: Selenium And I set the chorus context variable pathToTestHtmlFile When I navigate to ${pathToTestHtmlFile} Then the url is ${pathToTestHtmlFile} + And I close the browser diff --git a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/chromedriver/stdout.txt b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/chromedriver/stdout.txt index ef3f3e0c..30229370 100644 --- a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/chromedriver/stdout.txt +++ b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/chromedriver/stdout.txt @@ -6,8 +6,9 @@ Chorus --> INFO - Processing scenario: I can open Chrome and navigate to a pa And I set the chorus context variable pathToTestHtmlFile PASSED When I navigate to REPLACED PASSED Then the url is REPLACED PASSED + And I close the browser PASSED Features (total:1) (passed:1) (failed:0) Scenarios (total:1) (passed:1) (failed:0) -Steps (total:4) (passed:4) (failed:0) (undefined:0) (pending:0) (skipped:0) \ No newline at end of file +Steps (total:5) (passed:5) (failed:0) (undefined:0) (pending:0) (skipped:0) diff --git a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/edgeDriver.feature b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/edgeDriver.feature index f133c27c..30222f33 100644 --- a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/edgeDriver.feature +++ b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/edgeDriver.feature @@ -9,5 +9,6 @@ Uses: Selenium And I set the chorus context variable pathToTestHtmlFile When I navigate to ${pathToTestHtmlFile} Then the url is ${pathToTestHtmlFile} + And I close the browser diff --git a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/edgeDriver.properties b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/edgeDriver.properties index 26162a19..f8b8d28a 100644 --- a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/edgeDriver.properties +++ b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/edgeDriver.properties @@ -1,3 +1,4 @@ selenium.EDGE.driverType=EDGE +selenium.EDGE.driverLogLevel=OFF diff --git a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/stdout.txt b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/stdout.txt index 403e7a84..73ea32d9 100644 --- a/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/stdout.txt +++ b/integrationtest/src/test/java/org/chorusbdd/chorus/selftest/selenium/edgedriver/stdout.txt @@ -6,8 +6,9 @@ Chorus --> INFO - Processing scenario: I can open Edge and navigate to a page And I set the chorus context variable pathToTestHtmlFile PASSED When I navigate to REPLACED PASSED Then the url is REPLACED PASSED + And I close the browser PASSED Features (total:1) (passed:1) (failed:0) Scenarios (total:1) (passed:1) (failed:0) -Steps (total:4) (passed:4) (failed:0) (undefined:0) (pending:0) (skipped:0) \ No newline at end of file +Steps (total:5) (passed:5) (failed:0) (undefined:0) (pending:0) (skipped:0)