diff --git a/examples/cdp_mode/raw_async.py b/examples/cdp_mode/raw_async.py
index 88d0e6d5acd..183864d5eee 100644
--- a/examples/cdp_mode/raw_async.py
+++ b/examples/cdp_mode/raw_async.py
@@ -16,6 +16,7 @@ async def main():
time.sleep(1)
await element.send_keys_async("Boston")
time.sleep(2)
+ driver.stop()
if __name__ == "__main__":
# Call an async function with awaited methods
@@ -39,6 +40,7 @@ async def main():
time.sleep(2)
print(loop.run_until_complete(page.evaluate("document.title")))
time.sleep(1)
+ driver.stop()
# Call CDP methods via the simplified SB CDP API
sb = sb_cdp.Chrome("https://www.priceline.com/")
@@ -62,3 +64,4 @@ async def main():
cards = sb.select_all('span[data-automation*="product-list-card"]')
for card in cards:
print("* %s" % card.text)
+ sb.driver.stop()
diff --git a/examples/cdp_mode/raw_cdp.py b/examples/cdp_mode/raw_cdp.py
index 2c21f3c13d6..b3e18b98a45 100644
--- a/examples/cdp_mode/raw_cdp.py
+++ b/examples/cdp_mode/raw_cdp.py
@@ -30,6 +30,7 @@ def main():
cards = sb.select_all('span[data-automation*="product-list-card"]')
for card in cards:
print("* %s" % card.text)
+ sb.driver.stop()
if __name__ == "__main__":
diff --git a/examples/cdp_mode/raw_cdp_extended.py b/examples/cdp_mode/raw_cdp_extended.py
index ef3ec48abb7..e696cb39bee 100644
--- a/examples/cdp_mode/raw_cdp_extended.py
+++ b/examples/cdp_mode/raw_cdp_extended.py
@@ -21,3 +21,4 @@
sb.gui_drag_and_drop("img#logo", "div#drop2")
sb.nested_click("iframe#myFrame3", ".fBox")
sb.sleep(2)
+sb.driver.stop()
diff --git a/examples/cdp_mode/raw_cdp_nike.py b/examples/cdp_mode/raw_cdp_nike.py
index 8bf3b3ed934..2f19a88f2f8 100644
--- a/examples/cdp_mode/raw_cdp_nike.py
+++ b/examples/cdp_mode/raw_cdp_nike.py
@@ -12,3 +12,4 @@
print('**** Found results for "%s": ****' % search)
for element in elements:
print("* " + element.text)
+sb.driver.stop()
diff --git a/examples/cdp_mode/raw_cookies_async.py b/examples/cdp_mode/raw_cookies_async.py
index aaa01ebb0ee..e581feb5b18 100644
--- a/examples/cdp_mode/raw_cookies_async.py
+++ b/examples/cdp_mode/raw_cookies_async.py
@@ -16,7 +16,7 @@ async def get_login_cookies():
element = await page.select('input[type="submit"]')
await element.click_async()
cookies = await driver.cookies.get_all()
- await page.close()
+ driver.stop()
return cookies
@@ -30,6 +30,7 @@ async def login_with_cookies(cookies):
await driver.get(url_2)
await page.select("div.inventory_list")
time.sleep(2)
+ driver.stop()
if __name__ == "__main__":
diff --git a/examples/cdp_mode/raw_geolocation.py b/examples/cdp_mode/raw_geolocation.py
index 43a34fca3c9..3f4a087d7d1 100644
--- a/examples/cdp_mode/raw_geolocation.py
+++ b/examples/cdp_mode/raw_geolocation.py
@@ -11,6 +11,7 @@ def main():
sb.click('a[aria-label="Show My Location"]')
sb.assert_url_contains("48.876450/2.263400")
sb.sleep(5)
+ sb.driver.stop()
if __name__ == "__main__":
diff --git a/examples/cdp_mode/raw_multi_async.py b/examples/cdp_mode/raw_multi_async.py
index afaf3238f7e..e0a8817b091 100644
--- a/examples/cdp_mode/raw_multi_async.py
+++ b/examples/cdp_mode/raw_multi_async.py
@@ -15,6 +15,7 @@ async def main(url):
button = await page.select("button")
await button.click_async()
await page.sleep(2)
+ driver.stop()
def set_up_loop(url):
diff --git a/examples/cdp_mode/raw_proxy.py b/examples/cdp_mode/raw_proxy.py
index 6503b47974f..1e3cb562fa8 100644
--- a/examples/cdp_mode/raw_proxy.py
+++ b/examples/cdp_mode/raw_proxy.py
@@ -44,6 +44,7 @@ def main():
data.append(row.strip())
print("\n".join(data).replace('\n"', ' "'))
sb.sleep(3)
+ sb.driver.stop()
if __name__ == "__main__":
diff --git a/examples/cdp_mode/raw_req_async.py b/examples/cdp_mode/raw_req_async.py
index 663c93d4339..ba1c4b69298 100644
--- a/examples/cdp_mode/raw_req_async.py
+++ b/examples/cdp_mode/raw_req_async.py
@@ -36,6 +36,7 @@ async def start_test(self):
url = "https://gettyimages.com/photos/firefly-2003-nathan"
await driver.get(url)
await asyncio.sleep(5)
+ driver.stop()
@decorators.print_runtime("RequestPausedTest")
diff --git a/examples/cdp_mode/raw_timezone.py b/examples/cdp_mode/raw_timezone.py
index 7f269040b66..d2dd5a46a6e 100644
--- a/examples/cdp_mode/raw_timezone.py
+++ b/examples/cdp_mode/raw_timezone.py
@@ -28,6 +28,7 @@ def main():
sb.remove_elements("#right-sidebar")
sb.remove_elements('[id*="Footer"]')
sb.sleep(6)
+ sb.driver.stop()
if __name__ == "__main__":
diff --git a/help_docs/syntax_formats.md b/help_docs/syntax_formats.md
index 7e5e7ed2b81..fa1b39fb637 100644
--- a/help_docs/syntax_formats.md
+++ b/help_docs/syntax_formats.md
@@ -1033,6 +1033,7 @@ async def main():
time.sleep(1)
await element.send_keys_async("Boston")
time.sleep(2)
+ driver.stop()
if __name__ == "__main__":
loop = asyncio.new_event_loop()
@@ -1075,6 +1076,7 @@ def main():
cards = sb.select_all('span[data-automation*="product-list-card"]')
for card in cards:
print("* %s" % card.text)
+ sb.driver.stop()
if __name__ == "__main__":
diff --git a/requirements.txt b/requirements.txt
index f104aedf4e8..ab5a00ba0ee 100755
--- a/requirements.txt
+++ b/requirements.txt
@@ -45,7 +45,7 @@ trio-websocket==0.12.2
wsproto==1.2.0
websocket-client==1.8.0
selenium==4.27.1;python_version<"3.9"
-selenium==4.32.0;python_version>="3.9"
+selenium==4.33.0;python_version>="3.9"
cssselect==1.2.0;python_version<"3.9"
cssselect==1.3.0;python_version>="3.9"
sortedcontainers==2.4.0
@@ -74,7 +74,7 @@ rich>=14.0.0,<15
# ("pip install -r requirements.txt" also installs this, but "pip install -e ." won't.)
coverage>=7.6.1;python_version<"3.9"
-coverage>=7.8.1;python_version>="3.9"
+coverage>=7.8.2;python_version>="3.9"
pytest-cov>=5.0.0;python_version<"3.9"
pytest-cov>=6.1.1;python_version>="3.9"
flake8==5.0.4;python_version<"3.9"
diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py
index 608255c7e2a..5173bc46dcb 100755
--- a/seleniumbase/__version__.py
+++ b/seleniumbase/__version__.py
@@ -1,2 +1,2 @@
# seleniumbase package
-__version__ = "4.38.3"
+__version__ = "4.39.0"
diff --git a/seleniumbase/behave/behave_sb.py b/seleniumbase/behave/behave_sb.py
index ac7bd6001d3..71931e81701 100644
--- a/seleniumbase/behave/behave_sb.py
+++ b/seleniumbase/behave/behave_sb.py
@@ -1280,15 +1280,9 @@ def _perform_behave_unconfigure_():
)
find_it_3 = '
Untested | '
swap_with_3 = 'Unreported | '
- if sys.version_info[0] >= 3:
- # These use caching to prevent extra method calls
- DASH_PIE_PNG_1 = constants.Dashboard.get_dash_pie_1()
- DASH_PIE_PNG_2 = constants.Dashboard.get_dash_pie_2()
- else:
- from seleniumbase.core import encoded_images
-
- DASH_PIE_PNG_1 = encoded_images.get_dash_pie_png1()
- DASH_PIE_PNG_2 = encoded_images.get_dash_pie_png2()
+ # These use caching to prevent extra method calls
+ DASH_PIE_PNG_1 = constants.Dashboard.get_dash_pie_1()
+ DASH_PIE_PNG_2 = constants.Dashboard.get_dash_pie_2()
find_it_4 = 'href="%s"' % DASH_PIE_PNG_1
swap_with_4 = 'href="%s"' % DASH_PIE_PNG_2
try:
diff --git a/seleniumbase/console_scripts/run.py b/seleniumbase/console_scripts/run.py
index 962a7ad5c03..b11305d9846 100644
--- a/seleniumbase/console_scripts/run.py
+++ b/seleniumbase/console_scripts/run.py
@@ -1001,7 +1001,6 @@ def main():
retry_msg_2 = "** Unable to download driver! Retrying in 5s..."
if " --proxy=" in " ".join(sys.argv):
from seleniumbase.core import proxy_helper
-
for arg in sys.argv:
if arg.startswith("--proxy="):
proxy_string = arg.split("--proxy=")[1]
@@ -1036,11 +1035,9 @@ def main():
show_install_usage()
elif command == "commander" or command == "gui":
from seleniumbase.console_scripts import sb_commander
-
sb_commander.main()
elif command == "behave-gui" or command == "gui-behave":
from seleniumbase.console_scripts import sb_behave_gui
-
sb_behave_gui.main()
elif (
command == "caseplans"
@@ -1048,14 +1045,12 @@ def main():
or command == "case_plans"
):
from seleniumbase.console_scripts import sb_caseplans
-
sb_caseplans.main()
elif (
command == "recorder"
or (command == "record" and len(command_args) == 0)
):
from seleniumbase.console_scripts import sb_recorder
-
sb_recorder.main()
elif (
command == "mkrec"
@@ -1064,7 +1059,6 @@ def main():
):
if len(command_args) >= 1:
from seleniumbase.console_scripts import sb_mkrec
-
sb_mkrec.main()
else:
show_basic_usage()
@@ -1075,7 +1069,6 @@ def main():
elif command == "mkdir":
if len(command_args) >= 1:
from seleniumbase.console_scripts import sb_mkdir
-
sb_mkdir.main()
else:
show_basic_usage()
@@ -1083,7 +1076,6 @@ def main():
elif command == "mkfile":
if len(command_args) >= 1:
from seleniumbase.console_scripts import sb_mkfile
-
sb_mkfile.main()
else:
show_basic_usage()
@@ -1091,7 +1083,6 @@ def main():
elif command == "mkpres":
if len(command_args) >= 1:
from seleniumbase.console_scripts import sb_mkpres
-
sb_mkpres.main()
else:
show_basic_usage()
@@ -1099,7 +1090,6 @@ def main():
elif command == "mkchart":
if len(command_args) >= 1:
from seleniumbase.console_scripts import sb_mkchart
-
sb_mkchart.main()
else:
show_basic_usage()
@@ -1107,7 +1097,6 @@ def main():
elif command == "convert":
if len(command_args) == 1:
from seleniumbase.utilities.selenium_ide import convert_ide
-
convert_ide.main()
else:
show_basic_usage()
@@ -1115,22 +1104,13 @@ def main():
elif command == "print":
if len(command_args) >= 1:
from seleniumbase.console_scripts import sb_print
-
sb_print.main()
else:
show_basic_usage()
show_print_usage()
elif command == "translate":
if len(command_args) >= 1:
- if sys.version_info[0] == 2:
- c5 = colorama.Fore.RED + colorama.Back.LIGHTYELLOW_EX
- cr = colorama.Style.RESET_ALL
- msg = "The SeleniumBase Translator does NOT support Python 2!"
- message = "\n" + c5 + msg + cr + "\n"
- print("")
- raise Exception(message)
from seleniumbase.translate import translator
-
translator.main()
else:
show_basic_usage()
@@ -1138,7 +1118,6 @@ def main():
elif command == "extract-objects" or command == "extract_objects":
if len(command_args) >= 1:
from seleniumbase.console_scripts import sb_objectify
-
sb_objectify.extract_objects()
else:
show_basic_usage()
@@ -1154,7 +1133,6 @@ def main():
elif command == "objectify":
if len(command_args) >= 1:
from seleniumbase.console_scripts import sb_objectify
-
sb_objectify.objectify()
else:
show_basic_usage()
@@ -1162,7 +1140,6 @@ def main():
elif command == "revert-objects" or command == "revert_objects":
if len(command_args) >= 1:
from seleniumbase.console_scripts import sb_objectify
-
sb_objectify.revert_objects()
else:
show_basic_usage()
@@ -1170,7 +1147,6 @@ def main():
elif command == "encrypt" or command == "obfuscate":
if len(command_args) >= 0:
from seleniumbase.common import obfuscate
-
obfuscate.main()
else:
show_basic_usage()
@@ -1178,7 +1154,6 @@ def main():
elif command == "decrypt" or command == "unobfuscate":
if len(command_args) >= 0:
from seleniumbase.common import unobfuscate
-
unobfuscate.main()
else:
show_basic_usage()
@@ -1188,7 +1163,6 @@ def main():
from seleniumbase.utilities.selenium_grid import (
download_selenium_server,
)
-
download_selenium_server.main(force_download=True)
else:
show_basic_usage()
@@ -1196,7 +1170,6 @@ def main():
elif command == "grid-hub" or command == "grid_hub":
if len(command_args) >= 1:
from seleniumbase.utilities.selenium_grid import grid_hub
-
grid_hub.main()
else:
show_basic_usage()
@@ -1204,7 +1177,6 @@ def main():
elif command == "grid-node" or command == "grid_node":
if len(command_args) >= 1:
from seleniumbase.utilities.selenium_grid import grid_node
-
grid_node.main()
else:
show_basic_usage()
@@ -1212,7 +1184,6 @@ def main():
elif command == "version" or command == "--version" or command == "-v":
if len(command_args) == 0:
from seleniumbase.console_scripts import logo_helper
-
seleniumbase_logo = logo_helper.get_seleniumbase_logo()
print(seleniumbase_logo)
print("")
@@ -1231,7 +1202,6 @@ def main():
import fasteners
import os
import warnings
-
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=UserWarning)
pip_find_lock = fasteners.InterProcessLock(
diff --git a/seleniumbase/console_scripts/sb_behave_gui.py b/seleniumbase/console_scripts/sb_behave_gui.py
index 66c14caf04b..fbdbfd0e993 100644
--- a/seleniumbase/console_scripts/sb_behave_gui.py
+++ b/seleniumbase/console_scripts/sb_behave_gui.py
@@ -20,13 +20,6 @@
from seleniumbase.fixtures import shared_utils
from tkinter.scrolledtext import ScrolledText
-if sys.version_info <= (3, 8):
- current_version = ".".join(str(ver) for ver in sys.version_info[:3])
- raise Exception(
- "\n* SBase Commander requires Python 3.8 or newer!"
- "\n** You are currently using Python %s" % current_version
- )
-
def set_colors(use_colors):
c0 = ""
diff --git a/seleniumbase/console_scripts/sb_caseplans.py b/seleniumbase/console_scripts/sb_caseplans.py
index 9cc8a62a95e..f3b6229ab88 100644
--- a/seleniumbase/console_scripts/sb_caseplans.py
+++ b/seleniumbase/console_scripts/sb_caseplans.py
@@ -25,13 +25,6 @@
from tkinter import messagebox
from tkinter.scrolledtext import ScrolledText
-if sys.version_info <= (3, 8):
- current_version = ".".join(str(ver) for ver in sys.version_info[:3])
- raise Exception(
- "\n* SBase Case Plans Generator requires Python 3.8 or newer!"
- "\n** You are currently using Python %s" % current_version
- )
-
def set_colors(use_colors):
c0 = ""
diff --git a/seleniumbase/console_scripts/sb_commander.py b/seleniumbase/console_scripts/sb_commander.py
index 0ea306327b1..b0cd67978c6 100644
--- a/seleniumbase/console_scripts/sb_commander.py
+++ b/seleniumbase/console_scripts/sb_commander.py
@@ -25,13 +25,6 @@
from seleniumbase.fixtures import shared_utils
from tkinter.scrolledtext import ScrolledText
-if sys.version_info <= (3, 8):
- current_version = ".".join(str(ver) for ver in sys.version_info[:3])
- raise Exception(
- "\n* SBase Commander requires Python 3.8 or newer!"
- "\n** You are currently using Python %s" % current_version
- )
-
def set_colors(use_colors):
c0 = ""
diff --git a/seleniumbase/console_scripts/sb_recorder.py b/seleniumbase/console_scripts/sb_recorder.py
index a4507daaf98..d6a326913ab 100644
--- a/seleniumbase/console_scripts/sb_recorder.py
+++ b/seleniumbase/console_scripts/sb_recorder.py
@@ -30,12 +30,6 @@
sys_executable = sys.executable
if " " in sys_executable:
sys_executable = "python"
-if sys.version_info <= (3, 8):
- current_version = ".".join(str(ver) for ver in sys.version_info[:3])
- raise Exception(
- "\n* Recorder Desktop requires Python 3.8 or newer!"
- "\n*** You are currently using Python %s" % current_version
- )
def set_colors(use_colors):
diff --git a/seleniumbase/core/mysql.py b/seleniumbase/core/mysql.py
index a1bf47ddc84..88d91f65f0f 100644
--- a/seleniumbase/core/mysql.py
+++ b/seleniumbase/core/mysql.py
@@ -19,8 +19,8 @@ def __init__(self, database_env="test", conf_creds=None):
constants.PipInstall.FINDLOCK
)
with pip_find_lock:
- if sys.version_info >= (3, 7) and sys.version_info < (3, 9):
- # Fix bug in newer cryptography for Python 3.7 and 3.8:
+ if sys.version_info < (3, 9):
+ # Fix bug with newer cryptography on Python 3.8:
# "pyo3_runtime.PanicException: Python API call failed"
# (Match the version needed for pdfminer.six functions)
try:
diff --git a/seleniumbase/core/style_sheet.py b/seleniumbase/core/style_sheet.py
index 8414ae62f8a..ca8d78e314f 100644
--- a/seleniumbase/core/style_sheet.py
+++ b/seleniumbase/core/style_sheet.py
@@ -1,4 +1,3 @@
-import sys
import textwrap
from seleniumbase.fixtures import constants
@@ -11,18 +10,12 @@ class Saved:
def get_report_style():
if hasattr(Saved, "report_style"):
return Saved.report_style
- if sys.version_info[0] >= 3:
- # Uses caching to prevent extra method calls
- REPORT_FAVICON = constants.Report.get_favicon()
- else:
- from seleniumbase.core import encoded_images
-
- REPORT_FAVICON = encoded_images.get_report_favicon()
+ # Uses caching to prevent extra method calls
+ REPORT_FAVICON = constants.Report.get_favicon()
title = """
Test Report
""" % REPORT_FAVICON
-
style = (
title
+ """