seleniumbase 4.44.2__py3-none-any.whl → 4.45.10__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.
- seleniumbase/__version__.py +1 -1
- seleniumbase/behave/behave_sb.py +14 -0
- seleniumbase/console_scripts/run.py +1 -0
- seleniumbase/console_scripts/sb_install.py +142 -11
- seleniumbase/console_scripts/sb_mkdir.py +76 -0
- seleniumbase/console_scripts/sb_mkrec.py +25 -0
- seleniumbase/console_scripts/sb_recorder.py +40 -3
- seleniumbase/core/browser_launcher.py +279 -117
- seleniumbase/core/detect_b_ver.py +8 -6
- seleniumbase/core/log_helper.py +11 -16
- seleniumbase/core/mysql.py +1 -1
- seleniumbase/core/report_helper.py +3 -7
- seleniumbase/core/sb_cdp.py +275 -78
- seleniumbase/core/sb_driver.py +36 -5
- seleniumbase/core/session_helper.py +2 -4
- seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
- seleniumbase/fixtures/base_case.py +251 -201
- seleniumbase/fixtures/constants.py +1 -0
- seleniumbase/fixtures/js_utils.py +52 -14
- seleniumbase/fixtures/page_actions.py +18 -7
- seleniumbase/fixtures/page_utils.py +4 -2
- seleniumbase/fixtures/shared_utils.py +2 -4
- seleniumbase/masterqa/master_qa.py +16 -2
- seleniumbase/plugins/base_plugin.py +8 -0
- seleniumbase/plugins/driver_manager.py +15 -5
- seleniumbase/plugins/pytest_plugin.py +43 -57
- seleniumbase/plugins/sb_manager.py +23 -19
- seleniumbase/plugins/selenium_plugin.py +20 -13
- seleniumbase/undetected/__init__.py +11 -10
- seleniumbase/undetected/cdp.py +1 -12
- seleniumbase/undetected/cdp_driver/browser.py +330 -128
- seleniumbase/undetected/cdp_driver/cdp_util.py +48 -14
- seleniumbase/undetected/cdp_driver/config.py +78 -11
- seleniumbase/undetected/cdp_driver/connection.py +15 -43
- seleniumbase/undetected/cdp_driver/element.py +37 -22
- seleniumbase/undetected/cdp_driver/tab.py +414 -39
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/METADATA +140 -152
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/RECORD +42 -41
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/licenses/LICENSE +1 -1
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/WHEEL +0 -0
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/entry_points.txt +0 -0
- {seleniumbase-4.44.2.dist-info → seleniumbase-4.45.10.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.45.10
|
|
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
|
|
@@ -33,7 +33,6 @@ Classifier: Operating System :: Microsoft :: Windows
|
|
|
33
33
|
Classifier: Operating System :: POSIX :: Linux
|
|
34
34
|
Classifier: Programming Language :: Python
|
|
35
35
|
Classifier: Programming Language :: Python :: 3
|
|
36
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
37
36
|
Classifier: Programming Language :: Python :: 3.9
|
|
38
37
|
Classifier: Programming Language :: Python :: 3.10
|
|
39
38
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -56,35 +55,28 @@ Classifier: Topic :: Software Development :: Testing
|
|
|
56
55
|
Classifier: Topic :: Software Development :: Testing :: Acceptance
|
|
57
56
|
Classifier: Topic :: Software Development :: Testing :: Traffic Generation
|
|
58
57
|
Classifier: Topic :: Utilities
|
|
59
|
-
Requires-Python: >=3.
|
|
58
|
+
Requires-Python: >=3.9
|
|
60
59
|
Description-Content-Type: text/markdown
|
|
61
60
|
License-File: LICENSE
|
|
62
|
-
Requires-Dist: pip>=25.
|
|
63
|
-
Requires-Dist: pip>=25.3; python_version >= "3.9"
|
|
61
|
+
Requires-Dist: pip>=25.3
|
|
64
62
|
Requires-Dist: packaging>=25.0
|
|
65
63
|
Requires-Dist: setuptools~=70.2; python_version < "3.10"
|
|
66
64
|
Requires-Dist: setuptools>=80.9.0; python_version >= "3.10"
|
|
67
65
|
Requires-Dist: wheel>=0.45.1
|
|
68
|
-
Requires-Dist: attrs
|
|
69
|
-
Requires-Dist:
|
|
70
|
-
Requires-Dist:
|
|
71
|
-
Requires-Dist:
|
|
72
|
-
Requires-Dist:
|
|
73
|
-
Requires-Dist:
|
|
74
|
-
Requires-Dist: filelock~=3.16.1; python_version < "3.9"
|
|
75
|
-
Requires-Dist: filelock~=3.19.1; python_version >= "3.9" and python_version < "3.10"
|
|
76
|
-
Requires-Dist: filelock>=3.20.0; python_version >= "3.10"
|
|
66
|
+
Requires-Dist: attrs>=25.4.0
|
|
67
|
+
Requires-Dist: certifi>=2026.1.4
|
|
68
|
+
Requires-Dist: exceptiongroup>=1.3.1
|
|
69
|
+
Requires-Dist: websockets>=15.0.1
|
|
70
|
+
Requires-Dist: filelock~=3.19.1; python_version < "3.10"
|
|
71
|
+
Requires-Dist: filelock>=3.20.2; python_version >= "3.10"
|
|
77
72
|
Requires-Dist: fasteners>=0.20
|
|
78
|
-
Requires-Dist: mycdp>=1.2
|
|
73
|
+
Requires-Dist: mycdp>=1.3.2
|
|
79
74
|
Requires-Dist: pynose>=1.5.5
|
|
80
|
-
Requires-Dist: platformdirs~=4.
|
|
81
|
-
Requires-Dist: platformdirs
|
|
82
|
-
Requires-Dist:
|
|
83
|
-
Requires-Dist: typing-extensions~=4.13.2; python_version < "3.9"
|
|
84
|
-
Requires-Dist: typing-extensions>=4.15.0; python_version >= "3.9"
|
|
75
|
+
Requires-Dist: platformdirs~=4.4.0; python_version < "3.10"
|
|
76
|
+
Requires-Dist: platformdirs>=4.5.1; python_version >= "3.10"
|
|
77
|
+
Requires-Dist: typing-extensions>=4.15.0
|
|
85
78
|
Requires-Dist: sbvirtualdisplay>=1.4.0
|
|
86
|
-
Requires-Dist: MarkupSafe
|
|
87
|
-
Requires-Dist: MarkupSafe>=3.0.3; python_version >= "3.9"
|
|
79
|
+
Requires-Dist: MarkupSafe>=3.0.3
|
|
88
80
|
Requires-Dist: Jinja2>=3.1.6
|
|
89
81
|
Requires-Dist: six>=1.17.0
|
|
90
82
|
Requires-Dist: parse>=1.20.2
|
|
@@ -94,49 +86,44 @@ Requires-Dist: pyyaml>=6.0.3
|
|
|
94
86
|
Requires-Dist: pygments>=2.19.2
|
|
95
87
|
Requires-Dist: pyreadline3>=3.5.4; platform_system == "Windows"
|
|
96
88
|
Requires-Dist: tabcompleter>=1.4.0
|
|
97
|
-
Requires-Dist: pdbp>=1.8.
|
|
89
|
+
Requires-Dist: pdbp>=1.8.1
|
|
98
90
|
Requires-Dist: idna>=3.11
|
|
99
91
|
Requires-Dist: chardet==5.2.0
|
|
100
92
|
Requires-Dist: charset-normalizer<4,>=3.4.4
|
|
101
93
|
Requires-Dist: urllib3<2,>=1.26.20; python_version < "3.10"
|
|
102
|
-
Requires-Dist: urllib3<
|
|
103
|
-
Requires-Dist: requests
|
|
104
|
-
Requires-Dist: requests~=2.32.5; python_version >= "3.9"
|
|
94
|
+
Requires-Dist: urllib3<3,>=1.26.20; python_version >= "3.10"
|
|
95
|
+
Requires-Dist: requests~=2.32.5
|
|
105
96
|
Requires-Dist: sniffio==1.3.1
|
|
106
97
|
Requires-Dist: h11==0.16.0
|
|
107
98
|
Requires-Dist: outcome==1.3.0.post0
|
|
108
|
-
Requires-Dist: trio
|
|
109
|
-
Requires-Dist: trio<1,>=0.
|
|
99
|
+
Requires-Dist: trio<1,>=0.31.0; python_version < "3.10"
|
|
100
|
+
Requires-Dist: trio<1,>=0.32.0; python_version >= "3.10"
|
|
110
101
|
Requires-Dist: trio-websocket~=0.12.2
|
|
111
|
-
Requires-Dist: wsproto==1.2.0
|
|
112
|
-
Requires-Dist:
|
|
113
|
-
Requires-Dist: websocket-client~=1.9.0
|
|
114
|
-
Requires-Dist: selenium==4.
|
|
115
|
-
Requires-Dist: selenium==4.
|
|
116
|
-
Requires-Dist:
|
|
117
|
-
Requires-Dist:
|
|
118
|
-
Requires-Dist: cssselect==1.3.0; python_version >= "3.9"
|
|
102
|
+
Requires-Dist: wsproto==1.2.0; python_version < "3.10"
|
|
103
|
+
Requires-Dist: wsproto~=1.3.2; python_version >= "3.10"
|
|
104
|
+
Requires-Dist: websocket-client~=1.9.0
|
|
105
|
+
Requires-Dist: selenium==4.32.0; python_version < "3.10"
|
|
106
|
+
Requires-Dist: selenium==4.39.0; python_version >= "3.10"
|
|
107
|
+
Requires-Dist: cssselect==1.3.0
|
|
108
|
+
Requires-Dist: nest-asyncio==1.6.0
|
|
119
109
|
Requires-Dist: sortedcontainers==2.4.0
|
|
120
|
-
Requires-Dist: execnet==2.1.1
|
|
110
|
+
Requires-Dist: execnet==2.1.1; python_version < "3.10"
|
|
111
|
+
Requires-Dist: execnet==2.1.2; python_version >= "3.10"
|
|
121
112
|
Requires-Dist: iniconfig==2.1.0; python_version < "3.10"
|
|
122
113
|
Requires-Dist: iniconfig==2.3.0; python_version >= "3.10"
|
|
123
|
-
Requires-Dist: pluggy==1.
|
|
124
|
-
Requires-Dist:
|
|
125
|
-
Requires-Dist: pytest==
|
|
126
|
-
Requires-Dist: pytest==8.4.2; python_version >= "3.9"
|
|
114
|
+
Requires-Dist: pluggy==1.6.0
|
|
115
|
+
Requires-Dist: pytest==8.4.2; python_version < "3.11"
|
|
116
|
+
Requires-Dist: pytest==9.0.2; python_version >= "3.11"
|
|
127
117
|
Requires-Dist: pytest-html==4.0.2
|
|
128
118
|
Requires-Dist: pytest-metadata==3.1.1
|
|
129
119
|
Requires-Dist: pytest-ordering==0.6
|
|
130
|
-
Requires-Dist: pytest-rerunfailures==
|
|
131
|
-
Requires-Dist: pytest-rerunfailures==16.0.1; python_version >= "3.9" and python_version < "3.10"
|
|
120
|
+
Requires-Dist: pytest-rerunfailures==16.0.1; python_version < "3.10"
|
|
132
121
|
Requires-Dist: pytest-rerunfailures==16.1; python_version >= "3.10"
|
|
133
|
-
Requires-Dist: pytest-xdist==3.
|
|
134
|
-
Requires-Dist: pytest-xdist==3.8.0; python_version >= "3.9"
|
|
122
|
+
Requires-Dist: pytest-xdist==3.8.0
|
|
135
123
|
Requires-Dist: parameterized==0.9.0
|
|
136
124
|
Requires-Dist: behave==1.2.6
|
|
137
|
-
Requires-Dist: soupsieve
|
|
138
|
-
Requires-Dist:
|
|
139
|
-
Requires-Dist: beautifulsoup4~=4.14.2
|
|
125
|
+
Requires-Dist: soupsieve~=2.8.1
|
|
126
|
+
Requires-Dist: beautifulsoup4~=4.14.3
|
|
140
127
|
Requires-Dist: pyotp==2.9.0
|
|
141
128
|
Requires-Dist: python-xlib==0.33; platform_system == "Linux"
|
|
142
129
|
Requires-Dist: PyAutoGUI>=0.9.54; platform_system == "Linux"
|
|
@@ -149,44 +136,36 @@ Requires-Dist: allure-pytest>=2.13.5; extra == "allure"
|
|
|
149
136
|
Requires-Dist: allure-python-commons>=2.13.5; extra == "allure"
|
|
150
137
|
Requires-Dist: allure-behave>=2.13.5; extra == "allure"
|
|
151
138
|
Provides-Extra: coverage
|
|
152
|
-
Requires-Dist: coverage>=7.
|
|
153
|
-
Requires-Dist: coverage>=7.
|
|
154
|
-
Requires-Dist:
|
|
155
|
-
Requires-Dist: pytest-cov>=5.0.0; python_version < "3.9" and extra == "coverage"
|
|
156
|
-
Requires-Dist: pytest-cov>=7.0.0; python_version >= "3.9" and extra == "coverage"
|
|
139
|
+
Requires-Dist: coverage>=7.10.7; python_version < "3.10" and extra == "coverage"
|
|
140
|
+
Requires-Dist: coverage>=7.13.1; python_version >= "3.10" and extra == "coverage"
|
|
141
|
+
Requires-Dist: pytest-cov>=7.0.0; extra == "coverage"
|
|
157
142
|
Provides-Extra: flake8
|
|
158
|
-
Requires-Dist: flake8==
|
|
159
|
-
Requires-Dist: flake8==7.3.0; python_version >= "3.9" and extra == "flake8"
|
|
143
|
+
Requires-Dist: flake8==7.3.0; extra == "flake8"
|
|
160
144
|
Requires-Dist: mccabe==0.7.0; extra == "flake8"
|
|
161
|
-
Requires-Dist: pyflakes==
|
|
162
|
-
Requires-Dist:
|
|
163
|
-
Requires-Dist: pycodestyle==2.9.1; python_version < "3.9" and extra == "flake8"
|
|
164
|
-
Requires-Dist: pycodestyle==2.14.0; python_version >= "3.9" and extra == "flake8"
|
|
145
|
+
Requires-Dist: pyflakes==3.4.0; extra == "flake8"
|
|
146
|
+
Requires-Dist: pycodestyle==2.14.0; extra == "flake8"
|
|
165
147
|
Provides-Extra: ipdb
|
|
166
148
|
Requires-Dist: ipdb==0.13.13; extra == "ipdb"
|
|
167
149
|
Requires-Dist: ipython==7.34.0; extra == "ipdb"
|
|
168
150
|
Provides-Extra: mss
|
|
169
|
-
Requires-Dist: mss==
|
|
170
|
-
Requires-Dist: mss==10.0.0; python_version >= "3.9" and extra == "mss"
|
|
151
|
+
Requires-Dist: mss==10.1.0; extra == "mss"
|
|
171
152
|
Provides-Extra: pdfminer
|
|
172
|
-
Requires-Dist: pdfminer.six==
|
|
173
|
-
Requires-Dist: pdfminer.six==
|
|
174
|
-
Requires-Dist: cryptography==
|
|
175
|
-
Requires-Dist:
|
|
176
|
-
Requires-Dist:
|
|
177
|
-
Requires-Dist: cffi==2.0.0; python_version >= "3.9" and extra == "pdfminer"
|
|
178
|
-
Requires-Dist: pycparser==2.22; python_version < "3.9" and extra == "pdfminer"
|
|
179
|
-
Requires-Dist: pycparser==2.23; python_version >= "3.9" and extra == "pdfminer"
|
|
153
|
+
Requires-Dist: pdfminer.six==20251107; python_version < "3.10" and extra == "pdfminer"
|
|
154
|
+
Requires-Dist: pdfminer.six==20260107; python_version >= "3.10" and extra == "pdfminer"
|
|
155
|
+
Requires-Dist: cryptography==46.0.3; extra == "pdfminer"
|
|
156
|
+
Requires-Dist: cffi==2.0.0; extra == "pdfminer"
|
|
157
|
+
Requires-Dist: pycparser==2.23; extra == "pdfminer"
|
|
180
158
|
Provides-Extra: pillow
|
|
181
|
-
Requires-Dist: Pillow>=
|
|
182
|
-
Requires-Dist: Pillow>=
|
|
183
|
-
Requires-Dist: Pillow>=12.0.0; python_version >= "3.10" and extra == "pillow"
|
|
159
|
+
Requires-Dist: Pillow>=11.3.0; python_version < "3.10" and extra == "pillow"
|
|
160
|
+
Requires-Dist: Pillow>=12.1.0; python_version >= "3.10" and extra == "pillow"
|
|
184
161
|
Provides-Extra: pip-system-certs
|
|
185
162
|
Requires-Dist: pip-system-certs==4.0; platform_system == "Windows" and extra == "pip-system-certs"
|
|
186
163
|
Provides-Extra: proxy
|
|
187
164
|
Requires-Dist: proxy.py==2.4.3; extra == "proxy"
|
|
165
|
+
Provides-Extra: playwright
|
|
166
|
+
Requires-Dist: playwright>=1.56.0; extra == "playwright"
|
|
188
167
|
Provides-Extra: psutil
|
|
189
|
-
Requires-Dist: psutil
|
|
168
|
+
Requires-Dist: psutil>=7.1.3; extra == "psutil"
|
|
190
169
|
Provides-Extra: pyautogui
|
|
191
170
|
Requires-Dist: PyAutoGUI>=0.9.54; platform_system != "Linux" and extra == "pyautogui"
|
|
192
171
|
Provides-Extra: selenium-stealth
|
|
@@ -240,62 +219,62 @@ Dynamic: summary
|
|
|
240
219
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/features_list.md">🏰 Features</a> |
|
|
241
220
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/customizing_test_runs.md">🎛️ Options</a> |
|
|
242
221
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/ReadMe.md">📚 Examples</a> |
|
|
243
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/console_scripts/ReadMe.md"
|
|
222
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/console_scripts/ReadMe.md">🪄 Scripts</a> |
|
|
244
223
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/mobile_testing.md">📱 Mobile</a>
|
|
245
224
|
<br />
|
|
246
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📘
|
|
247
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md"> 🔠
|
|
225
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/method_summary.md">📘 The API</a> |
|
|
226
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md"> 🔠 SyntaxFormats</a> |
|
|
248
227
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md">🔴 Recorder</a> |
|
|
249
228
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/example_logs/ReadMe.md">📊 Dashboard</a> |
|
|
250
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/locale_codes.md">🗾
|
|
251
|
-
<a href="https://seleniumbase.io/devices/?url=seleniumbase.com">💻 Farm</a>
|
|
229
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/locale_codes.md">🗾 Locale</a>
|
|
252
230
|
<br />
|
|
253
231
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/commander.md">🎖️ GUI</a> |
|
|
254
232
|
<a href="https://seleniumbase.io/demo_page">📰 TestPage</a> |
|
|
255
233
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md">👤 UC Mode</a> |
|
|
256
234
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md">🐙 CDP Mode</a> |
|
|
257
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/chart_maker/ReadMe.md">📶 Charts</a>
|
|
258
|
-
<a href="https://
|
|
235
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/chart_maker/ReadMe.md">📶 Charts</a> |
|
|
236
|
+
<a href="https://seleniumbase.io/devices/?url=seleniumbase.com">🖥️ Farm</a>
|
|
259
237
|
<br />
|
|
260
238
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/how_it_works.md">👁️ How</a> |
|
|
261
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples/migration/raw_selenium">🚝
|
|
262
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/
|
|
263
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/
|
|
264
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md">🧬 Hybrid</a> |
|
|
239
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/tree/master/examples/migration/raw_selenium">🚝 Migration</a> |
|
|
240
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/playwright/ReadMe.md">🎭 Stealthy Playwright</a> |
|
|
241
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/master_qa/ReadMe.md">🛂 MasterQA</a> |
|
|
265
242
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/tour_examples/ReadMe.md">🚎 Tours</a>
|
|
266
243
|
<br />
|
|
267
244
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/integrations/github/workflows/ReadMe.md">🤖 CI/CD</a> |
|
|
268
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/js_package_manager.md"
|
|
245
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/js_package_manager.md">❇️ JSMgr</a> |
|
|
269
246
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/translations.md">🌏 Translator</a> |
|
|
270
247
|
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/presenter/ReadMe.md">🎞️ Presenter</a> |
|
|
271
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/
|
|
272
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/
|
|
248
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/visual_testing/ReadMe.md">🖼️ Visual</a> |
|
|
249
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/case_plans.md">🗂️ CPlans</a>
|
|
273
250
|
<br />
|
|
274
251
|
</p>
|
|
275
252
|
|
|
276
|
-
<p>SeleniumBase is a browser automation framework
|
|
253
|
+
<p>SeleniumBase is a browser automation framework that empowers software teams to innovate faster and handle modern web challenges with ease. With stealth options like CDP Mode, you'll avoid the usual restrictions imposed by websites deploying bot-detection services.</p>
|
|
277
254
|
|
|
278
255
|
--------
|
|
279
256
|
|
|
280
257
|
📚 Learn from [**over 200 examples** in the **SeleniumBase/examples/** folder](https://github.com/seleniumbase/SeleniumBase/tree/master/examples).
|
|
281
258
|
|
|
282
|
-
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a>
|
|
259
|
+
🐙 Stealth modes: <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/uc_mode.md"><b>UC Mode</b></a> and <a translate="no" href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/ReadMe.md"><b>CDP Mode</b></a> can bypass bot-detection, solve CAPTCHAs, and call advanced methods from the <a href="https://chromedevtools.github.io/devtools-protocol/" translate="no">Chrome Devtools Protocol</a>.
|
|
283
260
|
|
|
284
|
-
ℹ️
|
|
261
|
+
ℹ️ Many examples run with raw <code translate="no"><b>python</b></code>, although some use <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/syntax_formats.md">Syntax Formats</a> that expect <a href="https://docs.pytest.org/en/latest/how-to/usage.html" translate="no"><b>pytest</b></a> (a Python unit-testing framework included with SeleniumBase that can discover, collect, and run tests automatically).
|
|
285
262
|
|
|
286
263
|
--------
|
|
287
264
|
|
|
288
|
-
<p align="left">📗
|
|
265
|
+
<p align="left">📗 This script performs a Google Search using SeleniumBase UC Mode + CDP Mode:<br /><a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">SeleniumBase/examples/raw_google.py</a> (Results are saved as PDF, HTML, and PNG)</p>
|
|
289
266
|
|
|
290
267
|
```python
|
|
291
268
|
from seleniumbase import SB
|
|
292
269
|
|
|
293
|
-
with SB(
|
|
294
|
-
|
|
270
|
+
with SB(uc=True, test=True) as sb:
|
|
271
|
+
url = "https://google.com/ncr"
|
|
272
|
+
sb.activate_cdp_mode(url)
|
|
295
273
|
sb.type('[title="Search"]', "SeleniumBase GitHub page")
|
|
296
274
|
sb.click("div:not([jsname]) > * > input")
|
|
275
|
+
sb.sleep(2)
|
|
297
276
|
print(sb.get_page_title())
|
|
298
|
-
sb.sleep(
|
|
277
|
+
sb.sleep(1) # Wait for the "AI Overview" result
|
|
299
278
|
if sb.is_text_visible("Generating"):
|
|
300
279
|
sb.wait_for_text("AI Overview")
|
|
301
280
|
sb.save_as_pdf_to_logs() # Saved to ./latest_logs/
|
|
@@ -317,8 +296,8 @@ from seleniumbase import SB
|
|
|
317
296
|
with SB(uc=True, test=True, locale="en") as sb:
|
|
318
297
|
url = "https://gitlab.com/users/sign_in"
|
|
319
298
|
sb.activate_cdp_mode(url)
|
|
320
|
-
sb.sleep(2
|
|
321
|
-
sb.
|
|
299
|
+
sb.sleep(2)
|
|
300
|
+
sb.solve_captcha()
|
|
322
301
|
# (The rest is for testing and demo purposes)
|
|
323
302
|
sb.assert_text("Username", '[for="user_login"]', timeout=3)
|
|
324
303
|
sb.assert_element('label[for="user_login"]')
|
|
@@ -335,9 +314,9 @@ with SB(uc=True, test=True, locale="en") as sb:
|
|
|
335
314
|
from seleniumbase import sb_cdp
|
|
336
315
|
|
|
337
316
|
url = "https://gitlab.com/users/sign_in"
|
|
338
|
-
sb = sb_cdp.Chrome(url)
|
|
339
|
-
sb.sleep(2
|
|
340
|
-
sb.
|
|
317
|
+
sb = sb_cdp.Chrome(url, incognito=True)
|
|
318
|
+
sb.sleep(2)
|
|
319
|
+
sb.solve_captcha()
|
|
341
320
|
sb.highlight('h1:contains("GitLab")')
|
|
342
321
|
sb.highlight('button:contains("Sign in")')
|
|
343
322
|
sb.driver.stop()
|
|
@@ -373,7 +352,7 @@ class MyTestClass(BaseCase):
|
|
|
373
352
|
|
|
374
353
|
<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" title="SeleniumBase Test" width="480" /></a>
|
|
375
354
|
|
|
376
|
-
> (The default browser is
|
|
355
|
+
> (The default browser is `--chrome` if not set.)
|
|
377
356
|
|
|
378
357
|
--------
|
|
379
358
|
|
|
@@ -537,18 +516,18 @@ finally:
|
|
|
537
516
|
<a id="install_seleniumbase"></a>
|
|
538
517
|
<h2><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Install SeleniumBase:</h2>
|
|
539
518
|
|
|
540
|
-
**You can install
|
|
519
|
+
**You can install `seleniumbase` from [PyPI](https://pypi.org/project/seleniumbase/) or [GitHub](https://github.com/seleniumbase/SeleniumBase):**
|
|
541
520
|
|
|
542
|
-
🔵 **How to install
|
|
521
|
+
🔵 **How to install `seleniumbase` from PyPI:**
|
|
543
522
|
|
|
544
523
|
```zsh
|
|
545
524
|
pip install seleniumbase
|
|
546
525
|
```
|
|
547
526
|
|
|
548
|
-
* (Add
|
|
549
|
-
* (Add
|
|
527
|
+
* (Add `--upgrade` OR `-U` to upgrade SeleniumBase.)
|
|
528
|
+
* (Add `--force-reinstall` to upgrade indirect packages.)
|
|
550
529
|
|
|
551
|
-
🔵 **How to install
|
|
530
|
+
🔵 **How to install `seleniumbase` from a GitHub clone:**
|
|
552
531
|
|
|
553
532
|
```zsh
|
|
554
533
|
git clone https://github.com/seleniumbase/SeleniumBase.git
|
|
@@ -563,7 +542,7 @@ git pull
|
|
|
563
542
|
pip install -e .
|
|
564
543
|
```
|
|
565
544
|
|
|
566
|
-
🔵 **Type
|
|
545
|
+
🔵 **Type `seleniumbase` or `sbase` to verify that SeleniumBase was installed successfully:**
|
|
567
546
|
|
|
568
547
|
```zsh
|
|
569
548
|
___ _ _ ___
|
|
@@ -613,7 +592,7 @@ pip install -e .
|
|
|
613
592
|
|
|
614
593
|
<h3>🔵 Downloading webdrivers:</h3>
|
|
615
594
|
|
|
616
|
-
✅ SeleniumBase automatically downloads webdrivers as needed, such as
|
|
595
|
+
✅ SeleniumBase automatically downloads webdrivers as needed, such as `chromedriver`.
|
|
617
596
|
|
|
618
597
|
<div></div>
|
|
619
598
|
<details>
|
|
@@ -746,7 +725,7 @@ self.assert_no_js_errors() # Verify there are no JS errors.
|
|
|
746
725
|
self.type("input", "dogs\n") # (The "\n" presses ENTER)
|
|
747
726
|
```
|
|
748
727
|
|
|
749
|
-
Most SeleniumBase scripts can be run with <code translate="no">pytest</code>, <code translate="no">pynose</code>, or pure <code translate="no">python</code>. Not all test runners can run all test formats. For example, tests that use the
|
|
728
|
+
Most SeleniumBase scripts can be run with <code translate="no">pytest</code>, <code translate="no">pynose</code>, or pure <code translate="no">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>.
|
|
750
729
|
|
|
751
730
|
```zsh
|
|
752
731
|
pytest coffee_cart_tests.py --rs
|
|
@@ -765,10 +744,10 @@ behave calculator.feature -D rs -D dashboard
|
|
|
765
744
|
|
|
766
745
|
<p>✅ <code translate="no">pytest</code> includes automatic test discovery. If you don't specify a specific file or folder to run, <code translate="no">pytest</code> will automatically search through all subdirectories for tests to run based on the following criteria:</p>
|
|
767
746
|
|
|
768
|
-
* Python files that start with
|
|
769
|
-
* Python methods that start with
|
|
747
|
+
* Python files that start with `test_` or end with `_test.py`.
|
|
748
|
+
* Python methods that start with `test_`.
|
|
770
749
|
|
|
771
|
-
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
|
|
750
|
+
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.
|
|
772
751
|
|
|
773
752
|
<p>✅ You can do a pre-flight check to see which tests would get discovered by <code translate="no">pytest</code> before the actual run:</p>
|
|
774
753
|
|
|
@@ -810,7 +789,7 @@ pynose [FILE_NAME.py]:[CLASS_NAME].[METHOD_NAME]
|
|
|
810
789
|
pytest my_first_test.py --demo
|
|
811
790
|
```
|
|
812
791
|
|
|
813
|
-
🔵
|
|
792
|
+
🔵 `time.sleep(seconds)` can be used to make a test wait at a specific spot:
|
|
814
793
|
|
|
815
794
|
```python
|
|
816
795
|
import time; time.sleep(3) # Do nothing for 3 seconds.
|
|
@@ -824,15 +803,15 @@ import pytest; pytest.set_trace()
|
|
|
824
803
|
breakpoint() # Shortcut for "import pdb; pdb.set_trace()"
|
|
825
804
|
```
|
|
826
805
|
|
|
827
|
-
> (
|
|
806
|
+
> (**`pdb`** commands: `n`, `c`, `s`, `u`, `d` => `next`, `continue`, `step`, `up`, `down`)
|
|
828
807
|
|
|
829
|
-
🔵 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
|
|
808
|
+
🔵 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:
|
|
830
809
|
|
|
831
810
|
```zsh
|
|
832
811
|
pytest test_fail.py --pdb
|
|
833
812
|
```
|
|
834
813
|
|
|
835
|
-
🔵 To start tests in Debug Mode, add
|
|
814
|
+
🔵 To start tests in Debug Mode, add **`--trace`** as a `pytest` option:
|
|
836
815
|
|
|
837
816
|
```zsh
|
|
838
817
|
pytest test_coffee_cart.py --trace
|
|
@@ -977,7 +956,7 @@ pytest test_coffee_cart.py --trace
|
|
|
977
956
|
|
|
978
957
|
--------
|
|
979
958
|
|
|
980
|
-
🔵 During test failures, logs and screenshots from the most recent test run will get saved to the
|
|
959
|
+
🔵 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.
|
|
981
960
|
|
|
982
961
|
```zsh
|
|
983
962
|
cd examples/
|
|
@@ -989,18 +968,18 @@ pytest test_suite.py --firefox
|
|
|
989
968
|
|
|
990
969
|
An easy way to override seleniumbase/config/settings.py is by using a custom settings file.
|
|
991
970
|
Here's the command-line option to add to tests: (See [examples/custom_settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/custom_settings.py))
|
|
992
|
-
|
|
971
|
+
`--settings_file=custom_settings.py`
|
|
993
972
|
(Settings include default timeout values, a two-factor auth key, DB credentials, S3 credentials, and other important settings used by tests.)
|
|
994
973
|
|
|
995
|
-
🔵 To pass additional data from the command-line to tests, add
|
|
996
|
-
Inside your tests, you can use
|
|
974
|
+
🔵 To pass additional data from the command-line to tests, add `--data="ANY STRING"`.
|
|
975
|
+
Inside your tests, you can use `self.data` to access that.
|
|
997
976
|
|
|
998
977
|
<a id="directory_configuration"></a>
|
|
999
978
|
<h2><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Directory Configuration:</h2>
|
|
1000
979
|
|
|
1001
|
-
🔵 When running tests with
|
|
980
|
+
🔵 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. Test folders should also include a blank **[__init__.py](https://github.com/seleniumbase/SeleniumBase/blob/master/examples/offline_examples/__init__.py)** file to allow your test files to import other files from that folder.
|
|
1002
981
|
|
|
1003
|
-
🔵
|
|
982
|
+
🔵 `sbase mkdir DIR` creates a folder with config files and sample tests:
|
|
1004
983
|
|
|
1005
984
|
```zsh
|
|
1006
985
|
sbase mkdir ui_tests
|
|
@@ -1032,7 +1011,7 @@ ui_tests/
|
|
|
1032
1011
|
└── swag_labs_test.py
|
|
1033
1012
|
```
|
|
1034
1013
|
|
|
1035
|
-
<b>ProTip™:</b> You can also create a boilerplate folder without any sample tests in it by adding
|
|
1014
|
+
<b>ProTip™:</b> You can also create a boilerplate folder without any sample tests in it by adding `-b` or `--basic` to the `sbase mkdir` command:
|
|
1036
1015
|
|
|
1037
1016
|
```zsh
|
|
1038
1017
|
sbase mkdir ui_tests --basic
|
|
@@ -1048,7 +1027,16 @@ ui_tests/
|
|
|
1048
1027
|
└── setup.cfg
|
|
1049
1028
|
```
|
|
1050
1029
|
|
|
1051
|
-
Of those files, the
|
|
1030
|
+
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).
|
|
1031
|
+
|
|
1032
|
+
<b>ProTip™:</b> Add `--gha` to include a GitHub Actions `.yml` file with default settings:
|
|
1033
|
+
|
|
1034
|
+
```zsh
|
|
1035
|
+
ui_tests/
|
|
1036
|
+
└── .github
|
|
1037
|
+
└── workflows/
|
|
1038
|
+
└── python-package.yml
|
|
1039
|
+
```
|
|
1052
1040
|
|
|
1053
1041
|
--------
|
|
1054
1042
|
|
|
@@ -1068,20 +1056,20 @@ class MyTestClass(BaseCase):
|
|
|
1068
1056
|
self.assert_element("div#ARMY_OF_ROBOTS", timeout=1) # This should fail
|
|
1069
1057
|
```
|
|
1070
1058
|
|
|
1071
|
-
You can run it from the
|
|
1059
|
+
You can run it from the `examples/` folder like this:
|
|
1072
1060
|
|
|
1073
1061
|
```zsh
|
|
1074
1062
|
pytest test_fail.py
|
|
1075
1063
|
```
|
|
1076
1064
|
|
|
1077
|
-
🔵 You'll notice that a logs folder,
|
|
1065
|
+
🔵 You'll notice that a logs folder, `./latest_logs/`, was created to hold information (and screenshots) about the failing test. During test runs, past results get moved to the archived_logs folder if you have ARCHIVE_EXISTING_LOGS set to True in [settings.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/settings.py), or if your run tests with `--archive-logs`. If you choose not to archive existing logs, they will be deleted and replaced by the logs of the latest test run.
|
|
1078
1066
|
|
|
1079
1067
|
--------
|
|
1080
1068
|
|
|
1081
1069
|
<a id="seleniumbase_dashboard"></a>
|
|
1082
1070
|
<h2><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> SeleniumBase Dashboard:</h2>
|
|
1083
1071
|
|
|
1084
|
-
🔵 The
|
|
1072
|
+
🔵 The `--dashboard` option for pytest generates a SeleniumBase Dashboard located at `dashboard.html`, which updates automatically as tests run and produce results. Example:
|
|
1085
1073
|
|
|
1086
1074
|
```zsh
|
|
1087
1075
|
pytest --dashboard --rs --headless
|
|
@@ -1089,13 +1077,13 @@ pytest --dashboard --rs --headless
|
|
|
1089
1077
|
|
|
1090
1078
|
<img src="https://seleniumbase.github.io/cdn/img/dashboard_1.png" alt="The SeleniumBase Dashboard" title="The SeleniumBase Dashboard" width="380" />
|
|
1091
1079
|
|
|
1092
|
-
🔵 Additionally, you can host your own SeleniumBase Dashboard Server on a port of your choice. Here's an example of that using Python's
|
|
1080
|
+
🔵 Additionally, you can host your own SeleniumBase Dashboard Server on a port of your choice. Here's an example of that using Python's `http.server`:
|
|
1093
1081
|
|
|
1094
1082
|
```zsh
|
|
1095
1083
|
python -m http.server 1948
|
|
1096
1084
|
```
|
|
1097
1085
|
|
|
1098
|
-
🔵 Now you can navigate to
|
|
1086
|
+
🔵 Now you can navigate to `http://localhost:1948/dashboard.html` in order to view the dashboard as a web app. This requires two different terminal windows: one for running the server, and another for running the tests, which should be run from the same directory. (Use <kbd>Ctrl+C</kbd> to stop the http server.)
|
|
1099
1087
|
|
|
1100
1088
|
🔵 Here's a full example of what the SeleniumBase Dashboard may look like:
|
|
1101
1089
|
|
|
@@ -1112,7 +1100,7 @@ pytest test_suite.py test_image_saving.py --dashboard --rs --headless
|
|
|
1112
1100
|
|
|
1113
1101
|
<h3>🔵 <code>pytest</code> HTML Reports:</h3>
|
|
1114
1102
|
|
|
1115
|
-
✅ Using
|
|
1103
|
+
✅ Using `--html=report.html` gives you a fancy report of the name specified after your test suite completes.
|
|
1116
1104
|
|
|
1117
1105
|
```zsh
|
|
1118
1106
|
pytest test_suite.py --html=report.html
|
|
@@ -1120,7 +1108,7 @@ pytest test_suite.py --html=report.html
|
|
|
1120
1108
|
|
|
1121
1109
|
<img src="https://seleniumbase.github.io/cdn/img/html_report.png" alt="Example Pytest Report" title="Example Pytest Report" width="520" />
|
|
1122
1110
|
|
|
1123
|
-
✅ 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:
|
|
1111
|
+
✅ 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.
|
|
1124
1112
|
|
|
1125
1113
|
✅ Here's an example of an upgraded html report:
|
|
1126
1114
|
|
|
@@ -1132,7 +1120,7 @@ pytest test_suite.py --dashboard --html=report.html
|
|
|
1132
1120
|
|
|
1133
1121
|
If viewing pytest html reports in [Jenkins](https://www.jenkins.io/), you may need to [configure Jenkins settings](https://stackoverflow.com/a/46197356/7058266) for the html to render correctly. This is due to [Jenkins CSP changes](https://www.jenkins.io/doc/book/system-administration/security/configuring-content-security-policy/).
|
|
1134
1122
|
|
|
1135
|
-
You can also use
|
|
1123
|
+
You can also use `--junit-xml=report.xml` to get an xml report instead. Jenkins can use this file to display better reporting for your tests.
|
|
1136
1124
|
|
|
1137
1125
|
```zsh
|
|
1138
1126
|
pytest test_suite.py --junit-xml=report.xml
|
|
@@ -1140,7 +1128,7 @@ pytest test_suite.py --junit-xml=report.xml
|
|
|
1140
1128
|
|
|
1141
1129
|
<h3>🔵 <code>pynose</code> Reports:</h3>
|
|
1142
1130
|
|
|
1143
|
-
The
|
|
1131
|
+
The `--report` option gives you a fancy report after your test suite completes.
|
|
1144
1132
|
|
|
1145
1133
|
```zsh
|
|
1146
1134
|
pynose test_suite.py --report
|
|
@@ -1148,7 +1136,7 @@ pynose test_suite.py --report
|
|
|
1148
1136
|
|
|
1149
1137
|
<img src="https://seleniumbase.github.io/cdn/img/nose_report.png" alt="Example pynose Report" title="Example pynose Report" width="320" />
|
|
1150
1138
|
|
|
1151
|
-
(NOTE: You can add
|
|
1139
|
+
(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.)
|
|
1152
1140
|
|
|
1153
1141
|
<h3>🔵 <code>behave</code> Dashboard & Reports:</h3>
|
|
1154
1142
|
|
|
@@ -1160,7 +1148,7 @@ behave behave_bdd/features/ -D dashboard -D headless
|
|
|
1160
1148
|
|
|
1161
1149
|
<img src="https://seleniumbase.github.io/cdn/img/sb_behave_dashboard.png" title="SeleniumBase" width="520">
|
|
1162
1150
|
|
|
1163
|
-
You can also use
|
|
1151
|
+
You can also use `--junit` to get `.xml` reports for each <code translate="no">behave</code> feature. Jenkins can use these files to display better reporting for your tests.
|
|
1164
1152
|
|
|
1165
1153
|
```zsh
|
|
1166
1154
|
behave behave_bdd/features/ --junit -D rs -D headless
|
|
@@ -1170,7 +1158,7 @@ behave behave_bdd/features/ --junit -D rs -D headless
|
|
|
1170
1158
|
|
|
1171
1159
|
See: [https://allurereport.org/docs/pytest/](https://allurereport.org/docs/pytest/)
|
|
1172
1160
|
|
|
1173
|
-
SeleniumBase no longer includes
|
|
1161
|
+
SeleniumBase no longer includes `allure-pytest` as part of installed dependencies. If you want to use it, install it first:
|
|
1174
1162
|
|
|
1175
1163
|
```zsh
|
|
1176
1164
|
pip install allure-pytest
|
|
@@ -1186,7 +1174,7 @@ pytest test_suite.py --alluredir=allure_results
|
|
|
1186
1174
|
|
|
1187
1175
|
<h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Using a Proxy Server:</h3>
|
|
1188
1176
|
|
|
1189
|
-
If you wish to use a proxy server for your browser tests (Chromium or Firefox), you can add
|
|
1177
|
+
If you wish to use a proxy server for your browser tests (Chromium or Firefox), you can add `--proxy=IP_ADDRESS:PORT` as an argument on the command line.
|
|
1190
1178
|
|
|
1191
1179
|
```zsh
|
|
1192
1180
|
pytest proxy_test.py --proxy=IP_ADDRESS:PORT
|
|
@@ -1206,7 +1194,7 @@ pytest proxy_test.py --proxy="socks4://IP_ADDRESS:PORT"
|
|
|
1206
1194
|
pytest proxy_test.py --proxy="socks5://IP_ADDRESS:PORT"
|
|
1207
1195
|
```
|
|
1208
1196
|
|
|
1209
|
-
To make things easier, you can add your frequently-used proxies to PROXY_LIST in [proxy_list.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/proxy_list.py), and then use
|
|
1197
|
+
To make things easier, you can add your frequently-used proxies to PROXY_LIST in [proxy_list.py](https://github.com/seleniumbase/SeleniumBase/blob/master/seleniumbase/config/proxy_list.py), and then use `--proxy=KEY_FROM_PROXY_LIST` to use the IP_ADDRESS:PORT of that key.
|
|
1210
1198
|
|
|
1211
1199
|
```zsh
|
|
1212
1200
|
pytest proxy_test.py --proxy=proxy1
|
|
@@ -1215,7 +1203,7 @@ pytest proxy_test.py --proxy=proxy1
|
|
|
1215
1203
|
|
|
1216
1204
|
<h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Changing the User-Agent:</h3>
|
|
1217
1205
|
|
|
1218
|
-
🔵 If you wish to change the User-Agent for your browser tests (Chromium and Firefox only), you can add
|
|
1206
|
+
🔵 If you wish to change the User-Agent for your browser tests (Chromium and Firefox only), you can add `--agent="USER AGENT STRING"` as an argument on the command-line.
|
|
1219
1207
|
|
|
1220
1208
|
```zsh
|
|
1221
1209
|
pytest user_agent_test.py --agent="Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1.7412.EU"
|
|
@@ -1229,7 +1217,7 @@ pytest user_agent_test.py --agent="Mozilla/5.0 (Nintendo 3DS; U; ; en) Version/1
|
|
|
1229
1217
|
|
|
1230
1218
|
<h3><img src="https://seleniumbase.github.io/img/logo7.png" title="SeleniumBase" width="32" /> Building Guided Tours for Websites:</h3>
|
|
1231
1219
|
|
|
1232
|
-
🔵 Learn about <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/tour_examples/ReadMe.md">SeleniumBase Interactive Walkthroughs</a> (in the
|
|
1220
|
+
🔵 Learn about <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/tour_examples/ReadMe.md">SeleniumBase Interactive Walkthroughs</a> (in the `examples/tour_examples/` folder). It's great for prototyping a website onboarding experience.
|
|
1233
1221
|
|
|
1234
1222
|
|
|
1235
1223
|
<a id="utilizing_advanced_features"></a>
|
|
@@ -1298,7 +1286,7 @@ To click an element on the page:
|
|
|
1298
1286
|
self.click("div#my_id")
|
|
1299
1287
|
```
|
|
1300
1288
|
|
|
1301
|
-
**ProTip™:** In most web browsers, you can right-click on a page and select
|
|
1289
|
+
**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.
|
|
1302
1290
|
|
|
1303
1291
|
🔵 **Typing Text:**
|
|
1304
1292
|
|
|
@@ -1328,7 +1316,7 @@ attribute = self.get_attribute("#comic img", "title")
|
|
|
1328
1316
|
self.wait_for_element_present("div.my_class", timeout=10)
|
|
1329
1317
|
```
|
|
1330
1318
|
|
|
1331
|
-
(NOTE: You can also use:
|
|
1319
|
+
(NOTE: You can also use: `self.assert_element_present(ELEMENT)`)
|
|
1332
1320
|
|
|
1333
1321
|
🔵 **Asserting visibility of an element on a page within some number of seconds:**
|
|
1334
1322
|
|
|
@@ -1336,9 +1324,9 @@ self.wait_for_element_present("div.my_class", timeout=10)
|
|
|
1336
1324
|
self.wait_for_element_visible("a.my_class", timeout=5)
|
|
1337
1325
|
```
|
|
1338
1326
|
|
|
1339
|
-
(NOTE: The short versions of that are
|
|
1327
|
+
(NOTE: The short versions of that are `self.find_element(ELEMENT)` and `self.assert_element(ELEMENT)`. The `find_element()` version returns the element.)
|
|
1340
1328
|
|
|
1341
|
-
Since the line above returns the element, you can combine that with
|
|
1329
|
+
Since the line above returns the element, you can combine that with `.click()` as shown below:
|
|
1342
1330
|
|
|
1343
1331
|
```python
|
|
1344
1332
|
self.find_element("a.my_class", timeout=5).click()
|
|
@@ -1348,9 +1336,9 @@ self.find_element("a.my_class", timeout=5).click()
|
|
|
1348
1336
|
self.click("a.my_class") # DO IT THIS WAY!
|
|
1349
1337
|
```
|
|
1350
1338
|
|
|
1351
|
-
**ProTip™:** You can use dots to signify class names (Ex:
|
|
1339
|
+
**ProTip™:** You can use dots to signify class names (Ex: `div.class_name`) as a simplified version of `div[class="class_name"]` within a CSS selector.
|
|
1352
1340
|
|
|
1353
|
-
You can also use
|
|
1341
|
+
You can also use `*=` to search for any partial value in a CSS selector as shown below:
|
|
1354
1342
|
|
|
1355
1343
|
```python
|
|
1356
1344
|
self.click('a[name*="partial_name"]')
|
|
@@ -1363,7 +1351,7 @@ self.assert_text("Make it so!", "div#trek div.picard div.quotes")
|
|
|
1363
1351
|
self.assert_text("Tea. Earl Grey. Hot.", "div#trek div.picard div.quotes", timeout=3)
|
|
1364
1352
|
```
|
|
1365
1353
|
|
|
1366
|
-
(NOTE:
|
|
1354
|
+
(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.)
|
|
1367
1355
|
|
|
1368
1356
|
🔵 **Asserting Anything:**
|
|
1369
1357
|
|
|
@@ -1377,14 +1365,14 @@ self.assert_equal(var1, var2)
|
|
|
1377
1365
|
|
|
1378
1366
|
🔵 **Useful Conditional Statements: (with creative examples)**
|
|
1379
1367
|
|
|
1380
|
-
❓
|
|
1368
|
+
❓ `is_element_visible(selector):` (visible on the page)
|
|
1381
1369
|
|
|
1382
1370
|
```python
|
|
1383
1371
|
if self.is_element_visible('div#warning'):
|
|
1384
1372
|
print("Red Alert: Something bad might be happening!")
|
|
1385
1373
|
```
|
|
1386
1374
|
|
|
1387
|
-
❓
|
|
1375
|
+
❓ `is_element_present(selector):` (present in the HTML)
|
|
1388
1376
|
|
|
1389
1377
|
```python
|
|
1390
1378
|
if self.is_element_present('div#top_secret img.tracking_cookie'):
|
|
@@ -1401,7 +1389,7 @@ def is_there_a_cloaked_klingon_ship_on_this_page():
|
|
|
1401
1389
|
return False
|
|
1402
1390
|
```
|
|
1403
1391
|
|
|
1404
|
-
❓
|
|
1392
|
+
❓ `is_text_visible(text, selector):` (text visible on element)
|
|
1405
1393
|
|
|
1406
1394
|
```python
|
|
1407
1395
|
if self.is_text_visible("You Shall Not Pass!", "h1"):
|
|
@@ -1441,7 +1429,7 @@ def get_mirror_universe_captain_picard_superbowl_ad(superbowl_year):
|
|
|
1441
1429
|
|
|
1442
1430
|
</details>
|
|
1443
1431
|
|
|
1444
|
-
❓
|
|
1432
|
+
❓ `is_link_text_visible(link_text):`
|
|
1445
1433
|
|
|
1446
1434
|
```python
|
|
1447
1435
|
if self.is_link_text_visible("Stop! Hammer time!"):
|
|
@@ -1466,7 +1454,7 @@ self.switch_to_frame("iframe")
|
|
|
1466
1454
|
self.switch_to_parent_frame() # Exit the current iframe
|
|
1467
1455
|
```
|
|
1468
1456
|
|
|
1469
|
-
To exit from multiple iframes, use
|
|
1457
|
+
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()`.)
|
|
1470
1458
|
|
|
1471
1459
|
```python
|
|
1472
1460
|
self.switch_to_frame('iframe[name="frame1"]')
|
|
@@ -1539,7 +1527,7 @@ self.execute_script("return jQuery('textarea')[2].value") # Returns the css "va
|
|
|
1539
1527
|
|
|
1540
1528
|
<h3>🔵 How to handle a restrictive CSP:</h3>
|
|
1541
1529
|
|
|
1542
|
-
❗ 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 those websites, add
|
|
1530
|
+
❗ 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 those websites, add `--disable-csp` as a `pytest` command-line option to load a Chromium extension that bypasses the CSP.
|
|
1543
1531
|
|
|
1544
1532
|
<h3>🔵 More JavaScript fun:</h3>
|
|
1545
1533
|
|