From 0038e56a023408ac4abbb21c9f30d1d38a694923 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 21 Oct 2025 15:47:32 -0400 Subject: [PATCH 1/3] Prevent deprecation warnings on Python 3.14 --- mkdocs_build/prepare.py | 3 +- seleniumbase/behave/behave_sb.py | 5 +- seleniumbase/console_scripts/sb_caseplans.py | 5 +- seleniumbase/console_scripts/sb_mkchart.py | 3 +- seleniumbase/console_scripts/sb_mkdir.py | 43 +++++++++-------- seleniumbase/console_scripts/sb_mkfile.py | 3 +- seleniumbase/console_scripts/sb_mkpres.py | 3 +- seleniumbase/console_scripts/sb_mkrec.py | 3 +- seleniumbase/console_scripts/sb_objectify.py | 5 +- seleniumbase/core/browser_launcher.py | 4 +- seleniumbase/core/log_helper.py | 7 ++- seleniumbase/core/report_helper.py | 3 +- seleniumbase/core/sb_cdp.py | 3 +- seleniumbase/core/tour_helper.py | 3 +- seleniumbase/fixtures/base_case.py | 47 +++++++++---------- seleniumbase/fixtures/page_actions.py | 3 +- seleniumbase/fixtures/page_utils.py | 5 +- seleniumbase/plugins/basic_test_info.py | 5 +- seleniumbase/plugins/page_source.py | 5 +- seleniumbase/plugins/pytest_plugin.py | 5 +- seleniumbase/translate/translator.py | 3 +- .../undetected/cdp_driver/connection.py | 2 - .../utilities/selenium_grid/grid_hub.py | 3 +- .../utilities/selenium_grid/grid_node.py | 5 +- .../utilities/selenium_ide/convert_ide.py | 3 +- 25 files changed, 76 insertions(+), 103 deletions(-) diff --git a/mkdocs_build/prepare.py b/mkdocs_build/prepare.py index 2c796d634ba..e2a000fe5c6 100644 --- a/mkdocs_build/prepare.py +++ b/mkdocs_build/prepare.py @@ -1,6 +1,5 @@ """ For preparing the mkdocs-generated seleniumbase.io website. """ -import codecs import os import re from pathlib import Path @@ -196,6 +195,6 @@ def main(*args, **kwargs): ) seleniumbase_lines.append(line) if changed: - out_file = codecs.open(readme_file, "w+", encoding="utf-8") + out_file = open(readme_file, "w+", encoding="utf-8") out_file.writelines("\r\n".join(seleniumbase_lines)) out_file.close() diff --git a/seleniumbase/behave/behave_sb.py b/seleniumbase/behave/behave_sb.py index 8d6a42d3f3a..cc447014fc2 100644 --- a/seleniumbase/behave/behave_sb.py +++ b/seleniumbase/behave/behave_sb.py @@ -1205,7 +1205,6 @@ def dashboard_pre_processing(): def _create_dashboard_assets_(): - import codecs from seleniumbase.js_code.live_js import live_js from seleniumbase.core.style_sheet import get_pytest_style @@ -1222,7 +1221,7 @@ def _create_dashboard_assets_(): if existing_pytest_style == get_pytest_style(): add_pytest_style_css = False if add_pytest_style_css: - out_file = codecs.open(pytest_style_css, "w+", encoding="utf-8") + out_file = open(pytest_style_css, "w+", encoding="utf-8") out_file.writelines(get_pytest_style()) out_file.close() live_js_file = os.path.join(assets_folder, "live.js") @@ -1234,7 +1233,7 @@ def _create_dashboard_assets_(): if existing_live_js == live_js: add_live_js_file = False if add_live_js_file: - out_file = codecs.open(live_js_file, "w+", encoding="utf-8") + out_file = open(live_js_file, "w+", encoding="utf-8") out_file.writelines(live_js) out_file.close() diff --git a/seleniumbase/console_scripts/sb_caseplans.py b/seleniumbase/console_scripts/sb_caseplans.py index f3b6229ab88..56d7ff3882d 100644 --- a/seleniumbase/console_scripts/sb_caseplans.py +++ b/seleniumbase/console_scripts/sb_caseplans.py @@ -15,7 +15,6 @@ Output: Launches the SeleniumBase Case Plans Generator. """ -import codecs import colorama import os import subprocess @@ -135,7 +134,7 @@ def generate_case_plan_boilerplates( file_name = case_id file_path = os.path.join(full_folder_path, file_name) if not os.path.exists(file_path): - out_file = codecs.open(file_path, "w+", "utf-8") + out_file = open(file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() new_plans += 1 @@ -316,7 +315,7 @@ def view_summary_of_existing_case_plans(root, tests): full_plan = plan_head file_path = "case_summary.md" - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(full_plan)) file.close() diff --git a/seleniumbase/console_scripts/sb_mkchart.py b/seleniumbase/console_scripts/sb_mkchart.py index d8af20f1b24..d6ab0e9bd67 100644 --- a/seleniumbase/console_scripts/sb_mkchart.py +++ b/seleniumbase/console_scripts/sb_mkchart.py @@ -22,7 +22,6 @@ and use a "sky" theme with "slide" transition. The chart can be used as a basic boilerplate. """ -import codecs import colorama import os import sys @@ -254,7 +253,7 @@ def main(): continue new_data.append(line) data = new_data - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() if " " not in file_name: diff --git a/seleniumbase/console_scripts/sb_mkdir.py b/seleniumbase/console_scripts/sb_mkdir.py index 83fc045dc0f..10810ddd60e 100644 --- a/seleniumbase/console_scripts/sb_mkdir.py +++ b/seleniumbase/console_scripts/sb_mkdir.py @@ -18,7 +18,6 @@ and Python boilerplates for setting up customized test frameworks. """ -import codecs import colorama import os import sys @@ -114,7 +113,7 @@ def main(): data.append(seleniumbase_req) data.append("") file_path = "%s/%s" % (dir_name, "requirements.txt") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -152,7 +151,7 @@ def main(): data.append(" production: custom marker") data.append("") file_path = "%s/%s" % (dir_name, "pytest.ini") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -169,14 +168,14 @@ def main(): data.append("show_skipped=false") data.append("show_timings=false") file_path = "%s/%s" % (dir_name, "setup.cfg") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() data = [] data.append("") file_path = "%s/%s" % (dir_name, "__init__.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -312,7 +311,7 @@ def main(): data.append("temp_*/") data.append("node_modules") file_path = "%s/%s" % (dir_name, ".gitignore") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -324,7 +323,7 @@ def main(): data.append(" ├── requirements.txt") data.append(" └── setup.cfg") file_path = "%s/%s" % (dir_name, "outline.rst") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() os.system("sbase print %s -n" % file_path) @@ -368,7 +367,7 @@ def main(): data.append(' self.assert_element("div#login_button_container")') data.append("") file_path = "%s/%s" % (dir_name, "my_first_test.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -461,7 +460,7 @@ def main(): data.append(' self.assert_text("SeleniumBase", "h2")') data.append("") file_path = "%s/%s" % (dir_name, "test_demo_site.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -500,7 +499,7 @@ def main(): data.append(' self.assert_title_contains(title_text)') data.append("") file_path = "%s/%s" % (dir_name, "parameterized_test.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -510,7 +509,7 @@ def main(): data = [] data.append("") file_path = "%s/%s" % (dir_name_2, "__init__.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -545,7 +544,7 @@ def main(): data.append(" pass") data.append("") file_path = "%s/%s" % (dir_name_2, "base_test_case.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -554,7 +553,7 @@ def main(): data.append(' html = "html"') data.append("") file_path = "%s/%s" % (dir_name_2, "page_objects.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -570,7 +569,7 @@ def main(): data.append(" self.assert_element(Page.html)") data.append("") file_path = "%s/%s" % (dir_name_2, "boilerplate_test.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -594,7 +593,7 @@ def main(): data.append(' DataPage().add_input_text(self, "Goodbye!")') data.append("") file_path = "%s/%s" % (dir_name_2, "classic_obj_test.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -614,7 +613,7 @@ def main(): data.append(' DataPage().add_input_text(sb, "Goodbye!")') data.append("") file_path = "%s/%s" % (dir_name_2, "sb_fixture_test.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -624,7 +623,7 @@ def main(): data = [] data.append("") file_path = "%s/%s" % (dir_name_3, "__init__.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -652,7 +651,7 @@ def main(): ) data.append("") file_path = "%s/%s" % (dir_name_3, "google_test.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -670,7 +669,7 @@ def main(): data.append(' search_results = "div#center_col"') data.append("") file_path = "%s/%s" % (dir_name_3, "google_objects.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -702,7 +701,7 @@ def main(): data.append(' self.assert_element("div#login_button_container")') data.append("") file_path = "%s/%s" % (dir_name_3, "swag_labs_test.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -729,7 +728,7 @@ def main(): data.append(' sb.assert_element("div#login_button_container")') data.append("") file_path = "%s/%s" % (dir_name_3, "sb_swag_test.py") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() @@ -756,7 +755,7 @@ def main(): data.append(" ├── sb_swag_test.py") data.append(" └── swag_labs_test.py") file_path = "%s/%s" % (dir_name, "outline.rst") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() if " " not in file_path: diff --git a/seleniumbase/console_scripts/sb_mkfile.py b/seleniumbase/console_scripts/sb_mkfile.py index c2e235fff96..370139f5f6c 100644 --- a/seleniumbase/console_scripts/sb_mkfile.py +++ b/seleniumbase/console_scripts/sb_mkfile.py @@ -40,7 +40,6 @@ BaseCase format supports Languages or Recorder Mode. UC Mode automatically uses English with SB() format. """ -import codecs import colorama import os import sys @@ -413,7 +412,7 @@ def main(): continue new_data.append(line) data = new_data - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() if " " not in file_name: diff --git a/seleniumbase/console_scripts/sb_mkpres.py b/seleniumbase/console_scripts/sb_mkpres.py index 235bbfb0c96..fc00b0f1080 100644 --- a/seleniumbase/console_scripts/sb_mkpres.py +++ b/seleniumbase/console_scripts/sb_mkpres.py @@ -22,7 +22,6 @@ and use "serif" theme with "slide" transition. The slides can be used as a basic boilerplate. """ -import codecs import colorama import os import sys @@ -273,7 +272,7 @@ def main(): continue new_data.append(line) data = new_data - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() if " " not in file_name: diff --git a/seleniumbase/console_scripts/sb_mkrec.py b/seleniumbase/console_scripts/sb_mkrec.py index 7f72eb7fde7..ad29f4c378a 100644 --- a/seleniumbase/console_scripts/sb_mkrec.py +++ b/seleniumbase/console_scripts/sb_mkrec.py @@ -29,7 +29,6 @@ Creates a new SeleniumBase test using the Recorder. If the filename already exists, an error is raised. """ -import codecs import colorama import shutil import os @@ -240,7 +239,7 @@ def main(): d2.append("") data = d2 - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() success = ( diff --git a/seleniumbase/console_scripts/sb_objectify.py b/seleniumbase/console_scripts/sb_objectify.py index 0a3e880d7c9..0eb2be0e116 100644 --- a/seleniumbase/console_scripts/sb_objectify.py +++ b/seleniumbase/console_scripts/sb_objectify.py @@ -8,7 +8,6 @@ have been replaced with variable names defined in "page_objects.py", supporting the Page Object Pattern. """ -import codecs import os import re import sys @@ -136,7 +135,7 @@ def create_objects_file(selector_list_dict=None): data.append(' html = "html"') data.append("") file_path = PAGE_OBJECTS_FILE - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() if not selector_list_dict: @@ -3189,7 +3188,7 @@ def main(shell_command): # Create SeleniumBase test file base_file_name = seleniumbase_file.split(".py")[0] converted_file_name = base_file_name + ".py" # Change end to make a copy - out_file = codecs.open(converted_file_name, "w+", encoding="utf-8") + out_file = open(converted_file_name, "w+", encoding="utf-8") out_file.writelines(seleniumbase_code) out_file.close() print('\n>>> ["%s"] was updated!\n' % converted_file_name) diff --git a/seleniumbase/core/browser_launcher.py b/seleniumbase/core/browser_launcher.py index 2d5db1b88db..d17438f5e51 100644 --- a/seleniumbase/core/browser_launcher.py +++ b/seleniumbase/core/browser_launcher.py @@ -2006,14 +2006,12 @@ def _repair_edgedriver(edge_version): def _mark_driver_repaired(): - import codecs - abs_path = os.path.abspath(".") driver_repaired_lock = constants.MultiBrowser.DRIVER_REPAIRED file_path = os.path.join(abs_path, driver_repaired_lock) if not os.path.exists(DOWNLOADS_FOLDER): os.makedirs(DOWNLOADS_FOLDER) - out_file = codecs.open(file_path, "w+", encoding="utf-8") + out_file = open(file_path, "w+", encoding="utf-8") out_file.writelines("") out_file.close() diff --git a/seleniumbase/core/log_helper.py b/seleniumbase/core/log_helper.py index 2ba1c3d47ef..e03a47ee307 100644 --- a/seleniumbase/core/log_helper.py +++ b/seleniumbase/core/log_helper.py @@ -1,4 +1,3 @@ -import codecs import os import shutil import sys @@ -298,7 +297,7 @@ def log_test_failure_data(test, test_logpath, driver, browser, url=None): with suppress(Exception): os.makedirs(test_logpath) with suppress(Exception): - log_file = codecs.open(basic_file_path, "w+", encoding="utf-8") + log_file = open(basic_file_path, "w+", encoding="utf-8") log_file.writelines("\r\n".join(data_to_save)) log_file.close() shared_utils.make_writable(basic_file_path) @@ -353,7 +352,7 @@ def log_skipped_test_data(test, test_logpath, driver, browser, reason): data_to_save.append("") file_path = os.path.join(test_logpath, "skip_reason.txt") with suppress(Exception): - log_file = codecs.open(file_path, "w+", encoding="utf-8") + log_file = open(file_path, "w+", encoding="utf-8") log_file.writelines("\r\n".join(data_to_save)) log_file.close() shared_utils.make_writable(file_path) @@ -388,7 +387,7 @@ def log_page_source(test_logpath, driver, source=None): os.makedirs(test_logpath) html_file_path = os.path.join(test_logpath, html_file_name) with suppress(Exception): - html_file = codecs.open(html_file_path, "w+", encoding="utf-8") + html_file = open(html_file_path, "w+", encoding="utf-8") html_file.write(page_source) html_file.close() shared_utils.make_writable(html_file_path) diff --git a/seleniumbase/core/report_helper.py b/seleniumbase/core/report_helper.py index 649f398a9c7..99bbeffda8d 100644 --- a/seleniumbase/core/report_helper.py +++ b/seleniumbase/core/report_helper.py @@ -1,4 +1,3 @@ -import codecs import os import shutil import sys @@ -48,7 +47,7 @@ def save_test_failure_data(test, name, folder=None): failure_data_file_path = os.path.join(file_path, name) else: failure_data_file_path = name - failure_data_file = codecs.open(failure_data_file_path, "w+", "utf-8") + failure_data_file = open(failure_data_file_path, "w+", "utf-8") data_to_save = [] if not hasattr(sb_config, "_report_test_id"): exc_message = "(Unknown Exception)" diff --git a/seleniumbase/core/sb_cdp.py b/seleniumbase/core/sb_cdp.py index 80755b5b5c8..2979060f906 100644 --- a/seleniumbase/core/sb_cdp.py +++ b/seleniumbase/core/sb_cdp.py @@ -2669,7 +2669,6 @@ def scroll_down(self, amount=25): self.loop.run_until_complete(self.page.wait()) def save_page_source(self, name, folder=None): - import codecs from seleniumbase.core import log_helper if not name.endswith(".html"): name = name + ".html" @@ -2695,7 +2694,7 @@ def save_page_source(self, name, folder=None): rendered_source = "%s\n%s" % (base_href_html, page_source) else: rendered_source = page_source - html_file = codecs.open(html_file_path, "w+", "utf-8") + html_file = open(html_file_path, "w+", "utf-8") html_file.write(rendered_source) html_file.close() diff --git a/seleniumbase/core/tour_helper.py b/seleniumbase/core/tour_helper.py index 54ca484705b..d4b96eaf352 100644 --- a/seleniumbase/core/tour_helper.py +++ b/seleniumbase/core/tour_helper.py @@ -1134,10 +1134,9 @@ def export_tour(tour_steps, name=None, filename="my_tour.js", url=None): os.makedirs(exported_tours_folder) except Exception: pass - import codecs file_path = exported_tours_folder + "/" + filename - out_file = codecs.open(file_path, "w+", encoding="utf-8") + out_file = open(file_path, "w+", encoding="utf-8") out_file.writelines(instructions) out_file.close() print("\n>>> [%s] was saved!\n" % file_path) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index a75ee6e0a01..fac0ff6cf4d 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -32,7 +32,6 @@ def test_anything(self): Page elements are given enough time to load before WebDriver acts on them. Code becomes greatly simplified and easier to maintain.""" -import codecs import colorama import fasteners import json @@ -4683,7 +4682,7 @@ def save_cookies(self, name="cookies.txt"): if not os.path.exists(file_path): os.makedirs(file_path) cookies_file_path = os.path.join(file_path, name) - cookies_file = codecs.open(cookies_file_path, "w+", encoding="utf-8") + cookies_file = open(cookies_file_path, "w+", encoding="utf-8") cookies_file.writelines(json_cookies) cookies_file.close() @@ -5737,7 +5736,7 @@ def __process_recorded_actions(self): extra_file_name = "__init__.py" extra_file_path = os.path.join(recordings_folder, extra_file_name) if not os.path.exists(extra_file_path): - out_file = codecs.open(extra_file_path, "w+", "utf-8") + out_file = open(extra_file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() sys.stdout.write("\nCreated recordings%s__init__.py" % os.sep) @@ -5785,7 +5784,7 @@ def __process_recorded_actions(self): extra_file_name = "pytest.ini" extra_file_path = os.path.join(recordings_folder, extra_file_name) if not os.path.exists(extra_file_path): - out_file = codecs.open(extra_file_path, "w+", "utf-8") + out_file = open(extra_file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() sys.stdout.write("\nCreated recordings%spytest.ini" % os.sep) @@ -5806,7 +5805,7 @@ def __process_recorded_actions(self): extra_file_name = "setup.cfg" extra_file_path = os.path.join(recordings_folder, extra_file_name) if not os.path.exists(extra_file_path): - out_file = codecs.open(extra_file_path, "w+", "utf-8") + out_file = open(extra_file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() sys.stdout.write("\nCreated recordings%ssetup.cfg" % os.sep) @@ -5824,7 +5823,7 @@ def __process_recorded_actions(self): elif context_filename: file_name = context_filename file_path = os.path.join(recordings_folder, file_name) - out_file = codecs.open(file_path, "w+", "utf-8") + out_file = open(file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() rec_message = ">>> RECORDING SAVED as: " @@ -5926,7 +5925,7 @@ def __process_recorded_behave_actions(self, srt_actions, colorama): file_name = sb_config.behave_scenario.filename.replace(".", "_") file_name = file_name.split("/")[-1].split("\\")[-1] + "_rec.feature" file_path = os.path.join(features_folder, file_name) - out_file = codecs.open(file_path, "w+", "utf-8") + out_file = open(file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() @@ -5964,7 +5963,7 @@ def __process_recorded_behave_actions(self, srt_actions, colorama): file_name = "__init__.py" file_path = os.path.join(features_folder, file_name) if not os.path.exists(file_path): - out_file = codecs.open(file_path, "w+", "utf-8") + out_file = open(file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() print("Created recordings/features/__init__.py") @@ -5977,7 +5976,7 @@ def __process_recorded_behave_actions(self, srt_actions, colorama): file_name = "behave.ini" file_path = os.path.join(features_folder, file_name) if not os.path.exists(file_path): - out_file = codecs.open(file_path, "w+", "utf-8") + out_file = open(file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() print("Created recordings/features/behave.ini") @@ -6016,7 +6015,7 @@ def __process_recorded_behave_actions(self, srt_actions, colorama): file_name = "environment.py" file_path = os.path.join(features_folder, file_name) if not os.path.exists(file_path): - out_file = codecs.open(file_path, "w+", "utf-8") + out_file = open(file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() print("Created recordings/features/environment.py") @@ -6026,7 +6025,7 @@ def __process_recorded_behave_actions(self, srt_actions, colorama): file_name = "__init__.py" file_path = os.path.join(steps_folder, file_name) if not os.path.exists(file_path): - out_file = codecs.open(file_path, "w+", "utf-8") + out_file = open(file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() print("Created recordings/features/steps/__init__.py") @@ -6037,7 +6036,7 @@ def __process_recorded_behave_actions(self, srt_actions, colorama): file_name = "imported.py" file_path = os.path.join(steps_folder, file_name) if not os.path.exists(file_path): - out_file = codecs.open(file_path, "w+", "utf-8") + out_file = open(file_path, "w+", "utf-8") out_file.writelines("\r\n".join(data)) out_file.close() print("Created recordings/features/steps/imported.py") @@ -11078,7 +11077,7 @@ def __process_visual_baseline_logs(self): return # Skip the rest when deferred visual asserts are used the_html = visual_helper.get_sbs_html() file_path = os.path.join(test_logpath, constants.SideBySide.HTML_FILE) - out_file = codecs.open(file_path, "w+", encoding="utf-8") + out_file = open(file_path, "w+", encoding="utf-8") out_file.writelines(the_html) out_file.close() @@ -11238,16 +11237,16 @@ def check_window( self.save_screenshot( baseline_png, visual_baseline_path, selector="body" ) - out_file = codecs.open(page_url_file, "w+", encoding="utf-8") + out_file = open(page_url_file, "w+", encoding="utf-8") out_file.writelines(page_url) out_file.close() - out_file = codecs.open(level_1_file, "w+", encoding="utf-8") + out_file = open(level_1_file, "w+", encoding="utf-8") out_file.writelines(json.dumps(level_1)) out_file.close() - out_file = codecs.open(level_2_file, "w+", encoding="utf-8") + out_file = open(level_2_file, "w+", encoding="utf-8") out_file.writelines(json.dumps(level_2)) out_file.close() - out_file = codecs.open(level_3_file, "w+", encoding="utf-8") + out_file = open(level_3_file, "w+", encoding="utf-8") out_file.writelines(json.dumps(level_3)) out_file.close() @@ -11386,7 +11385,7 @@ def check_window( alpha_n_d_name = "".join([x if x.isalnum() else "_" for x in name]) side_by_side_name = "side_by_side_%s.html" % alpha_n_d_name file_path = os.path.join(test_logpath, side_by_side_name) - out_file = codecs.open(file_path, "w+", encoding="utf-8") + out_file = open(file_path, "w+", encoding="utf-8") out_file.writelines(the_html) out_file.close() @@ -12071,7 +12070,7 @@ def save_presentation( with suppress(Exception): os.makedirs(saved_presentations_folder) file_path = os.path.join(saved_presentations_folder, filename) - out_file = codecs.open(file_path, "w+", encoding="utf-8") + out_file = open(file_path, "w+", encoding="utf-8") out_file.writelines(the_html) out_file.close() if self._output_file_saves: @@ -12766,7 +12765,7 @@ def save_chart(self, chart_name=None, filename=None, folder=None): with suppress(Exception): os.makedirs(saved_charts_folder) file_path = os.path.join(saved_charts_folder, filename) - out_file = codecs.open(file_path, "w+", encoding="utf-8") + out_file = open(file_path, "w+", encoding="utf-8") out_file.writelines(the_html) out_file.close() if self._output_file_saves: @@ -16048,7 +16047,7 @@ def __get_test_id(self): test_id = test_id.replace(".py::", ".").replace("::", ".") test_id = test_id.replace("/", ".").replace("\\", ".") test_id = test_id.replace(" ", "_") - # Linux filename length limit for `codecs.open(filename)` = 255 + # Linux filename length limit for `open(filename)` = 255 # 255 - len("latest_logs/") - len("/basic_test_info.txt") = 223 if len(test_id) <= 223: return test_id @@ -16326,7 +16325,7 @@ def __process_dashboard(self, has_exception, init=False): dash_pie = json.dumps(sb_config._saved_dashboard_pie) dash_pie_loc = constants.Dashboard.DASH_PIE pie_path = os.path.join(abs_path, dash_pie_loc) - pie_file = codecs.open(pie_path, "w+", encoding="utf-8") + pie_file = open(pie_path, "w+", encoding="utf-8") pie_file.writelines(dash_pie) pie_file.close() DASH_PIE_PNG_1 = constants.Dashboard.get_dash_pie_1() @@ -16486,7 +16485,7 @@ def __process_dashboard(self, has_exception, init=False): ) abs_path = os.path.abspath(".") file_path = os.path.join(abs_path, "dashboard.html") - out_file = codecs.open(file_path, "w+", encoding="utf-8") + out_file = open(file_path, "w+", encoding="utf-8") out_file.writelines(the_html) out_file.close() sb_config._dash_html = the_html @@ -16499,7 +16498,7 @@ def __process_dashboard(self, has_exception, init=False): dash_json = json.dumps((_results, _display_id, _rt, _tlp, d_stats)) dash_json_loc = constants.Dashboard.DASH_JSON dash_jsonpath = os.path.join(abs_path, dash_json_loc) - dash_json_file = codecs.open(dash_jsonpath, "w+", encoding="utf-8") + dash_json_file = open(dash_jsonpath, "w+", encoding="utf-8") dash_json_file.writelines(dash_json) dash_json_file.close() diff --git a/seleniumbase/fixtures/page_actions.py b/seleniumbase/fixtures/page_actions.py index fd51e22ec68..373d5d6571b 100644 --- a/seleniumbase/fixtures/page_actions.py +++ b/seleniumbase/fixtures/page_actions.py @@ -17,7 +17,6 @@ By.TAG_NAME # "tag name" By.PARTIAL_LINK_TEXT # "partial link text" """ -import codecs import os import time from contextlib import suppress @@ -1531,7 +1530,7 @@ def save_page_source(driver, name, folder=None): rendered_source = log_helper.get_html_source_with_base_href( driver, page_source ) - html_file = codecs.open(html_file_path, "w+", "utf-8") + html_file = open(html_file_path, "w+", "utf-8") html_file.write(rendered_source) html_file.close() diff --git a/seleniumbase/fixtures/page_utils.py b/seleniumbase/fixtures/page_utils.py index 04348bfc284..7d93aa277d1 100644 --- a/seleniumbase/fixtures/page_utils.py +++ b/seleniumbase/fixtures/page_utils.py @@ -1,5 +1,4 @@ """This module contains useful utility methods""" -import codecs import fasteners import os import re @@ -314,7 +313,7 @@ def _save_data_as(data, destination_folder, file_name): constants.MultiBrowser.FILE_IO_LOCK ) with file_io_lock: - out_file = codecs.open( + out_file = open( os.path.join(destination_folder, file_name), "w+", encoding="utf-8" ) out_file.writelines(data) @@ -332,7 +331,7 @@ def _append_data_to_file(data, destination_folder, file_name): existing_data = f.read() if not existing_data.split("\n")[-1] == "": existing_data += "\n" - out_file = codecs.open( + out_file = open( os.path.join(destination_folder, file_name), "w+", encoding="utf-8" ) out_file.writelines("%s%s" % (existing_data, data)) diff --git a/seleniumbase/plugins/basic_test_info.py b/seleniumbase/plugins/basic_test_info.py index 851317eba1b..f5f5f6a9068 100644 --- a/seleniumbase/plugins/basic_test_info.py +++ b/seleniumbase/plugins/basic_test_info.py @@ -1,6 +1,5 @@ """Test Info Plugin for SeleniumBase tests that run with pynose / nosetests""" import os -import codecs import time import traceback from nose.plugins import Plugin @@ -26,7 +25,7 @@ def addError(self, test, err, capt=None): if not os.path.exists(test_logpath): os.makedirs(test_logpath) file_name = "%s/%s" % (test_logpath, self.logfile_name) - basic_info_file = codecs.open(file_name, "w+", "utf-8") + basic_info_file = open(file_name, "w+", "utf-8") self.__log_test_error_data(basic_info_file, test, err, "Error") basic_info_file.close() @@ -35,7 +34,7 @@ def addFailure(self, test, err, capt=None, tbinfo=None): if not os.path.exists(test_logpath): os.makedirs(test_logpath) file_name = "%s/%s" % (test_logpath, self.logfile_name) - basic_info_file = codecs.open(file_name, "w+", "utf-8") + basic_info_file = open(file_name, "w+", "utf-8") self.__log_test_error_data(basic_info_file, test, err, "Error") basic_info_file.close() diff --git a/seleniumbase/plugins/page_source.py b/seleniumbase/plugins/page_source.py index 6e8b7d75122..e22af22cd60 100644 --- a/seleniumbase/plugins/page_source.py +++ b/seleniumbase/plugins/page_source.py @@ -1,6 +1,5 @@ """PageSource Plugin for SeleniumBase tests that run with pynose / nosetests""" import os -import codecs from nose.plugins import Plugin from seleniumbase.config import settings from seleniumbase.core import log_helper @@ -29,7 +28,7 @@ def addError(self, test, err, capt=None): if not os.path.exists(test_logpath): os.makedirs(test_logpath) html_file_name = os.path.join(test_logpath, self.logfile_name) - html_file = codecs.open(html_file_name, "w+", "utf-8") + html_file = open(html_file_name, "w+", "utf-8") rendered_source = log_helper.get_html_source_with_base_href( test.driver, page_source ) @@ -45,7 +44,7 @@ def addFailure(self, test, err, capt=None, tbinfo=None): if not os.path.exists(test_logpath): os.makedirs(test_logpath) html_file_name = os.path.join(test_logpath, self.logfile_name) - html_file = codecs.open(html_file_name, "w+", "utf-8") + html_file = open(html_file_name, "w+", "utf-8") rendered_source = log_helper.get_html_source_with_base_href( test.driver, page_source ) diff --git a/seleniumbase/plugins/pytest_plugin.py b/seleniumbase/plugins/pytest_plugin.py index 708b7ac3efe..e905f88b2f1 100644 --- a/seleniumbase/plugins/pytest_plugin.py +++ b/seleniumbase/plugins/pytest_plugin.py @@ -1898,7 +1898,6 @@ def _get_test_ids_(the_item): def _create_dashboard_assets_(): - import codecs from seleniumbase.js_code.live_js import live_js from seleniumbase.core.style_sheet import get_pytest_style @@ -1916,7 +1915,7 @@ def _create_dashboard_assets_(): if existing_pytest_style == get_pytest_style(): add_pytest_style_css = False if add_pytest_style_css: - out_file = codecs.open(pytest_style_css, "w+", encoding="utf-8") + out_file = open(pytest_style_css, "w+", encoding="utf-8") out_file.writelines(get_pytest_style()) out_file.close() live_js_file = os.path.join(assets_folder, "live.js") @@ -1928,7 +1927,7 @@ def _create_dashboard_assets_(): if existing_live_js == live_js: add_live_js_file = False if add_live_js_file: - out_file = codecs.open(live_js_file, "w+", encoding="utf-8") + out_file = open(live_js_file, "w+", encoding="utf-8") out_file.writelines(live_js) out_file.close() diff --git a/seleniumbase/translate/translator.py b/seleniumbase/translate/translator.py index 6ca497d56c0..26242a5922f 100644 --- a/seleniumbase/translate/translator.py +++ b/seleniumbase/translate/translator.py @@ -27,7 +27,6 @@ (Example: Translating "test_1.py" into Japanese with "-c" will create a new file called "test_1_ja.py".) """ -import codecs import colorama import os import re @@ -1043,7 +1042,7 @@ def main(): pass # Print-only run already done if new_file_name: - out_file = codecs.open(new_file_name, "w+", encoding="utf-8") + out_file = open(new_file_name, "w+", encoding="utf-8") out_file.writelines("\r\n".join(seleniumbase_lines)) out_file.close() results_saved = ( diff --git a/seleniumbase/undetected/cdp_driver/connection.py b/seleniumbase/undetected/cdp_driver/connection.py index 392b337d19a..869c8bd768e 100644 --- a/seleniumbase/undetected/cdp_driver/connection.py +++ b/seleniumbase/undetected/cdp_driver/connection.py @@ -520,8 +520,6 @@ async def _register_handlers(self): except BaseException: logger.debug("NOT GOOD", exc_info=True) continue - finally: - continue for ed in enabled_domains: # Items still present at this point are unused and need removal. self.enabled_domains.remove(ed) diff --git a/seleniumbase/utilities/selenium_grid/grid_hub.py b/seleniumbase/utilities/selenium_grid/grid_hub.py index 27be503cec9..f8ee03dd4bd 100644 --- a/seleniumbase/utilities/selenium_grid/grid_hub.py +++ b/seleniumbase/utilities/selenium_grid/grid_hub.py @@ -1,4 +1,3 @@ -import codecs import os import subprocess import sys @@ -78,7 +77,7 @@ def main(): data = [] data.append(verbose) file_path = os.path.join(dir_path, "verbose_hub_server.dat") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() diff --git a/seleniumbase/utilities/selenium_grid/grid_node.py b/seleniumbase/utilities/selenium_grid/grid_node.py index a973b312d41..a3fc06e141c 100644 --- a/seleniumbase/utilities/selenium_grid/grid_node.py +++ b/seleniumbase/utilities/selenium_grid/grid_node.py @@ -1,4 +1,3 @@ -import codecs import os import subprocess import sys @@ -88,14 +87,14 @@ def main(): data = [] data.append(server_ip) file_path = os.path.join(dir_path, "ip_of_grid_hub.dat") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() data = [] data.append(verbose) file_path = os.path.join(dir_path, "verbose_node_server.dat") - file = codecs.open(file_path, "w+", "utf-8") + file = open(file_path, "w+", "utf-8") file.writelines("\r\n".join(data)) file.close() diff --git a/seleniumbase/utilities/selenium_ide/convert_ide.py b/seleniumbase/utilities/selenium_ide/convert_ide.py index 566585573c6..4241a39540e 100644 --- a/seleniumbase/utilities/selenium_ide/convert_ide.py +++ b/seleniumbase/utilities/selenium_ide/convert_ide.py @@ -8,7 +8,6 @@ Output: [NEW_FILE_SB].py (adds "_SB" to the original file name) (the original file is kept intact)""" -import codecs import re import sys from seleniumbase.fixtures import js_utils @@ -894,7 +893,7 @@ def main(): # Create SeleniumBase test file base_file_name = webdriver_python_file.split(".py")[0] converted_file_name = base_file_name + "_SB.py" - out_file = codecs.open(converted_file_name, "w+", encoding="utf-8") + out_file = open(converted_file_name, "w+", encoding="utf-8") out_file.writelines(seleniumbase_code) out_file.close() print( From 2972cc6df42e8b99c1043d8138b5c97b4c2f6dd6 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 21 Oct 2025 15:48:09 -0400 Subject: [PATCH 2/3] Refresh Python dependencies --- mkdocs_build/requirements.txt | 2 +- requirements.txt | 3 ++- setup.py | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mkdocs_build/requirements.txt b/mkdocs_build/requirements.txt index 327886dd1d0..03b41036faa 100644 --- a/mkdocs_build/requirements.txt +++ b/mkdocs_build/requirements.txt @@ -1,7 +1,7 @@ # mkdocs dependencies for generating the seleniumbase.io website # Minimum Python version: 3.10 (for generating docs only) -regex>=2025.9.18 +regex>=2025.10.23 pymdown-extensions>=10.16.1 pipdeptree>=2.29.0 python-dateutil>=2.8.2 diff --git a/requirements.txt b/requirements.txt index 80a446ecd49..a2c52fc2523 100755 --- a/requirements.txt +++ b/requirements.txt @@ -57,7 +57,8 @@ cssselect==1.2.0;python_version<"3.9" cssselect==1.3.0;python_version>="3.9" sortedcontainers==2.4.0 execnet==2.1.1 -iniconfig==2.1.0 +iniconfig==2.1.0;python_version<"3.10" +iniconfig==2.3.0;python_version>="3.10" pluggy==1.5.0;python_version<"3.9" pluggy==1.6.0;python_version>="3.9" pytest==8.3.5;python_version<"3.9" diff --git a/setup.py b/setup.py index 5bafac5dfdc..10361168738 100755 --- a/setup.py +++ b/setup.py @@ -204,7 +204,8 @@ 'cssselect==1.3.0;python_version>="3.9"', "sortedcontainers==2.4.0", 'execnet==2.1.1', - 'iniconfig==2.1.0', + 'iniconfig==2.1.0;python_version<"3.10"', + 'iniconfig==2.3.0;python_version>="3.10"', 'pluggy==1.5.0;python_version<"3.9"', 'pluggy==1.6.0;python_version>="3.9"', 'pytest==8.3.5;python_version<"3.9"', From 36dee33754a69d338d131034d1865533fa2e9610 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Tue, 21 Oct 2025 15:48:32 -0400 Subject: [PATCH 3/3] Version 4.43.1 --- seleniumbase/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index ae8ed88c79c..5116ba8828f 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.43.0" +__version__ = "4.43.1"