package com.codeborne.selenide; import org.openqa.selenium.*; import org.openqa.selenium.WebDriver.TargetLocator; import org.openqa.selenium.support.ui.ExpectedCondition; import java.util.ArrayList; import java.util.List; import java.util.Set; import static com.codeborne.selenide.Configuration.timeout; import static com.codeborne.selenide.Selenide.Wait; import static com.codeborne.selenide.WebDriverRunner.getWebDriver; import static com.codeborne.selenide.ex.UIAssertionError.wrapThrowable; import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent; import static org.openqa.selenium.support.ui.ExpectedConditions.frameToBeAvailableAndSwitchToIt; public class SelenideTargetLocator implements TargetLocator { private final TargetLocator delegate; SelenideTargetLocator(TargetLocator delegate) { this.delegate = delegate; } @Override public WebDriver frame(int index) { return Wait().until(frameToBeAvailableAndSwitchToIt(index)); } @Override public WebDriver frame(String nameOrId) { return Wait().until(frameToBeAvailableAndSwitchToIt(nameOrId)); } @Override public WebDriver frame(WebElement frameElement) { return Wait().until(frameToBeAvailableAndSwitchToIt(frameElement)); } @Override public WebDriver parentFrame() { return delegate.parentFrame(); } @Override public WebDriver defaultContent() { return delegate.defaultContent(); } @Override public WebElement activeElement() { return delegate.activeElement(); } @Override public Alert alert() { return Wait().until(alertIsPresent()); } /** * Switch to the inner frame (last child frame in given sequence) */ public WebDriver innerFrame(String... frames) { WebDriver driver = getWebDriver(); delegate.defaultContent(); for (String frame : frames) { try { String selector = String.format("frame#%1$s,frame[name=%1$s],iframe#%1$s,iframe[name=%1$s]", frame); Wait().until(frameToBeAvailableAndSwitchToIt_fixed(By.cssSelector(selector))); } catch (NoSuchElementException | TimeoutException e) { throw new NoSuchFrameException("No frame found with id/name = " + frame, e); } } return driver; } private static ExpectedCondition<WebDriver> frameToBeAvailableAndSwitchToIt_fixed(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; } catch (WebDriverException e) { return null; } } @Override public String toString() { return "frame to be available: " + locator; } }; } private static ExpectedCondition<WebDriver> windowToBeAvailableAndSwitchToIt(final String nameOrHandleOrTitle) { return new ExpectedCondition<WebDriver>() { @Override public WebDriver apply(WebDriver driver) { try { return driver.switchTo().window(nameOrHandleOrTitle); } catch (NoSuchWindowException windowWithNameOrHandleNotFound) { try { return windowByTitle(nameOrHandleOrTitle); } catch (NoSuchWindowException e) { return null; } } } @Override public String toString() { return "window to be available by name or handle or title: " + nameOrHandleOrTitle; } }; } private static ExpectedCondition<WebDriver> windowToBeAvailableAndSwitchToIt(final int index) { return new ExpectedCondition<WebDriver>() { @Override public WebDriver apply(WebDriver driver) { try { List<String> windowHandles = new ArrayList<>(driver.getWindowHandles()); return driver.switchTo().window(windowHandles.get(index)); } catch (IndexOutOfBoundsException windowWithIndexNotFound) { return null; } } @Override public String toString() { return "window to be available by index: " + index; } }; } /** * Switch to window/tab by index * NB! Order of windows/tabs can be different in different browsers, see Selenide tests. * @param index index of window (0-based) */ public WebDriver window(int index) { try { return Wait().until(windowToBeAvailableAndSwitchToIt(index)); } catch (TimeoutException e) { throw wrapThrowable(e, timeout); } } /** * Switch to window/tab by name/handle/title * @param nameOrHandleOrTitle name or handle or title of window/tab */ @Override public WebDriver window(String nameOrHandleOrTitle) { try { return Wait().until(windowToBeAvailableAndSwitchToIt(nameOrHandleOrTitle)); } catch (NoSuchWindowException windowWithNameOrHandleNotFound) { return windowByTitle(nameOrHandleOrTitle); } catch (TimeoutException e) { throw wrapThrowable(e, timeout); } } /** * Switch to window/tab by name/handle/title except some windows handles * @param title title of window/tab */ protected static WebDriver windowByTitle(String title) { WebDriver driver = getWebDriver(); Set<String> windowHandles = driver.getWindowHandles(); for (String windowHandle : windowHandles) { driver.switchTo().window(windowHandle); if (title.equals(driver.getTitle())) { return driver; } } throw new NoSuchWindowException("Window with title not found: " + title); } }