net.serenitybdd.core.pages.RenderedPageObjectView Maven / Gradle / Ivy
package net.serenitybdd.core.pages;
import net.serenitybdd.model.collect.NewList;
import net.thucydides.core.scheduling.NormalFluentWait;
import net.thucydides.core.scheduling.ThucydidesFluentWait;
import net.thucydides.core.steps.StepEventBus;
import net.thucydides.core.webdriver.stubs.WebElementFacadeStub;
import org.openqa.selenium.*;
import org.openqa.selenium.support.ui.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.time.Clock;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import static net.serenitybdd.core.pages.FindAllWaitOptions.WITH_NO_WAIT;
import static net.serenitybdd.core.pages.FindAllWaitOptions.WITH_WAIT;
import static net.serenitybdd.core.selectors.Selectors.formattedXpathOrCssSelector;
import static net.serenitybdd.core.selectors.Selectors.xpathOrCssSelector;
import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated;
/**
* A page view that handles checking and waiting for element visibility.
*/
public class RenderedPageObjectView {
private final transient WebDriver driver;
private transient Duration waitForTimeout;
private final Clock webdriverClock;
private final Sleeper sleeper;
private final PageObject pageObject;
private final boolean timeoutCanBeOverriden;
private static final int WAIT_FOR_ELEMENT_PAUSE_LENGTH = 50;
private static final Logger LOGGER = LoggerFactory
.getLogger(RenderedPageObjectView.class);
public RenderedPageObjectView(final WebDriver driver, final PageObject pageObject, long waitForTimeoutInMilliseconds) {
this(driver, pageObject, Duration.ofMillis(waitForTimeoutInMilliseconds), true);
}
public RenderedPageObjectView(final WebDriver driver, final PageObject pageObject, Duration waitForTimeout, boolean timeoutCanBeOverriden) {
this.driver = driver;
this.pageObject = pageObject;
setWaitForTimeout(waitForTimeout);
this.webdriverClock = Clock.systemDefaultZone();
this.sleeper = Sleeper.SYSTEM_SLEEPER;
this.timeoutCanBeOverriden = timeoutCanBeOverriden;
}
private boolean driverIsDisabled() {
return StepEventBus.getParallelEventBus().webdriverCallsAreSuspended();
}
public ThucydidesFluentWait waitForCondition() {
return new NormalFluentWait(driver, webdriverClock, sleeper)
.withTimeout(waitForTimeout)
.pollingEvery(WAIT_FOR_ELEMENT_PAUSE_LENGTH, TimeUnit.MILLISECONDS)
.ignoring(NoSuchElementException.class,
NoSuchFrameException.class,
StaleElementReferenceException.class,
InvalidElementStateException.class);
}
public FluentWait doWait() {
return new FluentWait(driver)
.withTimeout(waitForTimeout)
.pollingEvery(Duration.ofMillis(WAIT_FOR_ELEMENT_PAUSE_LENGTH))
.ignoreAll(NewList.of(NoSuchElementException.class,
NoSuchFrameException.class,
StaleElementReferenceException.class,
InvalidElementStateException.class));
}
private ExpectedCondition elementDisplayed(final By byElementCriteria) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return (elementIsCurrentlyVisible(byElementCriteria));
}
@Override
public String toString() {
return "Expecting element is displayed: " + byElementCriteria.toString();
}
};
}
/**
* This method will wait until an element is present and visible on the screen.
*/
public WebElementFacade waitFor(final By byElementCriteria) {
if (!driverIsDisabled()) {
waitForCondition().until(elementDisplayed(byElementCriteria));
return pageObject.find(byElementCriteria);
} else {
return new WebElementFacadeStub();
}
}
public T waitFor(final ExpectedCondition expectedCondition) {
return doWait().until(expectedCondition);
}
public T waitFor(String message, final ExpectedCondition expectedCondition) {
return doWait().until(new WaitForWithMessage<>(message, expectedCondition));
}
public WebElementFacade waitFor(String xpathOrCssSelector, Object... args) {
return waitFor(formattedXpathOrCssSelector(xpathOrCssSelector, args));
}
public WebElementFacade waitFor(final WebElement webElement) {
return (webElement instanceof WebElementFacade) ?
waitForElement((WebElementFacade) webElement) :
waitForElement(pageObject.element(webElement));
}
public WebElementFacade waitFor(final WebElementFacade webElement) {
return waitForElement(webElement);
}
public List waitFor(final List webElements) {
return waitForElements(webElements);
}
private WebElementFacade waitForElement(final WebElementFacade webElement) {
if (!driverIsDisabled()) {
waitForCondition().until(elementIsDisplayed(webElement));
}
return webElement;
}
private List waitForElements(final List elements) {
if (!driverIsDisabled()) {
waitForCondition().until(elementsAreDisplayed(elements));
}
return elements;
}
private Function super WebDriver, Boolean> elementIsDisplayed(final WebElementFacade webElement) {
return (ExpectedCondition) driver -> {
try {
if (webElement.isCurrentlyVisible()) {
return true;
}
} catch (NoSuchElementException noSuchElement) {
// Ignore exception
}
return false;
};
}
private boolean elementIsNotDisplayed(final By byElementCriteria) {
List matchingElements = findAllWithNoWait(byElementCriteria);
for (WebElementFacade matchingElement : matchingElements) {
if (matchingElement.isCurrentlyVisible()) {
return false;
}
}
return true;
}
private Function super WebDriver, Boolean> elementsAreDisplayed(final List webElements) {
return (ExpectedCondition) driver -> {
try {
return (webElements.size() > 0) && allElementsVisibleIn(webElements);
} catch (NoSuchElementException noSuchElement) {
// Ignore exception
}
return false;
};
}
private boolean allElementsVisibleIn(List webElements) {
for (WebElementFacade element : webElements) {
if (!element.isCurrentlyVisible()) {
return false;
}
}
return true;
}
/**
* This method will wait until an element is present on the screen, though not necessarily visible.
*/
public WebElement waitForPresenceOf(final By byElementCriteria) {
WebDriverWait wait = new WebDriverWait(driver, waitForTimeout);
return wait.until(presenceOfElementLocated(byElementCriteria));
}
public boolean elementIsPresent(final By byElementCriteria) {
boolean isDisplayed = true;
try {
List matchingElements = driver.findElements(byElementCriteria);
if (matchingElements.isEmpty()) {
isDisplayed = false;
}
} catch (NoSuchElementException noSuchElement) {
isDisplayed = false;
}
return isDisplayed;
}
public boolean elementIsDisplayed(final By byElementCriteria) {
try {
waitFor(ExpectedConditions.visibilityOfAllElementsLocatedBy(byElementCriteria));
return true;
} catch (NoSuchElementException | TimeoutException | StaleElementReferenceException noSuchElement) {
return false;
}
}
public boolean elementIsCurrentlyVisible(final By byElementCriteria) {
try {
List matchingElements = driver.findElements(byElementCriteria);
return (!matchingElements.isEmpty() && matchingElements.get(0).isDisplayed());
} catch (NoSuchElementException | StaleElementReferenceException | TimeoutException noSuchElement) {
return false;
}
}
private ExpectedCondition textPresent(final String expectedText) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return (containsText(expectedText));
}
@Override
public String toString() {
return "Expecting text present: '" + expectedText + "'";
}
};
}
public void waitForText(final String expectedText) {
if (!driverIsDisabled()) {
waitForCondition().until(textPresent(expectedText));
}
}
public WebDriverWait thenWait() {
return new WebDriverWait(driver, getWaitForTimeout());
}
private ExpectedCondition textPresentInElement(final WebElement element, final String expectedText) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return (containsText(element, expectedText));
}
@Override
public String toString() {
return "Expecting text present in element: '" + expectedText + "'";
}
};
}
public void waitForText(final WebElement element, final String expectedText) {
if (!driverIsDisabled()) {
waitForCondition().until(textPresentInElement(element, expectedText));
}
}
private ExpectedCondition titlePresent(final String expectedTitle) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return titleIs(expectedTitle);
}
@Override
public String toString() {
return "Expecting title present: '" + expectedTitle + "', but found '" + driver.getTitle() + "' instead.'";
}
};
}
public void waitForTitle(final String expectedTitle) {
if (!driverIsDisabled()) {
waitForCondition().until(titlePresent(expectedTitle));
}
}
private boolean titleIs(final String expectedTitle) {
return ((driver.getTitle() != null) && (driver.getTitle().equals(expectedTitle)));
}
public boolean containsText(final String textValue) {
return driver.findElement(By.tagName("body")).getText().contains(textValue);
}
public boolean containsText(final WebElement element, final String textValue) {
return element.getText().contains(textValue);
}
private ExpectedCondition textNotPresent(final String expectedText) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return !containsText(expectedText);
}
@Override
public String toString() {
return "Expecting text not present: '" + expectedText + "'";
}
};
}
public void waitForTextToDisappear(final String expectedText, final long timeout) {
if (!driverIsDisabled()) {
waitForCondition()
.withTimeout(timeout, TimeUnit.MILLISECONDS)
.until(textNotPresent(expectedText));
}
}
public void waitForTextToAppear(final String expectedText, final long timeout) {
if (!driverIsDisabled()) {
waitForCondition()
.withTimeout(timeout, TimeUnit.MILLISECONDS)
.until(textPresent(expectedText));
}
}
private ExpectedCondition titleNotPresent(final String expectedTitle) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return !titleIs(expectedTitle);
}
@Override
public String toString() {
return "Expecting title present: '" + expectedTitle + "', but found '" + driver.getTitle() + "' instead.";
}
};
}
public void waitForTitleToDisappear(final String expectedTitle) {
if (!driverIsDisabled()) {
waitForCondition().until(titleNotPresent(expectedTitle));
}
}
private ExpectedCondition anyTextPresent(final String... expectedTexts) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return pageContainsAny(expectedTexts);
}
};
}
public void waitForAnyTextToAppear(final String... expectedTexts) {
if (!driverIsDisabled()) {
waitForCondition().until(anyTextPresent(expectedTexts));
}
}
private ExpectedCondition anyTextPresentInElement(final WebElement element, final String... expectedTexts) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return elementContains(element, expectedTexts);
}
@Override
public String toString() {
return "Expecting any text present in element: '" + Arrays.toString(expectedTexts) + "'";
}
};
}
public void waitForAnyTextToAppear(final WebElement element, final String... expectedTexts) {
if (!driverIsDisabled()) {
waitForCondition().until(anyTextPresentInElement(element, expectedTexts));
}
}
public void waitForAbsenceOf(String xpathOrCssSelector) {
waitForElementsToDisappear(xpathOrCssSelector(xpathOrCssSelector));
}
private boolean elementContains(final WebElement element, final String... expectedTexts) {
for (String expectedText : expectedTexts) {
if (containsText(element, expectedText)) {
return true;
}
}
return false;
}
private boolean pageContainsAny(final String... expectedTexts) {
for (String expectedText : expectedTexts) {
if (containsText(expectedText)) {
return true;
}
}
return false;
}
private ExpectedCondition allTextPresent(final String... expectedTexts) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return Arrays.stream(expectedTexts).allMatch(expectedText -> containsText(expectedText));
//
// for (String expectedText : expectedTexts) {
// if (!containsText(expectedText)) {
// return false;
// }
// }
// return true;
}
@Override
public String toString() {
return "Expecting all texts present in element: '" + Arrays.toString(expectedTexts) + "'";
}
};
}
public void waitForAllTextToAppear(final String... expectedTexts) {
if (!driverIsDisabled()) {
waitForCondition().until(allTextPresent(expectedTexts));
}
}
private ExpectedCondition elementNotDisplayed(final By byElementCriteria) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
return (elementIsNotDisplayed(byElementCriteria));
}
@Override
public String toString() {
return "Expecting element not displayed: " + byElementCriteria;
}
};
}
public void waitForElementsToDisappear(final By byElementCriteria) {
if (!driverIsDisabled()) {
waitForCondition().until(elementNotDisplayed(byElementCriteria));
}
}
private ExpectedCondition anyElementPresent(final By... expectedElements) {
return new ExpectedCondition() {
public Boolean apply(WebDriver driver) {
for (By expectedElement : expectedElements) {
if (elementIsDisplayed(expectedElement)) {
return true;
}
}
return false;
}
@Override
public String toString() {
return "Expecting any element present: " + Arrays.toString(expectedElements);
}
};
}
public void waitForAnyRenderedElementOf(final By[] expectedElements) {
if (!driverIsDisabled()) {
waitForCondition().until(anyElementPresent(expectedElements));
}
}
// public void setWaitForTimeoutInMilliseconds(long waitForTimeoutInMilliseconds) {
// setWaitForTimeout(new Duration(waitForTimeoutInMilliseconds,TimeUnit.MILLISECONDS));
// }
public void setWaitForTimeout(Duration waitForTimeout) {
this.waitForTimeout = waitForTimeout;
}
public Duration getWaitForTimeout() {
return waitForTimeout;
}
protected List findAllWithOptionalWait(By bySelector, FindAllWaitOptions waitForOptions) {
List results;
try {
pageObject.setImplicitTimeout(0, ChronoUnit.SECONDS);
if (timeoutCanBeOverriden) {
overrideWaitForTimeoutTo( Duration.ofSeconds(0));
}
if (waitForOptions == WITH_WAIT) {
waitFor(bySelector);
}
results = pageObject.findAll(bySelector);
if (timeoutCanBeOverriden) {
resetWaitForTimeout();
}
pageObject.resetImplicitTimeout();
} catch (TimeoutException e) {
return new ArrayList();
}
return results;
}
public List findAll(By bySelector) {
return findAllWithOptionalWait(bySelector, WITH_WAIT);
}
public List findAllWithNoWait(By bySelector) {
return findAllWithOptionalWait(bySelector, WITH_NO_WAIT);
}
private Duration oldWaitFor;
private void overrideWaitForTimeoutTo(Duration duration) {
oldWaitFor = waitForTimeout;
setWaitForTimeout(duration);
}
private void resetWaitForTimeout() {
setWaitForTimeout(oldWaitFor);
}
public List findAll(String xpathOrCssSelector) {
return findAll(xpathOrCssSelector(xpathOrCssSelector));
}
public List findFirstMatching(List xpathOrCssSelectors) {
List matchingElements = new ArrayList<>();
for(String selector : xpathOrCssSelectors) {
matchingElements = findAllWithNoWait(xpathOrCssSelector(selector));
if (!matchingElements.isEmpty()) {
break;
}
}
return matchingElements;
}
//
// public static Function> containingTextAndMatchingCSS(String cssOrXPathLocator, String expectedText) {
// return page -> page.withTimeoutOf(Duration.ZERO)
// .findAll(cssOrXPathLocator)
// .stream()
// .filter(element -> element.getTextContent().contains(expectedText))
// .collect(Collectors.toList());
// }
//
//
// public static Function> containingTextAndMatchingCSS(List cssOrXPathLocators, String expectedText) {
// return page -> page.withTimeoutOf(Duration.ZERO)
// .findFirstMatching(cssOrXPathLocators)
// .stream()
// .filter(element -> element.getTextContent().contains(expectedText))
// .collect(Collectors.toList());
// }
public net.serenitybdd.core.pages.WebElementFacade $(ResolvableElement selector) {
return find(selector);
}
public net.serenitybdd.core.pages.WebElementFacade find(ResolvableElement selector) {
pageObject.setImplicitTimeout(0, ChronoUnit.SECONDS);
net.serenitybdd.core.pages.WebElementFacade result = selector.resolveFor(this.pageObject);
pageObject.resetImplicitTimeout();
return result;
}
public ListOfWebElementFacades findAll(ResolvableElement selector) {
pageObject.setImplicitTimeout(0, ChronoUnit.SECONDS);
ListOfWebElementFacades results = pageObject.findAllWithRetry((page) -> selector.resolveAllFor(this.pageObject));
pageObject.resetImplicitTimeout();
return results;
}
public WebElementFacade find(By bySelector) {
waitFor(bySelector);
pageObject.setImplicitTimeout(0, ChronoUnit.SECONDS);
WebElementFacade result = pageObject.find(bySelector);
pageObject.resetImplicitTimeout();
return result;
}
public WebElementFacade find(String xpathOrCssSelector) {
return find(xpathOrCssSelector(xpathOrCssSelector));
}
public WebElementFacade find(String xpathOrCssSelector, Object firstArgument, Object... arguments) {
List
© 2015 - 2024 Weber Informatics LLC | Privacy Policy