org.eclipse.skalli.selenium.utils.DriverProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.skalli.selenium.utils.DriverProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2010-2014 SAP AG and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     SAP AG - initial API and implementation
 *******************************************************************************/
package org.eclipse.skalli.selenium.utils;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import org.apache.commons.io.FileUtils;
import org.eclipse.skalli.selenium.pageobjects.concrete.LoginFailedPage;
import org.eclipse.skalli.selenium.pageobjects.concrete.LoginPage;
import org.eclipse.skalli.selenium.pageobjects.concrete.MainPage;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.support.PageFactory;

import com.thoughtworks.selenium.SeleniumException;

/**
 * The DriverProvider can be used to get a {@link org.openqa.selenium.WebDriver} instance which
 * will be instantiated, started, stopped when the program terminates and which will {@link org.openqa.selenium.WebDriver#get(String)}
 * the base url ({@link #getHTTPBaseUrl()}).
 * <br/>
 * The DriverProvider provides a method to {@link #login(WebDriver)} on the page and a method to be able to navigate to the
 * base url ({@link #navigateToBaseUrl(WebDriver)}).
 */
public class DriverProvider {
    /**
     * The host system property "tomcat.host" or "localhost" by default
     */
    private static final String TOMCAT_HOST = System.getProperty("tomcat.host", "localhost");

    /**
    * The port system property "tomcat.http.port" or "8080" by default
    */
    private static final int TOMCAT_HTTP_PORT = Integer.parseInt(System.getProperty("tomcat.http.port", "8080"));

    /**
     * The folder containing the browser plugins
     */
    private static final File BROWSER_PLUGINS_FOLDER = new File("browser_plugins");

    /**
     * Directory where test content can be copied from
     */
    private static final File TEST_CONTENT_DIR = new File("testdata");

    /**
     * Storage directory for test content
     */
    private static final File STORAGE_DIR = new File("workdir/storage");

    /**
     * The driver
     */
    private static WebDriver driver;

    /**
     * The shutdown hook
     */
    private static Thread shutdownHook = new Thread() {
        @Override
        public void run() {
            stopDriver();
        }
    };

    /**
     * Returns the {@link org.openqa.selenium.WebDriver} instance used for the tests.
     * The driver navigates to the URL returned by  {@link #getHTTPBaseUrl()}
     * @return The {@link org.openqa.selenium.WebDriver} instance used for the tests.
     */
    public static WebDriver getDriver() {
        if (driver == null) {
            startDriver();
        }
        return driver;
    }

    /**
    * Restarts the driver (means it stops the driver and then starts it again).
    * @return The driver to be used now
    */
    public static WebDriver restartDriver() {
        stopDriver();
        startDriver();

        return driver;
    }

    /**
     * Deletes all cookies so the login page can be displayed again
     */
    public static void goToLoginPage() {
        driver.manage().deleteAllCookies();
        navigateToBaseUrl(driver);

        //waits for the login page to be displayed
        LoginPage login = PageFactory.initElements(driver, LoginPage.class);
        login.isDisplayedWithExplicitWait();
    }

    /**
     * Starts the driver, adds a shutdown hook to stop the driver and navigates to {@link #getHTTPBaseUrl()}
     */
    private static void startDriver() {
        FirefoxProfile profile = new FirefoxProfile();

        //load the browser plugins
        if (BROWSER_PLUGINS_FOLDER.exists()) {
            File[] plugins = BROWSER_PLUGINS_FOLDER.listFiles();

            for (int i = 0; i < plugins.length; i++) {
                File plugin = plugins[i];
                String name = plugin.getName();

                if (!name.toLowerCase().contains(".xpi")) {
                    System.err.println("\"" + name + "\" is not a plugin -> remove from " + BROWSER_PLUGINS_FOLDER);
                    continue;
                }

                //pluginName = "firebug-" + FIREBUG_VERSION + ".xpi"
                //pluginName = "firepath-" + FIREPATH_VERSION + "-fx.xpi"

                //set up the plugin if needed
                if (name.toLowerCase().contains("firebug")) {
                    //pluginName = "firebug-" + FIREBUG_VERSION + ".xpi"
                    String version = name.substring("firebug-".length());
                    version = version.substring(0, version.length() - ".xpi".length());

                    //avoids that the first run page is shown
                    profile.setPreference("extensions.firebug.currentVersion", version);
                }

                //add the plugin
                try {
                    profile.addExtension(plugin);
                } catch (IOException e) {
                    System.err.println("could not add extension \"" + name + "\" to the profile\n" + e);
                    e.printStackTrace();
                }
            }
        }

        driver = new FirefoxDriver(profile);
        registerShutdownHook();
        driver.get(getHTTPBaseUrl());

        copyTestContent();
    }

    private static void copyTestContent() {
        try {
            FileUtils.copyDirectory(TEST_CONTENT_DIR, STORAGE_DIR);
        } catch (IOException e) {
            throw new SeleniumException("failed to copy test content", e);
        }
    }

    private static void removeTestContent() {
        try {
            FileUtils.deleteDirectory(STORAGE_DIR);
        } catch (IOException e) {
            throw new SeleniumException("failed to delete test content", e);
        }
    }

    /**
     * Stops the driver
     */
    private static void stopDriver() {
        driver.quit();
        driver = null;
        removeTestContent();
    }

    /**
     * Registers a shutdown hook via {@link Runtime#addShutdownHook(Thread)}
     */
    private static void registerShutdownHook() {
        Runtime.getRuntime().removeShutdownHook(shutdownHook);
        Runtime.getRuntime().addShutdownHook(shutdownHook);
    }

    /**
     * Returns the http base URL
     * @return the http base URL
     */
    private static String getHTTPBaseUrl() {
        return "http://" + TOMCAT_HOST + ":" + TOMCAT_HTTP_PORT;
    }

    /**
     * Navigates to the base url ({@link #getHTTPBaseUrl()})
     * @param driver The driver
     */
    public static void navigateToBaseUrl(WebDriver driver) {
        driver.navigate().to(getHTTPBaseUrl());
    }

    /**
     * Navigates to "{@link #getHTTPBaseUrl()} + {@code subUrl}"
     * @param driver The driver
     * @param subUrl The sub url
     */
    public static void navigateToSubUrl(WebDriver driver, String subUrl) {
        driver.navigate().to(getHTTPBaseUrl() + subUrl);
    }

    /**
     * Try to login with the given user name and password
     * @param driver The {@link org.openqa.selenium.WebDriver}
     * @param username The user name
     * @param password The password
     * @return {@code true} if the login was possible, {@code false} otherwise
     */
    public static boolean login(WebDriver driver, String username, String password) {
        try {
            LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);
            LoginFailedPage loginFailedPage = PageFactory.initElements(driver, LoginFailedPage.class);
            MainPage mainPage = PageFactory.initElements(driver, MainPage.class);

            driver.manage().timeouts().implicitlyWait(500, TimeUnit.MILLISECONDS);
            while (loginPage.isDisplayed()) {
                loginPage.sendKeysToUserNameAndPasswordFieldAndSubmit(username, password);

                driver.manage().timeouts().implicitlyWait(500, TimeUnit.MILLISECONDS);

                //avoiding that the driver is positioned at getHTTPBaseUrl() + "/favicon.ico"
                //maybe a bug!?
                try {
                    if (!loginFailedPage.isDisplayed() && !mainPage.isDisplayed()) {
                        navigateToBaseUrl(driver);
                    }
                } catch (Exception e) {
                }

                //if the login page is displayed the login was successful
                try {
                    if (mainPage.isDisplayed()) {
                        return true;
                    }
                } catch (Exception e) {
                }
            }
        } catch (NoSuchElementException e) {
            return false;
        }

        //should never be reached
        return true;
    }

    /**
     * Try to login with user name = "admin" and password = "admin"
     * @param driver The {@link org.openqa.selenium.WebDriver}
     * @return {@code true} if the login was possible, {@code false} otherwise
     */
    public static boolean login(WebDriver driver) {
        return login(driver, "admin", "admin");
    }

    /**
     * Returns whether the driver is located on the login page or not
     * @param driver The driver
     * @return {@code true} if the driver is on the login page {@code false} otherwise
     */
    public static boolean isOnLoginPage(WebDriver driver) {
        try {
            LoginPage login = PageFactory.initElements(driver, LoginPage.class);
            driver.manage().timeouts().implicitlyWait(500, TimeUnit.MILLISECONDS);
            login.isDisplayed();
        } catch (NoSuchElementException e) {
            return false;
        }

        return true;
    }
}