diff --git a/examples/cdp_mode/ReadMe.md b/examples/cdp_mode/ReadMe.md
index 27f8ac81160..ede98774998 100644
--- a/examples/cdp_mode/ReadMe.md
+++ b/examples/cdp_mode/ReadMe.md
@@ -420,8 +420,10 @@ sb.cdp.minimize()
sb.cdp.medimize()
sb.cdp.set_window_rect()
sb.cdp.reset_window_size()
+sb.cdp.open_new_window(url=None, switch_to=True)
sb.cdp.switch_to_window(window)
sb.cdp.switch_to_newest_window()
+sb.cdp.open_new_tab(url=None, switch_to=True)
sb.cdp.switch_to_tab(tab)
sb.cdp.switch_to_newest_tab()
sb.cdp.close_active_tab()
diff --git a/examples/cdp_mode/raw_tab_switching.py b/examples/cdp_mode/raw_tab_switching.py
new file mode 100644
index 00000000000..42e1e3bc7b4
--- /dev/null
+++ b/examples/cdp_mode/raw_tab_switching.py
@@ -0,0 +1,15 @@
+from seleniumbase import SB
+
+with SB(uc=True) as sb:
+ sb.activate_cdp_mode()
+ sb.open("data:text/html,
Page A
")
+ sb.assert_text("Page A")
+ sb.open_new_tab()
+ sb.open("data:text/html,Page B
")
+ sb.assert_text("Page B")
+ sb.switch_to_tab(0)
+ sb.assert_text("Page A")
+ sb.assert_text_not_visible("Page B")
+ sb.switch_to_tab(1)
+ sb.assert_text("Page B")
+ sb.assert_text_not_visible("Page A")
diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py
index 1ef94d85dba..7fb5236d53e 100755
--- a/seleniumbase/__version__.py
+++ b/seleniumbase/__version__.py
@@ -1,2 +1,2 @@
# seleniumbase package
-__version__ = "4.35.3"
+__version__ = "4.35.4"
diff --git a/seleniumbase/core/browser_launcher.py b/seleniumbase/core/browser_launcher.py
index 30ef2bf13d0..182c70c5b71 100644
--- a/seleniumbase/core/browser_launcher.py
+++ b/seleniumbase/core/browser_launcher.py
@@ -682,8 +682,10 @@ def uc_open_with_cdp_mode(driver, url=None):
cdp.gui_hover_element = CDPM.gui_hover_element
cdp.gui_hover_and_click = CDPM.gui_hover_and_click
cdp.internalize_links = CDPM.internalize_links
+ cdp.open_new_window = CDPM.open_new_window
cdp.switch_to_window = CDPM.switch_to_window
cdp.switch_to_newest_window = CDPM.switch_to_newest_window
+ cdp.open_new_tab = CDPM.open_new_tab
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
diff --git a/seleniumbase/core/sb_cdp.py b/seleniumbase/core/sb_cdp.py
index a4f5fba45bd..31bb25b1681 100644
--- a/seleniumbase/core/sb_cdp.py
+++ b/seleniumbase/core/sb_cdp.py
@@ -106,7 +106,7 @@ def get(self, url):
driver = self.driver
if hasattr(driver, "cdp_base"):
driver = driver.cdp_base
- self.page = self.loop.run_until_complete(driver.get(url))
+ self.loop.run_until_complete(self.page.get(url))
url_protocol = url.split(":")[0]
safe_url = True
if url_protocol not in ["about", "data", "chrome"]:
@@ -1014,12 +1014,22 @@ def reset_window_size(self):
self.set_window_rect(x, y, width, height)
self.__add_light_pause()
+ def open_new_window(self, url=None, switch_to=True):
+ return self.open_new_tab(url=url, switch_to=switch_to)
+
def switch_to_window(self, window):
self.switch_to_tab(window)
def switch_to_newest_window(self):
self.switch_to_tab(-1)
+ def open_new_tab(self, url=None, switch_to=True):
+ if not isinstance(url, str):
+ url = "about:blank"
+ self.loop.run_until_complete(self.page.get(url, new_tab=True))
+ if switch_to:
+ self.switch_to_newest_tab()
+
def switch_to_tab(self, tab):
driver = self.driver
if hasattr(driver, "cdp_base"):
diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py
index 036dd3057d0..905d93ea126 100644
--- a/seleniumbase/fixtures/base_case.py
+++ b/seleniumbase/fixtures/base_case.py
@@ -3896,6 +3896,9 @@ def set_content_to_parent_frame(self):
def open_new_window(self, switch_to=True):
"""Opens a new browser tab/window and switches to it by default."""
+ if self.__is_cdp_swap_needed():
+ self.cdp.open_new_tab(switch_to=switch_to)
+ return
self.wait_for_ready_state_complete()
if switch_to:
try:
@@ -10339,7 +10342,7 @@ def wait_for_text_not_visible(
timeout = self.__get_new_timeout(timeout)
selector, by = self.__recalculate_selector(selector, by)
if self.__is_cdp_swap_needed():
- return self.cdp.wait_for_text(
+ return self.cdp.wait_for_text_not_visible(
text, selector=selector, timeout=timeout
)
return page_actions.wait_for_text_not_visible(
diff --git a/seleniumbase/undetected/__init__.py b/seleniumbase/undetected/__init__.py
index 4a6827ea9ef..5635d63562f 100644
--- a/seleniumbase/undetected/__init__.py
+++ b/seleniumbase/undetected/__init__.py
@@ -477,6 +477,7 @@ def disconnect(self):
with suppress(Exception):
if self.service.is_connectable():
self.stop_client()
+ time.sleep(0.003)
self.service.stop()
self._is_connected = False
diff --git a/seleniumbase/undetected/cdp_driver/browser.py b/seleniumbase/undetected/cdp_driver/browser.py
index 2c0051e4816..1224fcdc530 100644
--- a/seleniumbase/undetected/cdp_driver/browser.py
+++ b/seleniumbase/undetected/cdp_driver/browser.py
@@ -792,7 +792,7 @@ async def clear(self):
connection = self._browser.connection
cookies = await connection.send(cdp.network.get_cookies())
if cookies:
- await connection.send(cdp.network.clear_cookies())
+ await connection.send(cdp.storage.clear_cookies())
class HTTPApi: