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

com.github.fscheffer.arras.test.ArrasTestCase Maven / Gradle / Ivy

package com.github.fscheffer.arras.test;

import java.util.List;

import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeMethod;

public abstract class ArrasTestCase {

    private static final Logger          logger        = LoggerFactory.getLogger(ArrasTestCase.class);

    private static final TestContextPool pool          = new TestContextPool();

    private PerThreadTestContext         threadContext = new PerThreadTestContext();

    @BeforeMethod
    protected void setup() {

        logger.debug("Setting up");

        try {
            if (this.threadContext.get() != null) {
                throw new IllegalStateException();
            }

            DesiredCapabilities capabilities = ArrasTestUtils.getDesiredCapabilities();

            this.threadContext.set(pool.aquire(capabilities));
        }
        catch (Exception e) {
            logger.error("Exception: ", e);
        }
    }

    @AfterMethod(alwaysRun = true)
    protected void cleanup() {

        logger.debug("Cleaning up");

        TestContext context = this.threadContext.get();
        if (context == null) {
            // looks like a listener killed the driver, so nothing to do for us.
            return;
        }

        try {
            pool.release(context);
            this.threadContext.set(null);
        }
        catch (Exception e) {
            logger.error("Exception: ", e);
        }
    }

    @AfterSuite(alwaysRun = true)
    protected void terminate() {
        pool.terminate();
    }

    protected final WebDriver driver() {
        return this.threadContext.get().getDriver();
    }

    protected final void open(String url) {

        String baseUrl = this.threadContext.get().getBaseUrl();

        String completeUrl = ArrasTestUtils.appendPath(baseUrl, url);
        driver().get(completeUrl);

        waitUntil(pageHasLoaded());
    }

    protected final void click(String cssSelector) {
        element(cssSelector).click();
    }

    protected final void sendKeys(String cssSelector, CharSequence... keysToSend) {
        element(cssSelector).sendKeys(keysToSend);
    }

    protected final void sendKeys(CharSequence keysToSend) {
        driver().switchTo().activeElement().sendKeys(keysToSend);
    }

    protected final void text(String cssSelector, String text) {

        WebElement element = element(cssSelector);

        element.click();

        // ensure that the right element is focused before we change the value
        waitUntil(focused(cssSelector));

        element.clear();
        element.sendKeys(text);

        // remove non printable characters
        waitUntil(valueContainsText(cssSelector, text.replaceAll("\\p{C}", "")));
    }

    protected final String text(String cssSelector) {
        return element(cssSelector).getText();
    }

    protected final void select(String cssSelector, String value) {

        Select select = new Select(element(cssSelector));
        select.selectByValue(value);
    }

    protected final WebElement element(String cssSelector) {
        return element(By.cssSelector(cssSelector));
    }

    protected final WebElement element(By by) {
        return driver().findElement(by);
    }

    protected final List elements(String cssSelector) {
        return driver().findElements(By.cssSelector(cssSelector));
    }

    protected final String attr(String cssSelector, String attribute) {
        return element(cssSelector).getAttribute(attribute);
    }

    protected final String title() {
        return driver().getTitle();
    }

    protected final Dimension viewport() {

        JavascriptExecutor executor = JavascriptExecutor.class.cast(driver());

        Number clientWidth = (Number) executor.executeScript("return document.documentElement.clientWidth");
        Number clientHeight = (Number) executor.executeScript("return document.documentElement.clientHeight");

        return new Dimension(clientWidth.intValue(), clientHeight.intValue());
    }

    protected final void hover(String cssSelector) {
        moveTo(cssSelector);
    }

    protected final void moveTo(String cssSelector) {
        new Actions(driver()).moveToElement(element(cssSelector)).perform();
    }

    protected final String css(String cssSelector, String property) {

        WebElement element = element(cssSelector);

        try {
            String value = element.getCssValue(property);
            if (value != null) {
                return value;
            }
            // null indicates the property is not present (or unknown), trying fallback.
        }
        catch (WebDriverException e) {
            // can happen when the browser does not support the property, trying fallback.
        }

        return element.getCssValue(findBrowserPrefix() + property);
    }

    private String findBrowserPrefix() {

        String browserName = this.threadContext.get().getCapabilities().getBrowserName();

        if (BrowserType.CHROME.equals(browserName) || BrowserType.GOOGLECHROME.equals(browserName)
            || BrowserType.SAFARI.equals(browserName)) {
            return "-webkit-";
        }

        if (BrowserType.FIREFOX.equals(browserName)) {
            return "-moz-";
        }

        if (BrowserType.IE.equals(browserName) || BrowserType.IEXPLORE.equals(browserName)) {
            return "-ms-";
        }

        throw new IllegalStateException("No css prefix for unknown browser " + browserName + "!");
    }

    protected static final ExpectedCondition pageHasLoaded() {
        return ArrasConditions.pageHasLoaded();
    }

    protected static final ExpectedCondition focused(String cssSelector) {
        return ArrasConditions.focusOnElementLocated(By.cssSelector(cssSelector));
    }

    protected static final ExpectedCondition attributeHasValue(String cssSelector, String name, String value) {
        return ArrasConditions.attributeHasValueOnElementLocated(By.cssSelector(cssSelector), name, value);
    }

    protected static final ExpectedCondition> present(String cssSelector) {
        return ArrasConditions.presenceOfElementsLocated(By.cssSelector(cssSelector));
    }

    protected static final ExpectedCondition> visible(String cssSelector) {
        return ArrasConditions.visibiltyOfElementsLocated(By.cssSelector(cssSelector));
    }

    protected static final ExpectedCondition> count(String cssSelector, int count) {
        return ArrasConditions.countOfElementsLocated(By.cssSelector(cssSelector), count);
    }

    protected static final ExpectedCondition invisible(String cssSelector) {
        return ExpectedConditions.invisibilityOfElementLocated(By.cssSelector(cssSelector));
    }

    protected static final ExpectedCondition containsText(String cssSelector, String text) {
        return ExpectedConditions.textToBePresentInElementLocated(By.cssSelector(cssSelector), text);
    }

    protected static final ExpectedCondition equalsText(String cssSelector, String text) {
        return ArrasConditions.textToBeEqualInElementLocated(By.cssSelector(cssSelector), text);
    }

    protected static final ExpectedCondition notContainsText(String cssSelector, String text) {
        return ExpectedConditions.not(containsText(cssSelector, text));
    }

    protected static final ExpectedCondition valueContainsText(String cssSelector, String text) {
        return ExpectedConditions.textToBePresentInElementValue(By.cssSelector(cssSelector), text);
    }

    protected static final ExpectedCondition classesPresent(String cssSelector, String... classes) {
        return ArrasConditions.presenceOfClasses(By.cssSelector(cssSelector), classes);
    }

    protected static final ExpectedCondition classesNotPresent(String cssSelector, String... classes) {
        return ArrasConditions.absenceOfClasses(By.cssSelector(cssSelector), classes);
    }

    protected static final ExpectedCondition attributeContains(String cssSelector, String attrName,
                                                                        String value) {
        return ArrasConditions.textToBePresentInAttribute(By.cssSelector(cssSelector), attrName, value);
    }

    protected final  T waitUntil(ExpectedCondition condition) {
        // Note: 10 sec is sometimes not enough
        int timeOutInSeconds = 45;
        int sleepInMillis = 200;
        return new WebDriverWait(driver(), timeOutInSeconds, sleepInMillis).until(condition);
    }

    /**
     * Waits until all active XHR requests (as noted by the t5/core/dom module)
     * have completed.
     *
     * @since 5.4
     */
    protected final void waitForAjaxRequestsToComplete() {
        // Ugly but necessary. Give the Ajax operation sufficient time to execute normally, then start
        // polling to see if it has complete.
        sleep(250);

        // The t5/core/dom module tracks how many Ajax requests are active
        // and body[data-ajax-active] as appropriate.

        try {
            waitUntil(present("body[data-ajax-active='0']"));
        }
        catch (TimeoutException e) {
            throw new AssertionError("Ajax request did not complete within 30 seconds.");
        }
    }

    /**
     * Sleeps for the indicated number of seconds.
     */
    protected final void sleep(long millis) {
        try {
            Thread.sleep(millis);
        }
        catch (InterruptedException ex) {
            // Ignore.
        }
    }

    /**
     * Formats a message from the provided arguments, which is written to System.err. In addition,
     * captures the AUT's markup, screenshot, and a report to the output directory.
     *
     * @param message
     * @param arguments
     * @since 5.4
     */
    protected final void reportAndThrowAssertionError(String message, Object... arguments) {
        StringBuilder builder = new StringBuilder(5000);

        String formatted = String.format(message, arguments);

        builder.append(formatted);

        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

        StringBuilder buffer = new StringBuilder(5000);

        boolean enabled = false;

        for (StackTraceElement e : stackTrace) {
            if (enabled) {
                buffer.append("\n- ");
                buffer.append(e);
                continue;
            }

            if (e.getMethodName().equals("reportAndThrowAssertionError")) {
                enabled = true;
            }
        }

        writeErrorReport(builder.toString());

        throw new AssertionError(formatted);
    }

    protected void writeErrorReport(String reportText) {
        logger.error(reportText);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy