Skip to content

Commit adf244c

Browse files
committed
Add updates for CDP Mode
1 parent 48b5529 commit adf244c

File tree

5 files changed

+101
-13
lines changed

5 files changed

+101
-13
lines changed

seleniumbase/core/browser_launcher.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,21 @@ def extend_driver(
159159
# Extend the driver with new methods
160160
driver.default_find_element = driver.find_element
161161
driver.default_find_elements = driver.find_elements
162+
driver.default_add_cookie = driver.add_cookie
163+
driver.default_get_cookie = driver.get_cookie
164+
driver.default_delete_cookie = driver.delete_cookie
165+
driver.default_back = driver.back
166+
driver.default_forward = driver.forward
167+
driver.default_refresh = driver.refresh
162168
DM = sb_driver.DriverMethods(driver)
163169
driver.find_element = DM.find_element
164170
driver.find_elements = DM.find_elements
171+
driver.add_cookie = DM.add_cookie
172+
driver.get_cookie = DM.get_cookie
173+
driver.delete_cookie = DM.delete_cookie
174+
driver.back = DM.back
175+
driver.forward = DM.forward
176+
driver.refresh = DM.refresh
165177
driver.locator = DM.locator
166178
page = types.SimpleNamespace()
167179
page.open = DM.open_url

seleniumbase/core/sb_cdp.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,10 @@ def click(self, selector, timeout=None):
713713
tag_name in ["a", "button", "canvas", "div", "input", "li", "span"]
714714
and "contains(" not in selector
715715
):
716-
element.mouse_click() # Simulated click (NOT PyAutoGUI)
716+
try:
717+
element.mouse_click() # Simulated click (NOT PyAutoGUI)
718+
except Exception:
719+
element.click() # Standard CDP click
717720
else:
718721
element.click() # Standard CDP click
719722
self.__slow_mode_pause_if_set()

seleniumbase/core/sb_driver.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
class DriverMethods(WebDriver):
1313
def __init__(self, driver):
1414
self.driver = driver
15+
if hasattr(driver, "session_id"):
16+
self.session_id = driver.session_id
17+
if hasattr(driver, "command_executor"):
18+
self.command_executor = driver.command_executor
1519

1620
def __is_cdp_swap_needed(self):
1721
"""If the driver is disconnected, use a CDP method when available."""
@@ -37,6 +41,36 @@ def find_elements(self, by=None, value=None):
3741
value, by = page_utils.swap_selector_and_by_if_reversed(value, by)
3842
return self.driver.default_find_elements(by=by, value=value)
3943

44+
def add_cookie(self, *args, **kwargs):
45+
page_actions._reconnect_if_disconnected(self.driver)
46+
self.driver.default_add_cookie(*args, **kwargs)
47+
48+
def get_cookie(self, *args, **kwargs):
49+
page_actions._reconnect_if_disconnected(self.driver)
50+
self.driver.default_get_cookie(*args, **kwargs)
51+
52+
def delete_cookie(self, *args, **kwargs):
53+
page_actions._reconnect_if_disconnected(self.driver)
54+
self.driver.default_delete_cookie(*args, **kwargs)
55+
56+
def back(self):
57+
if self.__is_cdp_swap_needed():
58+
self.driver.cdp.go_back()
59+
return
60+
self.driver.default_back()
61+
62+
def forward(self):
63+
if self.__is_cdp_swap_needed():
64+
self.driver.cdp.go_forward()
65+
return
66+
self.driver.default_forward()
67+
68+
def refresh(self, *args, **kwargs):
69+
if self.__is_cdp_swap_needed():
70+
self.driver.cdp.refresh(*args, **kwargs)
71+
return
72+
self.driver.default_refresh()
73+
4074
def locator(self, selector, by=None):
4175
if not by:
4276
by = "css selector"

seleniumbase/fixtures/base_case.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3969,8 +3969,23 @@ def set_content_to_parent_frame(self):
39693969

39703970
def open_new_window(self, switch_to=True):
39713971
"""Opens a new browser tab/window and switches to it by default."""
3972+
url = None
3973+
if self.__looks_like_a_page_url(str(switch_to)):
3974+
# Different API for CDP Mode: First arg is a `url`.
3975+
# (Also, don't break backwards compat for reg mode)
3976+
url = switch_to
3977+
switch_to = True
39723978
if self.__is_cdp_swap_needed():
3973-
self.cdp.open_new_tab(switch_to=switch_to)
3979+
self.cdp.open_new_tab(url=url, switch_to=switch_to)
3980+
return
3981+
elif (
3982+
hasattr(self.driver, "_is_using_uc")
3983+
and self.driver._is_using_uc
3984+
and hasattr(self.driver, "_is_using_cdp")
3985+
and self.driver._is_using_cdp
3986+
):
3987+
self.disconnect()
3988+
self.cdp.open_new_tab(url=url, switch_to=switch_to)
39743989
return
39753990
self.wait_for_ready_state_complete()
39763991
if switch_to:
@@ -5040,9 +5055,8 @@ def activate_cdp_mode(self, url=None, **kwargs):
50405055
if hasattr(self.cdp, "find_element_by_text"):
50415056
self.find_element_by_text = self.cdp.find_element_by_text
50425057
if (
5043-
hasattr(sb_config, "_cdp_proxy")
5044-
and sb_config._cdp_proxy
5045-
and "@" in sb_config._cdp_proxy
5058+
hasattr(self.driver, "_is_using_auth")
5059+
and self.driver._is_using_auth
50465060
):
50475061
with suppress(Exception):
50485062
self.cdp.loop.run_until_complete(self.cdp.page.wait(0.25))
@@ -6364,6 +6378,7 @@ def press_up_arrow(self, selector="body", times=1, by="css selector"):
63646378
By default, "html" will be used as the CSS Selector target.
63656379
You can specify how many times in-a-row the action happens."""
63666380
self.__check_scope()
6381+
self._check_browser()
63676382
if times < 1:
63686383
return
63696384
element = self.wait_for_element_present(selector)
@@ -6386,6 +6401,7 @@ def press_down_arrow(self, selector="body", times=1, by="css selector"):
63866401
By default, "html" will be used as the CSS Selector target.
63876402
You can specify how many times in-a-row the action happens."""
63886403
self.__check_scope()
6404+
self._check_browser()
63896405
if times < 1:
63906406
return
63916407
element = self.wait_for_element_present(selector)
@@ -6408,6 +6424,7 @@ def press_left_arrow(self, selector="body", times=1, by="css selector"):
64086424
By default, "html" will be used as the CSS Selector target.
64096425
You can specify how many times in-a-row the action happens."""
64106426
self.__check_scope()
6427+
self._check_browser()
64116428
if times < 1:
64126429
return
64136430
element = self.wait_for_element_present(selector)
@@ -6430,6 +6447,7 @@ def press_right_arrow(self, selector="body", times=1, by="css selector"):
64306447
By default, "html" will be used as the CSS Selector target.
64316448
You can specify how many times in-a-row the action happens."""
64326449
self.__check_scope()
6450+
self._check_browser()
64336451
if times < 1:
64346452
return
64356453
element = self.wait_for_element_present(selector)
@@ -8781,6 +8799,9 @@ def set_text(self, selector, text, by="css selector", timeout=None):
87818799
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
87828800
timeout = self.__get_new_timeout(timeout)
87838801
selector, by = self.__recalculate_selector(selector, by)
8802+
if self.__is_cdp_swap_needed():
8803+
self.cdp.set_value(selector, text)
8804+
return
87848805
self.wait_for_ready_state_complete()
87858806
element = page_actions.wait_for_element_present(
87868807
self.driver, selector, by, timeout
@@ -8801,10 +8822,14 @@ def set_text_content(
88018822
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
88028823
timeout = self.__get_new_timeout(timeout)
88038824
selector, by = self.__recalculate_selector(selector, by)
8804-
self.wait_for_ready_state_complete()
8805-
element = page_actions.wait_for_element_present(
8806-
self.driver, selector, by, timeout
8807-
)
8825+
element = None
8826+
if self.__is_cdp_swap_needed():
8827+
element = self.cdp.select(selector, timeout=timeout)
8828+
else:
8829+
self.wait_for_ready_state_complete()
8830+
element = page_actions.wait_for_element_present(
8831+
self.driver, selector, by, timeout
8832+
)
88088833
if element.tag_name.lower() in ["input", "textarea"]:
88098834
self.js_update_text(selector, text, by=by, timeout=timeout)
88108835
return

seleniumbase/undetected/cdp_driver/browser.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -430,14 +430,28 @@ async def get(
430430
username_and_password = sb_config._cdp_proxy.split("@")[0]
431431
proxy_user = username_and_password.split(":")[0]
432432
proxy_pass = username_and_password.split(":")[1]
433-
await self.set_auth(proxy_user, proxy_pass, self.tabs[0])
434-
time.sleep(0.25)
433+
if (
434+
hasattr(self.main_tab, "_last_auth")
435+
and self.main_tab._last_auth == username_and_password
436+
):
437+
pass # Auth was already set
438+
else:
439+
self.main_tab._last_auth = username_and_password
440+
await self.set_auth(proxy_user, proxy_pass, self.tabs[0])
441+
time.sleep(0.25)
435442
if "auth" in kwargs and kwargs["auth"] and ":" in kwargs["auth"]:
436443
username_and_password = kwargs["auth"]
437444
proxy_user = username_and_password.split(":")[0]
438445
proxy_pass = username_and_password.split(":")[1]
439-
await self.set_auth(proxy_user, proxy_pass, self.tabs[0])
440-
time.sleep(0.25)
446+
if (
447+
hasattr(self.main_tab, "_last_auth")
448+
and self.main_tab._last_auth == username_and_password
449+
):
450+
pass # Auth was already set
451+
else:
452+
self.main_tab._last_auth = username_and_password
453+
await self.set_auth(proxy_user, proxy_pass, self.tabs[0])
454+
time.sleep(0.25)
441455
await connection.sleep(0.15)
442456
frame_id, loader_id, *_ = await connection.send(
443457
cdp.page.navigate(url)

0 commit comments

Comments
 (0)