From 424dcdea696fed831ca8cbcd5f2ea671e0a1a9bb Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sat, 13 Sep 2025 14:37:33 -0400 Subject: [PATCH 1/5] Prevent odd warnings when getting PDF text --- seleniumbase/fixtures/base_case.py | 1 + 1 file changed, 1 insertion(+) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 639f9c06f91..e7be91a7e0d 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -7245,6 +7245,7 @@ def get_pdf_text( page_search = [page] else: page_search = None + logging.getLogger("pdfminer").setLevel(logging.ERROR) pdf_text = extract_text( file_path, password="", From e2e0695fd5ef241622136afdd049d983c21decdf Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sat, 13 Sep 2025 14:39:10 -0400 Subject: [PATCH 2/5] Add `sb.print_to_pdf()` --- help_docs/method_summary.md | 1 + seleniumbase/fixtures/base_case.py | 41 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/help_docs/method_summary.md b/help_docs/method_summary.md index dab3ac3989b..9b87ace0c4c 100644 --- a/help_docs/method_summary.md +++ b/help_docs/method_summary.md @@ -341,6 +341,7 @@ self.save_file_as(file_url, new_file_name, destination_folder=None) self.save_data_as(data, file_name, destination_folder=None) self.append_data_to_file(data, file_name, destination_folder=None) self.get_file_data(file_name, folder=None) +self.print_to_pdf(name, folder=None) self.get_downloads_folder() self.get_browser_downloads_folder() self.get_downloaded_files(regex=None, browser=False) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index e7be91a7e0d..38a41e03b64 100644 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -7553,6 +7553,47 @@ def get_file_data(self, file_name, folder=None): folder = constants.Files.DOWNLOADS_FOLDER return page_utils._get_file_data(folder, file_name) + def print_to_pdf(self, name, folder=None): + """Saves the current page as a PDF. + If no folder is specified, uses the folder where pytest was called. + If the folder provided doesn't exist, it will get created. + @Params + name - The name to give the PDF file. Must end in ".pdf". + folder - The directory where you want to save the PDF.""" + import base64 + from selenium.webdriver.common.print_page_options import PrintOptions + + if not name.lower().endswith(".pdf"): + raise Exception('PDF name {%s} must end in ".pdf"!)' % name) + download_file_lock = fasteners.InterProcessLock( + constants.MultiBrowser.DOWNLOAD_FILE_LOCK + ) + if self.__is_cdp_swap_needed(): + with download_file_lock: + with suppress(Exception): + shared_utils.make_writable( + constants.MultiBrowser.DOWNLOAD_FILE_LOCK + ) + if folder and not os.path.exists(folder): + os.makedirs(folder) + self.cdp.print_to_pdf(name, folder) + return + self.wait_for_ready_state_complete() + print_options = PrintOptions() + pdf_base64 = self.driver.print_page(print_options) + with download_file_lock: + with suppress(Exception): + shared_utils.make_writable( + constants.MultiBrowser.DOWNLOAD_FILE_LOCK + ) + if folder and not os.path.exists(folder): + os.makedirs(folder) + filename = name + if folder: + filename = os.path.join(folder, name) + with open(filename, "wb") as f: + f.write(base64.b64decode(pdf_base64)) + def get_downloads_folder(self): """Returns the path of the SeleniumBase "downloaded_files/" folder. Calling self.download_file(file_url) will put that file in here. From 6a043d819d28bd2873d3ae8784259665c4684404 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sat, 13 Sep 2025 14:39:48 -0400 Subject: [PATCH 3/5] Update an example that prints to a PDF --- examples/cdp_mode/raw_print_to_pdf.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/examples/cdp_mode/raw_print_to_pdf.py b/examples/cdp_mode/raw_print_to_pdf.py index 80054d379e1..de1a3ffe238 100644 --- a/examples/cdp_mode/raw_print_to_pdf.py +++ b/examples/cdp_mode/raw_print_to_pdf.py @@ -1,12 +1,10 @@ -import base64 from seleniumbase import SB -from selenium.webdriver.common.print_page_options import PrintOptions -with SB(uc=True, test=True, ad_block=True) as sb: +with SB(uc=True, test=True, pls="none") as sb: url = "https://seleniumbase.io" sb.activate_cdp_mode(url) - sb.reconnect() # To access WebDriver methods - print_options = PrintOptions() - pdf_base64 = sb.driver.print_page(print_options) - with open("downloaded_files/sb.pdf", "wb") as f: - f.write(base64.b64decode(pdf_base64)) + sb.assert_title("SeleniumBase Docs") + file_path = "downloaded_files/sb.pdf" + sb.print_to_pdf(file_path) + sb.assert_downloaded_file("sb.pdf") + sb.assert_pdf_text(file_path, "SeleniumBase") From ccbc0a2d807fc7e0cf886f1be11a670355a03b9b Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sat, 13 Sep 2025 14:40:24 -0400 Subject: [PATCH 4/5] Refresh Python dependencies --- requirements.txt | 12 ++++++------ setup.py | 18 ++++++++++-------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/requirements.txt b/requirements.txt index 2b2be344182..d22444aecfb 100755 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ filelock~=3.16.1;python_version<"3.9" filelock>=3.19.1;python_version>="3.9" fasteners>=0.20 mycdp>=1.2.0 -pynose>=1.5.4 +pynose>=1.5.5 platformdirs>=4.3.6;python_version<"3.9" platformdirs>=4.4.0;python_version>="3.9" typing-extensions>=4.13.2 @@ -36,15 +36,15 @@ charset-normalizer>=3.4.3,<4 urllib3>=1.26.20,<2;python_version<"3.10" urllib3>=1.26.20,<2.6.0;python_version>="3.10" requests==2.32.4;python_version<"3.9" -requests>=2.32.5,<2.33;python_version>="3.9" +requests~=2.32.5;python_version>="3.9" sniffio==1.3.1 h11==0.16.0 outcome==1.3.0.post0 trio==0.27.0;python_version<"3.9" -trio==0.30.0;python_version>="3.9" -trio-websocket==0.12.2 +trio~=0.30.0;python_version>="3.9" +trio-websocket~=0.12.2 wsproto==1.2.0 -websocket-client==1.8.0 +websocket-client~=1.8.0 selenium==4.27.1;python_version<"3.9" selenium==4.32.0;python_version>="3.9" and python_version<"3.10" selenium==4.35.0;python_version>="3.10" @@ -82,7 +82,7 @@ rich>=14.1.0,<15 coverage>=7.6.1;python_version<"3.9" coverage>=7.10.6;python_version>="3.9" pytest-cov>=5.0.0;python_version<"3.9" -pytest-cov>=6.3.0;python_version>="3.9" +pytest-cov>=7.0.0;python_version>="3.9" flake8==5.0.4;python_version<"3.9" flake8==7.3.0;python_version>="3.9" mccabe==0.7.0 diff --git a/setup.py b/setup.py index 56fdd06b0dd..c6459f2d693 100755 --- a/setup.py +++ b/setup.py @@ -161,7 +161,7 @@ 'filelock>=3.19.1;python_version>="3.9"', 'fasteners>=0.20', "mycdp>=1.2.0", - "pynose>=1.5.4", + "pynose>=1.5.5", 'platformdirs>=4.3.6;python_version<"3.9"', 'platformdirs>=4.4.0;python_version>="3.9"', 'typing-extensions>=4.13.2', @@ -184,15 +184,15 @@ 'urllib3>=1.26.20,<2;python_version<"3.10"', 'urllib3>=1.26.20,<2.6.0;python_version>="3.10"', 'requests==2.32.4;python_version<"3.9"', - 'requests>=2.32.5,<2.33;python_version>="3.9"', + 'requests~=2.32.5;python_version>="3.9"', 'sniffio==1.3.1', 'h11==0.16.0', 'outcome==1.3.0.post0', 'trio==0.27.0;python_version<"3.9"', - 'trio==0.30.0;python_version>="3.9"', - 'trio-websocket==0.12.2', + 'trio~=0.30.0;python_version>="3.9"', + 'trio-websocket~=0.12.2', 'wsproto==1.2.0', - 'websocket-client==1.8.0', + 'websocket-client~=1.8.0', 'selenium==4.27.1;python_version<"3.9"', 'selenium==4.32.0;python_version>="3.9" and python_version<"3.10"', 'selenium==4.35.0;python_version>="3.10"', @@ -239,7 +239,7 @@ 'coverage>=7.6.1;python_version<"3.9"', 'coverage>=7.10.6;python_version>="3.9"', 'pytest-cov>=5.0.0;python_version<"3.9"', - 'pytest-cov>=6.3.0;python_version>="3.9"', + 'pytest-cov>=7.0.0;python_version>="3.9"', ], # pip install -e .[flake8] # Usage: flake8 @@ -271,8 +271,10 @@ 'pdfminer.six==20250506;python_version>="3.9"', 'cryptography==39.0.2;python_version<"3.9"', 'cryptography==45.0.7;python_version>="3.9"', - 'cffi==1.17.1', - "pycparser==2.22", + 'cffi==1.17.1;python_version<"3.9"', + 'cffi==2.0.0;python_version>="3.9"', + 'pycparser==2.22;python_version<"3.9"', + 'pycparser==2.23;python_version>="3.9"', ], # pip install -e .[pillow] # (An optional library for image-processing.) From bb3c3fa9846a42e540dc4f43e2a060abd8abacd7 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Sat, 13 Sep 2025 14:40:40 -0400 Subject: [PATCH 5/5] Version 4.41.6 --- seleniumbase/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index 2ff1cf02805..5dd828fa63e 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "4.41.5" +__version__ = "4.41.6"