Skip to content

Commit

Permalink
Merge branch 'trunk' into webelement-rect-w3c
Browse files Browse the repository at this point in the history
  • Loading branch information
diemol authored May 27, 2022
2 parents cf8195b + cfcc455 commit f286267
Show file tree
Hide file tree
Showing 21 changed files with 222 additions and 74 deletions.
54 changes: 34 additions & 20 deletions common/src/web/mouse_interaction.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
<title>BasicMouseInterfaceTest</title>

<style>
div.solidborder { border-style:solid; border-width:1px;}
div.solidborder { border-style:solid; border-width:1px; margin: 10px;}
#draggable { width: 60px; height: 60px; padding: 0.5em; margin: 10px; }
#droppable { width: 75px; height: 75px; padding: 0.5em; margin: 10px; }
</style>

<link type="text/css" href="css/ui-lightness/jquery-ui-1.12.1.min.css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.12.1.min.js"></script>
<link type="text/css" href="https://selenium.dev/selenium/web/css/ui-lightness/jquery-ui-1.12.1.min.css" rel="stylesheet" />
<script type="text/javascript" src="https://selenium.dev/selenium/web/js/jquery-3.5.1.min.js"></script>
<script type="text/javascript" src="https://selenium.dev/selenium/web/js/jquery-ui-1.12.1.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function(){
$('#mousetracker').mousemove(function(e){
$('#mouse-tracker').mousemove(function(e){
xPos = e.pageX - this.offsetLeft;
yPos = e.pageY - this.offsetTop;
$('#status').html(xPos + ', ' + yPos);
$('#relative-location').html(xPos + ', ' + yPos);
});
})

Expand All @@ -29,14 +29,28 @@
document.getElementById('move-status').innerHTML = message;
}
function dropStatus(message) {
document.getElementById('drop-status').innerHTML = message;
document.getElementById('drop-status').innerHTML = message;
}
function relativeStatus(message) {
document.getElementById('relative-location').innerHTML = message;
}
function absoluteStatus(message) {
document.getElementById('absolute-location').innerHTML = message;
}
function tellPos(p){
document.getElementById('absolute-location').innerHTML = p.pageX + ', ' + p.pageY;
}
function clearAbsolute(p){
document.getElementById('absolute-location').innerHTML = '';
}
addEventListener('mousemove', tellPos, false);
document.documentElement.addEventListener('mouseleave', clearAbsolute, false);
</script>
<script type="text/javascript">
$(function () {
$("#draggable").draggable();
$("#droppable").droppable({
drop: function (event, ui) { dropStatus("Dropped!") }
drop: function (event, ui) { dropStatus("dropped") }
});
});
</script>
Expand All @@ -48,33 +62,33 @@ <h2>Mouse Clicks</h2>
<p><a href="resultPage.html" id="click">Click for Results Page</a></p>

<div>
<input type="text" id="presses"
onfocus="clickStatus('focus')"
oncontextmenu="clickStatus('contextClick')"
ondblclick="clickStatus('doubleClick')"
placeholder="Click"/>&nbsp;&nbsp;
<input type="text" id="clickable"
onfocus="clickStatus('focused')"
oncontextmenu="clickStatus('context-clicked')"
ondblclick="clickStatus('double-clicked')"
placeholder="Clickable"/>&nbsp;&nbsp;

<strong id="click-status">&nbsp;</strong>
</div>

<h2>Drag & Drop</h2>

<strong id="drop-status">&nbsp;</strong>
<div id="draggable" class="ui-widget-content">Drag this</div>
<div id="draggable" class="ui-widget-content">Draggable</div>

<div id="droppable" class="ui-widget-header">Drop here</div>
<div id="droppable" class="ui-widget-header">Droppable</div>

<h2>Mouse Position</h2>

<div>
<input type="button" id="hover" onmouseleave="moveStatus('')" onmouseover="moveStatus('hovered')" value="Hover"/>
<strong id="move-status">&nbsp;</strong>
<input type="button" id="hover" onmouseleave="moveStatus('')" onmouseover="moveStatus('hovered')" value="Hoverable"/>
<strong id="move-status">&nbsp</strong>
</div>

<p><strong id="status">0, 0</strong></p>
<div id="mousetracker" class="solidborder" style="position: absolute; height: 200px; width: 200px;">
<p><strong>Absolute Location: <span id="absolute-location" onmouseleave="absoluteStatus('')"></span></strong></p>
<p><strong>Relative Location in Box: <span id="relative-location"></span></strong></p>
<div id="mouse-tracker" onmouseleave="relativeStatus('')" class="solidborder" style="position: absolute; height: 200px; width: 200px;">
Move mouse here.
</div>

</body>
</html>
8 changes: 8 additions & 0 deletions dotnet/src/webdriver/Interactions/ActionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ public IList<ActionSequence> ToActionSequenceList()
return new List<ActionSequence>(this.sequences.Values).AsReadOnly();
}

/// <summary>
/// Resets the list of sequences.
/// </summary>
public void ClearSequences()
{
this.sequences = new Dictionary<InputDevice, ActionSequence>();
}

/// <summary>
/// Returns a string that represents the current <see cref="ActionBuilder"/>.
/// </summary>
Expand Down
30 changes: 22 additions & 8 deletions dotnet/src/webdriver/Interactions/Actions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ namespace OpenQA.Selenium.Interactions
/// <summary>
/// Provides values that indicate from where element offsets for MoveToElement
/// are calculated.
/// Note: TopLeft only does the expected thing when the element is completely
/// inside the viewport.
/// </summary>
[Obsolete("Starting in Selenium 4.3 only Center behavior will be supported")]
public enum MoveToElementOffsetOrigin
{
/// <summary>
Expand All @@ -49,6 +52,7 @@ public class Actions : IAction
private ActionBuilder actionBuilder = new ActionBuilder();
private PointerInputDevice defaultMouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
private KeyInputDevice defaultKeyboard = new KeyInputDevice("default keyboard");
private WheelInputDevice defaultWheel = new WheelInputDevice("default wheel");
private IActionExecutor actionExecutor;

/// <summary>
Expand Down Expand Up @@ -308,6 +312,7 @@ public Actions MoveToElement(IWebElement toElement)

/// <summary>
/// Moves the mouse to the specified offset of the top-left corner of the specified element.
/// In Selenium 4.3 the origin for the offset will be the in-view center point of the element.
/// </summary>
/// <param name="toElement">The element to which to move the mouse.</param>
/// <param name="offsetX">The horizontal offset to which to move the mouse.</param>
Expand All @@ -326,6 +331,7 @@ public Actions MoveToElement(IWebElement toElement, int offsetX, int offsetY)
/// <param name="offsetY">The vertical offset to which to move the mouse.</param>
/// <param name="offsetOrigin">The <see cref="MoveToElementOffsetOrigin"/> value from which to calculate the offset.</param>
/// <returns>A self-reference to this <see cref="Actions"/>.</returns>
[Obsolete("Starting in Selenium 4.3 only MoveToElementOffsetOrigin.Center will be supported")]
public Actions MoveToElement(IWebElement toElement, int offsetX, int offsetY, MoveToElementOffsetOrigin offsetOrigin)
{
ILocatable target = GetLocatableFromElement(toElement);
Expand Down Expand Up @@ -412,8 +418,7 @@ public Actions DragAndDropToOffset(IWebElement source, int offsetX, int offsetY)
/// <returns>A self-reference to this <see cref="Actions"/>.</returns>
public Actions ScrollToElement(IWebElement element)
{
WheelInputDevice wheel = new WheelInputDevice();
this.actionBuilder.AddAction(wheel.CreateWheelScroll(element, 0, 0, 0, 0, DefaultScrollDuration));
this.actionBuilder.AddAction(this.defaultWheel.CreateWheelScroll(element, 0, 0, 0, 0, DefaultScrollDuration));

return this;
}
Expand All @@ -426,8 +431,7 @@ public Actions ScrollToElement(IWebElement element)
/// <returns>A self-reference to this <see cref="Actions"/>.</returns>
public Actions ScrollByAmount(int deltaX, int deltaY)
{
WheelInputDevice wheel = new WheelInputDevice();
this.actionBuilder.AddAction(wheel.CreateWheelScroll(deltaX, deltaY, DefaultScrollDuration));
this.actionBuilder.AddAction(this.defaultWheel.CreateWheelScroll(deltaX, deltaY, DefaultScrollDuration));

return this;
}
Expand All @@ -447,27 +451,36 @@ public Actions ScrollByAmount(int deltaX, int deltaY)
/// <exception cref="MoveTargetOutOfBoundsException">If the origin with offset is outside the viewport.</exception>
public Actions ScrollFromOrigin(WheelInputDevice.ScrollOrigin scrollOrigin, int deltaX, int deltaY)
{
WheelInputDevice wheel = new WheelInputDevice();

if (scrollOrigin.Viewport && scrollOrigin.Element != null)
{
throw new ArgumentException("viewport can not be true if an element is defined.", nameof(scrollOrigin));
}

if (scrollOrigin.Viewport)
{
this.actionBuilder.AddAction(wheel.CreateWheelScroll(CoordinateOrigin.Viewport,
this.actionBuilder.AddAction(this.defaultWheel.CreateWheelScroll(CoordinateOrigin.Viewport,
scrollOrigin.XOffset, scrollOrigin.YOffset, deltaX, deltaY, DefaultScrollDuration));
}
else
{
this.actionBuilder.AddAction(wheel.CreateWheelScroll(scrollOrigin.Element,
this.actionBuilder.AddAction(this.defaultWheel.CreateWheelScroll(scrollOrigin.Element,
scrollOrigin.XOffset, scrollOrigin.YOffset, deltaX, deltaY, DefaultScrollDuration));
}

return this;
}

/// <summary>
/// Performs a Pause.
/// </summary>
/// <param name="duration">How long to pause the action chain.</param>
/// <returns>A self-reference to this <see cref="Actions"/>.</returns>
public Actions Pause(TimeSpan duration)
{
this.actionBuilder.AddAction(new PauseInteraction(this.defaultMouse, duration));
return this;
}

/// <summary>
/// Builds the sequence of actions.
/// </summary>
Expand All @@ -483,6 +496,7 @@ public IAction Build()
public void Perform()
{
this.actionExecutor.PerformActions(this.actionBuilder.ToActionSequenceList());
this.actionBuilder.ClearSequences();
}

/// <summary>
Expand Down
18 changes: 4 additions & 14 deletions dotnet/src/webdriver/Interactions/PointerInputDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,6 @@ public enum MouseButton
/// The X2 button used for navigating forward.
/// </summary>
Forward = 4,

/// <summary>
/// The button used by Pen pointers to erase.
/// </summary>
Eraser = 5
}

/// <summary>
Expand Down Expand Up @@ -177,7 +172,7 @@ public override Dictionary<string, object> ToDictionary()
/// <returns>The action representing the pointer down gesture.</returns>
public Interaction CreatePointerDown(MouseButton button)
{
return new PointerDownInteraction(this, button, new PointerEventProperties());
return CreatePointerDown(button, new PointerEventProperties());
}

/// <summary>
Expand All @@ -201,7 +196,7 @@ public Interaction CreatePointerDown(MouseButton button, PointerEventProperties
/// <returns>The action representing the pointer up gesture.</returns>
public Interaction CreatePointerUp(MouseButton button)
{
return new PointerUpInteraction(this, button, new PointerEventProperties());
return CreatePointerUp(button, new PointerEventProperties());
}

/// <summary>
Expand All @@ -228,7 +223,7 @@ public Interaction CreatePointerUp(MouseButton button, PointerEventProperties pr
/// <returns>The action representing the pointer move gesture.</returns>
public Interaction CreatePointerMove(IWebElement target, int xOffset, int yOffset, TimeSpan duration)
{
return new PointerMoveInteraction(this, target, CoordinateOrigin.Element, xOffset, yOffset, duration, new PointerEventProperties());
return CreatePointerMove(target, xOffset, yOffset, duration, new PointerEventProperties());
}

/// <summary>
Expand Down Expand Up @@ -258,12 +253,7 @@ public Interaction CreatePointerMove(IWebElement target, int xOffset, int yOffse
/// Users should us the other CreatePointerMove overload to move to a specific element.</exception>
public Interaction CreatePointerMove(CoordinateOrigin origin, int xOffset, int yOffset, TimeSpan duration)
{
if (origin == CoordinateOrigin.Element)
{
throw new ArgumentException("Using a value of CoordinateOrigin.Element without an element is not supported.", nameof(origin));
}

return new PointerMoveInteraction(this, null, origin, xOffset, yOffset, duration, new PointerEventProperties());
return CreatePointerMove(origin, xOffset, yOffset, duration, new PointerEventProperties());
}

/// <summary>
Expand Down
8 changes: 8 additions & 0 deletions dotnet/test/common/Interactions/CombinedInputActionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,14 @@ public void CanClickOnSuckerFishMenuItem()
WaitFor(() => { return result.Text.Contains("item 1"); }, "Result element does not contain text 'item 1'");
}

[Test]
public void PerformsPause()
{
DateTime start = DateTime.Now;
new Actions(driver).Pause(TimeSpan.FromMilliseconds(1200)).Build().Perform();
Assert.IsTrue(DateTime.Now - start > TimeSpan.FromMilliseconds(1200));
}

private bool FuzzyPositionMatching(int expectedX, int expectedY, string locationTuple)
{
string[] splitString = locationTuple.Split(',');
Expand Down
5 changes: 2 additions & 3 deletions java/src/org/openqa/selenium/interactions/Actions.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
import static org.openqa.selenium.interactions.PointerInput.MouseButton.LEFT;
import static org.openqa.selenium.interactions.PointerInput.MouseButton.RIGHT;

import org.openqa.selenium.Dimension;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.UnsupportedCommandException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
Expand Down Expand Up @@ -420,9 +422,6 @@ public Actions moveToElement(WebElement target, int xOffset, int yOffset) {
action.addAction(new MoveToOffsetAction(jsonMouse, (Locatable) target, xOffset, yOffset));
}

// Of course, this is the offset from the centre of the element. We have no idea what the width
// and height are once we execute this method.
LOG.info("When using the W3C Action commands, offsets are from the element's in-view center point");
return moveInTicks(target, xOffset, yOffset);
}

Expand Down
32 changes: 29 additions & 3 deletions java/src/org/openqa/selenium/interactions/PointerInput.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,32 @@ public Interaction createPointerDown(int button) {
return new PointerPress(this, PointerPress.Direction.DOWN, button);
}

/**
* @deprecated always use the method with the button
*/
@Deprecated
public Interaction createPointerDown(PointerEventProperties eventProperties) {
return new PointerPress(this, PointerPress.Direction.DOWN, eventProperties);
return createPointerDown(0, eventProperties);
}

public Interaction createPointerDown(int button, PointerEventProperties eventProperties) {
return new PointerPress(this, PointerPress.Direction.DOWN, button, eventProperties);
}

public Interaction createPointerUp(int button) {
return new PointerPress(this, PointerPress.Direction.UP, button);
}

/**
* @deprecated always use the method with the button
*/
@Deprecated
public Interaction createPointerUp(PointerEventProperties eventProperties) {
return new PointerPress(this, PointerPress.Direction.UP, eventProperties);
return createPointerUp(0, eventProperties);
}

public Interaction createPointerUp(int button, PointerEventProperties eventProperties) {
return new PointerPress(this, PointerPress.Direction.UP, button, eventProperties);
}

private static class PointerPress extends Interaction implements Encodable {
Expand All @@ -110,9 +126,17 @@ public PointerPress(InputSource source, Direction direction, int button) {
this.eventProperties = new PointerEventProperties();
}

/**
* @deprecated always use the constructor with the button
*/
@Deprecated
public PointerPress(InputSource source, Direction direction, PointerEventProperties eventProperties) {
this(source, direction, 0, eventProperties);
}

public PointerPress(InputSource source, Direction direction, int button, PointerEventProperties eventProperties) {
super(source);
this.button = 0;
this.button = button;
this.eventProperties = Require.nonNull("pointer event properties", eventProperties);
this.direction = Require.nonNull("Direction of press", direction);
}
Expand Down Expand Up @@ -212,6 +236,8 @@ public enum MouseButton {
LEFT(0),
MIDDLE(1),
RIGHT(2),
BACK(3),
FORWARD(4),
;

private final int button;
Expand Down
2 changes: 1 addition & 1 deletion java/src/org/openqa/selenium/remote/RemoteRotatable.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public ScreenOrientation getOrientation() {

@Override
public void rotate(DeviceRotation rotation) {
executeMethod.execute(DriverCommand.SET_SCREEN_ORIENTATION, rotation.parameters());
executeMethod.execute(DriverCommand.SET_SCREEN_ROTATION, rotation.parameters());
}

@Override
Expand Down
Loading

0 comments on commit f286267

Please sign in to comment.