diff --git a/java/src/org/openqa/selenium/support/ui/ExpectedConditions.java b/java/src/org/openqa/selenium/support/ui/ExpectedConditions.java index a294cdfdb98f7..1d170bdd810e1 100644 --- a/java/src/org/openqa/selenium/support/ui/ExpectedConditions.java +++ b/java/src/org/openqa/selenium/support/ui/ExpectedConditions.java @@ -18,9 +18,13 @@ package org.openqa.selenium.support.ui; import com.google.common.base.Joiner; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Optional; +import java.util.function.Predicate; import java.util.regex.Pattern; import org.openqa.selenium.Alert; import org.openqa.selenium.By; @@ -157,6 +161,37 @@ public String toString() { }; } + /** + * An expectation for checking that the current URL fulfills a given predicate. + * + * @param predicate a predicate that tests a URI and returns true if the condition is satisfied + * @return true when the predicate applied to the current URL returns true, false otherwise + */ + public static ExpectedCondition urlFulfills(Predicate predicate) { + Objects.requireNonNull(predicate, "predicate cannot be null"); + + return new ExpectedCondition() { + private String currentUrl = ""; + + @Override + public Boolean apply(WebDriver driver) { + currentUrl = driver.getCurrentUrl(); + try { + URI uri = new URI(currentUrl); + return predicate.test(uri); + } catch (URISyntaxException e) { + return false; + } + } + + @Override + public String toString() { + return String.format( + "url to apply a predicate. Current url: \"%s\"", 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. diff --git a/java/test/org/openqa/selenium/support/ui/ExpectedConditionsTest.java b/java/test/org/openqa/selenium/support/ui/ExpectedConditionsTest.java index d7cccb7616a38..85a0d901b8026 100644 --- a/java/test/org/openqa/selenium/support/ui/ExpectedConditionsTest.java +++ b/java/test/org/openqa/selenium/support/ui/ExpectedConditionsTest.java @@ -46,6 +46,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.textToBePresentInElement; import static org.openqa.selenium.support.ui.ExpectedConditions.textToBePresentInElementLocated; import static org.openqa.selenium.support.ui.ExpectedConditions.urlContains; +import static org.openqa.selenium.support.ui.ExpectedConditions.urlFulfills; import static org.openqa.selenium.support.ui.ExpectedConditions.urlMatches; import static org.openqa.selenium.support.ui.ExpectedConditions.urlToBe; import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOf; @@ -54,6 +55,7 @@ import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfNestedElementsLocatedBy; import com.google.common.collect.Sets; +import java.net.URI; import java.time.Duration; import java.time.Instant; import java.util.ArrayList; @@ -157,6 +159,50 @@ void negative_waitingForUrlToBeOpened_urlMatches() { .isThrownBy(() -> wait.until(urlMatches(".*\\/malformed.*"))); } + @Test + void waitingForUrlToBeOpened_urlFulfills() { + final String url = "https://example.com:8080/path"; + when(mockDriver.getCurrentUrl()).thenReturn(url); + + wait.until(urlFulfills(uri -> "https".equals(uri.getScheme()))); + wait.until(urlFulfills(uri -> "example.com".equals(uri.getHost()))); + wait.until(urlFulfills(uri -> uri.getPort() == 8080)); + wait.until(urlFulfills(uri -> "/path".equals(uri.getPath()))); + } + + @Test + void waitingForUrlToBeOpened_urlFulfills_withAbsoluteUrl() { + final String url = "https://example.com/absolute/path"; + when(mockDriver.getCurrentUrl()).thenReturn(url); + + wait.until(urlFulfills(URI::isAbsolute)); + } + + @Test + void negative_waitingForUrlToBeOpened_urlFulfills() { + final String url = "http://example.com/path"; + when(mockDriver.getCurrentUrl()).thenReturn(url); + + assertThatExceptionOfType(TimeoutException.class) + .isThrownBy(() -> wait.until(urlFulfills(uri -> "https".equals(uri.getScheme())))); + } + + @Test + void negative_waitingForUrlToBeOpened_urlFulfills_malformedUrl() { + final String url = "not-a-valid-url"; + when(mockDriver.getCurrentUrl()).thenReturn(url); + + assertThatExceptionOfType(TimeoutException.class) + .isThrownBy(() -> wait.until(urlFulfills(URI::isAbsolute))); + } + + @Test + void urlFulfills_throwsNullPointerException_whenPredicateIsNull() { + assertThatExceptionOfType(NullPointerException.class) + .isThrownBy(() -> urlFulfills(null)) + .withMessage("predicate cannot be null"); + } + @Test void waitingForVisibilityOfElement_elementAlreadyVisible() { when(mockElement.isDisplayed()).thenReturn(true);