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.
Files changed (162) hide show
  1. {seleniumbase-4.47.4/seleniumbase.egg-info → seleniumbase-4.47.6}/PKG-INFO +47 -35
  2. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/README.md +43 -31
  3. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/requirements.txt +3 -3
  4. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/__version__.py +1 -1
  5. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/browser_launcher.py +1 -0
  6. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/sb_cdp.py +21 -15
  7. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/base_case.py +31 -15
  8. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/page_actions.py +1 -1
  9. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/tab.py +13 -7
  10. {seleniumbase-4.47.4 → seleniumbase-4.47.6/seleniumbase.egg-info}/PKG-INFO +47 -35
  11. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/requires.txt +3 -3
  12. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/setup.py +3 -3
  13. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/.gitignore +0 -0
  14. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/LICENSE +0 -0
  15. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/MANIFEST.in +0 -0
  16. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/install.sh +0 -0
  17. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/pyproject.toml +0 -0
  18. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/pytest.ini +0 -0
  19. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/sbase/__init__.py +0 -0
  20. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/sbase/__main__.py +0 -0
  21. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/sbase/steps.py +0 -0
  22. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/__init__.py +0 -0
  23. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/__main__.py +0 -0
  24. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/behave/__init__.py +0 -0
  25. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/behave/behave_helper.py +0 -0
  26. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/behave/behave_sb.py +0 -0
  27. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/behave/steps.py +0 -0
  28. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/__init__.py +0 -0
  29. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/decorators.py +0 -0
  30. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/encryption.py +0 -0
  31. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/exceptions.py +0 -0
  32. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/obfuscate.py +0 -0
  33. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/common/unobfuscate.py +0 -0
  34. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/config/__init__.py +0 -0
  35. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/config/ad_block_list.py +0 -0
  36. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/config/proxy_list.py +0 -0
  37. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/config/settings.py +0 -0
  38. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/__init__.py +0 -0
  39. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/logo_helper.py +0 -0
  40. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/rich_helper.py +0 -0
  41. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/run.py +0 -0
  42. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
  43. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
  44. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_commander.py +0 -0
  45. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_install.py +0 -0
  46. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
  47. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
  48. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
  49. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
  50. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
  51. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_objectify.py +0 -0
  52. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_print.py +0 -0
  53. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/console_scripts/sb_recorder.py +0 -0
  54. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/__init__.py +0 -0
  55. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/application_manager.py +0 -0
  56. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/capabilities_parser.py +0 -0
  57. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/colored_traceback.py +0 -0
  58. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/create_db_tables.sql +0 -0
  59. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/detect_b_ver.py +0 -0
  60. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/download_helper.py +0 -0
  61. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/encoded_images.py +0 -0
  62. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/jqc_helper.py +0 -0
  63. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/log_helper.py +0 -0
  64. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/mysql.py +0 -0
  65. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/proxy_helper.py +0 -0
  66. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/recorder_helper.py +0 -0
  67. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/report_helper.py +0 -0
  68. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/s3_manager.py +0 -0
  69. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/sb_driver.py +0 -0
  70. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/session_helper.py +0 -0
  71. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/settings_parser.py +0 -0
  72. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/style_sheet.py +0 -0
  73. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/testcase_manager.py +0 -0
  74. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/tour_helper.py +0 -0
  75. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/core/visual_helper.py +0 -0
  76. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/__init__.py +0 -0
  77. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
  78. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
  79. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
  80. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
  81. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
  82. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
  83. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
  84. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/__init__.py +0 -0
  85. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/ad_block.zip +0 -0
  86. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/disable_csp.zip +0 -0
  87. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/recorder.zip +0 -0
  88. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/extensions/sbase_ext.zip +0 -0
  89. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/__init__.py +0 -0
  90. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/constants.py +0 -0
  91. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/css_to_xpath.py +0 -0
  92. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/errors.py +0 -0
  93. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/js_utils.py +0 -0
  94. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/page_utils.py +0 -0
  95. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/shared_utils.py +0 -0
  96. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/unittest_helper.py +0 -0
  97. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/words.py +0 -0
  98. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/fixtures/xpath_to_css.py +0 -0
  99. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/js_code/__init__.py +0 -0
  100. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/js_code/active_css_js.py +0 -0
  101. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/js_code/live_js.py +0 -0
  102. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/js_code/recorder_js.py +0 -0
  103. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/masterqa/__init__.py +0 -0
  104. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/masterqa/master_qa.py +0 -0
  105. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/__init__.py +0 -0
  106. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/base_plugin.py +0 -0
  107. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/basic_test_info.py +0 -0
  108. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
  109. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/driver_manager.py +0 -0
  110. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/page_source.py +0 -0
  111. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/pytest_plugin.py +0 -0
  112. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
  113. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/sb_manager.py +0 -0
  114. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/screen_shots.py +0 -0
  115. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/plugins/selenium_plugin.py +0 -0
  116. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/resources/__init__.py +0 -0
  117. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/__init__.py +0 -0
  118. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/chinese.py +0 -0
  119. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/dutch.py +0 -0
  120. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/french.py +0 -0
  121. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/italian.py +0 -0
  122. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/japanese.py +0 -0
  123. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/korean.py +0 -0
  124. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/master_dict.py +0 -0
  125. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/portuguese.py +0 -0
  126. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/russian.py +0 -0
  127. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/spanish.py +0 -0
  128. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/translate/translator.py +0 -0
  129. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/__init__.py +0 -0
  130. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp.py +0 -0
  131. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
  132. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
  133. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
  134. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
  135. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/config.py +0 -0
  136. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
  137. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/cdp_driver/element.py +0 -0
  138. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/dprocess.py +0 -0
  139. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/options.py +0 -0
  140. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/patcher.py +0 -0
  141. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/reactor.py +0 -0
  142. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/undetected/webelement.py +0 -0
  143. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/__init__.py +0 -0
  144. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
  145. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
  146. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/font_color +0 -0
  147. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
  148. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
  149. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
  150. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
  151. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
  152. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
  153. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
  154. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
  155. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
  156. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
  157. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/SOURCES.txt +0 -0
  158. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/dependency_links.txt +0 -0
  159. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/entry_points.txt +0 -0
  160. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/seleniumbase.egg-info/top_level.txt +0 -0
  161. {seleniumbase-4.47.4 → seleniumbase-4.47.6}/setup.cfg +0 -0
  162. {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.4
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>=25.4.0
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.6
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.0.0; extra == "coverage"
142
+ Requires-Dist: pytest-cov>=7.1.0; extra == "coverage"
143
143
  Provides-Extra: flake8
144
144
  Requires-Dist: flake8==7.3.0; extra == "flake8"
145
145
  Requires-Dist: mccabe==0.7.0; extra == "flake8"
@@ -209,7 +209,7 @@ Dynamic: summary
209
209
 
210
210
  <h1>SeleniumBase</h1>
211
211
 
212
- <p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/other/sbase_text_logo3t.png" alt="SeleniumBase" title="SeleniumBase" width="634" /></a></p>
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 web automation, testing, scraping, and stealth. Includes a <a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a> integration for customizing automation from the command-line.
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, solve CAPTCHAs, and call methods from the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome Devtools Protocol</a>. Includes <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md"><b><span translate="no">Stealthy Playwright Mode</span></b></a>, which makes Playwright stealthy via CDP Mode.
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
- 📚 Example scripts and tests are located in [**SeleniumBase/examples/**](https://github.com/seleniumbase/SeleniumBase/tree/master/examples).
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 example scripts are located in [**SeleniumBase/examples/cdp_mode/**](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
261
+ 🥷 Stealthy examples are located in [SeleniumBase/examples/cdp_mode/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
262
262
 
263
263
  --------
264
264
 
265
- <p align="left">📗 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>
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">📗 Here's a script that bypasses Cloudflare's challenge page with UC Mode + CDP Mode: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
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" title="SeleniumBase" width="344"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" title="SeleniumBase" width="298">
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">📙 There's also SeleniumBase's "Pure CDP Mode", which doesn't use WebDriver or Selenium at all: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py">SeleniumBase/examples/cdp_mode/raw_cdp_gitlab.py</a></p>
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">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">SeleniumBase/examples/test_get_swag.py</a>, which tests an e-commerce site:</p>
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" title="SeleniumBase Test" width="480" /></a>
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">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">SeleniumBase/examples/test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
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" title="SeleniumBase Coffee Cart Test" /></a></p>
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">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">SeleniumBase/examples/test_demo_site.py</a>, which covers several actions:</p>
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" title="SeleniumBase Example" /></a></p>
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" title="SeleniumBase Test" width="480" /></a>
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>). This means <b>you no longer need random <span><code translate="no">time.sleep()</code></span> statements</b> in your scripts.</p>
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/other/sbase_text_logo3t.png" alt="SeleniumBase" title="SeleniumBase" width="634" /></a></p>
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 web automation, testing, scraping, and stealth. Includes a <a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a> integration for customizing automation from the command-line.
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, solve CAPTCHAs, and call methods from the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome Devtools Protocol</a>. Includes <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md"><b><span translate="no">Stealthy Playwright Mode</span></b></a>, which makes Playwright stealthy via CDP Mode.
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
- 📚 Example scripts and tests are located in [**SeleniumBase/examples/**](https://github.com/seleniumbase/SeleniumBase/tree/master/examples).
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 example scripts are located in [**SeleniumBase/examples/cdp_mode/**](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
61
+ 🥷 Stealthy examples are located in [SeleniumBase/examples/cdp_mode/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
62
62
 
63
63
  --------
64
64
 
65
- <p align="left">📗 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>
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">📗 Here's a script that bypasses Cloudflare's challenge page with UC Mode + CDP Mode: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
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" title="SeleniumBase" width="344"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" title="SeleniumBase" width="298">
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">📙 There's also SeleniumBase's "Pure CDP Mode", which doesn't use WebDriver or Selenium at all: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py">SeleniumBase/examples/cdp_mode/raw_cdp_gitlab.py</a></p>
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">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">SeleniumBase/examples/test_get_swag.py</a>, which tests an e-commerce site:</p>
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" title="SeleniumBase Test" width="480" /></a>
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">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">SeleniumBase/examples/test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
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" title="SeleniumBase Coffee Cart Test" /></a></p>
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">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">SeleniumBase/examples/test_demo_site.py</a>, which covers several actions:</p>
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" title="SeleniumBase Example" /></a></p>
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" title="SeleniumBase Test" width="480" /></a>
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>). This means <b>you no longer need random <span><code translate="no">time.sleep()</code></span> statements</b> in your scripts.</p>
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>=25.4.0
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.6
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.0.0
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.4"
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
- element.scroll_into_view()
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
- element.scroll_into_view()
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
- element.scroll_into_view()
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
- element.scroll_into_view()
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
- element.scroll_into_view()
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
- element.scroll_into_view()
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: