Skip to content

Commit

Permalink
Merge pull request #3250 from seleniumbase/cdp-mode-patch-8
Browse files Browse the repository at this point in the history
CDP Mode - Patch 8
  • Loading branch information
mdmintz authored Nov 8, 2024
2 parents 7fadabd + 4f86de9 commit 44ba6a0
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 13 deletions.
7 changes: 7 additions & 0 deletions examples/cdp_mode/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,19 @@ sb.cdp.get_gui_element_center(selector)
sb.cdp.get_document()
sb.cdp.get_flattened_document()
sb.cdp.get_element_attributes(selector)
sb.cdp.get_element_attribute(selector, attribute)
sb.cdp.get_element_html(selector)
sb.cdp.set_locale(locale)
sb.cdp.set_attributes(selector, attribute, value)
sb.cdp.gui_click_x_y(x, y)
sb.cdp.gui_click_element(selector)
sb.cdp.internalize_links()
sb.cdp.is_checked(selector)
sb.cdp.is_selected(selector)
sb.cdp.check_if_unchecked(selector)
sb.cdp.select_if_unselected(selector)
sb.cdp.uncheck_if_checked(selector)
sb.cdp.unselect_if_selected(selector)
sb.cdp.is_element_present(selector)
sb.cdp.is_element_visible(selector)
sb.cdp.assert_element(selector)
Expand Down
8 changes: 8 additions & 0 deletions examples/cdp_mode/raw_planetmc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from seleniumbase import SB

with SB(uc=True, test=True, locale_code="en") as sb:
url = "www.planetminecraft.com/account/sign_in/"
sb.activate_cdp_mode(url)
sb.sleep(1)
sb.cdp.gui_click_element("#turnstile-widget")
sb.sleep(2)
8 changes: 8 additions & 0 deletions examples/cdp_mode/raw_wsform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from seleniumbase import SB

with SB(uc=True, test=True, locale_code="en") as sb:
url = "https://wsform.com/demo/"
sb.activate_cdp_mode(url)
sb.scroll_into_view("div.grid")
sb.uc_gui_click_captcha()
sb.sleep(1)
2 changes: 1 addition & 1 deletion mkdocs_build/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# mkdocs dependencies for generating the seleniumbase.io website
# Minimum Python version: 3.9 (for generating docs only)

regex>=2024.9.11
regex>=2024.11.6
pymdown-extensions>=10.12
pipdeptree>=2.23.4
python-dateutil>=2.8.2
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pyyaml>=6.0.2
pygments>=2.18.0
pyreadline3>=3.5.3;platform_system=="Windows"
tabcompleter>=1.4.0
pdbp>=1.6.0
pdbp>=1.6.1
idna==3.10
chardet==5.2.0
charset-normalizer==3.4.0
Expand Down
2 changes: 1 addition & 1 deletion seleniumbase/__version__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# seleniumbase package
__version__ = "4.32.7"
__version__ = "4.32.8"
6 changes: 6 additions & 0 deletions seleniumbase/core/browser_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ def uc_open_with_cdp_mode(driver, url=None):
cdp.internalize_links = CDPM.internalize_links
cdp.get_window = CDPM.get_window
cdp.get_element_attributes = CDPM.get_element_attributes
cdp.get_element_attribute = CDPM.get_element_attribute
cdp.get_element_html = CDPM.get_element_html
cdp.get_element_rect = CDPM.get_element_rect
cdp.get_element_size = CDPM.get_element_size
Expand All @@ -651,6 +652,11 @@ def uc_open_with_cdp_mode(driver, url=None):
cdp.focus = CDPM.focus
cdp.highlight_overlay = CDPM.highlight_overlay
cdp.get_window_position = CDPM.get_window_position
cdp.check_if_unchecked = CDPM.check_if_unchecked
cdp.uncheck_if_checked = CDPM.uncheck_if_checked
cdp.select_if_unselected = CDPM.select_if_unselected
cdp.unselect_if_selected = CDPM.unselect_if_selected
cdp.is_checked = CDPM.is_checked
cdp.is_element_present = CDPM.is_element_present
cdp.is_element_visible = CDPM.is_element_visible
cdp.assert_element_present = CDPM.assert_element_present
Expand Down
35 changes: 31 additions & 4 deletions seleniumbase/core/sb_cdp.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Add CDP methods to extend the driver"""
import fasteners
import math
import os
import re
import sys
Expand Down Expand Up @@ -771,10 +770,12 @@ def get_gui_element_rect(self, selector):
window_rect = self.get_window_rect()
w_bottom_y = window_rect["y"] + window_rect["height"]
viewport_height = window_rect["innerHeight"]
x = math.ceil(window_rect["x"] + element_rect["x"])
y = math.ceil(w_bottom_y - viewport_height + element_rect["y"])
x = window_rect["x"] + element_rect["x"]
y = w_bottom_y - viewport_height + element_rect["y"]
y_scroll_offset = window_rect["pageYOffset"]
y = int(y - y_scroll_offset)
y = y - y_scroll_offset
x = x + window_rect["scrollX"]
y = y + window_rect["scrollY"]
return ({"height": e_height, "width": e_width, "x": x, "y": y})

def get_gui_element_center(self, selector):
Expand Down Expand Up @@ -804,6 +805,10 @@ def get_element_attributes(self, selector):
)
)

def get_element_attribute(self, selector, attribute):
attributes = self.get_element_attributes(selector)
return attributes[attribute]

def get_element_html(self, selector):
selector = self.__convert_to_css_if_xpath(selector)
return self.loop.run_until_complete(
Expand Down Expand Up @@ -1033,6 +1038,28 @@ def internalize_links(self):
This prevents those links from opening in a new tab."""
self.set_attributes('[target="_blank"]', "target", "_self")

def is_checked(self, selector):
"""Return True if checkbox (or radio button) is checked."""
self.find_element(selector, timeout=settings.SMALL_TIMEOUT)
return self.get_element_attribute(selector, "checked")

def is_selected(self, selector):
return self.is_checked(selector)

def check_if_unchecked(self, selector):
if not self.is_checked(selector):
self.click(selector)

def select_if_unselected(self, selector):
self.check_if_unchecked(selector)

def uncheck_if_checked(self, selector):
if self.is_checked(selector):
self.click(selector)

def unselect_if_selected(self, selector):
self.uncheck_if_checked(selector)

def is_element_present(self, selector):
try:
self.select(selector, timeout=0.01)
Expand Down
19 changes: 14 additions & 5 deletions seleniumbase/fixtures/base_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,8 @@ def get_attribute(
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
timeout = self.__get_new_timeout(timeout)
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
return self.cdp.get_element_attribute(selector)
self.wait_for_ready_state_complete()
time.sleep(0.01)
if self.__is_shadow_selector(selector):
Expand Down Expand Up @@ -2460,16 +2462,14 @@ def is_checked(self, selector, by="css selector", timeout=None):
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
timeout = self.__get_new_timeout(timeout)
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
return self.cdp.is_checked(selector)
kind = self.get_attribute(selector, "type", by=by, timeout=timeout)
if kind != "checkbox" and kind != "radio":
raise Exception("Expecting a checkbox or a radio button element!")
is_checked = self.get_attribute(
return self.get_attribute(
selector, "checked", by=by, timeout=timeout, hard_fail=False
)
if is_checked:
return True
else: # (NoneType)
return False

def is_selected(self, selector, by="css selector", timeout=None):
"""Same as is_checked()"""
Expand All @@ -2479,6 +2479,9 @@ def check_if_unchecked(self, selector, by="css selector"):
"""If a checkbox or radio button is not checked, will check it."""
self.__check_scope()
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
self.cdp.check_if_unchecked(selector)
return
if not self.is_checked(selector, by=by):
if self.is_element_visible(selector, by=by):
self.click(selector, by=by)
Expand Down Expand Up @@ -2515,6 +2518,9 @@ def uncheck_if_checked(self, selector, by="css selector"):
"""If a checkbox is checked, will uncheck it."""
self.__check_scope()
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
self.cdp.uncheck_if_checked(selector)
return
if self.is_checked(selector, by=by):
if self.is_element_visible(selector, by=by):
self.click(selector, by=by)
Expand Down Expand Up @@ -6087,6 +6093,9 @@ def scroll_to(self, selector, by="css selector", timeout=None):
timeout = settings.SMALL_TIMEOUT
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
timeout = self.__get_new_timeout(timeout)
if self.__is_cdp_swap_needed():
self.cdp.scroll_into_view(selector)
return
if self.demo_mode or self.slow_mode:
self.slow_scroll_to(selector, by=by, timeout=timeout)
return
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
'pygments>=2.18.0',
'pyreadline3>=3.5.3;platform_system=="Windows"',
"tabcompleter>=1.4.0",
"pdbp>=1.6.0",
"pdbp>=1.6.1",
"idna==3.10",
'chardet==5.2.0',
'charset-normalizer==3.4.0',
Expand Down

0 comments on commit 44ba6a0

Please sign in to comment.