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

eu.tsystems.mms.tic.testframework.pageobjects.GuiElement Maven / Gradle / Ivy

There is a newer version: 2.10
Show newest version
/*
 * Testerra
 *
 * (C) 2020, Peter Lehmann, 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;

import eu.tsystems.mms.tic.testframework.common.Testerra;
import eu.tsystems.mms.tic.testframework.execution.testng.Assertion;
import eu.tsystems.mms.tic.testframework.execution.testng.CollectedAssertion;
import eu.tsystems.mms.tic.testframework.execution.testng.InstantAssertion;
import eu.tsystems.mms.tic.testframework.execution.testng.OptionalAssertion;
import eu.tsystems.mms.tic.testframework.internal.Nameable;
import eu.tsystems.mms.tic.testframework.internal.NameableChild;
import eu.tsystems.mms.tic.testframework.internal.asserts.PropertyAssertionConfig;
import eu.tsystems.mms.tic.testframework.logging.Loggable;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.DefaultLocator;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.UiElementFactory;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.asserts.DefaultUiElementAssertion;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.asserts.GuiElementAssert;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.asserts.GuiElementAssertDescriptionDecorator;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.asserts.LegacyGuiElementAssertWrapper;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.asserts.PerformanceTestGuiElementAssert;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.asserts.UiElementAssertion;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.AbstractGuiElementCore;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.GuiElementCore;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.GuiElementCoreSequenceDecorator;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.core.GuiElementData;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.facade.DelayActionsGuiElementFacade;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.facade.UiElementLogger;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.waiters.DefaultGuiElementWait;
import eu.tsystems.mms.tic.testframework.pageobjects.internal.waiters.GuiElementWait;
import eu.tsystems.mms.tic.testframework.report.Report;
import eu.tsystems.mms.tic.testframework.testing.WebDriverManagerProvider;
import eu.tsystems.mms.tic.testframework.webdriver.WebDriverFactory;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.awt.Color;
import java.io.File;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * GuiElement is the access point for most tests and is an extension of WebElement.
 * 

* Authors: pele, rnhb */ public class GuiElement implements UiElement, NameableChild, Loggable, WebDriverManagerProvider { /** * Factory required for {@link UiElementFinder} */ private static final UiElementFactory uiElementFactory = Testerra.getInjector().getInstance(UiElementFactory.class); /** * Get lazy initialized by {@link #asserts()} * Is one of: * {@link #collectableAssert} * {@link #instantAssert} */ private GuiElementAssert defaultAssert; /** * Gets lazy initialized by {@link #instantAsserts()} */ private GuiElementAssert instantAssert; /** * Gets lazy initialized by {@link #assertCollector()} */ private GuiElementAssert collectableAssert; /** * Gets lazy initialized by {@link #nonFunctionalAssert} */ private GuiElementAssert nonFunctionalAssert; /** * This is the raw core implementation of {@link GuiElementCore} */ private final GuiElementCore core; /** * Contains the elements base information and the {@link GuiElementData} hierarchy only. */ private final GuiElementData guiElementData; /** * This facade contains * {@link #core} * {@link GuiElementCoreSequenceDecorator} * {@link UiElementLogger} * {@link DelayActionsGuiElementFacade} */ private GuiElementCore decoratedCore; private GuiElementWait decoratedWait; /** * Contains the {@link Nameable} hierarchy for {@link UiElement} and {@link PageObject}. */ private Nameable parent; /** * Elementary constructor */ private GuiElement(GuiElementData data) { guiElementData = data; guiElementData.setGuiElement(this); WebDriverFactory factory = WEB_DRIVER_MANAGER.getWebDriverFactoryForBrowser(WEB_DRIVER_MANAGER.getRequestedBrowser(guiElementData.getWebDriver()).orElse(null)); this.core = factory.createCore(guiElementData); } protected GuiElement(GuiElementData data, GuiElementCore core) { this.guiElementData = data; guiElementData.setGuiElement(this); this.core = core; } /** * Package private constructor for list elements of {@link UiElementList}. * Elements created by this constructor are identical to it's parent, * but with a different element index. */ GuiElement(GuiElement guiElement, int index) { this(new GuiElementData(guiElement.guiElementData, index)); setParent(guiElement.getParent()); createDecorators(); } /** * Package private constructor for {@link UiElementFactory#createFromParent(UiElement, Locator)} * This is the internal standard constructor for elements with parent {@link GuiElementCore} implementations. */ GuiElement(GuiElementCore core) { this.core = core; AbstractGuiElementCore realCore = (AbstractGuiElementCore) core; guiElementData = realCore.guiElementData; guiElementData.setGuiElement(this); createDecorators(); } /** * @deprecated Use {@link UiElementFactory#createWithWebDriver(WebDriver, Locator)}} instead */ @Deprecated public GuiElement(WebDriver driver, Locator locator) { this(new GuiElementData(driver, locator)); guiElementData.setGuiElement(this); createDecorators(); } /** * @deprecated Use {@link UiElementFactory#createWithWebDriver(WebDriver, Locator)}} instead */ @Deprecated public GuiElement(WebDriver driver, By by) { this(driver, LOCATE.by(by)); } /** * Returns the raw core without any decorators */ public GuiElementCore getCore() { return this.core; } public GuiElementData getData() { return this.guiElementData; } @Override public Locator getLocator() { return guiElementData.getLocate(); } /** * We cannot use the GuiElementFactory for decorating the facade here, * since GuiElement is not always created by it's according factory * and implementing a GuiElementFacadeFactory is useless. * You can move this code to DefaultGuiElementFactory when no more 'new GuiElement()' calls exists. */ private void createDecorators() { // Wrap the core with sequence decorator, such that its methods are executed with sequence GuiElementCore sequenceCore = new GuiElementCoreSequenceDecorator(core); decoratedCore = new UiElementLogger(sequenceCore, this); int delayAfterAction = Properties.DELAY_AFTER_ACTION_MILLIS.asLong().intValue(); int delayBeforeAction = Properties.DELAY_BEFORE_ACTION_MILLIS.asLong().intValue(); if (delayAfterAction > 0 || delayBeforeAction > 0) { decoratedCore = new DelayActionsGuiElementFacade(decoratedCore, delayBeforeAction, delayAfterAction); } } /** * After retrieving all WebElements of the given locator, this method can be used to filter the WebElements. * Different filters can be applied in conjunction (and). * * @param filter Filters to be applied * @return The same GuiElement * @deprecated Use {@link DefaultLocator} instead */ @Deprecated public GuiElement withWebElementFilter(Predicate filter) { guiElementData.getLocate().filter(filter); return this; } /** * Add a Decorator to log every action performed on this element with addition to a short description of it. * * @param description A very short description of this GuiElement, for example "Continue Shopping Button" * @deprecated Use {@link #setName(String)} instead */ @Deprecated public GuiElement setDescription(String description) { guiElementData.setName(description); return this; } /** * Get sub element by locator. Using this executes a find on the parent element and the parent.findElement for the * given locator. It does not wait for the subelement if the parent has been found! * * @param by Locator of new element. * @return GuiElement */ @Deprecated public GuiElement getSubElement(By by) { return getSubElement(by, null); } /** * Get sub element by locator. Using this executes a find on the parent element and the parent.findElement for the * given locator. It does not wait for the subelement if the parent has been found! * * @param by Locator of new element. * @param description Description for GuiElement * @return GuiElement */ @Deprecated public GuiElement getSubElement(By by, String description) { GuiElement subElement = getSubElement(LOCATE.by(by)); if (description != null) subElement.setName(description); return subElement; } @Deprecated public GuiElement getSubElement(Locator locator) { return (GuiElement) find(locator); } @Override public UiElement scrollIntoView(Point offset) { decoratedCore.scrollIntoView(offset); return this; } @Override public UiElement scrollToTop() { decoratedCore.scrollToTop(); return this; } @Deprecated public By getBy() { return guiElementData.getLocate().getBy(); } @Deprecated public UiElement scrollToElement() { decoratedCore.scrollToElement(); return this; } @Deprecated public UiElement scrollToElement(int yOffset) { decoratedCore.scrollToElement(yOffset); return this; } @Override public UiElement select() { decoratedCore.select(); return this; } @Override public UiElement deselect() { decoratedCore.deselect(); return this; } @Override public UiElement type(String text) { decoratedCore.type(text); return this; } @Override public UiElement click() { decoratedCore.click(); return this; } @Override public UiElement submit() { decoratedCore.submit(); return this; } @Override public UiElement sendKeys(CharSequence... charSequences) { decoratedCore.sendKeys(charSequences); return this; } // @Override // public InteractiveUiElement asUser() { // if (this.userSimulator==null) { // this.userSimulator = new UserSimulator(this); // } // return this.userSimulator; // } /** * @deprecated This method is no longer acceptable as a part of GuiElement. * Use {@link eu.tsystems.mms.tic.testframework.webdrivermanager.DesktopWebDriverUtils#clickAbsolute()} instead */ @Override public UiElement clear() { decoratedCore.clear(); return this; } /** * @deprecated This method is no longer acceptable as a part of GuiElement. * Use {@link eu.tsystems.mms.tic.testframework.webdrivermanager.DesktopWebDriverUtils#mouseOverAbsolute2Axis()} instead */ @Override public InteractiveUiElement hover() { return mouseOver(); } @Deprecated public String getTagName() { return decoratedCore.getTagName(); } @Deprecated public String getAttribute(String attributeName) { return decoratedCore.getAttribute(attributeName); } @Deprecated public boolean isSelected() { return decoratedCore.isSelected(); } @Deprecated public boolean isEnabled() { return decoratedCore.isEnabled(); } @Deprecated public String getText() { return decoratedCore.getText(); } @Deprecated public boolean isDisplayed() { return decoratedCore.isDisplayed(); } @Deprecated public boolean isVisible(final boolean complete) { return decoratedCore.isVisible(complete); } /** * Checks if the element is selectable. *

* WARNING: To determine if the element is truly selectable, a selection or deselection will be done and reverted. * Keep this in mind. * * @return true, if the element is selectable. */ @Deprecated public boolean isSelectable() { return decoratedCore.isSelectable(); } @Deprecated public Point getLocation() { return decoratedCore.getLocation(); } @Deprecated public Dimension getSize() { return decoratedCore.getSize(); } @Override public UiElement find(Locator locator) { return uiElementFactory.createFromParent(guiElementData.getGuiElement(), locator); } @Override public UiElement createEmpty(Locator locator) { return new EmptyUiElement(this, locator); } @Override public UiElementList list() { return new DefaultUiElementList(this); } /** * @deprecated This method is no longer acceptable as a part of GuiElement. * Use {@link eu.tsystems.mms.tic.testframework.webdrivermanager.DesktopWebDriverUtils#mouseOverJS()} instead */ @Deprecated public String getCssValue(String cssIdentifier) { return decoratedCore.getCssValue(cssIdentifier); } @Deprecated public UiElement mouseOver() { decoratedCore.mouseOver(); return this; } @Deprecated public boolean isPresent() { return decoratedCore.isPresent(); } @Deprecated public List getTextsFromChildren() { return decoratedCore.getTextsFromChildren(); } @Deprecated public boolean anyFollowingTextNodeContains(String contains) { return anyElementContainsText(contains).waitFor().present(true); } /** * This method is no part of any interface, because we don't know if * we want to support this feature at the moment. * The better approach is to use {@link #find(XPath)} */ @Deprecated public TestableUiElement anyElementContainsText(String text) { String textFinderXpath = String.format("//text()[contains(., '%s')]/..", text); return find(By.xpath(textFinderXpath)); } @Override public WebDriver getWebDriver() { return guiElementData.getWebDriver(); } /** * It's dangerous to use this method and rely on the given {@link WebElement} * because it can become stale during the execution. * Use {@link #findWebElement(Consumer)} instead. */ @Deprecated public WebElement getWebElement() { return this.decoratedCore.getWebElement(); } @Override public UiElement doubleClick() { decoratedCore.doubleClick(); return this; } @Override public UiElement highlight(Color color) { decoratedCore.highlight(color); return this; } public UiElement swipe(int offsetX, int offSetY) { decoratedCore.swipe(offsetX, offSetY); return this; } @Deprecated public int getLengthOfValueAfterSendKeys(String textToInput) { return decoratedCore.getLengthOfValueAfterSendKeys(textToInput); } @Deprecated public int getNumberOfFoundElements() { return decoratedCore.getNumberOfFoundElements(); } /** * @deprecated Use {@link #contextClick()} instead */ @Deprecated public UiElement rightClick() { return this.contextClick(); } /** * @deprecated This method is no longer acceptable as a part of GuiElement. * Use {@link eu.tsystems.mms.tic.testframework.webdrivermanager.DesktopWebDriverUtils#doubleClickJS()} instead */ @Override public UiElement contextClick() { decoratedCore.contextClick(); return this; } @Deprecated public File takeScreenshot() { return decoratedCore.takeScreenshot(); } /** * Sets the abstract parent * * @param parent {@link UiElement} or {@link PageObject} */ public UiElement setParent(Nameable parent) { this.parent = parent; return this; } /** * Retrieves the nameable parent. * * @return Can be {@link UiElement} or {@link PageObject} */ @Override public Nameable getParent() { return parent; } @Override public boolean hasOwnName() { return guiElementData.hasOwnName(); } @Override public String toString() { return this.toString(false); } @Deprecated public WebDriver getDriver() { return getWebDriver(); } /** * @deprecated Use {@link GuiElement#hasSensitiveData()}} instead */ @Deprecated public boolean hasSensibleData() { return guiElementData.hasSensitiveData(); } public boolean hasSensitiveData() { return guiElementData.hasSensitiveData(); } /** * @deprecated Use {@link GuiElement#sensitiveData()}} instead */ @Deprecated @Override public GuiElement sensibleData() { guiElementData.setHasSensitiveData(true); return this; } @Override public GuiElement sensitiveData() { guiElementData.setHasSensitiveData(true); return this; } @Override public GuiElement setName(String name) { guiElementData.setName(name); return this; } @Override public String getName(boolean detailed) { return guiElementData.getName(detailed); } /** * Provides access to all functional assert methods. * * @return GuiElementAssert object for functional assertions */ @Deprecated public GuiElementAssert asserts() { if (defaultAssert == null) { if (UiElement.Properties.DEFAULT_ASSERT_IS_COLLECTOR.asBool()) { defaultAssert = assertCollector(); } else { defaultAssert = instantAsserts(); } } return defaultAssert; } /** * Provides access to all assert methods. If an assertion fails, the assertDescription will be given as cause, * instead of the technical cause like an isDisplayed error. * * @param errorMessage Cause returned on assertion error. * @return GuiElementAssert object for functional assertions */ @Deprecated public GuiElementAssert asserts(String errorMessage) { GuiElementAssertDescriptionDecorator guiElementAssertDescriptionDecorator = new GuiElementAssertDescriptionDecorator(errorMessage, asserts()); return guiElementAssertDescriptionDecorator; } /** * Provides access to all non-functional assert methods. * * @return GuiElementAssert object for non-functional assertions * @deprecated Use {@link #optionalAsserts()} instead */ @Deprecated public GuiElementAssert nonFunctionalAsserts() { if (nonFunctionalAssert == null) { OptionalAssertion assertion = Testerra.getInjector().getInstance(OptionalAssertion.class); nonFunctionalAssert = createAssertDecorators(assertion); } return nonFunctionalAssert; } @Deprecated private GuiElementAssert createAssertDecorators(Assertion assertion) { GuiElementAssert guiElementAssert; if (Testerra.Properties.PERF_TEST.asBool()) { guiElementAssert = new PerformanceTestGuiElementAssert(); } else { guiElementAssert = new LegacyGuiElementAssertWrapper(this, assertion); } return guiElementAssert; } /** * Provides access to all non-functional assert methods. If an assertion fails, the assertDescription will be * given as cause, instead of the technical cause like an isDisplayed error. * * @param errorMessage Cause returned on assertion error. * @return GuiElementAssert object for non-functional assertions * @deprecated Use {@link #optionalAsserts(String)} instead */ @Deprecated public GuiElementAssert nonFunctionalAsserts(String errorMessage) { GuiElementAssertDescriptionDecorator guiElementAssertDescriptionDecorator = new GuiElementAssertDescriptionDecorator(errorMessage, nonFunctionalAsserts()); return guiElementAssertDescriptionDecorator; } @Deprecated private GuiElementAssert instantAsserts() { if (instantAssert == null) { InstantAssertion assertion = Testerra.getInjector().getInstance(InstantAssertion.class); instantAssert = createAssertDecorators(assertion); } return instantAssert; } /** * Provides access to optional assert methods */ @Deprecated public GuiElementAssert optionalAsserts() { return nonFunctionalAsserts(); } /** * Provides access to optional assert methods */ @Deprecated public GuiElementAssert optionalAsserts(String errorMessage) { return nonFunctionalAsserts(errorMessage); } /** * Provides access to all functional assert methods. * * @return GuiElementAssert object for functional assertions * @deprecated Use {@link #asserts()} instead */ @Deprecated public GuiElementAssert assertCollector() { if (collectableAssert == null) { CollectedAssertion assertion = Testerra.getInjector().getInstance(CollectedAssertion.class); collectableAssert = createAssertDecorators(assertion); } return collectableAssert; } /** * Provides access to all assert methods. If an assertion fails, the assertDescription will be given as cause, * instead of the technical cause like an isDisplayed error. * * @param errorMessage Cause returned on assertion error. * @return GuiElementAssert object for functional assertions */ @Deprecated public GuiElementAssert assertCollector(String errorMessage) { GuiElementAssertDescriptionDecorator guiElementAssertDescriptionDecorator = new GuiElementAssertDescriptionDecorator(errorMessage, assertCollector()); return guiElementAssertDescriptionDecorator; } @Deprecated public List getList() { return list().stream().map(uiElement -> (GuiElement) uiElement).collect(Collectors.toList()); } @Deprecated public GuiElement shadowRoot() { guiElementData.setHasShadowRoot(true); return this; } /** * Provides access to all wait methods */ @Deprecated public GuiElementWait waits() { if (decoratedWait == null) { decoratedWait = new DefaultGuiElementWait(this); } return decoratedWait; } @Override public UiElementAssertion waitFor(int seconds) { PropertyAssertionConfig config = new PropertyAssertionConfig(); config.useTimeout = seconds; return new DefaultUiElementAssertion(this, config); } @Override public UiElementAssertion expect() { PropertyAssertionConfig config = new PropertyAssertionConfig(); config.throwErrors = true; return new DefaultUiElementAssertion(this, config); } @Override public String createXPath() { GuiElementData guiElementData = this.guiElementData; StringBuilder sb = new StringBuilder(); do { String elementPath = XPath.byToXPath(guiElementData.getLocate().getBy()); if (guiElementData.getIndex() >= 0) { elementPath += "[" + guiElementData.getIndex() + "]"; } sb.insert(0, elementPath); guiElementData = guiElementData.getParent(); } while (guiElementData != null && !guiElementData.isFrame()); return sb.toString(); } @Override public void findWebElement(Consumer consumer) { decoratedCore.findWebElement(consumer); } @Override public void screenshotToReport() { this.waitFor().screenshot(Report.Mode.ALWAYS); } @Deprecated public Select getSelectElement() { return new Select(getWebElement()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy