seleniumbase 4.45.2__tar.gz → 4.45.3__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.45.2 → seleniumbase-4.45.3}/.gitignore +10 -0
  2. {seleniumbase-4.45.2/seleniumbase.egg-info → seleniumbase-4.45.3}/PKG-INFO +2 -2
  3. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/pyproject.toml +1 -0
  4. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/requirements.txt +1 -1
  5. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/__version__.py +1 -1
  6. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/behave/behave_sb.py +6 -0
  7. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_install.py +136 -1
  8. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_mkdir.py +6 -0
  9. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_mkrec.py +5 -0
  10. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_recorder.py +2 -0
  11. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/browser_launcher.py +69 -0
  12. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/driver_manager.py +11 -4
  13. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/pytest_plugin.py +20 -4
  14. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/sb_manager.py +9 -4
  15. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/selenium_plugin.py +15 -3
  16. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/cdp_driver/cdp_util.py +3 -0
  17. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/cdp_driver/config.py +55 -1
  18. seleniumbase-4.45.3/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
  19. {seleniumbase-4.45.2 → seleniumbase-4.45.3/seleniumbase.egg-info}/PKG-INFO +2 -2
  20. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase.egg-info/SOURCES.txt +1 -0
  21. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase.egg-info/requires.txt +1 -1
  22. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/setup.py +2 -1
  23. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/LICENSE +0 -0
  24. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/MANIFEST.in +0 -0
  25. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/README.md +0 -0
  26. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/install.sh +0 -0
  27. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/pytest.ini +0 -0
  28. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/sbase/__init__.py +0 -0
  29. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/sbase/__main__.py +0 -0
  30. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/sbase/steps.py +0 -0
  31. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/__init__.py +0 -0
  32. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/__main__.py +0 -0
  33. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/behave/__init__.py +0 -0
  34. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/behave/behave_helper.py +0 -0
  35. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/behave/steps.py +0 -0
  36. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/common/__init__.py +0 -0
  37. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/common/decorators.py +0 -0
  38. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/common/encryption.py +0 -0
  39. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/common/exceptions.py +0 -0
  40. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/common/obfuscate.py +0 -0
  41. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/common/unobfuscate.py +0 -0
  42. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/config/__init__.py +0 -0
  43. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/config/ad_block_list.py +0 -0
  44. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/config/proxy_list.py +0 -0
  45. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/config/settings.py +0 -0
  46. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/__init__.py +0 -0
  47. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/logo_helper.py +0 -0
  48. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/rich_helper.py +0 -0
  49. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/run.py +0 -0
  50. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
  51. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
  52. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_commander.py +0 -0
  53. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
  54. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
  55. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
  56. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_objectify.py +0 -0
  57. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/console_scripts/sb_print.py +0 -0
  58. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/__init__.py +0 -0
  59. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/application_manager.py +0 -0
  60. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/capabilities_parser.py +0 -0
  61. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/colored_traceback.py +0 -0
  62. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/create_db_tables.sql +0 -0
  63. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/detect_b_ver.py +0 -0
  64. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/download_helper.py +0 -0
  65. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/encoded_images.py +0 -0
  66. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/jqc_helper.py +0 -0
  67. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/log_helper.py +0 -0
  68. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/mysql.py +0 -0
  69. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/proxy_helper.py +0 -0
  70. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/recorder_helper.py +0 -0
  71. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/report_helper.py +0 -0
  72. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/s3_manager.py +0 -0
  73. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/sb_cdp.py +0 -0
  74. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/sb_driver.py +0 -0
  75. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/session_helper.py +0 -0
  76. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/settings_parser.py +0 -0
  77. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/style_sheet.py +0 -0
  78. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/testcase_manager.py +0 -0
  79. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/tour_helper.py +0 -0
  80. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/core/visual_helper.py +0 -0
  81. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/drivers/__init__.py +0 -0
  82. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/drivers/atlas_drivers/__init__.py +0 -0
  83. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
  84. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
  85. {seleniumbase-4.45.2/seleniumbase/drivers/chs_drivers → seleniumbase-4.45.3/seleniumbase/drivers/chromium_drivers}/__init__.py +0 -0
  86. {seleniumbase-4.45.2/seleniumbase/drivers/comet_drivers → seleniumbase-4.45.3/seleniumbase/drivers/chs_drivers}/__init__.py +0 -0
  87. {seleniumbase-4.45.2/seleniumbase/drivers/opera_drivers → seleniumbase-4.45.3/seleniumbase/drivers/comet_drivers}/__init__.py +0 -0
  88. {seleniumbase-4.45.2/seleniumbase/extensions → seleniumbase-4.45.3/seleniumbase/drivers/opera_drivers}/__init__.py +0 -0
  89. {seleniumbase-4.45.2/seleniumbase/fixtures → seleniumbase-4.45.3/seleniumbase/extensions}/__init__.py +0 -0
  90. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/extensions/ad_block.zip +0 -0
  91. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/extensions/disable_csp.zip +0 -0
  92. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/extensions/recorder.zip +0 -0
  93. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/extensions/sbase_ext.zip +0 -0
  94. {seleniumbase-4.45.2/seleniumbase/js_code → seleniumbase-4.45.3/seleniumbase/fixtures}/__init__.py +0 -0
  95. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/base_case.py +0 -0
  96. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/constants.py +0 -0
  97. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/css_to_xpath.py +0 -0
  98. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/errors.py +0 -0
  99. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/js_utils.py +0 -0
  100. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/page_actions.py +0 -0
  101. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/page_utils.py +0 -0
  102. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/shared_utils.py +0 -0
  103. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/unittest_helper.py +0 -0
  104. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/words.py +0 -0
  105. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/fixtures/xpath_to_css.py +0 -0
  106. {seleniumbase-4.45.2/seleniumbase/masterqa → seleniumbase-4.45.3/seleniumbase/js_code}/__init__.py +0 -0
  107. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/js_code/active_css_js.py +0 -0
  108. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/js_code/live_js.py +0 -0
  109. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/js_code/recorder_js.py +0 -0
  110. {seleniumbase-4.45.2/seleniumbase/plugins → seleniumbase-4.45.3/seleniumbase/masterqa}/__init__.py +0 -0
  111. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/masterqa/master_qa.py +0 -0
  112. {seleniumbase-4.45.2/seleniumbase/resources → seleniumbase-4.45.3/seleniumbase/plugins}/__init__.py +0 -0
  113. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/base_plugin.py +0 -0
  114. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/basic_test_info.py +0 -0
  115. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
  116. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/page_source.py +0 -0
  117. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
  118. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/plugins/screen_shots.py +0 -0
  119. {seleniumbase-4.45.2/seleniumbase/utilities → seleniumbase-4.45.3/seleniumbase/resources}/__init__.py +0 -0
  120. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/__init__.py +0 -0
  121. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/chinese.py +0 -0
  122. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/dutch.py +0 -0
  123. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/french.py +0 -0
  124. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/italian.py +0 -0
  125. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/japanese.py +0 -0
  126. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/korean.py +0 -0
  127. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/master_dict.py +0 -0
  128. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/portuguese.py +0 -0
  129. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/russian.py +0 -0
  130. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/spanish.py +0 -0
  131. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/translate/translator.py +0 -0
  132. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/__init__.py +0 -0
  133. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/cdp.py +0 -0
  134. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
  135. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
  136. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
  137. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
  138. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/cdp_driver/element.py +0 -0
  139. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/cdp_driver/tab.py +0 -0
  140. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/dprocess.py +0 -0
  141. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/options.py +0 -0
  142. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/patcher.py +0 -0
  143. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/reactor.py +0 -0
  144. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/undetected/webelement.py +0 -0
  145. {seleniumbase-4.45.2/seleniumbase/utilities/selenium_grid → seleniumbase-4.45.3/seleniumbase/utilities}/__init__.py +0 -0
  146. {seleniumbase-4.45.2/seleniumbase/utilities/selenium_ide → seleniumbase-4.45.3/seleniumbase/utilities/selenium_grid}/__init__.py +0 -0
  147. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
  148. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/font_color +0 -0
  149. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
  150. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
  151. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
  152. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
  153. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
  154. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
  155. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
  156. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
  157. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
  158. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase.egg-info/dependency_links.txt +0 -0
  159. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase.egg-info/entry_points.txt +0 -0
  160. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/seleniumbase.egg-info/top_level.txt +0 -0
  161. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/setup.cfg +0 -0
  162. {seleniumbase-4.45.2 → seleniumbase-4.45.3}/virtualenv_install.sh +0 -0
@@ -82,6 +82,16 @@ msedgedriver.exe
82
82
  operadriver.exe
83
83
  uc_driver.exe
84
84
 
85
+ # Chromium Zip Files
86
+ chrome-mac.zip
87
+ chrome-linux.zip
88
+ chrome-win.zip
89
+
90
+ # Chromium folders
91
+ chrome-mac
92
+ chrome-linux
93
+ chrome-win
94
+
85
95
  # Chrome for Testing Zip Files
86
96
  chrome-mac-arm64.zip
87
97
  chrome-mac-x64.zip
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seleniumbase
3
- Version: 4.45.2
3
+ Version: 4.45.3
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
@@ -68,7 +68,7 @@ Requires-Dist: certifi>=2025.11.12
68
68
  Requires-Dist: exceptiongroup>=1.3.1
69
69
  Requires-Dist: websockets>=15.0.1
70
70
  Requires-Dist: filelock~=3.19.1; python_version < "3.10"
71
- Requires-Dist: filelock>=3.20.0; python_version >= "3.10"
71
+ Requires-Dist: filelock>=3.20.1; python_version >= "3.10"
72
72
  Requires-Dist: fasteners>=0.20
73
73
  Requires-Dist: mycdp>=1.3.2
74
74
  Requires-Dist: pynose>=1.5.5
@@ -47,6 +47,7 @@ packages = [
47
47
  "seleniumbase.drivers.brave_drivers",
48
48
  "seleniumbase.drivers.comet_drivers",
49
49
  "seleniumbase.drivers.atlas_drivers",
50
+ "seleniumbase.drivers.chromium_drivers",
50
51
  "seleniumbase.extensions",
51
52
  "seleniumbase.fixtures",
52
53
  "seleniumbase.js_code",
@@ -8,7 +8,7 @@ certifi>=2025.11.12
8
8
  exceptiongroup>=1.3.1
9
9
  websockets>=15.0.1
10
10
  filelock~=3.19.1;python_version<"3.10"
11
- filelock>=3.20.0;python_version>="3.10"
11
+ filelock>=3.20.1;python_version>="3.10"
12
12
  fasteners>=0.20
13
13
  mycdp>=1.3.2
14
14
  pynose>=1.5.5
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.45.2"
2
+ __version__ = "4.45.3"
@@ -494,6 +494,12 @@ def get_configured_sb(context):
494
494
  sb.binary_location = binary_location
495
495
  sb_config.binary_location = binary_location
496
496
  continue
497
+ # Handle: -D use-chromium
498
+ if low_key in ["use-chromium"] and not sb_config.binary_location:
499
+ binary_location = "_chromium_"
500
+ sb.binary_location = binary_location
501
+ sb_config.binary_location = binary_location
502
+ continue
497
503
  # Handle: -D cft
498
504
  if low_key in ["cft"] and not sb_config.binary_location:
499
505
  binary_location = "cft"
@@ -19,6 +19,7 @@ Examples:
19
19
  sbase get chromedriver stable
20
20
  sbase get chromedriver beta
21
21
  sbase get chromedriver -p
22
+ sbase get chromium
22
23
  sbase get cft 131
23
24
  sbase get chs
24
25
  Output:
@@ -46,16 +47,21 @@ from seleniumbase import config as sb_config
46
47
  from seleniumbase import drivers # webdriver storage folder for SeleniumBase
47
48
  from seleniumbase.drivers import cft_drivers # chrome-for-testing
48
49
  from seleniumbase.drivers import chs_drivers # chrome-headless-shell
50
+ from seleniumbase.drivers import chromium_drivers # base chromium
49
51
 
50
52
  urllib3.disable_warnings()
51
53
  ARCH = platform.architecture()[0]
52
54
  IS_ARM_MAC = shared_utils.is_arm_mac()
53
55
  IS_MAC = shared_utils.is_mac()
56
+ IS_ARM_LINUX = shared_utils.is_arm_linux()
54
57
  IS_LINUX = shared_utils.is_linux()
55
58
  IS_WINDOWS = shared_utils.is_windows()
56
59
  DRIVER_DIR = os.path.dirname(os.path.realpath(drivers.__file__))
57
60
  DRIVER_DIR_CFT = os.path.dirname(os.path.realpath(cft_drivers.__file__))
58
61
  DRIVER_DIR_CHS = os.path.dirname(os.path.realpath(chs_drivers.__file__))
62
+ DRIVER_DIR_CHROMIUM = os.path.dirname(
63
+ os.path.realpath(chromium_drivers.__file__)
64
+ )
59
65
  LOCAL_PATH = "/usr/local/bin/" # On Mac and Linux systems
60
66
  DEFAULT_CHROMEDRIVER_VERSION = "114.0.5735.90" # (If can't find LATEST_STABLE)
61
67
  DEFAULT_GECKODRIVER_VERSION = "v0.36.0"
@@ -203,6 +209,59 @@ def get_cft_latest_version_from_milestone(milestone):
203
209
  return url_request.json()["milestones"][milestone]["version"]
204
210
 
205
211
 
212
+ def get_chromium_channel_revision(platform_code, channel):
213
+ """Snapshots only exist for revisions where a build occurred.
214
+ Therefore, not all found revisions will lead to snapshots."""
215
+ platform_key = None
216
+ if platform_code in ["Mac_Arm", "Mac"]:
217
+ platform_key = "Mac"
218
+ elif platform_code in ["Linux_x64"]:
219
+ platform_key = "Linux"
220
+ elif platform_code in ["Win_x64"]:
221
+ platform_key = "Windows"
222
+ elif platform_code in ["Win"]:
223
+ platform_key = "Win32"
224
+ channel_key = None
225
+ if channel.lower() == "stable":
226
+ channel_key = "Stable"
227
+ elif channel.lower() == "beta":
228
+ channel_key = "Beta"
229
+ elif channel.lower() == "dev":
230
+ channel_key = "Dev"
231
+ elif channel.lower() == "canary":
232
+ channel_key = "Canary"
233
+ base_url = "https://chromiumdash.appspot.com/fetch_releases"
234
+ url = f"{base_url}?channel={channel_key}&platform={platform_key}&num=1"
235
+ url_request = requests_get_with_retry(url)
236
+ data = None
237
+ if url_request.ok:
238
+ data = url_request.text
239
+ else:
240
+ raise Exception("Could not determine Chromium revision!")
241
+ if data:
242
+ try:
243
+ import ast
244
+
245
+ result = ast.literal_eval(data)
246
+ revision = result[0]["chromium_main_branch_position"]
247
+ return str(revision)
248
+ except Exception:
249
+ return get_latest_chromedriver_version(platform_code)
250
+ else:
251
+ return get_latest_chromedriver_version(platform_code)
252
+
253
+
254
+ def get_chromium_latest_revision(platform_code):
255
+ base_url = "https://storage.googleapis.com/chromium-browser-snapshots"
256
+ url = f"{base_url}/{platform_code}/LAST_CHANGE"
257
+ url_request = requests_get_with_retry(url)
258
+ if url_request.ok:
259
+ latest_revision = url_request.text
260
+ else:
261
+ raise Exception("Could not determine latest Chromium revision!")
262
+ return latest_revision
263
+
264
+
206
265
  def get_latest_chromedriver_version(channel="Stable"):
207
266
  try:
208
267
  if getattr(sb_config, "cft_lkgv_json", None):
@@ -274,6 +333,11 @@ def main(override=None, intel_for_uc=None, force_uc=None):
274
333
  elif override.startswith("iedriver "):
275
334
  extra = override.split("iedriver ")[1]
276
335
  sys.argv = ["seleniumbase", "get", "iedriver", extra]
336
+ elif override == "chromium":
337
+ sys.argv = ["seleniumbase", "get", "chromium"]
338
+ elif override.startswith("chromium "):
339
+ extra = override.split("chromium ")[1]
340
+ sys.argv = ["seleniumbase", "get", "chromium", extra]
277
341
  elif override == "cft":
278
342
  sys.argv = ["seleniumbase", "get", "cft"]
279
343
  elif override.startswith("cft "):
@@ -316,6 +380,8 @@ def main(override=None, intel_for_uc=None, force_uc=None):
316
380
  downloads_folder = DRIVER_DIR_CFT
317
381
  elif override == "chs" or name == "chs":
318
382
  downloads_folder = DRIVER_DIR_CHS
383
+ elif override == "chromium":
384
+ downloads_folder = DRIVER_DIR_CHROMIUM
319
385
  expected_contents = None
320
386
  platform_code = None
321
387
  copy_to_path = False
@@ -643,6 +709,31 @@ def main(override=None, intel_for_uc=None, force_uc=None):
643
709
  "https://storage.googleapis.com/chrome-for-testing-public/"
644
710
  "%s/%s/%s" % (use_version, platform_code, file_name)
645
711
  )
712
+ elif name == "chromium":
713
+ if IS_MAC:
714
+ if IS_ARM_MAC:
715
+ platform_code = "Mac_Arm"
716
+ else:
717
+ platform_code = "Mac"
718
+ file_name = "chrome-mac.zip"
719
+ elif IS_LINUX:
720
+ platform_code = "Linux_x64"
721
+ file_name = "chrome-linux.zip"
722
+ elif IS_WINDOWS:
723
+ if "64" in ARCH:
724
+ platform_code = "Win_x64"
725
+ else:
726
+ platform_code = "Win"
727
+ file_name = "chrome-win.zip"
728
+ revision = get_chromium_latest_revision(platform_code)
729
+ msg = c2 + "Chromium revision to download" + cr
730
+ p_version = c3 + revision + cr
731
+ log_d("\n*** %s = %s" % (msg, p_version))
732
+ download_url = (
733
+ "https://storage.googleapis.com/chromium-browser-snapshots/"
734
+ "%s/%s/%s" % (platform_code, revision, file_name)
735
+ )
736
+ downloads_folder = DRIVER_DIR_CHROMIUM
646
737
  elif name == "chrome-headless-shell" or name == "chs":
647
738
  set_version = None
648
739
  found_version = None
@@ -1003,12 +1094,12 @@ def main(override=None, intel_for_uc=None, force_uc=None):
1003
1094
  remote_file = requests_get_with_retry(download_url)
1004
1095
  with open(file_path, "wb") as file:
1005
1096
  file.write(remote_file.content)
1006
- log_d("%sDownload Complete!%s\n" % (c1, cr))
1007
1097
 
1008
1098
  if file_name.endswith(".zip"):
1009
1099
  zip_file_path = file_path
1010
1100
  zip_ref = zipfile.ZipFile(zip_file_path, "r")
1011
1101
  contents = zip_ref.namelist()
1102
+ log_d("%sDownload Complete!%s\n" % (c1, cr))
1012
1103
  if (
1013
1104
  len(contents) >= 1
1014
1105
  and name in ["chromedriver", "uc_driver", "geckodriver"]
@@ -1249,6 +1340,48 @@ def main(override=None, intel_for_uc=None, force_uc=None):
1249
1340
  "Chrome for Testing was saved inside:\n%s%s\n%s\n"
1250
1341
  % (pr_base_path, pr_sep, pr_folder_name)
1251
1342
  )
1343
+ elif name == "chromium":
1344
+ # Zip file is valid. Proceed.
1345
+ driver_path = None
1346
+ driver_file = None
1347
+ base_path = os.sep.join(zip_file_path.split(os.sep)[:-1])
1348
+ folder_name = contents[0].split("/")[0]
1349
+ folder_path = os.path.join(base_path, folder_name)
1350
+ if IS_MAC or IS_LINUX:
1351
+ if (
1352
+ "chromium" in folder_path
1353
+ and "drivers" in folder_path
1354
+ and os.path.exists(folder_path)
1355
+ ):
1356
+ shutil.rmtree(folder_path)
1357
+ subprocess.run(
1358
+ ["unzip", zip_file_path, "-d", downloads_folder]
1359
+ )
1360
+ elif IS_WINDOWS:
1361
+ subprocess.run(
1362
+ [
1363
+ "powershell",
1364
+ "Expand-Archive",
1365
+ "-Path",
1366
+ zip_file_path,
1367
+ "-DestinationPath",
1368
+ downloads_folder,
1369
+ "-Force",
1370
+ ]
1371
+ )
1372
+ else:
1373
+ zip_ref.extractall(downloads_folder)
1374
+ zip_ref.close()
1375
+ with suppress(Exception):
1376
+ os.remove(zip_file_path)
1377
+ log_d("%sUnzip Complete!%s\n" % (c2, cr))
1378
+ pr_base_path = c3 + base_path + cr
1379
+ pr_sep = c3 + os.sep + cr
1380
+ pr_folder_name = c3 + folder_name + cr
1381
+ log_d(
1382
+ "Chromium was saved inside:\n%s%s\n%s\n"
1383
+ % (pr_base_path, pr_sep, pr_folder_name)
1384
+ )
1252
1385
  elif name == "chrome-headless-shell" or name == "chs":
1253
1386
  # Zip file is valid. Proceed.
1254
1387
  driver_path = None
@@ -1300,6 +1433,7 @@ def main(override=None, intel_for_uc=None, force_uc=None):
1300
1433
  tar = tarfile.open(file_path)
1301
1434
  contents = tar.getnames()
1302
1435
  if len(contents) == 1:
1436
+ log_d("%sDownload Complete!%s\n" % (c1, cr))
1303
1437
  for f_name in contents:
1304
1438
  # Remove existing version if exists
1305
1439
  new_file = os.path.join(downloads_folder, str(f_name))
@@ -1337,6 +1471,7 @@ def main(override=None, intel_for_uc=None, force_uc=None):
1337
1471
  else:
1338
1472
  # Not a .zip file or a .tar.gz file. Just a direct download.
1339
1473
  if "Driver" in file_name or "driver" in file_name:
1474
+ log_d("%sDownload Complete!%s\n" % (c1, cr))
1340
1475
  log_d("Making [%s] executable ..." % file_name)
1341
1476
  make_executable(file_path)
1342
1477
  log_d("%s[%s] is now ready for use!%s" % (c1, file_name, cr))
@@ -246,6 +246,12 @@ def main():
246
246
  data.append("msedgedriver.exe")
247
247
  data.append("operadriver.exe")
248
248
  data.append("uc_driver.exe")
249
+ data.append("chrome-mac.zip")
250
+ data.append("chrome-linux.zip")
251
+ data.append("chrome-win.zip")
252
+ data.append("chrome-mac")
253
+ data.append("chrome-linux")
254
+ data.append("chrome-win")
249
255
  data.append("chrome-mac-arm64.zip")
250
256
  data.append("chrome-mac-x64.zip")
251
257
  data.append("chrome-linux64.zip")
@@ -88,6 +88,7 @@ def main():
88
88
  use_brave = False
89
89
  use_comet = False
90
90
  use_atlas = False
91
+ use_chromium = False
91
92
  use_uc = False
92
93
  esc_end = False
93
94
  start_page = None
@@ -150,6 +151,8 @@ def main():
150
151
  use_comet = True
151
152
  elif option.lower() == "--atlas":
152
153
  use_atlas = True
154
+ elif option.lower() == "--use-chromium":
155
+ use_chromium = True
153
156
  elif option.lower() == "--ee":
154
157
  esc_end = True
155
158
  elif option.lower() in ("--gui", "--headed"):
@@ -295,6 +298,8 @@ def main():
295
298
  run_cmd += " --comet"
296
299
  elif use_atlas:
297
300
  run_cmd += " --atlas"
301
+ elif use_chromium:
302
+ run_cmd += " --use-chromium"
298
303
  if force_gui:
299
304
  run_cmd += " --gui"
300
305
  if use_uc:
@@ -152,6 +152,8 @@ def do_recording(file_name, url, overwrite_enabled, use_chrome, window):
152
152
  command += " --comet"
153
153
  elif "--atlas" in command_args:
154
154
  command += " --atlas"
155
+ elif "--use-chromium" in command_args:
156
+ command += " --use-chromium"
155
157
  if (
156
158
  "--uc" in command_args
157
159
  or "--cdp" in command_args
@@ -32,6 +32,7 @@ from seleniumbase.drivers import opera_drivers # still uses chromedriver
32
32
  from seleniumbase.drivers import brave_drivers # still uses chromedriver
33
33
  from seleniumbase.drivers import comet_drivers # still uses chromedriver
34
34
  from seleniumbase.drivers import atlas_drivers # still uses chromedriver
35
+ from seleniumbase.drivers import chromium_drivers # still uses chromedriver
35
36
  from seleniumbase import extensions # browser extensions storage folder
36
37
  from seleniumbase.config import settings
37
38
  from seleniumbase.core import detect_b_ver
@@ -52,6 +53,9 @@ DRIVER_DIR_OPERA = os.path.dirname(os.path.realpath(opera_drivers.__file__))
52
53
  DRIVER_DIR_BRAVE = os.path.dirname(os.path.realpath(brave_drivers.__file__))
53
54
  DRIVER_DIR_COMET = os.path.dirname(os.path.realpath(comet_drivers.__file__))
54
55
  DRIVER_DIR_ATLAS = os.path.dirname(os.path.realpath(atlas_drivers.__file__))
56
+ DRIVER_DIR_CHROMIUM = os.path.dirname(
57
+ os.path.realpath(chromium_drivers.__file__)
58
+ )
55
59
  # Make sure that the SeleniumBase DRIVER_DIR is at the top of the System PATH
56
60
  # (Changes to the System PATH with os.environ only last during the test run)
57
61
  if not os.environ["PATH"].startswith(DRIVER_DIR):
@@ -3057,6 +3061,8 @@ def get_driver(
3057
3061
  driver_dir = DRIVER_DIR_CFT
3058
3062
  if getattr(sb_config, "binary_location", None) == "chs":
3059
3063
  driver_dir = DRIVER_DIR_CHS
3064
+ if getattr(sb_config, "binary_location", None) == "_chromium_":
3065
+ driver_dir = DRIVER_DIR_CHROMIUM
3060
3066
  if _special_binary_exists(binary_location, "opera"):
3061
3067
  driver_dir = DRIVER_DIR_OPERA
3062
3068
  sb_config._cdp_browser = "opera"
@@ -3120,6 +3126,51 @@ def get_driver(
3120
3126
  or browser_name == constants.Browser.EDGE
3121
3127
  )
3122
3128
  ):
3129
+ if (
3130
+ binary_location.lower() == "_chromium_"
3131
+ and browser_name == constants.Browser.GOOGLE_CHROME
3132
+ ):
3133
+ binary_folder = None
3134
+ if IS_MAC:
3135
+ binary_folder = "chrome-mac"
3136
+ elif IS_LINUX:
3137
+ binary_folder = "chrome-linux"
3138
+ elif IS_WINDOWS:
3139
+ binary_folder = "chrome-win"
3140
+ if binary_folder:
3141
+ binary_location = os.path.join(driver_dir, binary_folder)
3142
+ if not os.path.exists(binary_location):
3143
+ from seleniumbase.console_scripts import sb_install
3144
+ args = " ".join(sys.argv)
3145
+ if not (
3146
+ "-n" in sys.argv or " -n=" in args or args == "-c"
3147
+ ):
3148
+ # (Not multithreaded)
3149
+ sys_args = sys.argv # Save a copy of current sys args
3150
+ log_d("\nWarning: Chromium binary not found...")
3151
+ try:
3152
+ sb_install.main(override="chromium")
3153
+ except Exception as e:
3154
+ log_d("\nWarning: Chrome download failed: %s" % e)
3155
+ sys.argv = sys_args # Put back the original sys args
3156
+ else:
3157
+ chrome_fixing_lock = fasteners.InterProcessLock(
3158
+ constants.MultiBrowser.DRIVER_FIXING_LOCK
3159
+ )
3160
+ with chrome_fixing_lock:
3161
+ with suppress(Exception):
3162
+ shared_utils.make_writable(
3163
+ constants.MultiBrowser.DRIVER_FIXING_LOCK
3164
+ )
3165
+ if not os.path.exists(binary_location):
3166
+ sys_args = sys.argv # Save a copy of sys args
3167
+ log_d(
3168
+ "\nWarning: Chromium binary not found..."
3169
+ )
3170
+ sb_install.main(override="chromium")
3171
+ sys.argv = sys_args # Put back original args
3172
+ else:
3173
+ binary_location = None
3123
3174
  if (
3124
3175
  binary_location.lower() == "cft"
3125
3176
  and browser_name == constants.Browser.GOOGLE_CHROME
@@ -3257,12 +3308,25 @@ def get_driver(
3257
3308
  binary_name = "Google Chrome for Testing"
3258
3309
  binary_location += "/Google Chrome for Testing.app"
3259
3310
  binary_location += "/Contents/MacOS/Google Chrome for Testing"
3311
+ elif binary_name == "Chromium.app":
3312
+ binary_name = "Chromium"
3313
+ binary_location += "/Contents/MacOS/Chromium"
3314
+ elif binary_name in ["chrome-mac"]:
3315
+ binary_name = "Chromium"
3316
+ binary_location += "/Chromium.app"
3317
+ binary_location += "/Contents/MacOS/Chromium"
3260
3318
  elif binary_name == "chrome-linux64":
3261
3319
  binary_name = "chrome"
3262
3320
  binary_location += "/chrome"
3321
+ elif binary_name == "chrome-linux":
3322
+ binary_name = "chrome"
3323
+ binary_location += "/chrome"
3263
3324
  elif binary_name in ["chrome-win32", "chrome-win64"]:
3264
3325
  binary_name = "chrome.exe"
3265
3326
  binary_location += "\\chrome.exe"
3327
+ elif binary_name in ["chrome-win"]:
3328
+ binary_name = "chrome.exe"
3329
+ binary_location += "\\chrome.exe"
3266
3330
  elif binary_name in [
3267
3331
  "chrome-headless-shell-mac-arm64",
3268
3332
  "chrome-headless-shell-mac-x64",
@@ -4034,6 +4098,9 @@ def get_local_driver(
4034
4098
  downloads_path = DOWNLOADS_FOLDER
4035
4099
  driver_dir = DRIVER_DIR
4036
4100
  special_chrome = False
4101
+ if getattr(sb_config, "binary_location", None) == "_chromium_":
4102
+ special_chrome = True
4103
+ driver_dir = DRIVER_DIR_CHROMIUM
4037
4104
  if getattr(sb_config, "binary_location", None) == "cft":
4038
4105
  special_chrome = True
4039
4106
  driver_dir = DRIVER_DIR_CFT
@@ -4969,6 +5036,8 @@ def get_local_driver(
4969
5036
  device_height,
4970
5037
  device_pixel_ratio,
4971
5038
  )
5039
+ if binary_location and "chromium_drivers" in binary_location:
5040
+ chrome_options.add_argument("--use-mock-keychain")
4972
5041
  use_version = "latest"
4973
5042
  major_chrome_version = None
4974
5043
  saved_mcv = None
@@ -140,6 +140,7 @@ def Driver(
140
140
  pls=None, # Shortcut / Duplicate of "page_load_strategy".
141
141
  cft=None, # Use "Chrome for Testing"
142
142
  chs=None, # Use "Chrome-Headless-Shell"
143
+ use_chromium=None, # Use base "Chromium"
143
144
  ) -> sb_driver.DriverMethods:
144
145
  """
145
146
  * SeleniumBase Driver as a Python Context Manager or a returnable object. *
@@ -665,11 +666,15 @@ def Driver(
665
666
  if arg.startswith("--bl="):
666
667
  binary_location = arg.split("--bl=")[1]
667
668
  break
668
- if cft and not binary_location:
669
+ if use_chromium and not binary_location:
670
+ binary_location = "_chromium_"
671
+ elif cft and not binary_location:
669
672
  binary_location = "cft"
670
673
  elif chs and not binary_location:
671
674
  binary_location = "chs"
672
- if "--cft" in sys_argv and not binary_location:
675
+ if "--use-chromium" in sys_argv and not binary_location:
676
+ binary_location = "_chromium_"
677
+ elif "--cft" in sys_argv and not binary_location:
673
678
  binary_location = "cft"
674
679
  elif "--chs" in sys_argv and not binary_location:
675
680
  binary_location = "chs"
@@ -747,7 +752,7 @@ def Driver(
747
752
  and browser not in ["chrome", "opera", "brave", "comet", "atlas"]
748
753
  ):
749
754
  message = (
750
- '\n Undetected-Chromedriver Mode ONLY supports Chrome!'
755
+ '\n Undetected-Chromedriver Mode ONLY supports Chromium browsers!'
751
756
  '\n ("uc=True" / "undetectable=True" / "--uc")'
752
757
  '\n (Your browser choice was: "%s".)'
753
758
  '\n (Will use "%s" without UC Mode.)\n' % (browser, browser)
@@ -778,7 +783,9 @@ def Driver(
778
783
  if headless2 and browser == "firefox":
779
784
  headless2 = False # Only for Chromium browsers
780
785
  headless = True # Firefox has regular headless
781
- elif browser not in ["chrome", "edge"]:
786
+ elif browser not in [
787
+ "chrome", "edge", "opera", "brave", "comet", "atlas"
788
+ ]:
782
789
  headless2 = False # Only for Chromium browsers
783
790
  if disable_csp is None:
784
791
  if (
@@ -33,6 +33,7 @@ def pytest_addoption(parser):
33
33
  --brave (Shortcut for "--browser=brave".)
34
34
  --comet (Shortcut for "--browser=comet".)
35
35
  --atlas (Shortcut for "--browser=atlas".)
36
+ --use-chromium (Shortcut for using base `Chromium`)
36
37
  --cft (Shortcut for using `Chrome for Testing`)
37
38
  --chs (Shortcut for using `Chrome-Headless-Shell`)
38
39
  --settings-file=FILE (Override default SeleniumBase settings.)
@@ -219,6 +220,13 @@ def pytest_addoption(parser):
219
220
  default=False,
220
221
  help="""Shortcut for --browser=atlas""",
221
222
  )
223
+ parser.addoption(
224
+ "--use-chromium",
225
+ action="store_true",
226
+ dest="use_chromium",
227
+ default=False,
228
+ help="""Shortcut for using base `Chromium`""",
229
+ )
222
230
  parser.addoption(
223
231
  "--cft",
224
232
  action="store_true",
@@ -1623,7 +1631,7 @@ def pytest_addoption(parser):
1623
1631
  using_recorder
1624
1632
  and browser_changes == 1
1625
1633
  and browser_text not in [
1626
- "chrome", "edge", "opera", "brave", "comet", "atlas"
1634
+ "chrome", "edge", "opera", "brave", "comet", "atlas", "chromium"
1627
1635
  ]
1628
1636
  ):
1629
1637
  message = (
@@ -1646,7 +1654,9 @@ def pytest_addoption(parser):
1646
1654
  undetectable = True
1647
1655
  if (
1648
1656
  browser_changes == 1
1649
- and browser_text not in ["chrome", "opera", "brave", "comet", "atlas"]
1657
+ and browser_text not in [
1658
+ "chrome", "opera", "brave", "comet", "atlas", "chromium"
1659
+ ]
1650
1660
  and undetectable
1651
1661
  ):
1652
1662
  message = (
@@ -1714,7 +1724,11 @@ def pytest_configure(config):
1714
1724
  if sb_config.headless2 and sb_config.browser == "firefox":
1715
1725
  sb_config.headless2 = False # Only for Chromium browsers
1716
1726
  sb_config.headless = True # Firefox has regular headless
1717
- elif sb_config.browser not in ["chrome", "edge"]:
1727
+ elif (
1728
+ sb_config.browser not in [
1729
+ "chrome", "edge", "opera", "brave", "comet", "atlas", "chromium"
1730
+ ]
1731
+ ):
1718
1732
  sb_config.headless2 = False # Only for Chromium browsers
1719
1733
  sb_config.headed = config.getoption("headed")
1720
1734
  sb_config.xvfb = config.getoption("xvfb")
@@ -1760,7 +1774,9 @@ def pytest_configure(config):
1760
1774
  bin_loc = detect_b_ver.get_binary_location("atlas")
1761
1775
  if bin_loc and os.path.exists(bin_loc):
1762
1776
  sb_config.binary_location = bin_loc
1763
- if config.getoption("use_cft") and not sb_config.binary_location:
1777
+ if config.getoption("use_chromium") and not sb_config.binary_location:
1778
+ sb_config.binary_location = "_chromium_"
1779
+ elif config.getoption("use_cft") and not sb_config.binary_location:
1764
1780
  sb_config.binary_location = "cft"
1765
1781
  elif config.getoption("use_chs") and not sb_config.binary_location:
1766
1782
  sb_config.binary_location = "chs"
@@ -123,6 +123,7 @@ def SB(
123
123
  wfa=None, # Shortcut / Duplicate of "wait_for_angularjs".
124
124
  cft=None, # Use "Chrome for Testing"
125
125
  chs=None, # Use "Chrome-Headless-Shell"
126
+ use_chromium=None, # Use base "Chromium"
126
127
  save_screenshot=None, # Save a screenshot at the end of each test.
127
128
  no_screenshot=None, # No screenshots saved unless tests directly ask it.
128
129
  page_load_strategy=None, # Set Chrome PLS to "normal", "eager", or "none".
@@ -699,11 +700,15 @@ def SB(
699
700
  if arg.startswith("--bl="):
700
701
  binary_location = arg.split("--bl=")[1]
701
702
  break
702
- if cft and not binary_location:
703
+ if use_chromium and not binary_location:
704
+ binary_location = "_chromium_"
705
+ elif cft and not binary_location:
703
706
  binary_location = "cft"
704
707
  elif chs and not binary_location:
705
708
  binary_location = "chs"
706
- if "--cft" in sys_argv and not binary_location:
709
+ if "--use-chromium" in sys_argv and not binary_location:
710
+ binary_location = "_chromium_"
711
+ elif "--cft" in sys_argv and not binary_location:
707
712
  binary_location = "cft"
708
713
  elif "--chs" in sys_argv and not binary_location:
709
714
  binary_location = "chs"
@@ -804,7 +809,7 @@ def SB(
804
809
  and browser not in ["chrome", "opera", "brave", "comet", "atlas"]
805
810
  ):
806
811
  message = (
807
- '\n Undetected-Chromedriver Mode ONLY supports Chrome!'
812
+ '\n Undetected-Chromedriver Mode ONLY supports Chromium browsers!'
808
813
  '\n ("uc=True" / "undetectable=True" / "--uc")'
809
814
  '\n (Your browser choice was: "%s".)'
810
815
  '\n (Will use "%s" without UC Mode.)\n' % (browser, browser)
@@ -830,7 +835,7 @@ def SB(
830
835
  if headless2 and browser == "firefox":
831
836
  headless2 = False # Only for Chromium browsers
832
837
  headless = True # Firefox has regular headless
833
- elif browser not in ["chrome", "edge"]:
838
+ elif browser not in ["chrome", "edge", "opera", "brave", "comet", "atlas"]:
834
839
  headless2 = False # Only for Chromium browsers
835
840
  if not headless and not headless2:
836
841
  headed = True
@@ -22,6 +22,7 @@ class SeleniumBrowser(Plugin):
22
22
  --brave (Shortcut for "--browser=brave".)
23
23
  --comet (Shortcut for "--browser=comet".)
24
24
  --atlas (Shortcut for "--browser=atlas".)
25
+ --use-chromium (Shortcut for using base `Chromium`)
25
26
  --cft (Shortcut for using `Chrome for Testing`)
26
27
  --chs (Shortcut for using `Chrome-Headless-Shell`)
27
28
  --user-data-dir=DIR (Set the Chrome user data directory to use.)
@@ -180,6 +181,13 @@ class SeleniumBrowser(Plugin):
180
181
  default=False,
181
182
  help="""Shortcut for --browser=atlas""",
182
183
  )
184
+ parser.addoption(
185
+ "--use-chromium",
186
+ action="store_true",
187
+ dest="use_chromium",
188
+ default=False,
189
+ help="""Shortcut for using base `Chromium`""",
190
+ )
183
191
  parser.addoption(
184
192
  "--cft",
185
193
  action="store_true",
@@ -1237,9 +1245,11 @@ class SeleniumBrowser(Plugin):
1237
1245
  raise Exception(message)
1238
1246
  if browser_text:
1239
1247
  browser = browser_text
1240
- if self.options.recorder_mode and browser not in ["chrome", "edge"]:
1248
+ if self.options.recorder_mode and browser not in [
1249
+ "chrome", "edge", "opera", "brave", "comet", "atlas", "chromium"
1250
+ ]:
1241
1251
  message = (
1242
- "\n\n Recorder Mode ONLY supports Chrome and Edge!"
1252
+ "\n\n Recorder Mode ONLY supports Chromium browsers!"
1243
1253
  '\n (Your browser choice was: "%s")\n' % browser
1244
1254
  )
1245
1255
  raise Exception(message)
@@ -1340,7 +1350,9 @@ class SeleniumBrowser(Plugin):
1340
1350
  test.test.binary_location = self.options.binary_location
1341
1351
  if getattr(sb_config, "_cdp_bin_loc", None):
1342
1352
  test.test.binary_location = sb_config._cdp_bin_loc
1343
- if self.options.use_cft and not test.test.binary_location:
1353
+ if self.options.use_chromium and not test.test.binary_location:
1354
+ test.test.binary_location = "_chromium_"
1355
+ elif self.options.use_cft and not test.test.binary_location:
1344
1356
  test.test.binary_location = "cft"
1345
1357
  elif self.options.use_chs and not test.test.binary_location:
1346
1358
  test.test.binary_location = "chs"