package net.thucydides.core.pages; import net.thucydides.core.scheduling.NormalFluentWait; import net.thucydides.core.scheduling.ThucydidesFluentWait; import org.openqa.selenium.*; import org.openqa.selenium.support.ui.*; import org.openqa.selenium.support.ui.SystemClock; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; import java.util.concurrent.TimeUnit; /** * A page view that handles checking and waiting for element visibility. */ public class RenderedPageObjectView { private final transient WebDriver driver; private transient long waitForTimeoutInMilliseconds; private final Clock webdriverClock; private final Sleeper sleeper; 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 long waitForTimeout) { this.driver = driver; this.waitForTimeoutInMilliseconds = waitForTimeout; this.webdriverClock = new SystemClock(); this.sleeper = Sleeper.SYSTEM_SLEEPER; } public ThucydidesFluentWait<WebDriver> waitForCondition() { return new NormalFluentWait<WebDriver>(driver, webdriverClock, sleeper) .withTimeout(waitForTimeoutInMilliseconds, TimeUnit.MILLISECONDS) .pollingEvery(WAIT_FOR_ELEMENT_PAUSE_LENGTH, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class, NoSuchFrameException.class); } public FluentWait<WebDriver> doWait() { return new FluentWait(driver) .withTimeout(waitForTimeoutInMilliseconds, TimeUnit.MILLISECONDS) .pollingEvery(WAIT_FOR_ELEMENT_PAUSE_LENGTH, TimeUnit.MILLISECONDS) .ignoring(NoSuchElementException.class, NoSuchFrameException.class); } private ExpectedCondition<Boolean> elementDisplayed(final By byElementCriteria) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return (elementIsDisplayed(byElementCriteria)); } }; } private ExpectedCondition<Boolean> elementPresent(final By byElementCriteria) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return (elementIsDisplayed(byElementCriteria)); } }; } /** * This method will wait until an element is present and visible on the screen. */ public void waitFor(final By byElementCriteria) { waitForCondition().until(elementDisplayed(byElementCriteria)); } public void waitFor(final ExpectedCondition expectedCondition) { doWait().until(expectedCondition); } /** * This method will wait until an element is present on the screen, though not necessarily visible. */ public void waitForPresenceOf(final By byElementCriteria) { WebDriverWait wait = new WebDriverWait(driver, (long)(waitForTimeoutInMilliseconds/1000)); wait.until(ExpectedConditions.presenceOfElementLocated(byElementCriteria)); // waitForCondition().until(elementPresent(byElementCriteria)); } public boolean elementIsPresent(final By byElementCriteria) { boolean isDisplayed = true; try { List<WebElement> matchingElements = driver.findElements(byElementCriteria); if (matchingElements.isEmpty()) { isDisplayed = false; } } catch (NoSuchElementException noSuchElement) { LOGGER.trace("No such element " + noSuchElement); isDisplayed = false; } return isDisplayed; } public boolean elementIsDisplayed(final By byElementCriteria) { try { List<WebElement> matchingElements = driver.findElements(byElementCriteria); for(WebElement webElement : matchingElements) { WebElementFacade element = WebElementFacadeImpl.wrapWebElement(driver, webElement, 100); if (element.isCurrentlyVisible()) { return true; } } return false; } catch (NoSuchElementException noSuchElement) { LOGGER.trace("No such element " + noSuchElement); return false; } catch (StaleElementReferenceException se) { LOGGER.trace("Element no longer attached to the DOM " + se); return false; } } private boolean matchingElementsArePresent(List<WebElement> matchingElements) { return (matchingElements != null) && (!matchingElements.isEmpty()); } private ExpectedCondition<Boolean> textPresent(final String expectedText) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return (containsText(expectedText)); } }; } public void waitForText(final String expectedText) { waitForCondition().until(textPresent(expectedText)); } private ExpectedCondition<Boolean> textPresentInElement(final WebElement element, final String expectedText) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return (containsText(element, expectedText)); } }; } public void waitForText(final WebElement element, final String expectedText) { waitForCondition().until(textPresentInElement(element, expectedText)); } private ExpectedCondition<Boolean> titlePresent(final String expectedTitle) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return titleIs(expectedTitle); } }; } public void waitForTitle(final String expectedTitle) { 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); } private boolean foundNo(List<WebElement> elements) { return ((elements == null) || (elements.isEmpty())); } public boolean containsText(final WebElement element, final String textValue) { return element.getText().contains(textValue); } private ExpectedCondition<Boolean> textNotPresent(final String expectedText) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return !containsText(expectedText); } }; } public void waitForTextToDisappear(final String expectedText, final long timeout) { waitForCondition() .withTimeout(timeout, TimeUnit.MILLISECONDS) .until(textNotPresent(expectedText)); } public void waitForTextToAppear(final String expectedText, final long timeout) { waitForCondition() .withTimeout(timeout, TimeUnit.MILLISECONDS) .until(textPresent(expectedText)); } private ExpectedCondition<Boolean> titleNotPresent(final String expectedTitle) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return !titleIs(expectedTitle); } }; } public void waitForTitleToDisappear(final String expectedTitle) { waitForCondition().until(titleNotPresent(expectedTitle)); } private ExpectedCondition<Boolean> anyTextPresent(final String... expectedTexts) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return pageContainsAny(expectedTexts); } }; } public void waitForAnyTextToAppear(final String... expectedTexts) { waitForCondition().until(anyTextPresent(expectedTexts)); } private ExpectedCondition<Boolean> anyTextPresentInElement(final WebElement element, final String... expectedTexts) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return elementContains(element, expectedTexts); } }; } public void waitForAnyTextToAppear(final WebElement element, final String... expectedTexts) { waitForCondition().until(anyTextPresentInElement(element, expectedTexts)); } 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<Boolean> allTextPresent(final String... expectedTexts) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { for(String expectedText : expectedTexts) { if (!containsText(expectedText)) { return false; } } return true; } }; } public void waitForAllTextToAppear(final String... expectedTexts) { waitForCondition().until(allTextPresent(expectedTexts)); } private ExpectedCondition<Boolean> elementNotDisplayed(final By byElementCriteria) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { return (!elementIsDisplayed(byElementCriteria)); } }; } public void waitForElementsToDisappear(final By byElementCriteria) { waitForCondition().until(elementNotDisplayed(byElementCriteria)); } private ExpectedCondition<Boolean> anyElementPresent(final By... expectedElements) { return new ExpectedCondition<Boolean>() { public Boolean apply(WebDriver driver) { for(By expectedElement : expectedElements) { if (elementIsDisplayed(expectedElement)) { return true; } } return false; } }; } public void waitForAnyRenderedElementOf(final By[] expectedElements) { waitForCondition().until(anyElementPresent(expectedElements)); } public void setWaitForTimeoutInMilliseconds(long waitForTimeoutInMilliseconds) { this.waitForTimeoutInMilliseconds = waitForTimeoutInMilliseconds; } public long getWaitForTimeoutInMilliseconds() { return waitForTimeoutInMilliseconds; } }