org.kitodo.selenium.testframework.pages.Page.java Source code

Java tutorial

Introduction

Here is the source code for org.kitodo.selenium.testframework.pages.Page.java

Source

/*
 * (c) Kitodo. Key to digital objects e. V. <contact@kitodo.org>
 *
 * This file is part of the Kitodo project.
 *
 * It is licensed under GNU General Public License version 3 or later.
 *
 * For the full copyright and license information, please read the
 * GPL3-License.txt file that was distributed with this source code.
 */

package org.kitodo.selenium.testframework.pages;

import static org.awaitility.Awaitility.await;
import static org.kitodo.selenium.testframework.Browser.getRowsOfTable;

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

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.awaitility.core.Predicate;
import org.kitodo.selenium.testframework.Browser;
import org.kitodo.selenium.testframework.Pages;
import org.openqa.selenium.By;
import org.openqa.selenium.NotFoundException;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public abstract class Page<T> {

    private static final Logger logger = LogManager.getLogger(Page.class);

    @SuppressWarnings("unused")
    @FindBy(id = "user-menu")
    private WebElement userMenuButton;

    @SuppressWarnings("unused")
    @FindBy(className = "ui-growl-item-container")
    private WebElement errorPopup;

    @SuppressWarnings("unused")
    @FindBy(className = "ui-messages-error-summary")
    private WebElement errorMessage;

    @SuppressWarnings("unused")
    @FindBy(id = "yesButton")
    private WebElement confirmRemoveButton;

    @SuppressWarnings("unused")
    @FindBy(id = "noButton")
    WebElement cancelRemoveButton;

    @SuppressWarnings("unused")
    @FindBy(id = "headerText")
    private WebElement header;

    @SuppressWarnings("unused")
    @FindBy(id = "search-form:search-field")
    private WebElement searchField;

    @SuppressWarnings("unused")
    @FindBy(id = "search-form:search")
    private WebElement searchButton;

    private String URL;

    Page(String URL) {
        this.URL = URL;
    }

    /**
     * Get page URL.
     *
     * @return page URL
     */
    public String getUrl() {
        return URL;
    }

    abstract public T goTo() throws Exception;

    /**
     * Check if the browser is currently at given page.
     *
     * @return true if browser is at given page
     */
    public boolean isAt() {
        return Browser.getCurrentUrl().contains(URL);
    }

    public boolean isResultSetNotEmpty(List<String> recordTitles) {
        if (recordTitles.isEmpty()) {
            return false;
        } else {
            if (recordTitles.size() == 1) {
                return !recordTitles.get(0).equals("No records found.");
            } else {
                return true;
            }
        }
    }

    /**
     * Check if the browser is currently not at given page.
     *
     * @return true if browser is not at given page
     */
    boolean isNotAt() {
        return !isAt();
    }

    /**
     * Find row matching to give table, click toggle row and return index of
     * found row.
     *
     * @param dataTable
     *            table for search
     * @param objectTitle
     *            searched row
     * @return index of found row
     */
    int triggerRowToggle(WebElement dataTable, String objectTitle) {
        List<WebElement> tableRows = getRowsOfTable(dataTable);

        int index = getRowIndex(dataTable, objectTitle);
        WebElement tableRow = tableRows.get(index);
        tableRow.findElement(By.className("ui-row-toggler")).click();

        return index;
    }

    /**
     * Find row in table matching to give title, return index of found row.
     *
     * @param dataTable
     *            table for search
     * @param objectTitle
     *            searched row
     * @return index of found row
     */
    int getRowIndex(WebElement dataTable, String objectTitle) {
        List<WebElement> tableRows = getRowsOfTable(dataTable);

        for (int i = 0; i < tableRows.size(); i++) {
            WebElement tableRow = tableRows.get(i);
            if (Browser.getCellDataByRow(tableRow, 1).equals(objectTitle)) {
                return i;
            }
        }

        throw new NotFoundException("Row for title " + objectTitle + " was not found!");
    }

    @SuppressWarnings("unchecked")
    T switchToTabByIndex(int index, WebElement tabView) throws Exception {
        if (isNotAt()) {
            goTo();
        }
        clickTab(index, tabView);
        return (T) this;
    }

    private void clickTab(int index, WebElement tabView) {
        List<WebElement> listTabs = tabView.findElements(By.tagName("li"));
        WebElement tab = listTabs.get(index);
        tab.click();
    }

    /**
     * Clicks a button which could be be stale, e.g. because of disabling and
     * enabling via Ajax. After click was performed, the browser waits for
     * redirecting to given url.
     *
     * @param button
     *            the button to be clicked
     * @param url
     *            the url to which is redirected after click
     */
    protected void clickButtonAndWaitForRedirect(WebElement button, String url) {
        WebDriverWait webDriverWait = new WebDriverWait(Browser.getDriver(), 60);
        for (int attempt = 1; attempt < 4; attempt++) {
            try {
                await("Wait for button clicked").pollDelay(700, TimeUnit.MILLISECONDS).atMost(30, TimeUnit.SECONDS)
                        .ignoreExceptions().until(() -> isButtonClicked.matches(button));
                webDriverWait.until(ExpectedConditions.urlContains(url));
                return;
            } catch (TimeoutException e) {
                logger.error("Clicking on button with id " + button.getAttribute("id")
                        + " was not successful. Retrying now.");
            }
        }
        throw new TimeoutException("Could not access button: " + button.getAttribute("id") + "!");
    }

    protected void clickElement(WebElement element) {
        await("Wait for element clicked").pollDelay(500, TimeUnit.MILLISECONDS).atMost(20, TimeUnit.SECONDS)
                .ignoreExceptions().until(() -> isButtonClicked.matches(element));
    }

    /**
     * Get header text.
     *
     * @return value of header text
     */
    public String getHeaderText() {
        return getWebElementText(header);
    }

    /**
     * Get web element text.
     *
     * @param webElement
     *            web element
     * @return text value of web element
     */
    private String getWebElementText(WebElement webElement) {
        return webElement.getText();
    }

    Predicate<WebElement> isButtonClicked = (webElement) -> {
        webElement.click();
        return true;
    };

    Predicate<WebElement> isInputValueNotEmpty = (webElement) -> {
        return !webElement.getAttribute("value").equals("");
    };

    Predicate<File> isFileDownloaded = (file) -> {
        return file.exists();
    };

    void deleteElement(String objectType, int removableID, int tabIndex, WebElement tabView) throws Exception {
        if (!isAt()) {
            goTo();
        }
        switchToTabByIndex(tabIndex, tabView);
        Browser.getDriver()
                .findElement(By.xpath("//a[@href='/kitodo/pages/" + objectType.toLowerCase() + "Edit.jsf?id="
                        + removableID + "']/following-sibling::a[@id[contains(., 'delete" + objectType + "')]]"))
                .click();
        await("Wait for 'confirm delete' dialog to be displayed")
                .atMost(Browser.getDelayAfterDelete(), TimeUnit.MILLISECONDS).ignoreExceptions()
                .until(() -> confirmRemoveButton.isDisplayed());
        confirmRemoveButton.click();
        Thread.sleep(Browser.getDelayAfterDelete());
        WebDriverWait wait = new WebDriverWait(Browser.getDriver(), 60);
        wait.until(ExpectedConditions.urlContains(getUrl()));
    }

    /**
     * Searches in the header-searchfield with the given query.
     * @param query the input to search for.
     * @throws Exception if Page could not be instantiated.
     */
    public void searchInSearchField(String query) throws Exception {
        searchField.clear();
        searchField.sendKeys(query);
        clickButtonAndWaitForRedirect(searchButton, Pages.getSearchResultPage().getUrl());
    }
}