com.formkiq.web.SeleniumTestBase.java Source code

Java tutorial

Introduction

Here is the source code for com.formkiq.web.SeleniumTestBase.java

Source

/*
 * Copyright (C) 2017 FormKiQ Inc.
 *
 * 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.formkiq.web;

import static com.formkiq.core.util.Strings.extractLabelAndValue;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.SystemUtils;
import org.junit.AfterClass;
import org.junit.Before;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;

import com.google.common.base.Predicate;

/**
 * Selenium Integration Base Class.
 *
 */
public class SeleniumTestBase extends AbstractIntegrationTest {

    /** Time out in Seconds. */
    protected static final long TIMEOUT = 10;

    /** WebDriver. */
    private static WebDriver driver;

    /** Whether Selenium is initialized. */
    private static boolean isInitialized = false;

    /**
     * after().
     */
    @AfterClass
    public static void afterClass() {
        if (driver != null) {
            driver.quit();
            isInitialized = false;
        }
    }

    /**
     * Create Chrome Driver.
     */
    protected static void initializeChromeDriver() {

        String path = "src/test/resources/selenium/chromedriver";

        if (SystemUtils.IS_OS_WINDOWS) {
            path += ".exe";
        }

        System.setProperty("webdriver.chrome.driver", path);

        ChromeOptions options = new ChromeOptions();
        options.setHeadless(true);
        driver = new ChromeDriver(options);
        isInitialized = true;
    }

    /**
     * assert {@link WebElement} does not exist.
     * @param by {@link By}
     */
    protected void assertNoSuchElement(final By by) {

        try {
            getDriver().findElement(by);
            fail();
        } catch (NoSuchElementException e) {
            // element does not exist
        }
    }

    /**
     * Assert Rows Match.
     *
     * @param elements {@link List}
     * @param texts {@link List}
     */
    protected void assertRowEquals(final List<WebElement> elements, final List<String> texts) {

        assertEquals(elements.size(), texts.size());
        for (int i = 0; i < elements.size(); i++) {
            assertEquals(elements.get(i).getText().trim(), texts.get(i).trim());
        }
    }

    @Override
    @Before
    public void before() throws Exception {
        super.before();
        initializeSelenium();
    }

    /**
     * @param by {@link By}
     * @return {@link WebElement}
     */
    public WebElement findElementBy(final By by) {
        //        getWait().until(ExpectedConditions.presenceOfElementLocated(by));
        waitUntil(new Predicate<WebDriver>() {
            @Override
            public boolean apply(final WebDriver d) {
                try {
                    getDriver().findElement(by);
                    return true;
                } catch (Exception e) {
                    return false;
                }
            }
        });

        getWait().until(ExpectedConditions.visibilityOfElementLocated(by));
        return getDriver().findElement(by);
    }

    /**
     * Find Element by type and name.
     * @param type {@link String}
     * @param attribute {@link String}
     * @param name {@link String}
     * @return {@link WebElement}
     */
    public WebElement findElementBy(final String type, final String attribute, final String name) {
        return findElementBy(getBy(type, attribute, name));
    }

    /**
     * Find Element by type and name.
     * @param type {@link String}
     * @param attribute {@link String}
     * @param name {@link String}
     * @return {@link List} of {@link WebElement}
     */
    public List<WebElement> findElementsBy(final String type, final String attribute, final String name) {
        return findElements(getBy(type, attribute, name));
    }

    /**
     * Find Element by name.
     * @param name {@link String}
     * @return {@link WebElement}
     */
    public WebElement findElementByName(final String name) {
        return findElementBy("*", "name", name);
    }

    /**
     * @param by {@link By}
     * @return {@link WebElement}
     */
    public List<WebElement> findElements(final By by) {
        getWait().until(ExpectedConditions.presenceOfElementLocated(by));
        getWait().until(ExpectedConditions.visibilityOfElementLocated(by));
        return getDriver().findElements(by);
    }

    /**
     * Find Element by type and name.
     * @param type {@link String}
     * @param attribute {@link String}
     * @param name {@link String}
     * @return {@link List} of {@link WebElement}
     */
    public List<WebElement> findElements(final String type, final String attribute, final String name) {
        return findElements(getBy(type, attribute, name));
    }

    /**
     * Find Elements with text.
     * @param by {@link By}
     * @return {@link List}
     */
    protected List<WebElement> findElementsWithText(final By by) {

        List<WebElement> list = new ArrayList<>();

        List<WebElement> elements = findElements(by);
        for (WebElement element : elements) {
            if (!isEmpty(element.getText())) {
                list.add(element);
            }
        }

        return list;
    }

    /**
     * Find Match Option.
     * @param select {@link Select}
     * @param value {@link String}
     * @return int
     */
    public int findMatchOption(final Select select, final String value) {

        int i = -1;
        for (WebElement e : select.getOptions()) {
            i++;
            String v = extractLabelAndValue(e.getAttribute("value")).getRight();
            if (v.equals(value)) {
                break;
            }
        }

        return i;
    }

    /**
     * @param type {@link String}
     * @param attribute {@link String}
     * @param name {@link String}
     * @return {@link By}
     */
    protected By getBy(final String type, final String attribute, final String name) {
        return By.xpath("//" + type + "[@" + attribute + "='" + name + "']");
    }

    /**
     * @return {@link String}
     */
    protected String getCurrentUrl() {
        return getDriver().getCurrentUrl();
    }

    /**
     * @return {@link WebDriver}
     */
    public WebDriver getDriver() {
        return driver;
    }

    /**
     * Get Page Source.
     * @return {@link String}
     */
    protected String getPageSource() {
        return getDriver().getPageSource();
    }

    /**
     * Get {@link Select} selected index.
     * @param select {@link Select}
     * @return int
     */
    public int getSelectedIndex(final Select select) {
        List<WebElement> list = select.getOptions();

        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getText().equals(select.getFirstSelectedOption().getText())) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Get Selected Value.
     * @param element {@link WebElement}
     * @return {@link String}
     */
    public String getSelectedValue(final WebElement element) {
        Select select = new Select(element);
        String v = extractLabelAndValue(select.getFirstSelectedOption().getAttribute("value")).getRight();
        return v;
    }

    /**
     * Get Table Row Count.
     * @param tableid {@link String}
     * @return int
     */
    protected int getTableRowCount(final String tableid) {
        return findElements(By.xpath("//table[@id='" + tableid + "']/tbody/tr")).size();
    }

    /**
     * Get Page Title.
     * @return {@link String}
     */
    protected String getTitle() {
        return getDriver().getTitle();
    }

    /**
     * @return {@link WebDriverWait}
     */
    public WebDriverWait getWait() {
        return getWait(TIMEOUT);
    }

    /**
     * @param timeOutInSeconds long
     * @return {@link WebDriverWait}
     */
    public WebDriverWait getWait(final long timeOutInSeconds) {
        WebDriverWait block = new WebDriverWait(getDriver(), timeOutInSeconds);
        return block;
    }

    /**
     * initializes selneium.
     */
    protected void initializeSelenium() {

        if (!isInitialized) {
            initializeChromeDriver();
        }

        driver.manage().deleteAllCookies();
    }

    /**
     *
     * @param email {@link String}
     */
    @Override
    public String login(final String email) {

        String loginURL = getDefaultHostAndPort() + "/login";
        getDriver().get(loginURL);

        if (driver.getCurrentUrl().endsWith("/login")) {

            WebElement element = findElementBy(By.name("username"));
            element.sendKeys(email);

            element = findElementBy(By.name("password"));
            element.sendKeys(getDefaultPass());

            element.submit();
        }

        return null;
    }

    /**
     * logs user out.
     */
    public void logout() {
        getDriver().get(getDefaultHostAndPort() + "/logout");
        assertEquals("FormKiQ Server - Login", getDriver().getTitle());
        getDriver().manage().deleteAllCookies();
    }

    /**
     * Select from selectbox.
     * @param dataformid {@link String}
     * @param index int
     */
    public void selectByIndex(final String dataformid, final int index) {
        new Select(findElementBy("select", "data-fieldid", dataformid)).selectByIndex(index);
    }

    /**
     * Select from selectbox.
     * @param dataformid {@link String}
     * @param value {@link String}
     */
    public void selectByValue(final String dataformid, final String value) {

        WebElement ele = findElementBy("select", "data-fieldid", dataformid);
        Select sel = new Select(ele);

        int index = findMatchOption(sel, value);
        sel.selectByIndex(index);
    }

    /**
     * Waiting for JQuery to Load.
     * @return boolean
     */
    @SuppressWarnings("boxing")
    public boolean waitForJSandJQueryToLoad() {

        WebDriverWait wait = new WebDriverWait(getDriver(), TIMEOUT);

        // wait for jQuery to load
        ExpectedCondition<Boolean> jQuery = new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(final WebDriver webdriver) {
                try {
                    return ((Long) ((JavascriptExecutor) webdriver).executeScript("return jQuery.active") == 0);
                } catch (Exception e) {
                    // no jQuery present
                    return true;
                }
            }
        };

        // wait for Javascript to load
        ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(final WebDriver webdriver) {
                return ((JavascriptExecutor) webdriver).executeScript("return document.readyState").toString()
                        .equals("complete");
            }
        };

        return wait.until(jQuery) && wait.until(jsLoad);
    }

    /**
     * Wait for.
     * @param predicate {@link Predicate}
     */
    protected void waitUntil(final Predicate<WebDriver> predicate) {
        new FluentWait<>(getDriver()).withTimeout(TIMEOUT, TimeUnit.SECONDS)
                .pollingEvery(TIMEOUT, TimeUnit.MILLISECONDS).until(predicate);
    }

    /**
     * Wait for Page Text.
     * @param text {@link String}
     */
    protected void waitUntilPageSourceText(final String text) {
        waitUntil(new Predicate<WebDriver>() {
            @Override
            public boolean apply(final WebDriver d) {
                return d.getPageSource().contains(text);
            }
        });
    }

    /**
     * Wait for Page Text.
     * @param by {@link By}
     */
    protected void click(final By by) {
        waitUntil(new Predicate<WebDriver>() {
            @Override
            public boolean apply(final WebDriver d) {
                try {
                    findElementBy(by).click();
                    return true;
                } catch (WebDriverException e) {
                    return false;
                }
            }
        });
    }

    /**
     * Wait for Page Text.
     * @param by {@link By}
     * @param className {@link String}
     */
    protected void waitUntilClassName(final By by, final String className) {
        waitUntil(new Predicate<WebDriver>() {
            @Override
            public boolean apply(final WebDriver d) {
                return d.findElement(by).getAttribute("class").equals(className);
            }
        });
    }

    /**
     * Wait until Select Options appear.
     * @param select {@link Select}
     */
    protected void waitUntilSelectOptionsPopulated(final Select select) {
        waitUntil(new Predicate<WebDriver>() {
            @Override
            public boolean apply(final WebDriver d) {
                return (select.getOptions().size() > 1);
            }
        });
    }
}