seleniumbase 4.47.8__tar.gz → 4.48.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {seleniumbase-4.47.8/seleniumbase.egg-info → seleniumbase-4.48.0}/PKG-INFO +9 -12
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/README.md +0 -2
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/requirements.txt +6 -7
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_mkfile.py +1 -1
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_mkrec.py +1 -1
- seleniumbase-4.48.0/seleniumbase/core/nest_asyncio.py +282 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/sb_cdp.py +76 -13
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/sb_manager.py +1 -3
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/cdp_driver/config.py +36 -14
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/cdp_driver/tab.py +48 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0/seleniumbase.egg-info}/PKG-INFO +9 -12
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase.egg-info/SOURCES.txt +1 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase.egg-info/requires.txt +8 -9
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/setup.py +8 -9
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/.gitignore +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/LICENSE +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/MANIFEST.in +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/install.sh +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/pyproject.toml +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/pytest.ini +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/sbase/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/sbase/__main__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/sbase/steps.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/browser_launcher.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/base_case.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/page_actions.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/pytest_plugin.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/setup.cfg +0 -0
- {seleniumbase-4.47.8 → seleniumbase-4.48.0}/virtualenv_install.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.48.0
|
|
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
|
|
@@ -74,7 +74,7 @@ Requires-Dist: fasteners>=0.20
|
|
|
74
74
|
Requires-Dist: mycdp>=1.3.7
|
|
75
75
|
Requires-Dist: pynose>=1.5.5
|
|
76
76
|
Requires-Dist: platformdirs~=4.4.0; python_version < "3.10"
|
|
77
|
-
Requires-Dist: platformdirs>=4.9.
|
|
77
|
+
Requires-Dist: platformdirs>=4.9.6; python_version >= "3.10"
|
|
78
78
|
Requires-Dist: typing-extensions>=4.15.0
|
|
79
79
|
Requires-Dist: sbvirtualdisplay>=1.4.0
|
|
80
80
|
Requires-Dist: MarkupSafe>=3.0.3
|
|
@@ -84,16 +84,16 @@ Requires-Dist: parse>=1.21.1
|
|
|
84
84
|
Requires-Dist: parse-type>=0.6.6
|
|
85
85
|
Requires-Dist: colorama>=0.4.6
|
|
86
86
|
Requires-Dist: pyyaml>=6.0.3
|
|
87
|
-
Requires-Dist: pygments>=2.
|
|
87
|
+
Requires-Dist: pygments>=2.20.0
|
|
88
88
|
Requires-Dist: pyreadline3>=3.5.4; platform_system == "Windows"
|
|
89
89
|
Requires-Dist: tabcompleter>=1.4.0
|
|
90
90
|
Requires-Dist: pdbp>=1.8.2
|
|
91
91
|
Requires-Dist: idna>=3.11
|
|
92
|
-
Requires-Dist: charset-normalizer<4,>=3.4.
|
|
92
|
+
Requires-Dist: charset-normalizer<4,>=3.4.7
|
|
93
93
|
Requires-Dist: urllib3<2,>=1.26.20; python_version < "3.10"
|
|
94
94
|
Requires-Dist: urllib3<3,>=1.26.20; python_version >= "3.10"
|
|
95
95
|
Requires-Dist: requests~=2.32.5; python_version < "3.10"
|
|
96
|
-
Requires-Dist: requests~=2.33.
|
|
96
|
+
Requires-Dist: requests~=2.33.1; python_version >= "3.10"
|
|
97
97
|
Requires-Dist: sniffio==1.3.1
|
|
98
98
|
Requires-Dist: h11==0.16.0
|
|
99
99
|
Requires-Dist: outcome==1.3.0.post0
|
|
@@ -104,10 +104,9 @@ Requires-Dist: wsproto==1.2.0; python_version < "3.10"
|
|
|
104
104
|
Requires-Dist: wsproto~=1.3.2; python_version >= "3.10"
|
|
105
105
|
Requires-Dist: websocket-client~=1.9.0
|
|
106
106
|
Requires-Dist: selenium==4.32.0; python_version < "3.10"
|
|
107
|
-
Requires-Dist: selenium==4.
|
|
107
|
+
Requires-Dist: selenium==4.43.0; python_version >= "3.10"
|
|
108
108
|
Requires-Dist: cssselect==1.3.0; python_version < "3.10"
|
|
109
109
|
Requires-Dist: cssselect<2,>=1.4.0; python_version >= "3.10"
|
|
110
|
-
Requires-Dist: nest-asyncio==1.6.0
|
|
111
110
|
Requires-Dist: sortedcontainers==2.4.0
|
|
112
111
|
Requires-Dist: execnet==2.1.1; python_version < "3.10"
|
|
113
112
|
Requires-Dist: execnet==2.1.2; python_version >= "3.10"
|
|
@@ -115,7 +114,7 @@ Requires-Dist: iniconfig==2.1.0; python_version < "3.10"
|
|
|
115
114
|
Requires-Dist: iniconfig==2.3.0; python_version >= "3.10"
|
|
116
115
|
Requires-Dist: pluggy==1.6.0
|
|
117
116
|
Requires-Dist: pytest==8.4.2; python_version < "3.11"
|
|
118
|
-
Requires-Dist: pytest==9.0.
|
|
117
|
+
Requires-Dist: pytest==9.0.3; python_version >= "3.11"
|
|
119
118
|
Requires-Dist: pytest-html==4.0.2
|
|
120
119
|
Requires-Dist: pytest-metadata==3.1.1
|
|
121
120
|
Requires-Dist: pytest-ordering==0.6
|
|
@@ -154,13 +153,13 @@ Requires-Dist: mss==10.1.0; extra == "mss"
|
|
|
154
153
|
Provides-Extra: pdfminer
|
|
155
154
|
Requires-Dist: pdfminer.six==20251107; python_version < "3.10" and extra == "pdfminer"
|
|
156
155
|
Requires-Dist: pdfminer.six==20260107; python_version >= "3.10" and extra == "pdfminer"
|
|
157
|
-
Requires-Dist: cryptography==46.0.
|
|
156
|
+
Requires-Dist: cryptography==46.0.7; extra == "pdfminer"
|
|
158
157
|
Requires-Dist: cffi==2.0.0; extra == "pdfminer"
|
|
159
158
|
Requires-Dist: pycparser==2.23; python_version < "3.10" and extra == "pdfminer"
|
|
160
159
|
Requires-Dist: pycparser==3.0; python_version >= "3.10" and extra == "pdfminer"
|
|
161
160
|
Provides-Extra: pillow
|
|
162
161
|
Requires-Dist: Pillow>=11.3.0; python_version < "3.10" and extra == "pillow"
|
|
163
|
-
Requires-Dist: Pillow>=12.
|
|
162
|
+
Requires-Dist: Pillow>=12.2.0; python_version >= "3.10" and extra == "pillow"
|
|
164
163
|
Provides-Extra: pip-system-certs
|
|
165
164
|
Requires-Dist: pip-system-certs==4.0; platform_system == "Windows" and extra == "pip-system-certs"
|
|
166
165
|
Provides-Extra: proxy
|
|
@@ -818,8 +817,6 @@ import time; time.sleep(3) # Do nothing for 3 seconds.
|
|
|
818
817
|
🔵 **Debug Mode** with Python's built-in **[pdb](https://docs.python.org/3/library/pdb.html)** library helps you debug tests:
|
|
819
818
|
|
|
820
819
|
```python
|
|
821
|
-
import pdb; pdb.set_trace()
|
|
822
|
-
import pytest; pytest.set_trace()
|
|
823
820
|
breakpoint() # Shortcut for "import pdb; pdb.set_trace()"
|
|
824
821
|
```
|
|
825
822
|
|
|
@@ -617,8 +617,6 @@ import time; time.sleep(3) # Do nothing for 3 seconds.
|
|
|
617
617
|
🔵 **Debug Mode** with Python's built-in **[pdb](https://docs.python.org/3/library/pdb.html)** library helps you debug tests:
|
|
618
618
|
|
|
619
619
|
```python
|
|
620
|
-
import pdb; pdb.set_trace()
|
|
621
|
-
import pytest; pytest.set_trace()
|
|
622
620
|
breakpoint() # Shortcut for "import pdb; pdb.set_trace()"
|
|
623
621
|
```
|
|
624
622
|
|
|
@@ -14,7 +14,7 @@ fasteners>=0.20
|
|
|
14
14
|
mycdp>=1.3.7
|
|
15
15
|
pynose>=1.5.5
|
|
16
16
|
platformdirs~=4.4.0;python_version<"3.10"
|
|
17
|
-
platformdirs>=4.9.
|
|
17
|
+
platformdirs>=4.9.6;python_version>="3.10"
|
|
18
18
|
typing-extensions>=4.15.0
|
|
19
19
|
sbvirtualdisplay>=1.4.0
|
|
20
20
|
MarkupSafe>=3.0.3
|
|
@@ -24,16 +24,16 @@ parse>=1.21.1
|
|
|
24
24
|
parse-type>=0.6.6
|
|
25
25
|
colorama>=0.4.6
|
|
26
26
|
pyyaml>=6.0.3
|
|
27
|
-
pygments>=2.
|
|
27
|
+
pygments>=2.20.0
|
|
28
28
|
pyreadline3>=3.5.4;platform_system=="Windows"
|
|
29
29
|
tabcompleter>=1.4.0
|
|
30
30
|
pdbp>=1.8.2
|
|
31
31
|
idna>=3.11
|
|
32
|
-
charset-normalizer>=3.4.
|
|
32
|
+
charset-normalizer>=3.4.7,<4
|
|
33
33
|
urllib3>=1.26.20,<2;python_version<"3.10"
|
|
34
34
|
urllib3>=1.26.20,<3;python_version>="3.10"
|
|
35
35
|
requests~=2.32.5;python_version<"3.10"
|
|
36
|
-
requests~=2.33.
|
|
36
|
+
requests~=2.33.1;python_version>="3.10"
|
|
37
37
|
sniffio==1.3.1
|
|
38
38
|
h11==0.16.0
|
|
39
39
|
outcome==1.3.0.post0
|
|
@@ -44,10 +44,9 @@ wsproto==1.2.0;python_version<"3.10"
|
|
|
44
44
|
wsproto~=1.3.2;python_version>="3.10"
|
|
45
45
|
websocket-client~=1.9.0
|
|
46
46
|
selenium==4.32.0;python_version<"3.10"
|
|
47
|
-
selenium==4.
|
|
47
|
+
selenium==4.43.0;python_version>="3.10"
|
|
48
48
|
cssselect==1.3.0;python_version<"3.10"
|
|
49
49
|
cssselect>=1.4.0,<2;python_version>="3.10"
|
|
50
|
-
nest-asyncio==1.6.0
|
|
51
50
|
sortedcontainers==2.4.0
|
|
52
51
|
execnet==2.1.1;python_version<"3.10"
|
|
53
52
|
execnet==2.1.2;python_version>="3.10"
|
|
@@ -55,7 +54,7 @@ iniconfig==2.1.0;python_version<"3.10"
|
|
|
55
54
|
iniconfig==2.3.0;python_version>="3.10"
|
|
56
55
|
pluggy==1.6.0
|
|
57
56
|
pytest==8.4.2;python_version<"3.11"
|
|
58
|
-
pytest==9.0.
|
|
57
|
+
pytest==9.0.3;python_version>="3.11"
|
|
59
58
|
pytest-html==4.0.2
|
|
60
59
|
pytest-metadata==3.1.1
|
|
61
60
|
pytest-ordering==0.6
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# seleniumbase package
|
|
2
|
-
__version__ = "4.
|
|
2
|
+
__version__ = "4.48.0"
|
|
@@ -277,7 +277,7 @@ def main():
|
|
|
277
277
|
data.append(' self.open("%s")' % url)
|
|
278
278
|
else:
|
|
279
279
|
data.append(" if self.recorder_ext and not self.xvfb:")
|
|
280
|
-
data.append("
|
|
280
|
+
data.append(" breakpoint()")
|
|
281
281
|
if not basic and not recorder:
|
|
282
282
|
data.append(
|
|
283
283
|
' self.type("input", "%s")' " # selector, text" % goodbye
|
|
@@ -216,7 +216,7 @@ def main():
|
|
|
216
216
|
data.append(" if self.recorder_ext:")
|
|
217
217
|
data.append(" # When done recording actions,")
|
|
218
218
|
data.append(' # type "c", and press [Enter].')
|
|
219
|
-
data.append("
|
|
219
|
+
data.append(" breakpoint()")
|
|
220
220
|
data.append("")
|
|
221
221
|
|
|
222
222
|
if esc_end:
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
"""Patch asyncio to allow nested event loops."""
|
|
2
|
+
import asyncio
|
|
3
|
+
import asyncio.events as events
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
import threading
|
|
7
|
+
from contextlib import contextmanager, suppress
|
|
8
|
+
from heapq import heappop
|
|
9
|
+
|
|
10
|
+
_run_close_loop = True
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class PatchedNestAsyncio:
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def apply(loop=None, *, run_close_loop=False, error_on_mispatched=False):
|
|
18
|
+
global _run_close_loop
|
|
19
|
+
_patch_asyncio(error_on_mispatched=error_on_mispatched)
|
|
20
|
+
_patch_policy()
|
|
21
|
+
_patch_tornado()
|
|
22
|
+
loop = loop or _get_event_loop()
|
|
23
|
+
if loop is not None:
|
|
24
|
+
_patch_loop(loop)
|
|
25
|
+
_run_close_loop &= run_close_loop
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
if sys.version_info < (3, 14, 0):
|
|
29
|
+
def _get_event_loop():
|
|
30
|
+
return asyncio.get_event_loop()
|
|
31
|
+
else:
|
|
32
|
+
def _get_event_loop():
|
|
33
|
+
try:
|
|
34
|
+
return asyncio.get_event_loop()
|
|
35
|
+
except RuntimeError:
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if sys.version_info < (3, 12, 0):
|
|
40
|
+
def run(main, *, debug=False):
|
|
41
|
+
loop = asyncio.get_event_loop()
|
|
42
|
+
loop.set_debug(debug)
|
|
43
|
+
task = asyncio.ensure_future(main)
|
|
44
|
+
try:
|
|
45
|
+
return loop.run_until_complete(task)
|
|
46
|
+
finally:
|
|
47
|
+
if not task.done():
|
|
48
|
+
task.cancel()
|
|
49
|
+
with suppress(asyncio.CancelledError):
|
|
50
|
+
loop.run_until_complete(task)
|
|
51
|
+
else:
|
|
52
|
+
def run(main, *, debug=False, loop_factory=None):
|
|
53
|
+
new_event_loop = False
|
|
54
|
+
set_event_loop = None
|
|
55
|
+
try:
|
|
56
|
+
loop = asyncio.get_running_loop()
|
|
57
|
+
except RuntimeError:
|
|
58
|
+
if not _run_close_loop:
|
|
59
|
+
loop = _get_event_loop()
|
|
60
|
+
if loop is None:
|
|
61
|
+
if loop_factory is None:
|
|
62
|
+
loop_factory = asyncio.new_event_loop
|
|
63
|
+
loop = loop_factory()
|
|
64
|
+
asyncio.set_event_loop(loop)
|
|
65
|
+
else:
|
|
66
|
+
if loop_factory is None:
|
|
67
|
+
loop = asyncio.new_event_loop()
|
|
68
|
+
set_event_loop = _get_event_loop()
|
|
69
|
+
asyncio.set_event_loop(loop)
|
|
70
|
+
else:
|
|
71
|
+
loop = loop_factory()
|
|
72
|
+
new_event_loop = True
|
|
73
|
+
_patch_loop(loop)
|
|
74
|
+
|
|
75
|
+
loop.set_debug(debug)
|
|
76
|
+
task = asyncio.ensure_future(main, loop=loop)
|
|
77
|
+
try:
|
|
78
|
+
return loop.run_until_complete(task)
|
|
79
|
+
finally:
|
|
80
|
+
if not task.done():
|
|
81
|
+
task.cancel()
|
|
82
|
+
with suppress(asyncio.CancelledError):
|
|
83
|
+
loop.run_until_complete(task)
|
|
84
|
+
if set_event_loop:
|
|
85
|
+
asyncio.set_event_loop(set_event_loop)
|
|
86
|
+
if new_event_loop:
|
|
87
|
+
# Avoid ResourceWarning: unclosed event loop
|
|
88
|
+
loop.close()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _patch_asyncio(*, error_on_mispatched=False):
|
|
92
|
+
"""Patch asyncio module to use pure Python tasks and futures."""
|
|
93
|
+
|
|
94
|
+
def _get_event_loop(stacklevel=3):
|
|
95
|
+
loop = events._get_running_loop()
|
|
96
|
+
if loop is None:
|
|
97
|
+
if sys.version_info < (3, 14, 0):
|
|
98
|
+
policy = events.get_event_loop_policy()
|
|
99
|
+
else:
|
|
100
|
+
policy = events._get_event_loop_policy()
|
|
101
|
+
loop = policy.get_event_loop()
|
|
102
|
+
return loop
|
|
103
|
+
|
|
104
|
+
if hasattr(asyncio, "_nest_patched"):
|
|
105
|
+
if not hasattr(asyncio, "_nest_asyncio"):
|
|
106
|
+
if error_on_mispatched:
|
|
107
|
+
raise RuntimeError("asyncio was already patched!")
|
|
108
|
+
elif sys.version_info >= (3, 12, 0):
|
|
109
|
+
import warnings
|
|
110
|
+
warnings.warn("asyncio was already patched!")
|
|
111
|
+
return
|
|
112
|
+
|
|
113
|
+
asyncio.tasks.Task = asyncio.tasks._PyTask
|
|
114
|
+
asyncio.Task = asyncio.tasks._CTask = asyncio.tasks.Task
|
|
115
|
+
asyncio.Future = asyncio.futures._CFuture = asyncio.futures.Future = (
|
|
116
|
+
asyncio.futures._PyFuture
|
|
117
|
+
)
|
|
118
|
+
asyncio.get_event_loop = _get_event_loop
|
|
119
|
+
events._get_event_loop = events.get_event_loop = asyncio.get_event_loop
|
|
120
|
+
asyncio.run = run
|
|
121
|
+
asyncio._nest_patched = True
|
|
122
|
+
asyncio._nest_asyncio = PatchedNestAsyncio()
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def _patch_policy():
|
|
126
|
+
"""Patch the policy to always return a patched loop."""
|
|
127
|
+
|
|
128
|
+
def get_event_loop(self):
|
|
129
|
+
if self._local._loop is None:
|
|
130
|
+
loop = self.new_event_loop()
|
|
131
|
+
_patch_loop(loop)
|
|
132
|
+
self.set_event_loop(loop)
|
|
133
|
+
return self._local._loop
|
|
134
|
+
|
|
135
|
+
if sys.version_info < (3, 14, 0):
|
|
136
|
+
policy = events.get_event_loop_policy()
|
|
137
|
+
else:
|
|
138
|
+
policy = events._get_event_loop_policy()
|
|
139
|
+
policy.__class__.get_event_loop = get_event_loop
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _patch_loop(loop):
|
|
143
|
+
"""Patch loop to make it reentrant."""
|
|
144
|
+
|
|
145
|
+
def run_forever(self):
|
|
146
|
+
with manage_run(self), manage_asyncgens(self):
|
|
147
|
+
while True:
|
|
148
|
+
self._run_once()
|
|
149
|
+
if self._stopping:
|
|
150
|
+
break
|
|
151
|
+
self._stopping = False
|
|
152
|
+
|
|
153
|
+
def run_until_complete(self, future):
|
|
154
|
+
with manage_run(self):
|
|
155
|
+
f = asyncio.ensure_future(future, loop=self)
|
|
156
|
+
if f is not future:
|
|
157
|
+
f._log_destroy_pending = False
|
|
158
|
+
while not f.done():
|
|
159
|
+
self._run_once()
|
|
160
|
+
if self._stopping:
|
|
161
|
+
break
|
|
162
|
+
if not f.done():
|
|
163
|
+
raise RuntimeError("Loop stopped before Future completed!")
|
|
164
|
+
return f.result()
|
|
165
|
+
|
|
166
|
+
def _run_once(self):
|
|
167
|
+
"""Simplified re-implementation of asyncio's _run_once."""
|
|
168
|
+
ready = self._ready
|
|
169
|
+
scheduled = self._scheduled
|
|
170
|
+
while scheduled and scheduled[0]._cancelled:
|
|
171
|
+
heappop(scheduled)
|
|
172
|
+
timeout = (
|
|
173
|
+
0
|
|
174
|
+
if ready or self._stopping
|
|
175
|
+
else min(max(scheduled[0]._when - self.time(), 0), 86400)
|
|
176
|
+
if scheduled
|
|
177
|
+
else None
|
|
178
|
+
)
|
|
179
|
+
event_list = self._selector.select(timeout)
|
|
180
|
+
self._process_events(event_list)
|
|
181
|
+
end_time = self.time() + self._clock_resolution
|
|
182
|
+
while scheduled and scheduled[0]._when < end_time:
|
|
183
|
+
handle = heappop(scheduled)
|
|
184
|
+
ready.append(handle)
|
|
185
|
+
for _ in range(len(ready)):
|
|
186
|
+
if not ready:
|
|
187
|
+
break
|
|
188
|
+
handle = ready.popleft()
|
|
189
|
+
if not handle._cancelled:
|
|
190
|
+
if sys.version_info < (3, 14, 0):
|
|
191
|
+
curr_task = curr_tasks.pop(self, None)
|
|
192
|
+
else:
|
|
193
|
+
try:
|
|
194
|
+
curr_task = asyncio.tasks._swap_current_task(
|
|
195
|
+
self, None
|
|
196
|
+
)
|
|
197
|
+
except KeyError:
|
|
198
|
+
curr_task = None
|
|
199
|
+
try:
|
|
200
|
+
handle._run()
|
|
201
|
+
finally:
|
|
202
|
+
if curr_task is not None:
|
|
203
|
+
if sys.version_info < (3, 14, 0):
|
|
204
|
+
curr_tasks[self] = curr_task
|
|
205
|
+
else:
|
|
206
|
+
asyncio.tasks._swap_current_task(self, curr_task)
|
|
207
|
+
handle = None
|
|
208
|
+
|
|
209
|
+
@contextmanager
|
|
210
|
+
def manage_run(self):
|
|
211
|
+
self._check_closed()
|
|
212
|
+
old_thread_id = self._thread_id
|
|
213
|
+
old_running_loop = events._get_running_loop()
|
|
214
|
+
try:
|
|
215
|
+
self._thread_id = threading.get_ident()
|
|
216
|
+
events._set_running_loop(self)
|
|
217
|
+
self._num_runs_pending += 1
|
|
218
|
+
if self._is_proactorloop:
|
|
219
|
+
if self._self_reading_future is None:
|
|
220
|
+
self.call_soon(self._loop_self_reading)
|
|
221
|
+
yield
|
|
222
|
+
finally:
|
|
223
|
+
self._thread_id = old_thread_id
|
|
224
|
+
events._set_running_loop(old_running_loop)
|
|
225
|
+
self._num_runs_pending -= 1
|
|
226
|
+
if self._is_proactorloop:
|
|
227
|
+
if (
|
|
228
|
+
self._num_runs_pending == 0
|
|
229
|
+
and self._self_reading_future is not None
|
|
230
|
+
):
|
|
231
|
+
ov = self._self_reading_future._ov
|
|
232
|
+
self._self_reading_future.cancel()
|
|
233
|
+
if ov is not None:
|
|
234
|
+
self._proactor._unregister(ov)
|
|
235
|
+
self._self_reading_future = None
|
|
236
|
+
|
|
237
|
+
@contextmanager
|
|
238
|
+
def manage_asyncgens(self):
|
|
239
|
+
old_agen_hooks = sys.get_asyncgen_hooks()
|
|
240
|
+
try:
|
|
241
|
+
self._set_coroutine_origin_tracking(self._debug)
|
|
242
|
+
if self._asyncgens is not None:
|
|
243
|
+
sys.set_asyncgen_hooks(
|
|
244
|
+
firstiter=self._asyncgen_firstiter_hook,
|
|
245
|
+
finalizer=self._asyncgen_finalizer_hook,
|
|
246
|
+
)
|
|
247
|
+
yield
|
|
248
|
+
finally:
|
|
249
|
+
self._set_coroutine_origin_tracking(False)
|
|
250
|
+
if self._asyncgens is not None:
|
|
251
|
+
sys.set_asyncgen_hooks(*old_agen_hooks)
|
|
252
|
+
|
|
253
|
+
def _check_running(self):
|
|
254
|
+
"""Do not throw exception if loop is already running."""
|
|
255
|
+
pass
|
|
256
|
+
|
|
257
|
+
if hasattr(loop, "_nest_patched"):
|
|
258
|
+
return
|
|
259
|
+
if not isinstance(loop, asyncio.BaseEventLoop):
|
|
260
|
+
raise ValueError("Can't patch loop of type %s" % type(loop))
|
|
261
|
+
cls = loop.__class__
|
|
262
|
+
cls.run_forever = run_forever
|
|
263
|
+
cls.run_until_complete = run_until_complete
|
|
264
|
+
cls._run_once = _run_once
|
|
265
|
+
cls._check_running = _check_running
|
|
266
|
+
cls._num_runs_pending = 1 if loop.is_running() else 0
|
|
267
|
+
cls._is_proactorloop = os.name == "nt" and issubclass(
|
|
268
|
+
cls, asyncio.ProactorEventLoop
|
|
269
|
+
)
|
|
270
|
+
curr_tasks = asyncio.tasks._current_tasks
|
|
271
|
+
cls._nest_patched = True
|
|
272
|
+
cls._nest_asyncio = PatchedNestAsyncio()
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def _patch_tornado():
|
|
276
|
+
"""If tornado is imported before nest_asyncio,
|
|
277
|
+
make tornado aware of the pure-Python asyncio Future."""
|
|
278
|
+
if "tornado" in sys.modules:
|
|
279
|
+
import tornado.concurrent as tc # type: ignore
|
|
280
|
+
tc.Future = asyncio.Future
|
|
281
|
+
if asyncio.Future not in tc.FUTURES:
|
|
282
|
+
tc.FUTURES += (asyncio.Future,)
|
|
@@ -193,7 +193,7 @@ class CDPMethods():
|
|
|
193
193
|
Also sets an environment variable to hide this warning:
|
|
194
194
|
Deprecation: "url.parse() behavior is not standardized".
|
|
195
195
|
(github.com/microsoft/playwright-python/issues/3016)"""
|
|
196
|
-
import nest_asyncio
|
|
196
|
+
from seleniumbase.core import nest_asyncio
|
|
197
197
|
nest_asyncio.apply()
|
|
198
198
|
os.environ["NODE_NO_WARNINGS"] = "1"
|
|
199
199
|
driver = self.driver
|
|
@@ -400,7 +400,7 @@ class CDPMethods():
|
|
|
400
400
|
self.__add_light_pause()
|
|
401
401
|
selector = self.__convert_to_css_if_xpath(selector)
|
|
402
402
|
if not self.is_element_present(selector):
|
|
403
|
-
|
|
403
|
+
time.sleep(1)
|
|
404
404
|
timeout = timeout - 1
|
|
405
405
|
if timeout < 1:
|
|
406
406
|
timeout = 1
|
|
@@ -1068,7 +1068,11 @@ class CDPMethods():
|
|
|
1068
1068
|
):
|
|
1069
1069
|
text = text.replace("\n", "\r")
|
|
1070
1070
|
for key in text:
|
|
1071
|
-
|
|
1071
|
+
try:
|
|
1072
|
+
element.send_keys(key)
|
|
1073
|
+
except AttributeError:
|
|
1074
|
+
element = self.select(selector, timeout=0.1)
|
|
1075
|
+
element.send_keys(key)
|
|
1072
1076
|
time.sleep(float(0.042 + (random.random() / 110.0)))
|
|
1073
1077
|
if submit:
|
|
1074
1078
|
element.send_keys("\r\n")
|
|
@@ -2057,7 +2061,7 @@ class CDPMethods():
|
|
|
2057
2061
|
return False
|
|
2058
2062
|
|
|
2059
2063
|
def _on_a_datadome_slider_page(self, *args, **kwargs):
|
|
2060
|
-
self.loop.run_until_complete(self.page.wait(0.
|
|
2064
|
+
self.loop.run_until_complete(self.page.wait(0.05))
|
|
2061
2065
|
if (
|
|
2062
2066
|
self.is_element_visible(
|
|
2063
2067
|
'body > iframe[src*="/geo.captcha-delivery.com/captcha/"]'
|
|
@@ -2066,6 +2070,12 @@ class CDPMethods():
|
|
|
2066
2070
|
return True
|
|
2067
2071
|
return False
|
|
2068
2072
|
|
|
2073
|
+
def _on_a_friendly_captcha_page(self, *args, **kwargs):
|
|
2074
|
+
self.loop.run_until_complete(self.page.wait(0.05))
|
|
2075
|
+
if self.is_element_visible('iframe[data--frc-frame-id]'):
|
|
2076
|
+
return True
|
|
2077
|
+
return False
|
|
2078
|
+
|
|
2069
2079
|
def _on_a_g_recaptcha_page(self, *args, **kwargs):
|
|
2070
2080
|
time.sleep(0.4) # reCAPTCHA may need a moment to appear
|
|
2071
2081
|
self.loop.run_until_complete(self.page.wait(0.1))
|
|
@@ -2127,7 +2137,7 @@ class CDPMethods():
|
|
|
2127
2137
|
sb_config._saved_cf_x_y = (x, y)
|
|
2128
2138
|
time.sleep(0.08)
|
|
2129
2139
|
if use_cdp:
|
|
2130
|
-
|
|
2140
|
+
time.sleep(0.03)
|
|
2131
2141
|
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
|
2132
2142
|
with gui_lock: # Prevent issues with multiple processes
|
|
2133
2143
|
self.bring_active_window_to_front()
|
|
@@ -2159,7 +2169,7 @@ class CDPMethods():
|
|
|
2159
2169
|
time.sleep(0.15)
|
|
2160
2170
|
return True
|
|
2161
2171
|
|
|
2162
|
-
def __cdp_click_incapsula_hcaptcha(self):
|
|
2172
|
+
def __cdp_click_incapsula_hcaptcha(self, use_cdp=True):
|
|
2163
2173
|
selector = "iframe[data-hcaptcha-widget-id]"
|
|
2164
2174
|
if self.is_element_visible('iframe[src*="_Incapsula_Resource?"]'):
|
|
2165
2175
|
outer_selector = 'iframe[src*="_Incapsula_Resource?"]'
|
|
@@ -2208,6 +2218,56 @@ class CDPMethods():
|
|
|
2208
2218
|
print(" <DEBUG> hCaptcha was NOT clicked!")
|
|
2209
2219
|
return False
|
|
2210
2220
|
|
|
2221
|
+
def __gui_click_friendly_captcha(self, use_cdp=False):
|
|
2222
|
+
selector = 'iframe[data--frc-frame-id]'
|
|
2223
|
+
if self.is_element_visible('iframe[data--frc-frame-id]'):
|
|
2224
|
+
element = self.select('iframe[data--frc-frame-id]')
|
|
2225
|
+
else:
|
|
2226
|
+
return False
|
|
2227
|
+
time.sleep(0.05)
|
|
2228
|
+
self.loop.run_until_complete(self.page.wait(0.1))
|
|
2229
|
+
time.sleep(0.05)
|
|
2230
|
+
with suppress(Exception):
|
|
2231
|
+
element_rect = self.get_element_rect(selector, timeout=0.1)
|
|
2232
|
+
e_x = element_rect["x"]
|
|
2233
|
+
e_y = element_rect["y"]
|
|
2234
|
+
window_rect = self.get_window_rect()
|
|
2235
|
+
win_width = window_rect["innerWidth"]
|
|
2236
|
+
win_height = window_rect["innerHeight"]
|
|
2237
|
+
if (
|
|
2238
|
+
e_x > 1040
|
|
2239
|
+
and e_y > 640
|
|
2240
|
+
and abs(win_width - e_x) < 110
|
|
2241
|
+
and abs(win_height - e_y) < 110
|
|
2242
|
+
):
|
|
2243
|
+
return False
|
|
2244
|
+
gui_element_rect = self.get_gui_element_rect(selector, timeout=1)
|
|
2245
|
+
gui_e_x = gui_element_rect["x"]
|
|
2246
|
+
gui_e_y = gui_element_rect["y"]
|
|
2247
|
+
x_offset = 27
|
|
2248
|
+
y_offset = 34
|
|
2249
|
+
x = gui_e_x + x_offset
|
|
2250
|
+
y = gui_e_y + y_offset
|
|
2251
|
+
sb_config._saved_cf_x_y = (x, y)
|
|
2252
|
+
time.sleep(0.08)
|
|
2253
|
+
if use_cdp:
|
|
2254
|
+
time.sleep(0.03)
|
|
2255
|
+
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
|
2256
|
+
with gui_lock: # Prevent issues with multiple processes
|
|
2257
|
+
self.bring_active_window_to_front()
|
|
2258
|
+
time.sleep(0.06)
|
|
2259
|
+
element.mouse_move()
|
|
2260
|
+
time.sleep(0.08)
|
|
2261
|
+
self.click_with_offset(selector, x_offset, y_offset)
|
|
2262
|
+
time.sleep(0.08)
|
|
2263
|
+
element.mouse_move()
|
|
2264
|
+
time.sleep(0.25)
|
|
2265
|
+
return True
|
|
2266
|
+
else:
|
|
2267
|
+
self.gui_click_x_y(x, y)
|
|
2268
|
+
return True
|
|
2269
|
+
return False
|
|
2270
|
+
|
|
2211
2271
|
def solve_captcha(self):
|
|
2212
2272
|
self.__click_captcha(use_cdp=True)
|
|
2213
2273
|
|
|
@@ -2221,9 +2281,9 @@ class CDPMethods():
|
|
|
2221
2281
|
|
|
2222
2282
|
def __click_captcha(self, use_cdp=False):
|
|
2223
2283
|
"""Uses PyAutoGUI unless use_cdp == True"""
|
|
2224
|
-
|
|
2284
|
+
time.sleep(0.075)
|
|
2225
2285
|
self.loop.run_until_complete(self.page.wait(0.1))
|
|
2226
|
-
|
|
2286
|
+
time.sleep(0.025)
|
|
2227
2287
|
source = self.get_page_source()
|
|
2228
2288
|
if self._on_a_cf_turnstile_page(source):
|
|
2229
2289
|
pass
|
|
@@ -2236,6 +2296,9 @@ class CDPMethods():
|
|
|
2236
2296
|
elif self._on_a_datadome_slider_page():
|
|
2237
2297
|
result = self.__gui_slide_datadome_captcha()
|
|
2238
2298
|
return result
|
|
2299
|
+
elif self._on_a_friendly_captcha_page():
|
|
2300
|
+
result = self.__gui_click_friendly_captcha(use_cdp)
|
|
2301
|
+
return result
|
|
2239
2302
|
else:
|
|
2240
2303
|
return False
|
|
2241
2304
|
selector = None
|
|
@@ -2391,7 +2454,7 @@ class CDPMethods():
|
|
|
2391
2454
|
if hasattr(sb_config, "_cdp_proxy") and sb_config._cdp_proxy:
|
|
2392
2455
|
time.sleep(0.22) # CAPTCHA may load slower with proxy
|
|
2393
2456
|
if use_cdp:
|
|
2394
|
-
|
|
2457
|
+
time.sleep(0.03)
|
|
2395
2458
|
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
|
2396
2459
|
with gui_lock: # Prevent issues with multiple processes
|
|
2397
2460
|
self.bring_active_window_to_front()
|
|
@@ -2591,9 +2654,9 @@ class CDPMethods():
|
|
|
2591
2654
|
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
|
2592
2655
|
with gui_lock:
|
|
2593
2656
|
self.bring_active_window_to_front()
|
|
2594
|
-
|
|
2657
|
+
time.sleep(0.02)
|
|
2595
2658
|
element.mouse_move()
|
|
2596
|
-
|
|
2659
|
+
time.sleep(timeframe)
|
|
2597
2660
|
|
|
2598
2661
|
def hover_and_click(self, hover_selector, click_selector):
|
|
2599
2662
|
if getattr(sb_config, "_cdp_mobile_mode", None):
|
|
@@ -2603,9 +2666,9 @@ class CDPMethods():
|
|
|
2603
2666
|
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
|
2604
2667
|
with gui_lock:
|
|
2605
2668
|
self.bring_active_window_to_front()
|
|
2606
|
-
|
|
2669
|
+
time.sleep(0.02)
|
|
2607
2670
|
hover_element.mouse_move()
|
|
2608
|
-
|
|
2671
|
+
time.sleep(0.25)
|
|
2609
2672
|
try:
|
|
2610
2673
|
self.click(click_selector, timeout=0.5)
|
|
2611
2674
|
except Exception:
|
|
@@ -1408,9 +1408,7 @@ def SB(
|
|
|
1408
1408
|
test_passed = True # This can change later
|
|
1409
1409
|
teardown_exception = None
|
|
1410
1410
|
if "--trace" in sys_argv:
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
pdb.set_trace() # Debug Mode
|
|
1411
|
+
breakpoint() # Debug Mode
|
|
1414
1412
|
# Type "s" and press [Enter] to step into "yield sb".
|
|
1415
1413
|
try:
|
|
1416
1414
|
yield sb
|