com.flexive.tests.browser.AbstractSeleniumTest.java Source code

Java tutorial

Introduction

Here is the source code for com.flexive.tests.browser.AbstractSeleniumTest.java

Source

/***************************************************************
 *  This file is part of the [fleXive](R) framework.
 *
 *  Copyright (c) 1999-2014
 *  UCS - unique computing solutions gmbh (http://www.ucs.at)
 *  All rights reserved
 *
 *  The [fleXive](R) project is free software; you can redistribute
 *  it and/or modify it under the terms of the GNU Lesser General Public
 *  License version 2.1 or higher as published by the Free Software Foundation.
 *
 *  The GNU Lesser General Public License can be found at
 *  http://www.gnu.org/licenses/lgpl.html.
 *  A copy is found in the textfile LGPL.txt and important notices to the
 *  license from the author are found in LICENSE.txt distributed with
 *  these libraries.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  For further information about UCS - unique computing solutions gmbh,
 *  please see the company website: http://www.ucs.at
 *
 *  For further information about [fleXive](R), please see the
 *  project website: http://www.flexive.org
 *
 *
 *  This copyright notice MUST APPEAR in all copies of the file!
 ***************************************************************/
package com.flexive.tests.browser;

import com.flexive.shared.FxSharedUtils;
import com.thoughtworks.selenium.HttpCommandProcessor;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * Base class for selenium browser tests. Note that a selenium server must
 * be started externally. The server address and port can be set with the
 * properties
 * <code>tests.browser.selenium.host</code> and
 * <code>tests.browser.selenium.port</code> in the <code>browser.properties</code> file.
 *
 * @author Daniel Lichtenberger (daniel.lichtenberger@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
 * @version $Rev$
 */
@Test(groups = "browser")
public abstract class AbstractSeleniumTest {
    private static final Log LOG = LogFactory.getLog(AbstractSeleniumTest.class);

    /**
     * Property for setting the selenium server port
     */
    public static final String PROP_PORT = "tests.browser.selenium.port";
    /**
     * Property for setting the selenium server host IP
     */
    public static final String PROP_HOST = "tests.browser.selenium.host";
    /**
     * The base URL for all tests
     */
    public static final String PROP_BASEURL = "tests.browser.selenium.baseUrl";
    /**
     * The startcommand of the browser
     */
    public static final String PROP_BROWSER_START = "tests.browser.selenium.browserStart";

    protected String initialUrl;
    protected final String configName;
    protected final Properties defaultProperties;

    private static FlexiveSelenium selenium;
    protected HttpCommandProcessor commandProcessor;

    /**
     * Create a browser test for the given initial URL.
     *
     * @param initialUrl The initial URL of the browser. All subsequent open(..) requests will be appended to this URL.
     */
    protected AbstractSeleniumTest(String initialUrl) {
        this(initialUrl, null, null);
    }

    /**
     * Creates a browser test for the given URL and default properties.
     *
     * @param initialUrl        The initial URL of the browser. All subsequent open(..) requests will be appended to this URL.
     * @param defaultProperties Default properties to be used if browser.properties is not available.
     */
    protected AbstractSeleniumTest(String initialUrl, Properties defaultProperties) {
        this(initialUrl, null, defaultProperties);
    }

    /**
     * Creates a browser test for the given URL and the given properties file name.
     *
     * @param initialUrl The initial URL of the browser. All subsequent open(..) requests will be appended to this URL.
     *                   If null, it has to be specified in the properties file specified in the next parameter.
     * @param configName The properties file name to be used for configuring the run-time parameters (default: browser.properties).
     */
    protected AbstractSeleniumTest(String initialUrl, String configName) {
        this(initialUrl, configName, null);
    }

    private AbstractSeleniumTest(String initialUrl, String configName, Properties defaultProperties) {
        this.initialUrl = initialUrl;
        this.configName = configName;
        this.defaultProperties = defaultProperties;
    }

    /**
     * Selenium setup code. Override this method in your actual test class and don't forget
     * to add the @BeforeClass annotation.
     */
    @BeforeClass
    public void beforeClass() {
        final Properties properties = new Properties(defaultProperties);
        if (StringUtils.isNotBlank(configName)) {
            try {
                InputStream inStream = this.getClass().getClassLoader().getResourceAsStream(configName);
                if (inStream == null) {
                    String msg = "Missing " + configName
                            + " file in src/framework/tests/java/com/flexive/tests/browser - copy from provided sample";
                    LOG.error(msg);
                    throw new RuntimeException(msg);
                }
                properties.load(inStream);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        if (this.initialUrl == null) {
            this.initialUrl = (String) properties.get(PROP_BASEURL);
        }
        final int port = Integer.parseInt(properties.getProperty(PROP_PORT, "80"));
        final String host = properties.getProperty(PROP_HOST, "localhost");
        final String browserStart = properties.getProperty(PROP_BROWSER_START, "*firefox");
        if (LOG.isInfoEnabled()) {
            LOG.info("Connecting to Selenium Server at " + host + ":" + port + "...");
            LOG.info("Base URL: " + this.initialUrl);
        }

        /**
         *
         *
         *  *firefox
         *mock
         *firefoxproxy
         *pifirefox
         *chrome
         *iexploreproxy
         *iexplore
         *firefox3
         *safariproxy
         *googlechrome
         *konqueror
         *firefox2
         *safari
         *piiexplore
         *firefoxchrome
         *opera
         *iehta
         */
        //        commandProcessor = new HttpCommandProcessor(host, port, "*iexploreproxy", initialUrl);
        commandProcessor = new HttpCommandProcessor(host, port, browserStart, initialUrl);
        selenium = new FlexiveSelenium(commandProcessor);
        LOG.info("using browser : " + browserStart.substring(1));
        selenium.start();
        selenium.createCookie(FxSharedUtils.COOKIE_FORCE_TEST_DIVISION + "=true", "path=/");
        try {
            LOG.info(selenium.getCookie());
        } catch (Throwable t) {
            LOG.error(t.getMessage());
        }
        //        LOG.error("Create Test-cookie DISABLED!!!");
    }

    /**
     * Selenium shutdown code. Override this method in your actual test class and don't forget
     * to add the @BeforeClass annotation.
     */
    @AfterClass
    public void afterClass() {
        selenium.stop();
    }

    protected void clickAndWait(String clickTarget) {
        clickAndWait_(clickTarget, 30000);
    }

    protected void clickAndWait(String clickTarget, int ms) {
        clickAndWait_(clickTarget, ms);
    }

    /**
     * Clicks multiple times (in case of timeout) on a link
     * <p/>
     * to have always the right stacktrace
     *
     * @param clickTarget
     * @param ms
     */
    private void clickAndWait_(String clickTarget, int ms) {
        int trys = 20;
        ms >>= 3;
        boolean error = false;
        String code = "";
        int errLeft = 5;
        while (trys-- > 0) {
            try {
                selenium.click(clickTarget);
                selenium.waitForPageToLoad("" + ms);
                if (error) {
                    System.err.println(
                            "you ment \"" + clickTarget + "\", but I corrected it for you! [" + code + "]");
                }
                break;
            } catch (Throwable t) {
                if (t.getMessage().endsWith(" not found") && errLeft-- <= 0 && !error) {
                    clickTarget = "link=" + clickTarget;
                    error = true;
                    code = "" + t.getStackTrace()[4];
                }
                sleep(200);
            }
        }
    }

    protected void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            // ignore it
        }
    }

    public static FlexiveSelenium getSeleniumInstance() {
        return selenium;
    }

}