diff --git a/dotnet/src/webdriver/Interactions/InputDeviceKind.cs b/dotnet/src/webdriver/Interactions/InputDeviceKind.cs index 0386ff8bdc224..f0ede0091c345 100644 --- a/dotnet/src/webdriver/Interactions/InputDeviceKind.cs +++ b/dotnet/src/webdriver/Interactions/InputDeviceKind.cs @@ -1,4 +1,4 @@ -// +// // 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 @@ -36,6 +36,11 @@ public enum InputDeviceKind /// /// Represents a pointer-based device, such as a mouse, pen, or stylus. /// - Pointer + Pointer, + + /// + /// Represents a wheel device. + /// + Wheel } } diff --git a/dotnet/src/webdriver/Interactions/PointerInputDevice.cs b/dotnet/src/webdriver/Interactions/PointerInputDevice.cs index a0dc147db2ec3..e7a8f632de51e 100644 --- a/dotnet/src/webdriver/Interactions/PointerInputDevice.cs +++ b/dotnet/src/webdriver/Interactions/PointerInputDevice.cs @@ -221,6 +221,15 @@ public Interaction CreatePointerCancel() private class PointerDownInteraction : Interaction { private MouseButton button; + private double? width; + private double? height; + private double? pressure; + private double? tangentialPressure; + private int? tiltX; + private int? tiltY; + private int? twist; + private double? altitudeAngle; + private double? azimuthAngle; public PointerDownInteraction(InputDevice sourceDevice, MouseButton button) : base(sourceDevice) @@ -234,6 +243,51 @@ public override Dictionary ToDictionary() toReturn["type"] = "pointerDown"; toReturn["button"] = Convert.ToInt32(this.button, CultureInfo.InvariantCulture); + if (this.width.HasValue) + { + toReturn["width"] = this.width.Value; + } + + if (this.height.HasValue) + { + toReturn["height"] = this.width.Value; + } + + if (this.pressure.HasValue) + { + toReturn["pressure"] = this.width.Value; + } + + if (this.tangentialPressure.HasValue) + { + toReturn["tangentialPressure"] = this.width.Value; + } + + if (this.tiltX.HasValue) + { + toReturn["tiltX"] = this.width.Value; + } + + if (this.tiltY.HasValue) + { + toReturn["tiltY"] = this.width.Value; + } + + if (this.twist.HasValue) + { + toReturn["twist"] = this.width.Value; + } + + if (this.altitudeAngle.HasValue) + { + toReturn["altitudeAngle"] = this.width.Value; + } + + if (this.azimuthAngle.HasValue) + { + toReturn["azimuthAngle"] = this.width.Value; + } + return toReturn; } @@ -246,6 +300,15 @@ public override string ToString() private class PointerUpInteraction : Interaction { private MouseButton button; + private double? width; + private double? height; + private double? pressure; + private double? tangentialPressure; + private int? tiltX; + private int? tiltY; + private int? twist; + private double? altitudeAngle; + private double? azimuthAngle; public PointerUpInteraction(InputDevice sourceDevice, MouseButton button) : base(sourceDevice) @@ -259,6 +322,51 @@ public override Dictionary ToDictionary() toReturn["type"] = "pointerUp"; toReturn["button"] = Convert.ToInt32(this.button, CultureInfo.InvariantCulture); + if (this.width.HasValue) + { + toReturn["width"] = this.width.Value; + } + + if (this.height.HasValue) + { + toReturn["height"] = this.width.Value; + } + + if (this.pressure.HasValue) + { + toReturn["pressure"] = this.width.Value; + } + + if (this.tangentialPressure.HasValue) + { + toReturn["tangentialPressure"] = this.width.Value; + } + + if (this.tiltX.HasValue) + { + toReturn["tiltX"] = this.width.Value; + } + + if (this.tiltY.HasValue) + { + toReturn["tiltY"] = this.width.Value; + } + + if (this.twist.HasValue) + { + toReturn["twist"] = this.width.Value; + } + + if (this.altitudeAngle.HasValue) + { + toReturn["altitudeAngle"] = this.width.Value; + } + + if (this.azimuthAngle.HasValue) + { + toReturn["azimuthAngle"] = this.width.Value; + } + return toReturn; } @@ -295,6 +403,15 @@ private class PointerMoveInteraction : Interaction private int y = 0; private TimeSpan duration = TimeSpan.MinValue; private CoordinateOrigin origin = CoordinateOrigin.Pointer; + private double? width; + private double? height; + private double? pressure; + private double? tangentialPressure; + private int? tiltX; + private int? tiltY; + private int? twist; + private double? altitudeAngle; + private double? azimuthAngle; public PointerMoveInteraction(InputDevice sourceDevice, IWebElement target, CoordinateOrigin origin, int x, int y, TimeSpan duration) : base(sourceDevice) @@ -343,6 +460,51 @@ public override Dictionary ToDictionary() toReturn["x"] = this.x; toReturn["y"] = this.y; + if (this.width.HasValue) + { + toReturn["width"] = this.width.Value; + } + + if (this.height.HasValue) + { + toReturn["height"] = this.width.Value; + } + + if (this.pressure.HasValue) + { + toReturn["pressure"] = this.width.Value; + } + + if (this.tangentialPressure.HasValue) + { + toReturn["tangentialPressure"] = this.width.Value; + } + + if (this.tiltX.HasValue) + { + toReturn["tiltX"] = this.width.Value; + } + + if (this.tiltY.HasValue) + { + toReturn["tiltY"] = this.width.Value; + } + + if (this.twist.HasValue) + { + toReturn["twist"] = this.width.Value; + } + + if (this.altitudeAngle.HasValue) + { + toReturn["altitudeAngle"] = this.width.Value; + } + + if (this.azimuthAngle.HasValue) + { + toReturn["azimuthAngle"] = this.width.Value; + } + return toReturn; } diff --git a/dotnet/src/webdriver/Interactions/WheelInputDevice.cs b/dotnet/src/webdriver/Interactions/WheelInputDevice.cs new file mode 100644 index 0000000000000..91fca0b0486ce --- /dev/null +++ b/dotnet/src/webdriver/Interactions/WheelInputDevice.cs @@ -0,0 +1,201 @@ +// +// 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. +// + +using OpenQA.Selenium.Internal; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace OpenQA.Selenium.Interactions +{ + /// + /// Represents a wheel input device, such as a mouse wheel. + /// + public class WheelInputDevice : InputDevice + { + /// + /// Initializes a new instance of the class. + /// + public WheelInputDevice() + : this(Guid.NewGuid().ToString()) + { + } + + /// + /// Initializes a new instance of the class, given the device's name. + /// + /// The unique name of this input device. + public WheelInputDevice(string deviceName) + : base(deviceName) + { + } + + /// + /// Gets the type of device for this input device. + /// + public override InputDeviceKind DeviceKind + { + get { return InputDeviceKind.Wheel; } + } + + /// + /// Returns a value for this input device that can be transmitted across the wire to a remote end. + /// + /// A representing this action. + public override Dictionary ToDictionary() + { + Dictionary toReturn = new Dictionary(); + + toReturn["type"] = "wheel"; + toReturn["id"] = this.DeviceName; + + return toReturn; + } + + /// + /// Creates a wheel scroll action. + /// + /// The distance along the X axis to scroll using the wheel. + /// The distance along the Y axis to scroll using the wheel. + /// The duration of the scroll action. + /// + public Interaction CreateWheelScroll(int deltaX, int deltaY, TimeSpan duration) + { + return new WheelScrollInteraction(this, null, CoordinateOrigin.Viewport, 0, 0, deltaX, deltaY, duration); + } + + /// + /// Creates a wheel scroll action beginning with an element. + /// + /// The in which to begin the scroll. + /// The horizontal offset from the center of the target element from which to start the scroll. + /// The vertical offset from the center of the target element from which to start the scroll. + /// The distance along the X axis to scroll using the wheel. + /// The distance along the Y axis to scroll using the wheel. + /// The duration of the scroll action. + /// + public Interaction CreateWheelScroll(IWebElement target, int xOffset, int yOffset, int deltaX, int deltaY, TimeSpan duration) + { + return new WheelScrollInteraction(this, target, CoordinateOrigin.Element, xOffset, yOffset, deltaX, deltaY, duration); + } + + /// + /// Creates a wheel scroll action. + /// + /// The coordinate origin, either the view port or the current pointer position, from which to begin the scroll. + /// The horizontal offset from the center of the origin from which to start the scroll. + /// The vertical offset from the center of the origin from which to start the scroll. + /// The distance along the X axis to scroll using the wheel. + /// The distance along the Y axis to scroll using the wheel. + /// The duration of the scroll action. + /// + public Interaction CreateWheelScroll(CoordinateOrigin origin, int xOffset, int yOffset, int deltaX, int deltaY, TimeSpan duration) + { + return new WheelScrollInteraction(this, null, origin, xOffset, yOffset, deltaX, deltaY, duration); + } + + private class WheelScrollInteraction : Interaction + { + private IWebElement target; + private int x = 0; + private int y = 0; + private int deltaX = 0; + private int deltaY = 0; + private TimeSpan duration = TimeSpan.MinValue; + private CoordinateOrigin origin = CoordinateOrigin.Viewport; + + public WheelScrollInteraction(InputDevice sourceDevice, IWebElement target, CoordinateOrigin origin, int x, int y, int deltaX, int deltaY, TimeSpan duration) + :base(sourceDevice) + { + if (target != null) + { + this.target = target; + this.origin = CoordinateOrigin.Element; + } + else + { + if (this.origin != CoordinateOrigin.Element) + { + this.origin = origin; + } + } + + if (duration != TimeSpan.MinValue) + { + this.duration = duration; + } + + this.x = x; + this.y = y; + this.deltaX = deltaX; + this.deltaY = deltaY; + } + + public override Dictionary ToDictionary() + { + Dictionary toReturn = new Dictionary(); + + toReturn["type"] = "pointerMove"; + if (this.duration != TimeSpan.MinValue) + { + toReturn["duration"] = Convert.ToInt64(this.duration.TotalMilliseconds); + } + + if (this.target != null) + { + toReturn["origin"] = this.ConvertElement(); + } + else + { + toReturn["origin"] = this.origin.ToString().ToLowerInvariant(); + } + + toReturn["x"] = this.x; + toReturn["y"] = this.y; + + toReturn["deltaX"] = this.deltaX; + toReturn["deltaY"] = this.deltaY; + + return toReturn; + } + + private Dictionary ConvertElement() + { + IWebElementReference elementReference = this.target as IWebElementReference; + if (elementReference == null) + { + IWrapsElement elementWrapper = this.target as IWrapsElement; + if (elementWrapper != null) + { + elementReference = elementWrapper.WrappedElement as IWebElementReference; + } + } + + if (elementReference == null) + { + throw new ArgumentException("Target element cannot be converted to IWebElementReference"); + } + + Dictionary elementDictionary = elementReference.ToDictionary(); + return elementDictionary; + } + } + } +}