From 1f606f967150817d73d98b4da81a60eda8acef46 Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Mon, 8 Dec 2025 22:52:16 -0500
Subject: [PATCH 1/6] Fix issue with passing options to new tabs in CDP Mode
---
seleniumbase/core/sb_cdp.py | 6 ++++--
seleniumbase/fixtures/base_case.py | 18 +++++++++---------
seleniumbase/undetected/cdp_driver/browser.py | 15 ++++++++++-----
seleniumbase/undetected/cdp_driver/tab.py | 2 +-
4 files changed, 24 insertions(+), 17 deletions(-)
diff --git a/seleniumbase/core/sb_cdp.py b/seleniumbase/core/sb_cdp.py
index 8e3e7ac03fb..aad1d27ad0c 100644
--- a/seleniumbase/core/sb_cdp.py
+++ b/seleniumbase/core/sb_cdp.py
@@ -1182,13 +1182,15 @@ def switch_to_window(self, window):
def switch_to_newest_window(self):
self.switch_to_tab(-1)
- def open_new_tab(self, url=None, switch_to=True):
+ def open_new_tab(self, url=None, switch_to=True, **kwargs):
driver = self.driver
if not isinstance(url, str):
url = "about:blank"
if hasattr(driver, "cdp_base"):
try:
- self.loop.run_until_complete(self.page.get(url, new_tab=True))
+ self.loop.run_until_complete(
+ self.page.get(url, new_tab=True, **kwargs)
+ )
except Exception:
original_targets = self.loop.run_until_complete(
self.page.send(mycdp.target.get_targets())
diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py
index 425ab1b00d6..447ef349646 100644
--- a/seleniumbase/fixtures/base_case.py
+++ b/seleniumbase/fixtures/base_case.py
@@ -221,11 +221,11 @@ def test_example(self):
[sys.executable, "-m", "pytest", file, "-s", *all_args]
)
- def open(self, url):
+ def open(self, url, **kwargs):
"""Navigates the current browser window to the specified page."""
self.__check_scope()
if self.__is_cdp_swap_needed():
- self.cdp.open(url)
+ self.cdp.open(url, **kwargs)
return
elif (
getattr(self.driver, "_is_using_uc", None)
@@ -235,14 +235,14 @@ def open(self, url):
# Auth in UC Mode requires CDP Mode
# (and now we're always forcing it)
logging.info("open() in UC Mode now always activates CDP Mode.")
- self.activate_cdp_mode(url)
+ self.activate_cdp_mode(url, **kwargs)
return
elif (
getattr(self.driver, "_is_using_uc", None)
and getattr(self.driver, "_is_using_cdp", None)
):
self.disconnect()
- self.cdp.open(url)
+ self.cdp.open(url, **kwargs)
return
self._check_browser()
if self.__needs_minimum_wait():
@@ -3960,7 +3960,7 @@ def set_content_to_parent_frame(self):
Reverts self.set_content_to_frame()."""
self.set_content_to_default(nested=True)
- def open_new_window(self, switch_to=True):
+ def open_new_window(self, switch_to=True, **kwargs):
"""Opens a new browser tab/window and switches to it by default."""
url = None
if self.__looks_like_a_page_url(str(switch_to)):
@@ -3969,14 +3969,14 @@ def open_new_window(self, switch_to=True):
url = switch_to
switch_to = True
if self.__is_cdp_swap_needed():
- self.cdp.open_new_tab(url=url, switch_to=switch_to)
+ self.cdp.open_new_tab(url=url, switch_to=switch_to, **kwargs)
return
elif (
getattr(self.driver, "_is_using_uc", None)
and getattr(self.driver, "_is_using_cdp", None)
):
self.disconnect()
- self.cdp.open_new_tab(url=url, switch_to=switch_to)
+ self.cdp.open_new_tab(url=url, switch_to=switch_to, **kwargs)
return
self.wait_for_ready_state_complete()
if switch_to:
@@ -9264,9 +9264,9 @@ def reload_page(self):
"""Same as self.refresh_page()"""
self.refresh_page()
- def open_new_tab(self, switch_to=True):
+ def open_new_tab(self, switch_to=True, **kwargs):
"""Same as self.open_new_window()"""
- self.open_new_window(switch_to=switch_to)
+ self.open_new_window(switch_to=switch_to, **kwargs)
def switch_to_tab(self, tab, timeout=None):
"""Same as self.switch_to_window()
diff --git a/seleniumbase/undetected/cdp_driver/browser.py b/seleniumbase/undetected/cdp_driver/browser.py
index 364b0d56ffc..58e7fc96434 100644
--- a/seleniumbase/undetected/cdp_driver/browser.py
+++ b/seleniumbase/undetected/cdp_driver/browser.py
@@ -333,11 +333,16 @@ async def get(
)
connection.browser = self
else:
- # First tab from browser.tabs
- connection: tab.Tab = next(
- filter(lambda item: item.type_ == "page", self.targets)
- )
- await connection.sleep(0.005)
+ try:
+ # Most recently opened tab
+ connection = self.targets[-1]
+ await connection.sleep(0.005)
+ except Exception:
+ # First tab from browser.tabs
+ connection: tab.Tab = next(
+ filter(lambda item: item.type_ == "page", self.targets)
+ )
+ await connection.sleep(0.005)
_cdp_timezone = None
_cdp_user_agent = ""
_cdp_locale = None
diff --git a/seleniumbase/undetected/cdp_driver/tab.py b/seleniumbase/undetected/cdp_driver/tab.py
index d99827229e6..a594bf26453 100644
--- a/seleniumbase/undetected/cdp_driver/tab.py
+++ b/seleniumbase/undetected/cdp_driver/tab.py
@@ -371,7 +371,7 @@ async def get(
return self
else:
return await self.browser.get(
- url, new_tab, new_window, **kwargs
+ url, new_tab=False, new_window=False, **kwargs
)
async def open(self, url="about:blank"):
From 759dd9ba7fd2f62ba6a587907939d954d1cb5cea Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Mon, 8 Dec 2025 22:53:07 -0500
Subject: [PATCH 2/6] Add method to CDP Mode
---
seleniumbase/undetected/cdp_driver/tab.py | 3 +++
1 file changed, 3 insertions(+)
diff --git a/seleniumbase/undetected/cdp_driver/tab.py b/seleniumbase/undetected/cdp_driver/tab.py
index a594bf26453..97ebbdf6662 100644
--- a/seleniumbase/undetected/cdp_driver/tab.py
+++ b/seleniumbase/undetected/cdp_driver/tab.py
@@ -1458,6 +1458,9 @@ async def get_gui_element_rect(self, selector, timeout=5):
async def get_title(self):
return await self.evaluate("document.title")
+ async def get_current_url(self):
+ return await self.evaluate("window.location.href")
+
async def send_keys(self, selector, text, timeout=5):
element = await self.find(selector, timeout=timeout)
await element.send_keys_async(text)
From f08b984c21b44115c7460f2c08ebc953cb2c26a7 Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Mon, 8 Dec 2025 23:00:45 -0500
Subject: [PATCH 3/6] Update CDP Mode examples
---
examples/cdp_mode/raw_async.py | 23 ++++++++++++-----------
examples/cdp_mode/raw_basic_async.py | 1 +
examples/cdp_mode/raw_cookies_async.py | 9 +++------
examples/cdp_mode/raw_mobile_async.py | 7 ++-----
examples/cdp_mode/raw_multi_async.py | 6 ++----
5 files changed, 20 insertions(+), 26 deletions(-)
diff --git a/examples/cdp_mode/raw_async.py b/examples/cdp_mode/raw_async.py
index fc193aadb58..745070feb4b 100644
--- a/examples/cdp_mode/raw_async.py
+++ b/examples/cdp_mode/raw_async.py
@@ -7,18 +7,19 @@
async def main():
url = "seleniumbase.io/simple/login"
- driver = await cdp_driver.start_async(incognito=True)
- page = await driver.get(url)
- print(await page.evaluate("document.title"))
- element = await page.select("#username")
- await element.send_keys_async("demo_user")
- element = await page.select("#password")
- await element.send_keys_async("secret_pass")
- element = await page.select("#log-in")
- await element.click_async()
- time.sleep(1)
+ driver = await cdp_driver.start_async()
+ page = await driver.get(url, lang="en")
+ print(await page.get_title())
+ await page.type("#username", "demo_user")
+ await page.type("#password", "secret_pass")
+ await page.click("#log-in")
+ print(await page.get_title())
element = await page.select("h1")
assert element.text == "Welcome!"
+ top_nav = await page.select("div.topnav")
+ links = await top_nav.query_selector_all_async("a")
+ for nav_item in links:
+ print(nav_item.text)
driver.stop()
if __name__ == "__main__":
@@ -26,7 +27,7 @@ async def main():
loop = asyncio.new_event_loop()
loop.run_until_complete(main())
- # Call everything without using async / await
+ # An example of wrapping all async calls with event loops
driver = cdp_driver.start_sync()
page = loop.run_until_complete(driver.get("about:blank"))
loop.run_until_complete(page.set_locale("en"))
diff --git a/examples/cdp_mode/raw_basic_async.py b/examples/cdp_mode/raw_basic_async.py
index af21373db96..5c3c1f6c536 100644
--- a/examples/cdp_mode/raw_basic_async.py
+++ b/examples/cdp_mode/raw_basic_async.py
@@ -18,6 +18,7 @@ async def main():
links = await top_nav.query_selector_all_async("a")
for nav_item in links:
print(nav_item.text)
+ driver.stop()
if __name__ == "__main__":
# Call an async function with awaited methods
diff --git a/examples/cdp_mode/raw_cookies_async.py b/examples/cdp_mode/raw_cookies_async.py
index e581feb5b18..aef54198d2b 100644
--- a/examples/cdp_mode/raw_cookies_async.py
+++ b/examples/cdp_mode/raw_cookies_async.py
@@ -9,12 +9,9 @@ async def get_login_cookies():
url = "https://www.saucedemo.com"
driver = await cdp_driver.start_async(incognito=True)
page = await driver.get(url)
- element = await page.select("#user-name")
- await element.send_keys_async("standard_user")
- element = await page.select("#password")
- await element.send_keys_async("secret_sauce")
- element = await page.select('input[type="submit"]')
- await element.click_async()
+ await page.type("#user-name", "standard_user")
+ await page.type("#password", "secret_sauce")
+ await page.click('input[type="submit"]')
cookies = await driver.cookies.get_all()
driver.stop()
return cookies
diff --git a/examples/cdp_mode/raw_mobile_async.py b/examples/cdp_mode/raw_mobile_async.py
index 2c99ff7d3f4..dd1fc72d9f5 100644
--- a/examples/cdp_mode/raw_mobile_async.py
+++ b/examples/cdp_mode/raw_mobile_async.py
@@ -15,17 +15,14 @@ async def main():
)
page = await driver.get(url, lang="en")
time.sleep(3)
- try:
- element = await page.select('[style*="grid"] div div', timeout=1)
- await element.mouse_click_with_offset_async(32, 28)
- except Exception:
- pass # Maybe CAPTCHA was already bypassed
+ await page.solve_captcha()
element = await page.select('label[for="user_login"]')
await element.flash_async(duration=1.5, color="44EE44")
time.sleep(1)
element = await page.select('[data-testid="sign-in-button"]')
await element.flash_async(duration=2, color="44EE44")
time.sleep(2)
+ driver.stop()
if __name__ == "__main__":
# Call an async function with awaited methods
diff --git a/examples/cdp_mode/raw_multi_async.py b/examples/cdp_mode/raw_multi_async.py
index 638af36a066..d7363f0768b 100644
--- a/examples/cdp_mode/raw_multi_async.py
+++ b/examples/cdp_mode/raw_multi_async.py
@@ -11,10 +11,8 @@ async def main(url):
page = await driver.get(url)
await page.set_window_rect(randint(4, 600), randint(8, 410), 860, 500)
await page.sleep(0.5)
- field = await page.select("input")
- await field.send_keys_async("Text")
- button = await page.select("button")
- await button.click_async()
+ await page.type("input", "Text")
+ await page.click("button")
await page.sleep(2)
driver.stop()
From cfe11392b4dfe2c48c4c050c588f3ace5a13627d Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Mon, 8 Dec 2025 23:02:11 -0500
Subject: [PATCH 4/6] Update the documentation
---
README.md | 17 ++---
examples/cdp_mode/ReadMe.md | 126 ++++++++++++++++++--------------
help_docs/ReadMe.md | 2 +
help_docs/cdp_mode_methods.md | 126 ++++++++++++++++++--------------
help_docs/js_package_manager.md | 4 +-
5 files changed, 151 insertions(+), 124 deletions(-)
diff --git a/README.md b/README.md
index e7a3bdb1870..d58547ac827 100755
--- a/README.md
+++ b/README.md
@@ -24,11 +24,11 @@
đ Scripts |
đą Mobile
-đ APIs |
- đ Formats |
+đ API |
+ đ Syntaxes |
đ´ Recorder |
đ Dashboard |
-đž Locales |
+đž Locale |
đģ Farm
đī¸ GUI |
@@ -39,18 +39,17 @@
đ Grid
đī¸ How |
-đ Migrate |
-đī¸ CasePlans |
-âģī¸ Template |
-đ§Ŧ Hybrid |
+đ Migration |
+đ Stealthy Playwright |
+đ MasterQA |
đ Tours
đ¤ CI/CD |
đšī¸ JSMgr |
đ Translator |
đī¸ Presenter |
-đ Dialog |
-đŧī¸ Visual
+đŧī¸ Visual |
+đī¸ CPlans
diff --git a/examples/cdp_mode/ReadMe.md b/examples/cdp_mode/ReadMe.md
index 601254a1630..b2f4b6d990f 100644
--- a/examples/cdp_mode/ReadMe.md
+++ b/examples/cdp_mode/ReadMe.md
@@ -620,63 +620,77 @@ sb.driver.stop()
### đ CDP Mode Async API / Methods
+Initialization:
+
+```python
+from seleniumbase import cdp_driver
+
+driver = await cdp_driver.start_async()
+tab = await driver.get(url, **kwargs)
+```
+
+Methods: (Sometimes `tab` is named `page` in examples)
+
```python
-await get(url="about:blank")
-await open(url="about:blank")
-await find(text, best_match=False, timeout=10) # `text` can be a selector
-await find_all(text, timeout=10) # `text` can be a selector
-await select(selector, timeout=10)
-await select_all(selector, timeout=10, include_frames=False)
-await query_selector(selector)
-await query_selector_all(selector)
-await find_element_by_text(text, best_match=False)
-await find_elements_by_text(text)
-await reload(ignore_cache=True, script_to_evaluate_on_load=None)
-await evaluate(expression)
-await js_dumps(obj_name)
-await back()
-await forward()
-await get_window()
-await get_content()
-await maximize()
-await minimize()
-await fullscreen()
-await medimize()
-await set_window_size(left=0, top=0, width=1280, height=1024)
-await set_window_rect(left=0, top=0, width=1280, height=1024)
-await activate()
-await bring_to_front()
-await set_window_state(left=0, top=0, width=1280, height=720, state="normal")
-await get_navigation_history()
-await open_external_inspector() # Open a separate browser for debugging
-await close()
-await scroll_down(amount=25)
-await scroll_up(amount=25)
-await wait_for(selector="", text="", timeout=10)
-await download_file(url, filename=None)
-await save_screenshot(filename="auto", format="png", full_page=False)
-await print_to_pdf(filename="auto")
-await set_download_path(path)
-await get_all_linked_sources()
-await get_all_urls(absolute=True)
-await get_html()
-await get_page_source()
-await is_element_present(selector)
-await is_element_visible(selector)
-await get_element_rect(selector, timeout=5) # (relative to window)
-await get_window_rect()
-await get_gui_element_rect(selector, timeout=5) # (relative to screen)
-await get_title()
-await send_keys(selector, text, timeout=5)
-await type(selector, text, timeout=5)
-await click(selector, timeout=5)
-await click_with_offset(selector, x, y, center=False, timeout=5)
-await solve_captcha()
-await click_captcha() # Same as solve_captcha()
-await get_document()
-await get_flattened_document()
-await get_local_storage()
-await set_local_storage(items)
+await tab.get(url="about:blank")
+await tab.open(url="about:blank")
+await tab.find(text, best_match=False, timeout=10) # text can be selector
+await tab.find_all(text, timeout=10) # text can be selector
+await tab.select(selector, timeout=10)
+await tab.select_all(selector, timeout=10, include_frames=False)
+await tab.query_selector(selector)
+await tab.query_selector_all(selector)
+await tab.find_element_by_text(text, best_match=False)
+await tab.find_elements_by_text(text)
+await tab.reload(ignore_cache=True, script_to_evaluate_on_load=None)
+await tab.evaluate(expression)
+await tab.js_dumps(obj_name)
+await tab.back()
+await tab.forward()
+await tab.get_window()
+await tab.get_content()
+await tab.maximize()
+await tab.minimize()
+await tab.fullscreen()
+await tab.medimize()
+await tab.set_window_size(left=0, top=0, width=1280, height=1024)
+await tab.set_window_rect(left=0, top=0, width=1280, height=1024)
+await tab.activate()
+await tab.bring_to_front()
+await tab.set_window_state(
+ left=0, top=0, width=1280, height=720, state="normal")
+await tab.get_navigation_history()
+await tab.open_external_inspector() # Open separate browser for debugging
+await tab.close()
+await tab.scroll_down(amount=25)
+await tab.scroll_up(amount=25)
+await tab.wait_for(selector="", text="", timeout=10)
+await tab.download_file(url, filename=None)
+await tab.save_screenshot(
+ filename="auto", format="png", full_page=False)
+await tab.print_to_pdf(filename="auto")
+await tab.set_download_path(path)
+await tab.get_all_linked_sources()
+await tab.get_all_urls(absolute=True)
+await tab.get_html()
+await tab.get_page_source()
+await tab.is_element_present(selector)
+await tab.is_element_visible(selector)
+await tab.get_element_rect(selector, timeout=5) # (window-based)
+await tab.get_window_rect()
+await tab.get_gui_element_rect(selector, timeout=5) # (screen-based)
+await tab.get_title()
+await tab.get_current_url()
+await tab.send_keys(selector, text, timeout=5)
+await tab.type(selector, text, timeout=5)
+await tab.click(selector, timeout=5)
+await tab.click_with_offset(selector, x, y, center=False, timeout=5)
+await tab.solve_captcha()
+await tab.click_captcha() # Same as solve_captcha()
+await tab.get_document()
+await tab.get_flattened_document()
+await tab.get_local_storage()
+await tab.set_local_storage(items)
```
--------
diff --git a/help_docs/ReadMe.md b/help_docs/ReadMe.md
index be492e5b389..bea3acf8d6d 100644
--- a/help_docs/ReadMe.md
+++ b/help_docs/ReadMe.md
@@ -35,6 +35,8 @@
đ´ Recorder |
đģ Device Farm
+đ Stealthy Playwright Mode
+
đī¸ Slides |
đļ Chart Maker
diff --git a/help_docs/cdp_mode_methods.md b/help_docs/cdp_mode_methods.md
index 8fba1e994d6..741391aeb14 100644
--- a/help_docs/cdp_mode_methods.md
+++ b/help_docs/cdp_mode_methods.md
@@ -258,63 +258,77 @@ sb.driver.stop()
### đ CDP Mode Async API / Methods
+Initialization:
+
+```python
+from seleniumbase import cdp_driver
+
+driver = await cdp_driver.start_async()
+tab = await driver.get(url, **kwargs)
+```
+
+Methods: (Sometimes `tab` is named `page` in examples)
+
```python
-await get(url="about:blank")
-await open(url="about:blank")
-await find(text, best_match=False, timeout=10) # `text` can be a selector
-await find_all(text, timeout=10) # `text` can be a selector
-await select(selector, timeout=10)
-await select_all(selector, timeout=10, include_frames=False)
-await query_selector(selector)
-await query_selector_all(selector)
-await find_element_by_text(text, best_match=False)
-await find_elements_by_text(text)
-await reload(ignore_cache=True, script_to_evaluate_on_load=None)
-await evaluate(expression)
-await js_dumps(obj_name)
-await back()
-await forward()
-await get_window()
-await get_content()
-await maximize()
-await minimize()
-await fullscreen()
-await medimize()
-await set_window_size(left=0, top=0, width=1280, height=1024)
-await set_window_rect(left=0, top=0, width=1280, height=1024)
-await activate()
-await bring_to_front()
-await set_window_state(left=0, top=0, width=1280, height=720, state="normal")
-await get_navigation_history()
-await open_external_inspector() # Open a separate browser for debugging
-await close()
-await scroll_down(amount=25)
-await scroll_up(amount=25)
-await wait_for(selector="", text="", timeout=10)
-await download_file(url, filename=None)
-await save_screenshot(filename="auto", format="png", full_page=False)
-await print_to_pdf(filename="auto")
-await set_download_path(path)
-await get_all_linked_sources()
-await get_all_urls(absolute=True)
-await get_html()
-await get_page_source()
-await is_element_present(selector)
-await is_element_visible(selector)
-await get_element_rect(selector, timeout=5) # (relative to window)
-await get_window_rect()
-await get_gui_element_rect(selector, timeout=5) # (relative to screen)
-await get_title()
-await send_keys(selector, text, timeout=5)
-await type(selector, text, timeout=5)
-await click(selector, timeout=5)
-await click_with_offset(selector, x, y, center=False, timeout=5)
-await solve_captcha()
-await click_captcha() # Same as solve_captcha()
-await get_document()
-await get_flattened_document()
-await get_local_storage()
-await set_local_storage(items)
+await tab.get(url="about:blank")
+await tab.open(url="about:blank")
+await tab.find(text, best_match=False, timeout=10) # text can be selector
+await tab.find_all(text, timeout=10) # text can be selector
+await tab.select(selector, timeout=10)
+await tab.select_all(selector, timeout=10, include_frames=False)
+await tab.query_selector(selector)
+await tab.query_selector_all(selector)
+await tab.find_element_by_text(text, best_match=False)
+await tab.find_elements_by_text(text)
+await tab.reload(ignore_cache=True, script_to_evaluate_on_load=None)
+await tab.evaluate(expression)
+await tab.js_dumps(obj_name)
+await tab.back()
+await tab.forward()
+await tab.get_window()
+await tab.get_content()
+await tab.maximize()
+await tab.minimize()
+await tab.fullscreen()
+await tab.medimize()
+await tab.set_window_size(left=0, top=0, width=1280, height=1024)
+await tab.set_window_rect(left=0, top=0, width=1280, height=1024)
+await tab.activate()
+await tab.bring_to_front()
+await tab.set_window_state(
+ left=0, top=0, width=1280, height=720, state="normal")
+await tab.get_navigation_history()
+await tab.open_external_inspector() # Open separate browser for debugging
+await tab.close()
+await tab.scroll_down(amount=25)
+await tab.scroll_up(amount=25)
+await tab.wait_for(selector="", text="", timeout=10)
+await tab.download_file(url, filename=None)
+await tab.save_screenshot(
+ filename="auto", format="png", full_page=False)
+await tab.print_to_pdf(filename="auto")
+await tab.set_download_path(path)
+await tab.get_all_linked_sources()
+await tab.get_all_urls(absolute=True)
+await tab.get_html()
+await tab.get_page_source()
+await tab.is_element_present(selector)
+await tab.is_element_visible(selector)
+await tab.get_element_rect(selector, timeout=5) # (window-based)
+await tab.get_window_rect()
+await tab.get_gui_element_rect(selector, timeout=5) # (screen-based)
+await tab.get_title()
+await tab.get_current_url()
+await tab.send_keys(selector, text, timeout=5)
+await tab.type(selector, text, timeout=5)
+await tab.click(selector, timeout=5)
+await tab.click_with_offset(selector, x, y, center=False, timeout=5)
+await tab.solve_captcha()
+await tab.click_captcha() # Same as solve_captcha()
+await tab.get_document()
+await tab.get_flattened_document()
+await tab.get_local_storage()
+await tab.set_local_storage(items)
```
--------
diff --git a/help_docs/js_package_manager.md b/help_docs/js_package_manager.md
index eeade9efb5e..f58773dc5d4 100644
--- a/help_docs/js_package_manager.md
+++ b/help_docs/js_package_manager.md
@@ -53,7 +53,7 @@ self.add_js_link(js_link)
đšī¸ This example loads the
IntroJS JavaScript library:
```python
-self.add_js_link("https://cdnjs.cloudflare.com/ajax/libs/intro.js/2.9.3/intro.min.js")
+self.add_js_link("https://cdn.jsdelivr.net/npm/intro.js@5.1.0/intro.min.js")
```
đšī¸ You can load any JS package this way as long as you know the URL.
@@ -133,8 +133,6 @@ pytest test_dialog_boxes.py
-[
](https://github.com/seleniumbase/SeleniumBase/)
-
To learn more about SeleniumBase, check out the Docs Site:
From c934bea10a5dfd3b0f8dc713c2598e30b08c1d0f Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Mon, 8 Dec 2025 23:03:01 -0500
Subject: [PATCH 5/6] Refresh coverage
---
requirements.txt | 2 +-
setup.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/requirements.txt b/requirements.txt
index 4c692cdfffc..60227ffd1f3 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -76,7 +76,7 @@ rich>=14.2.0,<15
# ("pip install -r requirements.txt" also installs this, but "pip install -e ." won't.)
coverage>=7.10.7;python_version<"3.10"
-coverage>=7.12.0;python_version>="3.10"
+coverage>=7.13.0;python_version>="3.10"
pytest-cov>=7.0.0
flake8==7.3.0
mccabe==0.7.0
diff --git a/setup.py b/setup.py
index 85cd8e79776..1b6ec808fb4 100755
--- a/setup.py
+++ b/setup.py
@@ -233,7 +233,7 @@
# Usage: coverage run -m pytest; coverage html; coverage report
"coverage": [
'coverage>=7.10.7;python_version<"3.10"',
- 'coverage>=7.12.0;python_version>="3.10"',
+ 'coverage>=7.13.0;python_version>="3.10"',
'pytest-cov>=7.0.0',
],
# pip install -e .[flake8]
From 5752ebb23355e90b38d4ce92e58c275c30a31ed7 Mon Sep 17 00:00:00 2001
From: Michael Mintz
Date: Mon, 8 Dec 2025 23:03:17 -0500
Subject: [PATCH 6/6] Version 4.45.1
---
seleniumbase/__version__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py
index 0a8dac81b9b..505895bdc30 100755
--- a/seleniumbase/__version__.py
+++ b/seleniumbase/__version__.py
@@ -1,2 +1,2 @@
# seleniumbase package
-__version__ = "4.45.0"
+__version__ = "4.45.1"