All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.googlecode.jmeter.plugins.webdriver.config.WebDriverConfig Maven / Gradle / Ivy

package com.googlecode.jmeter.plugins.webdriver.config;

import com.googlecode.jmeter.plugins.webdriver.proxy.ProxyFactory;
import com.googlecode.jmeter.plugins.webdriver.proxy.ProxyHostPort;
import com.googlecode.jmeter.plugins.webdriver.proxy.ProxyType;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.jmeter.config.ConfigTestElement;
import org.apache.jmeter.engine.event.LoopIterationEvent;
import org.apache.jmeter.engine.event.LoopIterationListener;
import org.apache.jmeter.testelement.ThreadListener;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.SessionNotFoundException;

public abstract class WebDriverConfig extends ConfigTestElement implements LoopIterationListener, ThreadListener {

    private static final long serialVersionUID = 100L;
    private static final Logger LOGGER = LoggingManager.getLoggerForClass();


    /**
     * This is the key used to store a WebDriver instance in the {@link org.apache.jmeter.threads.JMeterVariables} object.
     */
    public static final String BROWSER = "Browser";

    /**
     * Ideally we would have stored the WebDriver instances in the JMeterVariables object, however the JMeterVariables
     * is cleared BEFORE threadFinished() callback is called (hence would never be able to quit the WebDriver).
     */
    private static final Map webdrivers = new ConcurrentHashMap();

    private static final String PROXY_PAC_URL = "WebDriverConfig.proxy_pac_url";
    private static final String HTTP_HOST = "WebDriverConfig.http_host";
    private static final String HTTP_PORT = "WebDriverConfig.http_port";
    private static final String USE_HTTP_FOR_ALL_PROTOCOLS = "WebDriverConfig.use_http_for_all_protocols";
    private static final String HTTPS_HOST = "WebDriverConfig.https_host";
    private static final String HTTPS_PORT = "WebDriverConfig.https_port";
    private static final String FTP_HOST = "WebDriverConfig.ftp_host";
    private static final String FTP_PORT = "WebDriverConfig.ftp_port";
    private static final String SOCKS_HOST = "WebDriverConfig.socks_host";
    private static final String SOCKS_PORT = "WebDriverConfig.socks_port";
    private static final String NO_PROXY = "WebDriverConfig.no_proxy";
    private static final String PROXY_TYPE = "WebDriverConfig.proxy_type";
    private static final String MAXIMIZE_WINDOW = "WebDriverConfig.maximize_browser";

    /*
     * THE FOLLOWING CONFIGS ARE EXPERIMENTAL AND ARE SUBJECT TO CHANGE/REMOVAL.
     */
    private static final String RECREATE_ON_ITERATION_START = "WebDriverConfig.reset_per_iteration";
    private static final String DEV_MODE = "WebDriverConfig.dev_mode";

    private final transient ProxyFactory proxyFactory;

    protected WebDriverConfig() {
        this(ProxyFactory.getInstance());
    }

    protected WebDriverConfig(ProxyFactory proxyFactory) {
        this.proxyFactory = proxyFactory;
    }

    public void setProxyPacUrl(String pacUrl) {
        setProperty(PROXY_PAC_URL, pacUrl);
    }

    public String getProxyPacUrl() {
        return getPropertyAsString(PROXY_PAC_URL);
    }

    public void setHttpHost(String host) {
        setProperty(HTTP_HOST, host);
    }

    public String getHttpHost() {
        return getPropertyAsString(HTTP_HOST);
    }

    public void setHttpPort(int port) {
        setProperty(HTTP_PORT, port);
    }

    public int getHttpPort() {
        return getPropertyAsInt(HTTP_PORT);
    }

    public void setUseHttpSettingsForAllProtocols(boolean override) {
        setProperty(USE_HTTP_FOR_ALL_PROTOCOLS, override);
    }

    public boolean isUseHttpSettingsForAllProtocols() {
        return getPropertyAsBoolean(USE_HTTP_FOR_ALL_PROTOCOLS, true);
    }

    public void setHttpsHost(String httpsHost) {
        setProperty(HTTPS_HOST, httpsHost);
    }

    public String getHttpsHost() {
        return getPropertyAsString(HTTPS_HOST);
    }

    public void setHttpsPort(int port) {
        setProperty(HTTPS_PORT, port);
    }

    public int getHttpsPort() {
        return getPropertyAsInt(HTTPS_PORT);
    }

    public void setFtpHost(String host) {
        setProperty(FTP_HOST, host);
    }

    public String getFtpHost() {
        return getPropertyAsString(FTP_HOST);
    }

    public void setFtpPort(int port) {
        setProperty(FTP_PORT, port);
    }

    public int getFtpPort() {
        return getPropertyAsInt(FTP_PORT);
    }

    public void setSocksHost(String host) {
        setProperty(SOCKS_HOST, host);
    }

    public String getSocksHost() {
        return getPropertyAsString(SOCKS_HOST);
    }

    public void setSocksPort(int port) {
        setProperty(SOCKS_PORT, port);
    }

    public int getSocksPort() {
        return getPropertyAsInt(SOCKS_PORT);
    }

    public void setNoProxyHost(String noProxyHostList) {
        setProperty(NO_PROXY, noProxyHostList);
    }

    public String getNoProxyHost() {
        return getPropertyAsString(NO_PROXY);
    }

    public void setProxyType(ProxyType type) {
        setProperty(PROXY_TYPE, type.name());
    }

    public ProxyType getProxyType() {
        return ProxyType.valueOf(getPropertyAsString(PROXY_TYPE, ProxyType.SYSTEM.name()));
    }

    public boolean isBrowserMaximized() {
        return getPropertyAsBoolean(MAXIMIZE_WINDOW, false);
    }

    public void setBrowserMaximized(boolean state) {
        setProperty(MAXIMIZE_WINDOW, state);
    }

    /**
     * Call this method to create a {@link Proxy} instance for use when creating a {@link org.openqa.selenium.WebDriver}
     * instance.  The values/settings of the proxy depends entirely on the values set on this config instance.
     *
     * @return a {@link Proxy}
     */
    public Proxy createProxy() {
        switch (getProxyType()) {
            case PROXY_PAC:
                return proxyFactory.getConfigUrlProxy(getProxyPacUrl());
            case DIRECT:
                return proxyFactory.getDirectProxy();
            case AUTO_DETECT:
                return proxyFactory.getAutodetectProxy();
            case MANUAL:
                if (isUseHttpSettingsForAllProtocols()) {
                    ProxyHostPort proxy = new ProxyHostPort(getHttpHost(), getHttpPort());
                    return proxyFactory.getManualProxy(proxy, proxy, proxy, proxy, getNoProxyHost());
                }
                ProxyHostPort http = new ProxyHostPort(getHttpHost(), getHttpPort());
                ProxyHostPort https = new ProxyHostPort(getHttpsHost(), getHttpsPort());
                ProxyHostPort ftp = new ProxyHostPort(getFtpHost(), getFtpPort());
                ProxyHostPort socks = new ProxyHostPort(getSocksHost(), getSocksPort());
                return proxyFactory.getManualProxy(http, https, ftp, socks, getNoProxyHost());
            default:
                return proxyFactory.getSystemProxy();
        }
    }

    @Override
    public void iterationStart(LoopIterationEvent loopIterationEvent) {
        if (isRecreateBrowserOnIterationStart() && !isDevMode()) {
            final T browser = getThreadBrowser();
            quitBrowser(browser);
            setThreadBrowser(getPreparedBrowser());
            LOGGER.info("Created browser object: " + browser);
        }
        getThreadContext().getVariables().putObject(WebDriverConfig.BROWSER, getThreadBrowser());
    }

    @Override
    public void threadStarted() {
        // don't create new browser if there is one there already
        if (hasThreadBrowser()) {
            LOGGER.warn("Thread: " + currentThreadName() + " already has a WebDriver(" + getThreadBrowser() + ") associated with it. ThreadGroup can only contain a single WebDriverConfig.");
            return;
        }

        // create new browser instance
        final T browser = getPreparedBrowser();
        setThreadBrowser(browser);

        // ensures the browser will quit when JVM exits (especially important in devMode)
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                quitBrowser(browser);
            }
        });
    }

    private T getPreparedBrowser() {
        T browser = createBrowser();
        if (isBrowserMaximized()) {
            browser.manage().window().maximize();
        }
        return browser;
    }

    @Override
    public void threadFinished() {
        if (!isDevMode()) {
            final T browser = removeThreadBrowser();
            quitBrowser(browser);
        }
    }


    protected String currentThreadName() {
        return Thread.currentThread().getName();
    }

    /**
     * Creates a new browser at the start of the tests. This method will always return a new instance of a {@link WebDriver}
     * class and is called per thread.
     *
     * @return a new {@link WebDriver} object.
     */
    protected abstract T createBrowser();

    /**
     * Quits browser at the end of the tests. This will be envoked per thread/browser instance created.
     *
     * @param browser is the browser instance to quit. Will not quit if argument is null.
     */
    protected void quitBrowser(final T browser) {
        if (browser != null) {
            try {
                browser.quit();
            } catch (SessionNotFoundException e) {
                LOGGER.warn("Attempting to quit browser instance that has already exited.");
            }
        }
    }

    protected T getThreadBrowser() {
        return (T) webdrivers.get(currentThreadName());
    }

    protected boolean hasThreadBrowser() {
        if (webdrivers.containsKey(currentThreadName())) {
            WebDriver browser = webdrivers.get(currentThreadName());
            try {
                browser.getCurrentUrl();
                return true;
            } catch (Exception ex) {
                LOGGER.warn("Old browser object is inaccessible, will create new", ex);
                webdrivers.remove(currentThreadName());
            }
        }
        return false;
    }

    protected void setThreadBrowser(T browser) {
        if (browser != null) {
            webdrivers.put(currentThreadName(), browser);
        }
    }

    protected T removeThreadBrowser() {
        return (T) webdrivers.remove(currentThreadName());
    }

    void clearThreadBrowsers() {
        webdrivers.clear();
    }

    Map getThreadBrowsers() {
        return webdrivers;
    }

    public boolean isRecreateBrowserOnIterationStart() {
        return getPropertyAsBoolean(RECREATE_ON_ITERATION_START);
    }

    public void setRecreateBrowserOnIterationStart(boolean recreate) {
        setProperty(RECREATE_ON_ITERATION_START, recreate);
    }

    public boolean isDevMode() {
        return getPropertyAsBoolean(DEV_MODE);
    }

    public void setDevMode(boolean devMode) {
        setProperty(DEV_MODE, devMode);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy