seleniumbase 4.47.4__tar.gz → 4.47.6__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.4/seleniumbase.egg-info → seleniumbase-4.47.6}/PKG-INFO +47 -35
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/README.md +43 -31
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/requirements.txt +3 -3
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/browser_launcher.py +1 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/sb_cdp.py +21 -15
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/base_case.py +31 -15
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/page_actions.py +1 -1
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/tab.py +13 -7
- {seleniumbase-4.47.4 → seleniumbase-4.47.6/seleniumbase.egg-info}/PKG-INFO +47 -35
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/requires.txt +3 -3
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/setup.py +3 -3
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/.gitignore +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/LICENSE +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/MANIFEST.in +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/install.sh +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/pyproject.toml +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/pytest.ini +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/sbase/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/sbase/__main__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/sbase/steps.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/pytest_plugin.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/sb_manager.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/setup.cfg +0 -0
- {seleniumbase-4.47.4 → seleniumbase-4.47.6}/virtualenv_install.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.47.
|
|
3
|
+
Version: 4.47.6
|
|
4
4
|
Summary: A complete web automation framework for end-to-end testing.
|
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
|
6
6
|
Author: Michael Mintz
|
|
@@ -63,7 +63,7 @@ Requires-Dist: packaging>=26.0
|
|
|
63
63
|
Requires-Dist: setuptools~=70.2; python_version < "3.10"
|
|
64
64
|
Requires-Dist: setuptools>=82.0.1; python_version >= "3.10"
|
|
65
65
|
Requires-Dist: wheel>=0.46.3
|
|
66
|
-
Requires-Dist: attrs>=
|
|
66
|
+
Requires-Dist: attrs>=26.1.0
|
|
67
67
|
Requires-Dist: certifi>=2026.2.25
|
|
68
68
|
Requires-Dist: exceptiongroup>=1.3.1
|
|
69
69
|
Requires-Dist: websockets~=15.0.1; python_version < "3.10"
|
|
@@ -71,7 +71,7 @@ Requires-Dist: websockets>=16.0; python_version >= "3.10"
|
|
|
71
71
|
Requires-Dist: filelock~=3.19.1; python_version < "3.10"
|
|
72
72
|
Requires-Dist: filelock>=3.25.2; python_version >= "3.10"
|
|
73
73
|
Requires-Dist: fasteners>=0.20
|
|
74
|
-
Requires-Dist: mycdp>=1.3.
|
|
74
|
+
Requires-Dist: mycdp>=1.3.7
|
|
75
75
|
Requires-Dist: pynose>=1.5.5
|
|
76
76
|
Requires-Dist: platformdirs~=4.4.0; python_version < "3.10"
|
|
77
77
|
Requires-Dist: platformdirs>=4.9.4; python_version >= "3.10"
|
|
@@ -139,7 +139,7 @@ Requires-Dist: allure-behave>=2.13.5; extra == "allure"
|
|
|
139
139
|
Provides-Extra: coverage
|
|
140
140
|
Requires-Dist: coverage>=7.10.7; python_version < "3.10" and extra == "coverage"
|
|
141
141
|
Requires-Dist: coverage>=7.13.5; python_version >= "3.10" and extra == "coverage"
|
|
142
|
-
Requires-Dist: pytest-cov>=7.
|
|
142
|
+
Requires-Dist: pytest-cov>=7.1.0; extra == "coverage"
|
|
143
143
|
Provides-Extra: flake8
|
|
144
144
|
Requires-Dist: flake8==7.3.0; extra == "flake8"
|
|
145
145
|
Requires-Dist: mccabe==0.7.0; extra == "flake8"
|
|
@@ -209,7 +209,7 @@ Dynamic: summary
|
|
|
209
209
|
|
|
210
210
|
<h1>SeleniumBase</h1>
|
|
211
211
|
|
|
212
|
-
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/
|
|
212
|
+
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/nice_logo_8t.png" alt="SeleniumBase" width="424" /></a></p>
|
|
213
213
|
|
|
214
214
|
<p align="center" class="hero__title"><b>All-in-one Browser Automation Framework:<br />Web Crawling / Testing / Scraping / Stealth</b></p>
|
|
215
215
|
|
|
@@ -252,17 +252,40 @@ Dynamic: summary
|
|
|
252
252
|
<br />
|
|
253
253
|
</p>
|
|
254
254
|
|
|
255
|
-
📊 <a href="https://github.com/seleniumbase/SeleniumBase/"><b translate="no">SeleniumBase</b></a> is a complete framework for
|
|
255
|
+
📊 <a href="https://github.com/seleniumbase/SeleniumBase/"><b translate="no">SeleniumBase</b></a> is a complete framework for browser automation and testing with Python and <a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a>. Includes stealth options and other advanced features.
|
|
256
256
|
|
|
257
|
-
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">UC Mode</a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> can bypass bot-detection,
|
|
257
|
+
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">UC Mode</a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> can bypass bot-detection, handle CAPTCHAs, and call methods from the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome Devtools Protocol</a>. CDP Mode includes <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md"><b><span translate="no">Stealthy Playwright Mode</span></b></a>, which makes Playwright stealthy.
|
|
258
258
|
|
|
259
|
-
📚
|
|
259
|
+
📚 The [SeleniumBase/examples/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder includes over 100 ready-to-run examples. Examples that start with `test_` or end with `_test.py`/`_tests.py` are specifically designed to run with `pytest`. Other examples run directly with raw `python` (those files generally start with `raw_` to avoid confusion).
|
|
260
260
|
|
|
261
|
-
🥷 Stealthy
|
|
261
|
+
🥷 Stealthy examples are located in [SeleniumBase/examples/cdp_mode/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
|
|
262
262
|
|
|
263
263
|
--------
|
|
264
264
|
|
|
265
|
-
<
|
|
265
|
+
<h3 align="left">⚙️ Stealthy architecture flowchart:</h3>
|
|
266
|
+
|
|
267
|
+
<img src="https://seleniumbase.github.io/other/sb_stealth.png" width="596" alt="Stealthy architecture flowchart" />
|
|
268
|
+
|
|
269
|
+
(For maximum stealth, use <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">CDP Mode</a>, which includes <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">Stealthy Playwright Mode</a>)
|
|
270
|
+
|
|
271
|
+
--------
|
|
272
|
+
|
|
273
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_yc_news.py" target="_blank">This example</a> scrapes Hacker News listings with <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md#-pure-cdp-mode-sb_cdp">Pure CDP Mode</a>:
|
|
274
|
+
|
|
275
|
+
```python
|
|
276
|
+
from seleniumbase import sb_cdp
|
|
277
|
+
|
|
278
|
+
url = "https://news.ycombinator.com/submitted?id=seleniumbase"
|
|
279
|
+
sb = sb_cdp.Chrome(url)
|
|
280
|
+
elements = sb.find_elements("span.titleline > a")
|
|
281
|
+
for element in elements:
|
|
282
|
+
print("* " + element.text)
|
|
283
|
+
sb.driver.stop()
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
--------
|
|
287
|
+
|
|
288
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py" target="_blank">This example</a> saves Google Search results with UC + CDP Mode:<br />(Results are saved as PDF, HTML, and PNG files)</p>
|
|
266
289
|
|
|
267
290
|
```python
|
|
268
291
|
from seleniumbase import SB
|
|
@@ -280,13 +303,9 @@ with SB(uc=True, test=True) as sb:
|
|
|
280
303
|
print("Logs have been saved to: ./latest_logs/")
|
|
281
304
|
```
|
|
282
305
|
|
|
283
|
-
> `python raw_google.py`
|
|
284
|
-
|
|
285
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/img/google_sb_result.jpg" alt="SeleniumBase on Google" title="SeleniumBase on Google" width="580" /></a>
|
|
286
|
-
|
|
287
306
|
--------
|
|
288
307
|
|
|
289
|
-
<p align="left">📗
|
|
308
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py" target="_blank">This example</a> bypasses Cloudflare's challenge page with UC + CDP Mode:
|
|
290
309
|
|
|
291
310
|
```python
|
|
292
311
|
from seleniumbase import SB
|
|
@@ -304,9 +323,11 @@ with SB(uc=True, test=True, locale="en") as sb:
|
|
|
304
323
|
sb.post_message("SeleniumBase wasn't detected", duration=4)
|
|
305
324
|
```
|
|
306
325
|
|
|
307
|
-
<img src="https://seleniumbase.github.io/other/cf_sec.jpg"
|
|
326
|
+
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" alt="SeleniumBase" width="344"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" alt="SeleniumBase" width="298">
|
|
327
|
+
|
|
328
|
+
----
|
|
308
329
|
|
|
309
|
-
<p align="left"
|
|
330
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py" target="_blank">This example</a> handles a CAPTCHA page with Pure CDP Mode:
|
|
310
331
|
|
|
311
332
|
```python
|
|
312
333
|
from seleniumbase import sb_cdp
|
|
@@ -322,7 +343,7 @@ sb.driver.stop()
|
|
|
322
343
|
|
|
323
344
|
--------
|
|
324
345
|
|
|
325
|
-
<p align="left">📗
|
|
346
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py" target="_blank">This example</a> tests an e-commerce site with <code>pytest</code>:
|
|
326
347
|
|
|
327
348
|
```python
|
|
328
349
|
from seleniumbase import BaseCase
|
|
@@ -348,19 +369,17 @@ class MyTestClass(BaseCase):
|
|
|
348
369
|
|
|
349
370
|
> `pytest test_get_swag.py`
|
|
350
371
|
|
|
351
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test"
|
|
352
|
-
|
|
353
|
-
> (The default browser is `--chrome` if not set.)
|
|
372
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" width="480" /></a>
|
|
354
373
|
|
|
355
374
|
--------
|
|
356
375
|
|
|
357
|
-
<p align="left">📗
|
|
376
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">This example</a> tests another e-commerce site with <code>pytest</code>:
|
|
358
377
|
|
|
359
378
|
```zsh
|
|
360
379
|
pytest test_coffee_cart.py --demo
|
|
361
380
|
```
|
|
362
381
|
|
|
363
|
-
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test"
|
|
382
|
+
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test" /></a></p>
|
|
364
383
|
|
|
365
384
|
> <p>(<code translate="no">--demo</code> mode slows down tests and highlights actions)</p>
|
|
366
385
|
|
|
@@ -368,13 +387,13 @@ pytest test_coffee_cart.py --demo
|
|
|
368
387
|
|
|
369
388
|
<a id="multiple_examples"></a>
|
|
370
389
|
|
|
371
|
-
<p align="left">📗
|
|
390
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">This example</a> covers multiple actions with <code>pytest</code>:
|
|
372
391
|
|
|
373
392
|
```zsh
|
|
374
393
|
pytest test_demo_site.py
|
|
375
394
|
```
|
|
376
395
|
|
|
377
|
-
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example"
|
|
396
|
+
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example" /></a></p>
|
|
378
397
|
|
|
379
398
|
> Easy to type, click, select, toggle, drag & drop, and more.
|
|
380
399
|
|
|
@@ -382,14 +401,6 @@ pytest test_demo_site.py
|
|
|
382
401
|
|
|
383
402
|
--------
|
|
384
403
|
|
|
385
|
-
<p align="left">📓 Here's a high-level stealthy architecture overview of SeleniumBase:</p>
|
|
386
|
-
|
|
387
|
-
<img src="https://seleniumbase.github.io/other/sb_stealth.png" width="585" alt="High-Level Stealthy Architecture Overview" title="High-Level Stealthy Architecture Overview" />
|
|
388
|
-
|
|
389
|
-
(For maximum stealth, use <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">CDP Mode</a>, which is used by <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">Stealthy Playwright Mode</a>)
|
|
390
|
-
|
|
391
|
-
--------
|
|
392
|
-
|
|
393
404
|
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/super_logo_sb3.png" alt="SeleniumBase" title="SeleniumBase" width="232" /></a></p>
|
|
394
405
|
|
|
395
406
|
<blockquote>
|
|
@@ -637,7 +648,7 @@ cd examples/
|
|
|
637
648
|
pytest my_first_test.py
|
|
638
649
|
```
|
|
639
650
|
|
|
640
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test"
|
|
651
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" width="480" /></a>
|
|
641
652
|
|
|
642
653
|
<p align="left"><b>Here's the full code for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>:</b></p>
|
|
643
654
|
|
|
@@ -681,6 +692,7 @@ class MyTestClass(BaseCase):
|
|
|
681
692
|
|
|
682
693
|
```python
|
|
683
694
|
self.open(url) # Navigate the browser window to the URL.
|
|
695
|
+
self.activate_cdp_mode() # Activate CDP Mode from UC Mode.
|
|
684
696
|
self.type(selector, text) # Update the field with the text.
|
|
685
697
|
self.click(selector) # Click the element with the selector.
|
|
686
698
|
self.click_link(link_text) # Click the link containing text.
|
|
@@ -769,7 +781,7 @@ pytest [FILE_NAME.py]::[CLASS_NAME]::[METHOD_NAME]
|
|
|
769
781
|
pynose [FILE_NAME.py]:[CLASS_NAME].[METHOD_NAME]
|
|
770
782
|
```
|
|
771
783
|
|
|
772
|
-
<p>✅ No More Flaky Tests! SeleniumBase methods automatically wait for page elements to finish loading before interacting with them (<i>up to a timeout limit</i>)
|
|
784
|
+
<p>✅ No More Flaky Tests! SeleniumBase methods automatically wait for page elements to finish loading before interacting with them (<i>up to a timeout limit</i>).</p>
|
|
773
785
|
<img src="https://img.shields.io/badge/Flaky%20Tests%3F-%20NO%21-11BBDD.svg" alt="NO MORE FLAKY TESTS!" />
|
|
774
786
|
|
|
775
787
|
✅ SeleniumBase supports all major browsers and operating systems:
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
<h1>SeleniumBase</h1>
|
|
11
11
|
|
|
12
|
-
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/
|
|
12
|
+
<p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/nice_logo_8t.png" alt="SeleniumBase" width="424" /></a></p>
|
|
13
13
|
|
|
14
14
|
<p align="center" class="hero__title"><b>All-in-one Browser Automation Framework:<br />Web Crawling / Testing / Scraping / Stealth</b></p>
|
|
15
15
|
|
|
@@ -52,17 +52,40 @@
|
|
|
52
52
|
<br />
|
|
53
53
|
</p>
|
|
54
54
|
|
|
55
|
-
📊 <a href="https://github.com/seleniumbase/SeleniumBase/"><b translate="no">SeleniumBase</b></a> is a complete framework for
|
|
55
|
+
📊 <a href="https://github.com/seleniumbase/SeleniumBase/"><b translate="no">SeleniumBase</b></a> is a complete framework for browser automation and testing with Python and <a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a>. Includes stealth options and other advanced features.
|
|
56
56
|
|
|
57
|
-
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">UC Mode</a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> can bypass bot-detection,
|
|
57
|
+
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">UC Mode</a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> can bypass bot-detection, handle CAPTCHAs, and call methods from the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome Devtools Protocol</a>. CDP Mode includes <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md"><b><span translate="no">Stealthy Playwright Mode</span></b></a>, which makes Playwright stealthy.
|
|
58
58
|
|
|
59
|
-
📚
|
|
59
|
+
📚 The [SeleniumBase/examples/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder includes over 100 ready-to-run examples. Examples that start with `test_` or end with `_test.py`/`_tests.py` are specifically designed to run with `pytest`. Other examples run directly with raw `python` (those files generally start with `raw_` to avoid confusion).
|
|
60
60
|
|
|
61
|
-
🥷 Stealthy
|
|
61
|
+
🥷 Stealthy examples are located in [SeleniumBase/examples/cdp_mode/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
|
|
62
62
|
|
|
63
63
|
--------
|
|
64
64
|
|
|
65
|
-
<
|
|
65
|
+
<h3 align="left">⚙️ Stealthy architecture flowchart:</h3>
|
|
66
|
+
|
|
67
|
+
<img src="https://seleniumbase.github.io/other/sb_stealth.png" width="596" alt="Stealthy architecture flowchart" />
|
|
68
|
+
|
|
69
|
+
(For maximum stealth, use <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">CDP Mode</a>, which includes <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">Stealthy Playwright Mode</a>)
|
|
70
|
+
|
|
71
|
+
--------
|
|
72
|
+
|
|
73
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_yc_news.py" target="_blank">This example</a> scrapes Hacker News listings with <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md#-pure-cdp-mode-sb_cdp">Pure CDP Mode</a>:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from seleniumbase import sb_cdp
|
|
77
|
+
|
|
78
|
+
url = "https://news.ycombinator.com/submitted?id=seleniumbase"
|
|
79
|
+
sb = sb_cdp.Chrome(url)
|
|
80
|
+
elements = sb.find_elements("span.titleline > a")
|
|
81
|
+
for element in elements:
|
|
82
|
+
print("* " + element.text)
|
|
83
|
+
sb.driver.stop()
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
--------
|
|
87
|
+
|
|
88
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py" target="_blank">This example</a> saves Google Search results with UC + CDP Mode:<br />(Results are saved as PDF, HTML, and PNG files)</p>
|
|
66
89
|
|
|
67
90
|
```python
|
|
68
91
|
from seleniumbase import SB
|
|
@@ -80,13 +103,9 @@ with SB(uc=True, test=True) as sb:
|
|
|
80
103
|
print("Logs have been saved to: ./latest_logs/")
|
|
81
104
|
```
|
|
82
105
|
|
|
83
|
-
> `python raw_google.py`
|
|
84
|
-
|
|
85
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/img/google_sb_result.jpg" alt="SeleniumBase on Google" title="SeleniumBase on Google" width="580" /></a>
|
|
86
|
-
|
|
87
106
|
--------
|
|
88
107
|
|
|
89
|
-
<p align="left">📗
|
|
108
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py" target="_blank">This example</a> bypasses Cloudflare's challenge page with UC + CDP Mode:
|
|
90
109
|
|
|
91
110
|
```python
|
|
92
111
|
from seleniumbase import SB
|
|
@@ -104,9 +123,11 @@ with SB(uc=True, test=True, locale="en") as sb:
|
|
|
104
123
|
sb.post_message("SeleniumBase wasn't detected", duration=4)
|
|
105
124
|
```
|
|
106
125
|
|
|
107
|
-
<img src="https://seleniumbase.github.io/other/cf_sec.jpg"
|
|
126
|
+
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" alt="SeleniumBase" width="344"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" alt="SeleniumBase" width="298">
|
|
127
|
+
|
|
128
|
+
----
|
|
108
129
|
|
|
109
|
-
<p align="left"
|
|
130
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py" target="_blank">This example</a> handles a CAPTCHA page with Pure CDP Mode:
|
|
110
131
|
|
|
111
132
|
```python
|
|
112
133
|
from seleniumbase import sb_cdp
|
|
@@ -122,7 +143,7 @@ sb.driver.stop()
|
|
|
122
143
|
|
|
123
144
|
--------
|
|
124
145
|
|
|
125
|
-
<p align="left">📗
|
|
146
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py" target="_blank">This example</a> tests an e-commerce site with <code>pytest</code>:
|
|
126
147
|
|
|
127
148
|
```python
|
|
128
149
|
from seleniumbase import BaseCase
|
|
@@ -148,19 +169,17 @@ class MyTestClass(BaseCase):
|
|
|
148
169
|
|
|
149
170
|
> `pytest test_get_swag.py`
|
|
150
171
|
|
|
151
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test"
|
|
152
|
-
|
|
153
|
-
> (The default browser is `--chrome` if not set.)
|
|
172
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" width="480" /></a>
|
|
154
173
|
|
|
155
174
|
--------
|
|
156
175
|
|
|
157
|
-
<p align="left">📗
|
|
176
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">This example</a> tests another e-commerce site with <code>pytest</code>:
|
|
158
177
|
|
|
159
178
|
```zsh
|
|
160
179
|
pytest test_coffee_cart.py --demo
|
|
161
180
|
```
|
|
162
181
|
|
|
163
|
-
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test"
|
|
182
|
+
<p align="left"><a href="https://seleniumbase.io/coffee/" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/coffee_cart.gif" width="480" alt="SeleniumBase Coffee Cart Test" /></a></p>
|
|
164
183
|
|
|
165
184
|
> <p>(<code translate="no">--demo</code> mode slows down tests and highlights actions)</p>
|
|
166
185
|
|
|
@@ -168,13 +187,13 @@ pytest test_coffee_cart.py --demo
|
|
|
168
187
|
|
|
169
188
|
<a id="multiple_examples"></a>
|
|
170
189
|
|
|
171
|
-
<p align="left">📗
|
|
190
|
+
<p align="left">📗 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">This example</a> covers multiple actions with <code>pytest</code>:
|
|
172
191
|
|
|
173
192
|
```zsh
|
|
174
193
|
pytest test_demo_site.py
|
|
175
194
|
```
|
|
176
195
|
|
|
177
|
-
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example"
|
|
196
|
+
<p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example" /></a></p>
|
|
178
197
|
|
|
179
198
|
> Easy to type, click, select, toggle, drag & drop, and more.
|
|
180
199
|
|
|
@@ -182,14 +201,6 @@ pytest test_demo_site.py
|
|
|
182
201
|
|
|
183
202
|
--------
|
|
184
203
|
|
|
185
|
-
<p align="left">📓 Here's a high-level stealthy architecture overview of SeleniumBase:</p>
|
|
186
|
-
|
|
187
|
-
<img src="https://seleniumbase.github.io/other/sb_stealth.png" width="585" alt="High-Level Stealthy Architecture Overview" title="High-Level Stealthy Architecture Overview" />
|
|
188
|
-
|
|
189
|
-
(For maximum stealth, use <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">CDP Mode</a>, which is used by <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">Stealthy Playwright Mode</a>)
|
|
190
|
-
|
|
191
|
-
--------
|
|
192
|
-
|
|
193
204
|
<p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/super_logo_sb3.png" alt="SeleniumBase" title="SeleniumBase" width="232" /></a></p>
|
|
194
205
|
|
|
195
206
|
<blockquote>
|
|
@@ -437,7 +448,7 @@ cd examples/
|
|
|
437
448
|
pytest my_first_test.py
|
|
438
449
|
```
|
|
439
450
|
|
|
440
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test"
|
|
451
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" width="480" /></a>
|
|
441
452
|
|
|
442
453
|
<p align="left"><b>Here's the full code for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>:</b></p>
|
|
443
454
|
|
|
@@ -481,6 +492,7 @@ class MyTestClass(BaseCase):
|
|
|
481
492
|
|
|
482
493
|
```python
|
|
483
494
|
self.open(url) # Navigate the browser window to the URL.
|
|
495
|
+
self.activate_cdp_mode() # Activate CDP Mode from UC Mode.
|
|
484
496
|
self.type(selector, text) # Update the field with the text.
|
|
485
497
|
self.click(selector) # Click the element with the selector.
|
|
486
498
|
self.click_link(link_text) # Click the link containing text.
|
|
@@ -569,7 +581,7 @@ pytest [FILE_NAME.py]::[CLASS_NAME]::[METHOD_NAME]
|
|
|
569
581
|
pynose [FILE_NAME.py]:[CLASS_NAME].[METHOD_NAME]
|
|
570
582
|
```
|
|
571
583
|
|
|
572
|
-
<p>✅ No More Flaky Tests! SeleniumBase methods automatically wait for page elements to finish loading before interacting with them (<i>up to a timeout limit</i>)
|
|
584
|
+
<p>✅ No More Flaky Tests! SeleniumBase methods automatically wait for page elements to finish loading before interacting with them (<i>up to a timeout limit</i>).</p>
|
|
573
585
|
<img src="https://img.shields.io/badge/Flaky%20Tests%3F-%20NO%21-11BBDD.svg" alt="NO MORE FLAKY TESTS!" />
|
|
574
586
|
|
|
575
587
|
✅ SeleniumBase supports all major browsers and operating systems:
|
|
@@ -3,7 +3,7 @@ packaging>=26.0
|
|
|
3
3
|
setuptools~=70.2;python_version<"3.10"
|
|
4
4
|
setuptools>=82.0.1;python_version>="3.10"
|
|
5
5
|
wheel>=0.46.3
|
|
6
|
-
attrs>=
|
|
6
|
+
attrs>=26.1.0
|
|
7
7
|
certifi>=2026.2.25
|
|
8
8
|
exceptiongroup>=1.3.1
|
|
9
9
|
websockets~=15.0.1;python_version<"3.10"
|
|
@@ -11,7 +11,7 @@ websockets>=16.0;python_version>="3.10"
|
|
|
11
11
|
filelock~=3.19.1;python_version<"3.10"
|
|
12
12
|
filelock>=3.25.2;python_version>="3.10"
|
|
13
13
|
fasteners>=0.20
|
|
14
|
-
mycdp>=1.3.
|
|
14
|
+
mycdp>=1.3.7
|
|
15
15
|
pynose>=1.5.5
|
|
16
16
|
platformdirs~=4.4.0;python_version<"3.10"
|
|
17
17
|
platformdirs>=4.9.4;python_version>="3.10"
|
|
@@ -78,7 +78,7 @@ rich>=14.3.3,<15
|
|
|
78
78
|
|
|
79
79
|
coverage>=7.10.7;python_version<"3.10"
|
|
80
80
|
coverage>=7.13.5;python_version>="3.10"
|
|
81
|
-
pytest-cov>=7.
|
|
81
|
+
pytest-cov>=7.1.0
|
|
82
82
|
flake8==7.3.0
|
|
83
83
|
mccabe==0.7.0
|
|
84
84
|
pyflakes==3.4.0
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# seleniumbase package
|
|
2
|
-
__version__ = "4.47.
|
|
2
|
+
__version__ = "4.47.6"
|
|
@@ -296,6 +296,7 @@ def extend_driver(
|
|
|
296
296
|
driver.switch_to_tab = DM.switch_to_tab
|
|
297
297
|
driver.switch_to_frame = DM.switch_to_frame
|
|
298
298
|
driver.reset_window_size = DM.reset_window_size
|
|
299
|
+
driver.stop = driver.quit
|
|
299
300
|
if recorder_ext:
|
|
300
301
|
from seleniumbase.js_code.recorder_js import recorder_js
|
|
301
302
|
recorder_code = (
|
|
@@ -429,7 +429,7 @@ class CDPMethods():
|
|
|
429
429
|
visible_elements.append(element)
|
|
430
430
|
return visible_elements
|
|
431
431
|
|
|
432
|
-
def click_nth_element(self, selector, number):
|
|
432
|
+
def click_nth_element(self, selector, number, scroll=True):
|
|
433
433
|
elements = self.select_all(selector)
|
|
434
434
|
if len(elements) < number:
|
|
435
435
|
raise Exception(
|
|
@@ -440,10 +440,11 @@ class CDPMethods():
|
|
|
440
440
|
if number < 0:
|
|
441
441
|
number = 0
|
|
442
442
|
element = elements[number]
|
|
443
|
-
|
|
443
|
+
if scroll:
|
|
444
|
+
element.scroll_into_view()
|
|
444
445
|
element.click()
|
|
445
446
|
|
|
446
|
-
def click_nth_visible_element(self, selector, number):
|
|
447
|
+
def click_nth_visible_element(self, selector, number, scroll=True):
|
|
447
448
|
"""Finds all matching page elements and clicks the nth visible one.
|
|
448
449
|
Example: self.click_nth_visible_element('[type="checkbox"]', 5)
|
|
449
450
|
(Clicks the 5th visible checkbox on the page.)"""
|
|
@@ -457,7 +458,8 @@ class CDPMethods():
|
|
|
457
458
|
if number < 0:
|
|
458
459
|
number = 0
|
|
459
460
|
element = elements[number]
|
|
460
|
-
|
|
461
|
+
if scroll:
|
|
462
|
+
element.scroll_into_view()
|
|
461
463
|
element.click()
|
|
462
464
|
|
|
463
465
|
def click_link(self, link_text):
|
|
@@ -793,12 +795,13 @@ class CDPMethods():
|
|
|
793
795
|
js_code = js_code.replace("return getBestSelector", "getBestSelector")
|
|
794
796
|
return self.loop.run_until_complete(self.page.evaluate(js_code))
|
|
795
797
|
|
|
796
|
-
def click(self, selector, timeout=None):
|
|
798
|
+
def click(self, selector, timeout=None, scroll=True):
|
|
797
799
|
if not timeout:
|
|
798
800
|
timeout = settings.SMALL_TIMEOUT
|
|
799
801
|
self.__slow_mode_pause_if_set()
|
|
800
802
|
element = self.find_element(selector, timeout=timeout)
|
|
801
|
-
|
|
803
|
+
if scroll:
|
|
804
|
+
element.scroll_into_view()
|
|
802
805
|
tag_name = element.tag_name
|
|
803
806
|
if tag_name:
|
|
804
807
|
tag_name = tag_name.lower().strip()
|
|
@@ -824,10 +827,10 @@ class CDPMethods():
|
|
|
824
827
|
self.__slow_mode_pause_if_set()
|
|
825
828
|
self.loop.run_until_complete(self.page.wait(0.2))
|
|
826
829
|
|
|
827
|
-
def click_if_visible(self, selector, timeout=0):
|
|
830
|
+
def click_if_visible(self, selector, timeout=0, scroll=True):
|
|
828
831
|
if self.is_element_visible(selector):
|
|
829
832
|
with suppress(Exception):
|
|
830
|
-
self.click(selector, timeout=1)
|
|
833
|
+
self.click(selector, timeout=1, scroll=scroll)
|
|
831
834
|
elif timeout == 0:
|
|
832
835
|
return
|
|
833
836
|
else:
|
|
@@ -836,7 +839,7 @@ class CDPMethods():
|
|
|
836
839
|
if self.is_element_visible(selector):
|
|
837
840
|
self.click(selector, timeout=1)
|
|
838
841
|
|
|
839
|
-
def click_visible_elements(self, selector, limit=0):
|
|
842
|
+
def click_visible_elements(self, selector, limit=0, scroll=True):
|
|
840
843
|
"""Finds all matching page elements and clicks visible ones in order.
|
|
841
844
|
If a click reloads or opens a new page, the clicking will stop.
|
|
842
845
|
If no matching elements appear, an Exception will be raised.
|
|
@@ -859,7 +862,8 @@ class CDPMethods():
|
|
|
859
862
|
except Exception:
|
|
860
863
|
continue
|
|
861
864
|
if (width != 0 or height != 0):
|
|
862
|
-
|
|
865
|
+
if scroll:
|
|
866
|
+
element.scroll_into_view()
|
|
863
867
|
element.click()
|
|
864
868
|
click_count += 1
|
|
865
869
|
time.sleep(0.044)
|
|
@@ -868,13 +872,14 @@ class CDPMethods():
|
|
|
868
872
|
except Exception:
|
|
869
873
|
break
|
|
870
874
|
|
|
871
|
-
def mouse_click(self, selector, timeout=None):
|
|
875
|
+
def mouse_click(self, selector, timeout=None, scroll=True):
|
|
872
876
|
"""(Attempt simulating a mouse click)"""
|
|
873
877
|
if not timeout:
|
|
874
878
|
timeout = settings.SMALL_TIMEOUT
|
|
875
879
|
self.__slow_mode_pause_if_set()
|
|
876
880
|
element = self.find_element(selector, timeout=timeout)
|
|
877
|
-
|
|
881
|
+
if scroll:
|
|
882
|
+
element.scroll_into_view()
|
|
878
883
|
element.mouse_click()
|
|
879
884
|
self.__slow_mode_pause_if_set()
|
|
880
885
|
self.loop.run_until_complete(self.page.wait(0.2))
|
|
@@ -1335,7 +1340,7 @@ class CDPMethods():
|
|
|
1335
1340
|
def get_window(self):
|
|
1336
1341
|
return self.loop.run_until_complete(self.page.get_window())
|
|
1337
1342
|
|
|
1338
|
-
def get_text(self, selector):
|
|
1343
|
+
def get_text(self, selector="body"):
|
|
1339
1344
|
return self.find_element(selector).text_all
|
|
1340
1345
|
|
|
1341
1346
|
def get_title(self):
|
|
@@ -1970,9 +1975,10 @@ class CDPMethods():
|
|
|
1970
1975
|
py = element_rect["y"]
|
|
1971
1976
|
self.gui_click_x_y(px + x, py + y, timeframe=timeframe)
|
|
1972
1977
|
|
|
1973
|
-
def click_with_offset(self, selector, x, y, center=False):
|
|
1978
|
+
def click_with_offset(self, selector, x, y, center=False, scroll=True):
|
|
1974
1979
|
element = self.find_element(selector)
|
|
1975
|
-
|
|
1980
|
+
if scroll:
|
|
1981
|
+
element.scroll_into_view()
|
|
1976
1982
|
if "--debug" in sys.argv:
|
|
1977
1983
|
displayed_selector = "`%s`" % selector
|
|
1978
1984
|
if '"' not in selector:
|