seleniumbase 4.47.3__tar.gz → 4.47.5__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.47.3/seleniumbase.egg-info → seleniumbase-4.47.5}/PKG-INFO +46 -36
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/README.md +40 -30
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/requirements.txt +5 -5
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/browser_launcher.py +1 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/sb_cdp.py +4 -4
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/page_actions.py +1 -1
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/cdp_driver/browser.py +22 -10
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/cdp_driver/cdp_util.py +21 -13
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/cdp_driver/tab.py +7 -7
- {seleniumbase-4.47.3 → seleniumbase-4.47.5/seleniumbase.egg-info}/PKG-INFO +46 -36
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase.egg-info/requires.txt +5 -5
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/setup.py +5 -5
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/.gitignore +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/LICENSE +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/MANIFEST.in +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/install.sh +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/pyproject.toml +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/pytest.ini +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/sbase/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/sbase/__main__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/sbase/steps.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/base_case.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/pytest_plugin.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/sb_manager.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/setup.cfg +0 -0
- {seleniumbase-4.47.3 → seleniumbase-4.47.5}/virtualenv_install.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.47.
|
|
3
|
+
Version: 4.47.5
|
|
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
|
|
@@ -63,7 +63,7 @@ Requires-Dist: packaging>=26.0
|
|
|
63
63
|
Requires-Dist: setuptools~=70.2; python_version < "3.10"
|
|
64
64
|
Requires-Dist: setuptools>=82.0.1; python_version >= "3.10"
|
|
65
65
|
Requires-Dist: wheel>=0.46.3
|
|
66
|
-
Requires-Dist: attrs>=
|
|
66
|
+
Requires-Dist: attrs>=26.1.0
|
|
67
67
|
Requires-Dist: certifi>=2026.2.25
|
|
68
68
|
Requires-Dist: exceptiongroup>=1.3.1
|
|
69
69
|
Requires-Dist: websockets~=15.0.1; python_version < "3.10"
|
|
@@ -71,7 +71,7 @@ Requires-Dist: websockets>=16.0; python_version >= "3.10"
|
|
|
71
71
|
Requires-Dist: filelock~=3.19.1; python_version < "3.10"
|
|
72
72
|
Requires-Dist: filelock>=3.25.2; python_version >= "3.10"
|
|
73
73
|
Requires-Dist: fasteners>=0.20
|
|
74
|
-
Requires-Dist: mycdp>=1.3.
|
|
74
|
+
Requires-Dist: mycdp>=1.3.7
|
|
75
75
|
Requires-Dist: pynose>=1.5.5
|
|
76
76
|
Requires-Dist: platformdirs~=4.4.0; python_version < "3.10"
|
|
77
77
|
Requires-Dist: platformdirs>=4.9.4; python_version >= "3.10"
|
|
@@ -89,7 +89,7 @@ Requires-Dist: pyreadline3>=3.5.4; platform_system == "Windows"
|
|
|
89
89
|
Requires-Dist: tabcompleter>=1.4.0
|
|
90
90
|
Requires-Dist: pdbp>=1.8.2
|
|
91
91
|
Requires-Dist: idna>=3.11
|
|
92
|
-
Requires-Dist: charset-normalizer<4,>=3.4.
|
|
92
|
+
Requires-Dist: charset-normalizer<4,>=3.4.6
|
|
93
93
|
Requires-Dist: urllib3<2,>=1.26.20; python_version < "3.10"
|
|
94
94
|
Requires-Dist: urllib3<3,>=1.26.20; python_version >= "3.10"
|
|
95
95
|
Requires-Dist: requests~=2.32.5
|
|
@@ -138,8 +138,8 @@ Requires-Dist: allure-python-commons>=2.13.5; extra == "allure"
|
|
|
138
138
|
Requires-Dist: allure-behave>=2.13.5; extra == "allure"
|
|
139
139
|
Provides-Extra: coverage
|
|
140
140
|
Requires-Dist: coverage>=7.10.7; python_version < "3.10" and extra == "coverage"
|
|
141
|
-
Requires-Dist: coverage>=7.13.
|
|
142
|
-
Requires-Dist: pytest-cov>=7.
|
|
141
|
+
Requires-Dist: coverage>=7.13.5; python_version >= "3.10" and extra == "coverage"
|
|
142
|
+
Requires-Dist: pytest-cov>=7.1.0; extra == "coverage"
|
|
143
143
|
Provides-Extra: flake8
|
|
144
144
|
Requires-Dist: flake8==7.3.0; extra == "flake8"
|
|
145
145
|
Requires-Dist: mccabe==0.7.0; extra == "flake8"
|
|
@@ -209,7 +209,7 @@ Dynamic: summary
|
|
|
209
209
|
|
|
210
210
|
<h1>SeleniumBase</h1>
|
|
211
211
|
|
|
212
|
-
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/
|
|
212
|
+
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/nice_logo_8t.png" alt="SeleniumBase" width="424" /></a></p>
|
|
213
213
|
|
|
214
214
|
<p align="center" class="hero__title"><b>All-in-one Browser Automation Framework:<br />Web Crawling / Testing / Scraping / Stealth</b></p>
|
|
215
215
|
|
|
@@ -252,17 +252,39 @@ Dynamic: summary
|
|
|
252
252
|
<br />
|
|
253
253
|
</p>
|
|
254
254
|
|
|
255
|
-
📊 <a href="https://github.com/seleniumbase/SeleniumBase/"><b translate="no">SeleniumBase</b></a> is a complete framework for
|
|
255
|
+
📊 <a href="https://github.com/seleniumbase/SeleniumBase/"><b translate="no">SeleniumBase</b></a> is a complete framework for browser automation and testing with Python and <a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a>. Includes stealth options and other advanced features.
|
|
256
256
|
|
|
257
|
-
|
|
257
|
+
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">UC Mode</a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> can bypass bot-detection, handle CAPTCHAs, and call methods from the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome Devtools Protocol</a>. CDP Mode includes <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md"><b><span translate="no">Stealthy Playwright Mode</span></b></a>, which makes Playwright stealthy.
|
|
258
258
|
|
|
259
|
-
📚
|
|
259
|
+
📚 The [SeleniumBase/examples/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder includes over 100 ready-to-run examples. Examples that start with `test_` or end with `_test.py`/`_tests.py` are specifically designed to run with `pytest`. Other examples run directly with raw `python` (those files generally start with `raw_` to avoid confusion).
|
|
260
260
|
|
|
261
|
-
|
|
261
|
+
🥷 Stealthy examples are located in [SeleniumBase/examples/cdp_mode/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
|
|
262
262
|
|
|
263
263
|
--------
|
|
264
264
|
|
|
265
|
-
<p align="left"
|
|
265
|
+
<p align="left">📓 Here's the stealthy architecture overview:</p>
|
|
266
|
+
|
|
267
|
+
<img src="https://seleniumbase.github.io/other/sb_stealth.png" width="596" alt="Stealthy architecture overview" />
|
|
268
|
+
|
|
269
|
+
(For maximum stealth, use <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">CDP Mode</a>, which includes <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">Stealthy Playwright Mode</a>)
|
|
270
|
+
|
|
271
|
+
--------
|
|
272
|
+
|
|
273
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_yc_news.py" target="_blank">This example</a> scrapes Hacker News listings with <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md#-pure-cdp-mode-sb_cdp">Pure CDP Mode</a>:
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
from seleniumbase import sb_cdp
|
|
277
|
+
|
|
278
|
+
url = "https://news.ycombinator.com/submitted?id=seleniumbase"
|
|
279
|
+
sb = sb_cdp.Chrome(url)
|
|
280
|
+
elements = sb.find_elements("span.titleline > a")
|
|
281
|
+
for element in elements:
|
|
282
|
+
print("* " + element.text)
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
--------
|
|
286
|
+
|
|
287
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py" target="_blank">This example</a> saves Google Search results with UC + CDP Mode:<br />(Results are saved as PDF, HTML, and PNG files)</p>
|
|
266
288
|
|
|
267
289
|
```python
|
|
268
290
|
from seleniumbase import SB
|
|
@@ -280,13 +302,9 @@ with SB(uc=True, test=True) as sb:
|
|
|
280
302
|
print("Logs have been saved to: ./latest_logs/")
|
|
281
303
|
```
|
|
282
304
|
|
|
283
|
-
> `python raw_google.py`
|
|
284
|
-
|
|
285
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/img/google_sb_result.jpg" alt="SeleniumBase on Google" title="SeleniumBase on Google" width="580" /></a>
|
|
286
|
-
|
|
287
305
|
--------
|
|
288
306
|
|
|
289
|
-
<p align="left">📗
|
|
307
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py" target="_blank">This example</a> bypasses Cloudflare's challenge page with UC + CDP Mode:
|
|
290
308
|
|
|
291
309
|
```python
|
|
292
310
|
from seleniumbase import SB
|
|
@@ -304,9 +322,11 @@ with SB(uc=True, test=True, locale="en") as sb:
|
|
|
304
322
|
sb.post_message("SeleniumBase wasn't detected", duration=4)
|
|
305
323
|
```
|
|
306
324
|
|
|
307
|
-
<img src="https://seleniumbase.github.io/other/cf_sec.jpg"
|
|
325
|
+
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" alt="SeleniumBase" width="344"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" alt="SeleniumBase" width="298">
|
|
326
|
+
|
|
327
|
+
----
|
|
308
328
|
|
|
309
|
-
<p align="left"
|
|
329
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py" target="_blank">This example</a> handles a CAPTCHA page with Pure CDP Mode:
|
|
310
330
|
|
|
311
331
|
```python
|
|
312
332
|
from seleniumbase import sb_cdp
|
|
@@ -322,7 +342,7 @@ sb.driver.stop()
|
|
|
322
342
|
|
|
323
343
|
--------
|
|
324
344
|
|
|
325
|
-
<p align="left">📗
|
|
345
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py" target="_blank">This example</a> tests an e-commerce site with <code>pytest</code>:
|
|
326
346
|
|
|
327
347
|
```python
|
|
328
348
|
from seleniumbase import BaseCase
|
|
@@ -348,19 +368,17 @@ class MyTestClass(BaseCase):
|
|
|
348
368
|
|
|
349
369
|
> `pytest test_get_swag.py`
|
|
350
370
|
|
|
351
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test"
|
|
352
|
-
|
|
353
|
-
> (The default browser is `--chrome` if not set.)
|
|
371
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" width="480" /></a>
|
|
354
372
|
|
|
355
373
|
--------
|
|
356
374
|
|
|
357
|
-
<p align="left">📗
|
|
375
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">This example</a> tests another e-commerce site with <code>pytest</code>:
|
|
358
376
|
|
|
359
377
|
```zsh
|
|
360
378
|
pytest test_coffee_cart.py --demo
|
|
361
379
|
```
|
|
362
380
|
|
|
363
|
-
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test"
|
|
381
|
+
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test" /></a></p>
|
|
364
382
|
|
|
365
383
|
> <p>(<code translate="no">--demo</code> mode slows down tests and highlights actions)</p>
|
|
366
384
|
|
|
@@ -368,13 +386,13 @@ pytest test_coffee_cart.py --demo
|
|
|
368
386
|
|
|
369
387
|
<a id="multiple_examples"></a>
|
|
370
388
|
|
|
371
|
-
<p align="left">📗
|
|
389
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">This example</a> covers multiple actions with <code>pytest</code>:
|
|
372
390
|
|
|
373
391
|
```zsh
|
|
374
392
|
pytest test_demo_site.py
|
|
375
393
|
```
|
|
376
394
|
|
|
377
|
-
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example"
|
|
395
|
+
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example" /></a></p>
|
|
378
396
|
|
|
379
397
|
> Easy to type, click, select, toggle, drag & drop, and more.
|
|
380
398
|
|
|
@@ -382,14 +400,6 @@ pytest test_demo_site.py
|
|
|
382
400
|
|
|
383
401
|
--------
|
|
384
402
|
|
|
385
|
-
<p align="left">📓 Here's a high-level stealthy architecture overview of SeleniumBase:</p>
|
|
386
|
-
|
|
387
|
-
<img src="https://seleniumbase.github.io/other/sb_stealth.png" width="585" alt="High-Level Stealthy Architecture Overview" title="High-Level Stealthy Architecture Overview" />
|
|
388
|
-
|
|
389
|
-
(For maximum stealth, use <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">CDP Mode</a>, which is used by <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">Stealthy Playwright Mode</a>)
|
|
390
|
-
|
|
391
|
-
--------
|
|
392
|
-
|
|
393
403
|
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/super_logo_sb3.png" alt="SeleniumBase" title="SeleniumBase" width="232" /></a></p>
|
|
394
404
|
|
|
395
405
|
<blockquote>
|
|
@@ -637,7 +647,7 @@ cd examples/
|
|
|
637
647
|
pytest my_first_test.py
|
|
638
648
|
```
|
|
639
649
|
|
|
640
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test"
|
|
650
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" width="480" /></a>
|
|
641
651
|
|
|
642
652
|
<p align="left"><b>Here's the full code for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>:</b></p>
|
|
643
653
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
<h1>SeleniumBase</h1>
|
|
11
11
|
|
|
12
|
-
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/
|
|
12
|
+
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/nice_logo_8t.png" alt="SeleniumBase" width="424" /></a></p>
|
|
13
13
|
|
|
14
14
|
<p align="center" class="hero__title"><b>All-in-one Browser Automation Framework:<br />Web Crawling / Testing / Scraping / Stealth</b></p>
|
|
15
15
|
|
|
@@ -52,17 +52,39 @@
|
|
|
52
52
|
<br />
|
|
53
53
|
</p>
|
|
54
54
|
|
|
55
|
-
📊 <a href="https://github.com/seleniumbase/SeleniumBase/"><b translate="no">SeleniumBase</b></a> is a complete framework for
|
|
55
|
+
📊 <a href="https://github.com/seleniumbase/SeleniumBase/"><b translate="no">SeleniumBase</b></a> is a complete framework for browser automation and testing with Python and <a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a>. Includes stealth options and other advanced features.
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">UC Mode</a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> can bypass bot-detection, handle CAPTCHAs, and call methods from the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome Devtools Protocol</a>. CDP Mode includes <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md"><b><span translate="no">Stealthy Playwright Mode</span></b></a>, which makes Playwright stealthy.
|
|
58
58
|
|
|
59
|
-
📚
|
|
59
|
+
📚 The [SeleniumBase/examples/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder includes over 100 ready-to-run examples. Examples that start with `test_` or end with `_test.py`/`_tests.py` are specifically designed to run with `pytest`. Other examples run directly with raw `python` (those files generally start with `raw_` to avoid confusion).
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
🥷 Stealthy examples are located in [SeleniumBase/examples/cdp_mode/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
|
|
62
62
|
|
|
63
63
|
--------
|
|
64
64
|
|
|
65
|
-
<p align="left"
|
|
65
|
+
<p align="left">📓 Here's the stealthy architecture overview:</p>
|
|
66
|
+
|
|
67
|
+
<img src="https://seleniumbase.github.io/other/sb_stealth.png" width="596" alt="Stealthy architecture overview" />
|
|
68
|
+
|
|
69
|
+
(For maximum stealth, use <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">CDP Mode</a>, which includes <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">Stealthy Playwright Mode</a>)
|
|
70
|
+
|
|
71
|
+
--------
|
|
72
|
+
|
|
73
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_yc_news.py" target="_blank">This example</a> scrapes Hacker News listings with <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md#-pure-cdp-mode-sb_cdp">Pure CDP Mode</a>:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from seleniumbase import sb_cdp
|
|
77
|
+
|
|
78
|
+
url = "https://news.ycombinator.com/submitted?id=seleniumbase"
|
|
79
|
+
sb = sb_cdp.Chrome(url)
|
|
80
|
+
elements = sb.find_elements("span.titleline > a")
|
|
81
|
+
for element in elements:
|
|
82
|
+
print("* " + element.text)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
--------
|
|
86
|
+
|
|
87
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py" target="_blank">This example</a> saves Google Search results with UC + CDP Mode:<br />(Results are saved as PDF, HTML, and PNG files)</p>
|
|
66
88
|
|
|
67
89
|
```python
|
|
68
90
|
from seleniumbase import SB
|
|
@@ -80,13 +102,9 @@ with SB(uc=True, test=True) as sb:
|
|
|
80
102
|
print("Logs have been saved to: ./latest_logs/")
|
|
81
103
|
```
|
|
82
104
|
|
|
83
|
-
> `python raw_google.py`
|
|
84
|
-
|
|
85
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/img/google_sb_result.jpg" alt="SeleniumBase on Google" title="SeleniumBase on Google" width="580" /></a>
|
|
86
|
-
|
|
87
105
|
--------
|
|
88
106
|
|
|
89
|
-
<p align="left">📗
|
|
107
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py" target="_blank">This example</a> bypasses Cloudflare's challenge page with UC + CDP Mode:
|
|
90
108
|
|
|
91
109
|
```python
|
|
92
110
|
from seleniumbase import SB
|
|
@@ -104,9 +122,11 @@ with SB(uc=True, test=True, locale="en") as sb:
|
|
|
104
122
|
sb.post_message("SeleniumBase wasn't detected", duration=4)
|
|
105
123
|
```
|
|
106
124
|
|
|
107
|
-
<img src="https://seleniumbase.github.io/other/cf_sec.jpg"
|
|
125
|
+
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" alt="SeleniumBase" width="344"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" alt="SeleniumBase" width="298">
|
|
126
|
+
|
|
127
|
+
----
|
|
108
128
|
|
|
109
|
-
<p align="left"
|
|
129
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py" target="_blank">This example</a> handles a CAPTCHA page with Pure CDP Mode:
|
|
110
130
|
|
|
111
131
|
```python
|
|
112
132
|
from seleniumbase import sb_cdp
|
|
@@ -122,7 +142,7 @@ sb.driver.stop()
|
|
|
122
142
|
|
|
123
143
|
--------
|
|
124
144
|
|
|
125
|
-
<p align="left">📗
|
|
145
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py" target="_blank">This example</a> tests an e-commerce site with <code>pytest</code>:
|
|
126
146
|
|
|
127
147
|
```python
|
|
128
148
|
from seleniumbase import BaseCase
|
|
@@ -148,19 +168,17 @@ class MyTestClass(BaseCase):
|
|
|
148
168
|
|
|
149
169
|
> `pytest test_get_swag.py`
|
|
150
170
|
|
|
151
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test"
|
|
152
|
-
|
|
153
|
-
> (The default browser is `--chrome` if not set.)
|
|
171
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" width="480" /></a>
|
|
154
172
|
|
|
155
173
|
--------
|
|
156
174
|
|
|
157
|
-
<p align="left">📗
|
|
175
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">This example</a> tests another e-commerce site with <code>pytest</code>:
|
|
158
176
|
|
|
159
177
|
```zsh
|
|
160
178
|
pytest test_coffee_cart.py --demo
|
|
161
179
|
```
|
|
162
180
|
|
|
163
|
-
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test"
|
|
181
|
+
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test" /></a></p>
|
|
164
182
|
|
|
165
183
|
> <p>(<code translate="no">--demo</code> mode slows down tests and highlights actions)</p>
|
|
166
184
|
|
|
@@ -168,13 +186,13 @@ pytest test_coffee_cart.py --demo
|
|
|
168
186
|
|
|
169
187
|
<a id="multiple_examples"></a>
|
|
170
188
|
|
|
171
|
-
<p align="left">📗
|
|
189
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">This example</a> covers multiple actions with <code>pytest</code>:
|
|
172
190
|
|
|
173
191
|
```zsh
|
|
174
192
|
pytest test_demo_site.py
|
|
175
193
|
```
|
|
176
194
|
|
|
177
|
-
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example"
|
|
195
|
+
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example" /></a></p>
|
|
178
196
|
|
|
179
197
|
> Easy to type, click, select, toggle, drag & drop, and more.
|
|
180
198
|
|
|
@@ -182,14 +200,6 @@ pytest test_demo_site.py
|
|
|
182
200
|
|
|
183
201
|
--------
|
|
184
202
|
|
|
185
|
-
<p align="left">📓 Here's a high-level stealthy architecture overview of SeleniumBase:</p>
|
|
186
|
-
|
|
187
|
-
<img src="https://seleniumbase.github.io/other/sb_stealth.png" width="585" alt="High-Level Stealthy Architecture Overview" title="High-Level Stealthy Architecture Overview" />
|
|
188
|
-
|
|
189
|
-
(For maximum stealth, use <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">CDP Mode</a>, which is used by <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">Stealthy Playwright Mode</a>)
|
|
190
|
-
|
|
191
|
-
--------
|
|
192
|
-
|
|
193
203
|
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/super_logo_sb3.png" alt="SeleniumBase" title="SeleniumBase" width="232" /></a></p>
|
|
194
204
|
|
|
195
205
|
<blockquote>
|
|
@@ -437,7 +447,7 @@ cd examples/
|
|
|
437
447
|
pytest my_first_test.py
|
|
438
448
|
```
|
|
439
449
|
|
|
440
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test"
|
|
450
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" width="480" /></a>
|
|
441
451
|
|
|
442
452
|
<p align="left"><b>Here's the full code for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>:</b></p>
|
|
443
453
|
|
|
@@ -3,7 +3,7 @@ packaging>=26.0
|
|
|
3
3
|
setuptools~=70.2;python_version<"3.10"
|
|
4
4
|
setuptools>=82.0.1;python_version>="3.10"
|
|
5
5
|
wheel>=0.46.3
|
|
6
|
-
attrs>=
|
|
6
|
+
attrs>=26.1.0
|
|
7
7
|
certifi>=2026.2.25
|
|
8
8
|
exceptiongroup>=1.3.1
|
|
9
9
|
websockets~=15.0.1;python_version<"3.10"
|
|
@@ -11,7 +11,7 @@ websockets>=16.0;python_version>="3.10"
|
|
|
11
11
|
filelock~=3.19.1;python_version<"3.10"
|
|
12
12
|
filelock>=3.25.2;python_version>="3.10"
|
|
13
13
|
fasteners>=0.20
|
|
14
|
-
mycdp>=1.3.
|
|
14
|
+
mycdp>=1.3.7
|
|
15
15
|
pynose>=1.5.5
|
|
16
16
|
platformdirs~=4.4.0;python_version<"3.10"
|
|
17
17
|
platformdirs>=4.9.4;python_version>="3.10"
|
|
@@ -29,7 +29,7 @@ pyreadline3>=3.5.4;platform_system=="Windows"
|
|
|
29
29
|
tabcompleter>=1.4.0
|
|
30
30
|
pdbp>=1.8.2
|
|
31
31
|
idna>=3.11
|
|
32
|
-
charset-normalizer>=3.4.
|
|
32
|
+
charset-normalizer>=3.4.6,<4
|
|
33
33
|
urllib3>=1.26.20,<2;python_version<"3.10"
|
|
34
34
|
urllib3>=1.26.20,<3;python_version>="3.10"
|
|
35
35
|
requests~=2.32.5
|
|
@@ -77,8 +77,8 @@ rich>=14.3.3,<15
|
|
|
77
77
|
# ("pip install -r requirements.txt" also installs this, but "pip install -e ." won't.)
|
|
78
78
|
|
|
79
79
|
coverage>=7.10.7;python_version<"3.10"
|
|
80
|
-
coverage>=7.13.
|
|
81
|
-
pytest-cov>=7.
|
|
80
|
+
coverage>=7.13.5;python_version>="3.10"
|
|
81
|
+
pytest-cov>=7.1.0
|
|
82
82
|
flake8==7.3.0
|
|
83
83
|
mccabe==0.7.0
|
|
84
84
|
pyflakes==3.4.0
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# seleniumbase package
|
|
2
|
-
__version__ = "4.47.
|
|
2
|
+
__version__ = "4.47.5"
|
|
@@ -296,6 +296,7 @@ def extend_driver(
|
|
|
296
296
|
driver.switch_to_tab = DM.switch_to_tab
|
|
297
297
|
driver.switch_to_frame = DM.switch_to_frame
|
|
298
298
|
driver.reset_window_size = DM.reset_window_size
|
|
299
|
+
driver.stop = driver.quit
|
|
299
300
|
if recorder_ext:
|
|
300
301
|
from seleniumbase.js_code.recorder_js import recorder_js
|
|
301
302
|
recorder_code = (
|
|
@@ -391,7 +391,7 @@ class CDPMethods():
|
|
|
391
391
|
|
|
392
392
|
def select_all(self, selector, timeout=None):
|
|
393
393
|
if not timeout:
|
|
394
|
-
timeout = settings.
|
|
394
|
+
timeout = settings.MINI_TIMEOUT
|
|
395
395
|
self.__add_light_pause()
|
|
396
396
|
selector = self.__convert_to_css_if_xpath(selector)
|
|
397
397
|
if not self.is_element_present(selector):
|
|
@@ -414,12 +414,12 @@ class CDPMethods():
|
|
|
414
414
|
|
|
415
415
|
def find_elements(self, selector, timeout=None):
|
|
416
416
|
if not timeout:
|
|
417
|
-
timeout = settings.
|
|
417
|
+
timeout = settings.MINI_TIMEOUT
|
|
418
418
|
return self.select_all(selector, timeout=timeout)
|
|
419
419
|
|
|
420
420
|
def find_visible_elements(self, selector, timeout=None):
|
|
421
421
|
if not timeout:
|
|
422
|
-
timeout = settings.
|
|
422
|
+
timeout = settings.MINI_TIMEOUT
|
|
423
423
|
visible_elements = []
|
|
424
424
|
elements = self.select_all(selector, timeout=timeout)
|
|
425
425
|
for element in elements:
|
|
@@ -1335,7 +1335,7 @@ class CDPMethods():
|
|
|
1335
1335
|
def get_window(self):
|
|
1336
1336
|
return self.loop.run_until_complete(self.page.get_window())
|
|
1337
1337
|
|
|
1338
|
-
def get_text(self, selector):
|
|
1338
|
+
def get_text(self, selector="body"):
|
|
1339
1339
|
return self.find_element(selector).text_all
|
|
1340
1340
|
|
|
1341
1341
|
def get_title(self):
|
|
@@ -39,14 +39,22 @@ def deconstruct_browser():
|
|
|
39
39
|
for _ in __registered__instances__:
|
|
40
40
|
if not _.stopped:
|
|
41
41
|
_.stop(deconstruct=True)
|
|
42
|
-
|
|
42
|
+
max_attempts = 5
|
|
43
|
+
for attempt in range(max_attempts):
|
|
43
44
|
try:
|
|
44
45
|
if _.config and not _.config.uses_custom_data_dir:
|
|
45
|
-
|
|
46
|
+
if os.path.exists(_.config.user_data_dir):
|
|
47
|
+
shutil.rmtree(
|
|
48
|
+
_.config.user_data_dir, ignore_errors=False
|
|
49
|
+
)
|
|
50
|
+
if not os.path.exists(_.config.user_data_dir):
|
|
51
|
+
break
|
|
52
|
+
else:
|
|
53
|
+
time.sleep(0.12)
|
|
46
54
|
except FileNotFoundError:
|
|
47
55
|
break
|
|
48
56
|
except (PermissionError, OSError) as e:
|
|
49
|
-
if attempt ==
|
|
57
|
+
if attempt == max_attempts - 1:
|
|
50
58
|
logger.debug(
|
|
51
59
|
"Problem removing data dir %s\n"
|
|
52
60
|
"Consider checking whether it's there "
|
|
@@ -54,7 +62,7 @@ def deconstruct_browser():
|
|
|
54
62
|
% (_.config.user_data_dir, e)
|
|
55
63
|
)
|
|
56
64
|
break
|
|
57
|
-
time.sleep(0.
|
|
65
|
+
time.sleep(0.12)
|
|
58
66
|
continue
|
|
59
67
|
logging.debug("Temp profile %s was removed." % _.config.user_data_dir)
|
|
60
68
|
|
|
@@ -207,7 +215,8 @@ class Browser:
|
|
|
207
215
|
target_info = event.target_info
|
|
208
216
|
current_tab = next(
|
|
209
217
|
filter(
|
|
210
|
-
lambda item: item.target_id == target_info.target_id,
|
|
218
|
+
lambda item: item.target_id == target_info.target_id,
|
|
219
|
+
self.targets,
|
|
211
220
|
)
|
|
212
221
|
)
|
|
213
222
|
current_target = current_tab.target
|
|
@@ -583,11 +592,11 @@ class Browser:
|
|
|
583
592
|
else "c:/path/to/your/browser.exe"
|
|
584
593
|
)
|
|
585
594
|
)
|
|
586
|
-
if getattr(self.config, "_extensions", None):
|
|
595
|
+
if getattr(self.config, "_extensions", None):
|
|
587
596
|
self.config.add_argument(
|
|
588
597
|
"--load-extension=%s"
|
|
589
598
|
% ",".join(str(_) for _ in self.config._extensions)
|
|
590
|
-
)
|
|
599
|
+
)
|
|
591
600
|
exe = self.config.browser_executable_path
|
|
592
601
|
params = self.config()
|
|
593
602
|
logger.debug(
|
|
@@ -613,16 +622,17 @@ class Browser:
|
|
|
613
622
|
await asyncio.sleep(0.05)
|
|
614
623
|
get_registered_instances().add(self)
|
|
615
624
|
await asyncio.sleep(0.15)
|
|
616
|
-
|
|
625
|
+
max_attempts = 20
|
|
626
|
+
for attempt in range(max_attempts):
|
|
617
627
|
try:
|
|
618
628
|
self.info = ContraDict(
|
|
619
629
|
await self._http.get("version"), silent=True
|
|
620
630
|
)
|
|
621
631
|
except (Exception,):
|
|
622
|
-
if attempt ==
|
|
632
|
+
if attempt == max_attempts - 1:
|
|
623
633
|
logger.debug("Could not start", exc_info=True)
|
|
624
634
|
else:
|
|
625
|
-
await self.sleep(0.
|
|
635
|
+
await self.sleep(0.2)
|
|
626
636
|
else:
|
|
627
637
|
break
|
|
628
638
|
if not self.info:
|
|
@@ -644,9 +654,11 @@ class Browser:
|
|
|
644
654
|
%s
|
|
645
655
|
""" % (dashes, message, dashes)
|
|
646
656
|
)
|
|
657
|
+
await asyncio.sleep(0.03)
|
|
647
658
|
self.connection = Connection(
|
|
648
659
|
self.info.webSocketDebuggerUrl, browser=self
|
|
649
660
|
)
|
|
661
|
+
await asyncio.sleep(0.03)
|
|
650
662
|
if self.config.autodiscover_targets:
|
|
651
663
|
logger.debug("Enabling autodiscover targets")
|
|
652
664
|
self.connection.handlers[cdp.target.TargetInfoChanged] = [
|
|
@@ -115,13 +115,22 @@ def __activate_virtual_display_as_needed(
|
|
|
115
115
|
"Starting VDisplay from cdp_util: (%s, %s)"
|
|
116
116
|
% (_xvfb_width, _xvfb_height)
|
|
117
117
|
)
|
|
118
|
-
|
|
118
|
+
try:
|
|
119
|
+
_xvfb_display.start()
|
|
120
|
+
except Exception:
|
|
121
|
+
time.sleep(0.03)
|
|
122
|
+
_xvfb_display.start()
|
|
123
|
+
time.sleep(0.03)
|
|
119
124
|
if "DISPLAY" not in os.environ.keys():
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
+
time.sleep(0.03)
|
|
126
|
+
_xvfb_display.start()
|
|
127
|
+
time.sleep(0.08)
|
|
128
|
+
if "DISPLAY" not in os.environ.keys():
|
|
129
|
+
print(
|
|
130
|
+
"\n X11 display failed! Is Xvfb installed? "
|
|
131
|
+
"\n Try this: `sudo apt install -y xvfb`"
|
|
132
|
+
)
|
|
133
|
+
__activate_standard_virtual_display()
|
|
125
134
|
else:
|
|
126
135
|
sb_config._virtual_display = _xvfb_display
|
|
127
136
|
sb_config.headless_active = True
|
|
@@ -781,15 +790,14 @@ async def create_from_driver(driver) -> Browser:
|
|
|
781
790
|
|
|
782
791
|
|
|
783
792
|
def free_port() -> int:
|
|
784
|
-
"""
|
|
793
|
+
"""Find and return a free port number assigned by the OS."""
|
|
785
794
|
import socket
|
|
786
795
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
return port
|
|
796
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
797
|
+
# Binding to port 0 lets the OS pick a free port
|
|
798
|
+
s.bind(("127.0.0.1", 0))
|
|
799
|
+
s.listen(5)
|
|
800
|
+
return s.getsockname()[1]
|
|
793
801
|
|
|
794
802
|
|
|
795
803
|
def filter_recurse_all(
|