Skip to content

Commit acebbbb

Browse files
committed
Update CDP Mode
1 parent 3c9e4c0 commit acebbbb

6 files changed

Lines changed: 63 additions & 7 deletions

File tree

examples/cdp_mode/ReadMe.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,9 @@ sb.cdp.assert_equal(first, second)
559559
sb.cdp.assert_not_equal(first, second)
560560
sb.cdp.assert_in(first, second)
561561
sb.cdp.assert_not_in(first, second)
562+
sb.cdp.js_scroll_into_view(selector)
562563
sb.cdp.scroll_into_view(selector)
563564
sb.cdp.scroll_to_y(y)
564-
sb.cdp.scroll_by_y(y)
565565
sb.cdp.scroll_to_top()
566566
sb.cdp.scroll_to_bottom()
567567
sb.cdp.scroll_up(amount=25)
@@ -730,6 +730,7 @@ element.flash(duration=0.5, color="EE4488")
730730
element.focus()
731731
element.gui_click(timeframe=0.25)
732732
element.highlight_overlay()
733+
element.is_in_viewport()
733734
element.mouse_click()
734735
element.mouse_drag(destination)
735736
element.mouse_move()

help_docs/cdp_mode_methods.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,8 @@ sb.cdp.assert_equal(first, second)
187187
sb.cdp.assert_not_equal(first, second)
188188
sb.cdp.assert_in(first, second)
189189
sb.cdp.assert_not_in(first, second)
190+
sb.cdp.js_scroll_into_view(selector)
190191
sb.cdp.scroll_into_view(selector)
191-
sb.cdp.scroll_to_y(y)
192192
sb.cdp.scroll_by_y(y)
193193
sb.cdp.scroll_to_top()
194194
sb.cdp.scroll_to_bottom()
@@ -358,6 +358,7 @@ element.flash(duration=0.5, color="EE4488")
358358
element.focus()
359359
element.gui_click(timeframe=0.25)
360360
element.highlight_overlay()
361+
element.is_in_viewport()
361362
element.mouse_click()
362363
element.mouse_drag(destination)
363364
element.mouse_move()

seleniumbase/core/browser_launcher.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,6 +942,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
942942
cdp.assert_not_equal = CDPM.assert_not_equal
943943
cdp.assert_in = CDPM.assert_in
944944
cdp.assert_not_in = CDPM.assert_not_in
945+
cdp.js_scroll_into_view = CDPM.js_scroll_into_view
945946
cdp.scroll_into_view = CDPM.scroll_into_view
946947
cdp.scroll_to_y = CDPM.scroll_to_y
947948
cdp.scroll_by_y = CDPM.scroll_by_y

seleniumbase/core/sb_cdp.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def __add_sync_methods(self, element):
6666
lambda *args, **kwargs: self.__gui_click(element, *args, **kwargs)
6767
)
6868
element.highlight_overlay = lambda: self.__highlight_overlay(element)
69+
element.is_in_viewport = lambda: self.__is_in_viewport(element)
6970
element.mouse_click = lambda: self.__mouse_click(element)
7071
element.click_with_offset = (
7172
lambda *args, **kwargs: self.__mouse_click_with_offset_async(
@@ -543,6 +544,11 @@ def __highlight_overlay(self, element):
543544
self.loop.run_until_complete(element.highlight_overlay_async())
544545
)
545546

547+
def __is_in_viewport(self, element):
548+
return (
549+
self.loop.run_until_complete(element.is_in_viewport_async())
550+
)
551+
546552
def __mouse_click(self, element):
547553
result = (
548554
self.loop.run_until_complete(element.mouse_click_async())
@@ -800,22 +806,34 @@ def click(self, selector, timeout=None, scroll=True):
800806
timeout = settings.SMALL_TIMEOUT
801807
self.__slow_mode_pause_if_set()
802808
element = self.find_element(selector, timeout=timeout)
803-
if scroll:
804-
element.scroll_into_view()
805809
tag_name = element.tag_name
810+
current_url = self.get_current_url()
811+
806812
if tag_name:
807813
tag_name = tag_name.lower().strip()
808814
if (
809815
tag_name in [
810816
"a", "button", "canvas", "div", "input", "li", "span", "label"
811817
]
812818
and "contains(" not in selector
819+
and "://google" not in current_url
820+
and "://www.google" not in current_url
813821
):
822+
if scroll:
823+
element.scroll_into_view()
814824
try:
815825
element.mouse_click() # Simulated click (NOT PyAutoGUI)
816826
except Exception:
817827
element.click() # Standard CDP click
818828
else:
829+
if scroll:
830+
if "contains(" in selector:
831+
element.scroll_into_view()
832+
else:
833+
try:
834+
self.js_scroll_into_view(selector)
835+
except Exception:
836+
element.scroll_into_view()
819837
element.click() # Standard CDP click
820838
self.__slow_mode_pause_if_set()
821839
self.loop.run_until_complete(self.page.wait(0.2))
@@ -3109,6 +3127,17 @@ def assert_not_in(self, first, second):
31093127
if first in second:
31103128
raise AssertionError("%s is in %s" % (first, second))
31113129

3130+
def js_scroll_into_view(self, selector):
3131+
css_selector = self.__convert_to_css_if_xpath(selector)
3132+
css_selector = re.escape(css_selector) # Add "\\" to special chars
3133+
css_selector = js_utils.escape_quotes_if_needed(css_selector)
3134+
js_code = (
3135+
"document.querySelector('%s')?.scrollIntoView();"
3136+
% css_selector
3137+
)
3138+
with suppress(Exception):
3139+
self.loop.run_until_complete(self.page.evaluate(js_code))
3140+
31123141
def scroll_into_view(self, selector):
31133142
self.find_element(selector).scroll_into_view()
31143143
self.loop.run_until_complete(self.page.wait(0.1))

seleniumbase/undetected/cdp_driver/element.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,8 @@ async def get_position_async(self, abs=False) -> Position:
467467
raise Exception("Could not find position for %s " % self)
468468
pos = Position(quads[0])
469469
if abs:
470-
scroll_y = (await self.tab.evaluate("window.scrollY")).value
471-
scroll_x = (await self.tab.evaluate("window.scrollX")).value
470+
scroll_y = (await self.tab.evaluate("window.scrollY"))
471+
scroll_x = (await self.tab.evaluate("window.scrollX"))
472472
abs_x = pos.left + scroll_x + (pos.width / 2)
473473
abs_y = pos.top + scroll_y + (pos.height / 2)
474474
pos.abs_x = abs_x
@@ -717,6 +717,31 @@ async def mouse_drag_async(
717717
)
718718
)
719719

720+
async def is_in_viewport_async(self):
721+
try:
722+
layout = await self.tab.send(
723+
cdp.page.get_layout_metrics()
724+
)
725+
viewport = layout[4]
726+
v_left = viewport.page_x
727+
v_top = viewport.page_y
728+
v_right = v_left + viewport.client_width
729+
v_bottom = v_top + viewport.client_height
730+
box = await self.tab.send(
731+
cdp.dom.get_box_model(backend_node_id=self.backend_node_id)
732+
)
733+
quad = box.content
734+
e_left = min(quad[0], quad[2], quad[4], quad[6])
735+
e_top = min(quad[1], quad[3], quad[5], quad[7])
736+
e_right = max(quad[0], quad[2], quad[4], quad[6])
737+
e_bottom = max(quad[1], quad[3], quad[5], quad[7])
738+
return (
739+
e_left >= v_left and e_right <= v_right
740+
and e_top >= v_top and e_bottom <= v_bottom
741+
)
742+
except Exception:
743+
return False
744+
720745
async def scroll_into_view_async(self):
721746
"""Scrolls element into view."""
722747
try:

seleniumbase/undetected/cdp_driver/tab.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ async def find(
226226
except (Exception, TypeError):
227227
pass
228228
while not item:
229-
await self
230229
item = await self.find_element_by_text(
231230
text, best_match, return_enclosing_element
232231
)

0 commit comments

Comments
 (0)