diff --git a/src/main/java/com/xceptance/neodymium/common/browser/BrowserRunnerHelper.java b/src/main/java/com/xceptance/neodymium/common/browser/BrowserRunnerHelper.java
index 8c7f884c1..059dd1529 100644
--- a/src/main/java/com/xceptance/neodymium/common/browser/BrowserRunnerHelper.java
+++ b/src/main/java/com/xceptance/neodymium/common/browser/BrowserRunnerHelper.java
@@ -23,7 +23,6 @@
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
-import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
@@ -31,9 +30,7 @@
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.GeckoDriverService;
import org.openqa.selenium.ie.InternetExplorerDriver;
-import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;
-import org.openqa.selenium.os.ExecutableFinder;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
@@ -181,7 +178,7 @@ private static FirefoxBinary createFirefoxBinary(final String pathToBrowser)
* if Selenium grid is
* used and the given grid URL is invalid
*/
- public static WebDriverStateContainer createWebDriverStateContainer(final BrowserConfiguration config, final Object testClassInstance)
+ public static WebDriverStateContainer createWebDriverStateContainer(final BrowserConfiguration config, Object testClassInstance)
throws MalformedURLException
{
final MutableCapabilities capabilities = config.getCapabilities();
@@ -189,7 +186,7 @@ public static WebDriverStateContainer createWebDriverStateContainer(final Browse
SelenideProxyServer selenideProxyServer = null;
if (Neodymium.configuration().useLocalProxy())
{
- final BrowserUpProxy proxy = setupEmbeddedProxy();
+ BrowserUpProxy proxy = setupEmbeddedProxy();
// set the Proxy for later usage
wDSC.setProxy(proxy);
@@ -206,17 +203,16 @@ else if (Neodymium.configuration().useProxy())
{
if (Neodymium.configuration().enableSelenideProxy())
{
- final SelenideProxyServerFactory selenideProxyServerFactory = Plugins.inject(SelenideProxyServerFactory.class);
+ SelenideProxyServerFactory selenideProxyServerFactory = Plugins.inject(SelenideProxyServerFactory.class);
selenideProxyServer = selenideProxyServerFactory.create(new SelenideConfig(),
(Proxy) capabilities.getCapability(CapabilityType.PROXY));
- final var proxy = selenideProxyServer.getSeleniumProxy();
+ var proxy = selenideProxyServer.getSeleniumProxy();
capabilities.setCapability(CapabilityType.PROXY, proxy);
}
final String browserName = capabilities.getBrowserName();
if (chromeBrowsers.contains(browserName))
{
- final ChromeOptions options = new ChromeOptions();
- final String driverInPathPath = new ExecutableFinder().find("chromedriver");
+ final ChromeOptions options = (ChromeOptions) capabilities;
// do we have a custom path?
final String pathToBrowser = Neodymium.configuration().getChromeBrowserPath();
@@ -238,10 +234,9 @@ else if (Neodymium.configuration().useProxy())
options.setExperimentalOption("prefs", config.getPreferences());
}
- if ((config.getPreferences() != null && !config.getPreferences().isEmpty()) ||
- StringUtils.isNotBlank(config.getDownloadDirectory()))
+ if ((config.getPreferences() != null && !config.getPreferences().isEmpty()) || StringUtils.isNotBlank(config.getDownloadDirectory()))
{
- final HashMap prefs = new HashMap<>();
+ HashMap prefs = new HashMap<>();
// if we have configured prefs, we need to add all to the experimental options
if (config.getPreferences() != null && !config.getPreferences().isEmpty())
@@ -257,14 +252,12 @@ else if (Neodymium.configuration().useProxy())
options.setExperimentalOption("prefs", prefs);
}
- wDSC.setWebDriver(new ChromeDriver(new ChromeDriverService.Builder()
- .usingDriverExecutable(new File(driverInPathPath))
- .build(), options.merge(capabilities)));
+
+ wDSC.setWebDriver(new ChromeDriver(options));
}
else if (firefoxBrowsers.contains(browserName))
{
- final FirefoxOptions options = new FirefoxOptions();
- final String driverInPathPath = new ExecutableFinder().find("geckodriver");
+ final FirefoxOptions options = new FirefoxOptions().merge(capabilities);
options.setBinary(createFirefoxBinary(Neodymium.configuration().getFirefoxBrowserPath()));
if (config.isHeadless())
{
@@ -274,10 +267,9 @@ else if (firefoxBrowsers.contains(browserName))
{
options.addArguments(config.getArguments());
}
- if ((config.getPreferences() != null && !config.getPreferences().isEmpty()) ||
- StringUtils.isNotBlank(config.getDownloadDirectory()))
+ if ((config.getPreferences() != null && !config.getPreferences().isEmpty()) || StringUtils.isNotBlank(config.getDownloadDirectory()))
{
- final FirefoxProfile profile = new FirefoxProfile();
+ FirefoxProfile profile = new FirefoxProfile();
// if we have configured prefs, we need to add all to the experimental options
if (config.getPreferences() != null && !config.getPreferences().isEmpty())
@@ -310,52 +302,45 @@ else if (StringUtils.isNumeric(val.toString()))
options.setProfile(profile);
}
- wDSC.setWebDriver(new FirefoxDriver(new GeckoDriverService.Builder().withAllowHosts("localhost")
- .usingDriverExecutable(new File(driverInPathPath))
- .build(), options.merge(capabilities)));
+ wDSC.setWebDriver(new FirefoxDriver(new GeckoDriverService.Builder().withAllowHosts("localhost").build(), options));
}
else if (internetExplorerBrowsers.contains(browserName))
{
- final InternetExplorerOptions options = new InternetExplorerOptions();
- final String driverInPathPath = new ExecutableFinder().find("IEDriverServer");
+ final InternetExplorerOptions options = new InternetExplorerOptions().merge(capabilities);
if (config.getArguments() != null && config.getArguments().size() > 0)
{
- for (final String argument : config.getArguments())
+ for (String argument : config.getArguments())
{
options.addCommandSwitches(argument);
}
}
- wDSC.setWebDriver(new InternetExplorerDriver(new InternetExplorerDriverService.Builder()
- .usingDriverExecutable(new File(driverInPathPath))
- .build(), options.merge(capabilities)));
+ wDSC.setWebDriver(new InternetExplorerDriver(options));
}
else if (safariBrowsers.contains(browserName))
{
- // safari driver is not expected to be in PATH, it will be looked in
- // /usr/bin/safaridriver and /Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver
- final SafariOptions options = new SafariOptions();
+ final SafariOptions options = (SafariOptions) capabilities;
wDSC.setWebDriver(new SafariDriver(options));
}
else
{
- wDSC.setWebDriver(new RemoteWebDriver(capabilities.merge(capabilities)));
+ wDSC.setWebDriver(new RemoteWebDriver(capabilities));
}
}
else
{
// establish connection to target website
- final TestEnvironment testEnvironmentProperties = MultibrowserConfiguration.getInstance().getTestEnvironment(testEnvironment);
+ TestEnvironment testEnvironmentProperties = MultibrowserConfiguration.getInstance().getTestEnvironment(testEnvironment);
if (testEnvironmentProperties == null)
{
throw new IllegalArgumentException("No properties found for test environment: \"" + testEnvironment + "\"");
}
- final String testEnvironmentUrl = testEnvironmentProperties.getUrl();
+ String testEnvironmentUrl = testEnvironmentProperties.getUrl();
ClientConfig configClient = ClientConfig.defaultConfig();
configClient = configClient.baseUrl(new URL(testEnvironmentUrl));
config.getGridProperties().put("userName", testEnvironmentProperties.getUsername());
config.getGridProperties().put("accessKey", testEnvironmentProperties.getPassword());
- final String buildId = StringUtils.isBlank(System.getenv("BUILD_NUMBER")) ? "local run" : System.getenv("BUILD_NUMBER");
+ String buildId = StringUtils.isBlank(System.getenv("BUILD_NUMBER")) ? "local run" : System.getenv("BUILD_NUMBER");
config.getGridProperties().put("sessionName", testClassInstance.getClass().toString());
config.getGridProperties().put("buildName", "Test Automation");
config.getGridProperties().put("buildIdentifier", buildId);
@@ -369,10 +354,10 @@ else if (testEnvironmentUrl.contains("saucelabs"))
}
else
{
- final String optionsTag = testEnvironmentProperties.getOptionsTag();
+ String optionsTag = testEnvironmentProperties.getOptionsTag();
if (StringUtils.isBlank(optionsTag))
{
- for (final String key : config.getGridProperties().keySet())
+ for (String key : config.getGridProperties().keySet())
{
capabilities.setCapability(key, config.getGridProperties().get(key));
}
@@ -384,7 +369,7 @@ else if (testEnvironmentUrl.contains("saucelabs"))
}
wDSC.setWebDriver(new RemoteWebDriver(new HttpCommandExecutor(new HashMap<>(), configClient, new NeodymiumProxyHttpClientFactory(testEnvironmentProperties)), capabilities));
}
- final WebDriver decoratedDriver = new EventFiringDecorator(new NeodymiumWebDriverListener()).decorate(wDSC.getWebDriver());
+ WebDriver decoratedDriver = new EventFiringDecorator(new NeodymiumWebDriverListener()).decorate(wDSC.getWebDriver());
wDSC.setDecoratedWebDriver(decoratedDriver);
WebDriverRunner.setWebDriver(decoratedDriver, selenideProxyServer);
return wDSC;
@@ -398,8 +383,7 @@ private static BrowserUpProxy setupEmbeddedProxy()
if (Neodymium.configuration().useLocalProxyWithSelfSignedCertificate())
{
final CertificateAndKeySource rootCertificateSource = createLocalProxyRootCertSource();
- final ImpersonatingMitmManager mitmManager = ImpersonatingMitmManager.builder().rootCertificateSource(rootCertificateSource)
- .build();
+ final ImpersonatingMitmManager mitmManager = ImpersonatingMitmManager.builder().rootCertificateSource(rootCertificateSource).build();
proxy.setMitmManager(mitmManager);
}
else
@@ -467,10 +451,8 @@ public static Proxy createProxyCapabilities()
final Proxy webdriverProxy = new Proxy();
webdriverProxy.setHttpProxy(proxyHost);
webdriverProxy.setSslProxy(proxyHost);
- if (!StringUtils.isAllEmpty(Neodymium.configuration().getProxySocketUsername(),
- Neodymium.configuration().getProxySocketPassword())
- ||
- Neodymium.configuration().getProxySocketVersion() != null)
+ if (!StringUtils.isAllEmpty(Neodymium.configuration().getProxySocketUsername(), Neodymium.configuration().getProxySocketPassword())
+ || Neodymium.configuration().getProxySocketVersion() != null)
{
webdriverProxy.setSocksProxy(proxyHost);
if (StringUtils.isNoneEmpty(Neodymium.configuration().getProxySocketUsername(),
@@ -501,12 +483,11 @@ private static String popularContentTypes()
{
try
{
- final List popularContentTypes = IOUtils.readLines(BrowserConfigurationMapper.class.getResourceAsStream("/content-types.properties"),
- UTF_8);
+ List popularContentTypes = IOUtils.readLines(BrowserConfigurationMapper.class.getResourceAsStream("/content-types.properties"), UTF_8);
popularContentTypes.add("application/x-download");
return String.join(";", popularContentTypes);
}
- catch (final Exception e)
+ catch (Exception e)
{
return "text/plain;text/csv;application/zip;application/pdf;application/octet-stream;" +
"application/msword;application/vnd.ms-excel;text/css;text/html";
diff --git a/src/main/java/com/xceptance/neodymium/util/NeoWaitTime.java b/src/main/java/com/xceptance/neodymium/util/NeoWaitTime.java
new file mode 100644
index 000000000..71def92d9
--- /dev/null
+++ b/src/main/java/com/xceptance/neodymium/util/NeoWaitTime.java
@@ -0,0 +1,67 @@
+package com.xceptance.neodymium.util;
+
+import java.util.Map;
+
+import com.codeborne.selenide.Selenide;
+
+public class NeoWaitTime
+{
+ private final int standardWait, shortWait, doubleWait, longWait;
+
+ private final Map customWaitTimeMap;
+
+ private static NeoWaitTime INSTANCE;
+
+ private NeoWaitTime() {
+ this.standardWait = Neodymium.configuration().getStandardWaitTime();
+ this.shortWait = Neodymium.configuration().getShortWaitTime();
+ this.doubleWait = Neodymium.configuration().getDoubleWaitTime();
+ this.longWait = Neodymium.configuration().getLongWaitTime();
+ this.customWaitTimeMap = PropertiesUtil.getPropertiesMapForCustomIdentifier("neodymium.waitTime.custom");
+ }
+
+ public static void waitStandardWaitTime()
+ {
+ if (INSTANCE == null)
+ {
+ INSTANCE = new NeoWaitTime();
+ }
+ Selenide.sleep(INSTANCE.standardWait);
+ }
+
+ public static void waitShortWaitTime()
+ {
+ if (INSTANCE == null)
+ {
+ INSTANCE = new NeoWaitTime();
+ }
+ Selenide.sleep(INSTANCE.shortWait);
+ }
+
+ public static void waitDoubleWaitTime()
+ {
+ if (INSTANCE == null)
+ {
+ INSTANCE = new NeoWaitTime();
+ }
+ Selenide.sleep(INSTANCE.doubleWait);
+ }
+
+ public static void waitLongWaitTime()
+ {
+ if (INSTANCE == null)
+ {
+ INSTANCE = new NeoWaitTime();
+ }
+ Selenide.sleep(INSTANCE.longWait);
+ }
+
+ public static void waitCustomWaitTime(String key)
+ {
+ if (INSTANCE == null)
+ {
+ INSTANCE = new NeoWaitTime();
+ }
+ Selenide.sleep(Integer.valueOf(INSTANCE.customWaitTimeMap.get(key)));
+ }
+}
diff --git a/src/main/java/com/xceptance/neodymium/util/NeodymiumConfiguration.java b/src/main/java/com/xceptance/neodymium/util/NeodymiumConfiguration.java
index a6d4a7bee..05e411966 100644
--- a/src/main/java/com/xceptance/neodymium/util/NeodymiumConfiguration.java
+++ b/src/main/java/com/xceptance/neodymium/util/NeodymiumConfiguration.java
@@ -267,4 +267,20 @@ public interface NeodymiumConfiguration extends Mutable
@Key("neodymium.logNeoVersion")
@DefaultValue("true")
public boolean logNeoVersion();
+
+ @Key("neodymium.waitTime.standard")
+ @DefaultValue("100")
+ public int getStandardWaitTime();
+
+ @Key("neodymium.waitTime.short")
+ @DefaultValue("50")
+ public int getShortWaitTime();
+
+ @Key("neodymium.waitTime.double")
+ @DefaultValue("200")
+ public int getDoubleWaitTime();
+
+ @Key("neodymium.waitTime.long")
+ @DefaultValue("500")
+ public int getLongWaitTime();
}
diff --git a/src/main/java/com/xceptance/neodymium/util/PropertiesUtil.java b/src/main/java/com/xceptance/neodymium/util/PropertiesUtil.java
new file mode 100644
index 000000000..fe8f49134
--- /dev/null
+++ b/src/main/java/com/xceptance/neodymium/util/PropertiesUtil.java
@@ -0,0 +1,129 @@
+package com.xceptance.neodymium.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+import org.aeonbits.owner.ConfigFactory;
+import org.apache.commons.lang3.StringUtils;
+
+public class PropertiesUtil
+{
+ public static Set getSubkeysForPrefix(Properties properties, String prefix)
+ {
+ Set keys = new HashSet();
+
+ for (Object key : properties.keySet())
+ {
+ String keyString = (String) key;
+ if (keyString.toLowerCase().startsWith(prefix.toLowerCase()))
+ {
+ // cut off prefix
+ keyString = keyString.substring(prefix.length());
+
+ // split on the next dots
+ String[] split = keyString.split("\\.");
+ if (split != null && split.length > 0)
+ {
+ // the first entry in the resulting array will be the key we are searching for
+ String newKey = split[0];
+ if (StringUtils.isNotBlank(newKey))
+ {
+ keys.add(newKey);
+ }
+ }
+ }
+ }
+
+ return keys;
+ }
+
+ public static void loadPropertiesFromFile(String path, Properties properties)
+ {
+ try
+ {
+ File source = new File(path);
+ if (source.exists())
+ {
+ FileInputStream fileInputStream = new FileInputStream(source);
+ properties.load(fileInputStream);
+ fileInputStream.close();
+ }
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static Map getDataMapForIdentifier(String identifier, Properties properties)
+ {
+ Map resultMap = new HashMap();
+ for (Entry