Permalink
Switch branches/tags
selenium-3.14.0 selenium-3.13.0 selenium-3.12.0 selenium-3.11.0 selenium-3.10.0 selenium-3.9.1 selenium-3.9.0 selenium-3.8.1 selenium-3.8.0 selenium-3.7.1 selenium-3.7.0 selenium-3.6.0 selenium-3.5.3 selenium-3.5.2 selenium-3.5.1 selenium-3.5.0 selenium-3.4.0 selenium-3.3.1 selenium-3.3.0 selenium-3.2.0 selenium-3.1.0 selenium-3.0.1 selenium-3.0.0 selenium-3.0.0-beta-4 selenium-3.0.0-beta-3 selenium-3.0.0-beta-2 selenium-3.0.0-beta-1 selenium-2.53.1 selenium-2.53.0 selenium-2.52.0 selenium-2.51.0 selenium-2.50.1 selenium-2.50.0 selenium-2.49.1 selenium-2.49.0 selenium-2.48.2 selenium-2.48.1 selenium-2.48.0 selenium-2.47.1 selenium-2.47.0 selenium-2.46.0 selenium-2.45.0 selenium-2.44.0 selenium-2.43.1 selenium-2.43.0 selenium-2.42.2 selenium-2.42.1 selenium-2.42.0 selenium-2.41.0 selenium-2.40.0 selenium-2.39.0 selenium-2.38.0 selenium-2.37.0 selenium-2.36.0 selenium-2.35.0 selenium-2.33.0 selenium-2.32.0 selenium-2.31.0 selenium-2.30.0 selenium-2.29.0 selenium-2.29.0a selenium-2.28.0 selenium-2.27.0 selenium-2.26.0 selenium-2.25.0 selenium-2.24.1 selenium-2.23.1 selenium-2.23.0 selenium-2.22.0 selenium-2.21.0 selenium-2.20.0 selenium-2.19.0 selenium-2.18.0 selenium-2.17.0 selenium-2.16.0 selenium-2.15.0 selenium-2.14.0 selenium-2.13.0 selenium-2.12.0 selenium-2.11.0 selenium-2.10.0 selenium-2.9.0 selenium-2.8.0 selenium-2.7.0 selenium-2.6.0 selenium-2.5.0 selenium-2.4.0 selenium-2.3.0 selenium-2.2.0 selenium-2.1.0 selenium-2.0.0 selenium-2.0-rc1 selenium-2.0-rc-3 selenium-2.0-rc-2 selenium-2.0-beta-3 selenium-2.0-beta-2 selenium-2.0-beta-1 selenium-2.0-alpha-7 selenium-2.0-alpha-6 selenium-2.0-alpha-5
Nothing to show
Find file Copy path
1498 lines (1339 sloc) 48.7 KB
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses 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 org.openqa.selenium.support.ui;
import com.google.common.base.Joiner;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.NoSuchFrameException;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Canned {@link ExpectedCondition}s which are generally useful within webdriver tests.
*/
public class ExpectedConditions {
private final static Logger log = Logger.getLogger(ExpectedConditions.class.getName());
private ExpectedConditions() {
// Utility class
}
/**
* An expectation for checking the title of a page.
*
* @param title the expected title, which must be an exact match
* @return true when the title matches, false otherwise
*/
public static ExpectedCondition<Boolean> titleIs(final String title) {
return new ExpectedCondition<Boolean>() {
private String currentTitle = "";
@Override
public Boolean apply(WebDriver driver) {
currentTitle = driver.getTitle();
return title.equals(currentTitle);
}
@Override
public String toString() {
return String.format("title to be \"%s\". Current title: \"%s\"", title, currentTitle);
}
};
}
/**
* An expectation for checking that the title contains a case-sensitive substring
*
* @param title the fragment of title expected
* @return true when the title matches, false otherwise
*/
public static ExpectedCondition<Boolean> titleContains(final String title) {
return new ExpectedCondition<Boolean>() {
private String currentTitle = "";
@Override
public Boolean apply(WebDriver driver) {
currentTitle = driver.getTitle();
return currentTitle != null && currentTitle.contains(title);
}
@Override
public String toString() {
return String.format("title to contain \"%s\". Current title: \"%s\"", title, currentTitle);
}
};
}
/**
* An expectation for the URL of the current page to be a specific url.
*
* @param url the url that the page should be on
* @return <code>true</code> when the URL is what it should be
*/
public static ExpectedCondition<Boolean> urlToBe(final String url) {
return new ExpectedCondition<Boolean>() {
private String currentUrl = "";
@Override
public Boolean apply(WebDriver driver) {
currentUrl = driver.getCurrentUrl();
return currentUrl != null && currentUrl.equals(url);
}
@Override
public String toString() {
return String.format("url to be \"%s\". Current url: \"%s\"", url, currentUrl);
}
};
}
/**
* An expectation for the URL of the current page to contain specific text.
*
* @param fraction the fraction of the url that the page should be on
* @return <code>true</code> when the URL contains the text
*/
public static ExpectedCondition<Boolean> urlContains(final String fraction) {
return new ExpectedCondition<Boolean>() {
private String currentUrl = "";
@Override
public Boolean apply(WebDriver driver) {
currentUrl = driver.getCurrentUrl();
return currentUrl != null && currentUrl.contains(fraction);
}
@Override
public String toString() {
return String.format("url to contain \"%s\". Current url: \"%s\"", fraction, currentUrl);
}
};
}
/**
* Expectation for the URL to match a specific regular expression
*
* @param regex the regular expression that the URL should match
* @return <code>true</code> if the URL matches the specified regular expression
*/
public static ExpectedCondition<Boolean> urlMatches(final String regex) {
return new ExpectedCondition<Boolean>() {
private String currentUrl;
private Pattern pattern;
private Matcher matcher;
@Override
public Boolean apply(WebDriver driver) {
currentUrl = driver.getCurrentUrl();
pattern = Pattern.compile(regex);
matcher = pattern.matcher(currentUrl);
return matcher.find();
}
@Override
public String toString() {
return String
.format("url to match the regex \"%s\". Current url: \"%s\"", regex, currentUrl);
}
};
}
/**
* An expectation for checking that an element is present on the DOM of a page. This does not
* necessarily mean that the element is visible.
*
* @param locator used to find the element
* @return the WebElement once it is located
*/
public static ExpectedCondition<WebElement> presenceOfElementLocated(final By locator) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
@Override
public String toString() {
return "presence of element located by: " + locator;
}
};
}
/**
* An expectation for checking that an element is present on the DOM of a page and visible.
* Visibility means that the element is not only displayed but also has a height and width that is
* greater than 0.
*
* @param locator used to find the element
* @return the WebElement once it is located and visible
*/
public static ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
try {
return elementIfVisible(driver.findElement(locator));
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return "visibility of element located by " + locator;
}
};
}
/**
* An expectation for checking that all elements present on the web page that match the locator
* are visible. Visibility means that the elements are not only displayed but also have a height
* and width that is greater than 0.
*
* @param locator used to find the element
* @return the list of WebElements once they are located
*/
public static ExpectedCondition<List<WebElement>> visibilityOfAllElementsLocatedBy(
final By locator) {
return new ExpectedCondition<List<WebElement>>() {
@Override
public List<WebElement> apply(WebDriver driver) {
List<WebElement> elements = driver.findElements(locator);
for (WebElement element : elements) {
if (!element.isDisplayed()) {
return null;
}
}
return elements.size() > 0 ? elements : null;
}
@Override
public String toString() {
return "visibility of all elements located by " + locator;
}
};
}
/**
* An expectation for checking that all elements present on the web page that match the locator
* are visible. Visibility means that the elements are not only displayed but also have a height
* and width that is greater than 0.
*
* @param elements list of WebElements
* @return the list of WebElements once they are located
*/
public static ExpectedCondition<List<WebElement>> visibilityOfAllElements(
final WebElement... elements) {
return visibilityOfAllElements(Arrays.asList(elements));
}
/**
* An expectation for checking that all elements present on the web page that match the locator
* are visible. Visibility means that the elements are not only displayed but also have a height
* and width that is greater than 0.
*
* @param elements list of WebElements
* @return the list of WebElements once they are located
*/
public static ExpectedCondition<List<WebElement>> visibilityOfAllElements(
final List<WebElement> elements) {
return new ExpectedCondition<List<WebElement>>() {
@Override
public List<WebElement> apply(WebDriver driver) {
for (WebElement element : elements) {
if (!element.isDisplayed()) {
return null;
}
}
return elements.size() > 0 ? elements : null;
}
@Override
public String toString() {
return "visibility of all " + elements;
}
};
}
/**
* An expectation for checking that an element, known to be present on the DOM of a page, is
* visible. Visibility means that the element is not only displayed but also has a height and
* width that is greater than 0.
*
* @param element the WebElement
* @return the (same) WebElement once it is visible
*/
public static ExpectedCondition<WebElement> visibilityOf(final WebElement element) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
return elementIfVisible(element);
}
@Override
public String toString() {
return "visibility of " + element;
}
};
}
/**
* @return the given element if it is visible and has non-zero size, otherwise null.
*/
private static WebElement elementIfVisible(WebElement element) {
return element.isDisplayed() ? element : null;
}
/**
* An expectation for checking that there is at least one element present on a web page.
*
* @param locator used to find the element
* @return the list of WebElements once they are located
*/
public static ExpectedCondition<List<WebElement>> presenceOfAllElementsLocatedBy(
final By locator) {
return new ExpectedCondition<List<WebElement>>() {
@Override
public List<WebElement> apply(WebDriver driver) {
List<WebElement> elements = driver.findElements(locator);
return elements.size() > 0 ? elements : null;
}
@Override
public String toString() {
return "presence of any elements located by " + locator;
}
};
}
/**
* An expectation for checking if the given text is present in the specified element.
*
* @param element the WebElement
* @param text to be present in the element
* @return true once the element contains the given text
*/
public static ExpectedCondition<Boolean> textToBePresentInElement(final WebElement element,
final String text) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
String elementText = element.getText();
return elementText.contains(text);
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return String.format("text ('%s') to be present in element %s", text, element);
}
};
}
/**
* An expectation for checking if the given text is present in the element that matches the given
* locator.
*
* @param locator used to find the element
* @param text to be present in the element found by the locator
* @return true once the first element located by locator contains the given text
*/
public static ExpectedCondition<Boolean> textToBePresentInElementLocated(final By locator,
final String text) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
String elementText = driver.findElement(locator).getText();
return elementText.contains(text);
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return String.format("text ('%s') to be present in element found by %s",
text, locator);
}
};
}
/**
* An expectation for checking if the given text is present in the specified elements value
* attribute.
*
* @param element the WebElement
* @param text to be present in the element's value attribute
* @return true once the element's value attribute contains the given text
*/
public static ExpectedCondition<Boolean> textToBePresentInElementValue(final WebElement element,
final String text) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
String elementText = element.getAttribute("value");
if (elementText != null) {
return elementText.contains(text);
}
return false;
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return String.format("text ('%s') to be the value of element %s", text, element);
}
};
}
/**
* An expectation for checking if the given text is present in the specified elements value
* attribute.
*
* @param locator used to find the element
* @param text to be present in the value attribute of the element found by the locator
* @return true once the value attribute of the first element located by locator contains the
* given text
*/
public static ExpectedCondition<Boolean> textToBePresentInElementValue(final By locator,
final String text) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
String elementText = driver.findElement(locator).getAttribute("value");
if (elementText != null) {
return elementText.contains(text);
}
return false;
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return String.format("text ('%s') to be the value of element located by %s",
text, locator);
}
};
}
/**
* An expectation for checking whether the given frame is available to switch to. <p> If the frame
* is available it switches the given driver to the specified frame.
*
* @param frameLocator used to find the frame (id or name)
* @return WebDriver instance after frame has been switched
*/
public static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(
final String frameLocator) {
return new ExpectedCondition<WebDriver>() {
@Override
public WebDriver apply(WebDriver driver) {
try {
return driver.switchTo().frame(frameLocator);
} catch (NoSuchFrameException e) {
return null;
}
}
@Override
public String toString() {
return "frame to be available: " + frameLocator;
}
};
}
/**
* An expectation for checking whether the given frame is available to switch to. <p> If the frame
* is available it switches the given driver to the specified frame.
*
* @param locator used to find the frame
* @return WebDriver instance after frame has been switched
*/
public static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(final By locator) {
return new ExpectedCondition<WebDriver>() {
@Override
public WebDriver apply(WebDriver driver) {
try {
return driver.switchTo().frame(driver.findElement(locator));
} catch (NoSuchFrameException e) {
return null;
}
}
@Override
public String toString() {
return "frame to be available: " + locator;
}
};
}
/**
* An expectation for checking whether the given frame is available to switch to. <p> If the frame
* is available it switches the given driver to the specified frameIndex.
*
* @param frameLocator used to find the frame (index)
* @return WebDriver instance after frame has been switched
*/
public static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(
final int frameLocator) {
return new ExpectedCondition<WebDriver>() {
@Override
public WebDriver apply(WebDriver driver) {
try {
return driver.switchTo().frame(frameLocator);
} catch (NoSuchFrameException e) {
return null;
}
}
@Override
public String toString() {
return "frame to be available: " + frameLocator;
}
};
}
/**
* An expectation for checking whether the given frame is available to switch to. <p> If the frame
* is available it switches the given driver to the specified webelement.
*
* @param frameLocator used to find the frame (webelement)
* @return WebDriver instance after frame has been switched
*/
public static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt(
final WebElement frameLocator) {
return new ExpectedCondition<WebDriver>() {
@Override
public WebDriver apply(WebDriver driver) {
try {
return driver.switchTo().frame(frameLocator);
} catch (NoSuchFrameException e) {
return null;
}
}
@Override
public String toString() {
return "frame to be available: " + frameLocator;
}
};
}
/**
* An expectation for checking that an element is either invisible or not present on the DOM.
*
* @param locator used to find the element
* @return true if the element is not displayed or the element doesn't exist or stale element
*/
public static ExpectedCondition<Boolean> invisibilityOfElementLocated(final By locator) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return !(driver.findElement(locator).isDisplayed());
} catch (NoSuchElementException e) {
// Returns true because the element is not present in DOM. The
// try block checks if the element is present but is invisible.
return true;
} catch (StaleElementReferenceException e) {
// Returns true because stale element reference implies that element
// is no longer visible.
return true;
}
}
@Override
public String toString() {
return "element to no longer be visible: " + locator;
}
};
}
/**
* An expectation for checking that an element with text is either invisible or not present on the
* DOM.
*
* @param locator used to find the element
* @param text of the element
* @return true if no such element, stale element or displayed text not equal that provided
*/
public static ExpectedCondition<Boolean> invisibilityOfElementWithText(final By locator,
final String text) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return !driver.findElement(locator).getText().equals(text);
} catch (NoSuchElementException e) {
// Returns true because the element with text is not present in DOM. The
// try block checks if the element is present but is invisible.
return true;
} catch (StaleElementReferenceException e) {
// Returns true because stale element reference implies that element
// is no longer visible.
return true;
}
}
@Override
public String toString() {
return String.format("element containing '%s' to no longer be visible: %s",
text, locator);
}
};
}
/**
* An expectation for checking an element is visible and enabled such that you can click it.
*
* @param locator used to find the element
* @return the WebElement once it is located and clickable (visible and enabled)
*/
public static ExpectedCondition<WebElement> elementToBeClickable(final By locator) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
WebElement element = visibilityOfElementLocated(locator).apply(driver);
try {
if (element != null && element.isEnabled()) {
return element;
}
return null;
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return "element to be clickable: " + locator;
}
};
}
/**
* An expectation for checking an element is visible and enabled such that you can click it.
*
* @param element the WebElement
* @return the (same) WebElement once it is clickable (visible and enabled)
*/
public static ExpectedCondition<WebElement> elementToBeClickable(final WebElement element) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver driver) {
WebElement visibleElement = visibilityOf(element).apply(driver);
try {
if (visibleElement != null && visibleElement.isEnabled()) {
return visibleElement;
}
return null;
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return "element to be clickable: " + element;
}
};
}
/**
* Wait until an element is no longer attached to the DOM.
*
* @param element The element to wait for.
* @return false if the element is still attached to the DOM, true otherwise.
*/
public static ExpectedCondition<Boolean> stalenessOf(final WebElement element) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver ignored) {
try {
// Calling any method forces a staleness check
element.isEnabled();
return false;
} catch (StaleElementReferenceException expected) {
return true;
}
}
@Override
public String toString() {
return String.format("element (%s) to become stale", element);
}
};
}
/**
* Wrapper for a condition, which allows for elements to update by redrawing.
*
* This works around the problem of conditions which have two parts: find an element and then
* check for some condition on it. For these conditions it is possible that an element is located
* and then subsequently it is redrawn on the client. When this happens a {@link
* StaleElementReferenceException} is thrown when the second part of the condition is checked.
*
* @param condition ExpectedCondition to wrap
* @param <T> return type of the condition provided
* @return the result of the provided condition
*/
public static <T> ExpectedCondition<T> refreshed(final ExpectedCondition<T> condition) {
return new ExpectedCondition<T>() {
@Override
public T apply(WebDriver driver) {
try {
return condition.apply(driver);
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return String.format("condition (%s) to be refreshed", condition);
}
};
}
/**
* An expectation for checking if the given element is selected.
*
* @param element WebElement to be selected
* @return true once the element is selected
*/
public static ExpectedCondition<Boolean> elementToBeSelected(final WebElement element) {
return elementSelectionStateToBe(element, true);
}
/**
* An expectation for checking if the given element is selected.
*
* @param element WebElement to be selected
* @param selected boolean state of the selection state of the element
* @return true once the element's selection stated is that of selected
*/
public static ExpectedCondition<Boolean> elementSelectionStateToBe(final WebElement element,
final boolean selected) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
return element.isSelected() == selected;
}
@Override
public String toString() {
return String.format("element (%s) to %sbe selected", element, (selected ? "" : "not "));
}
};
}
public static ExpectedCondition<Boolean> elementToBeSelected(final By locator) {
return elementSelectionStateToBe(locator, true);
}
public static ExpectedCondition<Boolean> elementSelectionStateToBe(final By locator,
final boolean selected) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
WebElement element = driver.findElement(locator);
return element.isSelected() == selected;
} catch (StaleElementReferenceException e) {
return null;
}
}
@Override
public String toString() {
return String.format("element found by %s to %sbe selected",
locator, (selected ? "" : "not "));
}
};
}
public static ExpectedCondition<Alert> alertIsPresent() {
return new ExpectedCondition<Alert>() {
@Override
public Alert apply(WebDriver driver) {
try {
return driver.switchTo().alert();
} catch (NoAlertPresentException e) {
return null;
}
}
@Override
public String toString() {
return "alert to be present";
}
};
}
public static ExpectedCondition<Boolean> numberOfWindowsToBe(final int expectedNumberOfWindows) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
return driver.getWindowHandles().size() == expectedNumberOfWindows;
} catch (WebDriverException e) {
return null;
}
}
@Override
public String toString() {
return "number of open windows to be " + expectedNumberOfWindows;
}
};
}
/**
* An expectation with the logical opposite condition of the given condition.
*
* Note that if the Condition you are inverting throws an exception that is caught by the Ignored
* Exceptions, the inversion will not take place and lead to confusing results.
*
* @param condition ExpectedCondition to be inverted
* @return true once the condition is satisfied
*/
public static ExpectedCondition<Boolean> not(final ExpectedCondition<?> condition) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
Object result = condition.apply(driver);
return result == null || result.equals(Boolean.FALSE);
}
@Override
public String toString() {
return "condition to not be valid: " + condition;
}
};
}
/**
* An expectation for checking WebElement with given locator has attribute with a specific value
*
* @param locator used to find the element
* @param attribute used to define css or html attribute
* @param value used as expected attribute value
* @return Boolean true when element has css or html attribute with the value
*/
public static ExpectedCondition<Boolean> attributeToBe(final By locator, final String attribute,
final String value) {
return new ExpectedCondition<Boolean>() {
private String currentValue = null;
@Override
public Boolean apply(WebDriver driver) {
WebElement element = driver.findElement(locator);
currentValue = element.getAttribute(attribute);
if (currentValue == null||currentValue.isEmpty()) {
currentValue = element.getCssValue(attribute);
}
return value.equals(currentValue);
}
@Override
public String toString() {
return String.format("element found by %s to have value \"%s\". Current value: \"%s\"",
locator, value, currentValue);
}
};
}
/**
* An expectation for checking WebElement with given locator has specific text
*
* @param locator used to find the element
* @param value used as expected text
* @return Boolean true when element has text value equal to @value
*/
public static ExpectedCondition<Boolean> textToBe(final By locator, final String value) {
return new ExpectedCondition<Boolean>() {
private String currentValue = null;
@Override
public Boolean apply(WebDriver driver) {
try {
currentValue = driver.findElement(locator).getText();
return currentValue.equals(value);
} catch (Exception e) {
return false;
}
}
@Override
public String toString() {
return String.format("element found by %s to have text \"%s\". Current text: \"%s\"",
locator, value, currentValue);
}
};
}
/**
* An expectation for checking WebElement with given locator has text with a value as a part of
* it
*
* @param locator used to find the element
* @param pattern used as expected text matcher pattern
* @return Boolean true when element has text value containing @value
*/
public static ExpectedCondition<Boolean> textMatches(final By locator, final Pattern pattern) {
return new ExpectedCondition<Boolean>() {
private String currentValue = null;
@Override
public Boolean apply(WebDriver driver) {
try {
currentValue = driver.findElement(locator).getText();
return pattern.matcher(currentValue).find();
} catch (Exception e) {
return false;
}
}
@Override
public String toString() {
return String
.format("text found by %s to match pattern \"%s\". Current text: \"%s\"",
locator, pattern.pattern(), currentValue);
}
};
}
/**
* An expectation for checking number of WebElements with given locator being more than defined number
*
* @param locator used to find the element
* @param number used to define minimum number of elements
* @return Boolean true when size of elements list is more than defined
*/
public static ExpectedCondition<List<WebElement>> numberOfElementsToBeMoreThan(final By locator,
final Integer number) {
return new ExpectedCondition<List<WebElement>>() {
private Integer currentNumber = 0;
@Override
public List<WebElement> apply(WebDriver webDriver) {
List<WebElement> elements = webDriver.findElements(locator);
currentNumber = elements.size();
return currentNumber > number ? elements : null;
}
@Override
public String toString() {
return String.format("number of elements found by %s to be more than \"%s\". Current number: \"%s\"",
locator, number, currentNumber);
}
};
}
/**
* An expectation for checking number of WebElements with given locator being less than defined
* number
*
* @param locator used to find the element
* @param number used to define maximum number of elements
* @return Boolean true when size of elements list is less than defined
*/
public static ExpectedCondition<List<WebElement>> numberOfElementsToBeLessThan(final By locator,
final Integer number) {
return new ExpectedCondition<List<WebElement>>() {
private Integer currentNumber = 0;
@Override
public List<WebElement> apply(WebDriver webDriver) {
List<WebElement> elements = webDriver.findElements(locator);
currentNumber = elements.size();
return currentNumber < number ? elements : null;
}
@Override
public String toString() {
return String.format("number of elements found by %s to be less than \"%s\". Current number: \"%s\"",
locator, number, currentNumber);
}
};
}
/**
* An expectation for checking number of WebElements with given locator
*
* @param locator used to find the element
* @param number used to define number of elements
* @return Boolean true when size of elements list is equal to defined
*/
public static ExpectedCondition<List<WebElement>> numberOfElementsToBe(final By locator,
final Integer number) {
return new ExpectedCondition<List<WebElement>>() {
private Integer currentNumber = 0;
@Override
public List<WebElement> apply(WebDriver webDriver) {
List<WebElement> elements = webDriver.findElements(locator);
currentNumber = elements.size();
return currentNumber.equals(number) ? elements : null;
}
@Override
public String toString() {
return String
.format("number of elements found by %s to be \"%s\". Current number: \"%s\"",
locator, number, currentNumber);
}
};
}
/**
* An expectation for checking given WebElement has attribute with a specific value
*
* @param element used to check its parameters
* @param attribute used to define css or html attribute
* @param value used as expected attribute value
* @return Boolean true when element has css or html attribute with the value
*/
public static ExpectedCondition<Boolean> attributeToBe(final WebElement element,
final String attribute,
final String value) {
return new ExpectedCondition<Boolean>() {
private String currentValue = null;
@Override
public Boolean apply(WebDriver driver) {
currentValue = element.getAttribute(attribute);
if (currentValue == null || currentValue.isEmpty()) {
currentValue = element.getCssValue(attribute);
}
return value.equals(currentValue);
}
@Override
public String toString() {
return String.format(attribute + " to be \"%s\". Current " + attribute + ": \"%s\"", value,
currentValue);
}
};
}
/**
* An expectation for checking WebElement with given locator has attribute which contains specific
* value
*
* @param element used to check its parameters
* @param attribute used to define css or html attribute
* @param value used as expected attribute value
* @return Boolean true when element has css or html attribute which contains the value
*/
public static ExpectedCondition<Boolean> attributeContains(final WebElement element,
final String attribute,
final String value) {
return new ExpectedCondition<Boolean>() {
private String currentValue = null;
@Override
public Boolean apply(WebDriver driver) {
return getAttributeOrCssValue(element, attribute)
.map(seen -> seen.contains(value))
.orElse(false);
}
@Override
public String toString() {
return String.format("value to contain \"%s\". Current value: \"%s\"", value, currentValue);
}
};
}
/**
* An expectation for checking WebElement with given locator has attribute which contains specific
* value
*
* @param locator used to define WebElement to check its parameters
* @param attribute used to define css or html attribute
* @param value used as expected attribute value
* @return Boolean true when element has css or html attribute which contains the value
*/
public static ExpectedCondition<Boolean> attributeContains(final By locator,
final String attribute,
final String value) {
return new ExpectedCondition<Boolean>() {
private String currentValue = null;
@Override
public Boolean apply(WebDriver driver) {
return getAttributeOrCssValue(driver.findElement(locator), attribute)
.map(seen -> seen.contains(value))
.orElse(false);
}
@Override
public String toString() {
return String.format("value found by %s to contain \"%s\". Current value: \"%s\"",
locator, value, currentValue);
}
};
}
/**
* An expectation for checking WebElement any non empty value for given attribute
*
* @param element used to check its parameters
* @param attribute used to define css or html attribute
* @return Boolean true when element has css or html attribute with non empty value
*/
public static ExpectedCondition<Boolean> attributeToBeNotEmpty(final WebElement element,
final String attribute) {
return driver -> getAttributeOrCssValue(element, attribute).isPresent();
}
private static Optional<String> getAttributeOrCssValue(WebElement element, String name) {
String value = element.getAttribute(name);
if (value == null || value.isEmpty()) {
value = element.getCssValue(name);
}
if (value == null || value.isEmpty()) {
return Optional.empty();
}
return Optional.of(value);
}
/**
* An expectation for checking child WebElement as a part of parent element to be visible
*
* @param parent used to check parent element. For example table with locator
* By.id("fish")
* @param childLocator used to find the ultimate child element.
* @return visible nested element
*/
public static ExpectedCondition<List<WebElement>> visibilityOfNestedElementsLocatedBy(
final By parent,
final By childLocator) {
return new ExpectedCondition<List<WebElement>>() {
@Override
public List<WebElement> apply(WebDriver driver) {
WebElement current = driver.findElement(parent);
List<WebElement> allChildren = current.findElements(childLocator);
// The original code only checked the first element. Fair enough.
if (!allChildren.isEmpty() && allChildren.get(0).isDisplayed()) {
return allChildren;
}
return null;
}
@Override
public String toString() {
return String.format("visibility of elements located by %s -> %s", parent, childLocator);
}
};
}
/**
* An expectation for checking child WebElement as a part of parent element to be visible
*
* @param element used as parent element. For example table with locator By.xpath("//table")
* @param childLocator used to find child element. For example td By.xpath("./tr/td")
* @return visible subelement
*/
public static ExpectedCondition<List<WebElement>> visibilityOfNestedElementsLocatedBy(
final WebElement element, final By childLocator) {
return new ExpectedCondition<List<WebElement>>() {
@Override
public List<WebElement> apply(WebDriver webDriver) {
List<WebElement> allChildren = element.findElements(childLocator);
// The original code only checked the visibility of the first element.
if (!allChildren.isEmpty() && allChildren.get(0).isDisplayed()) {
return allChildren;
}
return null;
}
@Override
public String toString() {
return String.format("visibility of element located by %s -> %s", element, childLocator);
}
};
}
/**
* An expectation for checking child WebElement as a part of parent element to present
*
* @param locator used to check parent element. For example table with locator
* By.xpath("//table")
* @param childLocator used to find child element. For example td By.xpath("./tr/td")
* @return subelement
*/
public static ExpectedCondition<WebElement> presenceOfNestedElementLocatedBy(
final By locator,
final By childLocator) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver webDriver) {
return webDriver.findElement(locator).findElement(childLocator);
}
@Override
public String toString() {
return String.format("visibility of element located by %s -> %s", locator, childLocator);
}
};
}
/**
* An expectation for checking child WebElement as a part of parent element to be present
*
* @param element used as parent element
* @param childLocator used to find child element. For example td By.xpath("./tr/td")
* @return subelement
*/
public static ExpectedCondition<WebElement> presenceOfNestedElementLocatedBy(
final WebElement element,
final By childLocator) {
return new ExpectedCondition<WebElement>() {
@Override
public WebElement apply(WebDriver webDriver) {
return element.findElement(childLocator);
}
@Override
public String toString() {
return String.format("visibility of element located by %s", childLocator);
}
};
}
/**
* An expectation for checking child WebElement as a part of parent element to present
*
* @param parent used to check parent element. For example table with locator
* By.xpath("//table")
* @param childLocator used to find child element. For example td By.xpath("./tr/td")
* @return subelement
*/
public static ExpectedCondition<List<WebElement>> presenceOfNestedElementsLocatedBy(
final By parent,
final By childLocator) {
return new ExpectedCondition<List<WebElement>>() {
@Override
public List<WebElement> apply(WebDriver driver) {
List<WebElement> allChildren = driver.findElement(parent).findElements(childLocator);
return allChildren.isEmpty() ? null : allChildren;
}
@Override
public String toString() {
return String.format("visibility of element located by %s -> %s", parent, childLocator);
}
};
}
/**
* An expectation for checking all elements from given list to be invisible
*
* @param elements used to check their invisibility
* @return Boolean true when all elements are not visible anymore
*/
public static ExpectedCondition<Boolean> invisibilityOfAllElements(
final WebElement... elements) {
return invisibilityOfAllElements(Arrays.asList(elements));
}
/**
* An expectation for checking all elements from given list to be invisible
*
* @param elements used to check their invisibility
* @return Boolean true when all elements are not visible anymore
*/
public static ExpectedCondition<Boolean> invisibilityOfAllElements(
final List<WebElement> elements) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver webDriver) {
return elements.stream().allMatch(ExpectedConditions::isInvisible);
}
@Override
public String toString() {
return "invisibility of all elements " + elements;
}
};
}
/**
* An expectation for checking the element to be invisible
*
* @param element used to check its invisibility
* @return Boolean true when elements is not visible anymore
*/
public static ExpectedCondition<Boolean> invisibilityOf(final WebElement element) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver webDriver) {
return isInvisible(element);
}
@Override
public String toString() {
return "invisibility of " + element;
}
};
}
private static boolean isInvisible(final WebElement element) {
try {
return !element.isDisplayed();
} catch (StaleElementReferenceException ignored) {
// We can assume a stale element isn't displayed.
return true;
}
}
/**
* An expectation with the logical or condition of the given list of conditions.
*
* Each condition is checked until at least one of them returns true or not null.
*
* @param conditions ExpectedCondition is a list of alternative conditions
* @return true once one of conditions is satisfied
*/
public static ExpectedCondition<Boolean> or(final ExpectedCondition<?>... conditions) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
RuntimeException lastException = null;
for (ExpectedCondition<?> condition : conditions) {
try {
Object result = condition.apply(driver);
if (result != null) {
if (result instanceof Boolean) {
if (Boolean.TRUE.equals(result)) {
return true;
}
} else {
return true;
}
}
} catch (RuntimeException e) {
lastException = e;
}
}
if (lastException != null) {
throw lastException;
}
return false;
}
@Override
public String toString() {
StringBuilder message = new StringBuilder("at least one condition to be valid: ");
Joiner.on(" || ").appendTo(message, conditions);
return message.toString();
}
};
}
/**
* An expectation with the logical and condition of the given list of conditions.
*
* Each condition is checked until all of them return true or not null
*
* @param conditions ExpectedCondition is a list of alternative conditions
* @return true once all conditions are satisfied
*/
public static ExpectedCondition<Boolean> and(final ExpectedCondition<?>... conditions) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
for (ExpectedCondition<?> condition : conditions) {
Object result = condition.apply(driver);
if (result instanceof Boolean) {
if (Boolean.FALSE.equals(result)) {
return false;
}
}
if (result == null) {
return false;
}
}
return true;
}
@Override
public String toString() {
StringBuilder message = new StringBuilder("all conditions to be valid: ");
Joiner.on(" && ").appendTo(message, conditions);
return message.toString();
}
};
}
/**
* An expectation to check if js executable.
*
* Useful whenyou know that there should be a Javascript value or something at the stage.
*
* @param javaScript used as executable script
* @return true once javaScript executed without errors
*/
public static ExpectedCondition<Boolean> javaScriptThrowsNoExceptions(final String javaScript) {
return new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
((JavascriptExecutor) driver).executeScript(javaScript);
return true;
} catch (WebDriverException e) {
return false;
}
}
@Override
public String toString() {
return String.format("js %s to be executable", javaScript);
}
};
}
/**
* An expectation for String value from javascript
*
* @param javaScript as executable js line
* @return true once js return string
*/
public static ExpectedCondition<Object> jsReturnsValue(final String javaScript) {
return new ExpectedCondition<Object>() {
@Override
public Object apply(WebDriver driver) {
try {
Object value = ((JavascriptExecutor) driver).executeScript(javaScript);
if (value instanceof List) {
return ((List<?>) value).isEmpty() ? null : value;
}
if (value instanceof String) {
return ((String) value).isEmpty() ? null : value;
}
return value;
} catch (WebDriverException e) {
return null;
}
}
@Override
public String toString() {
return String.format("js %s to be executable", javaScript);
}
};
}
}