seleniumbase 4.55.1__tar.gz → 4.56.0__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 (164) hide show
  1. {seleniumbase-4.55.1/seleniumbase.egg-info → seleniumbase-4.56.0}/PKG-INFO +111 -97
  2. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/README.md +99 -87
  3. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/requirements.txt +9 -7
  4. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/__version__.py +1 -1
  5. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/browser_launcher.py +31 -18
  6. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/sb_driver.py +3 -0
  7. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/page_actions.py +34 -16
  8. {seleniumbase-4.55.1 → seleniumbase-4.56.0/seleniumbase.egg-info}/PKG-INFO +111 -97
  9. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase.egg-info/requires.txt +11 -9
  10. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/setup.py +11 -9
  11. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/.gitignore +0 -0
  12. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/LICENSE +0 -0
  13. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/MANIFEST.in +0 -0
  14. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/install.sh +0 -0
  15. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/mcp_servers/__init__.py +0 -0
  16. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/mcp_servers/server.py +0 -0
  17. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/pyproject.toml +0 -0
  18. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/pytest.ini +0 -0
  19. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/sbase/__init__.py +0 -0
  20. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/sbase/__main__.py +0 -0
  21. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/sbase/steps.py +0 -0
  22. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/__init__.py +0 -0
  23. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/__main__.py +0 -0
  24. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/behave/__init__.py +0 -0
  25. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/behave/behave_helper.py +0 -0
  26. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/behave/behave_sb.py +0 -0
  27. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/behave/steps.py +0 -0
  28. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/common/__init__.py +0 -0
  29. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/common/decorators.py +0 -0
  30. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/common/encryption.py +0 -0
  31. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/common/exceptions.py +0 -0
  32. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/common/obfuscate.py +0 -0
  33. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/common/unobfuscate.py +0 -0
  34. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/config/__init__.py +0 -0
  35. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/config/ad_block_list.py +0 -0
  36. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/config/proxy_list.py +0 -0
  37. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/config/settings.py +0 -0
  38. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/__init__.py +0 -0
  39. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/logo_helper.py +0 -0
  40. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/rich_helper.py +0 -0
  41. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/run.py +0 -0
  42. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
  43. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
  44. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_commander.py +0 -0
  45. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_install.py +0 -0
  46. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
  47. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
  48. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
  49. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
  50. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
  51. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_objectify.py +0 -0
  52. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_print.py +0 -0
  53. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/console_scripts/sb_recorder.py +0 -0
  54. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/__init__.py +0 -0
  55. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/application_manager.py +0 -0
  56. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/capabilities_parser.py +0 -0
  57. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/colored_traceback.py +0 -0
  58. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/create_db_tables.sql +0 -0
  59. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/detect_b_ver.py +0 -0
  60. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/download_helper.py +0 -0
  61. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/encoded_images.py +0 -0
  62. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/jqc_helper.py +0 -0
  63. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/log_helper.py +0 -0
  64. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/mysql.py +0 -0
  65. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/nest_asyncio.py +0 -0
  66. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/proxy_helper.py +0 -0
  67. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/recorder_helper.py +0 -0
  68. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/report_helper.py +0 -0
  69. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/s3_manager.py +0 -0
  70. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/sb_cdp.py +0 -0
  71. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/session_helper.py +0 -0
  72. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/settings_parser.py +0 -0
  73. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/style_sheet.py +0 -0
  74. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/testcase_manager.py +0 -0
  75. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/tour_helper.py +0 -0
  76. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/core/visual_helper.py +0 -0
  77. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/drivers/__init__.py +0 -0
  78. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
  79. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
  80. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
  81. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
  82. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
  83. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
  84. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/extensions/__init__.py +0 -0
  85. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/extensions/ad_block.zip +0 -0
  86. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/extensions/disable_csp.zip +0 -0
  87. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/extensions/recorder.zip +0 -0
  88. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/extensions/sbase_ext.zip +0 -0
  89. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/__init__.py +0 -0
  90. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/base_case.py +0 -0
  91. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/constants.py +0 -0
  92. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/css_to_xpath.py +0 -0
  93. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/errors.py +0 -0
  94. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/js_utils.py +0 -0
  95. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/page_utils.py +0 -0
  96. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/shared_utils.py +0 -0
  97. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/unittest_helper.py +0 -0
  98. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/words.py +0 -0
  99. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/fixtures/xpath_to_css.py +0 -0
  100. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/js_code/__init__.py +0 -0
  101. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/js_code/active_css_js.py +0 -0
  102. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/js_code/live_js.py +0 -0
  103. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/js_code/recorder_js.py +0 -0
  104. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/masterqa/__init__.py +0 -0
  105. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/masterqa/master_qa.py +0 -0
  106. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/__init__.py +0 -0
  107. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/base_plugin.py +0 -0
  108. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/basic_test_info.py +0 -0
  109. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
  110. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/driver_manager.py +0 -0
  111. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/page_source.py +0 -0
  112. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/pytest_plugin.py +0 -0
  113. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
  114. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/sb_manager.py +0 -0
  115. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/screen_shots.py +0 -0
  116. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/plugins/selenium_plugin.py +0 -0
  117. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/resources/__init__.py +0 -0
  118. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/__init__.py +0 -0
  119. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/chinese.py +0 -0
  120. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/dutch.py +0 -0
  121. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/french.py +0 -0
  122. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/italian.py +0 -0
  123. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/japanese.py +0 -0
  124. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/korean.py +0 -0
  125. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/master_dict.py +0 -0
  126. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/portuguese.py +0 -0
  127. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/russian.py +0 -0
  128. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/spanish.py +0 -0
  129. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/translate/translator.py +0 -0
  130. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/__init__.py +0 -0
  131. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/cdp.py +0 -0
  132. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
  133. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
  134. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
  135. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
  136. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/cdp_driver/config.py +0 -0
  137. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
  138. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/cdp_driver/element.py +0 -0
  139. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/cdp_driver/tab.py +0 -0
  140. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/dprocess.py +0 -0
  141. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/options.py +0 -0
  142. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/patcher.py +0 -0
  143. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/reactor.py +0 -0
  144. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/undetected/webelement.py +0 -0
  145. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/__init__.py +0 -0
  146. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
  147. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
  148. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/font_color +0 -0
  149. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
  150. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
  151. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
  152. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
  153. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
  154. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
  155. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
  156. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
  157. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
  158. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
  159. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase.egg-info/SOURCES.txt +0 -0
  160. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase.egg-info/dependency_links.txt +0 -0
  161. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase.egg-info/entry_points.txt +0 -0
  162. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/seleniumbase.egg-info/top_level.txt +0 -0
  163. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/setup.cfg +0 -0
  164. {seleniumbase-4.55.1 → seleniumbase-4.56.0}/virtualenv_install.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seleniumbase
3
- Version: 4.55.1
3
+ Version: 4.56.0
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
@@ -67,7 +67,7 @@ Requires-Dist: certifi>=2026.7.22
67
67
  Requires-Dist: exceptiongroup>=1.3.1
68
68
  Requires-Dist: websockets~=16.1.1; python_version == "3.10"
69
69
  Requires-Dist: websockets>=16.1.1; python_version >= "3.11"
70
- Requires-Dist: filelock>=4.0.12
70
+ Requires-Dist: filelock>=4.1.0
71
71
  Requires-Dist: fasteners>=0.20
72
72
  Requires-Dist: mycdp>=1.4.0
73
73
  Requires-Dist: pynose>=1.5.5
@@ -76,7 +76,7 @@ Requires-Dist: sbvirtualdisplay>=1.4.0
76
76
  Requires-Dist: MarkupSafe>=3.0.4
77
77
  Requires-Dist: Jinja2>=3.1.6
78
78
  Requires-Dist: six>=1.17.0
79
- Requires-Dist: parse>=1.22.2
79
+ Requires-Dist: parse>=1.22.3
80
80
  Requires-Dist: parse-type>=0.6.6
81
81
  Requires-Dist: colorama>=0.4.6
82
82
  Requires-Dist: psutil>=7.2.2
@@ -96,11 +96,12 @@ Requires-Dist: trio<1,>=0.34.0
96
96
  Requires-Dist: trio-websocket~=0.12.2
97
97
  Requires-Dist: wsproto~=1.3.2
98
98
  Requires-Dist: websocket-client~=1.9.2
99
- Requires-Dist: selenium==4.50.0
100
- Requires-Dist: cssselect<2,>=1.5.0
99
+ Requires-Dist: selenium==4.51.0
100
+ Requires-Dist: cssselect~=1.5.0; python_version < "3.11"
101
+ Requires-Dist: cssselect<2,>=1.6.0; python_version >= "3.11"
101
102
  Requires-Dist: sortedcontainers==2.4.0
102
103
  Requires-Dist: execnet==2.1.2
103
- Requires-Dist: iniconfig==2.3.0
104
+ Requires-Dist: iniconfig~=2.3.1
104
105
  Requires-Dist: pluggy==1.6.0
105
106
  Requires-Dist: pytest==8.4.2; python_version < "3.11"
106
107
  Requires-Dist: pytest==9.1.1; python_version >= "3.11"
@@ -112,7 +113,8 @@ Requires-Dist: pytest-rerunfailures==16.7; python_version >= "3.11"
112
113
  Requires-Dist: pytest-xdist==3.8.0
113
114
  Requires-Dist: parameterized==0.9.0
114
115
  Requires-Dist: behave==1.2.6
115
- Requires-Dist: soupsieve~=2.10.0
116
+ Requires-Dist: soupsieve~=2.10.0; python_version == "3.10"
117
+ Requires-Dist: soupsieve~=3.0.1; python_version >= "3.11"
116
118
  Requires-Dist: beautifulsoup4~=4.15.0
117
119
  Requires-Dist: pyotp~=2.10.0
118
120
  Requires-Dist: python-xlib==0.33; platform_system == "Linux"
@@ -130,7 +132,7 @@ Requires-Dist: pytest-cov>=7.1.0; extra == "coverage"
130
132
  Provides-Extra: flake8
131
133
  Requires-Dist: flake8==7.4.1; extra == "flake8"
132
134
  Requires-Dist: mccabe==0.7.0; extra == "flake8"
133
- Requires-Dist: pyflakes==4.0.2; extra == "flake8"
135
+ Requires-Dist: pyflakes==4.0.3; extra == "flake8"
134
136
  Requires-Dist: pycodestyle==2.15.0; extra == "flake8"
135
137
  Provides-Extra: mcp
136
138
  Requires-Dist: mcp[cli]<3.0.0,>=2.3.0; extra == "mcp"
@@ -140,7 +142,7 @@ Provides-Extra: pdfminer
140
142
  Requires-Dist: pdfminer.six==20260107; extra == "pdfminer"
141
143
  Requires-Dist: cryptography==50.0.2; extra == "pdfminer"
142
144
  Requires-Dist: cffi==2.1.1; extra == "pdfminer"
143
- Requires-Dist: pycparser==3.0; extra == "pdfminer"
145
+ Requires-Dist: pycparser==3.11; extra == "pdfminer"
144
146
  Provides-Extra: pillow
145
147
  Requires-Dist: Pillow>=12.3.0; extra == "pillow"
146
148
  Provides-Extra: pip-system-certs
@@ -154,7 +156,7 @@ Requires-Dist: pyee>=13.0.1; extra == "playwright"
154
156
  Provides-Extra: pyautogui
155
157
  Requires-Dist: PyAutoGUI>=0.9.54; platform_system != "Linux" and extra == "pyautogui"
156
158
  Provides-Extra: uv
157
- Requires-Dist: uv>=0.12.23; extra == "uv"
159
+ Requires-Dist: uv>=0.13.0; extra == "uv"
158
160
  Dynamic: author
159
161
  Dynamic: author-email
160
162
  Dynamic: classifier
@@ -173,17 +175,17 @@ Dynamic: summary
173
175
  <!-- mcp-name: io.github.seleniumbase/seleniumbase -->
174
176
 
175
177
  <meta property="og:site_name" content="SeleniumBase">
176
- <meta property="og:title" content="SeleniumBase: Stealthy Chromium Automation with Python; and E2E Testing." />
177
- <meta property="og:description" content="Stealthy Chromium Automation, including fast, easy, and reliable E2E testing with Python." />
178
- <meta property="og:keywords" content="Python, pytest, selenium, webdriver, testing, automation, seleniumbase, framework, dashboard, recorder, reports, screenshots, playwright, stealth, CAPTCHA">
178
+ <meta property="og:title" content="SeleniumBase: Python Web Automation and E2E Testing. Includes stealth options!" />
179
+ <meta property="og:description" content="Fast, easy, and reliable Web/UI testing with Python. Includes stealth options!" />
180
+ <meta property="og:keywords" content="Python, pytest, selenium, webdriver, testing, automation, seleniumbase, framework, dashboard, recorder, reports, screenshots">
179
181
  <meta property="og:image" content="https://seleniumbase.github.io/cdn/img/mac_sb_logo_5b.png" />
180
- <link rel="icon" href="https://seleniumbase.github.io/img/logo6.png" />
182
+ <link rel="icon" href="https://seleniumbase.github.io/img/logo7.png" />
181
183
 
182
- <p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/sbase_text_logo3t.png" alt="SeleniumBase" title="SeleniumBase" width="584" style="max-width: 100% !important; height: auto !important;" /></a></p>
184
+ <h1 align="center">📊 SeleniumBase</h1>
183
185
 
184
- <p align="center" class="hero__title"><b>End-to-End Testing and Stealthy Automation</b></p>
186
+ <p><h3 align="center">One framework for browser automation, web scraping, and testing.<br /></h3></p>
185
187
 
186
- <p align="center"><a href="https://pypi.python.org/pypi/seleniumbase" target="_blank"><img src="https://img.shields.io/pypi/v/seleniumbase.svg?color=3399EE" alt="PyPI version" height="20" /></a> <a href="https://pepy.tech/projects/seleniumbase?timeRange=threeMonths&category=version&includeCIDownloads=true&granularity=daily&viewType=line&versions=*" target="_blank"><img src="https://static.pepy.tech/badge/seleniumbase" alt="SeleniumBase PyPI downloads" height="20" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-22BBCC.svg" title="SeleniumBase" height="20" /></a> <a href="https://seleniumbase.io"><img src="https://img.shields.io/badge/docs-seleniumbase.io-11BBAA.svg" alt="SeleniumBase Docs" height="20" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/actions" target="_blank"><img src="https://github.com/seleniumbase/SeleniumBase/workflows/Tests/badge.svg" alt="SeleniumBase GitHub Actions" height="20" /></a> <a href="https://www.youtube.com/playlist?list=PLp9uKicxkBc5UIlGi2BuE3aWC7JyXpD3m"><img src="https://img.shields.io/badge/docs-📺-F12345.svg?style=flat&logo=YouTube&logoColor=white&label=YouTube" alt="YouTube Channel" height="20" /></a></p>
188
+ <p align="center"><a href="https://pypi.python.org/pypi/seleniumbase" target="_blank"><img src="https://img.shields.io/pypi/v/seleniumbase.svg?style=flat-square&color=3399EE" alt="PyPI version" height="20" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/actions" target="_blank"><img src="https://img.shields.io/github/actions/workflow/status/seleniumbase/SeleniumBase/python-package.yml?branch=master&style=flat-square&label=CI" alt="SeleniumBase GitHub Actions" height="20" /></a> <a href="https://seleniumbase.io"><img src="https://img.shields.io/badge/docs-seleniumbase.io-11BBAA.svg?style=flat-square" alt="SeleniumBase Docs" height="20" /></a> <a href="https://pepy.tech/projects/seleniumbase?timeRange=threeMonths&category=version&includeCIDownloads=true&granularity=daily&viewType=line&versions=*" target="_blank"><img src="https://img.shields.io/pepy/dt/seleniumbase?style=flat-square" alt="SeleniumBase PyPI downloads" height="20" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-f4c430.svg?style=flat-square" title="SeleniumBase" height="20" /></a><br /><a href="https://www.youtube.com/playlist?list=PLp9uKicxkBc5UIlGi2BuE3aWC7JyXpD3m"><img src="https://img.shields.io/badge/docs-📺-D124D8.svg?style=flat-square&logo=YouTube&logoColor=white&label=YouTube" alt="YouTube Channel" height="20" /></a> <a href="https://discord.gg/EdhQTn3EyE" target="_blank"><img src="https://img.shields.io/discord/727927627830001734?style=flat-square&color=7289DA&label=Discord&logo=discord&logoColor=white" height="20" /></a> <a href="https://www.facebook.com/SeleniumBase/" target="_blank"> <img src="https://img.shields.io/badge/Facebook-4K_followers-1877F2?style=flat-square&logo=facebook&logoColor=white" alt="SeleniumBase Facebook Followers" height="20" /></a> <a href="https://x.com/seleniumbase" target="_blank"><img src="https://img.shields.io/badge/-1K_followers-1DA1F2?style=flat-square&logo=x&logoColor=white&labelColor=000000" alt="SeleniumBase X Followers" height="20" /></a></p>
187
189
 
188
190
  <p align="center">
189
191
  <a href="#python_installation">🚀 Start</a> |
@@ -218,123 +220,105 @@ Dynamic: summary
218
220
  <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/presenter/ReadMe.md">🎞️ Presenter</a> |
219
221
  <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/visual_testing/ReadMe.md">🖼️ Visual</a> |
220
222
  <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/case_plans.md">🗂️ CPlans</a>
221
- <br />
222
223
  </p>
223
224
 
224
- <ul>
225
- <li><b>SeleniumBase bypasses bot-detection with</b> 🥷 <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></a> / 🐙 <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a><b>.</b></li>
226
- <li>🎭 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md"><b><span translate="no">Stealthy Playwright Mode</span></b></a> <b>extends CDP Mode's stealth to Playwright.</b></li>
227
- </ul>
228
- <ul>
229
- </ul>
225
+ --------
226
+
227
+ 🥷 <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></a> and the newer <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> makes your automation undetectable to anti-bot services. <b>CDP Mode</b> also <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md"><span translate="no">adds <b>stealth</b> to stock Playwright</span></a>.
228
+
229
+ 📚 Example scripts that start or end with "<code>test</code>" are specifically designed to be run with <code><b>pytest</b></code>. Other scripts run directly with raw <code><b>python</b></code>. (Those start with "<code>raw</code>" to avoid confusion.)
230
230
 
231
231
  --------
232
232
 
233
- <b>📝 Here's a Python <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_planetmc.py" target="_blank">example</a> that uses <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md#-pure-cdp-mode-sb_cdp">Pure CDP Mode</a> (<code>sb_cdp</code>):</b><br />(It navigates to PlanetMinecraft where it bypasses the CAPTCHA)
233
+ <b>📝 Here's a <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_planetmc.py" target="_blank">Python script</a> that uses <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md#-pure-cdp-mode-sb_cdp">Pure CDP Mode</a> (<code>sb_cdp</code>):</b><br />(It performs actions such as typing, clicking, and bypassing a Cloudflare Turnstile)
234
234
 
235
235
  ```python
236
236
  from seleniumbase import sb_cdp
237
237
 
238
- sb = sb_cdp.Chrome()
239
- sb.goto("www.planetminecraft.com/account/sign_in")
240
- sb.solve_captcha()
241
- # "LOG IN" is enabled when the CAPTCHA is bypassed
242
- sb.wait_for_element_absent("input[disabled]")
243
- sb.sleep(2)
238
+ sb = sb_cdp.Chrome(incognito=True)
239
+ sb.goto("https://www.planetminecraft.com/account")
240
+ sb.assert_element('input[name="login"]')
241
+ sb.type('input[name="email"]', "test@example.com")
242
+ sb.type('input[name="password"]', "Fake_Password")
243
+ sb.click("input#autologin") # The checkbox
244
+ if sb.is_element_visible("input[disabled]"):
245
+ sb.solve_captcha() # Enables the input
246
+ sb.assert_element_absent("input[disabled]")
247
+ sb.sleep(1.5)
244
248
  sb.quit()
245
249
  ```
246
250
 
247
- <p align="center">
248
- <img src="https://seleniumbase.github.io/other/pmc_captcha.png" width="570" style="max-width: 100% !important; height: auto !important;" alt="Cloudflare Turnstile bypassed successfully" />
249
- <br /><em>(Cloudflare Turnstile bypassed successfully)</em>
250
- </p>
251
-
252
- 💡 <b><code>sb.solve_captcha()</code></b> handles CAPTCHAs that aren't bypassed automatically.<br />(If no CAPTCHA is present on the current page, then nothing happens.)
253
-
254
- ----
255
-
256
- <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py" target="_blank">This example</a> bypasses Cloudflare's challenge page with UC + CDP Mode:</b><br />(If the Turnstile isn't bypassed automatically, <b><code>sb.solve_captcha()</code></b> handles it.)</p>
257
-
258
- ```python
259
- from seleniumbase import SB
260
-
261
- with SB(uc=True, test=True, locale="en") as sb:
262
- sb.activate_cdp_mode()
263
- sb.goto("https://gitlab.com/users/sign_in")
264
- sb.sleep(2)
265
- sb.solve_captcha()
266
- sb.highlight('h1:contains("GitLab")')
267
- sb.highlight('button:contains("Sign in")')
251
+ ```
252
+ python raw_cdp_planetmc.py
268
253
  ```
269
254
 
270
- <p align="center">
271
- <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" alt="SeleniumBase" width="350" style="max-width: 100% !important; height: auto !important;"/>
272
- <br /><em>(Successfully bypassed bot-detection on a Cloudflare challenge page)</em>
255
+ <p align="left">
256
+ <img src="https://seleniumbase.github.io/other/pmc_captcha_2.png" width="530" style="max-width: 100% !important; height: auto !important;" alt="Cloudflare Turnstile bypassed successfully" />
273
257
  </p>
274
258
 
259
+ ✅ <b><code>sb.solve_captcha()</code></b> handles CAPTCHAs that aren't bypassed automatically.<br />(If called when there's no CAPTCHA on the page, then nothing happens / no-op.)
260
+
261
+ ℹ️ <code>sb.assert_*</code> methods wait up to 7 seconds for the expected condition to occur.
262
+
275
263
  --------
276
264
 
277
- <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_cdp_google.py" target="_blank">This example</a> searches Google for the SeleniumBase GitHub page and outputs the result as a PDF:</b></p>
265
+ <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_yc_news.py" target="_blank">This script</a> scrapes Hacker News listings:</b></p>
278
266
 
279
267
  ```python
280
268
  from seleniumbase import sb_cdp
281
269
 
282
- sb = sb_cdp.Chrome()
283
- sb.goto("https://google.com/ncr")
284
- sb.click_if_visible('button:contains("Accept all")')
285
- sb.type('[name="q"]', "SeleniumBase site:github.com")
286
- sb.sleep(0.2)
287
- sb.click('[value="Google Search"]')
288
- sb.sleep(1)
289
- sb.click_if_visible('h3:contains("seleniumbase/SeleniumBase")')
290
- sb.sleep(1)
291
- print(sb.get_page_title())
292
- sb.save_as_pdf("seleniumbase.pdf", folder="./downloaded_files/")
293
- print("* PDF saved to ./downloaded_files/seleniumbase.pdf")
294
- sb.quit()
270
+ sb = sb_cdp.Chrome(fast=True)
271
+ sb.goto("https://news.ycombinator.com/submitted?id=seleniumbase")
272
+ elements = sb.find_elements("span.titleline > a")
273
+ for element in elements:
274
+ print("* " + element.text)
295
275
  ```
296
276
 
297
- <p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/google_search_2.gif" alt="SeleniumBase Test" width="500" style="max-width: 100% !important; height: auto !important;" /></a><br /><em>(The PDF will have all search results if SeleniumBase isn't in the list)</em></p>
277
+ ```
278
+ python raw_cdp_yc_news.py
279
+ ```
280
+
281
+ <p align="left">
282
+ <img src="https://seleniumbase.github.io/other/yc_news_results.png" alt="SeleniumBase" width="510" style="max-width: 100% !important; height: auto !important;"/>
283
+ </p>
298
284
 
299
285
  --------
300
286
 
301
- <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_yc_news.py" target="_blank">This example</a> scrapes Hacker News listings:</b></p>
287
+ <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py" target="_blank">This script</a> bypasses Cloudflare's challenge page with UC + CDP Mode:</b></p>
302
288
 
303
289
  ```python
304
- from seleniumbase import sb_cdp
290
+ from seleniumbase import SB
305
291
 
306
- sb = sb_cdp.Chrome()
307
- sb.goto("https://news.ycombinator.com/submitted?id=seleniumbase")
308
- elements = sb.find_elements("span.titleline > a")
309
- for element in elements:
310
- print("* %s" % element.text)
292
+ with SB(uc=True, test=True, locale="en") as sb:
293
+ sb.activate_cdp_mode()
294
+ sb.goto("https://gitlab.com/users/sign_in")
295
+ sb.sleep(2)
296
+ sb.solve_captcha()
297
+ sb.highlight('h1:contains("GitLab")')
298
+ sb.highlight('button:contains("Sign in")')
311
299
  ```
312
300
 
313
- <p align="center">
314
- <img src="https://seleniumbase.github.io/other/yc_news_results.png" alt="SeleniumBase" width="500" style="max-width: 100% !important; height: auto !important;"/>
315
- <br /><em>(Hacker News results for "SeleniumBase")</em>
301
+ ```
302
+ python raw_gitlab.py
303
+ ```
304
+
305
+ <p align="left">
306
+ <img src="https://seleniumbase.github.io/other/gitlab_bypass_2.png" alt="SeleniumBase" width="420" style="max-width: 100% !important; height: auto !important;"/>
316
307
  </p>
317
308
 
318
309
  --------
319
310
 
311
+ 🧪 End-to-End Testing examples are located in [./examples/](https://github.com/seleniumbase/SeleniumBase/blob/master/examples).
312
+
320
313
  🐙 Stealthy CDP Mode examples are located in [./examples/cdp_mode/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/cdp_mode).
321
314
 
322
315
  🎭 Stealthy Playwright examples are located in [./examples/cdp_mode/playwright/](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/).
323
316
 
324
317
  --------
325
318
 
326
- <h3 align="left">⚙️ Stealthy architecture flowchart:</h3>
327
-
328
- <p align="center">
329
- <img src="https://seleniumbase.github.io/other/sb_architecture.png" width="646" style="max-width: 100% !important; height: auto !important;" alt="Stealthy architecture flowchart" />
330
- <br /><em>(For maximum stealth, use <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">CDP Mode</a>, which includes <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">Stealthy Playwright Mode</a>.)</em>
331
- </p>
332
-
333
- --------
334
-
335
319
  <h3 align="left">🌐 CLI Options for Supported Chromium Browsers</h3>
336
320
 
337
- <p>💡 You can set the Chromium browser to use via command line parameters:</p>
321
+ <p>💡 You can set which Chromium browser to use via command-line parameters:</p>
338
322
 
339
323
  ```zsh
340
324
  python SCRIPT.py --chromium # Use the unbranded Chromium browser
@@ -353,13 +337,15 @@ sb = sb_cdp.Chrome(use_chromium=True)
353
337
 
354
338
  --------
355
339
 
356
- <h3>🧪 Comprehensive E2E Testing with <code>pytest</code>:</h3>
340
+ <h3 align="left">⚙️ Stealthy architecture flowchart:</h3>
357
341
 
358
- 📚 The [SeleniumBase/examples/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder includes over 150 ready-to-run examples of E2E testing. Examples that start with `test_` or end with `_test.py`/`_tests.py` run with `pytest`. Other examples run directly with raw `python` (those generally start with `raw_` to avoid confusion).
342
+ <img src="https://seleniumbase.github.io/other/sb_architecture.png" width="530" style="max-width: 100% !important; height: auto !important;" alt="Stealthy architecture flowchart" />
359
343
 
344
+ --------
360
345
 
346
+ <h3>🧪 Comprehensive E2E Testing with <code>pytest</code>:</h3>
361
347
 
362
- <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py" target="_blank">This example</a> tests an e-commerce site with <code>pytest</code>:</b></p>
348
+ <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py" target="_blank">This script</a> tests an e-commerce site with <code>pytest</code>:</b></p>
363
349
 
364
350
  ```python
365
351
  from seleniumbase import BaseCase
@@ -383,13 +369,41 @@ class MyTestClass(BaseCase):
383
369
  self.assert_text("Thank you for your order!")
384
370
  ```
385
371
 
386
- > `pytest test_get_swag.py`
372
+ ```
373
+ pytest test_get_swag.py
374
+ ```
387
375
 
388
376
  <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py"><img src="https://seleniumbase.github.io/cdn/gif/fast_swag_2.gif" alt="SeleniumBase Test" width="500" style="max-width: 100% !important; height: auto !important;" /></a>
389
377
 
378
+ 🥷 For stealth with `pytest`, add `--uc` as a command-line option.
379
+
390
380
  --------
391
381
 
392
- <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">This example</a> tests another e-commerce site with <code>pytest</code>:</b></p>
382
+ <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">This script</a> tests a different e-commerce site with <code>pytest</code>:</b></p>
383
+
384
+ ```python
385
+ from seleniumbase import BaseCase
386
+ BaseCase.main(__name__, __file__)
387
+
388
+ class CoffeeCartTest(BaseCase):
389
+ def test_coffee_cart(self):
390
+ self.goto("https://seleniumbase.io/coffee/")
391
+ self.assert_title("Coffee Cart")
392
+ self.assert_element('button:contains("Total: $0.00")')
393
+ self.click('div[data-sb="Cappuccino"]')
394
+ self.assert_exact_text("cart (1)", 'a[aria-label="Cart page"]')
395
+ self.click('div[data-sb="Flat-White"]')
396
+ self.assert_exact_text("cart (2)", 'a[aria-label="Cart page"]')
397
+ self.click('div[data-sb="Cafe-Latte"]')
398
+ self.assert_exact_text("cart (3)", 'a[aria-label="Cart page"]')
399
+ self.click('a[aria-label="Cart page"]')
400
+ self.assert_exact_text("Total: $53.00", "button.pay")
401
+ self.click("button.pay")
402
+ self.type("input#name", "Selenium Coffee")
403
+ self.type("input#email", "test@test.test")
404
+ self.click("button#submit-payment")
405
+ self.assert_text("Thanks for your purchase.", "#app .success")
406
+ ```
393
407
 
394
408
  ```zsh
395
409
  pytest test_coffee_cart.py --demo
@@ -403,7 +417,7 @@ pytest test_coffee_cart.py --demo
403
417
 
404
418
  <a id="multiple_examples"></a>
405
419
 
406
- <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">This example</a> covers multiple actions with <code>pytest</code>:</b></p>
420
+ <p align="left"><b>📝 <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">This script</a> covers multiple actions with <code>pytest</code>:</b></p>
407
421
 
408
422
  ```zsh
409
423
  pytest test_demo_site.py
@@ -413,7 +427,7 @@ pytest test_demo_site.py
413
427
 
414
428
  > Easy to type, click, select, toggle, drag & drop, and more.
415
429
 
416
- (For more examples, see the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">SeleniumBase/examples/</a> folder.)
430
+ 📚 For more scripts, see the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">SeleniumBase/examples/</a> folder.
417
431
 
418
432
  --------
419
433