Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.unitils.selenium.WebDriverModule Maven / Gradle / Ivy
package org.unitils.selenium;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.logging.Level;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.support.PageFactory;
import org.unitils.core.Module;
import org.unitils.core.TestListener;
import org.unitils.dbmaintainer.locator.ClassPathDataLocator;
import org.unitils.selenium.annotation.BaseUrl;
import org.unitils.selenium.annotation.TestWebDriver;
import org.unitils.selenium.annotation.WebPage;
import org.unitils.util.AnnotationUtils;
import org.unitils.util.PropertyUtils;
import org.unitils.util.ReflectionUtils;
/**
*
* @author Jeroen Horemans
* @author Thomas De Rycke
* @author Willemijn Wouters
*
* @since 1.0.0
*
*/
public class WebDriverModule implements Module {
protected static final String PACKAGENAME = "org.unitils.selenium";
protected static final String BROWSER_NAME_KEY = PACKAGENAME + ".browser.name";
protected static final String BASE_URL_KEY = PACKAGENAME + ".baseUrl";
protected static final String PROXY_HOST_KEY = PACKAGENAME + ".browser.proxy";
protected static final String DOWNLOADPATH = PACKAGENAME + ".downloadpath";
protected static final String FILETYPE = PACKAGENAME + ".filetype";
protected static final String LIST_AUTOMATICALLY_DOWNLOAD = "application/pdf, application/vnd.fdf, application/x-msdos-program, application/x-unknown-application-octet-stream, application/vnd.ms-powerpoint, application/excel, application/vnd.ms-publisher, application/x-unknown-message-rfc822, application/vnd.ms-excel, application/msword, application/x-mspublisher, application/x-tar, application/zip, application/x-gzip,application/x-stuffit,application/vnd.ms-works, application/powerpoint, application/rtf, application/postscript, application/x-gtar, video/quicktime, video/x-msvideo, video/mpeg, audio/x-wav, audio/x-midi, audio/x-aiff, application/octet-stream";
protected static final String FIREFOX_BINARY_KEY = PACKAGENAME + ".firefoxbinary";
protected static final String IE_BINARY_KEY = PACKAGENAME + ".iebinary";
protected static final String CHROME_DRIVER_KEY = PACKAGENAME + ".chromedriver";
protected static final String CHROME_BINARY_KEY = PACKAGENAME + ".chromebinary";
protected static final String LOGGINGPROP_CONSOLE_ENABLED = PACKAGENAME + ".logging.console.enabled";
protected static final String LOGGINGPROP_PERFORMANCE = PACKAGENAME + ".logging.performance";
protected static final String LOGGINGPROP_BROWSER = PACKAGENAME + ".logging.browser";
protected static final String LOGGINGPROP_CLIENT = PACKAGENAME + ".logging.client";
protected static final String LOGGINGPROP_DRIVER = PACKAGENAME + ".logging.driver";
protected static final String LOGGINGPROP_PROFILER = PACKAGENAME + ".logging.profiler";
protected static final String LOGGINGPROP_SERVER = PACKAGENAME + ".logging.server";
protected static final String LOGGING_FILE_PROP = PACKAGENAME + ".logging.file";
protected static final String LOGGINGPROP_IE = PACKAGENAME + ".logging.IE";
private BrowserChoice browserChoice;
private String baseUrl;
private String proxyUrl;
private String downloadPath;
private String fileType;
private Properties configuration;
private static final Log LOGGER = LogFactory.getLog(WebDriverModule.class);
private ClassPathDataLocator dataLocator;
@Override
public void init(Properties configuration) {
dataLocator = new ClassPathDataLocator();
browserChoice = resolveBrowserChoice(configuration);
baseUrl = resolveBaseUrl(configuration);
proxyUrl = resolveProxyHost(configuration);
LOGGER.debug("Driver Module loaded");
downloadPath = PropertyUtils.getString(DOWNLOADPATH, "", configuration);
fileType = PropertyUtils.getString(FILETYPE, LIST_AUTOMATICALLY_DOWNLOAD, configuration);
this.configuration = configuration;
String bit = System.getProperty("sun.arch.data.model");
ClassLoader classLoader = getClass().getClassLoader();
checkFirefoxDriver();
checkChromeDriver(bit, classLoader);
checkIEDriver(bit, classLoader);
}
@Override
public void afterInit() {
// nothing for now.
}
/**
* *
* Get the base URL out of unitils.properties
*
* @param configuration
* @return {@link String}
*/
private String resolveBaseUrl(Properties configuration) {
String result = configuration.getProperty(BASE_URL_KEY);
if (StringUtils.isEmpty(result)) {
throw new IllegalArgumentException("plz fill in a value in the unitils.properties for " + BASE_URL_KEY);
}
return result;
}
/**
* Gets the name of the browser out of unitils.properties
*
* @param configuration
* @return {@link BrowserChoice}
*/
private BrowserChoice resolveBrowserChoice(Properties configuration) {
String browserName = configuration.getProperty(BROWSER_NAME_KEY);
if (StringUtils.isEmpty(browserName)) {
LOGGER.info(BROWSER_NAME_KEY + " not set. Will choose browser FIREFOX");
return BrowserChoice.FIREFOX;
}
return BrowserChoice.valueOf(browserName);
}
/**
* Get the proxy host out of unitils.properties
*
* @param configuration
* @return {@link String}
*/
private String resolveProxyHost(Properties configuration) {
String result = configuration.getProperty(PROXY_HOST_KEY);
if (StringUtils.isEmpty(result)) {
LOGGER.info(PROXY_HOST_KEY + " not set. No proxy used");
return "";
}
LOGGER.info("proxy: [" + result + "] set. Proxy used");
return result;
}
/**
* Initialises the webdriver. The method searches if there are fields with
* the {@link TestWebDriver} and uses the browser choice (in
* unitils.properties) to create the driver.
*
* @param testObject
*/
public void initWebDriver(Object testObject) {
Set fields = AnnotationUtils.getFieldsAnnotatedWith(testObject.getClass(), TestWebDriver.class);
if (fields.size() > 1) {
//warn if there are more than one fields with the @TestWebDriver
StringBuilder builder = new StringBuilder();
builder.append("There are more than one webdrivers.\n");
for (Field field : fields) {
builder.append("class: ");
builder.append(field.getDeclaringClass().getName());
builder.append(", field: ");
builder.append(field.getName());
builder.append("\n");
}
LOGGER.warn(builder.toString());
}
for (Field field : fields) {
WebDriver driver;
if (proxyUrl.isEmpty()) {
driver = WebDriverFactory.createDriver(browserChoice, getAbsoluteDownloadPath(downloadPath), fileType);
} else {
driver = WebDriverFactory.createDriver(browserChoice, proxyUrl, getAbsoluteDownloadPath(downloadPath), fileType);
}
driver.manage().deleteAllCookies();
ReflectionUtils.setFieldValue(testObject, field, driver);
}
}
protected static String getAbsoluteDownloadPath(String path) {
if (!StringUtils.isEmpty(path)) {
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
return file.getAbsolutePath();
}
return "";
}
/**
* All the webdrivers (all the fields with the {@link TestWebDriver} of the
* testObject will be killed.
*
* @param testObject
*/
protected void killWebDriver(Object testObject) {
Set fields = AnnotationUtils.getFieldsAnnotatedWith(testObject.getClass(), TestWebDriver.class);
for (Field field : fields) {
WebDriver driver = ReflectionUtils.getFieldValue(testObject, field);
LOGGER.debug("closing a driver that is on page : " + driver.getCurrentUrl());
driver.close();
driver.quit();
nastyDoubleCheck(driver);
nastyDoubleCheck(driver);
}
}
private void nastyDoubleCheck(WebDriver driver) {
try {
Thread.sleep(500);
driver.getTitle();
driver.close();
driver.quit();
} catch (WebDriverException e) {
// continue
} catch (InterruptedException e) {
// continue
}
}
/**
* All the elements with the @BaseUrlString will be initialised with the
* base url value of the unitils.properties.
*
* @param testObject
*/
public void initBaseUrl(Object testObject) {
Set fields = AnnotationUtils.getFieldsAnnotatedWith(testObject.getClass(), BaseUrl.class);
for (Field field : fields) {
ReflectionUtils.setFieldValue(testObject, field, baseUrl);
}
}
/**
* *
* Searches all the fields with the {@link WebPage} annotation and sets the
* correct elements.
*
* @param testObject
*/
public void initElements(Object testObject) {
//find fields that has the @WebPage annotation
Set fields = AnnotationUtils.getFieldsAnnotatedWith(testObject.getClass(), WebPage.class);
//find the webdriver
Set webdrivers = AnnotationUtils.getFieldsAnnotatedWith(testObject.getClass(), TestWebDriver.class);
if (webdrivers.size() > 0) {
//initialise the page and set the object in the correct field.
WebDriver webdriver = ReflectionUtils.getFieldValue(testObject, webdrivers.iterator().next());
for (Field field : fields) {
if (webdriver != null) {
ReflectionUtils.setFieldValue(testObject, field, getElement(webdriver, field.getType()));
}
}
} else {
LOGGER.error("The TestWebDriver cannot be found.");
}
}
protected void checkChromeDriver(String bit, ClassLoader classLoader) {
String driver = "chrome driver";
String pathChrome = "webdriver.chrome.driver";
String absPath = "";
if (!(checkIfDriverIsAlreadyInSystem(System.getProperty(pathChrome), driver, pathChrome) || checkIfDriverPropertyExistsInUnitilsProperties(CHROME_DRIVER_KEY, driver, pathChrome))) {
if (SystemUtils.IS_OS_WINDOWS) {
absPath = copyDriverIntoNewTempFile(dataLocator.loadResources("chromedriver_win.exe", true).get(0), "chromedriver_win.exe");
System.setProperty(pathChrome, absPath);
} else if (SystemUtils.IS_OS_MAC) {
//set drivers mac
absPath = copyDriverIntoNewTempFile(dataLocator.loadResources("chromedriver_mac32", true).get(0), "chromedriver_mac32");
System.setProperty(pathChrome, absPath);
} else if (SystemUtils.IS_OS_LINUX) {
absPath = copyDriverIntoNewTempFile(dataLocator.loadResources("chromedriver_linux32", true).get(0), "chromedriver_linux32");
System.setProperty(pathChrome, absPath);
}
LOGGER.info(createLogNewDriver(pathChrome, absPath));
}
}
/**
* This method checks if their is a system property 'webdriver.firefox.bin'
* and checks if it exists. Otherwise it will check the unitils.properties
* if their is a property {@link WebDriverModule#FIREFOX_BINARY_KEY} in the
* unitils.properties.
*/
protected void checkFirefoxDriver() {
String driver = "firefox driver";
String pathFirefox = "webdriver.firefox.bin";
if (!(checkIfDriverIsAlreadyInSystem(System.getProperty(pathFirefox), driver, pathFirefox) || checkIfDriverPropertyExistsInUnitilsProperties(FIREFOX_BINARY_KEY, driver, pathFirefox))) {
LOGGER.error("There is no firefox driver found.");
}
}
/**
* This method checks if there is a system property 'webdriver.ie.driver'
* and checks if the location exists. If this doesn't exist than he looks if
* you've defined another IE driver ( {@link WebDriverModule#IE_BINARY_KEY}
* in your unitils.properties. The last option is that it uses the driver
* that is given by unitils-selenium.
*
* @param bit
* @param classLoader
*/
protected void checkIEDriver(String bit, ClassLoader classLoader) {
String pathIE = "webdriver.ie.driver";
String driver = "IE driver";
String absPath = "";
//this is only possible on WINDOWS
if (SystemUtils.IS_OS_WINDOWS) {
if (!(checkIfDriverIsAlreadyInSystem(System.getProperty(pathIE), driver, pathIE) || checkIfDriverPropertyExistsInUnitilsProperties(IE_BINARY_KEY, driver, pathIE))) {
if (bit.equals("32")) {
absPath = copyDriverIntoNewTempFile(dataLocator.loadResources("IEDriverServer.exe", true).get(0), "IEDriverServer.exe");
System.setProperty(pathIE, absPath);
} else if (bit.equals("64")) {
absPath = copyDriverIntoNewTempFile(dataLocator.loadResources("IEDriverServer_x64.exe", true).get(0), "IEDriverServer_x64.exe");
System.setProperty(pathIE, absPath);
}
LOGGER.info(createLogNewDriver(pathIE, absPath));
}
}
}
public boolean checkIfDriverIsAlreadyInSystem(String systemProp, String driver, String systemVarDriver) {
if (!StringUtils.isEmpty(systemProp) && new File(systemProp).exists()) {
StringBuilder builder = new StringBuilder()
.append("The ")
.append(driver)
.append(" already defined in the system (")
.append(systemVarDriver)
.append(") exists and will be used by Unitils. location:")
.append(systemProp);
LOGGER.info(builder);
return true;
}
return false;
}
public boolean checkIfDriverPropertyExistsInUnitilsProperties(String key, String driver, String systemKey) {
String unitilsDriver = PropertyUtils.getString(key, "", configuration);
if (configuration.containsKey(key) && !StringUtils.isEmpty(unitilsDriver)) {
File driverFile = new File(unitilsDriver);
if (driverFile.exists()) {
StringBuilder builder = new StringBuilder()
.append("The WebdriverModule uses the ")
.append(driver)
.append(" from the unitils.properties. location: ")
.append(driverFile.toString());
LOGGER.info(builder.toString());
System.setProperty(systemKey, driverFile.getAbsolutePath());
return true;
} else {
StringBuilder builder = new StringBuilder()
.append("The location of the ")
.append(driver)
.append(" defined in the unitils.properties does not exists. location: ")
.append(driverFile.getAbsolutePath());
LOGGER.error(builder.toString());
}
}
return false;
}
public String copyDriverIntoNewTempFile(URL url, String name) {
StringBuilder result = new StringBuilder(TARGETSUREFIREREPORTS).append(name);
File destination = new File(result.toString());
try {
FileUtils.copyInputStreamToFile(url.openStream(), destination);
destination.setExecutable(true);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
return url.getPath();
}
return destination.getAbsolutePath();
}
public static final String TARGETSUREFIREREPORTS = "target/surefire-reports/";
/**
* This is the actual method that creates an object of the correct type and
* initialises all the elements.
*
* @param webdriver
* @param type
* @return {@link Object}
*
*/
protected Object getElement(WebDriver webdriver, Class> type) {
return PageFactory.initElements(webdriver, type);
}
@Override
public TestListener getTestListener() {
return new TestListener() {
@Override
public void beforeTestSetUp(Object testObject, Method testMethod) {
super.beforeTestSetUp(testObject, testMethod);
initWebDriver(testObject);
initBaseUrl(testObject);
initElements(testObject);
}
/**
* @see
* org.unitils.core.TestListener#afterTestMethod(java.lang.Object,
* java.lang.reflect.Method, java.lang.Throwable)
*/
@Override
public void afterTestMethod(Object testObject, Method testMethod, Throwable testThrowable) {
//write the console logging
//TODO: This doesn't work yet with IE.
if (PropertyUtils.getBoolean(WebDriverModule.LOGGINGPROP_CONSOLE_ENABLED, false, configuration)) {
LOGGER.info("BEGIN CONSOLE TEST: " + testMethod.getName());
if (!resolveBrowserChoice(configuration).equals(BrowserChoice.IE)) {
for (Field webdriverField : AnnotationUtils.getFieldsAnnotatedWith(testObject.getClass(), TestWebDriver.class)) {
WebDriver webdriver = ReflectionUtils.getFieldValue(testObject, webdriverField);
for (String type : webdriver.manage().logs().getAvailableLogTypes()) {
try {
List entries = webdriver.manage().logs().get(type).getAll();
System.out.println(entries.size() + " " + type + " log entries found");
for (LogEntry entry : entries) {
if (!entry.getLevel().equals(Level.OFF)) {
SimpleDateFormat format = new SimpleDateFormat("YYMMddHHmmss");
System.out.println(
format.format(new Date(entry.getTimestamp())) + " " + entry.getLevel() + " " + entry.getMessage());
}
}
} catch (Exception e) {
LOGGER.debug("Log " + type + " is not available.");
}
}
};
}
LOGGER.info("END CONSOLE TEST: " + testMethod.getName());
}
if (testThrowable != null) {
int i = 0;
try {
Set fields = AnnotationUtils.getFieldsAnnotatedWith(testObject.getClass(), TestWebDriver.class);
for (Field field : fields) {
WebDriver driver = ReflectionUtils.getFieldValue(testObject, field);
File surefire = new File(TARGETSUREFIREREPORTS);
if (!surefire.exists()) {
surefire.mkdir();
}
StringBuilder builder = new StringBuilder()
.append(testObject.getClass().getSimpleName())
.append("-")
.append(testMethod.getName())
.append("-")
.append(field.getName())
.append("-")
.append(++i);
new ScreenshotTakingWebDriver(driver, baseUrl).saveScreenshot(surefire, builder.toString());
}
} catch (Exception e) {
LOGGER.error("The taking of the screenshot has made a terrible mistake! but we'll continue!", e);
}
}
}
/**
* @see
* org.unitils.core.TestListener#afterTestTearDown(java.lang.Object,
* java.lang.reflect.Method)
*/
@Override
public void afterTestTearDown(Object testObject, Method testMethod) {
killWebDriver(testObject);
super.afterTestTearDown(testObject, testMethod);
}
};
}
protected static String createLogNewDriver(String systemVarDriver, String absPath) {
return new StringBuilder().append("The location of the variable defined in the ' ")
.append(systemVarDriver)
.append("' didn't exist, so we have changed the location of the variable to the driver added in unitils.selenium. location: ")
.append(absPath)
.toString();
}
}