seleniumbase 4.41.5__tar.gz → 4.41.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {seleniumbase-4.41.5/seleniumbase.egg-info → seleniumbase-4.41.7}/PKG-INFO +49 -22
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/README.md +36 -11
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/requirements.txt +6 -6
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/sbase/steps.py +9 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/behave/behave_helper.py +2 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/browser_launcher.py +1 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/recorder_helper.py +3 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/sb_cdp.py +3 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/base_case.py +92 -1
- {seleniumbase-4.41.5 → seleniumbase-4.41.7/seleniumbase.egg-info}/PKG-INFO +49 -22
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase.egg-info/requires.txt +12 -10
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/setup.py +12 -10
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/.gitignore +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/LICENSE +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/MANIFEST.in +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/install.sh +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/pyproject.toml +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/pytest.ini +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/sbase/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/sbase/__main__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/page_actions.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/pytest_plugin.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/sb_manager.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/cdp_driver/tab.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/setup.cfg +0 -0
- {seleniumbase-4.41.5 → seleniumbase-4.41.7}/virtualenv_install.sh +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: seleniumbase
|
3
|
-
Version: 4.41.
|
3
|
+
Version: 4.41.7
|
4
4
|
Summary: A complete web automation framework for end-to-end testing.
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
6
6
|
Author: Michael Mintz
|
@@ -75,7 +75,7 @@ Requires-Dist: filelock~=3.16.1; python_version < "3.9"
|
|
75
75
|
Requires-Dist: filelock>=3.19.1; python_version >= "3.9"
|
76
76
|
Requires-Dist: fasteners>=0.20
|
77
77
|
Requires-Dist: mycdp>=1.2.0
|
78
|
-
Requires-Dist: pynose>=1.5.
|
78
|
+
Requires-Dist: pynose>=1.5.5
|
79
79
|
Requires-Dist: platformdirs>=4.3.6; python_version < "3.9"
|
80
80
|
Requires-Dist: platformdirs>=4.4.0; python_version >= "3.9"
|
81
81
|
Requires-Dist: typing-extensions>=4.13.2
|
@@ -98,15 +98,15 @@ Requires-Dist: charset-normalizer<4,>=3.4.3
|
|
98
98
|
Requires-Dist: urllib3<2,>=1.26.20; python_version < "3.10"
|
99
99
|
Requires-Dist: urllib3<2.6.0,>=1.26.20; python_version >= "3.10"
|
100
100
|
Requires-Dist: requests==2.32.4; python_version < "3.9"
|
101
|
-
Requires-Dist: requests
|
101
|
+
Requires-Dist: requests~=2.32.5; python_version >= "3.9"
|
102
102
|
Requires-Dist: sniffio==1.3.1
|
103
103
|
Requires-Dist: h11==0.16.0
|
104
104
|
Requires-Dist: outcome==1.3.0.post0
|
105
105
|
Requires-Dist: trio==0.27.0; python_version < "3.9"
|
106
|
-
Requires-Dist: trio
|
107
|
-
Requires-Dist: trio-websocket
|
106
|
+
Requires-Dist: trio~=0.30.0; python_version >= "3.9"
|
107
|
+
Requires-Dist: trio-websocket~=0.12.2
|
108
108
|
Requires-Dist: wsproto==1.2.0
|
109
|
-
Requires-Dist: websocket-client
|
109
|
+
Requires-Dist: websocket-client~=1.8.0
|
110
110
|
Requires-Dist: selenium==4.27.1; python_version < "3.9"
|
111
111
|
Requires-Dist: selenium==4.32.0; python_version >= "3.9" and python_version < "3.10"
|
112
112
|
Requires-Dist: selenium==4.35.0; python_version >= "3.10"
|
@@ -145,7 +145,7 @@ Provides-Extra: coverage
|
|
145
145
|
Requires-Dist: coverage>=7.6.1; python_version < "3.9" and extra == "coverage"
|
146
146
|
Requires-Dist: coverage>=7.10.6; python_version >= "3.9" and extra == "coverage"
|
147
147
|
Requires-Dist: pytest-cov>=5.0.0; python_version < "3.9" and extra == "coverage"
|
148
|
-
Requires-Dist: pytest-cov>=
|
148
|
+
Requires-Dist: pytest-cov>=7.0.0; python_version >= "3.9" and extra == "coverage"
|
149
149
|
Provides-Extra: flake8
|
150
150
|
Requires-Dist: flake8==5.0.4; python_version < "3.9" and extra == "flake8"
|
151
151
|
Requires-Dist: flake8==7.3.0; python_version >= "3.9" and extra == "flake8"
|
@@ -164,9 +164,11 @@ Provides-Extra: pdfminer
|
|
164
164
|
Requires-Dist: pdfminer.six==20250324; python_version < "3.9" and extra == "pdfminer"
|
165
165
|
Requires-Dist: pdfminer.six==20250506; python_version >= "3.9" and extra == "pdfminer"
|
166
166
|
Requires-Dist: cryptography==39.0.2; python_version < "3.9" and extra == "pdfminer"
|
167
|
-
Requires-Dist: cryptography==
|
168
|
-
Requires-Dist: cffi==1.17.1; extra == "pdfminer"
|
169
|
-
Requires-Dist:
|
167
|
+
Requires-Dist: cryptography==46.0.1; python_version >= "3.9" and extra == "pdfminer"
|
168
|
+
Requires-Dist: cffi==1.17.1; python_version < "3.9" and extra == "pdfminer"
|
169
|
+
Requires-Dist: cffi==2.0.0; python_version >= "3.9" and extra == "pdfminer"
|
170
|
+
Requires-Dist: pycparser==2.22; python_version < "3.9" and extra == "pdfminer"
|
171
|
+
Requires-Dist: pycparser==2.23; python_version >= "3.9" and extra == "pdfminer"
|
170
172
|
Provides-Extra: pillow
|
171
173
|
Requires-Dist: Pillow>=10.4.0; python_version < "3.9" and extra == "pillow"
|
172
174
|
Requires-Dist: Pillow>=11.3.0; python_version >= "3.9" and extra == "pillow"
|
@@ -175,7 +177,7 @@ Requires-Dist: pip-system-certs==4.0; platform_system == "Windows" and extra ==
|
|
175
177
|
Provides-Extra: proxy
|
176
178
|
Requires-Dist: proxy.py==2.4.3; extra == "proxy"
|
177
179
|
Provides-Extra: psutil
|
178
|
-
Requires-Dist: psutil==7.
|
180
|
+
Requires-Dist: psutil==7.1.0; extra == "psutil"
|
179
181
|
Provides-Extra: pyautogui
|
180
182
|
Requires-Dist: PyAutoGUI==0.9.54; extra == "pyautogui"
|
181
183
|
Provides-Extra: selenium-stealth
|
@@ -273,26 +275,31 @@ Dynamic: summary
|
|
273
275
|
|
274
276
|
--------
|
275
277
|
|
276
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">raw_google.py</a>, which
|
278
|
+
<p align="left">📗 For performing a Google Search without hitting the "unusual traffic" page, you can use SeleniumBase UC Mode. Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">SeleniumBase/examples/raw_google.py</a>, which exports the search results into different formats (PDF, HTML, PNG):</p>
|
277
279
|
|
278
280
|
```python
|
279
281
|
from seleniumbase import SB
|
280
282
|
|
281
283
|
with SB(test=True, uc=True) as sb:
|
282
284
|
sb.open("https://google.com/ncr")
|
283
|
-
sb.type('[title="Search"]', "SeleniumBase GitHub page
|
284
|
-
sb.click(
|
285
|
-
sb.save_screenshot_to_logs() # ./latest_logs/
|
285
|
+
sb.type('[title="Search"]', "SeleniumBase GitHub page")
|
286
|
+
sb.click("div:not([jsname]) > * > input")
|
286
287
|
print(sb.get_page_title())
|
288
|
+
sb.sleep(2) # Wait for the "AI Overview" result
|
289
|
+
if sb.is_text_visible("Generating"):
|
290
|
+
sb.wait_for_text("AI Overview")
|
291
|
+
sb.save_as_pdf_to_logs() # Saved to ./latest_logs/
|
292
|
+
sb.save_page_source_to_logs()
|
293
|
+
sb.save_screenshot_to_logs()
|
287
294
|
```
|
288
295
|
|
289
296
|
> `python raw_google.py`
|
290
297
|
|
291
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/
|
298
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/img/google_sb_result.png" alt="SeleniumBase on Google" title="SeleniumBase on Google" width="440" /></a>
|
292
299
|
|
293
300
|
--------
|
294
301
|
|
295
|
-
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
302
|
+
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page with UC Mode + CDP Mode: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
296
303
|
|
297
304
|
```python
|
298
305
|
from seleniumbase import SB
|
@@ -300,16 +307,36 @@ from seleniumbase import SB
|
|
300
307
|
with SB(uc=True, test=True, locale="en") as sb:
|
301
308
|
url = "https://gitlab.com/users/sign_in"
|
302
309
|
sb.activate_cdp_mode(url)
|
303
|
-
sb.sleep(
|
310
|
+
sb.sleep(2.2)
|
304
311
|
sb.uc_gui_click_captcha()
|
305
|
-
sb.
|
312
|
+
sb.assert_text("Username", '[for="user_login"]', timeout=3)
|
313
|
+
sb.assert_element('label[for="user_login"]')
|
314
|
+
sb.highlight('button:contains("Sign in")')
|
315
|
+
sb.highlight('h1:contains("GitLab.com")')
|
316
|
+
sb.post_message("SeleniumBase wasn't detected", duration=4)
|
306
317
|
```
|
307
318
|
|
308
319
|
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" title="SeleniumBase" width="332"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" title="SeleniumBase" width="288">
|
309
320
|
|
321
|
+
<p align="left">📙 You can also use SeleniumBase's pure CDP Mode, which doesn't use chromedriver, Selenium, or a Python context manager at all: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py">SeleniumBase/examples/cdp_mode/raw_cdp_gitlab.py</a></p>
|
322
|
+
|
323
|
+
```python
|
324
|
+
from seleniumbase import sb_cdp
|
325
|
+
|
326
|
+
url = "https://gitlab.com/users/sign_in"
|
327
|
+
sb = sb_cdp.Chrome(url)
|
328
|
+
sb.sleep(2.5)
|
329
|
+
sb.gui_click_captcha()
|
330
|
+
sb.highlight('h1:contains("GitLab.com")')
|
331
|
+
sb.highlight('button:contains("Sign in")')
|
332
|
+
sb.driver.stop()
|
333
|
+
```
|
334
|
+
|
335
|
+
> (Due to a change in Chrome 137 where the --load-extension switch was removed, one limitation with this format is that you can't load extensions directly. The other formats weren't affected by this change.)
|
336
|
+
|
310
337
|
--------
|
311
338
|
|
312
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">test_get_swag.py</a>, which tests an e-commerce site:</p>
|
339
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">SeleniumBase/examples/test_get_swag.py</a>, which tests an e-commerce site:</p>
|
313
340
|
|
314
341
|
```python
|
315
342
|
from seleniumbase import BaseCase
|
@@ -341,7 +368,7 @@ class MyTestClass(BaseCase):
|
|
341
368
|
|
342
369
|
--------
|
343
370
|
|
344
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
371
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">SeleniumBase/examples/test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
345
372
|
|
346
373
|
```zsh
|
347
374
|
pytest test_coffee_cart.py --demo
|
@@ -355,7 +382,7 @@ pytest test_coffee_cart.py --demo
|
|
355
382
|
|
356
383
|
<a id="multiple_examples"></a>
|
357
384
|
|
358
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">test_demo_site.py</a>, which covers several actions:</p>
|
385
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">SeleniumBase/examples/test_demo_site.py</a>, which covers several actions:</p>
|
359
386
|
|
360
387
|
```zsh
|
361
388
|
pytest test_demo_site.py
|
@@ -65,26 +65,31 @@
|
|
65
65
|
|
66
66
|
--------
|
67
67
|
|
68
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">raw_google.py</a>, which
|
68
|
+
<p align="left">📗 For performing a Google Search without hitting the "unusual traffic" page, you can use SeleniumBase UC Mode. Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">SeleniumBase/examples/raw_google.py</a>, which exports the search results into different formats (PDF, HTML, PNG):</p>
|
69
69
|
|
70
70
|
```python
|
71
71
|
from seleniumbase import SB
|
72
72
|
|
73
73
|
with SB(test=True, uc=True) as sb:
|
74
74
|
sb.open("https://google.com/ncr")
|
75
|
-
sb.type('[title="Search"]', "SeleniumBase GitHub page
|
76
|
-
sb.click(
|
77
|
-
sb.save_screenshot_to_logs() # ./latest_logs/
|
75
|
+
sb.type('[title="Search"]', "SeleniumBase GitHub page")
|
76
|
+
sb.click("div:not([jsname]) > * > input")
|
78
77
|
print(sb.get_page_title())
|
78
|
+
sb.sleep(2) # Wait for the "AI Overview" result
|
79
|
+
if sb.is_text_visible("Generating"):
|
80
|
+
sb.wait_for_text("AI Overview")
|
81
|
+
sb.save_as_pdf_to_logs() # Saved to ./latest_logs/
|
82
|
+
sb.save_page_source_to_logs()
|
83
|
+
sb.save_screenshot_to_logs()
|
79
84
|
```
|
80
85
|
|
81
86
|
> `python raw_google.py`
|
82
87
|
|
83
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/
|
88
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/img/google_sb_result.png" alt="SeleniumBase on Google" title="SeleniumBase on Google" width="440" /></a>
|
84
89
|
|
85
90
|
--------
|
86
91
|
|
87
|
-
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
92
|
+
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page with UC Mode + CDP Mode: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
88
93
|
|
89
94
|
```python
|
90
95
|
from seleniumbase import SB
|
@@ -92,16 +97,36 @@ from seleniumbase import SB
|
|
92
97
|
with SB(uc=True, test=True, locale="en") as sb:
|
93
98
|
url = "https://gitlab.com/users/sign_in"
|
94
99
|
sb.activate_cdp_mode(url)
|
95
|
-
sb.sleep(
|
100
|
+
sb.sleep(2.2)
|
96
101
|
sb.uc_gui_click_captcha()
|
97
|
-
sb.
|
102
|
+
sb.assert_text("Username", '[for="user_login"]', timeout=3)
|
103
|
+
sb.assert_element('label[for="user_login"]')
|
104
|
+
sb.highlight('button:contains("Sign in")')
|
105
|
+
sb.highlight('h1:contains("GitLab.com")')
|
106
|
+
sb.post_message("SeleniumBase wasn't detected", duration=4)
|
98
107
|
```
|
99
108
|
|
100
109
|
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" title="SeleniumBase" width="332"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" title="SeleniumBase" width="288">
|
101
110
|
|
111
|
+
<p align="left">📙 You can also use SeleniumBase's pure CDP Mode, which doesn't use chromedriver, Selenium, or a Python context manager at all: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py">SeleniumBase/examples/cdp_mode/raw_cdp_gitlab.py</a></p>
|
112
|
+
|
113
|
+
```python
|
114
|
+
from seleniumbase import sb_cdp
|
115
|
+
|
116
|
+
url = "https://gitlab.com/users/sign_in"
|
117
|
+
sb = sb_cdp.Chrome(url)
|
118
|
+
sb.sleep(2.5)
|
119
|
+
sb.gui_click_captcha()
|
120
|
+
sb.highlight('h1:contains("GitLab.com")')
|
121
|
+
sb.highlight('button:contains("Sign in")')
|
122
|
+
sb.driver.stop()
|
123
|
+
```
|
124
|
+
|
125
|
+
> (Due to a change in Chrome 137 where the --load-extension switch was removed, one limitation with this format is that you can't load extensions directly. The other formats weren't affected by this change.)
|
126
|
+
|
102
127
|
--------
|
103
128
|
|
104
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">test_get_swag.py</a>, which tests an e-commerce site:</p>
|
129
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">SeleniumBase/examples/test_get_swag.py</a>, which tests an e-commerce site:</p>
|
105
130
|
|
106
131
|
```python
|
107
132
|
from seleniumbase import BaseCase
|
@@ -133,7 +158,7 @@ class MyTestClass(BaseCase):
|
|
133
158
|
|
134
159
|
--------
|
135
160
|
|
136
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
161
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">SeleniumBase/examples/test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
137
162
|
|
138
163
|
```zsh
|
139
164
|
pytest test_coffee_cart.py --demo
|
@@ -147,7 +172,7 @@ pytest test_coffee_cart.py --demo
|
|
147
172
|
|
148
173
|
<a id="multiple_examples"></a>
|
149
174
|
|
150
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">test_demo_site.py</a>, which covers several actions:</p>
|
175
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">SeleniumBase/examples/test_demo_site.py</a>, which covers several actions:</p>
|
151
176
|
|
152
177
|
```zsh
|
153
178
|
pytest test_demo_site.py
|
@@ -13,7 +13,7 @@ filelock~=3.16.1;python_version<"3.9"
|
|
13
13
|
filelock>=3.19.1;python_version>="3.9"
|
14
14
|
fasteners>=0.20
|
15
15
|
mycdp>=1.2.0
|
16
|
-
pynose>=1.5.
|
16
|
+
pynose>=1.5.5
|
17
17
|
platformdirs>=4.3.6;python_version<"3.9"
|
18
18
|
platformdirs>=4.4.0;python_version>="3.9"
|
19
19
|
typing-extensions>=4.13.2
|
@@ -36,15 +36,15 @@ charset-normalizer>=3.4.3,<4
|
|
36
36
|
urllib3>=1.26.20,<2;python_version<"3.10"
|
37
37
|
urllib3>=1.26.20,<2.6.0;python_version>="3.10"
|
38
38
|
requests==2.32.4;python_version<"3.9"
|
39
|
-
requests
|
39
|
+
requests~=2.32.5;python_version>="3.9"
|
40
40
|
sniffio==1.3.1
|
41
41
|
h11==0.16.0
|
42
42
|
outcome==1.3.0.post0
|
43
43
|
trio==0.27.0;python_version<"3.9"
|
44
|
-
trio
|
45
|
-
trio-websocket
|
44
|
+
trio~=0.30.0;python_version>="3.9"
|
45
|
+
trio-websocket~=0.12.2
|
46
46
|
wsproto==1.2.0
|
47
|
-
websocket-client
|
47
|
+
websocket-client~=1.8.0
|
48
48
|
selenium==4.27.1;python_version<"3.9"
|
49
49
|
selenium==4.32.0;python_version>="3.9" and python_version<"3.10"
|
50
50
|
selenium==4.35.0;python_version>="3.10"
|
@@ -82,7 +82,7 @@ rich>=14.1.0,<15
|
|
82
82
|
coverage>=7.6.1;python_version<"3.9"
|
83
83
|
coverage>=7.10.6;python_version>="3.9"
|
84
84
|
pytest-cov>=5.0.0;python_version<"3.9"
|
85
|
-
pytest-cov>=
|
85
|
+
pytest-cov>=7.0.0;python_version>="3.9"
|
86
86
|
flake8==5.0.4;python_version<"3.9"
|
87
87
|
flake8==7.3.0;python_version>="3.9"
|
88
88
|
mccabe==0.7.0
|
@@ -1191,6 +1191,15 @@ def set_attributes(context, selector, attribute, value):
|
|
1191
1191
|
sb.set_attributes(selector, attribute, value)
|
1192
1192
|
|
1193
1193
|
|
1194
|
+
@step("Save as PDF to logs")
|
1195
|
+
@step("Save as PDF to the logs")
|
1196
|
+
@step("User saves page as PDF to logs")
|
1197
|
+
@step("User saves page as PDF to the logs")
|
1198
|
+
def save_as_pdf_to_logs(context):
|
1199
|
+
sb = context.sb
|
1200
|
+
sb.save_as_pdf_to_logs()
|
1201
|
+
|
1202
|
+
|
1194
1203
|
@step("Save page source to logs")
|
1195
1204
|
@step("Save the page source to the logs")
|
1196
1205
|
@step("User saves page source to logs")
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# seleniumbase package
|
2
|
-
__version__ = "4.41.
|
2
|
+
__version__ = "4.41.7"
|
@@ -522,6 +522,8 @@ def generate_gherkin(srt_actions):
|
|
522
522
|
)
|
523
523
|
elif action[0] == "ss_tl":
|
524
524
|
sb_actions.append("Save screenshot to logs")
|
525
|
+
elif action[0] == "pdftl":
|
526
|
+
sb_actions.append("Save as PDF to logs")
|
525
527
|
elif action[0] == "spstl":
|
526
528
|
sb_actions.append("Save page source to logs")
|
527
529
|
elif action[0] == "sh_fc":
|
@@ -865,6 +865,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
865
865
|
cdp.scroll_down = CDPM.scroll_down
|
866
866
|
cdp.save_screenshot = CDPM.save_screenshot
|
867
867
|
cdp.print_to_pdf = CDPM.print_to_pdf
|
868
|
+
cdp.save_as_pdf = CDPM.save_as_pdf
|
868
869
|
cdp.page = page # async world
|
869
870
|
cdp.driver = driver.cdp_base # async world
|
870
871
|
cdp.tab = cdp.page # shortcut (original)
|
@@ -556,6 +556,9 @@ def generate_sbase_code(srt_actions):
|
|
556
556
|
elif action[0] == "ss_tl":
|
557
557
|
method = "save_screenshot_to_logs"
|
558
558
|
sb_actions.append("self.%s()" % method)
|
559
|
+
elif action[0] == "pdftl":
|
560
|
+
method = "save_as_pdf_to_logs"
|
561
|
+
sb_actions.append("self.%s()" % method)
|
559
562
|
elif action[0] == "spstl":
|
560
563
|
method = "save_page_source_to_logs"
|
561
564
|
sb_actions.append("self.%s()" % method)
|
@@ -2571,6 +2571,9 @@ class CDPMethods():
|
|
2571
2571
|
filename = os.path.join(folder, name)
|
2572
2572
|
self.loop.run_until_complete(self.page.print_to_pdf(filename))
|
2573
2573
|
|
2574
|
+
def save_as_pdf(self, *args, **kwargs):
|
2575
|
+
self.print_to_pdf(*args, **kwargs)
|
2576
|
+
|
2574
2577
|
|
2575
2578
|
class Chrome(CDPMethods):
|
2576
2579
|
def __init__(self, url=None, **kwargs):
|
@@ -134,6 +134,7 @@ class BaseCase(unittest.TestCase):
|
|
134
134
|
self.__requests_timeout = None
|
135
135
|
self.__page_source_count = 0
|
136
136
|
self.__screenshot_count = 0
|
137
|
+
self.__saved_pdf_count = 0
|
137
138
|
self.__logs_data_count = 0
|
138
139
|
self.__last_data_file = None
|
139
140
|
self.__level_0_visual_f = False
|
@@ -4492,7 +4493,8 @@ class BaseCase(unittest.TestCase):
|
|
4492
4493
|
If a provided selector is not found, then takes a full-page screenshot.
|
4493
4494
|
(The last_page / failure screenshot is always "screenshot.png")
|
4494
4495
|
The screenshot will be in PNG format."""
|
4495
|
-
self.
|
4496
|
+
if not self.__is_cdp_swap_needed():
|
4497
|
+
self.wait_for_ready_state_complete()
|
4496
4498
|
test_logpath = os.path.join(self.log_path, self.__get_test_id())
|
4497
4499
|
self.__create_log_path_as_needed(test_logpath)
|
4498
4500
|
if name:
|
@@ -4510,6 +4512,11 @@ class BaseCase(unittest.TestCase):
|
|
4510
4512
|
if selector and by:
|
4511
4513
|
selector, by = self.__recalculate_selector(selector, by)
|
4512
4514
|
if page_actions.is_element_present(self.driver, selector, by):
|
4515
|
+
if self.__is_cdp_swap_needed():
|
4516
|
+
selector = self.convert_to_css_selector(selector, by=by)
|
4517
|
+
return self.cdp.save_screenshot(
|
4518
|
+
name, folder=test_logpath, selector=selector
|
4519
|
+
)
|
4513
4520
|
return page_actions.save_screenshot(
|
4514
4521
|
self.driver, name, test_logpath, selector, by
|
4515
4522
|
)
|
@@ -4523,8 +4530,49 @@ class BaseCase(unittest.TestCase):
|
|
4523
4530
|
action = ["ss_tl", "", origin, time_stamp]
|
4524
4531
|
self.__extra_actions.append(action)
|
4525
4532
|
sb_config._has_logs = True
|
4533
|
+
if self.__is_cdp_swap_needed():
|
4534
|
+
return self.cdp.save_screenshot(name, folder=test_logpath)
|
4526
4535
|
return page_actions.save_screenshot(self.driver, name, test_logpath)
|
4527
4536
|
|
4537
|
+
def save_as_pdf(self, name, folder=None):
|
4538
|
+
"""Same as self.print_to_pdf()"""
|
4539
|
+
return self.print_to_pdf(name, folder=folder)
|
4540
|
+
|
4541
|
+
def save_as_pdf_to_logs(self, name=None):
|
4542
|
+
"""Saves the page as a PDF to the "latest_logs/" folder.
|
4543
|
+
Naming is automatic:
|
4544
|
+
If NO NAME provided: "_1_PDF.pdf", "_2_PDF.pdf", etc.
|
4545
|
+
If NAME IS provided, then: "_1_name.pdf", "_2_name.pdf", etc."""
|
4546
|
+
if not self.__is_cdp_swap_needed():
|
4547
|
+
self.wait_for_ready_state_complete()
|
4548
|
+
test_logpath = os.path.join(self.log_path, self.__get_test_id())
|
4549
|
+
self.__create_log_path_as_needed(test_logpath)
|
4550
|
+
if name:
|
4551
|
+
name = str(name)
|
4552
|
+
self.__saved_pdf_count += 1
|
4553
|
+
if not name or len(name) == 0:
|
4554
|
+
name = "_%s_PDF.pdf" % self.__saved_pdf_count
|
4555
|
+
else:
|
4556
|
+
pre_name = "_%s_" % self.__saved_pdf_count
|
4557
|
+
if len(name) >= 4 and name[-4:].lower() == ".pdf":
|
4558
|
+
name = name[:-4]
|
4559
|
+
if len(name) == 0:
|
4560
|
+
name = "PDF"
|
4561
|
+
name = "%s%s.pdf" % (pre_name, name)
|
4562
|
+
if self.recorder_mode:
|
4563
|
+
url = self.get_current_url()
|
4564
|
+
if url and len(url) > 0:
|
4565
|
+
if ("http:") in url or ("https:") in url or ("file:") in url:
|
4566
|
+
if self.get_session_storage_item("pause_recorder") == "no":
|
4567
|
+
time_stamp = self.execute_script("return Date.now();")
|
4568
|
+
origin = self.get_origin()
|
4569
|
+
action = ["pdftl", "", origin, time_stamp]
|
4570
|
+
self.__extra_actions.append(action)
|
4571
|
+
sb_config._has_logs = True
|
4572
|
+
if self.__is_cdp_swap_needed():
|
4573
|
+
return self.cdp.print_to_pdf(name, folder=test_logpath)
|
4574
|
+
return self.print_to_pdf(name, test_logpath)
|
4575
|
+
|
4528
4576
|
def save_page_source_to_logs(self, name=None):
|
4529
4577
|
"""Saves the page HTML to the "latest_logs/" folder.
|
4530
4578
|
Naming is automatic:
|
@@ -5517,6 +5565,7 @@ class BaseCase(unittest.TestCase):
|
|
5517
5565
|
ext_actions.append("s_scr")
|
5518
5566
|
ext_actions.append("ss_tf")
|
5519
5567
|
ext_actions.append("ss_tl")
|
5568
|
+
ext_actions.append("pdftl")
|
5520
5569
|
ext_actions.append("spstl")
|
5521
5570
|
ext_actions.append("da_el")
|
5522
5571
|
ext_actions.append("da_ep")
|
@@ -7245,6 +7294,7 @@ class BaseCase(unittest.TestCase):
|
|
7245
7294
|
page_search = [page]
|
7246
7295
|
else:
|
7247
7296
|
page_search = None
|
7297
|
+
logging.getLogger("pdfminer").setLevel(logging.ERROR)
|
7248
7298
|
pdf_text = extract_text(
|
7249
7299
|
file_path,
|
7250
7300
|
password="",
|
@@ -7552,6 +7602,47 @@ class BaseCase(unittest.TestCase):
|
|
7552
7602
|
folder = constants.Files.DOWNLOADS_FOLDER
|
7553
7603
|
return page_utils._get_file_data(folder, file_name)
|
7554
7604
|
|
7605
|
+
def print_to_pdf(self, name, folder=None):
|
7606
|
+
"""Saves the current page as a PDF.
|
7607
|
+
If no folder is specified, uses the folder where pytest was called.
|
7608
|
+
If the folder provided doesn't exist, it will get created.
|
7609
|
+
@Params
|
7610
|
+
name - The name to give the PDF file. Must end in ".pdf".
|
7611
|
+
folder - The directory where you want to save the PDF."""
|
7612
|
+
import base64
|
7613
|
+
from selenium.webdriver.common.print_page_options import PrintOptions
|
7614
|
+
|
7615
|
+
if not name.lower().endswith(".pdf"):
|
7616
|
+
raise Exception('PDF name {%s} must end in ".pdf"!)' % name)
|
7617
|
+
download_file_lock = fasteners.InterProcessLock(
|
7618
|
+
constants.MultiBrowser.DOWNLOAD_FILE_LOCK
|
7619
|
+
)
|
7620
|
+
if self.__is_cdp_swap_needed():
|
7621
|
+
with download_file_lock:
|
7622
|
+
with suppress(Exception):
|
7623
|
+
shared_utils.make_writable(
|
7624
|
+
constants.MultiBrowser.DOWNLOAD_FILE_LOCK
|
7625
|
+
)
|
7626
|
+
if folder and not os.path.exists(folder):
|
7627
|
+
os.makedirs(folder)
|
7628
|
+
self.cdp.print_to_pdf(name, folder)
|
7629
|
+
return
|
7630
|
+
self.wait_for_ready_state_complete()
|
7631
|
+
print_options = PrintOptions()
|
7632
|
+
pdf_base64 = self.driver.print_page(print_options)
|
7633
|
+
with download_file_lock:
|
7634
|
+
with suppress(Exception):
|
7635
|
+
shared_utils.make_writable(
|
7636
|
+
constants.MultiBrowser.DOWNLOAD_FILE_LOCK
|
7637
|
+
)
|
7638
|
+
if folder and not os.path.exists(folder):
|
7639
|
+
os.makedirs(folder)
|
7640
|
+
filename = name
|
7641
|
+
if folder:
|
7642
|
+
filename = os.path.join(folder, name)
|
7643
|
+
with open(filename, "wb") as f:
|
7644
|
+
f.write(base64.b64decode(pdf_base64))
|
7645
|
+
|
7555
7646
|
def get_downloads_folder(self):
|
7556
7647
|
"""Returns the path of the SeleniumBase "downloaded_files/" folder.
|
7557
7648
|
Calling self.download_file(file_url) will put that file in here.
|