diff --git a/common/src/web/mouse_interaction.html b/common/src/web/mouse_interaction.html index f5cd7d3dad067..e771a6b42612e 100644 --- a/common/src/web/mouse_interaction.html +++ b/common/src/web/mouse_interaction.html @@ -3,20 +3,20 @@ BasicMouseInterfaceTest - - - + + + @@ -48,11 +62,11 @@

Mouse Clicks

Click for Results Page

-    +     
@@ -60,21 +74,21 @@

Mouse Clicks

Drag & Drop

  -
Drag this
+
Draggable
-
Drop here
+
Droppable

Mouse Position

- -   + +  
-

0, 0

-
+

Absolute Location:

+

Relative Location in Box:

+
Move mouse here.
- diff --git a/dotnet/src/webdriver/Interactions/ActionBuilder.cs b/dotnet/src/webdriver/Interactions/ActionBuilder.cs index 052c65041666f..21c8919287b68 100644 --- a/dotnet/src/webdriver/Interactions/ActionBuilder.cs +++ b/dotnet/src/webdriver/Interactions/ActionBuilder.cs @@ -66,6 +66,14 @@ public IList ToActionSequenceList() return new List(this.sequences.Values).AsReadOnly(); } + /// + /// Resets the list of sequences. + /// + public void ClearSequences() + { + this.sequences = new Dictionary(); + } + /// /// Returns a string that represents the current . /// diff --git a/dotnet/src/webdriver/Interactions/Actions.cs b/dotnet/src/webdriver/Interactions/Actions.cs index be4a530603b72..5fcdb95c90ac7 100644 --- a/dotnet/src/webdriver/Interactions/Actions.cs +++ b/dotnet/src/webdriver/Interactions/Actions.cs @@ -25,7 +25,10 @@ namespace OpenQA.Selenium.Interactions /// /// 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. /// + [Obsolete("Starting in Selenium 4.3 only Center behavior will be supported")] public enum MoveToElementOffsetOrigin { /// @@ -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; /// @@ -308,6 +312,7 @@ public Actions MoveToElement(IWebElement toElement) /// /// 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. /// /// The element to which to move the mouse. /// The horizontal offset to which to move the mouse. @@ -326,6 +331,7 @@ public Actions MoveToElement(IWebElement toElement, int offsetX, int offsetY) /// The vertical offset to which to move the mouse. /// The value from which to calculate the offset. /// A self-reference to this . + [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); @@ -412,8 +418,7 @@ public Actions DragAndDropToOffset(IWebElement source, int offsetX, int offsetY) /// A self-reference to this . 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; } @@ -426,8 +431,7 @@ public Actions ScrollToElement(IWebElement element) /// A self-reference to this . 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; } @@ -447,8 +451,6 @@ public Actions ScrollByAmount(int deltaX, int deltaY) /// If the origin with offset is outside the viewport. 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)); @@ -456,18 +458,29 @@ public Actions ScrollFromOrigin(WheelInputDevice.ScrollOrigin scrollOrigin, int 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; } + /// + /// Performs a Pause. + /// + /// How long to pause the action chain. + /// A self-reference to this . + public Actions Pause(TimeSpan duration) + { + this.actionBuilder.AddAction(new PauseInteraction(this.defaultMouse, duration)); + return this; + } + /// /// Builds the sequence of actions. /// @@ -483,6 +496,7 @@ public IAction Build() public void Perform() { this.actionExecutor.PerformActions(this.actionBuilder.ToActionSequenceList()); + this.actionBuilder.ClearSequences(); } /// diff --git a/dotnet/src/webdriver/Interactions/PointerInputDevice.cs b/dotnet/src/webdriver/Interactions/PointerInputDevice.cs index 6db1f3721187f..1aa6a4c4836fc 100644 --- a/dotnet/src/webdriver/Interactions/PointerInputDevice.cs +++ b/dotnet/src/webdriver/Interactions/PointerInputDevice.cs @@ -102,11 +102,6 @@ public enum MouseButton /// The X2 button used for navigating forward. /// Forward = 4, - - /// - /// The button used by Pen pointers to erase. - /// - Eraser = 5 } /// @@ -177,7 +172,7 @@ public override Dictionary ToDictionary() /// The action representing the pointer down gesture. public Interaction CreatePointerDown(MouseButton button) { - return new PointerDownInteraction(this, button, new PointerEventProperties()); + return CreatePointerDown(button, new PointerEventProperties()); } /// @@ -201,7 +196,7 @@ public Interaction CreatePointerDown(MouseButton button, PointerEventProperties /// The action representing the pointer up gesture. public Interaction CreatePointerUp(MouseButton button) { - return new PointerUpInteraction(this, button, new PointerEventProperties()); + return CreatePointerUp(button, new PointerEventProperties()); } /// @@ -228,7 +223,7 @@ public Interaction CreatePointerUp(MouseButton button, PointerEventProperties pr /// The action representing the pointer move gesture. 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()); } /// @@ -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. 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()); } /// diff --git a/dotnet/test/common/Interactions/CombinedInputActionsTest.cs b/dotnet/test/common/Interactions/CombinedInputActionsTest.cs index 01a9bde08e72f..608dbbf749709 100644 --- a/dotnet/test/common/Interactions/CombinedInputActionsTest.cs +++ b/dotnet/test/common/Interactions/CombinedInputActionsTest.cs @@ -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(','); diff --git a/java/src/org/openqa/selenium/interactions/Actions.java b/java/src/org/openqa/selenium/interactions/Actions.java index 811112625113d..6424bec1a77e1 100644 --- a/java/src/org/openqa/selenium/interactions/Actions.java +++ b/java/src/org/openqa/selenium/interactions/Actions.java @@ -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; @@ -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); } diff --git a/java/src/org/openqa/selenium/interactions/PointerInput.java b/java/src/org/openqa/selenium/interactions/PointerInput.java index 8bd2568e74c04..29b7bbf82d566 100644 --- a/java/src/org/openqa/selenium/interactions/PointerInput.java +++ b/java/src/org/openqa/selenium/interactions/PointerInput.java @@ -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 { @@ -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); } @@ -212,6 +236,8 @@ public enum MouseButton { LEFT(0), MIDDLE(1), RIGHT(2), + BACK(3), + FORWARD(4), ; private final int button; diff --git a/java/src/org/openqa/selenium/remote/RemoteRotatable.java b/java/src/org/openqa/selenium/remote/RemoteRotatable.java index 438d0498cb885..f6942a2a9592a 100644 --- a/java/src/org/openqa/selenium/remote/RemoteRotatable.java +++ b/java/src/org/openqa/selenium/remote/RemoteRotatable.java @@ -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 diff --git a/java/test/org/openqa/selenium/interactions/PenPointerTest.java b/java/test/org/openqa/selenium/interactions/PenPointerTest.java index 19bd6ed3ee071..93c7b7f5f16b7 100644 --- a/java/test/org/openqa/selenium/interactions/PenPointerTest.java +++ b/java/test/org/openqa/selenium/interactions/PenPointerTest.java @@ -17,12 +17,14 @@ package org.openqa.selenium.interactions; +import org.assertj.core.api.Assertions; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.Dimension; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.Point; +import org.openqa.selenium.Rectangle; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.remote.RemoteWebDriver; @@ -36,7 +38,11 @@ import org.openqa.selenium.testing.SwitchToTopAfterTest; import java.time.Duration; +import java.util.Arrays; import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; @@ -371,6 +377,70 @@ public void testCanMoveOverAndOutOfAnElement() { wait.until(attributeToBe(redbox, "background-color", Colors.GREEN.getColorValue().asRgba())); } + @Test + @Ignore(value = FIREFOX, issue = "https://github.com/mozilla/geckodriver/issues/789") + public void setPointerEventProperties() { + driver.get(pages.pointerActionsPage); + long start = System.currentTimeMillis(); + + WebElement pointerArea = driver.findElement(By.id("pointerArea")); + PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen"); + PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties() + .setTiltX(-72) + .setTiltY(9) + .setTwist(86); + PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea); + + Sequence actionListPen = new Sequence(pen, 0) + .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0)) + .addAction(pen.createPointerDown(0)) + .addAction(pen.createPointerMove(Duration.ofMillis(800), origin, 2, 2, eventProperties)) + .addAction(pen.createPointerUp(0)); + + ((RemoteWebDriver) driver).perform(List.of(actionListPen)); + + long duration = System.currentTimeMillis() - start; + Assertions.assertThat(duration).isGreaterThan(2); + + List moves = driver.findElements(By.className("pointermove")); + Map moveTo = properties(moves.get(0)); + Map down = properties(driver.findElement(By.className("pointerdown"))); + Map moveBy = properties(moves.get(1)); + Map up = properties(driver.findElement(By.className("pointerup"))); + + Rectangle rect = pointerArea.getRect(); + + int centerX = (int) Math.floor(rect.width / 2 + rect.getX()); + int centerY = (int) Math.floor(rect.height / 2 + rect.getY()); + Assertions.assertThat(moveTo.get("button")).isEqualTo("-1"); + Assertions.assertThat(moveTo.get("pageX")).isEqualTo("" + centerX); + Assertions.assertThat(moveTo.get("pageY")).isEqualTo("" + centerY); + Assertions.assertThat(down.get("button")).isEqualTo("0"); + Assertions.assertThat(down.get("pageX")).isEqualTo("" + centerX); + Assertions.assertThat(down.get("pageY")).isEqualTo("" + centerY); + Assertions.assertThat(moveBy.get("button")).isEqualTo("-1"); + Assertions.assertThat(moveBy.get("pageX")).isEqualTo("" + (centerX + 2)); + Assertions.assertThat(moveBy.get("pageY")).isEqualTo("" + (centerY + 2)); + Assertions.assertThat(moveBy.get("tiltX")).isEqualTo("-72"); + Assertions.assertThat(moveBy.get("tiltY")).isEqualTo("9"); + Assertions.assertThat(moveBy.get("twist")).isEqualTo("86"); + Assertions.assertThat(up.get("button")).isEqualTo("0"); + Assertions.assertThat(up.get("pageX")).isEqualTo("" + (centerX + 2)); + Assertions.assertThat(up.get("pageY")).isEqualTo("" + (centerY + 2)); + } + + private Map properties(WebElement element) { + String text = element.getText(); + text = text.substring(text.indexOf(' ') + 1); + + return Arrays.stream(text.split(", ")) + .map(s -> s.split(": ")) + .collect(Collectors.toMap( + a -> a[0], //key + a -> a[1] //value + )); + } + private boolean fuzzyPositionMatching(int expectedX, int expectedY, String locationTuple) { String[] splitString = locationTuple.split(","); int gotX = Integer.parseInt(splitString[0].trim()); diff --git a/java/test/org/openqa/selenium/interactions/PointerInputTest.java b/java/test/org/openqa/selenium/interactions/PointerInputTest.java index 7e21013cca455..836fa92f45e80 100644 --- a/java/test/org/openqa/selenium/interactions/PointerInputTest.java +++ b/java/test/org/openqa/selenium/interactions/PointerInputTest.java @@ -63,7 +63,7 @@ public void encodesWrappedElementInMoveOrigin() { @Test public void acceptsPointerEventProperties() { PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "my pen"); - Interaction pointerDown = pen.createPointerDown(PointerInput.eventProperties().setHeight(12).setTiltX(30)); + Interaction pointerDown = pen.createPointerDown(0, PointerInput.eventProperties().setHeight(12).setTiltX(30)); Map encode = ((Encodable) pointerDown).encode(); diff --git a/java/test/org/openqa/selenium/testing/Pages.java b/java/test/org/openqa/selenium/testing/Pages.java index 6e8ce4145783f..a397cf1ac0d1c 100644 --- a/java/test/org/openqa/selenium/testing/Pages.java +++ b/java/test/org/openqa/selenium/testing/Pages.java @@ -54,9 +54,11 @@ public class Pages { public String mapVisibilityPage; public String metaRedirectPage; public String missedJsReferencePage; + public String mouseInteractionPage; public String mouseOverPage; public String mouseTrackerPage; public String nestedPage; + public String pointerActionsPage; public String printPage; public String readOnlyPage; public String rectanglesPage; @@ -116,9 +118,11 @@ public Pages(AppServer appServer) { mapVisibilityPage = appServer.whereIs("map_visibility.html"); metaRedirectPage = appServer.whereIs("meta-redirect.html"); missedJsReferencePage = appServer.whereIs("missedJsReference.html"); + mouseInteractionPage = appServer.whereIs("mouse_interaction.html"); mouseOverPage = appServer.whereIs("mouseOver.html"); mouseTrackerPage = appServer.whereIs("mousePositionTracker.html"); nestedPage = appServer.whereIs("nestedElements.html"); + pointerActionsPage = appServer.whereIs("pointerActionsPage.html"); printPage = appServer.whereIs("printPage.html"); readOnlyPage = appServer.whereIs("readOnlyPage.html"); rectanglesPage = appServer.whereIs("rectangles.html"); diff --git a/py/selenium/webdriver/common/actions/mouse_button.py b/py/selenium/webdriver/common/actions/mouse_button.py index c187c37f1ce5b..1ebd28ff1ba53 100644 --- a/py/selenium/webdriver/common/actions/mouse_button.py +++ b/py/selenium/webdriver/common/actions/mouse_button.py @@ -21,3 +21,5 @@ class MouseButton: LEFT = 0 MIDDLE = 1 RIGHT = 2 + BACK = 3 + FORWARD = 4 diff --git a/py/selenium/webdriver/common/actions/pointer_actions.py b/py/selenium/webdriver/common/actions/pointer_actions.py index 8372c71b6a499..36572ef148db5 100644 --- a/py/selenium/webdriver/common/actions/pointer_actions.py +++ b/py/selenium/webdriver/common/actions/pointer_actions.py @@ -14,6 +14,8 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. +import warnings + from . import interaction from .interaction import Interaction @@ -57,6 +59,13 @@ def move_to(self, element, x=0, y=0, width=None, height=None, pressure=None, raise AttributeError("move_to requires a WebElement") if x or y: + warnings.warn( + "move_to_element_with_offset() currently tries to use the top left corner " + "of the element as the origin; in Selenium 4.3 it will use the in-view " + "center point of the element as the origin.", + DeprecationWarning, + stacklevel=2 + ) el_rect = element.rect left_offset = el_rect['width'] / 2 top_offset = el_rect['height'] / 2 diff --git a/rb/.rubocop.yml b/rb/.rubocop.yml index 5a06a7102d8e5..a1f6007e1c8e4 100644 --- a/rb/.rubocop.yml +++ b/rb/.rubocop.yml @@ -77,7 +77,7 @@ Metrics/MethodLength: Metrics/ModuleLength: CountComments: false - Max: 101 + Max: 110 Exclude: - 'lib/selenium/webdriver/common/platform.rb' - 'spec/**/*' diff --git a/rb/CHANGES b/rb/CHANGES index cd0ee91601753..346a02591eb4d 100644 --- a/rb/CHANGES +++ b/rb/CHANGES @@ -41,6 +41,7 @@ ActionBuilder: * Add support for pointer event properties * Implement scroll wheel support * Deprecate ordered pair parameters for pause method in favor of keywords + * Deprecate move to element with offset changing origin to top left of element 4.1.0 (2021-11-22) ========================= diff --git a/rb/lib/selenium/webdriver/common/action_builder.rb b/rb/lib/selenium/webdriver/common/action_builder.rb index 46944af37e601..0072aa3c31ce4 100644 --- a/rb/lib/selenium/webdriver/common/action_builder.rb +++ b/rb/lib/selenium/webdriver/common/action_builder.rb @@ -198,7 +198,7 @@ def pause(deprecated_device = nil, deprecated_duration = nil, device: nil, durat deprecate_method(deprecated_device, deprecated_duration) device ||= deprecated_device || pointer_input - device.create_pause(duration || deprecated_duration) + device.create_pause(deprecated_duration || duration) self end diff --git a/rb/lib/selenium/webdriver/common/interactions/pointer_actions.rb b/rb/lib/selenium/webdriver/common/interactions/pointer_actions.rb index 60bd448fd1358..25ceec4f4157b 100644 --- a/rb/lib/selenium/webdriver/common/interactions/pointer_actions.rb +++ b/rb/lib/selenium/webdriver/common/interactions/pointer_actions.rb @@ -99,6 +99,9 @@ def pointer_up(button = :left, device: nil, **opts) def move_to(element, right_by = nil, down_by = nil, device: nil, duration: default_move_duration, **opts) pointer = pointer_input(device) if right_by || down_by + WebDriver.logger.warn("moving to an element with offset currently tries to use +the top left corner of the element as the origin; in Selenium 4.3 it will use the in-view +center point of the element as the origin.") size = element.size left_offset = (size[:width] / 2).to_i top_offset = (size[:height] / 2).to_i @@ -134,12 +137,13 @@ def move_to(element, right_by = nil, down_by = nil, device: nil, duration: defau # @raise [MoveTargetOutOfBoundsError] if the provided offset is outside the document's boundaries. # - def move_by(right_by, down_by, device: nil, duration: default_move_duration) + def move_by(right_by, down_by, device: nil, duration: default_move_duration, **opts) pointer = pointer_input(device) pointer.create_pointer_move(duration: duration, x: Integer(right_by), y: Integer(down_by), - origin: Interactions::PointerMove::POINTER) + origin: Interactions::PointerMove::POINTER, + **opts) tick(pointer) self end @@ -161,12 +165,13 @@ def move_by(right_by, down_by, device: nil, duration: default_move_duration) # @raise [MoveTargetOutOfBoundsError] if the provided x or y value is outside the document's boundaries. # - def move_to_location(x, y, device: nil, duration: default_move_duration) + def move_to_location(x, y, device: nil, duration: default_move_duration, **opts) pointer = pointer_input(device) pointer.create_pointer_move(duration: duration, x: Integer(x), y: Integer(y), - origin: Interactions::PointerMove::VIEWPORT) + origin: Interactions::PointerMove::VIEWPORT, + **opts) tick(pointer) self end diff --git a/rb/lib/selenium/webdriver/common/interactions/pointer_press.rb b/rb/lib/selenium/webdriver/common/interactions/pointer_press.rb index d6d4871bf3984..e37e81f07f538 100644 --- a/rb/lib/selenium/webdriver/common/interactions/pointer_press.rb +++ b/rb/lib/selenium/webdriver/common/interactions/pointer_press.rb @@ -38,8 +38,7 @@ class PointerPress < Interaction x1: 3, back: 3, x2: 4, - forward: 4, - erase: 5}.freeze + forward: 4}.freeze DIRECTIONS = {down: :pointerDown, up: :pointerUp}.freeze def initialize(source, direction, button, **opts) diff --git a/rb/spec/integration/selenium/webdriver/action_builder_spec.rb b/rb/spec/integration/selenium/webdriver/action_builder_spec.rb index 5db550b70c7b7..ce966df9b5dc9 100644 --- a/rb/spec/integration/selenium/webdriver/action_builder_spec.rb +++ b/rb/spec/integration/selenium/webdriver/action_builder_spec.rb @@ -260,7 +260,7 @@ module WebDriver end end - describe 'pen stylus' do + describe 'pen stylus', except: {browser: :firefox, reason: 'Unknown pointerType'} do it 'sets pointer event properties' do driver.get 'https://titusfortner.com/examples/pointerActionsPage.html' pointer_area = driver.find_element(id: 'pointerArea') @@ -271,8 +271,8 @@ module WebDriver pointer_options = {pressure: 0.8, tilt_x: -40, tilt_y: -10, twist: 177} actions = driver.action(devices: :pen) .move_by(x_val + 5, y_val + 5) - .pointer_down(**pointer_options) - .move_by(2, 2, duration: 0.8) + .pointer_down + .move_by(2, 2, duration: 0.8, **pointer_options) .pointer_up start = Time.now @@ -288,15 +288,13 @@ module WebDriver expect(move_to).to include("button" => "-1", "pageX" => (x_val + 5).to_s, "pageY" => (y_val + 5).floor.to_s) - expect(down).to include("button" => "0", - "pageX" => (x_val + 5).to_s, - "pageY" => (y_val + 5).floor.to_s, - "tiltX" => "-40", - "tiltY" => "-10", - "twist" => "177") + expect(down).to include("button" => "0") expect(move_by).to include("button" => "-1", "pageX" => (x_val + 5 + 2).to_s, - "pageY" => (y_val + 5 + 2).floor.to_s) + "pageY" => (y_val + 5 + 2).floor.to_s, + "tiltX" => "-40", + "tiltY" => "-10", + "twist" => "177") expect(up).to include("button" => "0", "pageX" => (x_val + 5 + 2).to_s, "pageY" => (y_val + 5 + 2).floor.to_s) @@ -376,6 +374,7 @@ module WebDriver iframe = driver.find_element(tag_name: 'iframe') driver.switch_to.frame(iframe) checkbox = driver.find_element(name: 'scroll_checkbox') + sleep 0.5 expect(in_viewport?(checkbox)).to eq true end diff --git a/rb/spec/integration/selenium/webdriver/element_spec.rb b/rb/spec/integration/selenium/webdriver/element_spec.rb index 4145465a87956..2101646137cb9 100644 --- a/rb/spec/integration/selenium/webdriver/element_spec.rb +++ b/rb/spec/integration/selenium/webdriver/element_spec.rb @@ -45,7 +45,7 @@ module WebDriver driver.navigate.to url_for('formPage.html') driver.find_element(id: 'submitButton').submit - wait_for_new_url('formPage.html') + sleep 0.5 expect(driver.title).to eq('We Arrive Here') end @@ -53,7 +53,7 @@ module WebDriver driver.navigate.to url_for('formPage.html') driver.find_element(id: 'checky').submit - wait_for_new_url('formPage.html') + sleep 0.5 expect(driver.title).to eq('We Arrive Here') end @@ -61,7 +61,7 @@ module WebDriver driver.navigate.to url_for('formPage.html') driver.find_element(css: 'form > p').submit - wait_for_new_url('formPage.html') + sleep 0.5 expect(driver.title).to eq('We Arrive Here') end @@ -69,7 +69,7 @@ module WebDriver driver.navigate.to url_for('formPage.html') driver.find_element(id: 'submit').submit - wait_for_new_url('formPage.html') + sleep 0.5 expect(driver.title).to eq('We Arrive Here') end @@ -77,7 +77,7 @@ module WebDriver driver.navigate.to url_for('formPage.html') driver.find_element(name: 'submit').submit - wait_for_new_url('formPage.html') + sleep 0.5 expect(driver.title).to eq('We Arrive Here') end diff --git a/rb/spec/integration/selenium/webdriver/spec_support/test_environment.rb b/rb/spec/integration/selenium/webdriver/spec_support/test_environment.rb index dec712ae91379..0dbfba7d43d6c 100644 --- a/rb/spec/integration/selenium/webdriver/spec_support/test_environment.rb +++ b/rb/spec/integration/selenium/webdriver/spec_support/test_environment.rb @@ -29,7 +29,7 @@ def initialize extract_browser_from_bazel_target_name - @driver = ENV.fetch('WD_SPEC_DRIVER', :chrome).to_sym + @driver = ENV.fetch('WD_SPEC_DRIVER', :firefox).to_sym @driver_instance = nil end