Skip to content

Commit 33370bb

Browse files
committed
Add a scroll option to multiple clicking methods
1 parent fbd60e1 commit 33370bb

File tree

5 files changed

+72
-48
lines changed

5 files changed

+72
-48
lines changed

examples/cdp_mode/ReadMe.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -403,12 +403,12 @@ sb.cdp.select(selector, timeout=None)
403403
sb.cdp.select_all(selector, timeout=None)
404404
sb.cdp.find_elements(selector, timeout=None)
405405
sb.cdp.find_visible_elements(selector, timeout=None)
406-
sb.cdp.click(selector, timeout=None)
407-
sb.cdp.click_if_visible(selector, timeout=0)
408-
sb.cdp.click_visible_elements(selector, limit=0)
409-
sb.cdp.click_nth_element(selector, number)
410-
sb.cdp.click_nth_visible_element(selector, number)
411-
sb.cdp.click_with_offset(selector, x, y, center=False)
406+
sb.cdp.click(selector, timeout=None, scroll=True)
407+
sb.cdp.click_if_visible(selector, timeout=0, scroll=True)
408+
sb.cdp.click_visible_elements(selector, limit=0, scroll=True)
409+
sb.cdp.click_nth_element(selector, number, scroll=True)
410+
sb.cdp.click_nth_visible_element(selector, number, scroll=True)
411+
sb.cdp.click_with_offset(selector, x, y, center=False, scroll=True)
412412
sb.cdp.click_link(link_text)
413413
sb.cdp.go_back()
414414
sb.cdp.go_forward()
@@ -428,7 +428,7 @@ sb.cdp.bring_to_front()
428428
sb.cdp.get_active_element()
429429
sb.cdp.get_active_element_css()
430430
sb.cdp.click_active_element()
431-
sb.cdp.mouse_click(selector, timeout=None)
431+
sb.cdp.mouse_click(selector, timeout=None, scroll=True)
432432
sb.cdp.nested_click(parent_selector, selector)
433433
sb.cdp.get_nested_element(parent_selector, selector)
434434
sb.cdp.select_option_by_text(dropdown_selector, option)

help_docs/cdp_mode_methods.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ sb.cdp.select(selector, timeout=None)
2929
sb.cdp.select_all(selector, timeout=None)
3030
sb.cdp.find_elements(selector, timeout=None)
3131
sb.cdp.find_visible_elements(selector, timeout=None)
32-
sb.cdp.click(selector, timeout=None)
33-
sb.cdp.click_if_visible(selector)
34-
sb.cdp.click_visible_elements(selector, limit=0)
35-
sb.cdp.click_nth_element(selector, number)
36-
sb.cdp.click_nth_visible_element(selector, number)
37-
sb.cdp.click_with_offset(selector, x, y, center=False)
32+
sb.cdp.click(selector, timeout=None, scroll=True)
33+
sb.cdp.click_if_visible(selector, timeout=0, scroll=True)
34+
sb.cdp.click_visible_elements(selector, limit=0, scroll=True)
35+
sb.cdp.click_nth_element(selector, number, scroll=True)
36+
sb.cdp.click_nth_visible_element(selector, number, scroll=True)
37+
sb.cdp.click_with_offset(selector, x, y, center=False, scroll=True)
3838
sb.cdp.click_link(link_text)
3939
sb.cdp.go_back()
4040
sb.cdp.go_forward()
@@ -54,7 +54,7 @@ sb.cdp.bring_to_front()
5454
sb.cdp.get_active_element()
5555
sb.cdp.get_active_element_css()
5656
sb.cdp.click_active_element()
57-
sb.cdp.mouse_click(selector, timeout=None)
57+
sb.cdp.mouse_click(selector, timeout=None, scroll=True)
5858
sb.cdp.nested_click(parent_selector, selector)
5959
sb.cdp.get_nested_element(parent_selector, selector)
6060
sb.cdp.select_option_by_text(dropdown_selector, option)

help_docs/method_summary.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,16 @@ self.find_elements(selector, by="css selector", limit=0)
9090
# Duplicates:
9191
# self.select_all(selector, by="css selector", limit=0)
9292
self.find_visible_elements(selector, by="css selector", limit=0)
93-
self.click_visible_elements(selector, by="css selector", limit=0, timeout=None)
94-
self.click_nth_visible_element(selector, number, by="css selector", timeout=None)
95-
self.click_if_visible(selector, by="css selector", timeout=0)
93+
self.click_visible_elements(
94+
selector, by="css selector", limit=0, timeout=None, scroll=True)
95+
self.click_nth_visible_element(
96+
selector, number, by="css selector", timeout=None, scroll=True)
97+
self.click_if_visible(selector, by="css selector", timeout=0, scroll=True)
9698
self.click_active_element()
9799
self.click_with_offset(
98-
selector, x, y, by="css selector", mark=None, timeout=None, center=None)
100+
selector, x, y, by="css selector", mark=None, timeout=None, center=None, scroll=True)
99101
self.double_click_with_offset(
100-
selector, x, y, by="css selector", mark=None, timeout=None, center=None)
102+
selector, x, y, by="css selector", mark=None, timeout=None, center=None, scroll=True)
101103
self.is_checked(selector, by="css selector", timeout=None)
102104
# Duplicates:
103105
# self.is_selected(selector, by="css selector", timeout=None)

seleniumbase/core/sb_cdp.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ def find_visible_elements(self, selector, timeout=None):
429429
visible_elements.append(element)
430430
return visible_elements
431431

432-
def click_nth_element(self, selector, number):
432+
def click_nth_element(self, selector, number, scroll=True):
433433
elements = self.select_all(selector)
434434
if len(elements) < number:
435435
raise Exception(
@@ -440,10 +440,11 @@ def click_nth_element(self, selector, number):
440440
if number < 0:
441441
number = 0
442442
element = elements[number]
443-
element.scroll_into_view()
443+
if scroll:
444+
element.scroll_into_view()
444445
element.click()
445446

446-
def click_nth_visible_element(self, selector, number):
447+
def click_nth_visible_element(self, selector, number, scroll=True):
447448
"""Finds all matching page elements and clicks the nth visible one.
448449
Example: self.click_nth_visible_element('[type="checkbox"]', 5)
449450
(Clicks the 5th visible checkbox on the page.)"""
@@ -457,7 +458,8 @@ def click_nth_visible_element(self, selector, number):
457458
if number < 0:
458459
number = 0
459460
element = elements[number]
460-
element.scroll_into_view()
461+
if scroll:
462+
element.scroll_into_view()
461463
element.click()
462464

463465
def click_link(self, link_text):
@@ -793,12 +795,13 @@ def get_active_element_css(self):
793795
js_code = js_code.replace("return getBestSelector", "getBestSelector")
794796
return self.loop.run_until_complete(self.page.evaluate(js_code))
795797

796-
def click(self, selector, timeout=None):
798+
def click(self, selector, timeout=None, scroll=True):
797799
if not timeout:
798800
timeout = settings.SMALL_TIMEOUT
799801
self.__slow_mode_pause_if_set()
800802
element = self.find_element(selector, timeout=timeout)
801-
element.scroll_into_view()
803+
if scroll:
804+
element.scroll_into_view()
802805
tag_name = element.tag_name
803806
if tag_name:
804807
tag_name = tag_name.lower().strip()
@@ -824,10 +827,10 @@ def click_active_element(self):
824827
self.__slow_mode_pause_if_set()
825828
self.loop.run_until_complete(self.page.wait(0.2))
826829

827-
def click_if_visible(self, selector, timeout=0):
830+
def click_if_visible(self, selector, timeout=0, scroll=True):
828831
if self.is_element_visible(selector):
829832
with suppress(Exception):
830-
self.click(selector, timeout=1)
833+
self.click(selector, timeout=1, scroll=scroll)
831834
elif timeout == 0:
832835
return
833836
else:
@@ -836,7 +839,7 @@ def click_if_visible(self, selector, timeout=0):
836839
if self.is_element_visible(selector):
837840
self.click(selector, timeout=1)
838841

839-
def click_visible_elements(self, selector, limit=0):
842+
def click_visible_elements(self, selector, limit=0, scroll=True):
840843
"""Finds all matching page elements and clicks visible ones in order.
841844
If a click reloads or opens a new page, the clicking will stop.
842845
If no matching elements appear, an Exception will be raised.
@@ -859,7 +862,8 @@ def click_visible_elements(self, selector, limit=0):
859862
except Exception:
860863
continue
861864
if (width != 0 or height != 0):
862-
element.scroll_into_view()
865+
if scroll:
866+
element.scroll_into_view()
863867
element.click()
864868
click_count += 1
865869
time.sleep(0.044)
@@ -868,13 +872,14 @@ def click_visible_elements(self, selector, limit=0):
868872
except Exception:
869873
break
870874

871-
def mouse_click(self, selector, timeout=None):
875+
def mouse_click(self, selector, timeout=None, scroll=True):
872876
"""(Attempt simulating a mouse click)"""
873877
if not timeout:
874878
timeout = settings.SMALL_TIMEOUT
875879
self.__slow_mode_pause_if_set()
876880
element = self.find_element(selector, timeout=timeout)
877-
element.scroll_into_view()
881+
if scroll:
882+
element.scroll_into_view()
878883
element.mouse_click()
879884
self.__slow_mode_pause_if_set()
880885
self.loop.run_until_complete(self.page.wait(0.2))
@@ -1970,9 +1975,10 @@ def gui_click_with_offset(
19701975
py = element_rect["y"]
19711976
self.gui_click_x_y(px + x, py + y, timeframe=timeframe)
19721977

1973-
def click_with_offset(self, selector, x, y, center=False):
1978+
def click_with_offset(self, selector, x, y, center=False, scroll=True):
19741979
element = self.find_element(selector)
1975-
element.scroll_into_view()
1980+
if scroll:
1981+
element.scroll_into_view()
19761982
if "--debug" in sys.argv:
19771983
displayed_selector = "`%s`" % selector
19781984
if '"' not in selector:

seleniumbase/fixtures/base_case.py

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ def click(
411411
original_by = by
412412
selector, by = self.__recalculate_selector(selector, by)
413413
if self.__is_cdp_swap_needed():
414-
self.cdp.click(selector, timeout=timeout)
414+
self.cdp.click(selector, timeout=timeout, scroll=scroll)
415415
return
416416
if delay and (type(delay) in [int, float]) and delay > 0:
417417
time.sleep(delay)
@@ -2254,7 +2254,7 @@ def find_visible_elements(self, selector, by="css selector", limit=0):
22542254
)
22552255

22562256
def click_visible_elements(
2257-
self, selector, by="css selector", limit=0, timeout=None
2257+
self, selector, by="css selector", limit=0, timeout=None, scroll=True
22582258
):
22592259
"""Finds all matching page elements and clicks visible ones in order.
22602260
If a click reloads or opens a new page, the clicking will stop.
@@ -2270,7 +2270,7 @@ def click_visible_elements(
22702270
timeout = self.__get_new_timeout(timeout)
22712271
selector, by = self.__recalculate_selector(selector, by)
22722272
if self.__is_cdp_swap_needed():
2273-
self.cdp.click_visible_elements(selector, limit)
2273+
self.cdp.click_visible_elements(selector, limit, scroll=scroll)
22742274
return
22752275
self.wait_for_ready_state_complete()
22762276
if self.__needs_minimum_wait():
@@ -2297,7 +2297,8 @@ def click_visible_elements(
22972297
return
22982298
try:
22992299
if element.is_displayed():
2300-
self.__scroll_to_element(element)
2300+
if scroll:
2301+
self.__scroll_to_element(element)
23012302
if self.browser == "safari":
23022303
self.execute_script("arguments[0].click();", element)
23032304
else:
@@ -2311,7 +2312,8 @@ def click_visible_elements(
23112312
time.sleep(0.12)
23122313
try:
23132314
if element.is_displayed():
2314-
self.__scroll_to_element(element)
2315+
if scroll:
2316+
self.__scroll_to_element(element)
23152317
if self.browser == "safari":
23162318
self.execute_script(
23172319
"arguments[0].click();", element
@@ -2348,7 +2350,7 @@ def click_visible_elements(
23482350
self.__switch_to_newest_window_if_not_blank()
23492351

23502352
def click_nth_visible_element(
2351-
self, selector, number, by="css selector", timeout=None
2353+
self, selector, number, by="css selector", timeout=None, scroll=True
23522354
):
23532355
"""Finds all matching page elements and clicks the nth visible one.
23542356
Example: self.click_nth_visible_element('[type="checkbox"]', 5)
@@ -2360,7 +2362,7 @@ def click_nth_visible_element(
23602362
timeout = self.__get_new_timeout(timeout)
23612363
selector, by = self.__recalculate_selector(selector, by)
23622364
if self.__is_cdp_swap_needed():
2363-
self.cdp.click_nth_visible_element(selector, number)
2365+
self.cdp.click_nth_visible_element(selector, number, scroll=scroll)
23642366
return
23652367
self.wait_for_ready_state_complete()
23662368
self.wait_for_element_present(selector, by=by, timeout=timeout)
@@ -2379,7 +2381,8 @@ def click_nth_visible_element(
23792381
pre_action_url = self.driver.current_url
23802382
pre_window_count = len(self.driver.window_handles)
23812383
try:
2382-
self.__scroll_to_element(element)
2384+
if scroll:
2385+
self.__scroll_to_element(element)
23832386
self.__element_click(element)
23842387
except (Stale_Exception, ENI_Exception, ECI_Exception):
23852388
time.sleep(0.12)
@@ -2409,26 +2412,28 @@ def click_nth_visible_element(
24092412
):
24102413
self.__switch_to_newest_window_if_not_blank()
24112414

2412-
def click_if_visible(self, selector, by="css selector", timeout=0):
2415+
def click_if_visible(
2416+
self, selector, by="css selector", timeout=0, scroll=True
2417+
):
24132418
"""If the page selector exists and is visible, clicks on the element.
24142419
This method only clicks on the first matching element found.
24152420
Use click_visible_elements() to click all matching elements.
24162421
If a "timeout" is provided, waits that long for the element
24172422
to appear before giving up and returning without a click()."""
24182423
if self.__is_cdp_swap_needed():
2419-
self.cdp.click_if_visible(selector, timeout=timeout)
2424+
self.cdp.click_if_visible(selector, timeout=timeout, scroll=scroll)
24202425
return
24212426
self.wait_for_ready_state_complete()
24222427
if self.is_element_visible(selector, by=by):
2423-
self.click(selector, by=by)
2428+
self.click(selector, by=by, scroll=scroll)
24242429
elif timeout > 0:
24252430
with suppress(Exception):
24262431
self.wait_for_element_visible(
24272432
selector, by=by, timeout=timeout
24282433
)
24292434
self.sleep(0.2)
24302435
if self.is_element_visible(selector, by=by):
2431-
self.click(selector, by=by)
2436+
self.click(selector, by=by, scroll=scroll)
24322437

24332438
def click_active_element(self):
24342439
if self.__is_cdp_swap_needed():
@@ -2484,6 +2489,7 @@ def click_with_offset(
24842489
mark=None,
24852490
timeout=None,
24862491
center=None,
2492+
scroll=True,
24872493
):
24882494
"""Click an element at an {X,Y}-offset location.
24892495
{0,0} is the top-left corner of the element.
@@ -2500,6 +2506,7 @@ def click_with_offset(
25002506
mark=mark,
25012507
timeout=timeout,
25022508
center=center,
2509+
scroll=scroll,
25032510
)
25042511

25052512
def double_click_with_offset(
@@ -2511,6 +2518,7 @@ def double_click_with_offset(
25112518
mark=None,
25122519
timeout=None,
25132520
center=None,
2521+
scroll=True,
25142522
):
25152523
"""Double click an element at an {X,Y}-offset location.
25162524
{0,0} is the top-left corner of the element.
@@ -2527,6 +2535,7 @@ def double_click_with_offset(
25272535
mark=mark,
25282536
timeout=timeout,
25292537
center=center,
2538+
scroll=scroll,
25302539
)
25312540

25322541
def is_checked(self, selector, by="css selector", timeout=None):
@@ -14043,9 +14052,12 @@ def __click_with_offset(
1404314052
mark=None,
1404414053
timeout=None,
1404514054
center=None,
14055+
scroll=True,
1404614056
):
1404714057
if self.__is_cdp_swap_needed():
14048-
self.cdp.click_with_offset(selector, x, y, center=center)
14058+
self.cdp.click_with_offset(
14059+
selector, x, y, center=center, scroll=scroll
14060+
)
1404914061
return
1405014062
self.wait_for_ready_state_complete()
1405114063
if self.__needs_minimum_wait():
@@ -14061,9 +14073,13 @@ def __click_with_offset(
1406114073
if self.demo_mode:
1406214074
self.__highlight(selector, by=by, loops=1)
1406314075
elif self.slow_mode:
14064-
self.__slow_scroll_to_element(element)
14076+
if scroll:
14077+
self.__slow_scroll_to_element(element)
14078+
else:
14079+
self.sleep(0.2)
1406514080
else:
14066-
self.__scroll_to_element(element, selector, by)
14081+
if scroll:
14082+
self.__scroll_to_element(element, selector, by)
1406714083
self.wait_for_ready_state_complete()
1406814084
if self.__needs_minimum_wait():
1406914085
time.sleep(0.03)

0 commit comments

Comments
 (0)