Skip to content

CDP Mode - Patch 35 #3545

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/cdp_mode/ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ element.clear_input()
element.click()
element.flash(duration=0.5, color="EE4488")
element.focus()
element.gui_click(timeframe=0.25)
element.highlight_overlay()
element.mouse_click()
element.mouse_drag(destination)
Expand Down
4 changes: 2 additions & 2 deletions examples/cdp_mode/raw_cf.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"""Using CDP Mode with PyAutoGUI to bypass CAPTCHAs."""
from seleniumbase import SB

with SB(uc=True, test=True, locale_code="en") as sb:
with SB(uc=True, test=True, locale_code="en", incognito=True) as sb:
url = "https://www.cloudflare.com/login"
sb.activate_cdp_mode(url)
sb.sleep(3)
sb.uc_gui_handle_captcha() # PyAutoGUI press Tab and Spacebar
sb.sleep(2)

with SB(uc=True, test=True, locale_code="en") as sb:
with SB(uc=True, test=True, locale_code="en", incognito=True) as sb:
url = "https://www.cloudflare.com/login"
sb.activate_cdp_mode(url)
sb.sleep(2)
Expand Down
2 changes: 2 additions & 0 deletions examples/cdp_mode/raw_elal.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
print("*** Lowest Price: ***")
lowest_price = sorted(prices)[0]
print(lowest_price)
sb.cdp.scroll_down(12)
sb.sleep(1)
sb.cdp.find_element_by_text(lowest_price).click()
sb.sleep(1)
search_cell = 'button[aria-label*="Search.cell.buttonTitle"]'
Expand Down
3 changes: 3 additions & 0 deletions examples/test_usefixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
@pytest.mark.usefixtures("sb")
class Test_UseFixtures:
def test_usefixtures_on_class(self):
if not hasattr(self, "sb"):
print("This test is for pytest only!")
return
sb = self.sb
sb.open("https://seleniumbase.io/realworld/login")
sb.type("#username", "demo_user")
Expand Down
2 changes: 1 addition & 1 deletion mkdocs_build/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pathspec==0.12.1
Babel==2.17.0
paginate==0.5.7
mkdocs==1.6.1
mkdocs-material==9.6.4
mkdocs-material==9.6.5
mkdocs-exclude-search==0.6.6
mkdocs-simple-hooks==0.1.5
mkdocs-material-extensions==1.3.1
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ filelock~=3.16.1;python_version<"3.9"
filelock>=3.17.0;python_version>="3.9"
fasteners>=0.19
mycdp>=1.1.0
pynose>=1.5.3
pynose>=1.5.4
platformdirs>=4.3.6
typing-extensions>=4.12.2
sbvirtualdisplay>=1.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.34.16"
__version__ = "4.34.17"
40 changes: 37 additions & 3 deletions seleniumbase/core/sb_cdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ def __add_sync_methods(self, element):
element, *args, **kwargs
)
element.focus = lambda: self.__focus(element)
element.gui_click = (
lambda *args, **kwargs: self.__gui_click(element, *args, **kwargs)
)
element.highlight_overlay = lambda: self.__highlight_overlay(element)
element.mouse_click = lambda: self.__mouse_click(element)
element.mouse_drag = (
Expand Down Expand Up @@ -426,6 +429,39 @@ def __focus(self, element):
self.loop.run_until_complete(element.focus_async())
)

def __gui_click(self, element, timeframe=None):
element.scroll_into_view()
self.__add_light_pause()
position = element.get_position()
x = position.x
y = position.y
e_width = position.width
e_height = position.height
# Relative to window
element_rect = {"height": e_height, "width": e_width, "x": x, "y": y}
window_rect = self.get_window_rect()
w_bottom_y = window_rect["y"] + window_rect["height"]
viewport_height = window_rect["innerHeight"]
x = window_rect["x"] + element_rect["x"]
y = w_bottom_y - viewport_height + element_rect["y"]
y_scroll_offset = window_rect["pageYOffset"]
y = y - y_scroll_offset
x = x + window_rect["scrollX"]
y = y + window_rect["scrollY"]
# Relative to screen
element_rect = {"height": e_height, "width": e_width, "x": x, "y": y}
e_width = element_rect["width"]
e_height = element_rect["height"]
e_x = element_rect["x"]
e_y = element_rect["y"]
x, y = ((e_x + e_width / 2.0) + 0.5), ((e_y + e_height / 2.0) + 0.5)
if not timeframe or not isinstance(timeframe, (int, float)):
timeframe = 0.25
if timeframe > 3:
timeframe = 3
self.gui_click_x_y(x, y, timeframe=timeframe)
return self.loop.run_until_complete(self.page.wait())

def __highlight_overlay(self, element):
return (
self.loop.run_until_complete(element.highlight_overlay_async())
Expand Down Expand Up @@ -461,9 +497,7 @@ def __press_keys(self, element, text):
element.send_keys("\r\n")
time.sleep(0.044)
self.__slow_mode_pause_if_set()
return (
self.loop.run_until_complete(self.page.wait())
)
return self.loop.run_until_complete(self.page.wait())

def __query_selector(self, element, selector):
selector = self.__convert_to_css_if_xpath(selector)
Expand Down
27 changes: 12 additions & 15 deletions seleniumbase/plugins/base_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ def configure(self, options, conf):
self.duration = float(0)
self.page_results_list = []
self.test_count = 0
self.import_error = False
log_path = constants.Logs.LATEST + "/"
archive_logs = options.archive_logs
log_helper.log_folder_setup(log_path, archive_logs)
Expand Down Expand Up @@ -238,6 +237,7 @@ def beforeTest(self, test):
)
else:
variables = {}
test.test.test_id = test.id()
test.test.is_nosetest = True
test.test.environment = self.options.environment
test.test.env = self.options.environment # Add a shortened version
Expand All @@ -263,17 +263,16 @@ def finalize(self, result):
)
log_helper.clear_empty_logs()
if self.report_on:
if not self.import_error:
report_helper.add_bad_page_log_file(self.page_results_list)
report_log_path = report_helper.archive_new_report_logs()
report_helper.build_report(
report_log_path,
self.page_results_list,
self.successes,
self.failures,
self.options.browser,
self.show_report,
)
report_helper.add_bad_page_log_file(self.page_results_list)
report_log_path = report_helper.archive_new_report_logs()
report_helper.build_report(
report_log_path,
self.page_results_list,
self.successes,
self.failures,
self.options.browser,
self.show_report,
)

def addSuccess(self, test, capt):
if self.report_on:
Expand All @@ -293,9 +292,6 @@ def add_fails_or_errors(self, test, err):
"%.2fs" % (float(time.time()) - float(self.start_time))
)
if test.id() == "nose.failure.Failure.runTest":
print(">>> ERROR: Could not locate tests to run!")
print(">>> The Test Report WILL NOT be generated!")
self.import_error = True
return
self.failures.append(test.id())
self.page_results_list.append(
Expand All @@ -314,6 +310,7 @@ def add_fails_or_errors(self, test, err):
test._log_fail_data()
sb_config._excinfo_tb = err
log_path = None
source = None
if hasattr(sb_config, "_test_logpath"):
log_path = sb_config._test_logpath
if hasattr(sb_config, "_last_page_source"):
Expand Down
1 change: 1 addition & 0 deletions seleniumbase/plugins/selenium_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,7 @@ def beforeTest(self, test):
test.test.dashboard = False
test.test._multithreaded = False
test.test._reuse_session = False
sb_config.recorder_mode = test.test.recorder_mode
sb_config.no_screenshot = test.test.no_screenshot_after_test
if test.test.servername != "localhost":
# Using Selenium Grid
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@
'filelock>=3.17.0;python_version>="3.9"',
'fasteners>=0.19',
"mycdp>=1.1.0",
"pynose>=1.5.3",
"pynose>=1.5.4",
'platformdirs>=4.3.6',
'typing-extensions>=4.12.2',
"sbvirtualdisplay>=1.4.0",
Expand Down