seleniumbase 4.49.0__tar.gz → 4.49.2__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.49.0/seleniumbase.egg-info → seleniumbase-4.49.2}/PKG-INFO +67 -31
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/README.md +58 -23
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/requirements.txt +3 -2
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/browser_launcher.py +9 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/sb_cdp.py +18 -14
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/sb_driver.py +18 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/base_case.py +58 -3
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/__init__.py +24 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/cdp_driver/browser.py +25 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/cdp_driver/tab.py +7 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2/seleniumbase.egg-info}/PKG-INFO +67 -31
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase.egg-info/requires.txt +10 -6
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/setup.py +10 -14
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/.gitignore +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/LICENSE +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/MANIFEST.in +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/install.sh +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/pyproject.toml +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/pytest.ini +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/sbase/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/sbase/__main__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/sbase/steps.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/nest_asyncio.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/page_actions.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/pytest_plugin.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/sb_manager.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/setup.cfg +0 -0
- {seleniumbase-4.49.0 → seleniumbase-4.49.2}/virtualenv_install.sh +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.49.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 4.49.2
|
|
4
|
+
Summary: A framework for stealthy Chromium automation with CDP Mode. Includes CAPTCHA-bypass, E2E Testing, and a Playwright integration.
|
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
|
6
6
|
Author: Michael Mintz
|
|
7
7
|
Author-email: mdmintz@gmail.com
|
|
@@ -16,7 +16,7 @@ Project-URL: PyPI, https://pypi.org/project/seleniumbase/
|
|
|
16
16
|
Project-URL: Source, https://github.com/seleniumbase/SeleniumBase
|
|
17
17
|
Project-URL: Repository, https://github.com/seleniumbase/SeleniumBase
|
|
18
18
|
Project-URL: Documentation, https://seleniumbase.io/
|
|
19
|
-
Keywords: pytest,selenium,framework,automation,browser,testing,webdriver,seleniumbase,sbase,web-crawling,web-scraping,
|
|
19
|
+
Keywords: pytest,selenium,framework,automation,browser,testing,webdriver,seleniumbase,sbase,web-crawling,web-scraping,stealth,chromium,playwright,undetected,bot-detection,fingerprint,recaptcha,cloudflare,turnstile,datadome,captcha,headless
|
|
20
20
|
Platform: Windows
|
|
21
21
|
Platform: Linux
|
|
22
22
|
Platform: Mac OS-X
|
|
@@ -65,7 +65,7 @@ Requires-Dist: setuptools~=70.2; python_version < "3.10"
|
|
|
65
65
|
Requires-Dist: setuptools>=82.0.1; python_version >= "3.10"
|
|
66
66
|
Requires-Dist: wheel>=0.47.0
|
|
67
67
|
Requires-Dist: attrs>=26.1.0
|
|
68
|
-
Requires-Dist: certifi>=2026.
|
|
68
|
+
Requires-Dist: certifi>=2026.5.20
|
|
69
69
|
Requires-Dist: exceptiongroup>=1.3.1
|
|
70
70
|
Requires-Dist: websockets~=15.0.1; python_version < "3.10"
|
|
71
71
|
Requires-Dist: websockets>=16.0; python_version >= "3.10"
|
|
@@ -84,12 +84,13 @@ Requires-Dist: six>=1.17.0
|
|
|
84
84
|
Requires-Dist: parse>=1.22.0
|
|
85
85
|
Requires-Dist: parse-type>=0.6.6
|
|
86
86
|
Requires-Dist: colorama>=0.4.6
|
|
87
|
+
Requires-Dist: psutil>=7.2.2
|
|
87
88
|
Requires-Dist: pyyaml>=6.0.3
|
|
88
89
|
Requires-Dist: pygments>=2.20.0
|
|
89
90
|
Requires-Dist: pyreadline3>=3.5.4; platform_system == "Windows"
|
|
90
91
|
Requires-Dist: tabcompleter>=1.4.1
|
|
91
92
|
Requires-Dist: pdbp>=1.8.2
|
|
92
|
-
Requires-Dist: idna>=3.
|
|
93
|
+
Requires-Dist: idna>=3.16
|
|
93
94
|
Requires-Dist: charset-normalizer<4,>=3.4.7
|
|
94
95
|
Requires-Dist: urllib3<2,>=1.26.20; python_version < "3.10"
|
|
95
96
|
Requires-Dist: urllib3<3,>=2.7.0; python_version >= "3.10"
|
|
@@ -166,9 +167,9 @@ Requires-Dist: pip-system-certs==4.0; platform_system == "Windows" and extra ==
|
|
|
166
167
|
Provides-Extra: proxy
|
|
167
168
|
Requires-Dist: proxy.py==2.4.3; extra == "proxy"
|
|
168
169
|
Provides-Extra: playwright
|
|
169
|
-
Requires-Dist: playwright>=1.
|
|
170
|
-
|
|
171
|
-
Requires-Dist:
|
|
170
|
+
Requires-Dist: playwright>=1.60.0; extra == "playwright"
|
|
171
|
+
Requires-Dist: greenlet>=3.2.5; python_version < "3.10" and extra == "playwright"
|
|
172
|
+
Requires-Dist: greenlet>=3.5.1; python_version >= "3.10" and extra == "playwright"
|
|
172
173
|
Provides-Extra: pyautogui
|
|
173
174
|
Requires-Dist: PyAutoGUI>=0.9.54; platform_system != "Linux" and extra == "pyautogui"
|
|
174
175
|
Provides-Extra: selenium-stealth
|
|
@@ -208,19 +209,12 @@ Dynamic: summary
|
|
|
208
209
|
<meta property="og:image" content="https://seleniumbase.github.io/cdn/img/mac_sb_logo_5b.png" />
|
|
209
210
|
<link rel="icon" href="https://seleniumbase.github.io/img/logo7.png" />
|
|
210
211
|
|
|
211
|
-
<h1>SeleniumBase</h1>
|
|
212
|
-
|
|
213
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>
|
|
214
213
|
|
|
215
214
|
<p align="center"><a href="https://pypi.python.org/pypi/seleniumbase" target="_blank"><img src="https://img.shields.io/pypi/v/seleniumbase.svg?color=3399EE" alt="PyPI version" /></a> <a href="https://pepy.tech/projects/seleniumbase?timeRange=threeMonths&category=version&includeCIDownloads=true&granularity=daily&viewType=line&versions=*" target="_blank"><img src="https://static.pepy.tech/badge/seleniumbase" alt="SeleniumBase PyPI downloads" /></a> <a href="https://discord.gg/EdhQTn3EyE" target="_blank"><img src="https://img.shields.io/discord/727927627830001734?color=7289DA&label=Discord&logo=discord&logoColor=white"/></a><br /> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-22BBCC.svg" title="SeleniumBase" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/actions" target="_blank"><img src="https://github.com/seleniumbase/SeleniumBase/workflows/CI%20build/badge.svg" alt="SeleniumBase GitHub Actions" /></a> <a href="https://seleniumbase.io"><img src="https://img.shields.io/badge/docs-seleniumbase.io-11BBAA.svg" alt="SeleniumBase Docs" /></a></p>
|
|
216
215
|
<p align="center"></p>
|
|
217
216
|
|
|
218
|
-
<h3 align="center">Stealthy
|
|
219
|
-
|
|
220
|
-
<table align="center"><tr><td>
|
|
221
|
-
<b>Verified using multiple different Chromium browsers:<br />Chrome, Chrome-for-Testing, Chromium, Edge, Brave.</b>
|
|
222
|
-
</td></tr></table>
|
|
223
|
-
|
|
217
|
+
<h3 align="center">Stealthy Chromium Automation and E2E Testing.</h3>
|
|
224
218
|
|
|
225
219
|
<p align="center">
|
|
226
220
|
<a href="#python_installation">🚀 Start</a> |
|
|
@@ -240,7 +234,7 @@ Dynamic: summary
|
|
|
240
234
|
<a href="https://seleniumbase.io/demo_page">📰 TestPage</a> |
|
|
241
235
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">👤 UC Mode</a> |
|
|
242
236
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">🐙 CDP Mode</a> |
|
|
243
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/chart_maker/ReadMe.md">📶 Charts</a>
|
|
237
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/chart_maker/ReadMe.md">📶 Charts</a> |
|
|
244
238
|
<a href="https://seleniumbase.io/devices/?url=seleniumbase.com">🖥️ Farm</a>
|
|
245
239
|
<br />
|
|
246
240
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/how_it_works.md">👁️ How</a> |
|
|
@@ -258,11 +252,44 @@ Dynamic: summary
|
|
|
258
252
|
<br />
|
|
259
253
|
</p>
|
|
260
254
|
|
|
261
|
-
🐙 <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> bypasses bot-detection and handles CAPTCHAs
|
|
255
|
+
🐙 <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> <b>bypasses bot-detection</b> and handles CAPTCHAs with the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome DevTools Protocol</a>. 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 extends CDP Mode's anti-detection to <b>Playwright</b> scripts. <b><code>sb.solve_captcha()</code></b> handles CAPTCHAs that aren't bypassed automatically.
|
|
256
|
+
|
|
257
|
+
<b>Python sync version of SeleniumBase's CDP Mode: (<code>sb_cdp</code>)</b>
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
from seleniumbase import sb_cdp
|
|
261
|
+
|
|
262
|
+
sb = sb_cdp.Chrome()
|
|
263
|
+
sb.open("https://demo.fingerprint.com/playground")
|
|
264
|
+
sb.sleep(3)
|
|
265
|
+
sb.driver.quit()
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
<b>Playwright can use SeleniumBase's stealth browser:</b>
|
|
262
269
|
|
|
263
|
-
|
|
270
|
+
```python
|
|
271
|
+
from playwright.sync_api import sync_playwright
|
|
272
|
+
from seleniumbase import sb_cdp
|
|
264
273
|
|
|
265
|
-
|
|
274
|
+
sb = sb_cdp.Chrome()
|
|
275
|
+
endpoint_url = sb.get_endpoint_url()
|
|
276
|
+
|
|
277
|
+
with sync_playwright() as p:
|
|
278
|
+
browser = p.chromium.connect_over_cdp(endpoint_url)
|
|
279
|
+
page = browser.contexts[0].pages[0]
|
|
280
|
+
page.goto("https://browserscan.net/bot-detection")
|
|
281
|
+
|
|
282
|
+
sb.sleep(3)
|
|
283
|
+
sb.driver.quit()
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
--------
|
|
287
|
+
|
|
288
|
+
📚 The [SeleniumBase/examples/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder includes over 150 ready-to-run examples of E2E testing. Examples that start with `test_` or end with `_test.py`/`_tests.py` run with `pytest`. Other examples run directly with raw `python` (those generally start with `raw_` to avoid confusion).
|
|
289
|
+
|
|
290
|
+
🥷 Stealthy CDP Mode examples are located in [./examples/cdp_mode/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
|
|
291
|
+
|
|
292
|
+
🎭 Stealthy Playwright examples are located in [./examples/cdp_mode/playwright/](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/).
|
|
266
293
|
|
|
267
294
|
--------
|
|
268
295
|
|
|
@@ -279,17 +306,17 @@ Dynamic: summary
|
|
|
279
306
|
```python
|
|
280
307
|
from seleniumbase import sb_cdp
|
|
281
308
|
|
|
282
|
-
|
|
283
|
-
sb
|
|
284
|
-
sb.flash("Test Results", duration=
|
|
309
|
+
sb = sb_cdp.Chrome(locale="en", ad_block=True)
|
|
310
|
+
sb.open("https://browserscan.net/bot-detection")
|
|
311
|
+
sb.flash("Test Results", duration=1.5, pause=0.5)
|
|
285
312
|
sb.assert_element('strong:contains("Normal")')
|
|
286
|
-
print("Bot Not
|
|
287
|
-
sb.flash('strong:contains("Normal")',
|
|
313
|
+
print("Bot Not Detected")
|
|
314
|
+
sb.flash('strong:contains("Normal")', pause=1)
|
|
288
315
|
```
|
|
289
316
|
|
|
290
317
|
<img src="https://seleniumbase.github.io/other/b_scan_results.jpg" width="628" alt="Stealthy architecture flowchart" />
|
|
291
318
|
|
|
292
|
-
📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/raw_browserscan_sync.py">This</a>
|
|
319
|
+
📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/raw_browserscan_sync.py">This example</a> demonstrates the drop-in patch that makes Playwright stealthy:
|
|
293
320
|
|
|
294
321
|
```python
|
|
295
322
|
from playwright.sync_api import sync_playwright
|
|
@@ -301,16 +328,19 @@ endpoint_url = sb.get_endpoint_url()
|
|
|
301
328
|
with sync_playwright() as p:
|
|
302
329
|
browser = p.chromium.connect_over_cdp(endpoint_url)
|
|
303
330
|
page = browser.contexts[0].pages[0]
|
|
304
|
-
page.goto("https://
|
|
331
|
+
page.goto("https://browserscan.net/bot-detection")
|
|
305
332
|
page.wait_for_timeout(500)
|
|
306
|
-
sb.flash("Test Results", duration=
|
|
333
|
+
sb.flash("Test Results", duration=1.5, pause=0.5)
|
|
307
334
|
sb.assert_element('strong:contains("Normal")')
|
|
308
|
-
|
|
335
|
+
print("Bot Not Detected")
|
|
336
|
+
sb.flash('strong:contains("Normal")', pause=1)
|
|
309
337
|
```
|
|
310
338
|
|
|
311
339
|
--------
|
|
312
340
|
|
|
313
|
-
|
|
341
|
+
<h3 align="left">🌐 CLI Options for Supported Chromium Browsers</h3>
|
|
342
|
+
|
|
343
|
+
💡 You can set which Chromium browser to use via command-line options:
|
|
314
344
|
|
|
315
345
|
```zsh
|
|
316
346
|
python SCRIPT.py --use-chromium # Use the unbranded Chromium browser
|
|
@@ -319,7 +349,13 @@ python SCRIPT.py --edge # Use Microsoft Edge
|
|
|
319
349
|
python SCRIPT.py --brave # Use Brave browser
|
|
320
350
|
```
|
|
321
351
|
|
|
322
|
-
|
|
352
|
+
Google Chrome is the default browser if not specified. Only unbranded Chromium and Chrome-for-Testing are installed automatically if not already installed.
|
|
353
|
+
|
|
354
|
+
You can also set the browser via method args, eg: `cft=True`, `use_chromium=True`, `browser="edge"`, `browser="brave"`, etc. Eg:
|
|
355
|
+
|
|
356
|
+
```python
|
|
357
|
+
sb = sb_cdp.Chrome(url, use_chromium=True)
|
|
358
|
+
```
|
|
323
359
|
|
|
324
360
|
--------
|
|
325
361
|
|
|
@@ -7,19 +7,12 @@
|
|
|
7
7
|
<meta property="og:image" content="https://seleniumbase.github.io/cdn/img/mac_sb_logo_5b.png" />
|
|
8
8
|
<link rel="icon" href="https://seleniumbase.github.io/img/logo7.png" />
|
|
9
9
|
|
|
10
|
-
<h1>SeleniumBase</h1>
|
|
11
|
-
|
|
12
10
|
<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
11
|
|
|
14
12
|
<p align="center"><a href="https://pypi.python.org/pypi/seleniumbase" target="_blank"><img src="https://img.shields.io/pypi/v/seleniumbase.svg?color=3399EE" alt="PyPI version" /></a> <a href="https://pepy.tech/projects/seleniumbase?timeRange=threeMonths&category=version&includeCIDownloads=true&granularity=daily&viewType=line&versions=*" target="_blank"><img src="https://static.pepy.tech/badge/seleniumbase" alt="SeleniumBase PyPI downloads" /></a> <a href="https://discord.gg/EdhQTn3EyE" target="_blank"><img src="https://img.shields.io/discord/727927627830001734?color=7289DA&label=Discord&logo=discord&logoColor=white"/></a><br /> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-22BBCC.svg" title="SeleniumBase" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/actions" target="_blank"><img src="https://github.com/seleniumbase/SeleniumBase/workflows/CI%20build/badge.svg" alt="SeleniumBase GitHub Actions" /></a> <a href="https://seleniumbase.io"><img src="https://img.shields.io/badge/docs-seleniumbase.io-11BBAA.svg" alt="SeleniumBase Docs" /></a></p>
|
|
15
13
|
<p align="center"></p>
|
|
16
14
|
|
|
17
|
-
<h3 align="center">Stealthy
|
|
18
|
-
|
|
19
|
-
<table align="center"><tr><td>
|
|
20
|
-
<b>Verified using multiple different Chromium browsers:<br />Chrome, Chrome-for-Testing, Chromium, Edge, Brave.</b>
|
|
21
|
-
</td></tr></table>
|
|
22
|
-
|
|
15
|
+
<h3 align="center">Stealthy Chromium Automation and E2E Testing.</h3>
|
|
23
16
|
|
|
24
17
|
<p align="center">
|
|
25
18
|
<a href="#python_installation">🚀 Start</a> |
|
|
@@ -39,7 +32,7 @@
|
|
|
39
32
|
<a href="https://seleniumbase.io/demo_page">📰 TestPage</a> |
|
|
40
33
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">👤 UC Mode</a> |
|
|
41
34
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">🐙 CDP Mode</a> |
|
|
42
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/chart_maker/ReadMe.md">📶 Charts</a>
|
|
35
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/chart_maker/ReadMe.md">📶 Charts</a> |
|
|
43
36
|
<a href="https://seleniumbase.io/devices/?url=seleniumbase.com">🖥️ Farm</a>
|
|
44
37
|
<br />
|
|
45
38
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/how_it_works.md">👁️ How</a> |
|
|
@@ -57,11 +50,44 @@
|
|
|
57
50
|
<br />
|
|
58
51
|
</p>
|
|
59
52
|
|
|
60
|
-
🐙 <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> bypasses bot-detection and handles CAPTCHAs
|
|
53
|
+
🐙 <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> <b>bypasses bot-detection</b> and handles CAPTCHAs with the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome DevTools Protocol</a>. 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 extends CDP Mode's anti-detection to <b>Playwright</b> scripts. <b><code>sb.solve_captcha()</code></b> handles CAPTCHAs that aren't bypassed automatically.
|
|
54
|
+
|
|
55
|
+
<b>Python sync version of SeleniumBase's CDP Mode: (<code>sb_cdp</code>)</b>
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from seleniumbase import sb_cdp
|
|
59
|
+
|
|
60
|
+
sb = sb_cdp.Chrome()
|
|
61
|
+
sb.open("https://demo.fingerprint.com/playground")
|
|
62
|
+
sb.sleep(3)
|
|
63
|
+
sb.driver.quit()
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
<b>Playwright can use SeleniumBase's stealth browser:</b>
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
```python
|
|
69
|
+
from playwright.sync_api import sync_playwright
|
|
70
|
+
from seleniumbase import sb_cdp
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
sb = sb_cdp.Chrome()
|
|
73
|
+
endpoint_url = sb.get_endpoint_url()
|
|
74
|
+
|
|
75
|
+
with sync_playwright() as p:
|
|
76
|
+
browser = p.chromium.connect_over_cdp(endpoint_url)
|
|
77
|
+
page = browser.contexts[0].pages[0]
|
|
78
|
+
page.goto("https://browserscan.net/bot-detection")
|
|
79
|
+
|
|
80
|
+
sb.sleep(3)
|
|
81
|
+
sb.driver.quit()
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
--------
|
|
85
|
+
|
|
86
|
+
📚 The [SeleniumBase/examples/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder includes over 150 ready-to-run examples of E2E testing. Examples that start with `test_` or end with `_test.py`/`_tests.py` run with `pytest`. Other examples run directly with raw `python` (those generally start with `raw_` to avoid confusion).
|
|
87
|
+
|
|
88
|
+
🥷 Stealthy CDP Mode examples are located in [./examples/cdp_mode/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
|
|
89
|
+
|
|
90
|
+
🎭 Stealthy Playwright examples are located in [./examples/cdp_mode/playwright/](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/).
|
|
65
91
|
|
|
66
92
|
--------
|
|
67
93
|
|
|
@@ -78,17 +104,17 @@
|
|
|
78
104
|
```python
|
|
79
105
|
from seleniumbase import sb_cdp
|
|
80
106
|
|
|
81
|
-
|
|
82
|
-
sb
|
|
83
|
-
sb.flash("Test Results", duration=
|
|
107
|
+
sb = sb_cdp.Chrome(locale="en", ad_block=True)
|
|
108
|
+
sb.open("https://browserscan.net/bot-detection")
|
|
109
|
+
sb.flash("Test Results", duration=1.5, pause=0.5)
|
|
84
110
|
sb.assert_element('strong:contains("Normal")')
|
|
85
|
-
print("Bot Not
|
|
86
|
-
sb.flash('strong:contains("Normal")',
|
|
111
|
+
print("Bot Not Detected")
|
|
112
|
+
sb.flash('strong:contains("Normal")', pause=1)
|
|
87
113
|
```
|
|
88
114
|
|
|
89
115
|
<img src="https://seleniumbase.github.io/other/b_scan_results.jpg" width="628" alt="Stealthy architecture flowchart" />
|
|
90
116
|
|
|
91
|
-
📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/raw_browserscan_sync.py">This</a>
|
|
117
|
+
📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/raw_browserscan_sync.py">This example</a> demonstrates the drop-in patch that makes Playwright stealthy:
|
|
92
118
|
|
|
93
119
|
```python
|
|
94
120
|
from playwright.sync_api import sync_playwright
|
|
@@ -100,16 +126,19 @@ endpoint_url = sb.get_endpoint_url()
|
|
|
100
126
|
with sync_playwright() as p:
|
|
101
127
|
browser = p.chromium.connect_over_cdp(endpoint_url)
|
|
102
128
|
page = browser.contexts[0].pages[0]
|
|
103
|
-
page.goto("https://
|
|
129
|
+
page.goto("https://browserscan.net/bot-detection")
|
|
104
130
|
page.wait_for_timeout(500)
|
|
105
|
-
sb.flash("Test Results", duration=
|
|
131
|
+
sb.flash("Test Results", duration=1.5, pause=0.5)
|
|
106
132
|
sb.assert_element('strong:contains("Normal")')
|
|
107
|
-
|
|
133
|
+
print("Bot Not Detected")
|
|
134
|
+
sb.flash('strong:contains("Normal")', pause=1)
|
|
108
135
|
```
|
|
109
136
|
|
|
110
137
|
--------
|
|
111
138
|
|
|
112
|
-
|
|
139
|
+
<h3 align="left">🌐 CLI Options for Supported Chromium Browsers</h3>
|
|
140
|
+
|
|
141
|
+
💡 You can set which Chromium browser to use via command-line options:
|
|
113
142
|
|
|
114
143
|
```zsh
|
|
115
144
|
python SCRIPT.py --use-chromium # Use the unbranded Chromium browser
|
|
@@ -118,7 +147,13 @@ python SCRIPT.py --edge # Use Microsoft Edge
|
|
|
118
147
|
python SCRIPT.py --brave # Use Brave browser
|
|
119
148
|
```
|
|
120
149
|
|
|
121
|
-
|
|
150
|
+
Google Chrome is the default browser if not specified. Only unbranded Chromium and Chrome-for-Testing are installed automatically if not already installed.
|
|
151
|
+
|
|
152
|
+
You can also set the browser via method args, eg: `cft=True`, `use_chromium=True`, `browser="edge"`, `browser="brave"`, etc. Eg:
|
|
153
|
+
|
|
154
|
+
```python
|
|
155
|
+
sb = sb_cdp.Chrome(url, use_chromium=True)
|
|
156
|
+
```
|
|
122
157
|
|
|
123
158
|
--------
|
|
124
159
|
|
|
@@ -5,7 +5,7 @@ setuptools~=70.2;python_version<"3.10"
|
|
|
5
5
|
setuptools>=82.0.1;python_version>="3.10"
|
|
6
6
|
wheel>=0.47.0
|
|
7
7
|
attrs>=26.1.0
|
|
8
|
-
certifi>=2026.
|
|
8
|
+
certifi>=2026.5.20
|
|
9
9
|
exceptiongroup>=1.3.1
|
|
10
10
|
websockets~=15.0.1;python_version<"3.10"
|
|
11
11
|
websockets>=16.0;python_version>="3.10"
|
|
@@ -24,12 +24,13 @@ six>=1.17.0
|
|
|
24
24
|
parse>=1.22.0
|
|
25
25
|
parse-type>=0.6.6
|
|
26
26
|
colorama>=0.4.6
|
|
27
|
+
psutil>=7.2.2
|
|
27
28
|
pyyaml>=6.0.3
|
|
28
29
|
pygments>=2.20.0
|
|
29
30
|
pyreadline3>=3.5.4;platform_system=="Windows"
|
|
30
31
|
tabcompleter>=1.4.1
|
|
31
32
|
pdbp>=1.8.2
|
|
32
|
-
idna>=3.
|
|
33
|
+
idna>=3.16
|
|
33
34
|
charset-normalizer>=3.4.7,<4
|
|
34
35
|
urllib3>=1.26.20,<2;python_version<"3.10"
|
|
35
36
|
urllib3>=2.7.0,<3;python_version>="3.10"
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# seleniumbase package
|
|
2
|
-
__version__ = "4.49.
|
|
2
|
+
__version__ = "4.49.2"
|
|
@@ -176,8 +176,11 @@ def extend_driver(
|
|
|
176
176
|
driver.forward = DM.forward
|
|
177
177
|
driver.refresh = DM.refresh
|
|
178
178
|
driver.locator = DM.locator
|
|
179
|
+
driver.select = DM.select
|
|
180
|
+
driver.select_all = DM.select_all
|
|
179
181
|
page = types.SimpleNamespace()
|
|
180
182
|
page.open = DM.open_url
|
|
183
|
+
page.goto = DM.open_url
|
|
181
184
|
page.click = DM.click
|
|
182
185
|
page.click_link = DM.click_link
|
|
183
186
|
page.click_if_visible = DM.click_if_visible
|
|
@@ -210,6 +213,8 @@ def extend_driver(
|
|
|
210
213
|
page.find_element = DM.find_element
|
|
211
214
|
page.find_elements = DM.find_elements
|
|
212
215
|
page.locator = DM.locator
|
|
216
|
+
page.select = DM.select
|
|
217
|
+
page.select_all = DM.select_all
|
|
213
218
|
page.get_current_url = DM.get_current_url
|
|
214
219
|
page.get_page_source = DM.get_page_source
|
|
215
220
|
page.get_title = DM.get_title
|
|
@@ -231,6 +236,7 @@ def extend_driver(
|
|
|
231
236
|
js.highlight = DM.highlight
|
|
232
237
|
driver.js = js
|
|
233
238
|
driver.open = DM.open_url
|
|
239
|
+
driver.goto = DM.open_url
|
|
234
240
|
driver.click = DM.click
|
|
235
241
|
driver.click_link = DM.click_link
|
|
236
242
|
driver.click_if_visible = DM.click_if_visible
|
|
@@ -291,6 +297,7 @@ def extend_driver(
|
|
|
291
297
|
driver.switch_to_default_window = DM.switch_to_default_window
|
|
292
298
|
driver.switch_to_newest_window = DM.switch_to_newest_window
|
|
293
299
|
driver.open_new_window = DM.open_new_window
|
|
300
|
+
driver.switch_to_newest_tab = DM.switch_to_newest_tab
|
|
294
301
|
driver.open_new_tab = DM.open_new_tab
|
|
295
302
|
driver.switch_to_window = DM.switch_to_window
|
|
296
303
|
driver.switch_to_tab = DM.switch_to_tab
|
|
@@ -759,6 +766,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
759
766
|
CDPM = sb_cdp.CDPMethods(loop, page, driver)
|
|
760
767
|
cdp.get = CDPM.get
|
|
761
768
|
cdp.open = CDPM.open
|
|
769
|
+
cdp.goto = CDPM.goto
|
|
762
770
|
cdp.reload = CDPM.reload
|
|
763
771
|
cdp.refresh = CDPM.refresh
|
|
764
772
|
cdp.add_handler = CDPM.add_handler
|
|
@@ -972,6 +980,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
972
980
|
driver.solve_captcha = CDPM.solve_captcha
|
|
973
981
|
driver.click_captcha = CDPM.click_captcha
|
|
974
982
|
driver.find_element_by_text = CDPM.find_element_by_text
|
|
983
|
+
driver.flash = CDPM.flash
|
|
975
984
|
driver._is_using_cdp = True
|
|
976
985
|
if (
|
|
977
986
|
getattr(sb_config, "_cdp_proxy", None)
|
|
@@ -155,6 +155,9 @@ class CDPMethods():
|
|
|
155
155
|
def open(self, url, **kwargs):
|
|
156
156
|
self.get(url, **kwargs)
|
|
157
157
|
|
|
158
|
+
def goto(self, url, **kwargs):
|
|
159
|
+
self.get(url, **kwargs)
|
|
160
|
+
|
|
158
161
|
def reload(self, ignore_cache=True, script_to_evaluate_on_load=None):
|
|
159
162
|
self.loop.run_until_complete(
|
|
160
163
|
self.page.reload(
|
|
@@ -2033,6 +2036,13 @@ class CDPMethods():
|
|
|
2033
2036
|
self.__slow_mode_pause_if_set()
|
|
2034
2037
|
self.loop.run_until_complete(self.page.wait(0.2))
|
|
2035
2038
|
|
|
2039
|
+
def quit(self):
|
|
2040
|
+
"""Quit the browser in the Pure CDP Mode Sync format."""
|
|
2041
|
+
driver = self.driver
|
|
2042
|
+
if hasattr(driver, "cdp_base"):
|
|
2043
|
+
driver = driver.cdp_base
|
|
2044
|
+
driver.quit()
|
|
2045
|
+
|
|
2036
2046
|
def _on_a_cf_turnstile_page(self, source=None):
|
|
2037
2047
|
if not source or len(source) < 400:
|
|
2038
2048
|
time.sleep(0.2)
|
|
@@ -2325,28 +2335,22 @@ class CDPMethods():
|
|
|
2325
2335
|
'form div:not([class]):has(input[name*="cf-turn"])'
|
|
2326
2336
|
):
|
|
2327
2337
|
selector = 'form div:not([class]):has(input[name*="cf-turn"])'
|
|
2328
|
-
elif self.is_element_present("form div:not(:has(*))"):
|
|
2329
|
-
selector = "form div:not(:has(*))"
|
|
2330
2338
|
elif self.is_element_present("body > div#check > div:not([class])"):
|
|
2331
2339
|
selector = "body > div#check > div:not([class])"
|
|
2332
2340
|
elif self.is_element_present(".cf-turnstile-wrapper"):
|
|
2333
2341
|
selector = ".cf-turnstile-wrapper"
|
|
2334
|
-
elif self.is_element_present(
|
|
2335
|
-
'[id*="turnstile"] div:not([class])'
|
|
2336
|
-
):
|
|
2342
|
+
elif self.is_element_present('[id*="turnstile"] div:not([class])'):
|
|
2337
2343
|
selector = '[id*="turnstile"] div:not([class])'
|
|
2338
|
-
elif self.is_element_present(
|
|
2339
|
-
'[class*="turnstile"] div:not([class])'
|
|
2340
|
-
):
|
|
2344
|
+
elif self.is_element_present('[class*="turnstile"] div:not([class])'):
|
|
2341
2345
|
selector = '[class*="turnstile"] div:not([class])'
|
|
2342
|
-
elif self.is_element_present(
|
|
2343
|
-
"iframe[data-hcaptcha-widget-id]"
|
|
2344
|
-
):
|
|
2346
|
+
elif self.is_element_present("iframe[data-hcaptcha-widget-id]"):
|
|
2345
2347
|
selector = "iframe[data-hcaptcha-widget-id]"
|
|
2346
|
-
elif self.is_element_present(
|
|
2347
|
-
'[data-callback="onCaptchaSuccess"]'
|
|
2348
|
-
):
|
|
2348
|
+
elif self.is_element_present('[data-callback="onCaptchaSuccess"]'):
|
|
2349
2349
|
selector = '[data-callback="onCaptchaSuccess"]'
|
|
2350
|
+
elif self.is_element_present('[class*="captcha"] div:not([class])'):
|
|
2351
|
+
selector = '[class*="captcha"] div:not([class])'
|
|
2352
|
+
elif self.is_element_present("form div:not(:has(*))"):
|
|
2353
|
+
selector = "form div:not(:has(*))"
|
|
2350
2354
|
elif self.is_element_present(
|
|
2351
2355
|
"div:not([class]):not([id]):not([aria-label]) > "
|
|
2352
2356
|
"div:not([class]):not([id]):not([aria-label])"
|
|
@@ -41,6 +41,18 @@ class DriverMethods(WebDriver):
|
|
|
41
41
|
value, by = page_utils.swap_selector_and_by_if_reversed(value, by)
|
|
42
42
|
return self.driver.default_find_elements(by=by, value=value)
|
|
43
43
|
|
|
44
|
+
def select(self, *args, **kwargs):
|
|
45
|
+
if self.__is_cdp_swap_needed():
|
|
46
|
+
return self.driver.cdp.select(*args, **kwargs)
|
|
47
|
+
else:
|
|
48
|
+
return self.find_element(*args, **kwargs)
|
|
49
|
+
|
|
50
|
+
def select_all(self, *args, **kwargs):
|
|
51
|
+
if self.__is_cdp_swap_needed():
|
|
52
|
+
return self.driver.cdp.select_all(*args, **kwargs)
|
|
53
|
+
else:
|
|
54
|
+
return self.find_elements(*args, **kwargs)
|
|
55
|
+
|
|
44
56
|
def add_cookie(self, *args, **kwargs):
|
|
45
57
|
page_actions._reconnect_if_disconnected(self.driver)
|
|
46
58
|
self.driver.default_add_cookie(*args, **kwargs)
|
|
@@ -372,6 +384,12 @@ class DriverMethods(WebDriver):
|
|
|
372
384
|
def switch_to_window(self, *args, **kwargs):
|
|
373
385
|
page_actions.switch_to_window(self.driver, *args, **kwargs)
|
|
374
386
|
|
|
387
|
+
def switch_to_newest_tab(self):
|
|
388
|
+
if self.__is_cdp_swap_needed():
|
|
389
|
+
self.driver.cdp.switch_to_newest_tab()
|
|
390
|
+
return
|
|
391
|
+
self.switch_to_newest_window()
|
|
392
|
+
|
|
375
393
|
def switch_to_tab(self, *args, **kwargs):
|
|
376
394
|
self.switch_to_window(*args, **kwargs)
|
|
377
395
|
|
|
@@ -5096,8 +5096,32 @@ class BaseCase(unittest.TestCase):
|
|
|
5096
5096
|
self.solve_captcha = self.cdp.solve_captcha
|
|
5097
5097
|
if hasattr(self.cdp, "click_captcha"):
|
|
5098
5098
|
self.click_captcha = self.cdp.click_captcha
|
|
5099
|
+
if hasattr(self.cdp, "add_handler"):
|
|
5100
|
+
self.add_handler = self.cdp.add_handler
|
|
5101
|
+
if hasattr(self.cdp, "close_active_tab"):
|
|
5102
|
+
self.close_active_tab = self.cdp.close_active_tab
|
|
5099
5103
|
if hasattr(self.cdp, "find_element_by_text"):
|
|
5100
5104
|
self.find_element_by_text = self.cdp.find_element_by_text
|
|
5105
|
+
if hasattr(self.cdp, "flash"):
|
|
5106
|
+
self.flash = self.cdp.flash
|
|
5107
|
+
if hasattr(self.cdp, "get_active_tab"):
|
|
5108
|
+
self.get_active_tab = self.cdp.get_active_tab
|
|
5109
|
+
if hasattr(self.cdp, "get_endpoint_url"):
|
|
5110
|
+
self.get_endpoint_url = self.cdp.get_endpoint_url
|
|
5111
|
+
if hasattr(self.cdp, "get_event_loop"):
|
|
5112
|
+
self.get_event_loop = self.cdp.get_event_loop
|
|
5113
|
+
if hasattr(self.cdp, "get_tabs"):
|
|
5114
|
+
self.get_tabs = self.cdp.get_tabs
|
|
5115
|
+
if hasattr(self.cdp, "gui_click_and_hold"):
|
|
5116
|
+
self.gui_click_and_hold = self.cdp.gui_click_and_hold
|
|
5117
|
+
if hasattr(self.cdp, "gui_click_element"):
|
|
5118
|
+
self.gui_click_element = self.cdp.gui_click_element
|
|
5119
|
+
if hasattr(self.cdp, "gui_drag_and_drop"):
|
|
5120
|
+
self.gui_drag_and_drop = self.cdp.gui_drag_and_drop
|
|
5121
|
+
if hasattr(self.cdp, "gui_drag_drop_points"):
|
|
5122
|
+
self.gui_drag_drop_points = self.cdp.gui_drag_drop_points
|
|
5123
|
+
if hasattr(self.cdp, "highlight_overlay"):
|
|
5124
|
+
self.highlight_overlay = self.cdp.highlight_overlay
|
|
5101
5125
|
if getattr(self.driver, "_is_using_auth", None):
|
|
5102
5126
|
with suppress(Exception):
|
|
5103
5127
|
self.cdp.loop.run_until_complete(self.cdp.page.wait(0.25))
|
|
@@ -8861,9 +8885,22 @@ class BaseCase(unittest.TestCase):
|
|
|
8861
8885
|
element = page_actions.wait_for_element_present(
|
|
8862
8886
|
self.driver, selector, by, timeout
|
|
8863
8887
|
)
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8888
|
+
try:
|
|
8889
|
+
if element.tag_name.lower() in ["input", "textarea"]:
|
|
8890
|
+
self.js_update_text(selector, text, by=by, timeout=timeout)
|
|
8891
|
+
return
|
|
8892
|
+
except (Stale_Exception, ENI_Exception):
|
|
8893
|
+
time.sleep(0.16)
|
|
8894
|
+
if self.__is_cdp_swap_needed():
|
|
8895
|
+
element = self.cdp.select(selector, timeout=timeout)
|
|
8896
|
+
else:
|
|
8897
|
+
self.wait_for_ready_state_complete()
|
|
8898
|
+
element = page_actions.wait_for_element_present(
|
|
8899
|
+
self.driver, selector, by, timeout
|
|
8900
|
+
)
|
|
8901
|
+
if element.tag_name.lower() in ["input", "textarea"]:
|
|
8902
|
+
self.js_update_text(selector, text, by=by, timeout=timeout)
|
|
8903
|
+
return
|
|
8867
8904
|
original_selector = selector
|
|
8868
8905
|
css_selector = self.convert_to_css_selector(selector, by=by)
|
|
8869
8906
|
if scroll:
|
|
@@ -9340,6 +9377,9 @@ class BaseCase(unittest.TestCase):
|
|
|
9340
9377
|
|
|
9341
9378
|
def switch_to_newest_tab(self):
|
|
9342
9379
|
"""Same as self.switch_to_newest_window()"""
|
|
9380
|
+
if self.__is_cdp_swap_needed():
|
|
9381
|
+
self.cdp.switch_to_newest_tab()
|
|
9382
|
+
return
|
|
9343
9383
|
self.switch_to_newest_window()
|
|
9344
9384
|
|
|
9345
9385
|
def save_as_html(self, name, folder=None):
|
|
@@ -9976,6 +10016,8 @@ class BaseCase(unittest.TestCase):
|
|
|
9976
10016
|
self, selector, by="css selector", timeout=None
|
|
9977
10017
|
):
|
|
9978
10018
|
"""Waits for an element to appear in the HTML of a page.
|
|
10019
|
+
Returns the element once it exists in the HTML.
|
|
10020
|
+
Raises an exception if the element doesn't come in time.
|
|
9979
10021
|
The element does not need be visible (it may be hidden)."""
|
|
9980
10022
|
self.__check_scope()
|
|
9981
10023
|
if not timeout:
|
|
@@ -10022,6 +10064,19 @@ class BaseCase(unittest.TestCase):
|
|
|
10022
10064
|
self.driver, selector, by, timeout
|
|
10023
10065
|
)
|
|
10024
10066
|
|
|
10067
|
+
def select(self, selector, by="css selector", timeout=None):
|
|
10068
|
+
"""Returns the element once it appears in the HTML.
|
|
10069
|
+
Raises an exception if the element doesn't come in time.
|
|
10070
|
+
The element does not need be visible (it may be hidden).
|
|
10071
|
+
If CDP Mode has been activated: Calls self.cdp.select().
|
|
10072
|
+
Otherwise: Same as self.wait_for_element_present()."""
|
|
10073
|
+
if self.__is_cdp_swap_needed():
|
|
10074
|
+
return self.cdp.select(selector, timeout=timeout)
|
|
10075
|
+
else:
|
|
10076
|
+
return self.wait_for_element_present(
|
|
10077
|
+
selector, by=by, timeout=timeout
|
|
10078
|
+
)
|
|
10079
|
+
|
|
10025
10080
|
def get_element(self, selector, by="css selector", timeout=None):
|
|
10026
10081
|
"""Same as wait_for_element_present() - returns the element.
|
|
10027
10082
|
The element does not need be visible (it may be hidden)."""
|