Skip to content

Commit

Permalink
[java] Adding a command to open a new window. Implementation mimics a…
Browse files Browse the repository at this point in the history
…lready existing .Net one.
  • Loading branch information
barancev committed Feb 19, 2019
1 parent f082bb6 commit 501f2f7
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 6 deletions.
12 changes: 12 additions & 0 deletions java/client/src/org/openqa/selenium/WebDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,18 @@ interface TargetLocator {
*/
WebDriver window(String nameOrHandle);

/**
* Creates a new browser window and switches the focus for future commands of this driver
* to the new window..
*
* @param typeHint The type of new browser window to be created. The created window is not
* guaranteed to be of the requested type; if the driver does not support
* the requested type, a new browser window will be created of whatever type
* the driver does support.
* @return This driver focused on the given window
*/
WebDriver newWindow(WindowType typeHint);

/**
* Selects either the first frame on the page, or the main document when a page contains
* iframes.
Expand Down
50 changes: 50 additions & 0 deletions java/client/src/org/openqa/selenium/WindowType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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;

/**
* Represents the type of a new browser window that may be created.
*/
public enum WindowType {

WINDOW ("window"),
TAB ("tab"),
;

private String text;

WindowType(String text) {
this.text = text;
}

@Override
public String toString() {
return String.valueOf(text);
}

public static WindowType fromString(String text) {
if (text != null) {
for (WindowType b : WindowType.values()) {
if (text.equalsIgnoreCase(b.text)) {
return b;
}
}
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
import org.openqa.selenium.Cookie;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.interactions.Sequence;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
Expand Down Expand Up @@ -121,6 +121,11 @@ static CommandPayload UPLOAD_FILE(String file) {
static CommandPayload SWITCH_TO_WINDOW(String windowHandleOrName) {
return new CommandPayload(SWITCH_TO_WINDOW, ImmutableMap.of("handle", windowHandleOrName));
}
String SWITCH_TO_NEW_WINDOW = "newWindow";
static CommandPayload SWITCH_TO_NEW_WINDOW(WindowType typeHint) {
return new CommandPayload(SWITCH_TO_NEW_WINDOW, ImmutableMap.of("type", typeHint.toString()));
}

String SWITCH_TO_CONTEXT = "switchToContext";
String SWITCH_TO_FRAME = "switchToFrame";
static CommandPayload SWITCH_TO_FRAME(Object frame) {
Expand Down
15 changes: 15 additions & 0 deletions java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.interactions.HasInputDevices;
import org.openqa.selenium.interactions.Interactive;
import org.openqa.selenium.interactions.Keyboard;
Expand Down Expand Up @@ -974,6 +975,20 @@ public WebDriver window(String windowHandleOrName) {
}
}

@Override
public WebDriver newWindow(WindowType typeHint) {
String original = getWindowHandle();
try {
Response response = execute(DriverCommand.SWITCH_TO_NEW_WINDOW(typeHint));
String newWindowHandle = ((Map<String, Object>) response.getValue()).get("handle").toString();
switchTo().window(newWindowHandle);
return RemoteWebDriver.this;
} catch (WebDriverException ex) {
switchTo().window(original);
throw ex;
}
}

@Override
public WebDriver defaultContent() {
execute(DriverCommand.SWITCH_TO_FRAME(null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import static org.openqa.selenium.remote.DriverCommand.STATUS;
import static org.openqa.selenium.remote.DriverCommand.SWITCH_TO_CONTEXT;
import static org.openqa.selenium.remote.DriverCommand.SWITCH_TO_FRAME;
import static org.openqa.selenium.remote.DriverCommand.SWITCH_TO_NEW_WINDOW;
import static org.openqa.selenium.remote.DriverCommand.SWITCH_TO_PARENT_FRAME;
import static org.openqa.selenium.remote.DriverCommand.SWITCH_TO_WINDOW;
import static org.openqa.selenium.remote.DriverCommand.UPLOAD_FILE;
Expand Down Expand Up @@ -139,6 +140,7 @@ public AbstractHttpCommandCodec() {

defineCommand(CLOSE, delete("/session/:sessionId/window"));
defineCommand(SWITCH_TO_WINDOW, post("/session/:sessionId/window"));
defineCommand(SWITCH_TO_NEW_WINDOW, post("/session/:sessionId/window/new"));

defineCommand(FULLSCREEN_CURRENT_WINDOW, post("/session/:sessionId/window/fullscreen"));

Expand Down Expand Up @@ -265,7 +267,6 @@ public Command decode(final HttpRequest encodedCommand) {

String content = encodedCommand.getContentString();
if (!content.isEmpty()) {
@SuppressWarnings("unchecked")
Map<String, Object> tmp = json.toType(content, MAP_TYPE);
parameters.putAll(tmp);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.WrapsDriver;
import org.openqa.selenium.WrapsElement;
import org.openqa.selenium.interactions.Coordinates;
Expand Down Expand Up @@ -720,6 +721,14 @@ public WebDriver window(String windowName) {
return driverToReturn;
}

@Override
public WebDriver newWindow(WindowType typeHint) {
dispatcher.beforeSwitchToWindow(null, driver);
WebDriver driverToReturn = targetLocator.newWindow(typeHint);
dispatcher.afterSwitchToWindow(null, driver);
return driverToReturn;
}

@Override
public WebDriver defaultContent() {
return targetLocator.defaultContent();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;

public interface WebDriverEventListener {

Expand Down Expand Up @@ -175,7 +176,7 @@ public interface WebDriverEventListener {
void afterChangeValueOf(WebElement element, WebDriver driver, CharSequence[] keysToSend);

/**
* Called before {@link org.openqa.selenium.remote.RemoteWebDriver#executeScript(java.lang.String, java.lang.Object[]) }
* Called before {@link org.openqa.selenium.remote.RemoteWebDriver#executeScript(String, Object...)}
*
* @param driver WebDriver
* @param script the script to be executed
Expand All @@ -185,7 +186,7 @@ public interface WebDriverEventListener {
void beforeScript(String script, WebDriver driver);

/**
* Called after {@link org.openqa.selenium.remote.RemoteWebDriver#executeScript(java.lang.String, java.lang.Object[]) }.
* Called after {@link org.openqa.selenium.remote.RemoteWebDriver#executeScript(String, Object...)}.
* Not called if an exception is thrown
*
* @param driver WebDriver
Expand All @@ -197,15 +198,23 @@ public interface WebDriverEventListener {
void afterScript(String script, WebDriver driver);

/**
* This action will be performed each time before {@link org.openqa.selenium.WebDriver.TargetLocator#window(java.lang.String)}
* This action will be performed each time before {@link org.openqa.selenium.WebDriver.TargetLocator#window(String)}
*
* @param windowName The name of the window or the handle as returned by
* {@link org.openqa.selenium.WebDriver#getWindowHandle()}
* or <code>null</code> if switching to a new window created by
* {@link org.openqa.selenium.WebDriver.TargetLocator#newWindow(WindowType)}
* @param driver WebDriver
*/
void beforeSwitchToWindow(String windowName, WebDriver driver);

/**
* This action will be performed each time after {@link org.openqa.selenium.WebDriver.TargetLocator#window(java.lang.String)}
* This action will be performed each time after {@link org.openqa.selenium.WebDriver.TargetLocator#window(String)}
*
* @param windowName The name of the window or the handle as returned by
* {@link org.openqa.selenium.WebDriver#getWindowHandle()}
* or <code>null</code> if switching to a new window created by
* {@link org.openqa.selenium.WebDriver.TargetLocator#newWindow(WindowType)}
* @param driver WebDriver
*/
void afterSwitchToWindow(String windowName, WebDriver driver);
Expand Down
28 changes: 28 additions & 0 deletions java/client/test/org/openqa/selenium/WindowSwitchingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,13 @@
import static org.openqa.selenium.WaitingConditions.windowHandleCountToBe;
import static org.openqa.selenium.WaitingConditions.windowHandleCountToBeGreaterThan;
import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent;
import static org.openqa.selenium.testing.drivers.Browser.CHROME;
import static org.openqa.selenium.testing.drivers.Browser.FIREFOX;
import static org.openqa.selenium.testing.drivers.Browser.HTMLUNIT;
import static org.openqa.selenium.testing.drivers.Browser.IE;
import static org.openqa.selenium.testing.drivers.Browser.MARIONETTE;
import static org.openqa.selenium.testing.drivers.Browser.OPERA;
import static org.openqa.selenium.testing.drivers.Browser.OPERABLINK;
import static org.openqa.selenium.testing.drivers.Browser.SAFARI;
import static org.openqa.selenium.testing.TestUtilities.isIe6;
import static org.openqa.selenium.testing.TestUtilities.isInternetExplorer;
Expand Down Expand Up @@ -351,4 +356,27 @@ public void testShouldFocusOnTheTopMostFrameAfterSwitchingToAWindow() {
driver.findElement(By.name("myframe"));
}

@NoDriverAfterTest(failedOnly = true)
@Test
@NotYetImplemented(CHROME)
@NotYetImplemented(HTMLUNIT)
@NotYetImplemented(SAFARI) // actually not tested in this browser
@NotYetImplemented(OPERABLINK)
@Ignore(FIREFOX)
@Ignore(OPERA)
public void canOpenANewWindow() {
driver.get(pages.xhtmlTestPage);

String mainWindow = driver.getWindowHandle();
driver.switchTo().newWindow(WindowType.TAB);

assertThat(driver.getWindowHandles()).hasSize(2);

// no wait, the command should block until the new window is ready
String newHandle = driver.getWindowHandle();
assertThat(newHandle).isNotEqualTo(mainWindow);

driver.close();
driver.switchTo().window(mainWindow);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;

import java.io.IOException;
import java.lang.reflect.Array;
Expand Down Expand Up @@ -416,6 +417,22 @@ public void canHandleSwitchToWindowCommand() throws IOException {
new CommandPayload(DriverCommand.SWITCH_TO_WINDOW, ImmutableMap.of("handle", "window1")));
}

@Test
public void canHandleSwitchToNewWindowCommand() throws IOException {
CommandExecutor executor = prepareExecutorMock(
echoCapabilities, valueResponder(ImmutableMap.of("handle", "new window")));

RemoteWebDriver driver = new RemoteWebDriver(executor, new ImmutableCapabilities());
WebDriver driver2 = driver.switchTo().newWindow(WindowType.TAB);

assertThat(driver2).isSameAs(driver);
verifyCommands(
executor, driver.getSessionId(),
new CommandPayload(DriverCommand.GET_CURRENT_WINDOW_HANDLE, ImmutableMap.of()),
new CommandPayload(DriverCommand.SWITCH_TO_NEW_WINDOW, ImmutableMap.of("type", "tab")),
new CommandPayload(DriverCommand.SWITCH_TO_WINDOW, ImmutableMap.of("handle", "new window")));
}

@Test
public void canHandleSwitchToFrameByIndexCommand() throws IOException {
CommandExecutor executor = prepareExecutorMock(echoCapabilities, nullResponder);
Expand Down

0 comments on commit 501f2f7

Please sign in to comment.