package org.keycloak.testsuite.util; import org.jboss.logging.Logger; import org.openqa.selenium.TimeoutException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.ie.InternetExplorerDriver; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; import java.util.regex.Pattern; import static org.openqa.selenium.support.ui.ExpectedConditions.not; import static org.openqa.selenium.support.ui.ExpectedConditions.or; import static org.openqa.selenium.support.ui.ExpectedConditions.urlMatches; import static org.openqa.selenium.support.ui.ExpectedConditions.urlToBe; /** * @author Vaclav Muzikar <vmuzikar@redhat.com> */ public final class URLUtils { public static void navigateToUri(WebDriver driver, String uri, boolean waitForMatch) { navigateToUri(driver, uri, waitForMatch, true); } private static void navigateToUri(WebDriver driver, String uri, boolean waitForMatch, boolean enableIEWorkaround) { Logger log = Logger.getLogger(URLUtils.class); log.info("starting navigation"); // In IE, sometime the current URL is not correct; one of the indicators is that the target URL // equals the current URL if (driver instanceof InternetExplorerDriver && driver.getCurrentUrl().equals(uri)) { log.info("IE workaround: target URL equals current URL - refreshing the page"); driver.navigate().refresh(); } WaitUtils.waitForPageToLoad(driver); log.info("current URL: " + driver.getCurrentUrl()); log.info("navigating to " + uri); driver.navigate().to(uri); if (waitForMatch) { // Possible login URL; this is to eliminate unnecessary wait when navigating to a secured page and being // redirected to the login page String loginUrl = "^[^\\?]+/auth/realms/[^/]+/(protocol|login-actions).+$"; try { (new WebDriverWait(driver, 3)).until(or(urlMatches("^" + Pattern.quote(uri) + ".*$"), urlMatches(loginUrl))); } catch (TimeoutException e) { log.info("new current URL doesn't start with desired URL"); } } WaitUtils.waitForPageToLoad(driver); log.info("new current URL: " + driver.getCurrentUrl()); // In IE, after deleting the cookies for test realm, the first loaded page in master's admin console // contains invalid URL (misses #/realms/[realm] or contains state and code fragments), although the // address bar states the correct URL; seemingly this is another bug in IE WebDriver) if (enableIEWorkaround && driver instanceof InternetExplorerDriver && (driver.getCurrentUrl().matches("^[^#]+/#state=[^#/&]+&code=[^#/&]+$") || driver.getCurrentUrl().matches("^.+/auth/admin/[^/]+/console/$"))) { log.info("IE workaround: reloading the page after deleting the cookies..."); navigateToUri(driver, uri, waitForMatch, false); } else { log.info("navigation complete"); } } public static boolean currentUrlEqual(WebDriver driver, String url) { return urlCheck(driver, urlToBe(url)); } public static boolean currentUrlDoesntEqual(WebDriver driver, String url) { return urlCheck(driver, not(urlToBe(url))); } public static boolean currentUrlStartWith(WebDriver driver, String url) { return urlCheck(driver, urlMatches("^" + Pattern.quote(url) + ".*$")); } public static boolean currentUrlDoesntStartWith(WebDriver driver, String url) { return urlCheck(driver, urlMatches("^(?!" + Pattern.quote(url) + ").+$")); } private static boolean urlCheck(WebDriver driver, ExpectedCondition condition) { return urlCheck(driver, condition, false); } private static boolean urlCheck(WebDriver driver, ExpectedCondition condition, boolean secondTry) { Logger log = Logger.getLogger(URLUtils.class); try { (new WebDriverWait(driver, 1, 100)).until(condition); } catch (TimeoutException e) { if (driver instanceof InternetExplorerDriver && !secondTry) { // IE WebDriver has sometimes invalid current URL log.info("IE workaround: checking URL failed at first attempt - refreshing the page and trying one more time..."); driver.navigate().refresh(); urlCheck(driver, condition, true); } else { return false; } } return true; } }