Skip to content

Commit

Permalink
Implementing support for switching context as described here: http://…
Browse files Browse the repository at this point in the history
…code.google.com/p/selenium/source/browse/spec-draft.md?repo=mobile#133

- this feature will be used by mobile WebDriver users to switch between different contexts like the native or the webview UI element tree
- The feature is end to end tested with latest selendroid snapshot version (6a126ab3782deb7dd0cc99c6e3785c72d636959b)
  • Loading branch information
DominikDary committed Mar 12, 2014
1 parent b086af5 commit 8b6b171
Show file tree
Hide file tree
Showing 11 changed files with 179 additions and 0 deletions.
33 changes: 33 additions & 0 deletions java/client/src/org/openqa/selenium/NoSuchContextException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
Copyright 2014 Software Freedom Conservancy
Licensed 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;

/**
* Thrown by {@link org.openqa.selenium.WebDriver.TargetLocator#context(String) WebDriver.switchTo().context(String
* name)}.
*/
public class NoSuchContextException extends NotFoundException {

public NoSuchContextException(String reason) {
super(reason);
}

public NoSuchContextException(String reason, Throwable cause) {
super(reason, cause);
}

}
25 changes: 25 additions & 0 deletions java/client/src/org/openqa/selenium/WebDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,20 @@ public interface WebDriver extends SearchContext {
*/
String getWindowHandle();

/**
* Return a set of context handles which can be used to iterate over all contexts of this
* WebDriver instance
*
* @return A set of context handles which can be used to iterate over available contexts.
*/
Set<String> getContextHandles();

/**
* Return an opaque handle to this context that uniquely identifies it within this driver instance.
* This can be used to switch to this context at a later date
*/
String getContext();

/**
* Send future commands to a different frame or window.
*
Expand Down Expand Up @@ -374,6 +388,17 @@ interface TargetLocator {
* @throws NoAlertPresentException If the dialog cannot be found
*/
Alert alert();

/**
* Switch the focus of future commands for this driver to the context with the given name.
*
* @param name The name of the context as returned by
* {@link WebDriver#getContexts()}
* @return This driver focused on the given window
* @throws NoSuchContextException If the context cannot be found
*/
WebDriver context(String name);

}

interface Navigation {
Expand Down
14 changes: 14 additions & 0 deletions java/client/src/org/openqa/selenium/htmlunit/HtmlUnitDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,16 @@ public String getWindowHandle() {
return String.valueOf(System.identityHashCode(topWindow));
}

@Override
public Set<String> getContextHandles() {
throw new UnsupportedOperationException("getContextHandles");
}

@Override
public String getContext() {
throw new UnsupportedOperationException("getContext");
}

public Object executeScript(String script, final Object... args) {
HtmlPage page = getPageToInjectScriptInto();

Expand Down Expand Up @@ -1223,6 +1233,10 @@ public WebElement activeElement() {
public Alert alert() {
throw new UnsupportedOperationException("alert()");
}

public WebDriver context(String name) {
throw new UnsupportedOperationException("context(String)");
}
}

protected <X> X implicitlyWaitFor(Callable<X> condition) {
Expand Down
4 changes: 4 additions & 0 deletions java/client/src/org/openqa/selenium/remote/DriverCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ public interface DriverCommand {
String GET_CURRENT_WINDOW_HANDLE = "getCurrentWindowHandle";
String GET_WINDOW_HANDLES = "getWindowHandles";

String GET_CURRENT_CONTEXT_HANDLE = "getCurrentContextHandle";
String GET_CONTEXT_HANDLES = "getContextHandles";

String SWITCH_TO_WINDOW = "switchToWindow";
String SWITCH_TO_CONTEXT = "switchToContext";
String SWITCH_TO_FRAME = "switchToFrame";
String GET_ACTIVE_ELEMENT = "getActiveElement";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ public HttpCommandExecutor(Map<String, CommandInfo> additionalCommands, URL addr
.put(IS_BROWSER_ONLINE, get("/session/:sessionId/browser_connection"))
.put(SET_BROWSER_ONLINE, post("/session/:sessionId/browser_connection"))

.put(SWITCH_TO_CONTEXT, post("/session/:sessionId/context"))
.put(GET_CURRENT_CONTEXT_HANDLE, get("/session/:sessionId/context"))
.put(GET_CONTEXT_HANDLES, get("/session/:sessionId/contexts"))

// TODO (user): Would it be better to combine this command with
// GET_LOCAL_STORAGE_SIZE?
.put(GET_LOCAL_STORAGE_ITEM, get("/session/:sessionId/local_storage/key/:key"))
Expand Down
24 changes: 24 additions & 0 deletions java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,24 @@ public String getWindowHandle() {
return String.valueOf(execute(DriverCommand.GET_CURRENT_WINDOW_HANDLE).getValue());
}

@Override
public Set<String> getContextHandles() {
Response response = execute(DriverCommand.GET_CONTEXT_HANDLES);
Object value = response.getValue();
try {
List<String> returnedValues = (List<String>) value;
return new LinkedHashSet<String>(returnedValues);
} catch (ClassCastException ex) {
throw new WebDriverException(
"Returned value cannot be converted to List<String>: " + value, ex);
}
}

@Override
public String getContext() {
return String.valueOf(execute(DriverCommand.GET_CURRENT_CONTEXT_HANDLE).getValue());
}

public Object executeScript(String script, Object... args) {
if (!capabilities.isJavascriptEnabled()) {
throw new UnsupportedOperationException(
Expand Down Expand Up @@ -868,6 +886,12 @@ public Alert alert() {
execute(DriverCommand.GET_ALERT_TEXT);
return new RemoteAlert();
}

@Override
public WebDriver context(String name) {
execute(DriverCommand.SWITCH_TO_CONTEXT, ImmutableMap.of("name", name));
return RemoteWebDriver.this;
}
}

private class RemoteAlert implements Alert {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,16 @@ public String getWindowHandle() {
return driver.getWindowHandle();
}

@Override
public Set<String> getContextHandles() {
return driver.getContextHandles();
}

@Override
public String getContext() {
return driver.getContext();
}

public Object executeScript(String script, Object... args) {
if (driver instanceof JavascriptExecutor) {
dispatcher.beforeScript(script, driver);
Expand Down Expand Up @@ -596,6 +606,10 @@ public WebElement activeElement() {
public Alert alert() {
return targetLocator.alert();
}

public WebDriver context(String name) {
return targetLocator.context(name);
}
}

@Beta
Expand Down
45 changes: 45 additions & 0 deletions java/client/test/org/openqa/selenium/ContextSwitchingTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
Copyright 2014 Software Freedom Conservancy
Licensed 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;

import static org.openqa.selenium.testing.Ignore.Driver.IPHONE;
import static org.openqa.selenium.testing.Ignore.Driver.MARIONETTE;
import static org.openqa.selenium.testing.Ignore.Driver.OPERA_MOBILE;

import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.testing.Ignore;
import org.openqa.selenium.testing.JUnit4TestBase;

public class ContextSwitchingTest extends JUnit4TestBase {

@Test(expected = UnsupportedCommandException.class)
public void testShouldNotBeAbleToSwitchContext() {
driver.switchTo().context("WEBVIEW");
}

@Test(expected = UnsupportedCommandException.class)
public void testShouldNotBeAbleToGetContextHandle() {
driver.getContext();
}

@Test(expected = UnsupportedCommandException.class)
public void testShouldNotBeAbleToGetContextHandles() {
driver.getContextHandles();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
VisibilityTest.class,
WebElementTest.class,
WindowSwitchingTest.class,
ContextSwitchingTest.class,
WindowTest.class,

Html5Tests.class,
Expand Down
10 changes: 10 additions & 0 deletions java/client/test/org/openqa/selenium/StubDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ public String getWindowHandle() {
throw new UnsupportedOperationException("getWindowHandle");
}

@Override
public Set<String> getContextHandles() {
throw new UnsupportedOperationException("getContextHandles");
}

@Override
public String getContext() {
throw new UnsupportedOperationException("getContext");
}

public TargetLocator switchTo() {
throw new UnsupportedOperationException("switchTo");
}
Expand Down
5 changes: 5 additions & 0 deletions java/client/test/org/openqa/selenium/StubTargetLocator.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,9 @@ public WebElement activeElement() {
public Alert alert() {
throw new UnsupportedOperationException("alert()");
}

@Override
public WebDriver context(String name) {
throw new UnsupportedOperationException("context(String)");
}
}

0 comments on commit 8b6b171

Please sign in to comment.