package net.thucydides.core.webdriver;
import com.google.common.base.Preconditions;
import net.thucydides.core.Thucydides;
import net.thucydides.core.ThucydidesSystemProperty;
import net.thucydides.core.fixtureservices.FixtureException;
import net.thucydides.core.fixtureservices.FixtureProviderService;
import net.thucydides.core.fixtureservices.FixtureService;
import net.thucydides.core.guice.Injectors;
import net.thucydides.core.pages.PageObject;
import net.thucydides.core.steps.FilePathParser;
import net.thucydides.core.util.EnvironmentVariables;
import net.thucydides.core.webdriver.capabilities.BrowserStackRemoteDriverCapabilities;
import net.thucydides.core.webdriver.capabilities.SauceRemoteDriverCapabilities;
import net.thucydides.core.webdriver.chrome.OptionsSplitter;
import net.thucydides.core.webdriver.firefox.FirefoxProfileEnhancer;
import net.thucydides.core.webdriver.phantomjs.PhantomJSCapabilityEnhancer;
import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.internal.ProfilesIni;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.phantomjs.PhantomJSDriverService;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import static net.thucydides.core.webdriver.javascript.JavascriptSupport.activateJavascriptSupportFor;
import static org.apache.commons.lang3.StringUtils.isNotEmpty;
/**
* Provides an instance of a supported WebDriver.
* When you instanciate a Webdriver instance for Firefox or Chrome, it opens a new browser.
*
* @author johnsmart
*/
public class WebDriverFactory {
public static final String DEFAULT_DRIVER = "firefox";
public static final String REMOTE_DRIVER = "remote";
private final WebdriverInstanceFactory webdriverInstanceFactory;
private static final Logger LOGGER = LoggerFactory.getLogger(WebDriverFactory.class);
private ProfilesIni allProfiles;
private static final int DEFAULT_HEIGHT = ThucydidesSystemProperty.DEFAULT_HEIGHT;
private static final int DEFAULT_WIDTH = ThucydidesSystemProperty.DEFAULT_WIDTH;
private final EnvironmentVariables environmentVariables;
private final FirefoxProfileEnhancer firefoxProfileEnhancer;
private final FixtureProviderService fixtureProviderService;
private final ElementProxyCreator proxyCreator;
private final BrowserStackRemoteDriverCapabilities browserStackRemoteDriverCapabilities;
private final SauceRemoteDriverCapabilities sauceRemoteDriverCapabilities;
private final Integer EXTRA_TIME_TO_TAKE_SCREENSHOTS = 180;
public WebDriverFactory() {
this(new WebdriverInstanceFactory(), Injectors.getInjector().getProvider(EnvironmentVariables.class).get() );
}
public WebDriverFactory(EnvironmentVariables environmentVariables) {
this(new WebdriverInstanceFactory(), environmentVariables);
}
public WebDriverFactory(WebdriverInstanceFactory webdriverInstanceFactory,
EnvironmentVariables environmentVariables) {
this(webdriverInstanceFactory,
environmentVariables,
new FirefoxProfileEnhancer(environmentVariables));
}
public WebDriverFactory(WebdriverInstanceFactory webdriverInstanceFactory,
EnvironmentVariables environmentVariables,
FirefoxProfileEnhancer firefoxProfileEnhancer) {
this(webdriverInstanceFactory, environmentVariables, firefoxProfileEnhancer,
Injectors.getInjector().getInstance(FixtureProviderService.class),
Injectors.getInjector().getInstance(ElementProxyCreator.class));
}
public WebDriverFactory(WebdriverInstanceFactory webdriverInstanceFactory,
EnvironmentVariables environmentVariables,
FirefoxProfileEnhancer firefoxProfileEnhancer,
FixtureProviderService fixtureProviderService) {
this(webdriverInstanceFactory, environmentVariables, firefoxProfileEnhancer, fixtureProviderService,
Injectors.getInjector().getInstance(ElementProxyCreator.class));
}
public WebDriverFactory(WebdriverInstanceFactory webdriverInstanceFactory,
EnvironmentVariables environmentVariables,
FirefoxProfileEnhancer firefoxProfileEnhancer,
FixtureProviderService fixtureProviderService,
ElementProxyCreator proxyCreator) {
this.webdriverInstanceFactory = webdriverInstanceFactory;
this.environmentVariables = environmentVariables;
this.firefoxProfileEnhancer = firefoxProfileEnhancer;
this.fixtureProviderService = fixtureProviderService;
this.proxyCreator = proxyCreator;
this.browserStackRemoteDriverCapabilities = new BrowserStackRemoteDriverCapabilities(environmentVariables);
this.sauceRemoteDriverCapabilities = new SauceRemoteDriverCapabilities(environmentVariables);
}
protected ProfilesIni getAllProfiles() {
if (allProfiles == null) {
allProfiles = new ProfilesIni();
}
return allProfiles;
}
/**
* Create a new WebDriver instance of a given type.
*/
public WebDriver newInstanceOf(final SupportedWebDriver driverType) {
if (driverType == null) {
throw new IllegalArgumentException("Driver type cannot be null");
}
return newWebdriverInstance(driverType.getWebdriverClass());
}
public Class<? extends WebDriver> getClassFor(final SupportedWebDriver driverType) {
if (usesSauceLabs() && (driverType != SupportedWebDriver.HTMLUNIT)) {
return RemoteWebDriver.class;
} else {
return driverType.getWebdriverClass();
}
}
public boolean usesSauceLabs() {
return StringUtils.isNotEmpty(sauceRemoteDriverCapabilities.getUrl());
}
public boolean usesBrowserStack() {
return StringUtils.isNotEmpty(browserStackRemoteDriverCapabilities.getUrl());
}
/**
* This method is synchronized because multiple webdriver instances can be created in parallel.
* However, they may use common system resources such as ports, so may potentially interfere
* with each other.
*
* @param driverClass
*/
protected synchronized WebDriver newWebdriverInstance(final Class<? extends WebDriver> driverClass) {
try {
WebDriver driver;
if (isARemoteDriver(driverClass) || shouldUseARemoteDriver() || saucelabsUrlIsDefined() || browserStackUrlIsDefined()) {
driver = newRemoteDriver();
} else if (isAFirefoxDriver(driverClass)) {
driver = firefoxDriver();
} else if (isAnHtmlUnitDriver(driverClass)) {
driver = htmlunitDriver();
} else if (isAPhantomJSDriver(driverClass)) {
setPhantomJSPathIfNotSet();
driver = phantomJSDriver();
} else if (isAChromeDriver(driverClass)) {
driver = chromeDriver();
} else if (isASafariDriver(driverClass)) {
driver = safariDriver();
} else if (isAnInternetExplorerDriver(driverClass)) {
driver = internetExplorerDriver();
} else if (isAProvidedDriver(driverClass)) {
driver = providedDriver();
} else {
driver = newDriverInstanceFrom(driverClass);
}
setImplicitTimeoutsIfSpecified(driver);
redimensionBrowser(driver);
activateJavascriptSupportFor(driver);
return driver;
} catch (Exception cause) {
throw new UnsupportedDriverException("Could not instantiate " + driverClass, cause);
}
}
// IntelliJ in Mac OS X does not pick up environment variables. So to get PhantomJS working in IDE mode for the
// Thucydides tests, add the 'phantomjs.binary.path' property into a thucydides.properties file in your home directory.
private void setPhantomJSPathIfNotSet() {
if (!phantomJSIsAvailable()) {
LOGGER.info("PhantomJS not on path, trying to get path from PHANTOMJS_BINARY_PATH");
String phantomJSPath = System.getProperty(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY);
String phantomJSPathEnvironmentProperty = System.getenv("PHANTOMJS_BINARY_PATH");
LOGGER.info("PHANTOMJS_BINARY_PATH = " + phantomJSPathEnvironmentProperty);
LOGGER.info("PHANTOMJS_EXECUTABLE_PATH_PROPERTY = " + phantomJSPath);
if (StringUtils.isNotEmpty(phantomJSPath)) {
System.setProperty(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, phantomJSPath);
} else if (StringUtils.isNotEmpty(phantomJSPathEnvironmentProperty)) {
System.setProperty(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, phantomJSPathEnvironmentProperty);
}
}
}
private boolean phantomJSIsAvailable() {
try {
return (executeCommand("phantomjs -v") != 0);
} catch (IOException e) {
return false;
}
}
private int executeCommand(String command) throws IOException {
Process cmdProc = Runtime.getRuntime().exec(command);
try {
return cmdProc.waitFor();
} catch (InterruptedException e) {
return -1;
}
}
private boolean isAProvidedDriver(Class<? extends WebDriver> driverClass) {
return ProvidedDriver.class.isAssignableFrom(driverClass);
}
private WebDriver providedDriver() {
ProvidedDriverConfiguration sourceConfig = new ProvidedDriverConfiguration(environmentVariables);
try {
return sourceConfig.getDriverSource().newDriver();
} catch (Exception e) {
throw new RuntimeException("Could not instantiate the custom webdriver provider of type " + sourceConfig.getDriverName());
}
}
private void setImplicitTimeoutsIfSpecified(WebDriver driver) {
if (ThucydidesSystemProperty.WEBDRIVER_TIMEOUTS_IMPLICITLYWAIT.isDefinedIn(environmentVariables)) {
int timeout = environmentVariables.getPropertyAsInteger(ThucydidesSystemProperty.WEBDRIVER_TIMEOUTS_IMPLICITLYWAIT
.getPropertyName(),0);
driver.manage().timeouts().implicitlyWait(timeout, TimeUnit.MILLISECONDS);
}
}
private boolean shouldUseARemoteDriver() {
return ThucydidesSystemProperty.WEBDRIVER_REMOTE_URL.isDefinedIn(environmentVariables);
}
private WebDriver newDriverInstanceFrom(Class<? extends WebDriver> driverClass) throws IllegalAccessException, InstantiationException {
return webdriverInstanceFactory.newInstanceOf(driverClass);
}
private WebDriver newRemoteDriver() throws MalformedURLException {
WebDriver driver = null;
if (saucelabsUrlIsDefined()) {
driver = buildSaucelabsDriver();
} else if (browserStackUrlIsDefined()){
driver = buildBrowserStackDriver();
} else {
driver = buildRemoteDriver();
}
Augmenter augmenter = new Augmenter();
return augmenter.augment(driver);
}
private WebDriver buildRemoteDriver() throws MalformedURLException {
String remoteUrl = ThucydidesSystemProperty.WEBDRIVER_REMOTE_URL.from(environmentVariables);
return webdriverInstanceFactory.newRemoteDriver(new URL(remoteUrl), buildRemoteCapabilities());
}
private boolean saucelabsUrlIsDefined() {
return StringUtils.isNotEmpty(sauceRemoteDriverCapabilities.getUrl());
}
private boolean browserStackUrlIsDefined() {
return StringUtils.isNotEmpty(browserStackRemoteDriverCapabilities.getUrl());
}
private WebDriver buildSaucelabsDriver() throws MalformedURLException {
String saucelabsUrl = sauceRemoteDriverCapabilities.getUrl();
WebDriver driver = webdriverInstanceFactory.newRemoteDriver(new URL(saucelabsUrl), findSaucelabsCapabilities());
if (isNotEmpty(ThucydidesSystemProperty.SAUCELABS_IMPLICIT_TIMEOUT.from(environmentVariables))) {
int implicitWait = environmentVariables.getPropertyAsInteger(
ThucydidesSystemProperty.SAUCELABS_IMPLICIT_TIMEOUT.getPropertyName(), 30);
driver.manage().timeouts().implicitlyWait(implicitWait, TimeUnit.SECONDS);
}
return driver;
}
private WebDriver buildBrowserStackDriver() throws MalformedURLException{
String browserStackUrl = browserStackRemoteDriverCapabilities.getUrl();
WebDriver driver = webdriverInstanceFactory.newRemoteDriver(new URL(browserStackUrl), findbrowserStackCapabilities());
return driver;
}
public static String getDriverFrom(EnvironmentVariables environmentVariables, String defaultDriver) {
String driver = getDriverFrom(environmentVariables);
return (driver != null) ? driver : defaultDriver;
}
public static String getDriverFrom(EnvironmentVariables environmentVariables) {
String driver = ThucydidesSystemProperty.WEBDRIVER_DRIVER.from(environmentVariables);
if (driver == null) {
driver = ThucydidesSystemProperty.DRIVER.from(environmentVariables);
}
return driver;
}
private Capabilities findSaucelabsCapabilities() {
String driver = getDriverFrom(environmentVariables);
DesiredCapabilities capabilities = capabilitiesForDriver(driver);
return sauceRemoteDriverCapabilities.getCapabilities(capabilities);
}
private Capabilities findbrowserStackCapabilities() {
String driver = getDriverFrom(environmentVariables);
DesiredCapabilities capabilities = capabilitiesForDriver(driver);
return browserStackRemoteDriverCapabilities.getCapabilities(capabilities);
}
private Capabilities buildRemoteCapabilities() {
String driver = ThucydidesSystemProperty.WEBDRIVER_REMOTE_DRIVER.from(environmentVariables);
if (driver == null) {
driver = getDriverFrom(environmentVariables);
}
return capabilitiesForDriver(driver);
}
private DesiredCapabilities capabilitiesForDriver(String driver) {
if (driver == null) {
driver = REMOTE_DRIVER;
}
SupportedWebDriver driverType = driverTypeFor(driver);
Preconditions.checkNotNull(driverType, "Unsupported remote driver type: ");
if (driverType == SupportedWebDriver.REMOTE) {
return (DesiredCapabilities) enhancedCapabilities(remoteCapabilities());
} else {
return (DesiredCapabilities) enhancedCapabilities(realBrowserCapabilities(driverType));
}
}
private SupportedWebDriver driverTypeFor(String driver) {
String normalizedDriverName = driver.toUpperCase();
if (!SupportedWebDriver.listOfSupportedDrivers().contains(normalizedDriverName)) {
SupportedWebDriver closestDriver = SupportedWebDriver.getClosestDriverValueTo(normalizedDriverName);
throw new AssertionError("Unsupported driver for webdriver.driver or webdriver.remote.driver: " + driver
+ ". Did you mean " + closestDriver.toString().toLowerCase() + "?");
}
return SupportedWebDriver.valueOf(normalizedDriverName);
}
private DesiredCapabilities realBrowserCapabilities(SupportedWebDriver driverType) {
DesiredCapabilities capabilities = null;
switch (driverType) {
case CHROME:
capabilities = chromeCapabilities();
break;
case SAFARI:
capabilities = DesiredCapabilities.safari();
break;
case FIREFOX:
capabilities = DesiredCapabilities.firefox();
capabilities.setCapability("firefox_profile",buildFirefoxProfile());
break;
case HTMLUNIT:
capabilities = DesiredCapabilities.htmlUnit();
break;
case OPERA:
capabilities = DesiredCapabilities.opera();
break;
case IEXPLORER:
capabilities = DesiredCapabilities.internetExplorer();
break;
default:
capabilities = new DesiredCapabilities();
capabilities.setJavascriptEnabled(true);
}
return (DesiredCapabilities) enhancedCapabilities(capabilities);
}
private DesiredCapabilities remoteCapabilities() {
String remoteBrowser = ThucydidesSystemProperty.WEBDRIVER_REMOTE_DRIVER.from(environmentVariables, "firefox");
DesiredCapabilities capabilities = realBrowserCapabilities(driverTypeFor(remoteBrowser));
capabilities.setCapability("idle-timeout",EXTRA_TIME_TO_TAKE_SCREENSHOTS);
Boolean recordScreenshotsInSaucelabs
= environmentVariables.getPropertyAsBoolean(ThucydidesSystemProperty.SAUCELABS_RECORD_SCREENSHOTS, false);
capabilities.setCapability("record-screenshots", recordScreenshotsInSaucelabs);
if (environmentVariables.getProperty(ThucydidesSystemProperty.WEBDRIVER_REMOTE_OS) != null) {
capabilities.setCapability("platform", Platform.valueOf(environmentVariables.getProperty(ThucydidesSystemProperty.WEBDRIVER_REMOTE_OS)));
}
if (environmentVariables.getProperty(ThucydidesSystemProperty.WEBDRIVER_REMOTE_BROWSER_VERSION) != null) {
capabilities.setCapability("version", Platform.valueOf(environmentVariables.getProperty(ThucydidesSystemProperty.WEBDRIVER_REMOTE_BROWSER_VERSION)));
}
return capabilities;
}
private DesiredCapabilities addExtraCatabilitiesTo(DesiredCapabilities capabilities) {
CapabilitySet capabilitySet = new CapabilitySet(environmentVariables);
Map<String, Object> extraCapabilities = capabilitySet.getCapabilities();
for(String capabilityName : extraCapabilities.keySet()) {
capabilities.setCapability(capabilityName, extraCapabilities.get(capabilityName));
}
addCapabilitiesFromFixtureServicesTo(capabilities);
return capabilities;
}
public void setupFixtureServices() throws FixtureException {
for(FixtureService fixtureService : fixtureProviderService.getFixtureServices()) {
fixtureService.setup();
}
}
public void shutdownFixtureServices() {
for(FixtureService fixtureService : fixtureProviderService.getFixtureServices()) {
fixtureService.shutdown();
}
}
private void addCapabilitiesFromFixtureServicesTo(DesiredCapabilities capabilities) {
for(FixtureService fixtureService : fixtureProviderService.getFixtureServices()) {
fixtureService.addCapabilitiesTo(capabilities);
}
}
private WebDriver htmlunitDriver() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
DesiredCapabilities capabilities = DesiredCapabilities.htmlUnit();
capabilities.setJavascriptEnabled(true);
return webdriverInstanceFactory.newHtmlUnitDriver(enhancedCapabilities(capabilities));
}
private WebDriver phantomJSDriver() {
DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();
PhantomJSCapabilityEnhancer enhancer = new PhantomJSCapabilityEnhancer(environmentVariables);
enhancer.enhanceCapabilities(capabilities);
return webdriverInstanceFactory.newPhantomDriver(enhancedCapabilities(capabilities));
}
private WebDriver firefoxDriver() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
FirefoxProfile profile = buildFirefoxProfile();
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability(FirefoxDriver.PROFILE, profile);
return webdriverInstanceFactory.newFirefoxDriver(enhancedCapabilities(capabilities));
}
private WebDriver chromeDriver() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
DesiredCapabilities capabilities = chromeCapabilities();
updateChromePathIfSpecifiedIn(environmentVariables);
return webdriverInstanceFactory.newChromeDriver(enhancedCapabilities(capabilities));
}
private void updateChromePathIfSpecifiedIn(EnvironmentVariables environmentVariables) {
String environmentDefinedChromeDriverPath = environmentVariables.getProperty(ThucydidesSystemProperty.WEBDRIVER_CHROME_DRIVER);
if (StringUtils.isNotEmpty(environmentDefinedChromeDriverPath)) {
System.setProperty(ThucydidesSystemProperty.WEBDRIVER_CHROME_DRIVER.toString(), environmentDefinedChromeDriverPath);
}
}
private DesiredCapabilities chromeCapabilities() {
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
String chromeSwitches = environmentVariables.getProperty(ThucydidesSystemProperty.CHROME_SWITCHES);
capabilities.setCapability(ChromeOptions.CAPABILITY, optionsFromSwitches(chromeSwitches));
capabilities.setCapability("chrome.switches", chromeSwitches);
return capabilities;
}
private ChromeOptions optionsFromSwitches(String chromeSwitches) {
ChromeOptions options = new ChromeOptions();
options.addArguments("test-type");
if (StringUtils.isNotEmpty(chromeSwitches)) {
List<String> arguments = new OptionsSplitter().split(chromeSwitches);
options.addArguments(arguments);
}
return options;
}
private WebDriver safariDriver() throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
return webdriverInstanceFactory.newSafariDriver(enhancedCapabilities(DesiredCapabilities.safari()));
}
private WebDriver internetExplorerDriver() {
return webdriverInstanceFactory.newInternetExplorerDriver(enhancedCapabilities(DesiredCapabilities.internetExplorer()));
}
private Capabilities enhancedCapabilities(DesiredCapabilities capabilities) {
return addExtraCatabilitiesTo(capabilities);
}
private Dimension getRequestedBrowserSize() {
int height = environmentVariables.getPropertyAsInteger(ThucydidesSystemProperty.THUCYDIDES_BROWSER_HEIGHT, DEFAULT_HEIGHT);
int width = environmentVariables.getPropertyAsInteger(ThucydidesSystemProperty.THUCYDIDES_BROWSER_WIDTH, DEFAULT_WIDTH);
return new Dimension(width, height);
}
private void redimensionBrowser(final WebDriver driver) {
if (supportsScreenResizing(driver) && browserDimensionsSpecified()) {
resizeBrowserTo(driver,
getRequestedBrowserSize().height,
getRequestedBrowserSize().width);
}
}
private boolean browserDimensionsSpecified() {
String snapshotWidth = environmentVariables.getProperty(ThucydidesSystemProperty.THUCYDIDES_BROWSER_WIDTH);
String snapshotHeight = environmentVariables.getProperty(ThucydidesSystemProperty.THUCYDIDES_BROWSER_HEIGHT);
return (snapshotWidth != null) || (snapshotHeight != null);
}
private boolean supportsScreenResizing(final WebDriver driver) {
return isNotAMocked(driver) && (!isAnHtmlUnitDriver(getDriverClass(driver)));
}
private boolean isNotAMocked(WebDriver driver) {
return (!driver.getClass().getName().contains("Mock"));
}
protected void resizeBrowserTo(WebDriver driver, int height, int width) {
LOGGER.info("Setting browser dimensions to {}/{}", height, width);
if (usesFirefox(driver) || usesInternetExplorer(driver) || usesPhantomJS(driver)) {
driver.manage().window().setSize(new Dimension(width, height));
} else if (usesChrome(driver)) {
((JavascriptExecutor) driver).executeScript("window.open('about:blank','_blank','width=#{width},height=#{height}');");
Set<String> windowHandles = driver.getWindowHandles();
windowHandles.remove(driver.getWindowHandle());
String newWindowHandle = windowHandles.toArray(new String[]{})[0];
driver.switchTo().window(newWindowHandle);
}
String resizeWindow = "window.resizeTo(" + width + "," + height + ")";
((JavascriptExecutor) driver).executeScript(resizeWindow);
}
private boolean isARemoteDriver(Class<? extends WebDriver> driverClass) {
return (RemoteWebDriver.class == driverClass);
}
private boolean isAFirefoxDriver(Class<? extends WebDriver> driverClass) {
return (FirefoxDriver.class.isAssignableFrom(driverClass));
}
private boolean isAChromeDriver(Class<? extends WebDriver> driverClass) {
return (ChromeDriver.class.isAssignableFrom(driverClass));
}
private boolean isASafariDriver(Class<? extends WebDriver> driverClass) {
return (SafariDriver.class.isAssignableFrom(driverClass));
}
private boolean isAnInternetExplorerDriver(Class<? extends WebDriver> driverClass) {
return (InternetExplorerDriver.class.isAssignableFrom(driverClass));
}
private boolean usesFirefox(WebDriver driver) {
return (FirefoxDriver.class.isAssignableFrom(getDriverClass(driver)));
}
private boolean usesInternetExplorer(WebDriver driver) {
return (InternetExplorerDriver.class.isAssignableFrom(getDriverClass(driver)));
}
private boolean usesChrome(WebDriver driver) {
return (ChromeDriver.class.isAssignableFrom(getDriverClass(driver)));
}
private Class getDriverClass(WebDriver driver) {
Class driverClass = null;
if (driver instanceof WebDriverFacade) {
driverClass = ((WebDriverFacade) driver).getDriverClass();
} else {
driverClass = driver.getClass();
}
return driverClass;
}
private boolean isAnHtmlUnitDriver(Class<? extends WebDriver> driverClass) {
return (HtmlUnitDriver.class.isAssignableFrom(driverClass));
}
private boolean isAPhantomJSDriver(Class<? extends WebDriver> driverClass) {
return (PhantomJSDriver.class.isAssignableFrom(driverClass));
}
private boolean usesPhantomJS(WebDriver driver) {
return (PhantomJSDriver.class.isAssignableFrom(getDriverClass(driver)));
}
protected FirefoxProfile createNewFirefoxProfile() {
FirefoxProfile profile;
if (Thucydides.getFirefoxProfile() != null) {
profile = Thucydides.getFirefoxProfile();
} else {
profile = new FirefoxProfile();
profile.setPreference("network.proxy.socks_port",9999);
profile.setAlwaysLoadNoFocusLib(true);
profile.setEnableNativeEvents(true);
}
return profile;
}
protected FirefoxProfile useExistingFirefoxProfile(final File profileDirectory) {
return new FirefoxProfile(profileDirectory);
}
protected FirefoxProfile buildFirefoxProfile() {
String profileName = ThucydidesSystemProperty.WEBDRIVER_FIREFOX_PROFILE.from(environmentVariables);
FilePathParser parser = new FilePathParser(environmentVariables);
DesiredCapabilities firefoxCapabilities = DesiredCapabilities.firefox();
if (StringUtils.isNotEmpty(profileName)) {
firefoxCapabilities.setCapability(FirefoxDriver.PROFILE, parser.getInstanciatedPath(profileName));
}
FirefoxProfile profile;
if (profileName == null) {
profile = createNewFirefoxProfile();
} else {
profile = getProfileFrom(profileName);
}
firefoxProfileEnhancer.allowWindowResizeFor(profile);
firefoxProfileEnhancer.activateNativeEventsFor(profile, shouldEnableNativeEvents());
if (shouldActivateProxy()) {
activateProxyFor(profile, firefoxProfileEnhancer);
}
if (firefoxProfileEnhancer.shouldActivateFirebugs()) {
firefoxProfileEnhancer.addFirebugsTo(profile);
}
if (refuseUntrustedCertificates()) {
profile.setAssumeUntrustedCertificateIssuer(false);
profile.setAcceptUntrustedCertificates(false);
} else {
profile.setAssumeUntrustedCertificateIssuer(true);
profile.setAcceptUntrustedCertificates(true);
}
firefoxProfileEnhancer.configureJavaSupport(profile);
firefoxProfileEnhancer.addPreferences(profile);
return profile;
}
private boolean shouldEnableNativeEvents() {
return Boolean.valueOf(ThucydidesSystemProperty.THUCYDIDES_NATIVE_EVENTS.from(environmentVariables,"true"));
}
private void activateProxyFor(FirefoxProfile profile, FirefoxProfileEnhancer firefoxProfileEnhancer) {
String proxyUrl = getProxyUrlFromEnvironmentVariables();
String proxyPort = getProxyPortFromEnvironmentVariables();
firefoxProfileEnhancer.activateProxy(profile, proxyUrl, proxyPort);
}
private String getProxyPortFromEnvironmentVariables() {
return environmentVariables.getProperty(ThucydidesSystemProperty.THUCYDIDES_PROXY_HTTP_PORT.getPropertyName());
}
private boolean shouldActivateProxy() {
String proxyUrl = getProxyUrlFromEnvironmentVariables();
return StringUtils.isNotEmpty(proxyUrl);
}
private String getProxyUrlFromEnvironmentVariables() {
return environmentVariables.getProperty(ThucydidesSystemProperty.THUCYDIDES_PROXY_HTTP.getPropertyName());
}
private FirefoxProfile getProfileFrom(final String profileName) {
FirefoxProfile profile = getAllProfiles().getProfile(profileName);
if (profile == null) {
profile = useExistingFirefoxProfile(new File(profileName));
}
return profile;
}
private boolean refuseUntrustedCertificates() {
return environmentVariables.getPropertyAsBoolean(ThucydidesSystemProperty.REFUSE_UNTRUSTED_CERTIFICATES.getPropertyName(), false);
}
/**
* Initialize a page object's fields using the specified WebDriver instance.
*/
public void initElementsWithAjaxSupport(final PageObject pageObject, final WebDriver driver, int timeoutInSeconds) {
proxyCreator.proxyElements(pageObject, driver, timeoutInSeconds);
}
}