seleniumbase 4.15.9__py3-none-any.whl → 4.15.11__py3-none-any.whl

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.
@@ -1,2 +1,2 @@
1
1
  # seleniumbase package
2
- __version__ = "4.15.9"
2
+ __version__ = "4.15.11"
@@ -1972,7 +1972,10 @@ def pytest_terminal_summary(terminalreporter):
1972
1972
  def _perform_pytest_unconfigure_():
1973
1973
  from seleniumbase.core import proxy_helper
1974
1974
 
1975
- if not sb_config.multi_proxy:
1975
+ if (
1976
+ (hasattr(sb_config, "multi_proxy") and not sb_config.multi_proxy)
1977
+ or not hasattr(sb_config, "multi_proxy")
1978
+ ):
1976
1979
  proxy_helper.remove_proxy_zip_if_present()
1977
1980
  if hasattr(sb_config, "reuse_session") and sb_config.reuse_session:
1978
1981
  # Close the shared browser session
@@ -1225,7 +1225,10 @@ class SeleniumBrowser(Plugin):
1225
1225
 
1226
1226
  def finalize(self, result):
1227
1227
  """This runs after all tests have completed with nosetests."""
1228
- if not sb_config.multi_proxy:
1228
+ if (
1229
+ (hasattr(sb_config, "multi_proxy") and not sb_config.multi_proxy)
1230
+ or not hasattr(sb_config, "multi_proxy")
1231
+ ):
1229
1232
  proxy_helper.remove_proxy_zip_if_present()
1230
1233
 
1231
1234
  def afterTest(self, test):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: seleniumbase
3
- Version: 4.15.9
3
+ Version: 4.15.11
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
@@ -56,16 +56,13 @@ Classifier: Topic :: Utilities
56
56
  Requires-Python: >=3.6
57
57
  Description-Content-Type: text/markdown
58
58
  License-File: LICENSE
59
- Requires-Dist: PyYAML (>=6.0)
60
59
  Requires-Dist: certifi (>=2023.5.7)
61
60
  Requires-Dist: parse (>=1.19.1)
62
61
  Requires-Dist: parse-type (>=0.6.2)
63
62
  Requires-Dist: six (==1.16.0)
64
63
  Requires-Dist: idna (==3.4)
65
- Requires-Dist: requests-toolbelt (==1.0.0)
66
- Requires-Dist: pynose (==1.4.5)
64
+ Requires-Dist: pynose (==1.4.6)
67
65
  Requires-Dist: sortedcontainers (==2.4.0)
68
- Requires-Dist: execnet (==1.9.0)
69
66
  Requires-Dist: py (==1.11.0)
70
67
  Requires-Dist: pytest-html (==2.0.1)
71
68
  Requires-Dist: pytest-ordering (==0.6)
@@ -74,21 +71,14 @@ Requires-Dist: behave (==1.2.6)
74
71
  Requires-Dist: beautifulsoup4 (==4.12.2)
75
72
  Requires-Dist: tabcompleter (==1.2.1)
76
73
  Requires-Dist: pdbp (==1.4.2)
77
- Requires-Dist: pycparser (==2.21)
78
- Requires-Dist: cffi (==1.15.1)
79
74
  Requires-Dist: pyreadline3 (==3.4.1) ; platform_system == "Windows"
80
75
  Requires-Dist: pip (>=21.3.1) ; python_version < "3.7"
81
76
  Requires-Dist: packaging (>=21.3) ; python_version < "3.7"
82
77
  Requires-Dist: setuptools (>=59.6.0) ; python_version < "3.7"
83
- Requires-Dist: tomli (>=1.2.3) ; python_version < "3.7"
84
- Requires-Dist: tqdm (>=4.64.1) ; python_version < "3.7"
85
78
  Requires-Dist: wheel (>=0.37.1) ; python_version < "3.7"
86
79
  Requires-Dist: attrs (==22.1.0) ; python_version < "3.7"
87
80
  Requires-Dist: filelock (>=3.4.1) ; python_version < "3.7"
88
81
  Requires-Dist: platformdirs (>=2.4.0) ; python_version < "3.7"
89
- Requires-Dist: pyparsing (>=3.0.7) ; python_version < "3.7"
90
- Requires-Dist: zipp (==3.6.0) ; python_version < "3.7"
91
- Requires-Dist: more-itertools (==8.14.0) ; python_version < "3.7"
92
82
  Requires-Dist: chardet (==4.0.0) ; python_version < "3.7"
93
83
  Requires-Dist: charset-normalizer (==2.0.12) ; python_version < "3.7"
94
84
  Requires-Dist: urllib3 (==1.26.12) ; python_version < "3.7"
@@ -97,6 +87,7 @@ Requires-Dist: selenium (==3.141.0) ; python_version < "3.7"
97
87
  Requires-Dist: msedge-selenium-tools (==3.141.3) ; python_version < "3.7"
98
88
  Requires-Dist: cssselect (==1.1.0) ; python_version < "3.7"
99
89
  Requires-Dist: fasteners (==0.17.3) ; python_version < "3.7"
90
+ Requires-Dist: execnet (==1.9.0) ; python_version < "3.7"
100
91
  Requires-Dist: iniconfig (==1.1.1) ; python_version < "3.7"
101
92
  Requires-Dist: pluggy (==1.0.0) ; python_version < "3.7"
102
93
  Requires-Dist: pytest (==7.0.1) ; python_version < "3.7"
@@ -106,7 +97,6 @@ Requires-Dist: pytest-rerunfailures (==10.3) ; python_version < "3.7"
106
97
  Requires-Dist: pytest-xdist (==2.5.0) ; python_version < "3.7"
107
98
  Requires-Dist: parameterized (==0.8.1) ; python_version < "3.7"
108
99
  Requires-Dist: soupsieve (==2.3.2.post1) ; python_version < "3.7"
109
- Requires-Dist: cryptography (==36.0.2) ; python_version < "3.7"
110
100
  Requires-Dist: pygments (==2.14.0) ; python_version < "3.7"
111
101
  Requires-Dist: colorama (==0.4.5) ; python_version < "3.7"
112
102
  Requires-Dist: future-breakpoint (==2.0.0) ; python_version < "3.7"
@@ -114,44 +104,36 @@ Requires-Dist: pyotp (==2.7.0) ; python_version < "3.7"
114
104
  Requires-Dist: typing-extensions (==4.1.1) ; python_version < "3.7"
115
105
  Requires-Dist: commonmark (==0.9.1) ; python_version < "3.7"
116
106
  Requires-Dist: rich (==12.6.0) ; python_version < "3.7"
117
- Requires-Dist: keyring (>=23.4.1) ; python_version < "3.8"
118
107
  Requires-Dist: importlib-metadata (==4.2.0) ; python_version < "3.8"
119
108
  Requires-Dist: urllib3 (<2.1.0,>=1.26.16) ; python_version >= "3.10"
120
109
  Requires-Dist: pip (>=23.1.2) ; python_version >= "3.7"
121
110
  Requires-Dist: packaging (>=23.1) ; python_version >= "3.7"
122
111
  Requires-Dist: setuptools (>=68.0.0) ; python_version >= "3.7"
123
- Requires-Dist: tomli (>=2.0.1) ; python_version >= "3.7"
124
- Requires-Dist: tqdm (>=4.65.0) ; python_version >= "3.7"
125
112
  Requires-Dist: wheel (>=0.40.0) ; python_version >= "3.7"
126
113
  Requires-Dist: attrs (>=23.1.0) ; python_version >= "3.7"
127
114
  Requires-Dist: filelock (>=3.12.2) ; python_version >= "3.7"
128
- Requires-Dist: platformdirs (>=3.8.0) ; python_version >= "3.7"
129
- Requires-Dist: pyparsing (>=3.1.0) ; python_version >= "3.7"
130
- Requires-Dist: zipp (>=3.15.0) ; python_version >= "3.7"
131
- Requires-Dist: more-itertools (>=9.1.0) ; python_version >= "3.7"
115
+ Requires-Dist: platformdirs (>=3.8.1) ; python_version >= "3.7"
132
116
  Requires-Dist: chardet (==5.1.0) ; python_version >= "3.7"
133
- Requires-Dist: charset-normalizer (==3.1.0) ; python_version >= "3.7"
117
+ Requires-Dist: charset-normalizer (==3.2.0) ; python_version >= "3.7"
134
118
  Requires-Dist: requests (==2.31.0) ; python_version >= "3.7"
135
119
  Requires-Dist: sniffio (==1.3.0) ; python_version >= "3.7"
136
120
  Requires-Dist: h11 (==0.14.0) ; python_version >= "3.7"
137
121
  Requires-Dist: outcome (==1.2.0) ; python_version >= "3.7"
138
122
  Requires-Dist: trio (==0.22.1) ; python_version >= "3.7"
139
123
  Requires-Dist: trio-websocket (==0.10.3) ; python_version >= "3.7"
140
- Requires-Dist: pyopenssl (==23.2.0) ; python_version >= "3.7"
141
124
  Requires-Dist: wsproto (==1.2.0) ; python_version >= "3.7"
142
125
  Requires-Dist: selenium (==4.10.0) ; python_version >= "3.7"
143
126
  Requires-Dist: cssselect (==1.2.0) ; python_version >= "3.7"
144
127
  Requires-Dist: fasteners (==0.18) ; python_version >= "3.7"
128
+ Requires-Dist: execnet (==2.0.2) ; python_version >= "3.7"
145
129
  Requires-Dist: iniconfig (==2.0.0) ; python_version >= "3.7"
146
130
  Requires-Dist: pluggy (==1.2.0) ; python_version >= "3.7"
147
131
  Requires-Dist: pytest (==7.4.0) ; python_version >= "3.7"
148
- Requires-Dist: pytest-forked (==1.6.0) ; python_version >= "3.7"
149
132
  Requires-Dist: pytest-metadata (==3.0.0) ; python_version >= "3.7"
150
133
  Requires-Dist: pytest-rerunfailures (==12.0) ; python_version >= "3.7"
151
134
  Requires-Dist: pytest-xdist (==3.3.1) ; python_version >= "3.7"
152
135
  Requires-Dist: parameterized (==0.9.0) ; python_version >= "3.7"
153
136
  Requires-Dist: soupsieve (==2.4.1) ; python_version >= "3.7"
154
- Requires-Dist: cryptography (==41.0.1) ; python_version >= "3.7"
155
137
  Requires-Dist: pygments (==2.15.1) ; python_version >= "3.7"
156
138
  Requires-Dist: colorama (==0.4.6) ; python_version >= "3.7"
157
139
  Requires-Dist: exceptiongroup (==1.1.2) ; python_version >= "3.7"
@@ -159,7 +141,6 @@ Requires-Dist: pyotp (==2.8.0) ; python_version >= "3.7"
159
141
  Requires-Dist: mdurl (==0.1.2) ; python_version >= "3.7"
160
142
  Requires-Dist: rich (==13.4.2) ; python_version >= "3.7"
161
143
  Requires-Dist: urllib3 (<2,>=1.26.16) ; python_version >= "3.7" and python_version < "3.10"
162
- Requires-Dist: keyring (>=24.1.1) ; python_version >= "3.8"
163
144
  Requires-Dist: markdown-it-py (==3.0.0) ; python_version >= "3.8"
164
145
  Provides-Extra: allure
165
146
  Requires-Dist: allure-pytest (==2.9.45) ; (python_version < "3.7") and extra == 'allure'
@@ -186,8 +167,12 @@ Requires-Dist: ipdb (==0.13.11) ; extra == 'ipdb'
186
167
  Requires-Dist: ipython (==7.16.3) ; (python_version < "3.7") and extra == 'ipdb'
187
168
  Requires-Dist: ipython (==7.34.0) ; (python_version >= "3.7") and extra == 'ipdb'
188
169
  Provides-Extra: pdfminer
170
+ Requires-Dist: cffi (==1.15.1) ; extra == 'pdfminer'
171
+ Requires-Dist: pycparser (==2.21) ; extra == 'pdfminer'
189
172
  Requires-Dist: pdfminer.six (==20211012) ; (python_version < "3.7") and extra == 'pdfminer'
173
+ Requires-Dist: cryptography (==36.0.2) ; (python_version < "3.7") and extra == 'pdfminer'
190
174
  Requires-Dist: pdfminer.six (==20221105) ; (python_version >= "3.7") and extra == 'pdfminer'
175
+ Requires-Dist: cryptography (==41.0.1) ; (python_version >= "3.7") and extra == 'pdfminer'
191
176
  Provides-Extra: pillow
192
177
  Requires-Dist: Pillow (==8.4.0) ; (python_version < "3.7") and extra == 'pillow'
193
178
  Requires-Dist: Pillow (==9.5.0) ; (python_version >= "3.7" and python_version < "3.8") and extra == 'pillow'
@@ -210,13 +195,13 @@ Requires-Dist: zstandard (==0.21.0) ; (python_version >= "3.7") and extra == 'se
210
195
 
211
196
  <h1>SeleniumBase</h1>
212
197
 
213
- <h3 align="center">Python-powered web automation and testing with advanced tools.</h3>
198
+ <p align="center"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/sb_logo_10t.png" alt="SeleniumBase" title="SeleniumBase" width="266" /></a></p>
214
199
 
215
- <h3 align="center"><a href="https://github.com/seleniumbase/SeleniumBase"><img src="https://seleniumbase.github.io/cdn/gif/coffee_pdbp.gif" alt="SeleniumBase test with the pdbp debugger" title="SeleniumBase test with the pdbp debugger" /></a></h3>
200
+ <h2 align="center" class="hero__title">All-in-one Test Automation Framework</h2>
216
201
 
217
- <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" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/releases" target="_blank"><img src="https://img.shields.io/github/v/release/seleniumbase/SeleniumBase.svg?color=22AAEE" alt="GitHub version" /></a> <a href="https://seleniumbase.io"><img src="https://img.shields.io/badge/docs-seleniumbase.io-11BBAA.svg" alt="SeleniumBase Docs" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/actions" target="_blank"><img src="https://github.com/seleniumbase/SeleniumBase/workflows/CI%20build/badge.svg" alt="SeleniumBase GitHub Actions" /></a> <a href="https://gitter.im/seleniumbase/SeleniumBase" target="_blank"><img src="https://img.shields.io/gitter/room/seleniumbase/SeleniumBase.svg" alt="Gitter chat"/></a></p>
202
+ <h3 align="center"><img src="https://seleniumbase.github.io/cdn/img/python_logo.png" title="SeleniumBase" width="29" /> For Python enthusiasts and enterprise developers <img src="https://seleniumbase.github.io/cdn/img/python_logo.png" title="SeleniumBase" width="29" /></h3>
218
203
 
219
- <h4 align="center">Shortcuts / tutorials / tools / integrations:</h4>
204
+ <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" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/releases" target="_blank"><img src="https://img.shields.io/github/v/release/seleniumbase/SeleniumBase.svg?color=22AAEE" alt="GitHub version" /></a> <a href="https://seleniumbase.io"><img src="https://img.shields.io/badge/docs-seleniumbase.io-11BBAA.svg" alt="SeleniumBase Docs" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/actions" target="_blank"><img src="https://github.com/seleniumbase/SeleniumBase/workflows/CI%20build/badge.svg" alt="SeleniumBase GitHub Actions" /></a> <a href="https://gitter.im/seleniumbase/SeleniumBase" target="_blank"><img src="https://img.shields.io/gitter/room/seleniumbase/SeleniumBase.svg" alt="Gitter chat"/></a></p>
220
205
 
221
206
  <p align="center">
222
207
  <a href="#python_installation">🚀 Start</a> |
@@ -258,7 +243,40 @@ Requires-Dist: zstandard (==0.21.0) ; (python_version >= "3.7") and extra == 'se
258
243
 
259
244
  --------
260
245
 
246
+ <p align="left"><a href="https://github.com/seleniumbase/SeleniumBase/"><img src="https://seleniumbase.github.io/cdn/img/sb_logo_p3.png" alt="SeleniumBase" title="SeleniumBase" width="232" /></a></p>
247
+
248
+ <blockquote>
249
+ <p dir="auto"><strong>Jump to:</strong></p>
250
+ <ul dir="auto">
251
+ <li><a href="#install_seleniumbase" ><strong>Get Started / Installation</strong></a></li>
252
+ <li><a href="#basic_example_and_usage"><strong>Basic Example / Usage</strong></a></li>
253
+ <li><a href="#common_methods" ><strong>Common Test Methods</strong></a></li>
254
+ <li><a href="#fun_facts" ><strong>Fun Facts / Learn More</strong></a></li>
255
+ <li><a href="#demo_mode_and_debugging"><strong>Demo Mode / Debugging</strong></a></li>
256
+ <li><a href="#command_line_options" ><strong>Command-line Options</strong></a></li>
257
+ <li><a href="#directory_configuration"><strong>Directory Configuration</strong></a></li>
258
+ <li><a href="#seleniumbase_dashboard" ><strong>SeleniumBase Dashboard</strong></a></li>
259
+ <li><a href="#creating_visual_reports"><strong>Generating Test Reports</strong></a></li>
260
+ </ul>
261
+ </blockquote>
262
+
263
+ --------
264
+
261
265
  <a id="multiple_examples"></a>
266
+
267
+ <p align="left"><b>Example:</b> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">test_demo_site.py</a> from <a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples" target="_blank">./examples/</a> (Uses <code>--chrome</code> by default)</p>
268
+
269
+ ```bash
270
+ cd examples/
271
+ pytest test_demo_site.py
272
+ ```
273
+
274
+ <p align="left"><a href="https://seleniumbase.io/demo_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/demo_page_5.gif" width="480" alt="SeleniumBase Example" title="SeleniumBase Example" /></a></p>
275
+
276
+ > Easy to type, click, select, toggle, drag-and-drop, etc.
277
+
278
+ --------
279
+
262
280
  <p align="left"><b>Example:</b> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">test_coffee_cart.py</a> from <a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples" target="_blank">./examples/</a></p>
263
281
 
264
282
  ```bash
@@ -292,13 +310,15 @@ class CoffeeCartTest(BaseCase):
292
310
  self.assert_text("Thanks for your purchase.", "#app .success")
293
311
  ```
294
312
 
313
+ (For more examples, see the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">SeleniumBase/examples/</a> folder.)
314
+
295
315
  --------
296
316
 
297
317
  <details>
298
318
  <summary> ▶️ How is <b>SeleniumBase</b> different from raw Selenium? (<b>click to expand</b>)</summary>
299
319
  <div>
300
320
 
301
- <p>💡 SeleniumBase is a Python framework for browser automation and testing. SeleniumBase uses <a href="https://www.w3.org/TR/webdriver2/#endpoints" target="_blank">Selenium/WebDriver</a> APIs, and incorporates test-runners such as <code>pytest</code>, <code>nosetests</code>, and <code>behave</code> to provide organized structure, test discovery, test execution, test state (<i>eg. passed, failed, or skipped</i>), and command-line options for changing default settings (<i>such as choosing the browser to use</i>). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.</p>
321
+ <p>💡 SeleniumBase is a Python framework for browser automation and testing. SeleniumBase uses <a href="https://www.w3.org/TR/webdriver2/#endpoints" target="_blank">Selenium/WebDriver</a> APIs, and incorporates test-runners such as <code>pytest</code>, <code>pynose</code>, and <code>behave</code> to provide organized structure, test discovery, test execution, test state (<i>eg. passed, failed, or skipped</i>), and command-line options for changing default settings (<i>such as choosing the browser to use</i>). With raw Selenium, you would need to set up your own options-parser for configuring tests from the command-line.</p>
302
322
 
303
323
  <p>💡 With raw Selenium, commands that use selectors need to specify the type of selector (eg. <code>"css selector", "button#myButton"</code>). With SeleniumBase, there's auto-detection between CSS Selectors and XPath, which means you don't need to specify the type of selector in your commands (<i>but optionally you could</i>).</p>
304
324
 
@@ -333,7 +353,7 @@ With raw Selenium, that requires more code:<br />
333
353
  <summary> ▶️ Learn about different ways of writing tests (<b>click to expand</b>)</summary>
334
354
  <div>
335
355
 
336
- <p align="left">📘📝 An example test with the <b>BaseCase</b> class. Runs with <b><a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a></b> or <b>nosetests</b>. (<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">Learn more</a>)</p>
356
+ <p align="left">📘📝 An example test with the <b>BaseCase</b> class. Runs with <b><a href="https://docs.pytest.org/en/latest/how-to/usage.html">pytest</a></b> or <b>pynose</b>. (<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">Learn more</a>)</p>
337
357
 
338
358
  ```python
339
359
  from seleniumbase import BaseCase
@@ -383,7 +403,7 @@ with SB() as sb: # By default, browser="chrome" if not set.
383
403
  sb.assert_exact_text("You have been signed out!", "#top_message")
384
404
  ```
385
405
 
386
- <p align="left">📕📝 An example test with <b>behave-BDD</b> <a href="https://behave.readthedocs.io/en/stable/gherkin.html" target="_blank">Gherkin</a> structure. Runs with <b><code>behave</code></b>. (<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/ReadMe.md">Learn more</a>)</p>
406
+ <p align="left">📕📝 An example test with <b>behave-BDD</b> <a href="https://behave.readthedocs.io/en/stable/gherkin.html#features" target="_blank">Gherkin</a> structure. Runs with <b><code>behave</code></b>. (<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/ReadMe.md">Learn more</a>)</p>
387
407
 
388
408
  ```gherkin
389
409
  Feature: SeleniumBase scenarios for the RealWorld App
@@ -407,6 +427,8 @@ Feature: SeleniumBase scenarios for the RealWorld App
407
427
  <a id="python_installation"></a>
408
428
  <h2><img src="https://seleniumbase.github.io/cdn/img/python_logo.png" title="SeleniumBase" width="42" /> Set up Python & Git:</h2>
409
429
 
430
+ <a href="https://www.python.org/downloads/"><img src="https://img.shields.io/pypi/pyversions/seleniumbase.svg?color=FACE42" title="Supported Python Versions" /></a>
431
+
410
432
  🔵 Add <b><a href="https://www.python.org/downloads/">Python</a></b> and <b><a href="https://git-scm.com/">Git</a></b> to your System PATH.
411
433
 
412
434
  🔵 Using a <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/virtualenv_instructions.md">Python virtual env</a> is recommended.
@@ -416,7 +438,7 @@ Feature: SeleniumBase scenarios for the RealWorld App
416
438
 
417
439
  **You can install ``seleniumbase`` from [PyPI](https://pypi.org/project/seleniumbase/) or [GitHub](https://github.com/seleniumbase/SeleniumBase):**
418
440
 
419
- 🔵 **Installing ``seleniumbase`` from PyPI:**
441
+ 🔵 **How to install ``seleniumbase`` from PyPI:**
420
442
 
421
443
  ```bash
422
444
  pip install seleniumbase
@@ -426,7 +448,7 @@ pip install seleniumbase
426
448
  * (Add ``--force-reinstall`` to upgrade indirect packages.)
427
449
  * (Use ``pip3`` if multiple versions of Python are present.)
428
450
 
429
- 🔵 **Installing ``seleniumbase`` from a GitHub clone:**
451
+ 🔵 **How to install ``seleniumbase`` from a GitHub clone:**
430
452
 
431
453
  ```bash
432
454
  git clone https://github.com/seleniumbase/SeleniumBase.git
@@ -434,14 +456,14 @@ cd SeleniumBase/
434
456
  pip install -e .
435
457
  ```
436
458
 
437
- **To upgrade an existing install from a GitHub clone:**
459
+ 🔵 **How to upgrade an existing install from a GitHub clone:**
438
460
 
439
461
  ```bash
440
462
  git pull
441
463
  pip install -e .
442
464
  ```
443
465
 
444
- 🔵 Type ``seleniumbase`` or ``sbase`` to verify that SeleniumBase was installed successfully:
466
+ 🔵 **Type ``seleniumbase`` or ``sbase`` to verify that SeleniumBase was installed successfully:**
445
467
 
446
468
  ```bash
447
469
  ______ __ _ ____
@@ -488,16 +510,38 @@ COMMANDS:
488
510
  Use "pytest" for running tests.
489
511
  ```
490
512
 
491
-
492
- <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Downloading webdrivers:</h3>
513
+ <h3>🔵 Downloading webdrivers:</h3>
493
514
 
494
515
  ✅ SeleniumBase automatically downloads webdrivers as needed, such as ``chromedriver``.
495
516
 
517
+ <div></div>
518
+ <details>
519
+ <summary> ▶️ Here's output from a chromedriver download. (<b>click to expand</b>)</summary>
520
+
521
+ ```bash
522
+ *** chromedriver version for download = 114.0.5735.90 (Latest)
523
+
524
+ Downloading chromedriver_mac_arm64.zip from:
525
+ https://chromedriver.storage.googleapis.com/114.0.5735.90/chromedriver_mac_arm64.zip ...
526
+ Download Complete!
527
+
528
+ Extracting ['chromedriver'] from chromedriver_mac_arm64.zip ...
529
+ Unzip Complete!
530
+
531
+ The file [chromedriver] was saved to:
532
+ /Users/michael/github/SeleniumBase/seleniumbase/drivers/chromedriver
533
+
534
+ Making [chromedriver 114.0.5735.90] executable ...
535
+ [chromedriver 114.0.5735.90] is now ready for use!
536
+ ```
537
+
538
+ </details>
539
+
496
540
  ✅ To manually download a webdriver, see [Console Scripts](https://seleniumbase.io/seleniumbase/console_scripts/ReadMe/) OR [Webdriver Installation](https://seleniumbase.io/help_docs/webdriver_installation/).
497
541
 
498
542
 
499
543
  <a id="basic_example_and_usage"></a>
500
- <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Basic Example & Usage:</h3>
544
+ <h2><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Basic Example / Usage:</h2>
501
545
 
502
546
  🔵 If you've cloned SeleniumBase, you can run tests from the [examples/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder.
503
547
 
@@ -512,6 +556,8 @@ pytest my_first_test.py
512
556
 
513
557
  <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py"><img src="https://seleniumbase.github.io/cdn/gif/swag_labs_4.gif" alt="SeleniumBase Test" title="SeleniumBase Test" width="480" /></a>
514
558
 
559
+ > SeleniumBase easily handles login, shopping, and checkout.
560
+
515
561
  <p align="left"><b>Here's the code for <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/my_first_test.py">my_first_test.py</a>:</b></p>
516
562
 
517
563
  ```python
@@ -550,7 +596,7 @@ class MyTestClass(BaseCase):
550
596
 
551
597
 
552
598
  <a id="common_methods"></a>
553
- <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Here are some common SeleniumBase methods that you might find in tests:</h3>
599
+ <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Here are some common SeleniumBase methods:</h3>
554
600
 
555
601
  ```python
556
602
  self.open(url) # Navigate the browser window to the URL.
@@ -603,12 +649,21 @@ self.assert_no_js_errors() # Verify there are no JS errors.
603
649
  self.type("input", "dogs\n")
604
650
  ```
605
651
 
606
- SeleniumBase tests can be run with <code>pytest</code> or <code>nosetests</code>. (There's also a <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/ReadMe.md">behave BDD</a> format.)
652
+ Most SeleniumBase scripts can be run with <code>pytest</code>, <code>pynose</code>, or pure <code>python</code>. Not all test runners can run all test formats. For example, tests that use the ``sb`` pytest fixture can only be run with ``pytest``. (See <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">Syntax Formats</a>) There's also a <a href="https://behave.readthedocs.io/en/stable/gherkin.html#features" target="_blank">Gherkin</a> test format that runs with <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/behave_bdd/ReadMe.md">behave</a>.
607
653
 
608
654
  ```bash
609
- pytest my_first_test.py --chrome
655
+ pytest coffee_cart_tests.py --rs
656
+ pytest test_sb_fixture.py
657
+ pytest test_suite.py --rs --html=report.html --dashboard
610
658
 
611
- nosetests test_suite.py --firefox
659
+ pynose basic_test.py --mobile
660
+ pynose test_suite.py --headless --report --show-report
661
+
662
+ python raw_sb.py
663
+ python raw_test_scripts.py
664
+
665
+ behave realworld.feature
666
+ behave calculator.feature -D rs -D dashboard
612
667
  ```
613
668
 
614
669
  <p>✅ <code>pytest</code> includes automatic test discovery. If you don't specify a specific file or folder to run, <code>pytest</code> will automatically search through all subdirectories for tests to run based on the following criteria:</p>
@@ -616,7 +671,7 @@ nosetests test_suite.py --firefox
616
671
  * Python files that start with ``test_`` or end with ``_test.py``.
617
672
  * Python methods that start with ``test_``.
618
673
 
619
- With a SeleniumBase [pytest.ini](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/pytest.ini) file present, you can modify default discovery settings. The Python class name can be anything because ``seleniumbase.BaseCase`` inherits ``unittest.TestCase``, which triggers autodiscovery.
674
+ With a SeleniumBase [pytest.ini](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/pytest.ini) file present, you can modify default discovery settings. The Python class name can be anything because ``seleniumbase.BaseCase`` inherits ``unittest.TestCase`` to trigger autodiscovery.
620
675
 
621
676
  <p>✅ You can do a pre-flight check to see which tests would get discovered by <code>pytest</code> before the real flight:</p>
622
677
 
@@ -624,12 +679,12 @@ With a SeleniumBase [pytest.ini](https://github.com/seleniumbase/SeleniumBase/bl
624
679
  pytest --collect-only -q
625
680
  ```
626
681
 
627
- <p>✅ You can be more specific when calling <code>pytest</code> on a file:</p>
682
+ <p>✅ You can be more specific when calling <code>pytest</code> or <code>pynose</code> on a file:</p>
628
683
 
629
684
  ```bash
630
685
  pytest [FILE_NAME.py]::[CLASS_NAME]::[METHOD_NAME]
631
686
 
632
- nosetests [FILE_NAME.py]:[CLASS_NAME].[METHOD_NAME]
687
+ pynose [FILE_NAME.py]:[CLASS_NAME].[METHOD_NAME]
633
688
  ```
634
689
 
635
690
  <p>✅ No More Flaky Tests! SeleniumBase methods automatically wait for page elements to finish loading before interacting with them (<i>up to a timeout limit</i>). This means <b>you no longer need random <span><code>time.sleep()</code></span> statements</b> in your scripts.</p>
@@ -642,39 +697,56 @@ nosetests [FILE_NAME.py]:[CLASS_NAME].[METHOD_NAME]
642
697
  ✅ SeleniumBase works on all popular CI/CD platforms:
643
698
  <p><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/github/workflows/ReadMe.md"><img alt="GitHub Actions integration" src="https://img.shields.io/badge/GitHub_Actions-12B2C2.svg?logo=GitHubActions&logoColor=CFFFC2" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/azure/jenkins/ReadMe.md"><img alt="Jenkins integration" src="https://img.shields.io/badge/Jenkins-32B242.svg?logo=jenkins&logoColor=white" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/azure/azure_pipelines/ReadMe.md"><img alt="Azure integration" src="https://img.shields.io/badge/Azure-2288EE.svg?logo=AzurePipelines&logoColor=white" /></a> <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/google_cloud/ReadMe.md"><img alt="Google Cloud integration" src="https://img.shields.io/badge/Google_Cloud-11CAE8.svg?logo=GoogleCloud&logoColor=EE0066" /></a> <a href="#utilizing_advanced_features"><img alt="AWS integration" src="https://img.shields.io/badge/AWS-4488DD.svg?logo=AmazonAWS&logoColor=FFFF44" /></a> <a href="https://en.wikipedia.org/wiki/Personal_computer" target="_blank"><img alt="Your Computer" src="https://img.shields.io/badge/💻_Your_Computer-44E6E6.svg" /></a></p>
644
699
 
645
- <p>✅ SeleniumBase includes an automated/manual hybrid solution called <b><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md">MasterQA</a></b>, which speeds up manual testing by having automation perform all the browser actions while the manual tester handles validation.</p>
700
+ <p>✅ SeleniumBase includes an automated/manual hybrid solution called <b><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md">MasterQA</a></b> to speed up manual testing with automation while the manual tester handles validation.</p>
646
701
 
647
702
  <p>✅ For a full list of SeleniumBase features, <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/features_list.md">Click Here</a>.</p>
648
703
 
649
704
 
650
- <a id="detailed_instructions"></a>
651
- <h2><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Detailed Instructions:</h2>
705
+ <a id="demo_mode_and_debugging"></a>
706
+ <h2><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Demo Mode / Debugging:</h2>
652
707
 
653
- <a id="seleniumbase_demo_mode"></a>
654
- 🔵 <b>Demo Mode</b> helps you see what a test is doing. If a test is moving too fast for your eyes, run it in <b>Demo Mode</b>, which pauses the browser briefly between actions, highlights page elements being acted on, and displays assertions:
708
+ 🔵 <b>Demo Mode</b> helps you see what a test is doing. If a test is moving too fast for your eyes, run it in <b>Demo Mode</b> to pause the browser briefly between actions, highlight page elements being acted on, and display assertions:
655
709
 
656
710
  ```bash
657
711
  pytest my_first_test.py --demo
658
712
  ```
659
713
 
660
- 🔵 You can use the following calls in your scripts to help you debug issues:
714
+ 🔵 ``time.sleep(seconds)`` can be used to make a test wait at a specific spot:
715
+
716
+ ```python
717
+ import time; time.sleep(3) # Do nothing for 3 seconds.
718
+ ```
719
+
720
+ 🔵 **Debug Mode** with Python's built-in **[pdb](https://docs.python.org/3/library/pdb.html)** library helps you debug tests:
661
721
 
662
722
  ```python
663
- import time; time.sleep(5) # Makes the test wait and do nothing for 5 seconds.
664
- import pdb; pdb.set_trace() # Enter debugging mode. n = next, c = continue, s = step.
665
- import pytest; pytest.set_trace() # Enter debugging mode. n = next, c = continue, s = step.
723
+ import pdb; pdb.set_trace()
724
+ import pytest; pytest.set_trace()
725
+ breakpoint() # Shortcut for "import pdb; pdb.set_trace()"
666
726
  ```
667
727
 
728
+ > (**``pdb``** commands: ``n``, ``c``, ``s``, ``u``, ``d`` => ``next``, ``continue``, ``step``, ``up``, ``down``)
729
+
668
730
  🔵 To pause an active test that throws an exception or error, (*and keep the browser window open while **Debug Mode** begins in the console*), add **``--pdb``** as a ``pytest`` option:
669
731
 
670
732
  ```bash
671
- pytest my_first_test.py --pdb
733
+ pytest test_fail.py --pdb
734
+ ```
735
+
736
+ 🔵 To start tests in Debug Mode, add **``--trace``** as a ``pytest`` option:
737
+
738
+ ```bash
739
+ pytest test_coffee_cart.py --trace
672
740
  ```
673
741
 
674
- (**``pdb``** console commands: ``n``, ``c``, ``s`` => ``next``, ``continue``, ``step``).
742
+ <a href="https://github.com/seleniumbase/SeleniumBase"><img src="https://seleniumbase.github.io/cdn/gif/coffee_pdbp.gif" alt="SeleniumBase test with the pdbp (Pdb+) debugger" title="SeleniumBase test with the pdbp (Pdb+) debugger" /></a>
743
+
744
+
745
+ <a id="command_line_options"></a>
746
+ <h2>🔵 Command-line Options:</h2>
675
747
 
676
748
  <a id="pytest_options"></a>
677
- 🔵 Here are some useful command-line options that come with <code>pytest</code>:
749
+ Here are some useful command-line options that come with <code>pytest</code>:
678
750
 
679
751
  ```bash
680
752
  -v # Verbose mode. Prints the full name of each test and shows more details.
@@ -691,7 +763,7 @@ pytest my_first_test.py --pdb
691
763
  ```
692
764
 
693
765
  <a id="new_pytest_options"></a>
694
- 🔵 SeleniumBase provides additional <code>pytest</code> command-line options for tests:
766
+ SeleniumBase provides additional <code>pytest</code> command-line options for tests:
695
767
 
696
768
  ```bash
697
769
  --browser=BROWSER # (The web browser to use. Default: "chrome".)
@@ -788,7 +860,9 @@ pytest my_first_test.py --pdb
788
860
 
789
861
  (See the full list of command-line option definitions **[here](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/plugins/pytest_plugin.py)**. For detailed examples of command-line options, see **[customizing_test_runs.md](https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md)**)
790
862
 
791
- 🔵 During test failures, logs and screenshots from the most recent test run will get saved to the ``latest_logs/`` folder. Those logs will get moved to ``archived_logs/`` if you add --archive_logs to command-line options, or have ARCHIVE_EXISTING_LOGS set to True in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py), otherwise log files with be cleaned up at the start of the next test run. The ``test_suite.py`` collection contains tests that fail on purpose so that you can see how logging works.
863
+ --------
864
+
865
+ 🔵 During test failures, logs and screenshots from the most recent test run will get saved to the ``latest_logs/`` folder. Those logs will get moved to ``archived_logs/`` if you add --archive_logs to command-line options, or have ``ARCHIVE_EXISTING_LOGS`` set to True in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py), otherwise log files with be cleaned up at the start of the next test run. The ``test_suite.py`` collection contains tests that fail on purpose so that you can see how logging works.
792
866
 
793
867
  ```bash
794
868
  cd examples/
@@ -806,10 +880,10 @@ Here's the command-line option to add to tests: (See [examples/custom_settings.p
806
880
  🔵 To pass additional data from the command-line to tests, add ``--data="ANY STRING"``.
807
881
  Inside your tests, you can use ``self.data`` to access that.
808
882
 
883
+ <a id="directory_configuration"></a>
884
+ <h2><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Directory Configuration:</h2>
809
885
 
810
- <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Test Directory Configuration:</h3>
811
-
812
- 🔵 When running tests with **pytest**, you'll want a copy of **[pytest.ini](https://github.com/seleniumbase/SeleniumBase/blob/master/pytest.ini)** in your root folders. When running tests with **nosetests**, you'll want a copy of **[setup.cfg](https://github.com/seleniumbase/SeleniumBase/blob/master/setup.cfg)** in your root folders. These files specify default configuration details for tests. Folders should also include a blank ``__init__.py`` file, which allows your tests to import files from that folder.
886
+ 🔵 When running tests with **pytest**, you'll want a copy of **[pytest.ini](https://github.com/seleniumbase/SeleniumBase/blob/master/pytest.ini)** in your root folders. When running tests with **pynose**, you'll want a copy of **[setup.cfg](https://github.com/seleniumbase/SeleniumBase/blob/master/setup.cfg)** in your root folders. These files specify default configuration details for tests. Folders should also include a blank ``__init__.py`` file to allow your tests to import files from that folder.
813
887
 
814
888
  🔵 ``sbase mkdir DIR`` creates a folder with config files and sample tests:
815
889
 
@@ -859,7 +933,7 @@ ui_tests/
859
933
  └── setup.cfg
860
934
  ```
861
935
 
862
- Of those files, the ``pytest.ini`` config file is the most important, followed by a blank ``__init__.py`` file. There's also a ``setup.cfg`` file (only needed for nosetests). Finally, the ``requirements.txt`` file can be used to help you install seleniumbase into your environments (if it's not already installed).
936
+ Of those files, the ``pytest.ini`` config file is the most important, followed by a blank ``__init__.py`` file. There's also a ``setup.cfg`` file (for pynose). Finally, the ``requirements.txt`` file can be used to help you install seleniumbase into your environments (if it's not already installed).
863
937
 
864
938
  --------
865
939
 
@@ -889,7 +963,8 @@ pytest test_fail.py
889
963
 
890
964
  --------
891
965
 
892
- <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> The SeleniumBase Dashboard:</h3>
966
+ <a id="seleniumbase_dashboard"></a>
967
+ <h2><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> SeleniumBase Dashboard:</h2>
893
968
 
894
969
  🔵 The ``--dashboard`` option for pytest generates a SeleniumBase Dashboard located at ``dashboard.html``, which updates automatically as tests run and produce results. Example:
895
970
 
@@ -918,11 +993,11 @@ pytest test_suite.py --dashboard --rs --headless
918
993
  --------
919
994
 
920
995
  <a id="creating_visual_reports"></a>
921
- <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Generating Test Reports:</h3>
996
+ <h2><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Generating Test Reports:</h2>
922
997
 
923
- <h4><b>Pytest Reports:</b></h4>
998
+ <h3>🔵 Pytest Reports:</h3>
924
999
 
925
- 🔵 Using ``--html=report.html`` gives you a fancy report of the name specified after your test suite completes.
1000
+ Using ``--html=report.html`` gives you a fancy report of the name specified after your test suite completes.
926
1001
 
927
1002
  ```bash
928
1003
  pytest test_suite.py --html=report.html
@@ -930,9 +1005,9 @@ pytest test_suite.py --html=report.html
930
1005
 
931
1006
  <img src="https://seleniumbase.github.io/cdn/img/html_report.png" alt="Example Pytest Report" title="Example Pytest Report" width="520" />
932
1007
 
933
- 🔵 When combining pytest html reports with SeleniumBase Dashboard usage, the pie chart from the Dashboard will get added to the html report. Additionally, if you set the html report URL to be the same as the Dashboard URL when also using the dashboard, (example: ``--dashboard --html=dashboard.html``), then the Dashboard will become an advanced html report when all the tests complete.
1008
+ When combining pytest html reports with SeleniumBase Dashboard usage, the pie chart from the Dashboard will get added to the html report. Additionally, if you set the html report URL to be the same as the Dashboard URL when also using the dashboard, (example: ``--dashboard --html=dashboard.html``), then the Dashboard will become an advanced html report when all the tests complete.
934
1009
 
935
- 🔵 Here's an example of an upgraded html report:
1010
+ Here's an example of an upgraded html report:
936
1011
 
937
1012
  ```bash
938
1013
  pytest test_suite.py --dashboard --html=report.html
@@ -948,19 +1023,19 @@ You can also use ``--junit-xml=report.xml`` to get an xml report instead. Jenkin
948
1023
  pytest test_suite.py --junit-xml=report.xml
949
1024
  ```
950
1025
 
951
- <h4><b>Nosetest Reports:</b></h4>
1026
+ <h3>🔵 pynose Reports:</h3>
952
1027
 
953
1028
  The ``--report`` option gives you a fancy report after your test suite completes.
954
1029
 
955
1030
  ```bash
956
- nosetests test_suite.py --report
1031
+ pynose test_suite.py --report
957
1032
  ```
958
1033
 
959
- <img src="https://seleniumbase.github.io/cdn/img/nose_report.png" alt="Example Nosetest Report" title="Example Nosetest Report" width="320" />
1034
+ <img src="https://seleniumbase.github.io/cdn/img/nose_report.png" alt="Example pynose Report" title="Example pynose Report" width="320" />
960
1035
 
961
- (NOTE: You can add ``--show-report`` to immediately display Nosetest reports after the test suite completes. Only use ``--show-report`` when running tests locally because it pauses the test run.)
1036
+ (NOTE: You can add ``--show-report`` to immediately display pynose reports after the test suite completes. Only use ``--show-report`` when running tests locally because it pauses the test run.)
962
1037
 
963
- <h4><b>Behave Dashboard & Reports:</b></h4>
1038
+ <h3>🔵 Behave Dashboard & Reports:</h4>
964
1039
 
965
1040
  (The [behave_bdd/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples/behave_bdd) folder can be found in the [examples/](https://github.com/seleniumbase/SeleniumBase/tree/master/examples) folder.)
966
1041
 
@@ -976,7 +1051,7 @@ You can also use ``--junit`` to get ``.xml`` reports for each Behave feature. Je
976
1051
  behave behave_bdd/features/ --junit -D rs -D headless
977
1052
  ```
978
1053
 
979
- <h4><b>Allure Reports:</b></h4>
1054
+ <h3>🔵 Allure Reports:</h3>
980
1055
 
981
1056
  See: [https://docs.qameta.io/allure/](https://docs.qameta.io/allure/#_pytest)
982
1057
 
@@ -992,6 +1067,7 @@ Now your tests can create Allure results files, which can be processed by Allure
992
1067
  pytest test_suite.py --alluredir=allure_results
993
1068
  ```
994
1069
 
1070
+ --------
995
1071
 
996
1072
  <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Using a Proxy Server:</h3>
997
1073
 
@@ -1055,7 +1131,7 @@ pytest user_agent_test.py --agent="Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1
1055
1131
  <ul>
1056
1132
  <li>You can set up a <a href="https://jenkins.io/" target="_blank">Jenkins</a> build server for running tests at regular intervals. For a real-world Jenkins example of headless browser automation in action, check out the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/azure/jenkins/ReadMe.md">SeleniumBase Jenkins example on Azure</a> or the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/google_cloud/ReadMe.md">SeleniumBase Jenkins example on Google Cloud</a>.</li>
1057
1133
 
1058
- <li>You can use <a href="https://selenium.dev/documentation/en/grid/" target="_blank">the Selenium Grid</a> to scale your testing by distributing tests on several machines with parallel execution. To do this, check out the <a href="https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/utilities/selenium_grid">SeleniumBase selenium_grid folder</a>, which should have everything you need, including the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_grid/ReadMe.md">Selenium Grid ReadMe</a>, which will help you get started.</li>
1134
+ <li>You can use <a href="https://selenium.dev/documentation/en/grid/" target="_blank">the Selenium Grid</a> to scale your testing by distributing tests on several machines with parallel execution. To do this, check out the <a href="https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/utilities/selenium_grid">SeleniumBase selenium_grid folder</a>, which should have everything you need, including the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/utilities/selenium_grid/ReadMe.md">Selenium Grid ReadMe</a> to help you get started.</li>
1059
1135
 
1060
1136
  <li>If you're using the <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/mysql_installation.md">SeleniumBase MySQL feature</a> to save results from tests running on a server machine, you can install <a href="https://dev.mysql.com/downloads/tools/workbench/">MySQL Workbench</a> to help you read & write from your DB more easily.</li>
1061
1137
 
@@ -1074,7 +1150,7 @@ pytest [YOUR_TEST_FILE.py] --with-db-reporting --with-s3-logging
1074
1150
  <a id="detailed_method_specifications"></a>
1075
1151
  <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Detailed Method Specifications and Examples:</h3>
1076
1152
 
1077
- 🔵 Navigating to a web page: (and related commands)
1153
+ 🔵 **Navigating to a web page: (and related commands)**
1078
1154
 
1079
1155
  ```python
1080
1156
  self.open("https://xkcd.com/378/") # This method opens the specified page.
@@ -1099,7 +1175,7 @@ head_close_tag = source.find('</head>', head_open_tag)
1099
1175
  everything_inside_head = source[head_open_tag+len('<head>'):head_close_tag]
1100
1176
  ```
1101
1177
 
1102
- 🔵 Clicking:
1178
+ 🔵 **Clicking:**
1103
1179
 
1104
1180
  To click an element on the page:
1105
1181
 
@@ -1109,7 +1185,7 @@ self.click("div#my_id")
1109
1185
 
1110
1186
  **ProTip™:** In most web browsers, you can right-click on a page and select ``Inspect Element`` to see the CSS selector details that you'll need to create your own scripts.
1111
1187
 
1112
- 🔵 Typing Text:
1188
+ 🔵 **Typing Text:**
1113
1189
 
1114
1190
  <code>self.type(selector, text)</code> # updates the text from the specified element with the specified value. An exception is raised if the element is missing or if the text field is not editable. Example:
1115
1191
 
@@ -1119,19 +1195,19 @@ self.type("input#id_value", "2012")
1119
1195
 
1120
1196
  You can also use <code>self.add_text()</code> or the <a href="https://www.selenium.dev/documentation/webdriver/" target="_blank">WebDriver</a> <code>.send_keys()</code> command, but those won't clear the text box first if there's already text inside.
1121
1197
 
1122
- 🔵 Getting the text from an element on a page:
1198
+ 🔵 **Getting the text from an element on a page:**
1123
1199
 
1124
1200
  ```python
1125
1201
  text = self.get_text("header h2")
1126
1202
  ```
1127
1203
 
1128
- 🔵 Getting the attribute value from an element on a page:
1204
+ 🔵 **Getting the attribute value from an element on a page:**
1129
1205
 
1130
1206
  ```python
1131
1207
  attribute = self.get_attribute("#comic img", "title")
1132
1208
  ```
1133
1209
 
1134
- 🔵 Asserting existence of an element on a page within some number of seconds:
1210
+ 🔵 **Asserting existence of an element on a page within some number of seconds:**
1135
1211
 
1136
1212
  ```python
1137
1213
  self.wait_for_element_present("div.my_class", timeout=10)
@@ -1139,7 +1215,7 @@ self.wait_for_element_present("div.my_class", timeout=10)
1139
1215
 
1140
1216
  (NOTE: You can also use: ``self.assert_element_present(ELEMENT)``)
1141
1217
 
1142
- 🔵 Asserting visibility of an element on a page within some number of seconds:
1218
+ 🔵 **Asserting visibility of an element on a page within some number of seconds:**
1143
1219
 
1144
1220
  ```python
1145
1221
  self.wait_for_element_visible("a.my_class", timeout=5)
@@ -1165,7 +1241,7 @@ You can also use ``*=`` to search for any partial value in a CSS selector as sho
1165
1241
  self.click('a[name*="partial_name"]')
1166
1242
  ```
1167
1243
 
1168
- 🔵 Asserting visibility of text inside an element on a page within some number of seconds:
1244
+ 🔵 **Asserting visibility of text inside an element on a page within some number of seconds:**
1169
1245
 
1170
1246
  ```python
1171
1247
  self.assert_text("Make it so!", "div#trek div.picard div.quotes")
@@ -1174,7 +1250,7 @@ self.assert_text("Tea. Earl Grey. Hot.", "div#trek div.picard div.quotes", timeo
1174
1250
 
1175
1251
  (NOTE: ``self.find_text(TEXT, ELEMENT)`` and ``self.wait_for_text(TEXT, ELEMENT)`` also do this. For backwards compatibility, older method names were kept, but the default timeout may be different.)
1176
1252
 
1177
- 🔵 Asserting Anything:
1253
+ 🔵 **Asserting Anything:**
1178
1254
 
1179
1255
  ```python
1180
1256
  self.assert_true(var1 == var2)
@@ -1184,7 +1260,7 @@ self.assert_false(var1 == var2)
1184
1260
  self.assert_equal(var1, var2)
1185
1261
  ```
1186
1262
 
1187
- 🔵 Useful Conditional Statements: (with creative examples)
1263
+ 🔵 **Useful Conditional Statements: (with creative examples)**
1188
1264
 
1189
1265
  ❓ ``is_element_visible(selector):`` (visible on the page)
1190
1266
 
@@ -1257,7 +1333,7 @@ if self.is_link_text_visible("Stop! Hammer time!"):
1257
1333
  self.click_link("Stop! Hammer time!")
1258
1334
  ```
1259
1335
 
1260
- 🔵 Switching Tabs:
1336
+ <h3>🔵 Switching Tabs:</h3>
1261
1337
 
1262
1338
  <p>If your test opens up a new tab/window, you can switch to it. (SeleniumBase automatically switches to new tabs that don't open to <code>about:blank</code> URLs.)</p>
1263
1339
 
@@ -1265,16 +1341,27 @@ if self.is_link_text_visible("Stop! Hammer time!"):
1265
1341
  self.switch_to_window(1) # This switches to the new tab (0 is the first one)
1266
1342
  ```
1267
1343
 
1268
- 🔵 <b>ProTip™:</b> iframes follow the same principle as new windows - you need to specify the iframe if you want to take action on something in there
1344
+ <h3>🔵 How to handle iframes:</h3>
1345
+
1346
+ 🔵 <b>ProTip™:</b> iframes follow the same principle as new windows: You must first switch to the iframe if you want to perform actions in there:
1347
+
1348
+ ```python
1349
+ self.switch_to_frame("iframe")
1350
+ # ... Now perform actions inside the iframe
1351
+ self.switch_to_parent_frame() # Exit the current iframe
1352
+ ```
1353
+
1354
+ To exit from multiple iframes, use ``self.switch_to_default_content()``. If inside a single iframe, this has the same effect as ``self.switch_to_parent_frame()``.
1355
+
1356
+ 🔵 You can also use a context manager to act inside iframes:
1269
1357
 
1270
1358
  ```python
1271
- self.switch_to_frame('ContentManagerTextBody_ifr')
1272
- # Now you can act inside the iframe
1273
- # .... Do something cool (here)
1274
- self.switch_to_default_content() # Exit the iframe when you're done
1359
+ with self.frame_switch("iframe"):
1360
+ # ... Now perform actions while inside the code block
1361
+ # You have left the iframe!
1275
1362
  ```
1276
1363
 
1277
- 🔵 Executing Custom jQuery Scripts:
1364
+ <h3>🔵 How to execute custom jQuery scripts:</h3>
1278
1365
 
1279
1366
  <p>jQuery is a powerful JavaScript library that allows you to perform advanced actions in a web browser.
1280
1367
  If the web page you're on already has jQuery loaded, you can start executing jQuery scripts immediately.
@@ -1318,7 +1405,11 @@ self.execute_script("return jQuery('textarea')[2].value") # Returns the css "va
1318
1405
 
1319
1406
  </details>
1320
1407
 
1321
- 🔵 Some websites have a restrictive [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) to prevent users from loading jQuery and other external libraries onto their websites. If you need to use jQuery or another JS library on such a website, add ``--disable-csp`` on the command-line.
1408
+ <h3>🔵 How to handle a restrictive CSP:</h3>
1409
+
1410
+ 🛑 Some websites have a restrictive [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) to prevent users from loading jQuery and other external libraries onto their websites. If you need to use jQuery or another JS library on such a website, add ``--disable-csp`` as a ``pytest`` command-line option.
1411
+
1412
+ <h3>🔵 More JavaScript fun:</h3>
1322
1413
 
1323
1414
  <div></div>
1324
1415
  <details>
@@ -1337,7 +1428,7 @@ self.click("a.analytics") # Clicks the generated button
1337
1428
 
1338
1429
  </details>
1339
1430
 
1340
- 🔵 Using deferred asserts:
1431
+ <h3>🔵 How to use deferred asserts:</h3>
1341
1432
 
1342
1433
  <p>Let's say you want to verify multiple different elements on a web page in a single test, but you don't want the test to fail until you verified several elements at once so that you don't have to rerun the test to find more missing elements on the same page. That's where deferred asserts come in. Here's the example:</p>
1343
1434
 
@@ -1346,7 +1437,6 @@ from seleniumbase import BaseCase
1346
1437
  BaseCase.main(__name__, __file__)
1347
1438
 
1348
1439
  class MyTestClass(BaseCase):
1349
-
1350
1440
  def test_deferred_asserts(self):
1351
1441
  self.open('https://xkcd.com/993/')
1352
1442
  self.wait_for_element('#comic')
@@ -1362,7 +1452,7 @@ class MyTestClass(BaseCase):
1362
1452
  <code>deferred_assert_element()</code> and <code>deferred_assert_text()</code> will save any exceptions that would be raised.
1363
1453
  To flush out all the failed deferred asserts into a single exception, make sure to call <code>self.process_deferred_asserts()</code> at the end of your test method. If your test hits multiple pages, you can call <code>self.process_deferred_asserts()</code> before navigating to a new page so that the screenshot from your log files matches the URL where the deferred asserts were made.
1364
1454
 
1365
- 🔵 Accessing Raw <a href="https://www.selenium.dev/documentation/webdriver/" target="_blank">WebDriver</a>:
1455
+ <h3>🔵 How to access raw <a href="https://www.selenium.dev/documentation/webdriver/" target="_blank">WebDriver</a>:</h3>
1366
1456
 
1367
1457
  <p>If you need access to any commands that come with standard <a href="https://www.selenium.dev/documentation/webdriver/" target="_blank">WebDriver</a>, you can call them directly like this:</p>
1368
1458
 
@@ -1374,9 +1464,9 @@ self.driver.find_elements("partial link text", "GitHub")
1374
1464
 
1375
1465
  (In general, you'll want to use the SeleniumBase versions of methods when available.)
1376
1466
 
1377
- 🔵 Retrying failing tests automatically:
1467
+ <h3>🔵 How to retry failing tests automatically:</h3>
1378
1468
 
1379
- <p>You can use <code>--reruns=NUM</code> to retry failing tests that many times. Use <code>--reruns-delay=SECONDS</code> to wait that many seconds between retries. Example:</p>
1469
+ <p>You can use <code>pytest --reruns=NUM</code> to retry failing tests that many times. Add <code>--reruns-delay=SECONDS</code> to wait that many seconds between retries. Example:</p>
1380
1470
 
1381
1471
  ```bash
1382
1472
  pytest --reruns=1 --reruns-delay=1
@@ -1384,10 +1474,15 @@ pytest --reruns=1 --reruns-delay=1
1384
1474
 
1385
1475
  <p>You can use the <code>@retry_on_exception()</code> decorator to retry failing methods. (First import: <code>from seleniumbase import decorators</code>). To learn more about SeleniumBase decorators, <a href="https://github.com/seleniumbase/SeleniumBase/tree/master/seleniumbase/common">click here</a>.</p>
1386
1476
 
1477
+ --------
1387
1478
 
1388
- <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Wrap-Up</h3>
1479
+ > "Catch bugs in QA before deploying code to Production!"
1389
1480
 
1390
- <b>Congratulations on getting started with SeleniumBase!</b>
1481
+ <p align="left"><a href="https://seleniumbase.io/error_page" target="_blank"><img src="https://seleniumbase.github.io/cdn/gif/error_page.gif" alt="Catch bugs in QA before deploying code to Production!" title="Catch bugs in QA before deploying code to Production!" /></a></p>
1482
+
1483
+ --------
1484
+
1485
+ <h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Wrap-Up</h3>
1391
1486
 
1392
1487
  <p>
1393
1488
  <div><b>If you see something, say something!</b></div>
@@ -1407,9 +1502,9 @@ pytest --reruns=1 --reruns-delay=1
1407
1502
  <p><a href="https://pepy.tech/project/seleniumbase" target="_blank"><img src="https://pepy.tech/badge/seleniumbase" alt="SeleniumBase PyPI downloads" /></a></p>
1408
1503
 
1409
1504
  <p><div>
1410
- <span><a href="https://www.youtube.com/playlist?list=PLp9uKicxkBc5UIlGi2BuE3aWC7JyXpD3m"><img src="https://seleniumbase.github.io/cdn/img/youtube.png" title="SeleniumBase Playlist on YouTube" alt="SeleniumBase Playlist on YouTube" width="54" /></a></span>
1411
- <span><a href="https://github.com/seleniumbase/SeleniumBase"><img src="https://seleniumbase.github.io/img/social/share_github.svg" title="SeleniumBase on GitHub" alt="SeleniumBase on GitHub" width="50" /></a></span>
1412
- <span><a href="https://gitter.im/seleniumbase/SeleniumBase" target="_blank"><img src="https://seleniumbase.github.io/img/social/share_gitter.svg" title="SeleniumBase on Gitter" alt="SeleniumBase on Gitter" width="38" /></a></span>
1505
+ <span><a href="https://www.youtube.com/playlist?list=PLp9uKicxkBc5UIlGi2BuE3aWC7JyXpD3m"><img src="https://seleniumbase.github.io/cdn/img/youtube.png" title="SeleniumBase Playlist on YouTube" alt="SeleniumBase Playlist on YouTube" width="70" /></a></span>
1506
+ <span><a href="https://github.com/seleniumbase/SeleniumBase"><img src="https://seleniumbase.github.io/img/social/share_github.svg" title="SeleniumBase on GitHub" alt="SeleniumBase on GitHub" width="64" /></a></span>
1507
+ <span><a href="https://gitter.im/seleniumbase/SeleniumBase" target="_blank"><img src="https://seleniumbase.github.io/img/social/share_gitter.svg" title="SeleniumBase on Gitter" alt="SeleniumBase on Gitter" width="52" /></a></span>
1413
1508
  </div></p>
1414
1509
 
1415
1510
  --------
@@ -5,7 +5,7 @@ sbase/steps.py,sha256=RCZ_tKo7kFvgzVrHpIHb090c0on14ObIEkmMHjDURWE,38261
5
5
  seleniumbase/ReadMe.md,sha256=5Bnv8gsyKQGABhLj0S4HXZdtVic98puQlIGYc7YHUm8,3612
6
6
  seleniumbase/__init__.py,sha256=UKfONr7JsfKiXKvqdO5KJ1gMOBzvQ66PHHVAfE636ro,2068
7
7
  seleniumbase/__main__.py,sha256=dn1p6dgCchmcH1zzTzzQvFwwdQQqnTGH6ULV9m4hv24,654
8
- seleniumbase/__version__.py,sha256=L2kkMC09exGZ4qwumjOXpjBO-iJglR13V6qRWvdT858,46
8
+ seleniumbase/__version__.py,sha256=khf_wwYDlYgA5z7wzXQ_hYM8N25HNyGDPdBeAYvOQpk,47
9
9
  seleniumbase/behave/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
10
  seleniumbase/behave/behave_helper.py,sha256=KQ4rgOcWkMFSbD8QBUmevxO47M9UoSDenfoBHy9VaPk,22206
11
11
  seleniumbase/behave/behave_sb.py,sha256=fU8dLa-5Ohb5xVXq9nqVXHeLV4z3RDu5AnDJVvSD60c,54220
@@ -93,11 +93,11 @@ seleniumbase/plugins/basic_test_info.py,sha256=aoNynuw1jWF8LNDhcRQB6aMv7CwKn-gPv
93
93
  seleniumbase/plugins/db_reporting_plugin.py,sha256=DD8F2FIyGGIn2VEDOc_2hPwAcSXblzX57nyH_UFJq20,7281
94
94
  seleniumbase/plugins/driver_manager.py,sha256=gMFQ-bUkh9ENfILGlFyASpeZBhaV9ei9D5KuR1IT2vU,17064
95
95
  seleniumbase/plugins/page_source.py,sha256=woH_gqMCytoOaAbvcF7T2W11AbJzMgAIe3M1YlkJi6U,2056
96
- seleniumbase/plugins/pytest_plugin.py,sha256=j_uFqpTCIH9F_z0g-WpLD3LXjCzNqa9CvD7Hyl9CpbM,90968
96
+ seleniumbase/plugins/pytest_plugin.py,sha256=nxB8F0qUaPCpSnHw08PbMbfhTQ-UjJ9gb-LI2GR1nps,91073
97
97
  seleniumbase/plugins/s3_logging_plugin.py,sha256=jw2_fb0i27Cf6nh8nOCuASEBF3KJZCVbSSJt03lbWMs,1956
98
98
  seleniumbase/plugins/sb_manager.py,sha256=VTOOAMb0R1EwvyvHhecL23yd_5_1X-CFShDKICnqA94,35331
99
99
  seleniumbase/plugins/screen_shots.py,sha256=qZ6M-dC6MZQXVSISZBztOs7qZz2RY06iSPSA-Trv5EI,1138
100
- seleniumbase/plugins/selenium_plugin.py,sha256=TZo4GXTxcscgMP_EMhqRKBL-WdDC8mMb_RkXdkMkTRM,52875
100
+ seleniumbase/plugins/selenium_plugin.py,sha256=0dg-95tejkOdjFBhvUvanOYdkwHE_niYjNCaI4TsKPg,52992
101
101
  seleniumbase/resources/ReadMe.md,sha256=uminnO5_Uv-UZDKcc9a9s9kxisaYUps-H98Fp5PJcaU,2124
102
102
  seleniumbase/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
103
  seleniumbase/resources/favicon.ico,sha256=QPf_YK0QXa_--C4_CH-odh6OTHRQ9k-4O6WcCpXSdwM,1150
@@ -136,9 +136,9 @@ seleniumbase/utilities/selenium_grid/start-grid-hub.sh,sha256=KADv0RUHONLL2_I443
136
136
  seleniumbase/utilities/selenium_ide/ReadMe.md,sha256=hznGeuMpkIimqMiZBW-4goIy2ltW4l8X9kb0YSPUQfE,4483
137
137
  seleniumbase/utilities/selenium_ide/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
138
138
  seleniumbase/utilities/selenium_ide/convert_ide.py,sha256=pZFnqEJQEKZPyNFjkLD29s2HPQgCrWW9XJWpCPhWOoM,31691
139
- seleniumbase-4.15.9.dist-info/LICENSE,sha256=9CweYVs2pqSWEApWewHooJ5p5F44GV0wSXi-jV0kA_U,1085
140
- seleniumbase-4.15.9.dist-info/METADATA,sha256=QDk0ECXpSe3fS9yi94b994RROz-FTq2naYRmsszTVCg,77405
141
- seleniumbase-4.15.9.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
142
- seleniumbase-4.15.9.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
143
- seleniumbase-4.15.9.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
144
- seleniumbase-4.15.9.dist-info/RECORD,,
139
+ seleniumbase-4.15.11.dist-info/LICENSE,sha256=9CweYVs2pqSWEApWewHooJ5p5F44GV0wSXi-jV0kA_U,1085
140
+ seleniumbase-4.15.11.dist-info/METADATA,sha256=SjqCMCfSy-cbfeYUK7hXfY3UTjth3c25TUWorzpu6gQ,81504
141
+ seleniumbase-4.15.11.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
142
+ seleniumbase-4.15.11.dist-info/entry_points.txt,sha256=CNrh2EKNaHYEhO6pP1RJyVLB99LkDDYX7TnUK8xfjqk,623
143
+ seleniumbase-4.15.11.dist-info/top_level.txt,sha256=4N97aBOQ8ETCnDnokBsWb07lJfTaq3C1ZzYRxvLMxqU,19
144
+ seleniumbase-4.15.11.dist-info/RECORD,,