com.sebuilder.interpreter.TestRun.java Source code

Java tutorial

Introduction

Here is the source code for com.sebuilder.interpreter.TestRun.java

Source

/*
* Copyright 2012 Sauce Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.sebuilder.interpreter;

import com.sebuilder.interpreter.webdriverfactory.WebDriverFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openqa.selenium.remote.RemoteWebDriver;

/**
 * A single run of a test script.
 * @author zarkonnen
 */
public class TestRun {
    HashMap<String, String> vars = new HashMap<String, String>();
    Script script;
    protected int stepIndex = -1;
    RemoteWebDriver driver;
    Log log;
    WebDriverFactory webDriverFactory = SeInterpreter.DEFAULT_DRIVER_FACTORY;
    HashMap<String, String> webDriverConfig = new HashMap<String, String>();
    Long implicitlyWaitDriverTimeout;
    Long pageLoadDriverTimeout;

    public Log getLog() {
        return log;
    }

    public RemoteWebDriver getDriver() {
        return driver;
    }

    public Script getScript() {
        return script;
    }

    public TestRun(Script script) {
        this.script = script;
        log = LogFactory.getFactory().getInstance(SeInterpreter.class);
    }

    public TestRun(Script script, int implicitlyWaitDriverTimeout, int pageLoadDriverTimeout) {
        this(script);
        setTimeouts(implicitlyWaitDriverTimeout, pageLoadDriverTimeout);
    }

    public TestRun(Script script, int implicitlyWaitDriverTimeout, int pageLoadDriverTimeout,
            Map<String, String> initialVars) {
        this(script);
        setTimeouts(implicitlyWaitDriverTimeout, pageLoadDriverTimeout);
        vars.putAll(initialVars);
    }

    public TestRun(Script script, Log log) {
        this.script = script;
        this.log = log;
    }

    public TestRun(Script script, Log log, WebDriverFactory webDriverFactory,
            HashMap<String, String> webDriverConfig) {
        this(script, log);
        this.webDriverFactory = webDriverFactory;
        this.webDriverConfig = webDriverConfig;
    }

    public TestRun(Script script, Log log, WebDriverFactory webDriverFactory,
            HashMap<String, String> webDriverConfig, Map<String, String> initialVars) {
        this(script, log);
        this.webDriverFactory = webDriverFactory;
        this.webDriverConfig = webDriverConfig;
        if (initialVars != null) {
            vars.putAll(initialVars);
        }
    }

    public TestRun(Script script, Log log, WebDriverFactory webDriverFactory,
            HashMap<String, String> webDriverConfig, int implicitlyWaitDriverTimeout, int pageLoadDriverTimeout) {
        this(script, log, webDriverFactory, webDriverConfig);
        setTimeouts(implicitlyWaitDriverTimeout, pageLoadDriverTimeout);
    }

    public TestRun(Script script, Log log, WebDriverFactory webDriverFactory,
            HashMap<String, String> webDriverConfig, int implicitlyWaitDriverTimeout, int pageLoadDriverTimeout,
            Map<String, String> initialVars) {
        this(script, log, webDriverFactory, webDriverConfig);
        if (initialVars != null) {
            vars.putAll(initialVars);
        }
        setTimeouts(implicitlyWaitDriverTimeout, pageLoadDriverTimeout);
    }

    public TestRun(Script script, Log log, TestRun previousRun, int implicitlyWaitDriverTimeout,
            int pageLoadDriverTimeout, Map<String, String> initialVars) {
        this(script, log);
        this.driver = previousRun.driver;
        vars.putAll(previousRun.vars);
        if (initialVars != null) {
            vars.putAll(initialVars);
        }
        setTimeouts(implicitlyWaitDriverTimeout, pageLoadDriverTimeout);
    }

    /** @return True if there is another step to execute. */
    public boolean hasNext() {
        boolean hasNext = stepIndex < script.steps.size() - 1;
        if (!hasNext && driver != null && script.closeDriver) {
            log.debug("Quitting driver.");
            driver.quit();
            driver = null;
        }
        return hasNext;
    }

    /**
     * Executes the next step.
     * @return True on success.
     */
    public boolean next() {
        if (stepIndex == -1) {
            log.debug("Starting test run.");
        }

        initRemoteWebDriver();

        log.debug("Running step " + (stepIndex + 2) + ": " + script.steps.get(stepIndex + 1).toPrettyString());
        boolean result = false;
        try {
            result = script.steps.get(++stepIndex).type.run(this);
        } catch (Exception e) {
            throw new RuntimeException(currentStep() + " failed.", e);
        }

        if (!result) {
            // If a verify failed, we just note this but continue.
            if (currentStep().type instanceof Verify) {
                log.error(currentStep() + " failed.");
                return false;
            }
            // In all other cases, we throw an exception to stop the run.
            RuntimeException e = new RuntimeException(currentStep() + " failed.");
            e.fillInStackTrace();
            log.fatal(e);
            throw e;
        } else {
            return true;
        }
    }

    /**
     * Resets the script's progress and closes the driver if needed.
     */
    public void reset() {
        log.debug("Resetting test run.");
        vars.clear();
        stepIndex = -1;
        if (driver != null) {
            driver.quit();
            driver = null;
        }
    }

    /**
     * Runs the entire (rest of the) script.
     * @return True if the script ran successfully, false if a verification failed.
     *         Any other failure throws an exception.
     * @throws RuntimeException if the script failed.
     */
    public boolean finish() {
        boolean success = true;
        try {
            while (hasNext()) {
                success = next() && success;
            }
        } catch (RuntimeException e) {
            // If the script terminates, the driver will be closed automatically.
            if (script.closeDriver) {
                try {
                    driver.quit();
                } catch (Exception e2) {
                }
                driver = null;
            }
            throw e;
        }
        return success;
    }

    /** @return The step that is being/has just been executed. */
    public Step currentStep() {
        return script.steps.get(stepIndex);
    }

    /** @return The driver instance being used. */
    public RemoteWebDriver driver() {
        return driver;
    }

    /** @return The logger being used. */
    public Log log() {
        return log;
    }

    /** @return The HashMap of variables. */
    public HashMap<String, String> vars() {
        return vars;
    }

    /**
     * Fetches a String parameter from the current step.
     * @param paramName The parameter's name.
     * @return The parameter's value.
     */
    public String string(String paramName) {
        String s = currentStep().stringParams.get(paramName);
        if (s == null) {
            throw new RuntimeException("Missing parameter \"" + paramName + "\" at step #" + (stepIndex + 1) + ".");
        }
        // This kind of variable substitution makes for short code, but it's inefficient.
        for (Map.Entry<String, String> v : vars.entrySet()) {
            s = s.replace("${" + v.getKey() + "}", v.getValue());
        }
        return s;
    }

    /**
     * Fetches a Locator parameter from the current step.
     * @param paramName The parameter's name.
     * @return The parameter's value.
     */
    public Locator locator(String paramName) {
        Locator l = new Locator(currentStep().locatorParams.get(paramName));
        if (l == null) {
            throw new RuntimeException("Missing parameter \"" + paramName + "\" at step #" + (stepIndex + 1) + ".");
        }
        // This kind of variable substitution makes for short code, but it's inefficient.
        for (Map.Entry<String, String> v : vars.entrySet()) {
            l.value = l.value.replace("${" + v.getKey() + "}", v.getValue());
        }
        return l;
    }

    /**
     * Initialises remoteWebDriver by invoking factory and set timeouts when
     * needed
     */
    public void initRemoteWebDriver() {
        if (driver == null) {
            log.debug("Initialising driver.");
            try {
                driver = webDriverFactory.make(webDriverConfig);
                if (implicitlyWaitDriverTimeout != null) {
                    driver.manage().timeouts().implicitlyWait(implicitlyWaitDriverTimeout, TimeUnit.SECONDS);
                }
                if (pageLoadDriverTimeout != null) {
                    driver.manage().timeouts().pageLoadTimeout(pageLoadDriverTimeout, TimeUnit.SECONDS);
                }
            } catch (Exception e) {
                throw new RuntimeException("Test run failed: unable to create driver.", e);
            }
        }
    }

    /**
     *
     * @param implicitlyWaitDriverTimeout
     * @param pageLoadDriverTimeout
     */
    private void setTimeouts(int implicitlyWaitDriverTimeout, int pageLoadDriverTimeout) {
        if (implicitlyWaitDriverTimeout > 0) {
            this.implicitlyWaitDriverTimeout = Long.valueOf(implicitlyWaitDriverTimeout);
        }
        if (pageLoadDriverTimeout > 0) {
            this.pageLoadDriverTimeout = Long.valueOf(pageLoadDriverTimeout);
        }
    }
}