seleniumbase 4.44.1__tar.gz → 4.44.15__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.44.1/seleniumbase.egg-info → seleniumbase-4.44.15}/PKG-INFO +28 -22
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/README.md +14 -12
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/requirements.txt +12 -8
- seleniumbase-4.44.15/seleniumbase/__version__.py +2 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/behave/behave_sb.py +8 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/browser_launcher.py +103 -42
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/detect_b_ver.py +8 -6
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/log_helper.py +2 -2
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/report_helper.py +1 -1
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/sb_cdp.py +192 -81
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/sb_driver.py +36 -5
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/base_case.py +121 -36
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/constants.py +1 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/js_utils.py +5 -4
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/page_actions.py +23 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/masterqa/master_qa.py +16 -2
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/base_plugin.py +8 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/driver_manager.py +4 -1
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/pytest_plugin.py +5 -15
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/sb_manager.py +14 -15
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/cdp.py +1 -12
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/cdp_driver/browser.py +205 -99
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/cdp_driver/cdp_util.py +11 -1
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/cdp_driver/config.py +13 -4
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/cdp_driver/connection.py +4 -35
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/cdp_driver/element.py +81 -21
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/cdp_driver/tab.py +14 -23
- {seleniumbase-4.44.1 → seleniumbase-4.44.15/seleniumbase.egg-info}/PKG-INFO +28 -22
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase.egg-info/requires.txt +17 -9
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/setup.py +13 -9
- seleniumbase-4.44.1/seleniumbase/__version__.py +0 -2
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/.gitignore +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/LICENSE +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/MANIFEST.in +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/install.sh +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/pyproject.toml +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/pytest.ini +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/sbase/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/sbase/__main__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/sbase/steps.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/setup.cfg +0 -0
- {seleniumbase-4.44.1 → seleniumbase-4.44.15}/virtualenv_install.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.44.
|
|
3
|
+
Version: 4.44.15
|
|
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
|
|
@@ -67,7 +67,7 @@ Requires-Dist: setuptools>=80.9.0; python_version >= "3.10"
|
|
|
67
67
|
Requires-Dist: wheel>=0.45.1
|
|
68
68
|
Requires-Dist: attrs~=25.3.0; python_version < "3.9"
|
|
69
69
|
Requires-Dist: attrs>=25.4.0; python_version >= "3.9"
|
|
70
|
-
Requires-Dist: certifi>=2025.
|
|
70
|
+
Requires-Dist: certifi>=2025.11.12
|
|
71
71
|
Requires-Dist: exceptiongroup>=1.3.0
|
|
72
72
|
Requires-Dist: websockets~=13.1; python_version < "3.9"
|
|
73
73
|
Requires-Dist: websockets>=15.0.1; python_version >= "3.9"
|
|
@@ -75,7 +75,7 @@ Requires-Dist: filelock~=3.16.1; python_version < "3.9"
|
|
|
75
75
|
Requires-Dist: filelock~=3.19.1; python_version >= "3.9" and python_version < "3.10"
|
|
76
76
|
Requires-Dist: filelock>=3.20.0; python_version >= "3.10"
|
|
77
77
|
Requires-Dist: fasteners>=0.20
|
|
78
|
-
Requires-Dist: mycdp>=1.
|
|
78
|
+
Requires-Dist: mycdp>=1.3.0
|
|
79
79
|
Requires-Dist: pynose>=1.5.5
|
|
80
80
|
Requires-Dist: platformdirs~=4.3.6; python_version < "3.9"
|
|
81
81
|
Requires-Dist: platformdirs~=4.4.0; python_version >= "3.9" and python_version < "3.10"
|
|
@@ -94,7 +94,7 @@ Requires-Dist: pyyaml>=6.0.3
|
|
|
94
94
|
Requires-Dist: pygments>=2.19.2
|
|
95
95
|
Requires-Dist: pyreadline3>=3.5.4; platform_system == "Windows"
|
|
96
96
|
Requires-Dist: tabcompleter>=1.4.0
|
|
97
|
-
Requires-Dist: pdbp>=1.8.
|
|
97
|
+
Requires-Dist: pdbp>=1.8.1
|
|
98
98
|
Requires-Dist: idna>=3.11
|
|
99
99
|
Requires-Dist: chardet==5.2.0
|
|
100
100
|
Requires-Dist: charset-normalizer<4,>=3.4.4
|
|
@@ -106,9 +106,11 @@ Requires-Dist: sniffio==1.3.1
|
|
|
106
106
|
Requires-Dist: h11==0.16.0
|
|
107
107
|
Requires-Dist: outcome==1.3.0.post0
|
|
108
108
|
Requires-Dist: trio==0.27.0; python_version < "3.9"
|
|
109
|
-
Requires-Dist: trio<1,>=0.31.0; python_version >= "3.9"
|
|
109
|
+
Requires-Dist: trio<1,>=0.31.0; python_version >= "3.9" and python_version < "3.10"
|
|
110
|
+
Requires-Dist: trio<1,>=0.32.0; python_version >= "3.10"
|
|
110
111
|
Requires-Dist: trio-websocket~=0.12.2
|
|
111
|
-
Requires-Dist: wsproto==1.2.0
|
|
112
|
+
Requires-Dist: wsproto==1.2.0; python_version < "3.10"
|
|
113
|
+
Requires-Dist: wsproto==1.3.1; python_version >= "3.10"
|
|
112
114
|
Requires-Dist: websocket-client~=1.8.0; python_version < "3.9"
|
|
113
115
|
Requires-Dist: websocket-client~=1.9.0; python_version >= "3.9"
|
|
114
116
|
Requires-Dist: selenium==4.27.1; python_version < "3.9"
|
|
@@ -117,13 +119,15 @@ Requires-Dist: selenium==4.38.0; python_version >= "3.10"
|
|
|
117
119
|
Requires-Dist: cssselect==1.2.0; python_version < "3.9"
|
|
118
120
|
Requires-Dist: cssselect==1.3.0; python_version >= "3.9"
|
|
119
121
|
Requires-Dist: sortedcontainers==2.4.0
|
|
120
|
-
Requires-Dist: execnet==2.1.1
|
|
122
|
+
Requires-Dist: execnet==2.1.1; python_version < "3.10"
|
|
123
|
+
Requires-Dist: execnet==2.1.2; python_version >= "3.10"
|
|
121
124
|
Requires-Dist: iniconfig==2.1.0; python_version < "3.10"
|
|
122
125
|
Requires-Dist: iniconfig==2.3.0; python_version >= "3.10"
|
|
123
126
|
Requires-Dist: pluggy==1.5.0; python_version < "3.9"
|
|
124
127
|
Requires-Dist: pluggy==1.6.0; python_version >= "3.9"
|
|
125
128
|
Requires-Dist: pytest==8.3.5; python_version < "3.9"
|
|
126
|
-
Requires-Dist: pytest==8.4.2; python_version >= "3.9"
|
|
129
|
+
Requires-Dist: pytest==8.4.2; python_version >= "3.9" and python_version < "3.11"
|
|
130
|
+
Requires-Dist: pytest==9.0.1; python_version >= "3.11"
|
|
127
131
|
Requires-Dist: pytest-html==4.0.2
|
|
128
132
|
Requires-Dist: pytest-metadata==3.1.1
|
|
129
133
|
Requires-Dist: pytest-ordering==0.6
|
|
@@ -151,7 +155,7 @@ Requires-Dist: allure-behave>=2.13.5; extra == "allure"
|
|
|
151
155
|
Provides-Extra: coverage
|
|
152
156
|
Requires-Dist: coverage>=7.6.1; python_version < "3.9" and extra == "coverage"
|
|
153
157
|
Requires-Dist: coverage>=7.10.7; (python_version >= "3.9" and python_version < "3.10") and extra == "coverage"
|
|
154
|
-
Requires-Dist: coverage>=7.
|
|
158
|
+
Requires-Dist: coverage>=7.12.0; python_version >= "3.10" and extra == "coverage"
|
|
155
159
|
Requires-Dist: pytest-cov>=5.0.0; python_version < "3.9" and extra == "coverage"
|
|
156
160
|
Requires-Dist: pytest-cov>=7.0.0; python_version >= "3.9" and extra == "coverage"
|
|
157
161
|
Provides-Extra: flake8
|
|
@@ -170,7 +174,7 @@ Requires-Dist: mss==9.0.2; python_version < "3.9" and extra == "mss"
|
|
|
170
174
|
Requires-Dist: mss==10.0.0; python_version >= "3.9" and extra == "mss"
|
|
171
175
|
Provides-Extra: pdfminer
|
|
172
176
|
Requires-Dist: pdfminer.six==20250324; python_version < "3.9" and extra == "pdfminer"
|
|
173
|
-
Requires-Dist: pdfminer.six==
|
|
177
|
+
Requires-Dist: pdfminer.six==20251107; python_version >= "3.9" and extra == "pdfminer"
|
|
174
178
|
Requires-Dist: cryptography==39.0.2; python_version < "3.9" and extra == "pdfminer"
|
|
175
179
|
Requires-Dist: cryptography==46.0.3; python_version >= "3.9" and extra == "pdfminer"
|
|
176
180
|
Requires-Dist: cffi==1.17.1; python_version < "3.9" and extra == "pdfminer"
|
|
@@ -273,29 +277,31 @@ Dynamic: summary
|
|
|
273
277
|
<br />
|
|
274
278
|
</p>
|
|
275
279
|
|
|
276
|
-
<p>SeleniumBase is a browser automation framework
|
|
280
|
+
<p>SeleniumBase is a browser automation framework that empowers software teams to innovate faster and handle modern web challenges with ease. With stealth options like CDP Mode, you'll avoid the usual restrictions imposed by websites deploying bot-detection services.</p>
|
|
277
281
|
|
|
278
282
|
--------
|
|
279
283
|
|
|
280
284
|
📚 Learn from [**over 200 examples** in the **SeleniumBase/examples/** folder](https://github.com/seleniumbase/SeleniumBase/tree/master/examples).
|
|
281
285
|
|
|
282
|
-
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a>
|
|
286
|
+
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></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, solve CAPTCHAs, and call advanced methods from the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome Devtools Protocol</a>.
|
|
283
287
|
|
|
284
|
-
ℹ️
|
|
288
|
+
ℹ️ Many examples run with raw <code translate="no"><b>python</b></code>, although some use <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">Syntax Formats</a> that expect <a href="https://docs.pytest.org/en/latest/how-to/usage.html" translate="no"><b>pytest</b></a> (a Python unit-testing framework included with SeleniumBase that can discover, collect, and run tests automatically).
|
|
285
289
|
|
|
286
290
|
--------
|
|
287
291
|
|
|
288
|
-
<p align="left">📗
|
|
292
|
+
<p align="left">📗 This script performs a Google Search using SeleniumBase UC Mode + CDP Mode:<br /><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">SeleniumBase/examples/raw_google.py</a> (Results are saved as PDF, HTML, and PNG)</p>
|
|
289
293
|
|
|
290
294
|
```python
|
|
291
295
|
from seleniumbase import SB
|
|
292
296
|
|
|
293
|
-
with SB(
|
|
294
|
-
|
|
297
|
+
with SB(uc=True, test=True) as sb:
|
|
298
|
+
url = "https://google.com/ncr"
|
|
299
|
+
sb.activate_cdp_mode(url)
|
|
295
300
|
sb.type('[title="Search"]', "SeleniumBase GitHub page")
|
|
296
301
|
sb.click("div:not([jsname]) > * > input")
|
|
302
|
+
sb.sleep(2)
|
|
297
303
|
print(sb.get_page_title())
|
|
298
|
-
sb.sleep(
|
|
304
|
+
sb.sleep(1) # Wait for the "AI Overview" result
|
|
299
305
|
if sb.is_text_visible("Generating"):
|
|
300
306
|
sb.wait_for_text("AI Overview")
|
|
301
307
|
sb.save_as_pdf_to_logs() # Saved to ./latest_logs/
|
|
@@ -317,8 +323,8 @@ from seleniumbase import SB
|
|
|
317
323
|
with SB(uc=True, test=True, locale="en") as sb:
|
|
318
324
|
url = "https://gitlab.com/users/sign_in"
|
|
319
325
|
sb.activate_cdp_mode(url)
|
|
320
|
-
sb.sleep(2
|
|
321
|
-
sb.
|
|
326
|
+
sb.sleep(2)
|
|
327
|
+
sb.solve_captcha()
|
|
322
328
|
# (The rest is for testing and demo purposes)
|
|
323
329
|
sb.assert_text("Username", '[for="user_login"]', timeout=3)
|
|
324
330
|
sb.assert_element('label[for="user_login"]')
|
|
@@ -335,9 +341,9 @@ with SB(uc=True, test=True, locale="en") as sb:
|
|
|
335
341
|
from seleniumbase import sb_cdp
|
|
336
342
|
|
|
337
343
|
url = "https://gitlab.com/users/sign_in"
|
|
338
|
-
sb = sb_cdp.Chrome(url)
|
|
339
|
-
sb.sleep(2
|
|
340
|
-
sb.
|
|
344
|
+
sb = sb_cdp.Chrome(url, incognito=True)
|
|
345
|
+
sb.sleep(2)
|
|
346
|
+
sb.solve_captcha()
|
|
341
347
|
sb.highlight('h1:contains("GitLab")')
|
|
342
348
|
sb.highlight('button:contains("Sign in")')
|
|
343
349
|
sb.driver.stop()
|
|
@@ -54,29 +54,31 @@
|
|
|
54
54
|
<br />
|
|
55
55
|
</p>
|
|
56
56
|
|
|
57
|
-
<p>SeleniumBase is a browser automation framework
|
|
57
|
+
<p>SeleniumBase is a browser automation framework that empowers software teams to innovate faster and handle modern web challenges with ease. With stealth options like CDP Mode, you'll avoid the usual restrictions imposed by websites deploying bot-detection services.</p>
|
|
58
58
|
|
|
59
59
|
--------
|
|
60
60
|
|
|
61
61
|
📚 Learn from [**over 200 examples** in the **SeleniumBase/examples/** folder](https://github.com/seleniumbase/SeleniumBase/tree/master/examples).
|
|
62
62
|
|
|
63
|
-
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a>
|
|
63
|
+
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></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, solve CAPTCHAs, and call advanced methods from the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome Devtools Protocol</a>.
|
|
64
64
|
|
|
65
|
-
ℹ️
|
|
65
|
+
ℹ️ Many examples run with raw <code translate="no"><b>python</b></code>, although some use <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">Syntax Formats</a> that expect <a href="https://docs.pytest.org/en/latest/how-to/usage.html" translate="no"><b>pytest</b></a> (a Python unit-testing framework included with SeleniumBase that can discover, collect, and run tests automatically).
|
|
66
66
|
|
|
67
67
|
--------
|
|
68
68
|
|
|
69
|
-
<p align="left">📗
|
|
69
|
+
<p align="left">📗 This script performs a Google Search using SeleniumBase UC Mode + CDP Mode:<br /><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">SeleniumBase/examples/raw_google.py</a> (Results are saved as PDF, HTML, and PNG)</p>
|
|
70
70
|
|
|
71
71
|
```python
|
|
72
72
|
from seleniumbase import SB
|
|
73
73
|
|
|
74
|
-
with SB(
|
|
75
|
-
|
|
74
|
+
with SB(uc=True, test=True) as sb:
|
|
75
|
+
url = "https://google.com/ncr"
|
|
76
|
+
sb.activate_cdp_mode(url)
|
|
76
77
|
sb.type('[title="Search"]', "SeleniumBase GitHub page")
|
|
77
78
|
sb.click("div:not([jsname]) > * > input")
|
|
79
|
+
sb.sleep(2)
|
|
78
80
|
print(sb.get_page_title())
|
|
79
|
-
sb.sleep(
|
|
81
|
+
sb.sleep(1) # Wait for the "AI Overview" result
|
|
80
82
|
if sb.is_text_visible("Generating"):
|
|
81
83
|
sb.wait_for_text("AI Overview")
|
|
82
84
|
sb.save_as_pdf_to_logs() # Saved to ./latest_logs/
|
|
@@ -98,8 +100,8 @@ from seleniumbase import SB
|
|
|
98
100
|
with SB(uc=True, test=True, locale="en") as sb:
|
|
99
101
|
url = "https://gitlab.com/users/sign_in"
|
|
100
102
|
sb.activate_cdp_mode(url)
|
|
101
|
-
sb.sleep(2
|
|
102
|
-
sb.
|
|
103
|
+
sb.sleep(2)
|
|
104
|
+
sb.solve_captcha()
|
|
103
105
|
# (The rest is for testing and demo purposes)
|
|
104
106
|
sb.assert_text("Username", '[for="user_login"]', timeout=3)
|
|
105
107
|
sb.assert_element('label[for="user_login"]')
|
|
@@ -116,9 +118,9 @@ with SB(uc=True, test=True, locale="en") as sb:
|
|
|
116
118
|
from seleniumbase import sb_cdp
|
|
117
119
|
|
|
118
120
|
url = "https://gitlab.com/users/sign_in"
|
|
119
|
-
sb = sb_cdp.Chrome(url)
|
|
120
|
-
sb.sleep(2
|
|
121
|
-
sb.
|
|
121
|
+
sb = sb_cdp.Chrome(url, incognito=True)
|
|
122
|
+
sb.sleep(2)
|
|
123
|
+
sb.solve_captcha()
|
|
122
124
|
sb.highlight('h1:contains("GitLab")')
|
|
123
125
|
sb.highlight('button:contains("Sign in")')
|
|
124
126
|
sb.driver.stop()
|
|
@@ -6,7 +6,7 @@ setuptools>=80.9.0;python_version>="3.10"
|
|
|
6
6
|
wheel>=0.45.1
|
|
7
7
|
attrs~=25.3.0;python_version<"3.9"
|
|
8
8
|
attrs>=25.4.0;python_version>="3.9"
|
|
9
|
-
certifi>=2025.
|
|
9
|
+
certifi>=2025.11.12
|
|
10
10
|
exceptiongroup>=1.3.0
|
|
11
11
|
websockets~=13.1;python_version<"3.9"
|
|
12
12
|
websockets>=15.0.1;python_version>="3.9"
|
|
@@ -14,7 +14,7 @@ filelock~=3.16.1;python_version<"3.9"
|
|
|
14
14
|
filelock~=3.19.1;python_version>="3.9" and python_version<"3.10"
|
|
15
15
|
filelock>=3.20.0;python_version>="3.10"
|
|
16
16
|
fasteners>=0.20
|
|
17
|
-
mycdp>=1.
|
|
17
|
+
mycdp>=1.3.0
|
|
18
18
|
pynose>=1.5.5
|
|
19
19
|
platformdirs~=4.3.6;python_version<"3.9"
|
|
20
20
|
platformdirs~=4.4.0;python_version>="3.9" and python_version<"3.10"
|
|
@@ -33,7 +33,7 @@ pyyaml>=6.0.3
|
|
|
33
33
|
pygments>=2.19.2
|
|
34
34
|
pyreadline3>=3.5.4;platform_system=="Windows"
|
|
35
35
|
tabcompleter>=1.4.0
|
|
36
|
-
pdbp>=1.8.
|
|
36
|
+
pdbp>=1.8.1
|
|
37
37
|
idna>=3.11
|
|
38
38
|
chardet==5.2.0
|
|
39
39
|
charset-normalizer>=3.4.4,<4
|
|
@@ -45,9 +45,11 @@ sniffio==1.3.1
|
|
|
45
45
|
h11==0.16.0
|
|
46
46
|
outcome==1.3.0.post0
|
|
47
47
|
trio==0.27.0;python_version<"3.9"
|
|
48
|
-
trio>=0.31.0,<1;python_version>="3.9"
|
|
48
|
+
trio>=0.31.0,<1;python_version>="3.9" and python_version<"3.10"
|
|
49
|
+
trio>=0.32.0,<1;python_version>="3.10"
|
|
49
50
|
trio-websocket~=0.12.2
|
|
50
|
-
wsproto==1.2.0
|
|
51
|
+
wsproto==1.2.0;python_version<"3.10"
|
|
52
|
+
wsproto==1.3.1;python_version>="3.10"
|
|
51
53
|
websocket-client~=1.8.0;python_version<"3.9"
|
|
52
54
|
websocket-client~=1.9.0;python_version>="3.9"
|
|
53
55
|
selenium==4.27.1;python_version<"3.9"
|
|
@@ -56,13 +58,15 @@ selenium==4.38.0;python_version>="3.10"
|
|
|
56
58
|
cssselect==1.2.0;python_version<"3.9"
|
|
57
59
|
cssselect==1.3.0;python_version>="3.9"
|
|
58
60
|
sortedcontainers==2.4.0
|
|
59
|
-
execnet==2.1.1
|
|
61
|
+
execnet==2.1.1;python_version<"3.10"
|
|
62
|
+
execnet==2.1.2;python_version>="3.10"
|
|
60
63
|
iniconfig==2.1.0;python_version<"3.10"
|
|
61
64
|
iniconfig==2.3.0;python_version>="3.10"
|
|
62
65
|
pluggy==1.5.0;python_version<"3.9"
|
|
63
66
|
pluggy==1.6.0;python_version>="3.9"
|
|
64
67
|
pytest==8.3.5;python_version<"3.9"
|
|
65
|
-
pytest==8.4.2;python_version>="3.9"
|
|
68
|
+
pytest==8.4.2;python_version>="3.9" and python_version<"3.11"
|
|
69
|
+
pytest==9.0.1;python_version>="3.11"
|
|
66
70
|
pytest-html==4.0.2
|
|
67
71
|
pytest-metadata==3.1.1
|
|
68
72
|
pytest-ordering==0.6
|
|
@@ -89,7 +93,7 @@ rich>=14.2.0,<15
|
|
|
89
93
|
|
|
90
94
|
coverage>=7.6.1;python_version<"3.9"
|
|
91
95
|
coverage>=7.10.7;python_version>="3.9" and python_version<"3.10"
|
|
92
|
-
coverage>=7.
|
|
96
|
+
coverage>=7.12.0;python_version>="3.10"
|
|
93
97
|
pytest-cov>=5.0.0;python_version<"3.9"
|
|
94
98
|
pytest-cov>=7.0.0;python_version>="3.9"
|
|
95
99
|
flake8==5.0.4;python_version<"3.9"
|
|
@@ -113,6 +113,7 @@ import sys
|
|
|
113
113
|
from contextlib import suppress
|
|
114
114
|
from seleniumbase import config as sb_config
|
|
115
115
|
from seleniumbase.config import settings
|
|
116
|
+
from seleniumbase.core import detect_b_ver
|
|
116
117
|
from seleniumbase.core import download_helper
|
|
117
118
|
from seleniumbase.core import log_helper
|
|
118
119
|
from seleniumbase.core import proxy_helper
|
|
@@ -890,6 +891,13 @@ def get_configured_sb(context):
|
|
|
890
891
|
"\nOnly ONE default browser is allowed!\n"
|
|
891
892
|
"%s browsers were selected: %s" % (len(browsers), browsers)
|
|
892
893
|
)
|
|
894
|
+
if sb.browser in ["opera", "brave", "comet", "atlas"]:
|
|
895
|
+
bin_loc = detect_b_ver.get_binary_location(sb.browser)
|
|
896
|
+
if bin_loc and os.path.exists(bin_loc):
|
|
897
|
+
sb_config._cdp_browser = sb.browser
|
|
898
|
+
sb_config._cdp_bin_loc = bin_loc
|
|
899
|
+
sb_config.binary_location = bin_loc
|
|
900
|
+
sb.binary_location = bin_loc
|
|
893
901
|
# Recorder Mode can still optimize scripts in "-D headless2" mode.
|
|
894
902
|
if sb.recorder_ext and sb.headless:
|
|
895
903
|
sb.headless = False
|
|
@@ -159,9 +159,21 @@ def extend_driver(
|
|
|
159
159
|
# Extend the driver with new methods
|
|
160
160
|
driver.default_find_element = driver.find_element
|
|
161
161
|
driver.default_find_elements = driver.find_elements
|
|
162
|
+
driver.default_add_cookie = driver.add_cookie
|
|
163
|
+
driver.default_get_cookie = driver.get_cookie
|
|
164
|
+
driver.default_delete_cookie = driver.delete_cookie
|
|
165
|
+
driver.default_back = driver.back
|
|
166
|
+
driver.default_forward = driver.forward
|
|
167
|
+
driver.default_refresh = driver.refresh
|
|
162
168
|
DM = sb_driver.DriverMethods(driver)
|
|
163
169
|
driver.find_element = DM.find_element
|
|
164
170
|
driver.find_elements = DM.find_elements
|
|
171
|
+
driver.add_cookie = DM.add_cookie
|
|
172
|
+
driver.get_cookie = DM.get_cookie
|
|
173
|
+
driver.delete_cookie = DM.delete_cookie
|
|
174
|
+
driver.back = DM.back
|
|
175
|
+
driver.forward = DM.forward
|
|
176
|
+
driver.refresh = DM.refresh
|
|
165
177
|
driver.locator = DM.locator
|
|
166
178
|
page = types.SimpleNamespace()
|
|
167
179
|
page.open = DM.open_url
|
|
@@ -293,7 +305,19 @@ def extend_driver(
|
|
|
293
305
|
)
|
|
294
306
|
if hasattr(driver, "proxy"):
|
|
295
307
|
driver.set_wire_proxy = DM.set_wire_proxy
|
|
308
|
+
completed_loads = []
|
|
309
|
+
for ext_dir in sb_config._ext_dirs:
|
|
310
|
+
if ext_dir not in completed_loads:
|
|
311
|
+
completed_loads.append(ext_dir)
|
|
312
|
+
if not use_uc and os.path.exists(os.path.realpath(ext_dir)):
|
|
313
|
+
with suppress(Exception):
|
|
314
|
+
driver.webextension.install(os.path.realpath(ext_dir))
|
|
315
|
+
driver._is_using_auth = False
|
|
296
316
|
if proxy_auth:
|
|
317
|
+
driver._is_using_auth = True
|
|
318
|
+
if not use_uc and os.path.exists(proxy_helper.PROXY_DIR_PATH):
|
|
319
|
+
with suppress(Exception):
|
|
320
|
+
driver.webextension.install(proxy_helper.PROXY_DIR_PATH)
|
|
297
321
|
# Proxy needs a moment to load in Manifest V3
|
|
298
322
|
if use_uc:
|
|
299
323
|
time.sleep(0.14)
|
|
@@ -446,6 +470,12 @@ def uc_execute_cdp_cmd(driver, *args, **kwargs):
|
|
|
446
470
|
return driver.default_execute_cdp_cmd(*args, **kwargs)
|
|
447
471
|
|
|
448
472
|
|
|
473
|
+
def updated_get(driver, url):
|
|
474
|
+
if url and ":" not in url and "." in url:
|
|
475
|
+
url = "https:" + url
|
|
476
|
+
driver.default_get(url)
|
|
477
|
+
|
|
478
|
+
|
|
449
479
|
def uc_special_open_if_cf(
|
|
450
480
|
driver,
|
|
451
481
|
url,
|
|
@@ -455,6 +485,8 @@ def uc_special_open_if_cf(
|
|
|
455
485
|
device_height=None,
|
|
456
486
|
device_pixel_ratio=None,
|
|
457
487
|
):
|
|
488
|
+
if url and ":" not in url and "." in url:
|
|
489
|
+
url = "https:" + url
|
|
458
490
|
if url.startswith("http:") or url.startswith("https:"):
|
|
459
491
|
special = False
|
|
460
492
|
with suppress(Exception):
|
|
@@ -764,6 +796,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
764
796
|
cdp.click_active_element = CDPM.click_active_element
|
|
765
797
|
cdp.click_if_visible = CDPM.click_if_visible
|
|
766
798
|
cdp.click_visible_elements = CDPM.click_visible_elements
|
|
799
|
+
cdp.click_with_offset = CDPM.click_with_offset
|
|
767
800
|
cdp.mouse_click = CDPM.mouse_click
|
|
768
801
|
cdp.get_parent = CDPM.get_parent
|
|
769
802
|
cdp.remove_element = CDPM.remove_element
|
|
@@ -793,11 +826,13 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
793
826
|
cdp.set_attributes = CDPM.set_attributes
|
|
794
827
|
cdp.is_attribute_present = CDPM.is_attribute_present
|
|
795
828
|
cdp.is_online = CDPM.is_online
|
|
829
|
+
cdp.solve_captcha = CDPM.solve_captcha
|
|
796
830
|
cdp.gui_press_key = CDPM.gui_press_key
|
|
797
831
|
cdp.gui_press_keys = CDPM.gui_press_keys
|
|
798
832
|
cdp.gui_write = CDPM.gui_write
|
|
799
833
|
cdp.gui_click_x_y = CDPM.gui_click_x_y
|
|
800
834
|
cdp.gui_click_element = CDPM.gui_click_element
|
|
835
|
+
cdp.gui_click_with_offset = CDPM.gui_click_with_offset
|
|
801
836
|
cdp.gui_click_captcha = CDPM.gui_click_captcha
|
|
802
837
|
cdp.gui_drag_drop_points = CDPM.gui_drag_drop_points
|
|
803
838
|
cdp.gui_drag_and_drop = CDPM.gui_drag_and_drop
|
|
@@ -825,6 +860,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
825
860
|
cdp.get_element_position = CDPM.get_element_position
|
|
826
861
|
cdp.get_gui_element_rect = CDPM.get_gui_element_rect
|
|
827
862
|
cdp.get_gui_element_center = CDPM.get_gui_element_center
|
|
863
|
+
cdp.get_html = CDPM.get_html
|
|
828
864
|
cdp.get_page_source = CDPM.get_page_source
|
|
829
865
|
cdp.get_user_agent = CDPM.get_user_agent
|
|
830
866
|
cdp.get_cookie_string = CDPM.get_cookie_string
|
|
@@ -921,7 +957,17 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
|
921
957
|
cdp.core = core_items
|
|
922
958
|
cdp.loop = cdp.get_event_loop()
|
|
923
959
|
driver.cdp = cdp
|
|
960
|
+
driver.solve_captcha = CDPM.solve_captcha
|
|
961
|
+
driver.find_element_by_text = CDPM.find_element_by_text
|
|
924
962
|
driver._is_using_cdp = True
|
|
963
|
+
if (
|
|
964
|
+
hasattr(sb_config, "_cdp_proxy")
|
|
965
|
+
and sb_config._cdp_proxy
|
|
966
|
+
and "@" in sb_config._cdp_proxy
|
|
967
|
+
):
|
|
968
|
+
time.sleep(0.077)
|
|
969
|
+
loop.run_until_complete(page.wait(0.25))
|
|
970
|
+
time.sleep(0.022)
|
|
925
971
|
|
|
926
972
|
|
|
927
973
|
def uc_activate_cdp_mode(driver, url=None, **kwargs):
|
|
@@ -1384,14 +1430,10 @@ def _uc_gui_click_captcha(
|
|
|
1384
1430
|
and driver.is_element_present("%s div" % frame)
|
|
1385
1431
|
):
|
|
1386
1432
|
frame = "%s div" % frame
|
|
1387
|
-
elif (
|
|
1388
|
-
driver.is_element_present('[name*="cf-turnstile-"]')
|
|
1389
|
-
and driver.is_element_present("#challenge-form div > div")
|
|
1390
|
-
):
|
|
1433
|
+
elif driver.is_element_present("#challenge-form div > div"):
|
|
1391
1434
|
frame = "#challenge-form div > div"
|
|
1392
1435
|
elif (
|
|
1393
|
-
driver.is_element_present(
|
|
1394
|
-
and driver.is_element_present(
|
|
1436
|
+
driver.is_element_present(
|
|
1395
1437
|
'[style="display: grid;"] div div'
|
|
1396
1438
|
)
|
|
1397
1439
|
):
|
|
@@ -1404,13 +1446,11 @@ def _uc_gui_click_captcha(
|
|
|
1404
1446
|
):
|
|
1405
1447
|
frame = '.spacer + div div:not([class])'
|
|
1406
1448
|
elif (
|
|
1407
|
-
driver.is_element_present(
|
|
1408
|
-
and driver.is_element_present(".spacer div:not([class])")
|
|
1449
|
+
driver.is_element_present(".spacer div:not([class])")
|
|
1409
1450
|
):
|
|
1410
1451
|
frame = ".spacer div:not([class])"
|
|
1411
1452
|
elif (
|
|
1412
|
-
driver.is_element_present(
|
|
1413
|
-
and driver.is_element_present(
|
|
1453
|
+
driver.is_element_present(
|
|
1414
1454
|
'[data-testid*="challenge-"] div'
|
|
1415
1455
|
)
|
|
1416
1456
|
):
|
|
@@ -2084,6 +2124,7 @@ def _add_chrome_proxy_extension(
|
|
|
2084
2124
|
"""Implementation of https://stackoverflow.com/a/35293284/7058266
|
|
2085
2125
|
for https://stackoverflow.com/q/12848327/7058266
|
|
2086
2126
|
(Run Selenium on a proxy server that requires authentication.)"""
|
|
2127
|
+
zip_it = False
|
|
2087
2128
|
args = " ".join(sys.argv)
|
|
2088
2129
|
bypass_list = proxy_bypass_list
|
|
2089
2130
|
if (
|
|
@@ -2463,14 +2504,28 @@ def _set_chrome_options(
|
|
|
2463
2504
|
# Can be a comma-separated list of .ZIP or .CRX files
|
|
2464
2505
|
extension_zip_list = extension_zip.split(",")
|
|
2465
2506
|
for extension_zip_item in extension_zip_list:
|
|
2466
|
-
abs_path = os.path.
|
|
2467
|
-
|
|
2507
|
+
abs_path = os.path.realpath(extension_zip_item)
|
|
2508
|
+
if os.path.exists(abs_path):
|
|
2509
|
+
try:
|
|
2510
|
+
abs_path_dir = os.path.join(
|
|
2511
|
+
DOWNLOADS_FOLDER, abs_path.split(".")[0]
|
|
2512
|
+
)
|
|
2513
|
+
_unzip_to_new_folder(abs_path, abs_path_dir)
|
|
2514
|
+
chrome_options = add_chrome_ext_dir(
|
|
2515
|
+
chrome_options, abs_path_dir
|
|
2516
|
+
)
|
|
2517
|
+
sb_config._ext_dirs.append(abs_path_dir)
|
|
2518
|
+
except Exception:
|
|
2519
|
+
with suppress(Exception):
|
|
2520
|
+
chrome_options.add_extension(abs_path)
|
|
2468
2521
|
if extension_dir:
|
|
2469
2522
|
# load-extension input can be a comma-separated list
|
|
2470
2523
|
abs_path = (
|
|
2471
|
-
",".join(os.path.
|
|
2524
|
+
",".join(os.path.realpath(p) for p in extension_dir.split(","))
|
|
2472
2525
|
)
|
|
2473
2526
|
chrome_options = add_chrome_ext_dir(chrome_options, abs_path)
|
|
2527
|
+
for p in extension_dir.split(","):
|
|
2528
|
+
sb_config._ext_dirs.append(os.path.realpath(p))
|
|
2474
2529
|
if (
|
|
2475
2530
|
page_load_strategy
|
|
2476
2531
|
and page_load_strategy.lower() in ["eager", "none"]
|
|
@@ -2505,37 +2560,32 @@ def _set_chrome_options(
|
|
|
2505
2560
|
if (settings.DISABLE_CSP_ON_CHROME or disable_csp) and not headless:
|
|
2506
2561
|
# Headless Chrome does not support extensions, which are required
|
|
2507
2562
|
# for disabling the Content Security Policy on Chrome.
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
chrome_options
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
else:
|
|
2516
|
-
chrome_options = _add_chrome_disable_csp_extension(chrome_options)
|
|
2563
|
+
disable_csp_zip = DISABLE_CSP_ZIP_PATH
|
|
2564
|
+
disable_csp_dir = os.path.join(DOWNLOADS_FOLDER, "disable_csp")
|
|
2565
|
+
_unzip_to_new_folder(disable_csp_zip, disable_csp_dir)
|
|
2566
|
+
chrome_options = add_chrome_ext_dir(
|
|
2567
|
+
chrome_options, disable_csp_dir
|
|
2568
|
+
)
|
|
2569
|
+
sb_config._ext_dirs.append(disable_csp_dir)
|
|
2517
2570
|
if ad_block_on and not headless:
|
|
2518
2571
|
# Headless Chrome does not support extensions.
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
else:
|
|
2525
|
-
chrome_options = _add_chrome_ad_block_extension(chrome_options)
|
|
2572
|
+
ad_block_zip = AD_BLOCK_ZIP_PATH
|
|
2573
|
+
ad_block_dir = os.path.join(DOWNLOADS_FOLDER, "ad_block")
|
|
2574
|
+
_unzip_to_new_folder(ad_block_zip, ad_block_dir)
|
|
2575
|
+
chrome_options = add_chrome_ext_dir(chrome_options, ad_block_dir)
|
|
2576
|
+
sb_config._ext_dirs.append(ad_block_dir)
|
|
2526
2577
|
if recorder_ext and not headless:
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
else:
|
|
2533
|
-
chrome_options = _add_chrome_recorder_extension(chrome_options)
|
|
2578
|
+
recorder_zip = RECORDER_ZIP_PATH
|
|
2579
|
+
recorder_dir = os.path.join(DOWNLOADS_FOLDER, "recorder")
|
|
2580
|
+
_unzip_to_new_folder(recorder_zip, recorder_dir)
|
|
2581
|
+
chrome_options = add_chrome_ext_dir(chrome_options, recorder_dir)
|
|
2582
|
+
sb_config._ext_dirs.append(recorder_dir)
|
|
2534
2583
|
if chromium_arg and "sbase" in chromium_arg:
|
|
2535
2584
|
sbase_ext_zip = SBASE_EXT_ZIP_PATH
|
|
2536
2585
|
sbase_ext_dir = os.path.join(DOWNLOADS_FOLDER, "sbase_ext")
|
|
2537
2586
|
_unzip_to_new_folder(sbase_ext_zip, sbase_ext_dir)
|
|
2538
2587
|
chrome_options = add_chrome_ext_dir(chrome_options, sbase_ext_dir)
|
|
2588
|
+
sb_config._ext_dirs.append(sbase_ext_dir)
|
|
2539
2589
|
if proxy_string:
|
|
2540
2590
|
if proxy_auth:
|
|
2541
2591
|
zip_it = True
|
|
@@ -2719,8 +2769,14 @@ def _set_chrome_options(
|
|
|
2719
2769
|
included_disabled_features.append(item)
|
|
2720
2770
|
d_f_string = ",".join(included_disabled_features)
|
|
2721
2771
|
chrome_options.add_argument("--disable-features=%s" % d_f_string)
|
|
2722
|
-
|
|
2772
|
+
chrome_options.add_argument("--enable-unsafe-extension-debugging")
|
|
2773
|
+
if proxy_string:
|
|
2723
2774
|
chrome_options.add_argument("--test-type")
|
|
2775
|
+
if proxy_auth or sb_config._ext_dirs:
|
|
2776
|
+
if not is_using_uc(undetectable, browser_name):
|
|
2777
|
+
chrome_options.add_argument("--remote-debugging-pipe")
|
|
2778
|
+
chrome_options.enable_webextensions = True
|
|
2779
|
+
chrome_options.enable_bidi = True
|
|
2724
2780
|
if (
|
|
2725
2781
|
is_using_uc(undetectable, browser_name)
|
|
2726
2782
|
and (
|
|
@@ -2738,7 +2794,7 @@ def _set_chrome_options(
|
|
|
2738
2794
|
chrome_options.add_argument("--disable-popup-blocking")
|
|
2739
2795
|
# Skip remaining options that trigger anti-bot services
|
|
2740
2796
|
return chrome_options
|
|
2741
|
-
if not
|
|
2797
|
+
if not proxy_string:
|
|
2742
2798
|
chrome_options.add_argument("--test-type")
|
|
2743
2799
|
chrome_options.add_argument("--log-level=3")
|
|
2744
2800
|
chrome_options.add_argument("--no-first-run")
|
|
@@ -2985,6 +3041,7 @@ def get_driver(
|
|
|
2985
3041
|
device_pixel_ratio=None,
|
|
2986
3042
|
browser=None, # A duplicate of browser_name to avoid confusion
|
|
2987
3043
|
):
|
|
3044
|
+
sb_config._ext_dirs = []
|
|
2988
3045
|
driver_dir = DRIVER_DIR
|
|
2989
3046
|
if (
|
|
2990
3047
|
hasattr(sb_config, "binary_location")
|
|
@@ -3223,8 +3280,8 @@ def get_driver(
|
|
|
3223
3280
|
proxy_pass = None
|
|
3224
3281
|
proxy_scheme = "http"
|
|
3225
3282
|
if proxy_string:
|
|
3226
|
-
# (The
|
|
3227
|
-
|
|
3283
|
+
# (The line below is for the Chrome 142 proxy auth fix)
|
|
3284
|
+
sb_config._cdp_proxy = proxy_string
|
|
3228
3285
|
username_and_password = None
|
|
3229
3286
|
if "@" in proxy_string:
|
|
3230
3287
|
# Format => username:password@hostname:port
|
|
@@ -4549,12 +4606,12 @@ def get_local_driver(
|
|
|
4549
4606
|
# Can be a comma-separated list of .ZIP or .CRX files
|
|
4550
4607
|
extension_zip_list = extension_zip.split(",")
|
|
4551
4608
|
for extension_zip_item in extension_zip_list:
|
|
4552
|
-
abs_path = os.path.
|
|
4609
|
+
abs_path = os.path.realpath(extension_zip_item)
|
|
4553
4610
|
edge_options.add_extension(abs_path)
|
|
4554
4611
|
if extension_dir:
|
|
4555
4612
|
# load-extension input can be a comma-separated list
|
|
4556
4613
|
abs_path = (
|
|
4557
|
-
",".join(os.path.
|
|
4614
|
+
",".join(os.path.realpath(p) for p in extension_dir.split(","))
|
|
4558
4615
|
)
|
|
4559
4616
|
edge_options = add_chrome_ext_dir(edge_options, abs_path)
|
|
4560
4617
|
edge_options.add_argument("--disable-infobars")
|
|
@@ -5745,6 +5802,7 @@ def get_local_driver(
|
|
|
5745
5802
|
)
|
|
5746
5803
|
driver.default_get = driver.get # Save copy of original
|
|
5747
5804
|
driver.cdp = None # Set a placeholder
|
|
5805
|
+
driver._is_using_uc = False
|
|
5748
5806
|
driver._is_using_cdp = False
|
|
5749
5807
|
driver._is_connected = True
|
|
5750
5808
|
if uc_activated:
|
|
@@ -5779,6 +5837,7 @@ def get_local_driver(
|
|
|
5779
5837
|
driver, *args, **kwargs
|
|
5780
5838
|
)
|
|
5781
5839
|
)
|
|
5840
|
+
driver.activate_cdp_mode = driver.uc_activate_cdp_mode
|
|
5782
5841
|
driver.uc_open_with_cdp_mode = (
|
|
5783
5842
|
lambda *args, **kwargs: uc_open_with_cdp_mode(
|
|
5784
5843
|
driver, *args, **kwargs
|
|
@@ -5887,6 +5946,8 @@ def get_local_driver(
|
|
|
5887
5946
|
'Emulation.setDeviceMetricsOverride',
|
|
5888
5947
|
set_device_metrics_override
|
|
5889
5948
|
)
|
|
5949
|
+
else:
|
|
5950
|
+
driver.get = lambda url: updated_get(driver, url)
|
|
5890
5951
|
return extend_driver(
|
|
5891
5952
|
driver, proxy_auth, use_uc, recorder_ext
|
|
5892
5953
|
)
|