diff --git a/java/client/src/org/openqa/selenium/BUCK b/java/client/src/org/openqa/selenium/BUCK index 272e848cfd74e..1122294509dcd 100644 --- a/java/client/src/org/openqa/selenium/BUCK +++ b/java/client/src/org/openqa/selenium/BUCK @@ -29,6 +29,7 @@ java_library(name = 'core', 'ContextAware.java', 'HasCapabilities.java', 'JavascriptExecutor.java', + 'DeviceRotation.java', 'Keys.java', 'OutputType.java', 'Proxy.java', @@ -60,6 +61,7 @@ java_library(name = 'core', '//java/client/src/org/openqa/selenium/interactions:exceptions', '//java/client/src/org/openqa/selenium/logging:api', '//java/client/src/org/openqa/selenium/security:security', + '//third_party/java/guava:guava', ], visibility = [ '//java/client/src/org/openqa/selenium/interactions:interactions', diff --git a/java/client/src/org/openqa/selenium/DeviceRotation.java b/java/client/src/org/openqa/selenium/DeviceRotation.java new file mode 100644 index 0000000000000..df7fa654df028 --- /dev/null +++ b/java/client/src/org/openqa/selenium/DeviceRotation.java @@ -0,0 +1,102 @@ +// 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; + +import java.util.Map; +import com.google.common.collect.ImmutableMap; + +/** + * Defines an object which represents the three dimensional plane and how a device can be rotated about it. + * Each of the axis is in positive degrees on the real number scale (0 <= deg <= 360). + * + * Example Instantiation to rotate device to "Landscape Right": + * DeviceRotation(0, 0, 90); + */ +public class DeviceRotation { + //Default orientation is portrait + private int x = 0; + private int y = 0; + private int z = 0; + + /** + * Instantiate a DeviceRotation object based on three integers. + * @param x + * @param y + * @param z + */ + public DeviceRotation(int x, int y, int z) { + this.validateParameters(x, y, z); + this.x = x; + this.y = y; + this.z = z; + } + + /** + * Instantiate a DeviceRotation object based on a + * HashMap object where the keys are the axis x, y, and z respectively: + * x : xVal + * y : yVal + * z : zVal + * @param map + */ + public DeviceRotation(Map map) { + if (map == null || !map.containsKey("x") || !map.containsKey("y") || !map.containsKey("z")) { + throw new IllegalArgumentException("Could not initialize DeviceRotation with map given: " + map.toString()); + } + this.validateParameters(map.get("x"), map.get("y"), map.get("z")); + this.x = map.get("x"); + this.y = map.get("y"); + this.z = map.get("z"); + } + + private void validateParameters(int x, int y, int z) { + if (x < 0 || y < 0 || z < 0) { + throw new IllegalArgumentException("DeviceRotation requires positive axis values: \nx = " + x + "\ny = " + y + "\nz = " + z); + } + } + + /** + * @return the x + */ + public int getX() { + return x; + } + + /** + * @return the y + */ + public int getY() { + return y; + } + + /** + * @return the z + */ + public int getZ() { + return z; + } + + /** + * @return returns all axis mapped to an ImmutableMap + */ + public ImmutableMap parameters() { + return ImmutableMap.of("x", this.x, "y", this.y, "z", this.z); + } + + +} diff --git a/java/client/src/org/openqa/selenium/Rotatable.java b/java/client/src/org/openqa/selenium/Rotatable.java index 57d153723f77d..d4e3df11f9a52 100644 --- a/java/client/src/org/openqa/selenium/Rotatable.java +++ b/java/client/src/org/openqa/selenium/Rotatable.java @@ -36,4 +36,17 @@ public interface Rotatable { * @return the current screen orientation of the browser */ ScreenOrientation getOrientation(); + + /** + * Changes the rotation of the browser window. + * + * @param rotation + */ + void rotate(DeviceRotation rotation); + + /** + * @return DeviceOrientation describing the current screen rotation of the browser window + */ + DeviceRotation rotation(); + } diff --git a/java/client/src/org/openqa/selenium/remote/AddRotatable.java b/java/client/src/org/openqa/selenium/remote/AddRotatable.java index ebce7509b56e7..88707623c113b 100644 --- a/java/client/src/org/openqa/selenium/remote/AddRotatable.java +++ b/java/client/src/org/openqa/selenium/remote/AddRotatable.java @@ -19,13 +19,14 @@ import com.google.common.collect.ImmutableMap; +import org.openqa.selenium.DeviceRotation; import org.openqa.selenium.Rotatable; import org.openqa.selenium.ScreenOrientation; import java.lang.reflect.Method; public class AddRotatable implements AugmenterProvider { - + public Class getDescribedInterface() { return Rotatable.class; } @@ -33,14 +34,28 @@ public Class getDescribedInterface() { public InterfaceImplementation getImplementation(Object value) { return new InterfaceImplementation() { public Object invoke(ExecuteMethod executeMethod, Object self, Method method, Object... args) { - if ("rotate".equals(method.getName())) { - return executeMethod.execute(DriverCommand.SET_SCREEN_ORIENTATION, - ImmutableMap.of("orientation", args[0])); - } else if ("getOrientation".equals(method.getName())) { - return ScreenOrientation.valueOf((String) executeMethod.execute( - DriverCommand.GET_SCREEN_ORIENTATION, null)); + String m = method.getName(); + Object response; + switch(m) { + case "rotate": + if (args[0] instanceof ScreenOrientation) { + response = executeMethod.execute(DriverCommand.SET_SCREEN_ORIENTATION, ImmutableMap.of("orientation", args[0])); + } else if (args[0] instanceof DeviceRotation) { + response = executeMethod.execute(DriverCommand.SET_SCREEN_ORIENTATION, ((DeviceRotation)args[0]).parameters()); + } else { + throw new IllegalArgumentException("rotate parameter must be either of type 'ScreenOrientation' or 'DeviceRotation'"); + } + break; + case "getOrientation": + response = ScreenOrientation.valueOf((String) executeMethod.execute(DriverCommand.GET_SCREEN_ORIENTATION, null)); + break; + case "rotation": + response = (DeviceRotation) executeMethod.execute(DriverCommand.GET_SCREEN_ROTATION, null); + break; + default: + throw new IllegalArgumentException(method.getName() + ", Not defined in rotatable interface"); } - return null; + return response; } }; } diff --git a/java/client/src/org/openqa/selenium/remote/DriverCommand.java b/java/client/src/org/openqa/selenium/remote/DriverCommand.java index af28e2e3f2f88..c19e43aafc354 100644 --- a/java/client/src/org/openqa/selenium/remote/DriverCommand.java +++ b/java/client/src/org/openqa/selenium/remote/DriverCommand.java @@ -134,6 +134,8 @@ public interface DriverCommand { String SET_SCREEN_ORIENTATION = "setScreenOrientation"; String GET_SCREEN_ORIENTATION = "getScreenOrientation"; + String SET_SCREEN_ROTATION = "setScreenRotation"; + String GET_SCREEN_ROTATION = "getScreenRotation"; String ACTION_CHAIN = "actionChain"; diff --git a/java/client/src/org/openqa/selenium/remote/http/JsonHttpCommandCodec.java b/java/client/src/org/openqa/selenium/remote/http/JsonHttpCommandCodec.java index ff785424be081..335a2c50fa854 100644 --- a/java/client/src/org/openqa/selenium/remote/http/JsonHttpCommandCodec.java +++ b/java/client/src/org/openqa/selenium/remote/http/JsonHttpCommandCodec.java @@ -183,6 +183,8 @@ public JsonHttpCommandCodec() { defineCommand(GET_SCREEN_ORIENTATION, get("/session/:sessionId/orientation")); defineCommand(SET_SCREEN_ORIENTATION, post("/session/:sessionId/orientation")); + defineCommand(GET_SCREEN_ROTATION, get("/session/:sessionId/rotation")); + defineCommand(SET_SCREEN_ROTATION, post("/session/:sessionId/rotation")); // Interactions-related commands. defineCommand(MOUSE_DOWN, post("/session/:sessionId/buttondown"));