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

io.github.kgress.scaffold.webdriver.BasePage Maven / Gradle / Ivy

package io.github.kgress.scaffold.webdriver;

import io.github.kgress.scaffold.util.AutomationWait;
import io.github.kgress.scaffold.webelements.AbstractWebElement;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.interactions.Actions;

import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * The purpose of this object is to provide a set of common functionality that can be shared across page objects in
 * an implementing project.
 *
 * A common use case for all pages is a form of verification that the page is correct when navigated to. For now, the inclusion
 * of {@link #verifyIsOnPage(AbstractWebElement...)} will be used. As we continue development, we can continue to add functionality here.
 *
 * Note: We should also be very protective about page objects *not* having access to the web driver. The page object, by
 * design, should be agnostic to any relationship with the web driver and only have the knowledge of our strongly typed
 * elements. With access to the web driver, it will be very easy to get carried away with back doors that could break
 * threading for testing.
 */
public abstract class BasePage {

    /**
     * {@link Deprecated} in favor of {@link #verifyIsOnPage(AbstractWebElement...)}. This method will be phased out in the next
     * breaking release.
     *
     * A method to be overridden by the implementing project. Typically, it's best to use elements that are unique to
     * the page object that is being navigated to.
     *
     * @return the {@link Boolean} value to determine if the page is correctly loaded
     */
    @Deprecated
    public abstract boolean isOnPage();

    /**
     * A method that is used to verify a number of elements are displayed on the page when navigating to it. In addition,
     * it will check to ensure the DOM is in a ready and loaded state prior to proceeding. This will help alleviate
     * issues with websites where it takes additional time to load the page due to extraneous db calls or slow loading JS.
     *
     * It's best to use this method in the constructor of the page object as it will be invoked at the time the page is
     * instantiated. For example:
     *
     * 
     * @Getter
     * public class LoginPage() {
     *     private InputWebElement emailInput = new InputWebElement("#email");
     *     private InputWebElement passwordInput = new InputWebElement("#password");
     *
     *     public LoginPage() {
     *         isOnPage(getEmailInput, getPasswordInput);
     *     }
     * }
     * 
* * The elements passed in to this method will be checked by selenium to see if they are displayed. Make sure to pass in * elements that are unique to the page that won't show up on other pages. For example, a login page will have an email * and password input and would pass in those elements as parameters. Don't use elements from headers or a logo that * might appear on all of the pages. * * @param element the element(s) that will be checked if displayed * @return the {@link Boolean} value to determine if the page is correctly loaded */ public Boolean verifyIsOnPage(AbstractWebElement... element) { // Get the list of elements and iterate over them so we can remove any duplicates var listOfElements = Arrays.stream(element) .distinct() //removes duplicates .collect(Collectors.toList()); // Check to make sure the list isn't empty, just in case. We need to at least have one element so we can verify // it's displayed if (listOfElements.isEmpty()) { throw new RuntimeException(String.format("No elements to search for when verifying %s. " + "Please provide at least one element to check it is displayed.", getClass().getSimpleName())); } // The wait condition should wait for the page to load into the complete state. When complete, check to make // sure the elements are displayed. However, if it doesn't (for example, if there's a time out), throw an exception. var isPageLoaded = getAutomationWait().waitUntilPageIsLoaded(); if (isPageLoaded) { listOfElements.forEach(elementOnPage -> { var isDisplayed = elementOnPage.isDisplayed(); if (!isDisplayed) { throw new NoSuchElementException(String.format("Page verification failed. Could not find the element %s for " + "the intended page: %s", elementOnPage.toString(), getClass().getSimpleName())); } }); } return true; } /** * Gets the Selenium based {@link Actions} object for the current thread. This is currently not strongly typed and * should be added in a future update. * * TODO add a strongly typed {@link Actions} object * * @return {@link Actions} */ protected Actions getActions() { return getWebDriverWrapper().getActions(); } /** * Gets the selenium based {@link JavascriptExecutor} for the current thread. * * @return {@link JavascriptExecutor} */ protected JavascriptExecutor getJavascriptExecutor() { return getWebDriverWrapper().getJavascriptExecutor(); } /** * Gets the {@link AutomationWait} from the current thread's {@link WebDriverWrapper} * @return as {@link AutomationWait} */ protected AutomationWait getAutomationWait() { return getWebDriverWrapper().getAutomationWait(); } /** * Gets the {@link WebDriverWrapper} for the current thread. * * @return {@link WebDriverWrapper} */ private WebDriverWrapper getWebDriverWrapper() { return TestContext.baseContext().getWebDriverContext().getWebDriverManager().getWebDriverWrapper(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy