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 + """