seleniumbase 4.47.6__tar.gz → 4.47.8__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.6/seleniumbase.egg-info → seleniumbase-4.47.8}/PKG-INFO +5 -3
  2. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/README.md +1 -0
  3. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/requirements.txt +2 -1
  4. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/__version__.py +1 -1
  5. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_mkdir.py +3 -0
  6. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/browser_launcher.py +2 -0
  7. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/sb_cdp.py +51 -4
  8. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/sb_manager.py +2 -0
  9. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/cdp_driver/cdp_util.py +19 -11
  10. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/cdp_driver/connection.py +27 -16
  11. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/cdp_driver/element.py +27 -2
  12. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/cdp_driver/tab.py +0 -1
  13. {seleniumbase-4.47.6 → seleniumbase-4.47.8/seleniumbase.egg-info}/PKG-INFO +5 -3
  14. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase.egg-info/requires.txt +3 -2
  15. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/setup.py +3 -2
  16. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/.gitignore +0 -0
  17. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/LICENSE +0 -0
  18. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/MANIFEST.in +0 -0
  19. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/install.sh +0 -0
  20. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/pyproject.toml +0 -0
  21. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/pytest.ini +0 -0
  22. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/sbase/__init__.py +0 -0
  23. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/sbase/__main__.py +0 -0
  24. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/sbase/steps.py +0 -0
  25. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/__init__.py +0 -0
  26. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/__main__.py +0 -0
  27. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/behave/__init__.py +0 -0
  28. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/behave/behave_helper.py +0 -0
  29. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/behave/behave_sb.py +0 -0
  30. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/behave/steps.py +0 -0
  31. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/common/__init__.py +0 -0
  32. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/common/decorators.py +0 -0
  33. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/common/encryption.py +0 -0
  34. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/common/exceptions.py +0 -0
  35. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/common/obfuscate.py +0 -0
  36. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/common/unobfuscate.py +0 -0
  37. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/config/__init__.py +0 -0
  38. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/config/ad_block_list.py +0 -0
  39. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/config/proxy_list.py +0 -0
  40. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/config/settings.py +0 -0
  41. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/__init__.py +0 -0
  42. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/logo_helper.py +0 -0
  43. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/rich_helper.py +0 -0
  44. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/run.py +0 -0
  45. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
  46. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
  47. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_commander.py +0 -0
  48. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_install.py +0 -0
  49. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
  50. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
  51. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
  52. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
  53. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_objectify.py +0 -0
  54. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_print.py +0 -0
  55. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/console_scripts/sb_recorder.py +0 -0
  56. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/__init__.py +0 -0
  57. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/application_manager.py +0 -0
  58. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/capabilities_parser.py +0 -0
  59. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/colored_traceback.py +0 -0
  60. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/create_db_tables.sql +0 -0
  61. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/detect_b_ver.py +0 -0
  62. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/download_helper.py +0 -0
  63. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/encoded_images.py +0 -0
  64. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/jqc_helper.py +0 -0
  65. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/log_helper.py +0 -0
  66. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/mysql.py +0 -0
  67. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/proxy_helper.py +0 -0
  68. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/recorder_helper.py +0 -0
  69. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/report_helper.py +0 -0
  70. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/s3_manager.py +0 -0
  71. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/sb_driver.py +0 -0
  72. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/session_helper.py +0 -0
  73. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/settings_parser.py +0 -0
  74. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/style_sheet.py +0 -0
  75. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/testcase_manager.py +0 -0
  76. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/tour_helper.py +0 -0
  77. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/core/visual_helper.py +0 -0
  78. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/drivers/__init__.py +0 -0
  79. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
  80. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
  81. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
  82. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
  83. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
  84. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
  85. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
  86. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/extensions/__init__.py +0 -0
  87. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/extensions/ad_block.zip +0 -0
  88. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/extensions/disable_csp.zip +0 -0
  89. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/extensions/recorder.zip +0 -0
  90. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/extensions/sbase_ext.zip +0 -0
  91. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/__init__.py +0 -0
  92. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/base_case.py +0 -0
  93. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/constants.py +0 -0
  94. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/css_to_xpath.py +0 -0
  95. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/errors.py +0 -0
  96. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/js_utils.py +0 -0
  97. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/page_actions.py +0 -0
  98. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/page_utils.py +0 -0
  99. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/shared_utils.py +0 -0
  100. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/unittest_helper.py +0 -0
  101. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/words.py +0 -0
  102. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/fixtures/xpath_to_css.py +0 -0
  103. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/js_code/__init__.py +0 -0
  104. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/js_code/active_css_js.py +0 -0
  105. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/js_code/live_js.py +0 -0
  106. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/js_code/recorder_js.py +0 -0
  107. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/masterqa/__init__.py +0 -0
  108. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/masterqa/master_qa.py +0 -0
  109. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/__init__.py +0 -0
  110. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/base_plugin.py +0 -0
  111. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/basic_test_info.py +0 -0
  112. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
  113. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/driver_manager.py +0 -0
  114. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/page_source.py +0 -0
  115. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/pytest_plugin.py +0 -0
  116. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
  117. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/screen_shots.py +0 -0
  118. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/plugins/selenium_plugin.py +0 -0
  119. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/resources/__init__.py +0 -0
  120. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/__init__.py +0 -0
  121. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/chinese.py +0 -0
  122. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/dutch.py +0 -0
  123. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/french.py +0 -0
  124. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/italian.py +0 -0
  125. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/japanese.py +0 -0
  126. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/korean.py +0 -0
  127. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/master_dict.py +0 -0
  128. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/portuguese.py +0 -0
  129. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/russian.py +0 -0
  130. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/spanish.py +0 -0
  131. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/translate/translator.py +0 -0
  132. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/__init__.py +0 -0
  133. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/cdp.py +0 -0
  134. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
  135. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
  136. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
  137. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/cdp_driver/config.py +0 -0
  138. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/dprocess.py +0 -0
  139. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/options.py +0 -0
  140. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/patcher.py +0 -0
  141. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/reactor.py +0 -0
  142. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/undetected/webelement.py +0 -0
  143. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/__init__.py +0 -0
  144. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
  145. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
  146. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/font_color +0 -0
  147. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
  148. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
  149. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
  150. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
  151. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
  152. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
  153. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
  154. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
  155. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
  156. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
  157. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase.egg-info/SOURCES.txt +0 -0
  158. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase.egg-info/dependency_links.txt +0 -0
  159. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase.egg-info/entry_points.txt +0 -0
  160. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/seleniumbase.egg-info/top_level.txt +0 -0
  161. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/setup.cfg +0 -0
  162. {seleniumbase-4.47.6 → seleniumbase-4.47.8}/virtualenv_install.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seleniumbase
3
- Version: 4.47.6
3
+ Version: 4.47.8
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
@@ -92,7 +92,8 @@ Requires-Dist: idna>=3.11
92
92
  Requires-Dist: charset-normalizer<4,>=3.4.6
93
93
  Requires-Dist: urllib3<2,>=1.26.20; python_version < "3.10"
94
94
  Requires-Dist: urllib3<3,>=1.26.20; python_version >= "3.10"
95
- Requires-Dist: requests~=2.32.5
95
+ Requires-Dist: requests~=2.32.5; python_version < "3.10"
96
+ Requires-Dist: requests~=2.33.0; python_version >= "3.10"
96
97
  Requires-Dist: sniffio==1.3.1
97
98
  Requires-Dist: h11==0.16.0
98
99
  Requires-Dist: outcome==1.3.0.post0
@@ -153,7 +154,7 @@ Requires-Dist: mss==10.1.0; extra == "mss"
153
154
  Provides-Extra: pdfminer
154
155
  Requires-Dist: pdfminer.six==20251107; python_version < "3.10" and extra == "pdfminer"
155
156
  Requires-Dist: pdfminer.six==20260107; python_version >= "3.10" and extra == "pdfminer"
156
- Requires-Dist: cryptography==46.0.5; extra == "pdfminer"
157
+ Requires-Dist: cryptography==46.0.6; extra == "pdfminer"
157
158
  Requires-Dist: cffi==2.0.0; extra == "pdfminer"
158
159
  Requires-Dist: pycparser==2.23; python_version < "3.10" and extra == "pdfminer"
159
160
  Requires-Dist: pycparser==3.0; python_version >= "3.10" and extra == "pdfminer"
@@ -293,6 +294,7 @@ from seleniumbase import SB
293
294
  with SB(uc=True, test=True) as sb:
294
295
  url = "https://google.com/ncr"
295
296
  sb.activate_cdp_mode(url)
297
+ sb.click_if_visible('button:contains("Accept all")')
296
298
  sb.type('[name="q"]', "SeleniumBase GitHub page")
297
299
  sb.click('[value="Google Search"]')
298
300
  sb.sleep(4) # The "AI Overview" sometimes loads
@@ -93,6 +93,7 @@ from seleniumbase import SB
93
93
  with SB(uc=True, test=True) as sb:
94
94
  url = "https://google.com/ncr"
95
95
  sb.activate_cdp_mode(url)
96
+ sb.click_if_visible('button:contains("Accept all")')
96
97
  sb.type('[name="q"]', "SeleniumBase GitHub page")
97
98
  sb.click('[value="Google Search"]')
98
99
  sb.sleep(4) # The "AI Overview" sometimes loads
@@ -32,7 +32,8 @@ idna>=3.11
32
32
  charset-normalizer>=3.4.6,<4
33
33
  urllib3>=1.26.20,<2;python_version<"3.10"
34
34
  urllib3>=1.26.20,<3;python_version>="3.10"
35
- requests~=2.32.5
35
+ requests~=2.32.5;python_version<"3.10"
36
+ requests~=2.33.0;python_version>="3.10"
36
37
  sniffio==1.3.1
37
38
  h11==0.16.0
38
39
  outcome==1.3.0.post0
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.47.6"
2
+ __version__ = "4.47.8"
@@ -712,6 +712,9 @@ def main():
712
712
  data.append(" if not self.undetectable:")
713
713
  data.append(" self.get_new_driver(undetectable=True)")
714
714
  data.append(' self.open("https://google.com/ncr")')
715
+ data.append(
716
+ " sb.click_if_visible('button:contains(\"Accept all\")')"
717
+ )
715
718
  data.append(' self.assert_title_contains("Google")')
716
719
  data.append(" self.save_screenshot_to_logs()")
717
720
  data.append(' self.type(HomePage.search_box, "github.com")')
@@ -872,6 +872,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
872
872
  cdp.get_gui_element_center = CDPM.get_gui_element_center
873
873
  cdp.get_html = CDPM.get_html
874
874
  cdp.get_page_source = CDPM.get_page_source
875
+ cdp.get_beautiful_soup = CDPM.get_beautiful_soup
875
876
  cdp.get_user_agent = CDPM.get_user_agent
876
877
  cdp.get_cookie_string = CDPM.get_cookie_string
877
878
  cdp.get_locale_code = CDPM.get_locale_code
@@ -942,6 +943,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
942
943
  cdp.assert_not_equal = CDPM.assert_not_equal
943
944
  cdp.assert_in = CDPM.assert_in
944
945
  cdp.assert_not_in = CDPM.assert_not_in
946
+ cdp.js_scroll_into_view = CDPM.js_scroll_into_view
945
947
  cdp.scroll_into_view = CDPM.scroll_into_view
946
948
  cdp.scroll_to_y = CDPM.scroll_to_y
947
949
  cdp.scroll_by_y = CDPM.scroll_by_y
@@ -66,6 +66,7 @@ class CDPMethods():
66
66
  lambda *args, **kwargs: self.__gui_click(element, *args, **kwargs)
67
67
  )
68
68
  element.highlight_overlay = lambda: self.__highlight_overlay(element)
69
+ element.is_in_viewport = lambda: self.__is_in_viewport(element)
69
70
  element.mouse_click = lambda: self.__mouse_click(element)
70
71
  element.click_with_offset = (
71
72
  lambda *args, **kwargs: self.__mouse_click_with_offset_async(
@@ -116,10 +117,10 @@ class CDPMethods():
116
117
  if hasattr(driver, "cdp_base"):
117
118
  driver = driver.cdp_base
118
119
  load_timeout = 60.0
119
- wait_timeout = 30.0
120
+ wait_timeout = 50.0
120
121
  if hasattr(sb_config, "_cdp_proxy") and sb_config._cdp_proxy:
121
122
  load_timeout = 90.0
122
- wait_timeout = 45.0
123
+ wait_timeout = 75.0
123
124
  try:
124
125
  task = self.page.get(url, **kwargs)
125
126
  self.loop.run_until_complete(
@@ -127,6 +128,10 @@ class CDPMethods():
127
128
  )
128
129
  except asyncio.TimeoutError:
129
130
  print("Timeout loading %s" % url)
131
+ except RuntimeError:
132
+ self.loop.run_until_complete(
133
+ self.page.get(url, **kwargs)
134
+ )
130
135
  url_protocol = url.split(":")[0]
131
136
  safe_url = True
132
137
  if url_protocol not in ["about", "data", "chrome"]:
@@ -543,6 +548,11 @@ class CDPMethods():
543
548
  self.loop.run_until_complete(element.highlight_overlay_async())
544
549
  )
545
550
 
551
+ def __is_in_viewport(self, element):
552
+ return (
553
+ self.loop.run_until_complete(element.is_in_viewport_async())
554
+ )
555
+
546
556
  def __mouse_click(self, element):
547
557
  result = (
548
558
  self.loop.run_until_complete(element.mouse_click_async())
@@ -800,9 +810,9 @@ class CDPMethods():
800
810
  timeout = settings.SMALL_TIMEOUT
801
811
  self.__slow_mode_pause_if_set()
802
812
  element = self.find_element(selector, timeout=timeout)
803
- if scroll:
804
- element.scroll_into_view()
805
813
  tag_name = element.tag_name
814
+ current_url = self.get_current_url()
815
+
806
816
  if tag_name:
807
817
  tag_name = tag_name.lower().strip()
808
818
  if (
@@ -810,12 +820,24 @@ class CDPMethods():
810
820
  "a", "button", "canvas", "div", "input", "li", "span", "label"
811
821
  ]
812
822
  and "contains(" not in selector
823
+ and "://google" not in current_url
824
+ and "://www.google" not in current_url
813
825
  ):
826
+ if scroll:
827
+ element.scroll_into_view()
814
828
  try:
815
829
  element.mouse_click() # Simulated click (NOT PyAutoGUI)
816
830
  except Exception:
817
831
  element.click() # Standard CDP click
818
832
  else:
833
+ if scroll:
834
+ if "contains(" in selector:
835
+ element.scroll_into_view()
836
+ else:
837
+ try:
838
+ self.js_scroll_into_view(selector)
839
+ except Exception:
840
+ element.scroll_into_view()
819
841
  element.click() # Standard CDP click
820
842
  self.__slow_mode_pause_if_set()
821
843
  self.loop.run_until_complete(self.page.wait(0.2))
@@ -1377,6 +1399,20 @@ class CDPMethods():
1377
1399
  )
1378
1400
  return source
1379
1401
 
1402
+ def get_beautiful_soup(self, source=None):
1403
+ """BeautifulSoup is a toolkit for dissecting an HTML document
1404
+ and extracting what you need. It's great for screen-scraping!
1405
+ See: https://www.crummy.com/software/BeautifulSoup/bs4/doc/ """
1406
+ from bs4 import BeautifulSoup
1407
+
1408
+ if not source:
1409
+ with suppress(Exception):
1410
+ self.wait_for_element_visible(
1411
+ "body", timeout=settings.MINI_TIMEOUT
1412
+ )
1413
+ source = self.get_page_source()
1414
+ return BeautifulSoup(source, "html.parser")
1415
+
1380
1416
  def get_user_agent(self):
1381
1417
  return self.loop.run_until_complete(
1382
1418
  self.page.evaluate("navigator.userAgent")
@@ -3109,6 +3145,17 @@ class CDPMethods():
3109
3145
  if first in second:
3110
3146
  raise AssertionError("%s is in %s" % (first, second))
3111
3147
 
3148
+ def js_scroll_into_view(self, selector):
3149
+ css_selector = self.__convert_to_css_if_xpath(selector)
3150
+ css_selector = re.escape(css_selector) # Add "\\" to special chars
3151
+ css_selector = js_utils.escape_quotes_if_needed(css_selector)
3152
+ js_code = (
3153
+ "document.querySelector('%s')?.scrollIntoView();"
3154
+ % css_selector
3155
+ )
3156
+ with suppress(Exception):
3157
+ self.loop.run_until_complete(self.page.evaluate(js_code))
3158
+
3112
3159
  def scroll_into_view(self, selector):
3113
3160
  self.find_element(selector).scroll_into_view()
3114
3161
  self.loop.run_until_complete(self.page.wait(0.1))
@@ -13,6 +13,7 @@ from seleniumbase import SB
13
13
  with SB(uc=True, test=True) as sb:
14
14
  url = "https://google.com/ncr"
15
15
  sb.activate_cdp_mode(url)
16
+ sb.click_if_visible('button:contains("Accept all")')
16
17
  sb.type('[name="q"]', "SeleniumBase GitHub page")
17
18
  sb.click('[value="Google Search"]')
18
19
  sb.sleep(2)
@@ -148,6 +149,7 @@ def SB(
148
149
  with SB(uc=True, test=True) as sb:
149
150
  url = "https://google.com/ncr"
150
151
  sb.activate_cdp_mode(url)
152
+ sb.click_if_visible('button:contains("Accept all")')
151
153
  sb.type('[name="q"]', "SeleniumBase GitHub page")
152
154
  sb.click('[value="Google Search"]')
153
155
  sb.sleep(2)
@@ -31,6 +31,7 @@ DOWNLOADS_FOLDER = download_helper.get_downloads_folder()
31
31
  PROXY_DIR_LOCK = proxy_helper.PROXY_DIR_LOCK
32
32
  EXTENSIONS_DIR = os.path.dirname(os.path.realpath(extensions.__file__))
33
33
  AD_BLOCK_ZIP_PATH = os.path.join(EXTENSIONS_DIR, "ad_block.zip")
34
+ DISABLE_CSP_ZIP_PATH = os.path.join(EXTENSIONS_DIR, "disable_csp.zip")
34
35
  T = typing.TypeVar("T")
35
36
 
36
37
 
@@ -598,16 +599,6 @@ async def start(
598
599
  proxy_pass,
599
600
  proxy_scheme,
600
601
  )
601
- if ad_block:
602
- sb_config.ad_block_on = True
603
- incognito = False
604
- guest = False
605
- ad_block_zip = AD_BLOCK_ZIP_PATH
606
- ad_block_dir = os.path.join(DOWNLOADS_FOLDER, "ad_block")
607
- __unzip_to_new_folder(ad_block_zip, ad_block_dir)
608
- extension_dir = __add_chrome_ext_dir(extension_dir, ad_block_dir)
609
- if disable_csp:
610
- sb_config.disable_csp = True
611
602
  if "binary_location" in kwargs and not browser_executable_path:
612
603
  browser_executable_path = kwargs["binary_location"]
613
604
  if not user_data_dir and "--user-data-dir" in arg_join:
@@ -624,8 +615,8 @@ async def start(
624
615
  user_data_dir = udd_string
625
616
  if user_data_dir:
626
617
  user_data_dir = os.path.abspath(user_data_dir)
618
+ browser = None
627
619
  if not browser_executable_path:
628
- browser = None
629
620
  if "browser" in kwargs:
630
621
  browser = kwargs["browser"]
631
622
  if not browser and "--browser" in arg_join:
@@ -675,6 +666,23 @@ async def start(
675
666
  sb_config._cdp_browser = "atlas"
676
667
  else:
677
668
  sb_config._cdp_browser = "chrome"
669
+ if ad_block:
670
+ sb_config.ad_block_on = True
671
+ incognito = False
672
+ guest = False
673
+ ad_block_zip = AD_BLOCK_ZIP_PATH
674
+ ad_block_dir = os.path.join(DOWNLOADS_FOLDER, "ad_block")
675
+ __unzip_to_new_folder(ad_block_zip, ad_block_dir)
676
+ extension_dir = __add_chrome_ext_dir(extension_dir, ad_block_dir)
677
+ if disable_csp:
678
+ sb_config.disable_csp = True
679
+ if not incognito and not guest:
680
+ disable_csp_zip = DISABLE_CSP_ZIP_PATH
681
+ disable_csp_dir = os.path.join(DOWNLOADS_FOLDER, "disable_csp")
682
+ __unzip_to_new_folder(disable_csp_zip, disable_csp_dir)
683
+ extension_dir = __add_chrome_ext_dir(
684
+ extension_dir, disable_csp_dir
685
+ )
678
686
  sb_config.incognito = incognito
679
687
  sb_config.guest_mode = guest
680
688
  if not config:
@@ -305,20 +305,31 @@ class Connection(metaclass=CantTouchThis):
305
305
  await self.update_target()
306
306
  loop = asyncio.get_running_loop()
307
307
  start_time = loop.time()
308
- try:
309
- if isinstance(t, (int, float)):
310
- await asyncio.wait_for(self.listener.idle.wait(), timeout=t)
311
- while (loop.time() - start_time) < t:
312
- await asyncio.sleep(0.1)
313
- else:
314
- await self.listener.idle.wait()
315
- except asyncio.TimeoutError:
316
- if isinstance(t, (int, float)):
317
- # Explicit time is given, which is now passed, so leave now.
318
- return
319
- except AttributeError:
320
- # No listener created yet.
321
- pass
308
+ with warnings.catch_warnings():
309
+ warnings.filterwarnings(
310
+ action="ignore",
311
+ category=RuntimeWarning,
312
+ message=".*coroutine.*",
313
+ )
314
+ try:
315
+ if isinstance(t, (int, float)):
316
+ try:
317
+ await asyncio.wait_for(
318
+ self.listener.idle.wait(), timeout=t
319
+ )
320
+ except RuntimeError:
321
+ await self.listener.idle.wait()
322
+ while (loop.time() - start_time) < t:
323
+ await asyncio.sleep(0.1)
324
+ else:
325
+ await self.listener.idle.wait()
326
+ except asyncio.TimeoutError:
327
+ if isinstance(t, (int, float)):
328
+ # Explicit time that's given has passed, so leave now.
329
+ return
330
+ except AttributeError:
331
+ # No listener created yet.
332
+ pass
322
333
 
323
334
  async def set_locale(self, locale: Optional[str] = None):
324
335
  """Sets the Language Locale code via set_user_agent_override."""
@@ -423,9 +434,9 @@ class Connection(metaclass=CantTouchThis):
423
434
  await self.websocket.send(tx.message)
424
435
  with warnings.catch_warnings():
425
436
  warnings.filterwarnings(
426
- "ignore",
427
- message="coroutine .* was never awaited",
437
+ action="ignore",
428
438
  category=RuntimeWarning,
439
+ message=".*coroutine.*",
429
440
  )
430
441
  try:
431
442
  return await tx
@@ -467,8 +467,8 @@ class Element:
467
467
  raise Exception("Could not find position for %s " % self)
468
468
  pos = Position(quads[0])
469
469
  if abs:
470
- scroll_y = (await self.tab.evaluate("window.scrollY")).value
471
- scroll_x = (await self.tab.evaluate("window.scrollX")).value
470
+ scroll_y = (await self.tab.evaluate("window.scrollY"))
471
+ scroll_x = (await self.tab.evaluate("window.scrollX"))
472
472
  abs_x = pos.left + scroll_x + (pos.width / 2)
473
473
  abs_y = pos.top + scroll_y + (pos.height / 2)
474
474
  pos.abs_x = abs_x
@@ -717,6 +717,31 @@ class Element:
717
717
  )
718
718
  )
719
719
 
720
+ async def is_in_viewport_async(self):
721
+ try:
722
+ layout = await self.tab.send(
723
+ cdp.page.get_layout_metrics()
724
+ )
725
+ viewport = layout[4]
726
+ v_left = viewport.page_x
727
+ v_top = viewport.page_y
728
+ v_right = v_left + viewport.client_width
729
+ v_bottom = v_top + viewport.client_height
730
+ box = await self.tab.send(
731
+ cdp.dom.get_box_model(backend_node_id=self.backend_node_id)
732
+ )
733
+ quad = box.content
734
+ e_left = min(quad[0], quad[2], quad[4], quad[6])
735
+ e_top = min(quad[1], quad[3], quad[5], quad[7])
736
+ e_right = max(quad[0], quad[2], quad[4], quad[6])
737
+ e_bottom = max(quad[1], quad[3], quad[5], quad[7])
738
+ return (
739
+ e_left >= v_left and e_right <= v_right
740
+ and e_top >= v_top and e_bottom <= v_bottom
741
+ )
742
+ except Exception:
743
+ return False
744
+
720
745
  async def scroll_into_view_async(self):
721
746
  """Scrolls element into view."""
722
747
  try:
@@ -226,7 +226,6 @@ class Tab(Connection):
226
226
  except (Exception, TypeError):
227
227
  pass
228
228
  while not item:
229
- await self
230
229
  item = await self.find_element_by_text(
231
230
  text, best_match, return_enclosing_element
232
231
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seleniumbase
3
- Version: 4.47.6
3
+ Version: 4.47.8
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
@@ -92,7 +92,8 @@ Requires-Dist: idna>=3.11
92
92
  Requires-Dist: charset-normalizer<4,>=3.4.6
93
93
  Requires-Dist: urllib3<2,>=1.26.20; python_version < "3.10"
94
94
  Requires-Dist: urllib3<3,>=1.26.20; python_version >= "3.10"
95
- Requires-Dist: requests~=2.32.5
95
+ Requires-Dist: requests~=2.32.5; python_version < "3.10"
96
+ Requires-Dist: requests~=2.33.0; python_version >= "3.10"
96
97
  Requires-Dist: sniffio==1.3.1
97
98
  Requires-Dist: h11==0.16.0
98
99
  Requires-Dist: outcome==1.3.0.post0
@@ -153,7 +154,7 @@ Requires-Dist: mss==10.1.0; extra == "mss"
153
154
  Provides-Extra: pdfminer
154
155
  Requires-Dist: pdfminer.six==20251107; python_version < "3.10" and extra == "pdfminer"
155
156
  Requires-Dist: pdfminer.six==20260107; python_version >= "3.10" and extra == "pdfminer"
156
- Requires-Dist: cryptography==46.0.5; extra == "pdfminer"
157
+ Requires-Dist: cryptography==46.0.6; extra == "pdfminer"
157
158
  Requires-Dist: cffi==2.0.0; extra == "pdfminer"
158
159
  Requires-Dist: pycparser==2.23; python_version < "3.10" and extra == "pdfminer"
159
160
  Requires-Dist: pycparser==3.0; python_version >= "3.10" and extra == "pdfminer"
@@ -293,6 +294,7 @@ from seleniumbase import SB
293
294
  with SB(uc=True, test=True) as sb:
294
295
  url = "https://google.com/ncr"
295
296
  sb.activate_cdp_mode(url)
297
+ sb.click_if_visible('button:contains("Accept all")')
296
298
  sb.type('[name="q"]', "SeleniumBase GitHub page")
297
299
  sb.click('[value="Google Search"]')
298
300
  sb.sleep(4) # The "AI Overview" sometimes loads
@@ -21,7 +21,6 @@ tabcompleter>=1.4.0
21
21
  pdbp>=1.8.2
22
22
  idna>=3.11
23
23
  charset-normalizer<4,>=3.4.6
24
- requests~=2.32.5
25
24
  sniffio==1.3.1
26
25
  h11==0.16.0
27
26
  outcome==1.3.0.post0
@@ -55,6 +54,7 @@ websockets~=15.0.1
55
54
  filelock~=3.19.1
56
55
  platformdirs~=4.4.0
57
56
  urllib3<2,>=1.26.20
57
+ requests~=2.32.5
58
58
  trio<1,>=0.31.0
59
59
  wsproto==1.2.0
60
60
  selenium==4.32.0
@@ -73,6 +73,7 @@ websockets>=16.0
73
73
  filelock>=3.25.2
74
74
  platformdirs>=4.9.4
75
75
  urllib3<3,>=1.26.20
76
+ requests~=2.33.0
76
77
  trio<1,>=0.33.0
77
78
  wsproto~=1.3.2
78
79
  selenium==4.41.0
@@ -113,7 +114,7 @@ ipython==7.34.0
113
114
  mss==10.1.0
114
115
 
115
116
  [pdfminer]
116
- cryptography==46.0.5
117
+ cryptography==46.0.6
117
118
  cffi==2.0.0
118
119
 
119
120
  [pdfminer:python_version < "3.10"]
@@ -180,7 +180,8 @@ setup(
180
180
  'charset-normalizer>=3.4.6,<4',
181
181
  'urllib3>=1.26.20,<2;python_version<"3.10"',
182
182
  'urllib3>=1.26.20,<3;python_version>="3.10"',
183
- 'requests~=2.32.5',
183
+ 'requests~=2.32.5;python_version<"3.10"',
184
+ 'requests~=2.33.0;python_version>="3.10"',
184
185
  'sniffio==1.3.1',
185
186
  'h11==0.16.0',
186
187
  'outcome==1.3.0.post0',
@@ -261,7 +262,7 @@ setup(
261
262
  "pdfminer": [
262
263
  'pdfminer.six==20251107;python_version<"3.10"',
263
264
  'pdfminer.six==20260107;python_version>="3.10"',
264
- 'cryptography==46.0.5',
265
+ 'cryptography==46.0.6',
265
266
  'cffi==2.0.0',
266
267
  'pycparser==2.23;python_version<"3.10"',
267
268
  'pycparser==3.0;python_version>="3.10"',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes