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

eu.tsystems.mms.tic.testframework.pageobjects.internal.AbstractPage Maven / Gradle / Ivy

The newest version!
/*
 * Testerra
 *
 * (C) 2020, Mike Reiche, T-Systems Multimedia Solutions GmbH, Deutsche Telekom AG
 *
 * Deutsche Telekom AG and all other contributors /
 * copyright owners license this file to you 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 eu.tsystems.mms.tic.testframework.pageobjects.internal;

import eu.tsystems.mms.tic.testframework.annotations.PageOptions;
import eu.tsystems.mms.tic.testframework.common.Testerra;
import eu.tsystems.mms.tic.testframework.enums.CheckRule;
import eu.tsystems.mms.tic.testframework.logging.Loggable;
import eu.tsystems.mms.tic.testframework.pageobjects.AbstractComponent;
import eu.tsystems.mms.tic.testframework.pageobjects.Check;
import eu.tsystems.mms.tic.testframework.pageobjects.Component;
import eu.tsystems.mms.tic.testframework.pageobjects.EmptyUiElement;
import eu.tsystems.mms.tic.testframework.pageobjects.Locator;
import eu.tsystems.mms.tic.testframework.pageobjects.LocatorFactoryProvider;
import eu.tsystems.mms.tic.testframework.pageobjects.Page;
import eu.tsystems.mms.tic.testframework.pageobjects.PageObject;
import eu.tsystems.mms.tic.testframework.pageobjects.UiElement;
import eu.tsystems.mms.tic.testframework.pageobjects.XPath;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.action.AbstractFieldAction;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.action.GuiElementCheckFieldAction;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.action.SetNameFieldAction;
import eu.tsystems.mms.tic.testframework.testing.TestControllerProvider;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;

/**
 * This is an abstract page object used for {@link Page} and {@link AbstractComponent}.
 * Provides basic {@link PageObject} related features:
 * Supports element {@link Check}
 * Supports {@link PageOptions}
 * Livecycle methods for {@link #checkUiElements(CheckRule)}:
 * {@link #checkPagePreparation()}
 * {@link #addCustomFieldActions}
 * 

* {@link #checkPageErrorState(Throwable)} * * @author Peter Lehmann * @author Mike Reiche * @todo Rename to AbstractPageObject * @see {https://martinfowler.com/bliki/PageObject.html} */ public abstract class AbstractPage implements Loggable, TestControllerProvider, PageObject, LocatorFactoryProvider, PageCreator { protected static final PageFactory pageFactory = Testerra.getInjector().getInstance(PageFactory.class); abstract protected UiElement find(Locator locator); abstract protected UiElement findDeep(Locator locator); protected UiElement findById(Object id) { return find(LOCATE.by(By.id(id.toString()))); } protected UiElement findByQa(String qa) { return find(LOCATE.byQa(qa)); } protected UiElement find(By by) { return find(LOCATE.by(by)); } protected UiElement find(XPath xPath) { return find(LOCATE.by(xPath)); } protected UiElement findDeep(XPath xPath) { return findDeep(LOCATE.by(xPath)); } protected UiElement findDeep(By by) { return findDeep(LOCATE.by(by)); } protected UiElement createEmpty() { return createEmpty(LOCATE.by(By.tagName("empty"))); } protected UiElement createEmpty(Locator locator) { return new EmptyUiElement(this, locator); } /** * Package private accessible by {@link PageFactory} */ void checkUiElements() throws Throwable { checkUiElements(CheckRule.DEFAULT); } /** * Package private accessible by {@link PageFactory} */ void checkUiElements(CheckRule checkRule) throws Throwable { /* page checks */ checkPagePreparation(); try { checkAnnotatedFields(checkRule); } catch (Throwable throwable) { // call page error state logic checkPageErrorState(throwable); } pageLoaded(); } public abstract String getName(boolean detailed); /** * Allows pages to run code before performing checkpage */ protected void checkPagePreparation() { } protected void pageLoaded() { } /** * Method entered when checkPage runs into an error (catching any throwable). You can throw a new throwable that * should be stacked onto the checkpage error (like new RuntimeException("bla", throwable) ). * * @param throwable . * @throws Throwable . */ protected void checkPageErrorState(Throwable throwable) throws Throwable { throw throwable; } /** * Gets all @Check annotated fields of a class and executes a webdriver find(). */ private void checkAnnotatedFields(CheckRule checkRule) { List> allClasses = collectAllSuperClasses(); allClasses.forEach(pageClass -> { for (Field field : pageClass.getDeclaredFields()) { field.setAccessible(true); List fieldActions = getFieldActions(field, checkRule, this); fieldActions.forEach(AbstractFieldAction::run); field.setAccessible(false); } }); } protected Optional> addCustomFieldActions(Field field, AbstractPage declaringPage) { return Optional.empty(); } private List getFieldActions(Field field, CheckRule checkRule, AbstractPage declaringPage) { List fieldActions = new ArrayList<>(); SetNameFieldAction setNameFieldAction = new SetNameFieldAction(field, declaringPage); fieldActions.add(setNameFieldAction); addCustomFieldActions(field, declaringPage).ifPresent(fieldActions::addAll); GuiElementCheckFieldAction guiElementCheckFieldAction = new GuiElementCheckFieldAction(field, checkRule, declaringPage); fieldActions.add(guiElementCheckFieldAction); return fieldActions; } /** * Collects all classes in the hierarchy that are sub classes of {@link AbstractPage} */ private List> collectAllSuperClasses() { final LinkedList> allClasses = new LinkedList<>(); allClasses.add(this.getClass()); boolean running = true; /* * Find all superclasses. */ Class clazz = this.getClass(); while (running) { clazz = clazz.getSuperclass(); try { if (clazz == null) { running = false; } else if (clazz == AbstractComponent.class || clazz == Page.class) { /* When the class is on of the abstract implementations, then stop searching here */ break; } else { @SuppressWarnings("unchecked") final Class pageClass = (Class) clazz; allClasses.add(pageClass); } } catch (final ClassCastException e) { running = false; } } return allClasses; } @Override abstract public WebDriver getWebDriver(); protected T createComponent(Class componentClass, UiElement rootElement) { return pageFactory.createComponent(componentClass, rootElement); } @Override public T createPage(final Class pageClass) { return pageFactory.createPage(pageClass, getWebDriver()); } @Override public Optional waitForPage(final Class pageClass, int seconds) { return pageFactory.waitForPage(pageClass, getWebDriver(), seconds); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy