Update CDP Mode

This commit is contained in:
Michael Mintz 2025-03-04 22:49:51 -05:00
parent aa0b70a799
commit cc1073a66b
7 changed files with 72 additions and 17 deletions

View File

@ -420,6 +420,13 @@ sb.cdp.minimize()
sb.cdp.medimize() sb.cdp.medimize()
sb.cdp.set_window_rect() sb.cdp.set_window_rect()
sb.cdp.reset_window_size() sb.cdp.reset_window_size()
sb.cdp.switch_to_window(window)
sb.cdp.switch_to_newest_window()
sb.cdp.switch_to_tab(tab)
sb.cdp.switch_to_newest_tab()
sb.cdp.close_active_tab()
sb.cdp.get_active_tab()
sb.cdp.get_tabs()
sb.cdp.get_window() sb.cdp.get_window()
sb.cdp.get_text(selector) sb.cdp.get_text(selector)
sb.cdp.get_title() sb.cdp.get_title()

View File

@ -682,6 +682,13 @@ def uc_open_with_cdp_mode(driver, url=None):
cdp.gui_hover_element = CDPM.gui_hover_element cdp.gui_hover_element = CDPM.gui_hover_element
cdp.gui_hover_and_click = CDPM.gui_hover_and_click cdp.gui_hover_and_click = CDPM.gui_hover_and_click
cdp.internalize_links = CDPM.internalize_links cdp.internalize_links = CDPM.internalize_links
cdp.switch_to_window = CDPM.switch_to_window
cdp.switch_to_newest_window = CDPM.switch_to_newest_window
cdp.switch_to_tab = CDPM.switch_to_tab
cdp.switch_to_newest_tab = CDPM.switch_to_newest_tab
cdp.close_active_tab = CDPM.close_active_tab
cdp.get_active_tab = CDPM.get_active_tab
cdp.get_tabs = CDPM.get_tabs
cdp.get_window = CDPM.get_window cdp.get_window = CDPM.get_window
cdp.get_element_attributes = CDPM.get_element_attributes cdp.get_element_attributes = CDPM.get_element_attributes
cdp.get_element_attribute = CDPM.get_element_attribute cdp.get_element_attribute = CDPM.get_element_attribute
@ -2033,6 +2040,7 @@ def _set_chrome_options(
prefs["download.default_directory"] = downloads_path prefs["download.default_directory"] = downloads_path
prefs["download.directory_upgrade"] = True prefs["download.directory_upgrade"] = True
prefs["download.prompt_for_download"] = False prefs["download.prompt_for_download"] = False
prefs["download_bubble.partial_view_enabled"] = False
prefs["credentials_enable_service"] = False prefs["credentials_enable_service"] = False
prefs["local_discovery.notifications_enabled"] = False prefs["local_discovery.notifications_enabled"] = False
prefs["safebrowsing.enabled"] = False # Prevent PW "data breach" pop-ups prefs["safebrowsing.enabled"] = False # Prevent PW "data breach" pop-ups

View File

@ -1014,10 +1014,51 @@ class CDPMethods():
self.set_window_rect(x, y, width, height) self.set_window_rect(x, y, width, height)
self.__add_light_pause() self.__add_light_pause()
def switch_to_window(self, window):
self.switch_to_tab(window)
def switch_to_newest_window(self):
self.switch_to_tab(-1)
def switch_to_tab(self, tab):
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
if isinstance(tab, int):
self.page = driver.tabs[tab]
elif isinstance(tab, cdp_util.Tab):
self.page = tab
else:
raise Exception("`tab` must be an int or a Tab type!")
self.bring_active_window_to_front()
def switch_to_newest_tab(self):
self.switch_to_tab(-1)
def close_active_tab(self):
"""Close the active tab.
The active tab is the one currenly controlled by CDP.
The active tab MIGHT NOT be the currently visible tab!
(If a page opens a new tab, the new tab WON'T be active)
To switch the active tab, call: sb.switch_to_tab(tab)"""
return self.loop.run_until_complete(self.page.close())
def get_active_tab(self):
"""Return the active tab.
The active tab is the one currenly controlled by CDP.
The active tab MIGHT NOT be the currently visible tab!
(If a page opens a new tab, the new tab WON'T be active)
To switch the active tab, call: sb.switch_to_tab(tab)"""
return self.page
def get_tabs(self):
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
return driver.tabs
def get_window(self): def get_window(self):
return self.loop.run_until_complete( return self.loop.run_until_complete(self.page.get_window())
self.page.get_window()
)
def get_text(self, selector): def get_text(self, selector):
return self.find_element(selector).text_all return self.find_element(selector).text_all
@ -1211,14 +1252,10 @@ class CDPMethods():
return ((e_x + e_width / 2.0) + 0.5, (e_y + e_height / 2.0) + 0.5) return ((e_x + e_width / 2.0) + 0.5, (e_y + e_height / 2.0) + 0.5)
def get_document(self): def get_document(self):
return self.loop.run_until_complete( return self.loop.run_until_complete(self.page.get_document())
self.page.get_document()
)
def get_flattened_document(self): def get_flattened_document(self):
return self.loop.run_until_complete( return self.loop.run_until_complete(self.page.get_flattened_document())
self.page.get_flattened_document()
)
def get_element_attributes(self, selector): def get_element_attributes(self, selector):
selector = self.__convert_to_css_if_xpath(selector) selector = self.__convert_to_css_if_xpath(selector)

View File

@ -3918,6 +3918,9 @@ class BaseCase(unittest.TestCase):
timeout = settings.SMALL_TIMEOUT timeout = settings.SMALL_TIMEOUT
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
timeout = self.__get_new_timeout(timeout) timeout = self.__get_new_timeout(timeout)
if self.__is_cdp_swap_needed() and not isinstance(window, str):
self.cdp.switch_to_tab(window)
return
page_actions.switch_to_window(self.driver, window, timeout) page_actions.switch_to_window(self.driver, window, timeout)
def switch_to_default_window(self): def switch_to_default_window(self):

View File

@ -660,7 +660,7 @@ class CookieJar:
break break
else: else:
connection = self._browser.connection connection = self._browser.connection
cookies = await connection.send(cdp.storage.get_cookies()) cookies = await connection.send(cdp.network.get_cookies())
if requests_cookie_format: if requests_cookie_format:
import requests.cookies import requests.cookies
@ -690,8 +690,7 @@ class CookieJar:
break break
else: else:
connection = self._browser.connection connection = self._browser.connection
cookies = await connection.send(cdp.storage.get_cookies()) await connection.send(cdp.network.set_cookies(cookies))
await connection.send(cdp.storage.set_cookies(cookies))
async def save(self, file: PathLike = ".session.dat", pattern: str = ".*"): async def save(self, file: PathLike = ".session.dat", pattern: str = ".*"):
""" """
@ -718,7 +717,7 @@ class CookieJar:
break break
else: else:
connection = self._browser.connection connection = self._browser.connection
cookies = await connection.send(cdp.storage.get_cookies()) cookies = await connection.send(cdp.network.get_cookies())
# if not connection: # if not connection:
# return # return
# if not connection.websocket: # if not connection.websocket:
@ -776,7 +775,7 @@ class CookieJar:
cookie.value, cookie.value,
) )
break break
await connection.send(cdp.storage.set_cookies(included_cookies)) await connection.send(cdp.network.set_cookies(included_cookies))
async def clear(self): async def clear(self):
""" """
@ -791,9 +790,9 @@ class CookieJar:
break break
else: else:
connection = self._browser.connection connection = self._browser.connection
cookies = await connection.send(cdp.storage.get_cookies()) cookies = await connection.send(cdp.network.get_cookies())
if cookies: if cookies:
await connection.send(cdp.storage.clear_cookies()) await connection.send(cdp.network.clear_cookies())
class HTTPApi: class HTTPApi:

View File

@ -382,7 +382,7 @@ class Connection(metaclass=CantTouchThis):
async def send( async def send(
self, self,
cdp_obj: Generator[dict[str, Any], dict[str, Any], Any], cdp_obj: Generator[dict[str, Any], dict[str, Any], Any],
_is_update=False, _is_update=True,
) -> Any: ) -> Any:
""" """
Send a protocol command. Send a protocol command.

View File

@ -852,6 +852,7 @@ class Tab(Connection):
await self.send( await self.send(
cdp.target.close_target(target_id=self.target.target_id) cdp.target.close_target(target_id=self.target.target_id)
) )
await asyncio.sleep(0.1)
async def get_window(self) -> Tuple[ async def get_window(self) -> Tuple[
cdp.browser.WindowID, cdp.browser.Bounds cdp.browser.WindowID, cdp.browser.Bounds