Skip to content

Commit

Permalink
Update CDP Mode / UC Mode
Browse files Browse the repository at this point in the history
  • Loading branch information
mdmintz committed Oct 26, 2024
1 parent 32f1288 commit 2700066
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 54 deletions.
11 changes: 9 additions & 2 deletions seleniumbase/core/browser_launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ def uc_open_with_cdp_mode(driver, url=None):
cdp = types.SimpleNamespace()
CDPM = sb_cdp.CDPMethods(loop, page, driver)
cdp.get = CDPM.get
cdp.open = CDPM.get
cdp.open = CDPM.open
cdp.reload = CDPM.reload
cdp.refresh = CDPM.refresh
cdp.add_handler = CDPM.add_handler
Expand Down Expand Up @@ -590,6 +590,7 @@ def uc_open_with_cdp_mode(driver, url=None):
cdp.medimize = CDPM.medimize
cdp.set_window_rect = CDPM.set_window_rect
cdp.reset_window_size = CDPM.reset_window_size
cdp.set_locale = CDPM.set_locale
cdp.set_attributes = CDPM.set_attributes
cdp.internalize_links = CDPM.internalize_links
cdp.get_window = CDPM.get_window
Expand Down Expand Up @@ -2179,8 +2180,13 @@ def _set_chrome_options(
or IS_LINUX # switches to Xvfb (non-headless)
)
):
chrome_options.add_argument("--no-pings")
chrome_options.add_argument("--disable-popup-blocking")
chrome_options.add_argument("--homepage=chrome://new-tab-page/")
chrome_options.add_argument("--homepage=chrome://version/")
chrome_options.add_argument("--animation-duration-scale=0")
chrome_options.add_argument("--wm-window-animations-disabled")
chrome_options.add_argument("--enable-privacy-sandbox-ads-apis")
chrome_options.add_argument("--disable-background-timer-throttling")
# Skip remaining options that trigger anti-bot services
return chrome_options
chrome_options.add_argument("--test-type")
Expand Down Expand Up @@ -4523,6 +4529,7 @@ def get_local_driver(
and uc_chrome_version
and uc_chrome_version >= 117
and (headless or headless2)
and chromium_arg != "decoy"
):
from seleniumbase.console_scripts import (
sb_install
Expand Down
78 changes: 65 additions & 13 deletions seleniumbase/core/sb_cdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,21 @@ def __add_sync_methods(self, element):

def get(self, url):
url = shared_utils.fix_url_as_needed(url)
self.page = self.loop.run_until_complete(self.driver.cdp_base.get(url))
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
self.page = self.loop.run_until_complete(driver.get(url))
url_protocol = url.split(":")[0]
safe_url = True
if url_protocol not in ["about", "data", "chrome"]:
safe_url = False
if not safe_url:
time.sleep(constants.UC.CDP_MODE_OPEN_WAIT)
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait())

def open(self, url):
self.get(url)

def reload(self, ignore_cache=True, script_to_evaluate_on_load=None):
self.loop.run_until_complete(
Expand Down Expand Up @@ -111,18 +119,28 @@ def find_element(
with the closest text-length to the text being searched for."""
self.__add_light_pause()
selector = self.__convert_to_css_if_xpath(selector)
early_failure = False
if (":contains(" in selector):
tag_name = selector.split(":contains(")[0].split(" ")[-1]
text = selector.split(":contains(")[1].split(")")[0][1:-1]
with suppress(Exception):
self.loop.run_until_complete(
self.page.select(tag_name, timeout=3)
self.page.select(tag_name, timeout=timeout)
)
self.loop.run_until_complete(self.page.find(text, timeout=3))
element = self.find_elements_by_text(text, tag_name=tag_name)[0]
return self.__add_sync_methods(element)
self.loop.run_until_complete(
self.page.find(text, timeout=timeout)
)
elements = []
with suppress(Exception):
elements = self.find_elements_by_text(text, tag_name=tag_name)
if elements:
return self.__add_sync_methods(elements[0])
else:
early_failure = True
failure = False
try:
if early_failure:
raise Exception("Failed!")
element = self.loop.run_until_complete(
self.page.find(
selector, best_match=best_match, timeout=timeout
Expand Down Expand Up @@ -230,9 +248,11 @@ def __clear_input(self, element):
)

def __click(self, element):
return (
result = (
self.loop.run_until_complete(element.click_async())
)
self.loop.run_until_complete(self.page.wait())
return result

def __flash(self, element):
return (
Expand All @@ -250,9 +270,11 @@ def __highlight_overlay(self, element):
)

def __mouse_click(self, element):
return (
result = (
self.loop.run_until_complete(element.mouse_click_async())
)
self.loop.run_until_complete(self.page.wait())
return result

def __mouse_drag(self, element, destination):
return (
Expand Down Expand Up @@ -353,33 +375,51 @@ def __get_js_attributes(self, element):

def tile_windows(self, windows=None, max_columns=0):
"""Tile windows and return the grid of tiled windows."""
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
return self.loop.run_until_complete(
self.driver.cdp_base.tile_windows(windows, max_columns)
driver.tile_windows(windows, max_columns)
)

def get_all_cookies(self, *args, **kwargs):
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
return self.loop.run_until_complete(
self.driver.cdp_base.cookies.get_all(*args, **kwargs)
driver.cookies.get_all(*args, **kwargs)
)

def set_all_cookies(self, *args, **kwargs):
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
return self.loop.run_until_complete(
self.driver.cdp_base.cookies.set_all(*args, **kwargs)
driver.cookies.set_all(*args, **kwargs)
)

def save_cookies(self, *args, **kwargs):
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
return self.loop.run_until_complete(
self.driver.cdp_base.cookies.save(*args, **kwargs)
driver.cookies.save(*args, **kwargs)
)

def load_cookies(self, *args, **kwargs):
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
return self.loop.run_until_complete(
self.driver.cdp_base.cookies.load(*args, **kwargs)
driver.cookies.load(*args, **kwargs)
)

def clear_cookies(self, *args, **kwargs):
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
return self.loop.run_until_complete(
self.driver.cdp_base.cookies.clear(*args, **kwargs)
driver.cookies.clear(*args, **kwargs)
)

def sleep(self, seconds):
Expand Down Expand Up @@ -408,17 +448,20 @@ def click(self, selector, timeout=settings.SMALL_TIMEOUT):
self.__add_light_pause()
element.click()
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait())

def click_active_element(self):
self.loop.run_until_complete(
self.page.evaluate("document.activeElement.click()")
)
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait())

def click_if_visible(self, selector):
if self.is_element_visible(selector):
self.find_element(selector).click()
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait())

def mouse_click(self, selector, timeout=settings.SMALL_TIMEOUT):
"""(Attempt simulating a mouse click)"""
Expand All @@ -427,6 +470,7 @@ def mouse_click(self, selector, timeout=settings.SMALL_TIMEOUT):
self.__add_light_pause()
element.mouse_click()
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait())

def nested_click(self, parent_selector, selector):
"""
Expand All @@ -436,6 +480,7 @@ def nested_click(self, parent_selector, selector):
element = self.find_element(parent_selector)
element.query_selector(selector).mouse_click()
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait())

def get_nested_element(self, parent_selector, selector):
"""(Can be used to find an element inside an iframe)"""
Expand Down Expand Up @@ -483,6 +528,7 @@ def send_keys(self, selector, text, timeout=settings.SMALL_TIMEOUT):
text = text[:-1] + "\r\n"
element.send_keys(text)
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait())

def press_keys(self, selector, text, timeout=settings.SMALL_TIMEOUT):
"""Similar to send_keys(), but presses keys at human speed."""
Expand All @@ -499,6 +545,7 @@ def press_keys(self, selector, text, timeout=settings.SMALL_TIMEOUT):
element.send_keys("\r\n")
time.sleep(0.0375)
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait())

def type(self, selector, text, timeout=settings.SMALL_TIMEOUT):
"""Similar to send_keys(), but clears the text field first."""
Expand All @@ -510,6 +557,7 @@ def type(self, selector, text, timeout=settings.SMALL_TIMEOUT):
text = text[:-1] + "\r\n"
element.send_keys(text)
self.__slow_mode_pause_if_set()
self.loop.run_until_complete(self.page.wait())

def evaluate(self, expression):
"""Run a JavaScript expression and return the result."""
Expand Down Expand Up @@ -760,6 +808,10 @@ def get_element_html(self, selector):
)
)

def set_locale(self, locale):
"""(Settings will take effect on the next page load)"""
self.loop.run_until_complete(self.page.set_locale(locale))

def set_attributes(self, selector, attribute, value):
"""This method uses JavaScript to set/update a common attribute.
All matching selectors from querySelectorAll() are used.
Expand Down
Loading

0 comments on commit 2700066

Please sign in to comment.