package org.fluentlenium.core.action; import org.fluentlenium.core.FluentControl; import org.fluentlenium.core.components.ComponentInstantiator; import org.fluentlenium.core.domain.FluentWebElement; import org.fluentlenium.core.switchto.FluentTargetLocator; import org.fluentlenium.core.switchto.FluentTargetLocatorImpl; import org.openqa.selenium.Dimension; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.Point; import org.openqa.selenium.WebDriver; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; /** * Execute actions on active window. */ public class WindowAction { private final FluentControl fluentControl; private final ComponentInstantiator instantiator; private final WebDriver driver; /** * Creates a new window action. * * @param control control interface * @param instantiator component instantiator * @param driver selenium driver */ public WindowAction(FluentControl control, ComponentInstantiator instantiator, WebDriver driver) { this.driver = driver; this.instantiator = instantiator; fluentControl = control; } /** * Gets the page title. * * @return page title text */ public String title() { return driver.getTitle(); } /** * Maximize the current window. * * @return the WindowAction object itself */ public WindowAction maximize() { driver.manage().window().maximize(); return this; } /** * FullScreen the current window. * * @return the WindowAction object itself */ public WindowAction fullscreen() { driver.manage().window().fullscreen(); return this; } /** * Sets the current window size. * * @param size size of the window * @return the WindowAction object itself */ public WindowAction setSize(Dimension size) { driver.manage().window().setSize(size); return this; } /** * Gets the current window size. * * @return the current window size */ public Dimension getSize() { return driver.manage().window().getSize(); } /** * Sets the current window position. * * @param position position to set * @return the WindowAction object itself */ public WindowAction setPosition(Point position) { driver.manage().window().setPosition(position); return this; } /** * Gets the current window position. * * @return the WindowAction object itself */ public Point getPosition() { return driver.manage().window().getPosition(); } /** * Clicks button, which opens new window and switches to newly opened window. * <p> * This method doesn't force opening window in new window, we assume the code under test will open new window. * * @param button button to be clicked * @return handle of old (parent) window */ public String clickAndOpenNew(FluentWebElement button) { String oldWindowHandle = driver.getWindowHandle(); Set<String> oldWindowHandles = driver.getWindowHandles(); button.click(); waitForNewWindowToOpen(oldWindowHandles); Set<String> newWindowHandles = new HashSet<>(driver.getWindowHandles()); newWindowHandles.removeAll(oldWindowHandles); String newWindowHandle = newWindowHandles.iterator().next(); switchTo(newWindowHandle); return oldWindowHandle; } /** * Opens new window. * * @return handle of old (parent) window */ public String openNewAndSwitch() { Set<String> oldWindowHandles = driver.getWindowHandles(); String oldWindowHandle = driver.getWindowHandle(); JavascriptExecutor jse = (JavascriptExecutor) driver; jse.executeScript("window.open('someUrl', '_blank')"); waitForNewWindowToOpen(oldWindowHandles); switchToLast(oldWindowHandle); return oldWindowHandle; } /** * Clicks button, which closes current window and switches to last window (in set returned by * {@link WebDriver#getWindowHandles()}). * <p> * If the last window is not the target window, use {@link #switchTo(String)} * to focus on desired window * * @param button button to be clicked */ public void clickAndCloseCurrent(FluentWebElement button) { String currentWindowHandle = driver.getWindowHandle(); button.click(); fluentControl.await().untilWindow(currentWindowHandle).notDisplayed(); switchToLast(); } /** * Close the current window. */ public void close() { driver.close(); } /** * Create a switch target locator. * * @return an object to perform switch on various target. */ public FluentTargetLocator<WindowAction> switchTo() { return new FluentTargetLocatorImpl<>(this, instantiator, driver.switchTo()); } /** * Switches to lastly opened window. * * @return the WindowAction object itself */ public WindowAction switchToLast() { List<String> windowHandles = new ArrayList<>(driver.getWindowHandles()); driver.switchTo().window(windowHandles.get(windowHandles.size() - 1)); return this; } /** * Switches to lastly opened window excluding the one provided as a parameter. * * @param nameOrHandleToExclude if list size is greater than one it will be removed * @return the WindowAction object itself */ public WindowAction switchToLast(String nameOrHandleToExclude) { List<String> windowHandles = new ArrayList<>(driver.getWindowHandles()); if (windowHandles.size() > 1) { windowHandles.remove(nameOrHandleToExclude); } driver.switchTo().window(windowHandles.get(windowHandles.size() - 1)); return this; } /** * Switches to particular window by handle. * * @param nameOrHandle window name or handle * @return the WindowAction object itself */ public WindowAction switchTo(String nameOrHandle) { return switchTo().window(nameOrHandle); } /** * Gets the current window object. * * @return the WebDriver.Window object */ public WebDriver.Window getWindow() { return driver.manage().window(); } private class WindowHandlesCountIs implements Predicate<FluentControl> { private final int expectedValue; WindowHandlesCountIs(int expectedValue) { this.expectedValue = expectedValue; } @Override public boolean test(FluentControl fluentControl) { return driver.getWindowHandles().size() == expectedValue; } } private void waitForNewWindowToOpen(Set<String> oldWindowHandles) { fluentControl.await().atMost(10, TimeUnit.SECONDS).withMessage("Timed out waiting for new window to open.") .untilPredicate(new WindowHandlesCountIs(oldWindowHandles.size() + 1)); } }