Skip to content

Commit

Permalink
Normalise how we handle window commands.
Browse files Browse the repository at this point in the history
This allows the codec to massage the parameters being passed
to the remote end. We try and have our default parameters look
like the ones for the w3c protocol.
  • Loading branch information
shs96c committed Aug 19, 2016
1 parent 9573544 commit 09b887e
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,8 @@ public interface DriverCommand {
String TOUCH_FLICK = "touchFlick";

// Window API
String SET_WINDOW_SIZE = "setWindowSize";
String SET_WINDOW_POSITION = "setWindowPosition";
String GET_WINDOW_SIZE = "getWindowSize";
String SET_CURRENT_WINDOW_POSITION = "setWindowPosition";
String GET_WINDOW_POSITION = "getWindowPosition";
String MAXIMIZE_WINDOW = "maximizeWindow";

// W3C compatible Window API
String SET_CURRENT_WINDOW_SIZE = "setCurrentWindowSize";
Expand Down
31 changes: 6 additions & 25 deletions java/client/src/org/openqa/selenium/remote/RemoteWebDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -879,32 +879,18 @@ public Timeouts pageLoadTimeout(long time, TimeUnit unit) {
protected class RemoteWindow implements Window {

public void setSize(Dimension targetSize) {
if (getW3CStandardComplianceLevel() == 0) {
execute(DriverCommand.SET_WINDOW_SIZE,
ImmutableMap.of("windowHandle", "current",
"width", targetSize.width, "height", targetSize.height));
} else {
execute(DriverCommand.SET_CURRENT_WINDOW_SIZE,
ImmutableMap.of("width", targetSize.width, "height", targetSize.height));
}
execute(DriverCommand.SET_CURRENT_WINDOW_SIZE,
ImmutableMap.of("width", targetSize.width, "height", targetSize.height));
}

public void setPosition(Point targetPosition) {
if (getW3CStandardComplianceLevel() == 0) {
execute(DriverCommand.SET_WINDOW_POSITION,
ImmutableMap
.of("windowHandle", "current", "x", targetPosition.x, "y", targetPosition.y));
} else {
executeScript("window.screenX = arguments[0]; window.screenY = arguments[1]",
targetPosition.x, targetPosition.y);
}
execute(DriverCommand.SET_CURRENT_WINDOW_POSITION,
ImmutableMap.of("x", targetPosition.x, "y", targetPosition.y));
}

@SuppressWarnings({"unchecked"})
public Dimension getSize() {
Response response = getW3CStandardComplianceLevel() == 0
? execute(DriverCommand.GET_WINDOW_SIZE, ImmutableMap.of("windowHandle", "current"))
: execute(DriverCommand.GET_CURRENT_WINDOW_SIZE);
Response response = execute(DriverCommand.GET_CURRENT_WINDOW_SIZE);

Map<String, Object> rawSize = (Map<String, Object>) response.getValue();

Expand Down Expand Up @@ -933,12 +919,7 @@ public Point getPosition() {
}

public void maximize() {
if (getW3CStandardComplianceLevel() == 0) {
execute(DriverCommand.MAXIMIZE_WINDOW,
ImmutableMap.of("windowHandle", "current"));
} else {
execute(DriverCommand.MAXIMIZE_CURRENT_WINDOW);
}
execute(DriverCommand.MAXIMIZE_CURRENT_WINDOW);
}

public void fullscreen() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
*
* @see <a href="https://w3.org/tr/webdriver">W3C WebDriver spec</a>
*/
public class AbstractHttpCommandCodec implements CommandCodec<HttpRequest> {
public abstract class AbstractHttpCommandCodec implements CommandCodec<HttpRequest> {
private static final Splitter PATH_SPLITTER = Splitter.on('/').omitEmptyStrings();
private static final String SESSION_ID_PARAM = "sessionId";

Expand All @@ -79,17 +79,9 @@ public AbstractHttpCommandCodec() {
defineCommand(SWITCH_TO_WINDOW, post("/session/:sessionId/window"));

defineCommand(GET_WINDOW_HANDLES, get("/session/:sessionId/window/handles"));
defineCommand(MAXIMIZE_WINDOW, post("/session/:sessionId/window/:windowHandle/maximize"));
defineCommand(GET_WINDOW_SIZE, get("/session/:sessionId/window/:windowHandle/size"));
defineCommand(SET_WINDOW_SIZE, post("/session/:sessionId/window/:windowHandle/size"));
defineCommand(GET_WINDOW_POSITION, get("/session/:sessionId/window/:windowHandle/position"));
defineCommand(SET_WINDOW_POSITION, post("/session/:sessionId/window/:windowHandle/position"));
defineCommand(GET_CURRENT_WINDOW_HANDLE, get("/session/:sessionId/window"));

defineCommand(MAXIMIZE_CURRENT_WINDOW, post("/session/:sessionId/window/maximize"));
defineCommand(FULLSCREEN_CURRENT_WINDOW, post("/session/:sessionId/window/fullscreen"));
defineCommand(GET_CURRENT_WINDOW_SIZE, get("/session/:sessionId/window/size"));
defineCommand(SET_CURRENT_WINDOW_SIZE, post("/session/:sessionId/window/size"));

defineCommand(GET_CURRENT_URL, get("/session/:sessionId/url"));
defineCommand(GET, post("/session/:sessionId/url"));
Expand Down Expand Up @@ -204,12 +196,14 @@ public HttpRequest encode(Command command) {
if (spec == null) {
throw new UnsupportedCommandException(command.getName());
}
String uri = buildUri(command, spec);
Map<String, ?> parameters = amendParameters(command.getName(), command.getParameters());
String uri = buildUri(command.getName(), command.getSessionId(), parameters, spec);

HttpRequest request = new HttpRequest(spec.method, uri);

if (HttpMethod.POST == spec.method) {
String content = beanToJsonConverter.convert(command.getParameters());

String content = beanToJsonConverter.convert(parameters);
byte[] data = content.getBytes(UTF_8);

request.setHeader(CONTENT_LENGTH, String.valueOf(data.length));
Expand All @@ -224,6 +218,8 @@ public HttpRequest encode(Command command) {
return request;
}

protected abstract Map<String,?> amendParameters(String name, Map<String, ?> parameters);

@Override
public Command decode(final HttpRequest encodedCommand) {
final String path = Strings.isNullOrEmpty(encodedCommand.getUri())
Expand Down Expand Up @@ -293,7 +289,11 @@ protected static CommandSpec post(String path) {
return new CommandSpec(HttpMethod.POST, path);
}

private String buildUri(Command command, CommandSpec spec) {
private String buildUri(
String commandName,
SessionId sessionId,
Map<String, ?> parameters,
CommandSpec spec) {
StringBuilder builder = new StringBuilder();
for (String part : spec.pathSegments) {
if (part.isEmpty()) {
Expand All @@ -302,24 +302,28 @@ private String buildUri(Command command, CommandSpec spec) {

builder.append("/");
if (part.startsWith(":")) {
builder.append(getParameter(part.substring(1), command));
builder.append(getParameter(part.substring(1), commandName, sessionId, parameters));
} else {
builder.append(part);
}
}
return builder.toString();
}

private String getParameter(String parameterName, Command command) {
private String getParameter(
String parameterName,
String commandName,
SessionId sessionId,
Map<String, ?> parameters) {
if ("sessionId".equals(parameterName)) {
SessionId id = command.getSessionId();
checkArgument(id != null, "Session ID may not be null for command %s", command.getName());
SessionId id = sessionId;
checkArgument(id != null, "Session ID may not be null for command %s", commandName);
return id.toString();
}

Object value = command.getParameters().get(parameterName);
Object value = parameters.get(parameterName);
checkArgument(value != null,
"Missing required parameter \"%s\" for command %s", parameterName, command.getName());
"Missing required parameter \"%s\" for command %s", parameterName, commandName);
return Urls.urlEncode(String.valueOf(value));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,17 @@
import static org.openqa.selenium.remote.DriverCommand.EXECUTE_ASYNC_SCRIPT;
import static org.openqa.selenium.remote.DriverCommand.EXECUTE_SCRIPT;
import static org.openqa.selenium.remote.DriverCommand.GET_ALERT_TEXT;
import static org.openqa.selenium.remote.DriverCommand.GET_CURRENT_WINDOW_SIZE;
import static org.openqa.selenium.remote.DriverCommand.MAXIMIZE_CURRENT_WINDOW;
import static org.openqa.selenium.remote.DriverCommand.SET_ALERT_VALUE;
import static org.openqa.selenium.remote.DriverCommand.SET_CURRENT_WINDOW_POSITION;
import static org.openqa.selenium.remote.DriverCommand.SET_CURRENT_WINDOW_SIZE;

import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.remote.DriverCommand;

import java.util.Map;

/**
* A command codec that adheres to the Selenium project's JSON/HTTP wire protocol.
Expand All @@ -33,6 +43,11 @@
public class JsonHttpCommandCodec extends AbstractHttpCommandCodec {

public JsonHttpCommandCodec() {
defineCommand(MAXIMIZE_CURRENT_WINDOW, post("/session/:sessionId/window/:windowHandle/maximize"));
defineCommand(SET_CURRENT_WINDOW_POSITION, post("/session/:sessionId/window/:windowHandle/position"));
defineCommand(GET_CURRENT_WINDOW_SIZE, get("/session/:sessionId/window/:windowHandle/size"));
defineCommand(SET_CURRENT_WINDOW_SIZE, post("/session/:sessionId/window/:windowHandle/size"));

defineCommand(ACCEPT_ALERT, post("/session/:sessionId/accept_alert"));
defineCommand(DISMISS_ALERT, post("/session/:sessionId/dismiss_alert"));
defineCommand(GET_ALERT_TEXT, get("/session/:sessionId/alert_text"));
Expand All @@ -41,4 +56,22 @@ public JsonHttpCommandCodec() {
defineCommand(EXECUTE_SCRIPT, post("/session/:sessionId/execute"));
defineCommand(EXECUTE_ASYNC_SCRIPT, post("/session/:sessionId/execute_async"));
}

@Override
protected Map<String, ?> amendParameters(String name, Map<String, ?> parameters) {
switch (name) {
case DriverCommand.GET_CURRENT_WINDOW_SIZE:
case DriverCommand.MAXIMIZE_CURRENT_WINDOW:
case DriverCommand.SET_CURRENT_WINDOW_SIZE:
case DriverCommand.SET_CURRENT_WINDOW_POSITION:
return ImmutableMap.<String, Object>builder()
.putAll(parameters)
.put("windowHandle", "current")
.put("handle", "current")
.build();

default:
return parameters;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,20 @@
import static org.openqa.selenium.remote.DriverCommand.EXECUTE_ASYNC_SCRIPT;
import static org.openqa.selenium.remote.DriverCommand.EXECUTE_SCRIPT;
import static org.openqa.selenium.remote.DriverCommand.GET_ALERT_TEXT;
import static org.openqa.selenium.remote.DriverCommand.GET_CURRENT_WINDOW_SIZE;
import static org.openqa.selenium.remote.DriverCommand.MAXIMIZE_CURRENT_WINDOW;
import static org.openqa.selenium.remote.DriverCommand.SET_ALERT_VALUE;
import static org.openqa.selenium.remote.DriverCommand.SET_CURRENT_WINDOW_SIZE;
import static org.openqa.selenium.remote.DriverCommand.SET_CURRENT_WINDOW_POSITION;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

import org.openqa.selenium.remote.DriverCommand;
import org.openqa.selenium.remote.internal.WebElementToJsonConverter;

import java.util.Map;

/**
* A command codec that adheres to the W3C's WebDriver wire protocol.
Expand All @@ -32,6 +45,12 @@
public class W3CHttpCommandCodec extends AbstractHttpCommandCodec {

public W3CHttpCommandCodec() {
defineCommand(MAXIMIZE_CURRENT_WINDOW, post("/session/:sessionId/window/maximize"));
defineCommand(SET_CURRENT_WINDOW_POSITION, post("/session/:sessionId/execute/sync"));
defineCommand(GET_CURRENT_WINDOW_SIZE, get("/session/:sessionId/window/size"));
defineCommand(SET_CURRENT_WINDOW_SIZE, post("/session/:sessionId/window/size"));


defineCommand(ACCEPT_ALERT, post("/session/:sessionId/alert/accept"));
defineCommand(DISMISS_ALERT, post("/session/:sessionId/alert/dismiss"));
defineCommand(GET_ALERT_TEXT, get("/session/:sessionId/alert/text"));
Expand All @@ -40,4 +59,30 @@ public W3CHttpCommandCodec() {
defineCommand(EXECUTE_SCRIPT, post("/session/:sessionId/execute/sync"));
defineCommand(EXECUTE_ASYNC_SCRIPT, post("/session/:sessionId/execute/async"));
}

@Override
protected Map<String, ?> amendParameters(String name, Map<String, ?> parameters) {
switch (name) {
case DriverCommand.SET_CURRENT_WINDOW_POSITION:
return toScript(
"window.screenX = arguments[0]; window.screenY = arguments[1]",
parameters.get("x"),
parameters.get("y"));

default:
return parameters;
}
}

private Map<String, ?> toScript(String script, Object... args) {
// Escape the quote marks
script = script.replaceAll("\"", "\\\"");

Iterable<Object> convertedArgs = Iterables.transform(
Lists.newArrayList(args), new WebElementToJsonConverter());

return ImmutableMap.of(
"script", script,
"args", Lists.newArrayList(convertedArgs));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -264,13 +264,10 @@ private void setUpMappings() {
addNewMapping(SWITCH_TO_WINDOW, SwitchToWindow.class);
addNewMapping(CLOSE, CloseWindow.class);

addNewMapping(GET_WINDOW_SIZE, GetWindowSize.class);
addNewMapping(GET_CURRENT_WINDOW_SIZE, GetWindowSize.class);
addNewMapping(SET_WINDOW_SIZE, SetWindowSize.class);
addNewMapping(SET_CURRENT_WINDOW_SIZE, SetWindowSize.class);
addNewMapping(GET_WINDOW_POSITION, GetWindowPosition.class);
addNewMapping(SET_WINDOW_POSITION, SetWindowPosition.class);
addNewMapping(MAXIMIZE_WINDOW, MaximizeWindow.class);
addNewMapping(SET_CURRENT_WINDOW_POSITION, SetWindowPosition.class);
addNewMapping(MAXIMIZE_CURRENT_WINDOW, MaximizeWindow.class);
addNewMapping(FULLSCREEN_CURRENT_WINDOW, FullscreenWindow.class);

Expand Down

0 comments on commit 09b887e

Please sign in to comment.