Skip to content

Commit 7fe7873

Browse files
committed
update ruby & python scrolling tests and documentation to match Java and .NET
1 parent 1a2a35b commit 7fe7873

5 files changed

Lines changed: 53 additions & 43 deletions

File tree

py/selenium/webdriver/common/action_chains.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
"""
1919
The ActionChains implementation,
2020
"""
21+
from typing import Union
2122

2223
from .utils import keys_to_typing
2324
from .actions.action_builder import ActionBuilder
25+
from selenium.webdriver.remote.webelement import WebElement
2426

2527

2628
class ActionChains:
@@ -321,16 +323,22 @@ def send_keys_to_element(self, element, *keys_to_send):
321323
self.send_keys(*keys_to_send)
322324
return self
323325

324-
def scroll(self, x: int, y: int, delta_x: int, delta_y: int, duration: int = 0, origin= "viewport"):
326+
def scroll(self, x: int, y: int, delta_x: int, delta_y: int, duration: int = 0, origin: Union[str,WebElement] = "viewport"):
325327
"""
326-
Sends wheel scroll information to the browser to be processed.
328+
Scrolls by the provided amount from a designated origination point.
329+
The scroll origin is either the center of an element or the upper left of the viewport plus any offsets.
330+
If the origin is an element, and the element is not in the viewport, the bottom of the element will first
331+
be scrolled to the bottom of the viewport.
327332
328333
:Args:
329-
- x: starting X coordinate
330-
- y: starting Y coordinate
331-
- delta_x: the distance the mouse will scroll on the x axis
332-
- delta_y: the distance the mouse will scroll on the y axis
333-
- origin: element whose center is the origination point of the scroll; the default is upper left of viewport.
334+
- x: The horizontal offset from the origin from which to start the scroll.
335+
- y: The vertical offset from the origin from which to start the scroll.
336+
- delta_x: Distance along X axis to scroll using the wheel. A negative value scrolls left.
337+
- delta_y: Distance along Y axis to scroll using the wheel. A negative value scrolls up.
338+
- origin: Where scroll originates (viewport or element center). The default is upper left of viewport.
339+
340+
:Raises: If the origin with offset is outside the viewport.
341+
- MoveTargetOutOfBoundsException - If the origin with offset is outside the viewport.
334342
"""
335343
self.w3c_actions.wheel_action.scroll(x=x, y=y, delta_x=delta_x, delta_y=delta_y,
336344
duration=duration, origin=origin)

py/test/selenium/webdriver/common/interactions_tests.py

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ def test_can_scroll_from_element_by_amount(driver, pages):
284284

285285
driver.switch_to.frame(iframe)
286286
checkbox = driver.find_element(By.NAME, "scroll_checkbox")
287-
288287
assert _in_viewport(driver, checkbox)
289288

290289

@@ -299,7 +298,6 @@ def test_can_scroll_from_element_with_offset_by_amount(driver, pages):
299298
iframe = driver.find_element(By.TAG_NAME, "iframe")
300299
driver.switch_to.frame(iframe)
301300
checkbox = driver.find_element(By.NAME, "scroll_checkbox")
302-
303301
assert _in_viewport(driver, checkbox)
304302

305303

@@ -318,9 +316,9 @@ def test_errors_when_element_offset_not_in_viewport(driver, pages):
318316
def test_can_scroll_from_viewport_by_amount(driver, pages):
319317
pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")
320318
footer = driver.find_element(By.TAG_NAME, "footer")
321-
y = footer.rect['y']
319+
delta_y = footer.rect['y']
322320

323-
ActionChains(driver).scroll(0, 0, 0, y).pause(0.2).perform()
321+
ActionChains(driver).scroll(0, 0, 0, delta_y).pause(0.2).perform()
324322

325323
assert _in_viewport(driver, footer)
326324

@@ -329,42 +327,24 @@ def test_can_scroll_from_viewport_by_amount(driver, pages):
329327
@pytest.mark.xfail_remote
330328
def test_can_scroll_from_viewport_with_offset_by_amount(driver, pages):
331329
pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html")
332-
iframe = driver.find_element(By.TAG_NAME, "iframe")
333330

334331
ActionChains(driver).scroll(10, 10, 0, 200).pause(0.2).perform()
335332

333+
iframe = driver.find_element(By.TAG_NAME, "iframe")
336334
driver.switch_to.frame(iframe)
337335
checkbox = driver.find_element(By.NAME, "scroll_checkbox")
338-
339336
assert _in_viewport(driver, checkbox)
340337

341338

342339
@pytest.mark.xfail_firefox
343340
@pytest.mark.xfail_remote
344341
def test_errors_when_origin_offset_not_in_viewport(driver, pages):
345-
pages.load("scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")
342+
pages.load("scrolling_tests/frame_with_nested_scrolling_frame.html")
346343

347344
with pytest.raises(MoveTargetOutOfBoundsException):
348345
ActionChains(driver).scroll(-10, -10, 0, 200).perform()
349346

350347

351-
@pytest.mark.xfail_firefox
352-
@pytest.mark.xfail_remote
353-
def test_can_scroll_mouse_wheel(driver, pages):
354-
pages.load("scrollingPage.html")
355-
driver.execute_script("document.scrollingElement.scrollTop = 0")
356-
357-
scrollable = driver.find_element(By.CSS_SELECTOR, "#scrollable")
358-
ActionChains(driver).scroll(0, 0, 5, 10, origin=scrollable).perform()
359-
events = _get_events(driver)
360-
assert len(events) == 1
361-
assert events[0]["type"] == "wheel"
362-
assert events[0]["deltaX"] >= 5
363-
assert events[0]["deltaY"] >= 10
364-
assert events[0]["deltaZ"] == 0
365-
assert events[0]["target"] == "scrollContent"
366-
367-
368348
def _get_events(driver):
369349
"""Return list of key events recorded in the test_keys_page fixture."""
370350
events = driver.execute_script("return allEvents.events;") or []

py/test/selenium/webdriver/common/w3c_interaction_tests.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import pytest
1919

20+
from selenium.webdriver.common.actions.wheel_input import WheelInput
2021
from selenium.webdriver.common.keys import Keys
2122
from selenium.webdriver.common.actions.action_builder import ActionBuilder
2223
from selenium.webdriver.common.actions.pointer_input import PointerInput
@@ -259,6 +260,25 @@ def test_touch_pointer_properties(driver, pages):
259260
assert events[3]["twist"] == 345
260261

261262

263+
def test_can_scroll_mouse_wheel(driver, pages):
264+
pages.load("scrollingPage.html")
265+
driver.execute_script("document.scrollingElement.scrollTop = 0")
266+
scrollable = driver.find_element(By.CSS_SELECTOR, "#scrollable")
267+
268+
wheel_input = WheelInput("wheel")
269+
actions = ActionBuilder(driver, wheel=wheel_input)
270+
actions.wheel_action.scroll(0, 0, 5, 10, 0, scrollable)
271+
272+
actions.perform()
273+
events = _get_events(driver)
274+
assert len(events) == 1
275+
assert events[0]["type"] == "wheel"
276+
assert events[0]["deltaX"] >= 5
277+
assert events[0]["deltaY"] >= 10
278+
assert events[0]["deltaZ"] == 0
279+
assert events[0]["target"] == "scrollContent"
280+
281+
262282
def _perform_drag_and_drop_with_mouse(driver, pages):
263283
"""Copied from org.openqa.selenium.interactions.TestBasicMouseInterface."""
264284
pages.load("draggableLists.html")

rb/lib/selenium/webdriver/common/interactions/wheel_actions.rb

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@ def default_scroll_duration
2525
end
2626

2727
#
28-
# This method uses a Scroll Wheel Input to determine where and by how much to scroll
28+
# Scrolls by the provided amount from a designated origination point.
2929
#
30-
# The scroll happens from an origin plus an offset.
31-
# The amount to scroll is represented by delta_x and delta_y
32-
# The origin is either the center of a provided element or the upper left of the current viewport
33-
# The offset from the origin is represented by x and y
30+
# The scroll origin is either the center of an element or the upper left of the viewport plus offsets.
31+
# If the origin is an element, and the element is not in the viewport, the bottom of the element will first
32+
# be scrolled to the bottom of the viewport.
3433
#
3534
# @example Scroll to element
3635
# el = driver.find_element(id: "some_id")
@@ -57,8 +56,8 @@ def default_scroll_duration
5756
# @option opts [Integer] delta_x Distance along X axis to scroll using the wheel. A negative value scrolls left.
5857
# @option opts [Integer] delta_y Distance along Y axis to scroll using the wheel. A negative value scrolls up.
5958
# @option opts [String, Element] origin The origin of the scroll, either the viewport or the center of an element.
60-
# @return [ActionBuilder] A self reference.
61-
# @raise [MoveTargetOutOfBoundsError] if the origin plus offset is located outside the viewport.
59+
# @return [Selenium::WebDriver::WheelActions] A self reference.
60+
# @raise [Error::MoveTargetOutOfBoundsError] If the origin with offset is outside the viewport.
6261
#
6362

6463
def scroll(**opts)

rb/spec/integration/selenium/webdriver/action_builder_spec.rb

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ def in_viewport?(element)
274274
it 'scrolls to element' do
275275
driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')
276276
iframe = driver.find_element(tag_name: 'iframe')
277+
277278
expect(in_viewport?(iframe)).to eq false
278279

279280
driver.action.scroll(origin: iframe).perform
@@ -283,8 +284,8 @@ def in_viewport?(element)
283284

284285
it 'scrolls from element by given amount' do
285286
driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')
286-
287287
iframe = driver.find_element(tag_name: 'iframe')
288+
288289
driver.action.scroll(delta_y: 200, origin: iframe).perform
289290

290291
driver.switch_to.frame(iframe)
@@ -294,11 +295,12 @@ def in_viewport?(element)
294295

295296
it 'scrolls from element by given amount with offset' do
296297
driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')
297-
298298
footer = driver.find_element(tag_name: 'footer')
299+
299300
driver.action.scroll(y: -50, delta_y: 200, origin: footer).perform
300301

301-
driver.switch_to.frame(driver.find_element(tag_name: 'iframe'))
302+
iframe = driver.find_element(tag_name: 'iframe')
303+
driver.switch_to.frame(iframe)
302304
checkbox = driver.find_element(name: 'scroll_checkbox')
303305
expect(in_viewport?(checkbox)).to eq true
304306
end
@@ -315,8 +317,9 @@ def in_viewport?(element)
315317
it 'scrolls by given amount' do
316318
driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')
317319
footer = driver.find_element(tag_name: 'footer')
320+
delta_y = footer.rect.y
318321

319-
driver.action.scroll(delta_y: footer.rect.y).perform
322+
driver.action.scroll(delta_y: delta_y).perform
320323

321324
expect(in_viewport?(footer)).to eq true
322325
end
@@ -333,7 +336,7 @@ def in_viewport?(element)
333336
end
334337

335338
it 'raises MoveTargetOutOfBoundsError when origin offset is out of viewport' do
336-
driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')
339+
driver.navigate.to url_for('scrolling_tests/frame_with_nested_scrolling_frame.html')
337340

338341
expect {
339342
driver.action.scroll(x: -10, y: -10, delta_y: 200).perform

0 commit comments

Comments
 (0)