Skip to content

Commit b0d76be

Browse files
committed
Update CDP Mode
1 parent ebb4e6b commit b0d76be

File tree

8 files changed

+132
-8
lines changed

8 files changed

+132
-8
lines changed

help_docs/method_summary.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,10 @@ self.save_screenshot_to_logs(name=None, selector=None, by="css selector")
250250
self.save_as_pdf_to_logs(name=None)
251251
self.save_data_to_logs(data, file_name=None)
252252
self.append_data_to_logs(data, file_name=None)
253-
self.save_page_source(name, folder=None)
254253
self.save_page_source_to_logs(name=None)
254+
self.save_page_source(name, folder=None)
255+
# Duplicates:
256+
# self.save_as_html(name, folder=None)
255257
self.save_cookies(name="cookies.txt")
256258
self.load_cookies(name="cookies.txt", expiry=False)
257259
self.delete_all_cookies()

seleniumbase/core/browser_launcher.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,12 +756,16 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
756756
cdp.set_value = CDPM.set_value
757757
cdp.submit = CDPM.submit
758758
cdp.evaluate = CDPM.evaluate
759+
cdp.execute_script = CDPM.execute_script
759760
cdp.js_dumps = CDPM.js_dumps
760761
cdp.maximize = CDPM.maximize
761762
cdp.minimize = CDPM.minimize
762763
cdp.medimize = CDPM.medimize
763764
cdp.set_window_rect = CDPM.set_window_rect
764765
cdp.reset_window_size = CDPM.reset_window_size
766+
cdp.activate_messenger = CDPM.activate_messenger
767+
cdp.set_messenger_theme = CDPM.set_messenger_theme
768+
cdp.post_message = CDPM.post_message
765769
cdp.set_locale = CDPM.set_locale
766770
cdp.set_local_storage_item = CDPM.set_local_storage_item
767771
cdp.set_session_storage_item = CDPM.set_session_storage_item
@@ -877,6 +881,8 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
877881
cdp.scroll_to_bottom = CDPM.scroll_to_bottom
878882
cdp.scroll_up = CDPM.scroll_up
879883
cdp.scroll_down = CDPM.scroll_down
884+
cdp.save_page_source = CDPM.save_page_source
885+
cdp.save_as_html = CDPM.save_as_html
880886
cdp.save_screenshot = CDPM.save_screenshot
881887
cdp.print_to_pdf = CDPM.print_to_pdf
882888
cdp.save_as_pdf = CDPM.save_as_pdf

seleniumbase/core/sb_cdp.py

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,9 @@ def evaluate(self, expression):
10241024
).strip()
10251025
return self.loop.run_until_complete(self.page.evaluate(expression))
10261026

1027+
def execute_script(self, expression):
1028+
return self.evaluate(expression)
1029+
10271030
def js_dumps(self, obj_name):
10281031
"""Similar to evaluate(), but for dictionary results."""
10291032
if obj_name.startswith("return "):
@@ -1407,6 +1410,64 @@ def enter_mfa_code(self, selector, totp_key=None, timeout=None):
14071410
mfa_code = self.get_mfa_code(totp_key)
14081411
self.type(selector, mfa_code + "\n", timeout=timeout)
14091412

1413+
def activate_messenger(self):
1414+
js_utils.activate_messenger(self)
1415+
self.__add_light_pause()
1416+
1417+
def set_messenger_theme(
1418+
self, theme="default", location="default", max_messages="default"
1419+
):
1420+
"""Sets a theme for posting messages.
1421+
Themes: ["flat", "future", "block", "air", "ice"]
1422+
Locations: ["top_left", "top_center", "top_right",
1423+
"bottom_left", "bottom_center", "bottom_right"]
1424+
max_messages: The limit of concurrent messages to display."""
1425+
if not theme:
1426+
theme = "default" # "flat"
1427+
if not location:
1428+
location = "default" # "bottom_right"
1429+
if not max_messages:
1430+
max_messages = "default" # "8"
1431+
else:
1432+
max_messages = str(max_messages) # Value must be in string format
1433+
js_utils.set_messenger_theme(
1434+
self,
1435+
theme=theme,
1436+
location=location,
1437+
max_messages=max_messages,
1438+
)
1439+
self.__add_light_pause()
1440+
1441+
def post_message(self, message, duration=None, pause=True, style="info"):
1442+
"""Post a message on the screen with Messenger.
1443+
Arguments:
1444+
message: The message to display.
1445+
duration: The time until the message vanishes. (Default: 2.55s)
1446+
pause: If True, the program waits until the message completes.
1447+
style: "info", "success", or "error"."""
1448+
driver = self.driver
1449+
if hasattr(driver, "cdp_base"):
1450+
driver = driver.cdp_base
1451+
if style not in ["info", "success", "error"]:
1452+
style = "info"
1453+
if not duration:
1454+
duration = settings.DEFAULT_MESSAGE_DURATION
1455+
if (
1456+
(
1457+
driver.config.headless
1458+
or (hasattr(sb_config, "xvfb") and sb_config.xvfb)
1459+
)
1460+
and float(duration) > 0.75
1461+
):
1462+
duration = 0.75
1463+
try:
1464+
js_utils.post_message(self, message, duration, style=style)
1465+
except Exception:
1466+
print(" * %s message: %s" % (style.upper(), message))
1467+
if pause:
1468+
duration = float(duration) + 0.15
1469+
time.sleep(float(duration))
1470+
14101471
def set_locale(self, locale):
14111472
"""(Settings will take effect on the next page load)"""
14121473
self.loop.run_until_complete(self.page.set_locale(locale))
@@ -1510,7 +1571,10 @@ def __install_pyautogui_if_missing(self):
15101571
except Exception:
15111572
if (
15121573
shared_utils.is_linux()
1513-
and (not sb_config.headed or sb_config.xvfb)
1574+
and (
1575+
not sb_config.headed
1576+
or (hasattr(sb_config, "xvfb") and sb_config.xvfb)
1577+
)
15141578
and not driver.config.headless
15151579
and (
15161580
not hasattr(sb_config, "_virtual_display")
@@ -2611,6 +2675,40 @@ def scroll_down(self, amount=25):
26112675
self.loop.run_until_complete(self.page.scroll_down(amount))
26122676
self.loop.run_until_complete(self.page.wait())
26132677

2678+
def save_page_source(self, name, folder=None):
2679+
import codecs
2680+
from seleniumbase.core import log_helper
2681+
if not name.endswith(".html"):
2682+
name = name + ".html"
2683+
if folder:
2684+
abs_path = os.path.abspath(".")
2685+
file_path = os.path.join(abs_path, folder)
2686+
if not os.path.exists(file_path):
2687+
os.makedirs(file_path)
2688+
html_file_path = os.path.join(file_path, name)
2689+
else:
2690+
html_file_path = name
2691+
page_source = self.get_page_source()
2692+
last_page = self.get_current_url()
2693+
meta_charset = '<meta charset="utf-8">'
2694+
rendered_source = ""
2695+
if "://" in last_page:
2696+
base_href_html = log_helper.get_base_href_html(last_page)
2697+
if ' charset="' not in page_source:
2698+
rendered_source = "%s\n%s\n%s" % (
2699+
base_href_html, meta_charset, page_source
2700+
)
2701+
else:
2702+
rendered_source = "%s\n%s" % (base_href_html, page_source)
2703+
else:
2704+
rendered_source = page_source
2705+
html_file = codecs.open(html_file_path, "w+", "utf-8")
2706+
html_file.write(rendered_source)
2707+
html_file.close()
2708+
2709+
def save_as_html(self, *args, **kwargs):
2710+
self.save_page_source(*args, **kwargs)
2711+
26142712
def save_screenshot(self, name, folder=None, selector=None):
26152713
filename = name
26162714
if folder:

seleniumbase/fixtures/base_case.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9205,6 +9205,10 @@ def switch_to_newest_tab(self):
92059205
"""Same as self.switch_to_newest_window()"""
92069206
self.switch_to_newest_window()
92079207

9208+
def save_as_html(self, name, folder=None):
9209+
"""Same as self.save_page_source()"""
9210+
self.save_page_source(name, folder=folder)
9211+
92089212
def input(
92099213
self, selector, text, by="css selector", timeout=None, retry=False
92109214
):
@@ -9654,9 +9658,11 @@ def add_meta_tag(self, http_equiv=None, content=None):
96549658

96559659
def activate_messenger(self):
96569660
self.__check_scope()
9657-
self._check_browser()
9661+
if not self.__is_cdp_swap_needed():
9662+
self._check_browser()
96589663
js_utils.activate_messenger(self.driver)
9659-
self.wait_for_ready_state_complete()
9664+
if not self.__is_cdp_swap_needed():
9665+
self.wait_for_ready_state_complete()
96609666

96619667
def set_messenger_theme(
96629668
self, theme="default", location="default", max_messages="default"

seleniumbase/fixtures/js_utils.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ def wait_for_ready_state_complete(driver, timeout=settings.LARGE_TIMEOUT):
2929
If the timeout is exceeded, the test will still continue
3030
because readyState == "interactive" may be good enough.
3131
(Previously, tests would fail immediately if exceeding the timeout.)"""
32+
if hasattr(driver, "_swap_driver"):
33+
return
3234
if hasattr(settings, "SKIP_JS_WAITS") and settings.SKIP_JS_WAITS:
3335
return
3436
start_ms = time.time() * 1000.0
@@ -54,8 +56,12 @@ def wait_for_ready_state_complete(driver, timeout=settings.LARGE_TIMEOUT):
5456

5557

5658
def execute_async_script(driver, script, timeout=settings.LARGE_TIMEOUT):
57-
driver.set_script_timeout(timeout)
58-
return driver.execute_async_script(script)
59+
if hasattr(driver, "set_script_timeout"):
60+
driver.set_script_timeout(timeout)
61+
if hasattr(driver, "execute_async_script"):
62+
return driver.execute_async_script(script)
63+
else:
64+
return None
5965

6066

6167
def wait_for_angularjs(driver, timeout=settings.LARGE_TIMEOUT, **kwargs):
@@ -937,7 +943,10 @@ def post_message(driver, message, msg_dur=None, style="info"):
937943
execute_script(driver, messenger_script)
938944
except TypeError as e:
939945
if (
940-
shared_utils.is_cdp_swap_needed(driver)
946+
(
947+
shared_utils.is_cdp_swap_needed(driver)
948+
or hasattr(driver, "_swap_driver")
949+
)
941950
and "cannot unpack non-iterable" in str(e)
942951
):
943952
pass

seleniumbase/fixtures/page_actions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1528,10 +1528,10 @@ def save_page_source(driver, name, folder=None):
15281528
page_source = driver.cdp.get_page_source()
15291529
else:
15301530
page_source = driver.page_source
1531-
html_file = codecs.open(html_file_path, "w+", "utf-8")
15321531
rendered_source = log_helper.get_html_source_with_base_href(
15331532
driver, page_source
15341533
)
1534+
html_file = codecs.open(html_file_path, "w+", "utf-8")
15351535
html_file.write(rendered_source)
15361536
html_file.close()
15371537

seleniumbase/undetected/cdp_driver/cdp_util.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,8 @@ async def start(
335335
xvfb = True
336336
else:
337337
xvfb = False
338+
if not hasattr(sb_config, "xvfb"):
339+
sb_config.xvfb = xvfb
338340
if incognito is None:
339341
if "--incognito" in sys_argv:
340342
incognito = True

seleniumbase/undetected/cdp_driver/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ def __call__(self):
202202
"InsecureDownloadWarnings,DownloadBubble,DownloadBubbleV2,"
203203
"OptimizationTargetPrediction,OptimizationGuideModelDownloading,"
204204
"SidePanelPinning,UserAgentClientHint,PrivacySandboxSettings4,"
205+
"OptimizationHintsFetching,InterestFeedContentSuggestions,"
205206
"DisableLoadExtensionCommandLineSwitch"
206207
]
207208
if self.proxy:

0 commit comments

Comments
 (0)