diff --git a/java/client/src/org/openqa/selenium/BUCK b/java/client/src/org/openqa/selenium/BUCK index ffb68b899a0b0..2987cdf487f2c 100644 --- a/java/client/src/org/openqa/selenium/BUCK +++ b/java/client/src/org/openqa/selenium/BUCK @@ -40,6 +40,7 @@ java_library(name = 'core', 'UnexpectedAlertBehaviour.java', 'WebDriver.java', 'WebElement.java', + 'internal/HasIdentity.java', 'internal/Killable.java', 'internal/Locatable.java', 'internal/Lock.java', @@ -135,4 +136,4 @@ java_binary(name = 'selenium-java', '//java/client/src/org/openqa/selenium/safari:safari', '//java/client/src/org/openqa/selenium/support:support', ], -) \ No newline at end of file +) diff --git a/java/client/src/org/openqa/selenium/build.desc b/java/client/src/org/openqa/selenium/build.desc index e65f5b820cb64..95cd5a7424971 100644 --- a/java/client/src/org/openqa/selenium/build.desc +++ b/java/client/src/org/openqa/selenium/build.desc @@ -70,6 +70,7 @@ java_library(name = "webdriver-api", "internal/FindsByName.java", "internal/FindsByTagName.java", "internal/FindsByXPath.java", + "internal/HasIdentity.java", "internal/Killable.java", "internal/Locatable.java", "internal/Lock.java", diff --git a/java/client/src/org/openqa/selenium/firefox/internal/MarionetteConnection.java b/java/client/src/org/openqa/selenium/firefox/internal/MarionetteConnection.java index 09dab4c87c98e..7f7127723ebe6 100644 --- a/java/client/src/org/openqa/selenium/firefox/internal/MarionetteConnection.java +++ b/java/client/src/org/openqa/selenium/firefox/internal/MarionetteConnection.java @@ -76,6 +76,10 @@ public class MarionetteConnection implements ExtensionConnection, NeedsLocalLogs .put(DriverCommand.GET_ELEMENT_LOCATION, "getElementPosition") .put(DriverCommand.GET_ALL_COOKIES, "getAllCookies") .put(DriverCommand.QUIT, "deleteSession") + .put(DriverCommand.MOVE_TO, "move") + .put(DriverCommand.MOUSE_DOWN, "press") + .put(DriverCommand.MOUSE_UP, "release") + .put(DriverCommand.CLICK, "click") .build(); private Socket socket; @@ -195,39 +199,11 @@ public Response execute(Command command) throws IOException { response.setValue(map.get("value")); } else { + response = new JsonToBeanConverter().convert(Response.class, rawResponse); if (map.containsKey("error")) { - // *************************************************************** - // Marionette Compliance Issue: Error responses should, at a - // minimum, put the status property at the root of the object. - // In other words: - // { - // status: 7, - // value: - // { - // message: "Did not find element with id=foo", - // stackTrace: - // } - // } - // *************************************************************** - response = new Response(); - Object value = map.get("error"); - if (value != null) { - if (value instanceof Map) { - Map errorMap = (Map) value; - if (errorMap != null) { - response.setStatus(Integer.parseInt(errorMap.get("status").toString())); - errorMap.remove("status"); - response.setValue(errorMap); - } - } else { - response.setStatus(ErrorCodes.UNHANDLED_ERROR); - response.setValue(value + ": " + map.get("message")); - } - } + response.setValue(map.get("error")); } else { - response = new JsonToBeanConverter().convert(Response.class, rawResponse); - // *************************************************************** // Marionette Compliance Issue: Responses from findElements // are returned with raw element IDs as the value. @@ -280,7 +256,8 @@ private String serializeCommand(Command command) { || DriverCommand.MOUSE_DOWN.equals(commandName) || DriverCommand.MOUSE_UP.equals(commandName) || DriverCommand.MOVE_TO.equals(commandName)) { - String actionName = commandName; + String actionName = seleniumToMarionetteCommandMap.containsKey(commandName) ? + seleniumToMarionetteCommandMap.get(commandName) : commandName; commandName = "actionChain"; List action = Lists.newArrayList(); action.add(actionName); diff --git a/java/client/src/org/openqa/selenium/interactions/BUCK b/java/client/src/org/openqa/selenium/interactions/BUCK index af8db3c4fe1a3..c3bfe4c9c13ea 100644 --- a/java/client/src/org/openqa/selenium/interactions/BUCK +++ b/java/client/src/org/openqa/selenium/interactions/BUCK @@ -6,6 +6,7 @@ java_library(name = 'interactions', ':core', ':exceptions', '//java/client/src/org/openqa/selenium:core', + '//java/client/src/org/openqa/remote:remote', ], deps = [ '//third_party/java/guava-libraries', @@ -40,6 +41,5 @@ java_library(name = 'exceptions', ], visibility = [ '//java/client/src/org/openqa/selenium:webdriver-api', - '//java/client/src/org/openqa/selenium/remote:remote', ], ) diff --git a/java/client/src/org/openqa/selenium/interactions/ButtonReleaseAction.java b/java/client/src/org/openqa/selenium/interactions/ButtonReleaseAction.java index 2ed091e02a248..d6a0678b96063 100644 --- a/java/client/src/org/openqa/selenium/interactions/ButtonReleaseAction.java +++ b/java/client/src/org/openqa/selenium/interactions/ButtonReleaseAction.java @@ -20,6 +20,9 @@ import org.openqa.selenium.interactions.internal.MouseAction; import org.openqa.selenium.internal.Locatable; +import java.util.Arrays; +import java.util.List; + /** * Releases the left mouse button * @@ -40,4 +43,8 @@ public void perform() { moveToLocation(); mouse.mouseUp(getActionLocation()); } + + public List asList() { + return Arrays.asList("release"); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/ClickAction.java b/java/client/src/org/openqa/selenium/interactions/ClickAction.java index 06e612af17c65..cb9865ce89699 100644 --- a/java/client/src/org/openqa/selenium/interactions/ClickAction.java +++ b/java/client/src/org/openqa/selenium/interactions/ClickAction.java @@ -20,6 +20,9 @@ import org.openqa.selenium.interactions.internal.MouseAction; import org.openqa.selenium.internal.Locatable; +import java.util.Arrays; +import java.util.List; + /** * clicks an element. * @@ -33,4 +36,8 @@ public void perform() { moveToLocation(); mouse.click(getActionLocation()); } + + public List asList() { + return Arrays.asList("click", getTargetId(), Button.LEFT, 1); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/ClickAndHoldAction.java b/java/client/src/org/openqa/selenium/interactions/ClickAndHoldAction.java index 3775990727579..e19082c88eb4f 100644 --- a/java/client/src/org/openqa/selenium/interactions/ClickAndHoldAction.java +++ b/java/client/src/org/openqa/selenium/interactions/ClickAndHoldAction.java @@ -20,6 +20,9 @@ import org.openqa.selenium.interactions.internal.MouseAction; import org.openqa.selenium.internal.Locatable; +import java.util.Arrays; +import java.util.List; + /** * Presses the left mouse button without releasing it. * @@ -38,4 +41,8 @@ public void perform() { moveToLocation(); mouse.mouseDown(getActionLocation()); } + + public List asList() { + return Arrays.asList("press", getTargetId()); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/ContextClickAction.java b/java/client/src/org/openqa/selenium/interactions/ContextClickAction.java index 3664c9c655c0b..3dc6841ffd440 100644 --- a/java/client/src/org/openqa/selenium/interactions/ContextClickAction.java +++ b/java/client/src/org/openqa/selenium/interactions/ContextClickAction.java @@ -20,6 +20,9 @@ import org.openqa.selenium.interactions.internal.MouseAction; import org.openqa.selenium.internal.Locatable; +import java.util.Arrays; +import java.util.List; + /** * Context-clicks an element * @@ -38,4 +41,7 @@ public void perform() { mouse.contextClick(getActionLocation()); } + public List asList() { + return Arrays.asList("click", getTargetId(), Button.RIGHT, 1); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/DoubleClickAction.java b/java/client/src/org/openqa/selenium/interactions/DoubleClickAction.java index 565ce8b39372f..ccf6c72fc3ad4 100644 --- a/java/client/src/org/openqa/selenium/interactions/DoubleClickAction.java +++ b/java/client/src/org/openqa/selenium/interactions/DoubleClickAction.java @@ -20,6 +20,9 @@ import org.openqa.selenium.interactions.internal.MouseAction; import org.openqa.selenium.internal.Locatable; +import java.util.Arrays; +import java.util.List; + /** * Double-clicks an element. * @@ -36,4 +39,8 @@ public void perform() { moveToLocation(); mouse.doubleClick(getActionLocation()); } + + public List asList() { + return Arrays.asList("click", getTargetId(), Button.LEFT, 2); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/KeyDownAction.java b/java/client/src/org/openqa/selenium/interactions/KeyDownAction.java index a719101720519..f8693f6c1f893 100644 --- a/java/client/src/org/openqa/selenium/interactions/KeyDownAction.java +++ b/java/client/src/org/openqa/selenium/interactions/KeyDownAction.java @@ -21,6 +21,9 @@ import org.openqa.selenium.interactions.internal.SingleKeyAction; import org.openqa.selenium.internal.Locatable; +import java.util.Arrays; +import java.util.List; + /** * Emulates key press only, without the release. * @@ -39,4 +42,8 @@ public void perform() { keyboard.pressKey(key); } + + public List asList() { + return Arrays.asList("keyDown", key); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/KeyUpAction.java b/java/client/src/org/openqa/selenium/interactions/KeyUpAction.java index f9711a520bcca..33971e0e0c015 100644 --- a/java/client/src/org/openqa/selenium/interactions/KeyUpAction.java +++ b/java/client/src/org/openqa/selenium/interactions/KeyUpAction.java @@ -21,6 +21,9 @@ import org.openqa.selenium.interactions.internal.SingleKeyAction; import org.openqa.selenium.internal.Locatable; +import java.util.Arrays; +import java.util.List; + /** * Emulates key release only, without the press. * @@ -39,4 +42,8 @@ public void perform() { keyboard.releaseKey(key); } + + public List asList() { + return Arrays.asList("keyUp", key); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/MoveMouseAction.java b/java/client/src/org/openqa/selenium/interactions/MoveMouseAction.java index 2663494af5a51..a656e6b639480 100644 --- a/java/client/src/org/openqa/selenium/interactions/MoveMouseAction.java +++ b/java/client/src/org/openqa/selenium/interactions/MoveMouseAction.java @@ -20,6 +20,9 @@ import org.openqa.selenium.interactions.internal.MouseAction; import org.openqa.selenium.internal.Locatable; +import java.util.Arrays; +import java.util.List; + /** * Moves the mouse to an element. * @@ -35,4 +38,8 @@ public MoveMouseAction(Mouse mouse, Locatable locationProvider) { public void perform() { mouse.mouseMove(getActionLocation()); } + + public List asList() { + return Arrays.asList("move", getTargetId()); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/MoveToOffsetAction.java b/java/client/src/org/openqa/selenium/interactions/MoveToOffsetAction.java index 2fadd0495e796..813a213755719 100644 --- a/java/client/src/org/openqa/selenium/interactions/MoveToOffsetAction.java +++ b/java/client/src/org/openqa/selenium/interactions/MoveToOffsetAction.java @@ -20,6 +20,9 @@ import org.openqa.selenium.interactions.internal.MouseAction; import org.openqa.selenium.internal.Locatable; +import java.util.Arrays; +import java.util.List; + /** * Move the mouse to a location within the element provided. The coordinates provided specify the * offset from the top-left corner of the element. @@ -37,4 +40,8 @@ public MoveToOffsetAction(Mouse mouse, Locatable locationProvider, int x, int y) public void perform() { mouse.mouseMove(getActionLocation(), xOffset, yOffset); } + + public List asList() { + return Arrays.asList("move", getTargetId(), xOffset, yOffset); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/PauseAction.java b/java/client/src/org/openqa/selenium/interactions/PauseAction.java index 6482a41850bab..46c873a450c15 100644 --- a/java/client/src/org/openqa/selenium/interactions/PauseAction.java +++ b/java/client/src/org/openqa/selenium/interactions/PauseAction.java @@ -17,6 +17,9 @@ package org.openqa.selenium.interactions; +import java.util.Arrays; +import java.util.List; + /** * Takes a pause. * @@ -37,4 +40,8 @@ public void perform() { } catch (InterruptedException e) { } } + + public List asList() { + return Arrays.asList("wait", pause); + } } diff --git a/java/client/src/org/openqa/selenium/interactions/internal/BaseAction.java b/java/client/src/org/openqa/selenium/interactions/internal/BaseAction.java index 26197328cb834..bda780630ca8c 100644 --- a/java/client/src/org/openqa/selenium/interactions/internal/BaseAction.java +++ b/java/client/src/org/openqa/selenium/interactions/internal/BaseAction.java @@ -17,7 +17,10 @@ package org.openqa.selenium.interactions.internal; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.HasIdentity; import org.openqa.selenium.internal.Locatable; +import org.openqa.selenium.internal.WrapsElement; /** * Base class for all actions. @@ -40,4 +43,22 @@ protected BaseAction(Locatable actionLocation) { protected BaseAction() { this.where = null; } + + protected String getTargetId() { + if (!(where instanceof WebElement)) { + return null; + } + + WebElement target = (WebElement) where; + + while (target instanceof WrapsElement) { + target = ((WrapsElement) target).getWrappedElement(); + } + + if (target instanceof HasIdentity) { + return ((HasIdentity) target).getId(); + } + + return null; + } } diff --git a/java/client/src/org/openqa/selenium/interactions/internal/MouseAction.java b/java/client/src/org/openqa/selenium/interactions/internal/MouseAction.java index 8535f0f39cec1..32e15a932388e 100644 --- a/java/client/src/org/openqa/selenium/interactions/internal/MouseAction.java +++ b/java/client/src/org/openqa/selenium/interactions/internal/MouseAction.java @@ -25,6 +25,17 @@ * Base class for all mouse-related actions. */ public class MouseAction extends BaseAction { + public enum Button { + LEFT(0), + MIDDLE(1), + RIGHT(2); + + private final int b; + Button(int b) { + this.b = b; + } + } + protected final Mouse mouse; protected MouseAction(Mouse mouse, Locatable locationProvider) { diff --git a/java/client/src/org/openqa/selenium/internal/HasIdentity.java b/java/client/src/org/openqa/selenium/internal/HasIdentity.java new file mode 100644 index 0000000000000..90e9a2ab9c3de --- /dev/null +++ b/java/client/src/org/openqa/selenium/internal/HasIdentity.java @@ -0,0 +1,24 @@ +// 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.internal; + +import org.openqa.selenium.interactions.internal.Coordinates; + +public interface HasIdentity { + String getId(); +} diff --git a/java/client/src/org/openqa/selenium/remote/BUCK b/java/client/src/org/openqa/selenium/remote/BUCK index fd90810daf54b..f236cfb2d7aad 100644 --- a/java/client/src/org/openqa/selenium/remote/BUCK +++ b/java/client/src/org/openqa/selenium/remote/BUCK @@ -46,6 +46,7 @@ java_library(name = 'remote', 'JsonException.java', 'JsonToBeanConverter.java', 'LocalFileDetector.java', + 'RemoteActionChainExecutor.java', 'RemoteExecuteMethod.java', 'RemoteKeyboard.java', 'RemoteLogs.java', diff --git a/java/client/src/org/openqa/selenium/remote/RemoteWebElement.java b/java/client/src/org/openqa/selenium/remote/RemoteWebElement.java index 2de54e1747d56..0f64ffaa16aa1 100644 --- a/java/client/src/org/openqa/selenium/remote/RemoteWebElement.java +++ b/java/client/src/org/openqa/selenium/remote/RemoteWebElement.java @@ -34,6 +34,7 @@ import org.openqa.selenium.internal.FindsByName; import org.openqa.selenium.internal.FindsByTagName; import org.openqa.selenium.internal.FindsByXPath; +import org.openqa.selenium.internal.HasIdentity; import org.openqa.selenium.internal.Locatable; import org.openqa.selenium.internal.WrapsDriver; import org.openqa.selenium.internal.WrapsElement; @@ -46,7 +47,7 @@ public class RemoteWebElement implements WebElement, FindsByLinkText, FindsById, FindsByName, FindsByTagName, FindsByClassName, FindsByCssSelector, - FindsByXPath, WrapsDriver, Locatable { + FindsByXPath, WrapsDriver, Locatable, HasIdentity { private String foundBy; protected String id; diff --git a/java/client/src/org/openqa/selenium/remote/build.desc b/java/client/src/org/openqa/selenium/remote/build.desc index ae81ee8a2011a..9015dd54707a3 100644 --- a/java/client/src/org/openqa/selenium/remote/build.desc +++ b/java/client/src/org/openqa/selenium/remote/build.desc @@ -77,6 +77,7 @@ java_library(name = "remote", "HttpCommandExecutor.java", "HttpVerb.java", "LocalFileDetector.java", + "RemoteActionChainExecutor.java", "RemoteExecuteMethod.java", "RemoteKeyboard.java", "RemoteLogs.java",