seleniumbase 4.49.8__tar.gz → 4.49.9__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 (163) hide show
  1. {seleniumbase-4.49.8/seleniumbase.egg-info → seleniumbase-4.49.9}/PKG-INFO +2 -2
  2. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/requirements.txt +1 -1
  3. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/__version__.py +1 -1
  4. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/browser_launcher.py +6 -0
  5. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/sb_cdp.py +100 -4
  6. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/base_case.py +2 -0
  7. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/cdp_driver/browser.py +6 -0
  8. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/cdp_driver/cdp_util.py +2 -0
  9. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/cdp_driver/connection.py +13 -0
  10. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/cdp_driver/tab.py +25 -36
  11. {seleniumbase-4.49.8 → seleniumbase-4.49.9/seleniumbase.egg-info}/PKG-INFO +2 -2
  12. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase.egg-info/requires.txt +1 -1
  13. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/setup.py +1 -1
  14. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/.gitignore +0 -0
  15. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/LICENSE +0 -0
  16. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/MANIFEST.in +0 -0
  17. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/README.md +0 -0
  18. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/install.sh +0 -0
  19. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/pyproject.toml +0 -0
  20. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/pytest.ini +0 -0
  21. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/sbase/__init__.py +0 -0
  22. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/sbase/__main__.py +0 -0
  23. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/sbase/steps.py +0 -0
  24. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/__init__.py +0 -0
  25. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/__main__.py +0 -0
  26. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/behave/__init__.py +0 -0
  27. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/behave/behave_helper.py +0 -0
  28. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/behave/behave_sb.py +0 -0
  29. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/behave/steps.py +0 -0
  30. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/common/__init__.py +0 -0
  31. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/common/decorators.py +0 -0
  32. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/common/encryption.py +0 -0
  33. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/common/exceptions.py +0 -0
  34. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/common/obfuscate.py +0 -0
  35. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/common/unobfuscate.py +0 -0
  36. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/config/__init__.py +0 -0
  37. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/config/ad_block_list.py +0 -0
  38. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/config/proxy_list.py +0 -0
  39. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/config/settings.py +0 -0
  40. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/__init__.py +0 -0
  41. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/logo_helper.py +0 -0
  42. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/rich_helper.py +0 -0
  43. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/run.py +0 -0
  44. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
  45. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
  46. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_commander.py +0 -0
  47. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_install.py +0 -0
  48. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
  49. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
  50. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
  51. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
  52. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
  53. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_objectify.py +0 -0
  54. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_print.py +0 -0
  55. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/console_scripts/sb_recorder.py +0 -0
  56. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/__init__.py +0 -0
  57. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/application_manager.py +0 -0
  58. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/capabilities_parser.py +0 -0
  59. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/colored_traceback.py +0 -0
  60. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/create_db_tables.sql +0 -0
  61. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/detect_b_ver.py +0 -0
  62. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/download_helper.py +0 -0
  63. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/encoded_images.py +0 -0
  64. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/jqc_helper.py +0 -0
  65. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/log_helper.py +0 -0
  66. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/mysql.py +0 -0
  67. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/nest_asyncio.py +0 -0
  68. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/proxy_helper.py +0 -0
  69. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/recorder_helper.py +0 -0
  70. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/report_helper.py +0 -0
  71. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/s3_manager.py +0 -0
  72. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/sb_driver.py +0 -0
  73. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/session_helper.py +0 -0
  74. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/settings_parser.py +0 -0
  75. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/style_sheet.py +0 -0
  76. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/testcase_manager.py +0 -0
  77. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/tour_helper.py +0 -0
  78. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/core/visual_helper.py +0 -0
  79. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/drivers/__init__.py +0 -0
  80. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
  81. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
  82. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
  83. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
  84. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
  85. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
  86. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
  87. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/extensions/__init__.py +0 -0
  88. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/extensions/ad_block.zip +0 -0
  89. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/extensions/disable_csp.zip +0 -0
  90. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/extensions/recorder.zip +0 -0
  91. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/extensions/sbase_ext.zip +0 -0
  92. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/__init__.py +0 -0
  93. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/constants.py +0 -0
  94. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/css_to_xpath.py +0 -0
  95. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/errors.py +0 -0
  96. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/js_utils.py +0 -0
  97. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/page_actions.py +0 -0
  98. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/page_utils.py +0 -0
  99. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/shared_utils.py +0 -0
  100. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/unittest_helper.py +0 -0
  101. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/words.py +0 -0
  102. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/fixtures/xpath_to_css.py +0 -0
  103. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/js_code/__init__.py +0 -0
  104. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/js_code/active_css_js.py +0 -0
  105. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/js_code/live_js.py +0 -0
  106. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/js_code/recorder_js.py +0 -0
  107. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/masterqa/__init__.py +0 -0
  108. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/masterqa/master_qa.py +0 -0
  109. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/__init__.py +0 -0
  110. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/base_plugin.py +0 -0
  111. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/basic_test_info.py +0 -0
  112. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
  113. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/driver_manager.py +0 -0
  114. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/page_source.py +0 -0
  115. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/pytest_plugin.py +0 -0
  116. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
  117. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/sb_manager.py +0 -0
  118. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/screen_shots.py +0 -0
  119. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/plugins/selenium_plugin.py +0 -0
  120. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/resources/__init__.py +0 -0
  121. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/__init__.py +0 -0
  122. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/chinese.py +0 -0
  123. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/dutch.py +0 -0
  124. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/french.py +0 -0
  125. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/italian.py +0 -0
  126. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/japanese.py +0 -0
  127. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/korean.py +0 -0
  128. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/master_dict.py +0 -0
  129. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/portuguese.py +0 -0
  130. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/russian.py +0 -0
  131. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/spanish.py +0 -0
  132. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/translate/translator.py +0 -0
  133. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/__init__.py +0 -0
  134. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/cdp.py +0 -0
  135. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
  136. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
  137. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/cdp_driver/config.py +0 -0
  138. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/cdp_driver/element.py +0 -0
  139. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/dprocess.py +0 -0
  140. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/options.py +0 -0
  141. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/patcher.py +0 -0
  142. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/reactor.py +0 -0
  143. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/undetected/webelement.py +0 -0
  144. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/__init__.py +0 -0
  145. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
  146. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
  147. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/font_color +0 -0
  148. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
  149. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
  150. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
  151. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
  152. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
  153. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
  154. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
  155. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
  156. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
  157. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
  158. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase.egg-info/SOURCES.txt +0 -0
  159. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase.egg-info/dependency_links.txt +0 -0
  160. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase.egg-info/entry_points.txt +0 -0
  161. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/seleniumbase.egg-info/top_level.txt +0 -0
  162. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/setup.cfg +0 -0
  163. {seleniumbase-4.49.8 → seleniumbase-4.49.9}/virtualenv_install.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seleniumbase
3
- Version: 4.49.8
3
+ Version: 4.49.9
4
4
  Summary: SeleniumBase is a framework for web crawling, scraping, and testing. Supports pytest. CDP Mode adds stealth. Includes many tools.
5
5
  Home-page: https://github.com/seleniumbase/SeleniumBase
6
6
  Author: Michael Mintz
@@ -71,7 +71,7 @@ Requires-Dist: exceptiongroup>=1.3.1
71
71
  Requires-Dist: websockets~=15.0.1; python_version < "3.10"
72
72
  Requires-Dist: websockets>=16.0; python_version >= "3.10"
73
73
  Requires-Dist: filelock~=3.19.1; python_version < "3.10"
74
- Requires-Dist: filelock>=3.29.1; python_version >= "3.10"
74
+ Requires-Dist: filelock>=3.29.3; python_version >= "3.10"
75
75
  Requires-Dist: fasteners>=0.20
76
76
  Requires-Dist: mycdp>=1.3.7
77
77
  Requires-Dist: pynose>=1.5.5
@@ -10,7 +10,7 @@ exceptiongroup>=1.3.1
10
10
  websockets~=15.0.1;python_version<"3.10"
11
11
  websockets>=16.0;python_version>="3.10"
12
12
  filelock~=3.19.1;python_version<"3.10"
13
- filelock>=3.29.1;python_version>="3.10"
13
+ filelock>=3.29.3;python_version>="3.10"
14
14
  fasteners>=0.20
15
15
  mycdp>=1.3.7
16
16
  pynose>=1.5.5
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.49.8"
2
+ __version__ = "4.49.9"
@@ -793,6 +793,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
793
793
  cdp.grant_permissions = CDPM.grant_permissions
794
794
  cdp.grant_all_permissions = CDPM.grant_all_permissions
795
795
  cdp.reset_permissions = CDPM.reset_permissions
796
+ cdp.get_all_urls = CDPM.get_all_urls
796
797
  cdp.get_all_cookies = CDPM.get_all_cookies
797
798
  cdp.set_all_cookies = CDPM.set_all_cookies
798
799
  cdp.save_cookies = CDPM.save_cookies
@@ -831,6 +832,11 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
831
832
  cdp.activate_messenger = CDPM.activate_messenger
832
833
  cdp.set_messenger_theme = CDPM.set_messenger_theme
833
834
  cdp.post_message = CDPM.post_message
835
+ cdp.download_file = CDPM.download_file
836
+ cdp.save_file_as = CDPM.save_file_as
837
+ cdp.assert_downloaded_file = CDPM.assert_downloaded_file
838
+ cdp.get_path_of_downloaded_file = CDPM.get_path_of_downloaded_file
839
+ cdp.set_download_path = CDPM.set_download_path
834
840
  cdp.set_locale = CDPM.set_locale
835
841
  cdp.set_local_storage_item = CDPM.set_local_storage_item
836
842
  cdp.set_session_storage_item = CDPM.set_session_storage_item
@@ -752,6 +752,18 @@ class CDPMethods():
752
752
  driver = driver.cdp_base
753
753
  return self.loop.run_until_complete(driver.reset_permissions())
754
754
 
755
+ def get_all_urls(self, absolute=True):
756
+ """
757
+ Convenience function that returns all links (a,link,img,script,meta).
758
+ :param absolute:
759
+ Try to build all the links in absolute form
760
+ instead of "as is", often relative.
761
+ :return: List of URLs.
762
+ """
763
+ return self.loop.run_until_complete(
764
+ self.page.get_all_urls(absolute=absolute)
765
+ )
766
+
755
767
  def get_all_cookies(self, *args, **kwargs):
756
768
  driver = self.driver
757
769
  if hasattr(driver, "cdp_base"):
@@ -1725,6 +1737,80 @@ class CDPMethods():
1725
1737
  duration = float(duration) + 0.15
1726
1738
  time.sleep(float(duration))
1727
1739
 
1740
+ def download_file(self, file_url):
1741
+ """Download a file from a URL.
1742
+ The default download location is: "./downloaded_files/"."""
1743
+ self.loop.run_until_complete(
1744
+ self.page.download_file(file_url)
1745
+ )
1746
+
1747
+ def save_file_as(self, file_url, new_file_name):
1748
+ """Download a file from a URL and rename it.
1749
+ The default download location is: "./downloaded_files/"."""
1750
+ self.loop.run_until_complete(
1751
+ self.page.download_file(file_url, new_file_name)
1752
+ )
1753
+
1754
+ def assert_downloaded_file(self, file, timeout=None):
1755
+ """Asserts that the file exists in SeleniumBase's [Downloads Folder].
1756
+ For browser click-initiated downloads, SeleniumBase will override
1757
+ the system [Downloads Folder] to be "./downloaded_files/".
1758
+ @Params
1759
+ file - The filename of the downloaded file.
1760
+ timeout - The time (seconds) to wait for the download to complete.
1761
+ browser - If True, uses the path set by click-initiated downloads."""
1762
+ downloads_folder = constants.Files.DOWNLOADS_FOLDER
1763
+ abs_path = os.path.abspath(".")
1764
+ downloads_path = os.path.join(abs_path, downloads_folder)
1765
+ if not timeout:
1766
+ timeout = settings.LARGE_TIMEOUT
1767
+ start_ms = time.time() * 1000.0
1768
+ stop_ms = start_ms + (timeout * 1000.0)
1769
+ downloaded_file_path = os.path.join(downloads_path, file)
1770
+ found = False
1771
+ for x in range(int(timeout)):
1772
+ shared_utils.check_if_time_limit_exceeded()
1773
+ try:
1774
+ self.assert_true(
1775
+ os.path.exists(downloaded_file_path),
1776
+ "File [%s] was not found in the downloads folder [%s]!"
1777
+ % (file, downloads_path),
1778
+ )
1779
+ found = True
1780
+ break
1781
+ except Exception:
1782
+ now_ms = time.time() * 1000.0
1783
+ if now_ms >= stop_ms:
1784
+ break
1785
+ time.sleep(1)
1786
+ if not found and not os.path.exists(downloaded_file_path):
1787
+ plural = "s"
1788
+ if timeout == 1:
1789
+ plural = ""
1790
+ message = (
1791
+ "File {%s} was not found in the downloads folder {%s} "
1792
+ "after %s second%s! (Or the download didn't complete!)"
1793
+ % (file, downloads_path, timeout, plural)
1794
+ )
1795
+ from seleniumbase.common.exceptions import NoSuchFileException
1796
+ raise NoSuchFileException(message)
1797
+
1798
+ def get_path_of_downloaded_file(self, file):
1799
+ """This assumes the default location of SeleniumBase downloads,
1800
+ which is the "./downloaded_files/" folder where scripts run."""
1801
+ downloads_folder = constants.Files.DOWNLOADS_FOLDER
1802
+ abs_path = os.path.abspath(".")
1803
+ downloads_path = os.path.join(abs_path, downloads_folder)
1804
+ return os.path.join(downloads_path, file)
1805
+
1806
+ def set_download_path(self, path):
1807
+ """Set a new download path for click-initiated downloads.
1808
+ (For Pure CDP Mode sync format only! -> sb_cdp.)
1809
+ The default download location is: "./downloaded_files/".
1810
+ Convenience methods such as assert_downloaded_file(file)
1811
+ will still expect the default location."""
1812
+ self.loop.run_until_complete(self.page.set_download_path(path))
1813
+
1728
1814
  def set_locale(self, locale):
1729
1815
  """(Settings will take effect on the next page load)"""
1730
1816
  self.loop.run_until_complete(self.page.set_locale(locale))
@@ -3233,13 +3319,23 @@ class CDPMethods():
3233
3319
  )
3234
3320
  return True
3235
3321
 
3236
- def assert_true(self, expression):
3322
+ def assert_true(self, expression, msg=None):
3237
3323
  if not expression:
3238
- raise AssertionError("%s is not true" % expression)
3324
+ if not msg:
3325
+ raise AssertionError("%s is not true" % expression)
3326
+ else:
3327
+ raise AssertionError(
3328
+ "%s is not true. (%s)" % (expression, msg)
3329
+ )
3239
3330
 
3240
- def assert_false(self, expression):
3331
+ def assert_false(self, expression, msg=None):
3241
3332
  if expression:
3242
- raise AssertionError("%s is not false" % expression)
3333
+ if not msg:
3334
+ raise AssertionError("%s is not false" % expression)
3335
+ else:
3336
+ raise AssertionError(
3337
+ "%s is not false. (%s)" % (expression, msg)
3338
+ )
3243
3339
 
3244
3340
  def assert_equal(self, first, second):
3245
3341
  if first != second:
@@ -5103,6 +5103,8 @@ class BaseCase(unittest.TestCase):
5103
5103
  self.find_element_by_text = self.cdp.find_element_by_text
5104
5104
  if hasattr(self.cdp, "get_active_tab"):
5105
5105
  self.get_active_tab = self.cdp.get_active_tab
5106
+ if hasattr(self.cdp, "get_all_urls"):
5107
+ self.get_all_urls = self.cdp.get_all_urls
5106
5108
  if hasattr(self.cdp, "get_endpoint_url"):
5107
5109
  self.get_endpoint_url = self.cdp.get_endpoint_url
5108
5110
  if hasattr(self.cdp, "get_event_loop"):
@@ -380,6 +380,7 @@ class Browser:
380
380
  filter(lambda item: item.type_ == "page", self.targets)
381
381
  )
382
382
  await connection.sleep(0.005)
383
+ _cdp_downloads_path = None
383
384
  _cdp_timezone = None
384
385
  _cdp_user_agent = ""
385
386
  _cdp_locale = None
@@ -389,6 +390,8 @@ class Browser:
389
390
  _cdp_mobile_mode = None
390
391
  _cdp_recorder = None
391
392
  _cdp_ad_block = None
393
+ if getattr(sb_config, "_cdp_downloads_path", None):
394
+ _cdp_downloads_path = sb_config._cdp_downloads_path
392
395
  if getattr(sb_config, "_cdp_timezone", None):
393
396
  _cdp_timezone = sb_config._cdp_timezone
394
397
  if getattr(sb_config, "_cdp_user_agent", None):
@@ -405,6 +408,8 @@ class Browser:
405
408
  _cdp_ad_block = sb_config.ad_block_on
406
409
  if getattr(sb_config, "disable_csp", None):
407
410
  _cdp_disable_csp = sb_config.disable_csp
411
+ if "downloads_path" in kwargs:
412
+ _cdp_downloads_path = kwargs["downloads_path"]
408
413
  if "timezone" in kwargs:
409
414
  _cdp_timezone = kwargs["timezone"]
410
415
  elif "tzone" in kwargs:
@@ -439,6 +444,7 @@ class Browser:
439
444
  await connection.sleep(0.01)
440
445
  await connection.send(cdp.network.enable())
441
446
  await connection.sleep(0.01)
447
+ await connection.set_downloads_folder(_cdp_downloads_path)
442
448
  if _cdp_timezone:
443
449
  await connection.set_timezone(_cdp_timezone)
444
450
  if _cdp_locale:
@@ -744,6 +744,8 @@ async def start(
744
744
  sb_config._cdp_user_agent = kwargs["user_agent"]
745
745
  else:
746
746
  sb_config._cdp_user_agent = None
747
+ if "downloads_path" in kwargs:
748
+ sb_config._cdp_downloads_path = kwargs["downloads_path"]
747
749
  if "platform" in kwargs:
748
750
  sb_config._cdp_platform = kwargs["platform"]
749
751
  elif "plat" in kwargs:
@@ -5,6 +5,7 @@ import inspect
5
5
  import itertools
6
6
  import json
7
7
  import logging
8
+ import os
8
9
  import sys
9
10
  import types
10
11
  import warnings
@@ -19,6 +20,7 @@ from typing import (
19
20
  )
20
21
  import websockets
21
22
  from websockets.protocol import State
23
+ from seleniumbase.fixtures import constants
22
24
  from . import cdp_util as util
23
25
  import mycdp as cdp
24
26
  import mycdp.network
@@ -335,6 +337,17 @@ class Connection(metaclass=CantTouchThis):
335
337
  # No listener created yet.
336
338
  pass
337
339
 
340
+ async def set_downloads_folder(self, downloads_path):
341
+ if not downloads_path:
342
+ downloads_dir = constants.Files.DOWNLOADS_FOLDER
343
+ abs_path = os.path.abspath(".")
344
+ downloads_path = os.path.join(abs_path, downloads_dir)
345
+ await self.send(
346
+ cdp.browser.set_download_behavior(
347
+ behavior="allow", download_path=str(downloads_path)
348
+ )
349
+ )
350
+
338
351
  async def set_locale(self, locale: Optional[str] = None):
339
352
  """Sets the Language Locale code via set_user_agent_override."""
340
353
  await self.set_user_agent(user_agent="", accept_language=locale)
@@ -7,7 +7,6 @@ import pathlib
7
7
  import re
8
8
  import sys
9
9
  import urllib.parse
10
- import warnings
11
10
  from contextlib import suppress
12
11
  from filelock import AsyncFileLock
13
12
  from seleniumbase import config as sb_config
@@ -1154,52 +1153,40 @@ class Tab(Connection):
1154
1153
  Downloads the file by the given url.
1155
1154
  :param url: The URL of the file.
1156
1155
  :param filename: The name for the file.
1157
- If not specified, the name is composed from the url file name
1156
+ If not specified, the name is composed from the url file name.
1158
1157
  """
1159
- if not self._download_behavior:
1160
- directory_path = pathlib.Path.cwd() / "downloads"
1161
- directory_path.mkdir(exist_ok=True)
1162
- await self.set_download_path(directory_path)
1163
-
1164
- warnings.warn(
1165
- f"No download path set, so creating and using a default of "
1166
- f"{directory_path}"
1167
- )
1168
1158
  if not filename:
1169
1159
  filename = url.rsplit("/")[-1]
1170
1160
  filename = filename.split("?")[0]
1171
1161
  code = """
1172
- (elem) => {
1173
- async function _downloadFile(
1174
- imageSrc,
1175
- nameOfDownload,
1176
- ) {
1177
- const response = await fetch(imageSrc);
1178
- const blobImage = await response.blob();
1179
- const href = URL.createObjectURL(blobImage);
1180
- const anchorElement = document.createElement('a');
1181
- anchorElement.href = href;
1182
- anchorElement.download = nameOfDownload;
1183
- document.body.appendChild(anchorElement);
1184
- anchorElement.click();
1185
- setTimeout(() => {
1186
- document.body.removeChild(anchorElement);
1187
- window.URL.revokeObjectURL(href);
1188
- }, 500);
1189
- }
1190
- _downloadFile('%s', '%s')
1162
+ async function(elem, downloadUrl, nameOfDownload) {
1163
+ const response = await fetch(downloadUrl);
1164
+ const blobImage = await response.blob();
1165
+ const href = URL.createObjectURL(blobImage);
1166
+ const anchorElement = document.createElement('a');
1167
+ anchorElement.href = href;
1168
+ anchorElement.download = nameOfDownload;
1169
+ document.body.appendChild(anchorElement);
1170
+ anchorElement.click();
1171
+ // Clean up the DOM and memory space safely after trigger
1172
+ setTimeout(() => {
1173
+ document.body.removeChild(anchorElement);
1174
+ window.URL.revokeObjectURL(href);
1175
+ }, 1000);
1191
1176
  }
1192
- """ % (
1193
- url,
1194
- filename,
1195
- )
1177
+ """
1196
1178
  body = (await self.query_selector_all("body"))[0]
1197
1179
  await body.update()
1198
1180
  await self.send(
1199
1181
  cdp.runtime.call_function_on(
1200
- code,
1182
+ function_declaration=code,
1201
1183
  object_id=body.object_id,
1202
- arguments=[cdp.runtime.CallArgument(object_id=body.object_id)],
1184
+ arguments=[
1185
+ cdp.runtime.CallArgument(object_id=body.object_id),
1186
+ cdp.runtime.CallArgument(value=url),
1187
+ cdp.runtime.CallArgument(value=filename),
1188
+ ],
1189
+ await_promise=True,
1203
1190
  )
1204
1191
  )
1205
1192
 
@@ -1300,6 +1287,8 @@ class Tab(Connection):
1300
1287
  When not set, a default folder is used.
1301
1288
  :param path:
1302
1289
  """
1290
+ with suppress(Exception):
1291
+ path = pathlib.Path(path)
1303
1292
  await self.send(
1304
1293
  cdp.browser.set_download_behavior(
1305
1294
  behavior="allow", download_path=str(path.resolve())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seleniumbase
3
- Version: 4.49.8
3
+ Version: 4.49.9
4
4
  Summary: SeleniumBase is a framework for web crawling, scraping, and testing. Supports pytest. CDP Mode adds stealth. Includes many tools.
5
5
  Home-page: https://github.com/seleniumbase/SeleniumBase
6
6
  Author: Michael Mintz
@@ -71,7 +71,7 @@ Requires-Dist: exceptiongroup>=1.3.1
71
71
  Requires-Dist: websockets~=15.0.1; python_version < "3.10"
72
72
  Requires-Dist: websockets>=16.0; python_version >= "3.10"
73
73
  Requires-Dist: filelock~=3.19.1; python_version < "3.10"
74
- Requires-Dist: filelock>=3.29.1; python_version >= "3.10"
74
+ Requires-Dist: filelock>=3.29.3; python_version >= "3.10"
75
75
  Requires-Dist: fasteners>=0.20
76
76
  Requires-Dist: mycdp>=1.3.7
77
77
  Requires-Dist: pynose>=1.5.5
@@ -71,7 +71,7 @@ pytest==8.4.2
71
71
  pip>=26.1.2
72
72
  setuptools>=82.0.1
73
73
  websockets>=16.0
74
- filelock>=3.29.1
74
+ filelock>=3.29.3
75
75
  platformdirs>=4.10.0
76
76
  urllib3<3,>=2.7.0
77
77
  requests~=2.34.2
@@ -174,7 +174,7 @@ setup(
174
174
  'websockets~=15.0.1;python_version<"3.10"',
175
175
  'websockets>=16.0;python_version>="3.10"',
176
176
  'filelock~=3.19.1;python_version<"3.10"',
177
- 'filelock>=3.29.1;python_version>="3.10"',
177
+ 'filelock>=3.29.3;python_version>="3.10"',
178
178
  'fasteners>=0.20',
179
179
  'mycdp>=1.3.7',
180
180
  'pynose>=1.5.5',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes