seleniumbase 4.41.6__tar.gz → 4.41.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {seleniumbase-4.41.6/seleniumbase.egg-info → seleniumbase-4.41.8}/PKG-INFO +39 -14
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/README.md +36 -11
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/sbase/steps.py +9 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/behave/behave_helper.py +2 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/common/decorators.py +3 -1
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/browser_launcher.py +2 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/recorder_helper.py +3 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/sb_cdp.py +10 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/base_case.py +50 -1
- {seleniumbase-4.41.6 → seleniumbase-4.41.8/seleniumbase.egg-info}/PKG-INFO +39 -14
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase.egg-info/requires.txt +2 -2
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/setup.py +2 -2
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/.gitignore +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/LICENSE +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/MANIFEST.in +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/install.sh +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/pyproject.toml +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/pytest.ini +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/requirements.txt +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/sbase/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/sbase/__main__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/page_actions.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/pytest_plugin.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/sb_manager.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/tab.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/setup.cfg +0 -0
- {seleniumbase-4.41.6 → seleniumbase-4.41.8}/virtualenv_install.sh +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: seleniumbase
|
3
|
-
Version: 4.41.
|
3
|
+
Version: 4.41.8
|
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
|
@@ -164,7 +164,7 @@ Provides-Extra: pdfminer
|
|
164
164
|
Requires-Dist: pdfminer.six==20250324; python_version < "3.9" and extra == "pdfminer"
|
165
165
|
Requires-Dist: pdfminer.six==20250506; python_version >= "3.9" and extra == "pdfminer"
|
166
166
|
Requires-Dist: cryptography==39.0.2; python_version < "3.9" and extra == "pdfminer"
|
167
|
-
Requires-Dist: cryptography==
|
167
|
+
Requires-Dist: cryptography==46.0.1; python_version >= "3.9" and extra == "pdfminer"
|
168
168
|
Requires-Dist: cffi==1.17.1; python_version < "3.9" and extra == "pdfminer"
|
169
169
|
Requires-Dist: cffi==2.0.0; python_version >= "3.9" and extra == "pdfminer"
|
170
170
|
Requires-Dist: pycparser==2.22; python_version < "3.9" and extra == "pdfminer"
|
@@ -177,7 +177,7 @@ Requires-Dist: pip-system-certs==4.0; platform_system == "Windows" and extra ==
|
|
177
177
|
Provides-Extra: proxy
|
178
178
|
Requires-Dist: proxy.py==2.4.3; extra == "proxy"
|
179
179
|
Provides-Extra: psutil
|
180
|
-
Requires-Dist: psutil==7.
|
180
|
+
Requires-Dist: psutil==7.1.0; extra == "psutil"
|
181
181
|
Provides-Extra: pyautogui
|
182
182
|
Requires-Dist: PyAutoGUI==0.9.54; extra == "pyautogui"
|
183
183
|
Provides-Extra: selenium-stealth
|
@@ -275,26 +275,31 @@ Dynamic: summary
|
|
275
275
|
|
276
276
|
--------
|
277
277
|
|
278
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">raw_google.py</a>, which
|
278
|
+
<p align="left">📗 For performing a Google Search without hitting the "unusual traffic" page, you can use SeleniumBase UC Mode.<br />Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">SeleniumBase/examples/raw_google.py</a>, which exports results into different formats (PDF, HTML, PNG):</p>
|
279
279
|
|
280
280
|
```python
|
281
281
|
from seleniumbase import SB
|
282
282
|
|
283
283
|
with SB(test=True, uc=True) as sb:
|
284
284
|
sb.open("https://google.com/ncr")
|
285
|
-
sb.type('[title="Search"]', "SeleniumBase GitHub page
|
286
|
-
sb.click(
|
287
|
-
sb.save_screenshot_to_logs() # ./latest_logs/
|
285
|
+
sb.type('[title="Search"]', "SeleniumBase GitHub page")
|
286
|
+
sb.click("div:not([jsname]) > * > input")
|
288
287
|
print(sb.get_page_title())
|
288
|
+
sb.sleep(2) # Wait for the "AI Overview" result
|
289
|
+
if sb.is_text_visible("Generating"):
|
290
|
+
sb.wait_for_text("AI Overview")
|
291
|
+
sb.save_as_pdf_to_logs() # Saved to ./latest_logs/
|
292
|
+
sb.save_page_source_to_logs()
|
293
|
+
sb.save_screenshot_to_logs()
|
289
294
|
```
|
290
295
|
|
291
296
|
> `python raw_google.py`
|
292
297
|
|
293
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/
|
298
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/img/google_sb_result.png" alt="SeleniumBase on Google" title="SeleniumBase on Google" width="480" /></a>
|
294
299
|
|
295
300
|
--------
|
296
301
|
|
297
|
-
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
302
|
+
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page with UC Mode + CDP Mode: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
298
303
|
|
299
304
|
```python
|
300
305
|
from seleniumbase import SB
|
@@ -302,16 +307,36 @@ from seleniumbase import SB
|
|
302
307
|
with SB(uc=True, test=True, locale="en") as sb:
|
303
308
|
url = "https://gitlab.com/users/sign_in"
|
304
309
|
sb.activate_cdp_mode(url)
|
305
|
-
sb.sleep(
|
310
|
+
sb.sleep(2.2)
|
306
311
|
sb.uc_gui_click_captcha()
|
307
|
-
sb.
|
312
|
+
sb.assert_text("Username", '[for="user_login"]', timeout=3)
|
313
|
+
sb.assert_element('label[for="user_login"]')
|
314
|
+
sb.highlight('button:contains("Sign in")')
|
315
|
+
sb.highlight('h1:contains("GitLab.com")')
|
316
|
+
sb.post_message("SeleniumBase wasn't detected", duration=4)
|
308
317
|
```
|
309
318
|
|
310
319
|
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" title="SeleniumBase" width="332"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" title="SeleniumBase" width="288">
|
311
320
|
|
321
|
+
<p align="left">📙 You can also use SeleniumBase's pure CDP Mode, which doesn't use chromedriver, Selenium, or a Python context manager at all: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py">SeleniumBase/examples/cdp_mode/raw_cdp_gitlab.py</a></p>
|
322
|
+
|
323
|
+
```python
|
324
|
+
from seleniumbase import sb_cdp
|
325
|
+
|
326
|
+
url = "https://gitlab.com/users/sign_in"
|
327
|
+
sb = sb_cdp.Chrome(url)
|
328
|
+
sb.sleep(2.5)
|
329
|
+
sb.gui_click_captcha()
|
330
|
+
sb.highlight('h1:contains("GitLab.com")')
|
331
|
+
sb.highlight('button:contains("Sign in")')
|
332
|
+
sb.driver.stop()
|
333
|
+
```
|
334
|
+
|
335
|
+
> (Due to a change in Chrome 137 where the --load-extension switch was removed, one limitation with this format is that you can't load extensions directly. The other formats weren't affected by this change.)
|
336
|
+
|
312
337
|
--------
|
313
338
|
|
314
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">test_get_swag.py</a>, which tests an e-commerce site:</p>
|
339
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">SeleniumBase/examples/test_get_swag.py</a>, which tests an e-commerce site:</p>
|
315
340
|
|
316
341
|
```python
|
317
342
|
from seleniumbase import BaseCase
|
@@ -343,7 +368,7 @@ class MyTestClass(BaseCase):
|
|
343
368
|
|
344
369
|
--------
|
345
370
|
|
346
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
371
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">SeleniumBase/examples/test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
347
372
|
|
348
373
|
```zsh
|
349
374
|
pytest test_coffee_cart.py --demo
|
@@ -357,7 +382,7 @@ pytest test_coffee_cart.py --demo
|
|
357
382
|
|
358
383
|
<a id="multiple_examples"></a>
|
359
384
|
|
360
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">test_demo_site.py</a>, which covers several actions:</p>
|
385
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">SeleniumBase/examples/test_demo_site.py</a>, which covers several actions:</p>
|
361
386
|
|
362
387
|
```zsh
|
363
388
|
pytest test_demo_site.py
|
@@ -65,26 +65,31 @@
|
|
65
65
|
|
66
66
|
--------
|
67
67
|
|
68
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">raw_google.py</a>, which
|
68
|
+
<p align="left">📗 For performing a Google Search without hitting the "unusual traffic" page, you can use SeleniumBase UC Mode.<br />Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">SeleniumBase/examples/raw_google.py</a>, which exports results into different formats (PDF, HTML, PNG):</p>
|
69
69
|
|
70
70
|
```python
|
71
71
|
from seleniumbase import SB
|
72
72
|
|
73
73
|
with SB(test=True, uc=True) as sb:
|
74
74
|
sb.open("https://google.com/ncr")
|
75
|
-
sb.type('[title="Search"]', "SeleniumBase GitHub page
|
76
|
-
sb.click(
|
77
|
-
sb.save_screenshot_to_logs() # ./latest_logs/
|
75
|
+
sb.type('[title="Search"]', "SeleniumBase GitHub page")
|
76
|
+
sb.click("div:not([jsname]) > * > input")
|
78
77
|
print(sb.get_page_title())
|
78
|
+
sb.sleep(2) # Wait for the "AI Overview" result
|
79
|
+
if sb.is_text_visible("Generating"):
|
80
|
+
sb.wait_for_text("AI Overview")
|
81
|
+
sb.save_as_pdf_to_logs() # Saved to ./latest_logs/
|
82
|
+
sb.save_page_source_to_logs()
|
83
|
+
sb.save_screenshot_to_logs()
|
79
84
|
```
|
80
85
|
|
81
86
|
> `python raw_google.py`
|
82
87
|
|
83
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/
|
88
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/img/google_sb_result.png" alt="SeleniumBase on Google" title="SeleniumBase on Google" width="480" /></a>
|
84
89
|
|
85
90
|
--------
|
86
91
|
|
87
|
-
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
92
|
+
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page with UC Mode + CDP Mode: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
88
93
|
|
89
94
|
```python
|
90
95
|
from seleniumbase import SB
|
@@ -92,16 +97,36 @@ from seleniumbase import SB
|
|
92
97
|
with SB(uc=True, test=True, locale="en") as sb:
|
93
98
|
url = "https://gitlab.com/users/sign_in"
|
94
99
|
sb.activate_cdp_mode(url)
|
95
|
-
sb.sleep(
|
100
|
+
sb.sleep(2.2)
|
96
101
|
sb.uc_gui_click_captcha()
|
97
|
-
sb.
|
102
|
+
sb.assert_text("Username", '[for="user_login"]', timeout=3)
|
103
|
+
sb.assert_element('label[for="user_login"]')
|
104
|
+
sb.highlight('button:contains("Sign in")')
|
105
|
+
sb.highlight('h1:contains("GitLab.com")')
|
106
|
+
sb.post_message("SeleniumBase wasn't detected", duration=4)
|
98
107
|
```
|
99
108
|
|
100
109
|
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" title="SeleniumBase" width="332"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" title="SeleniumBase" width="288">
|
101
110
|
|
111
|
+
<p align="left">📙 You can also use SeleniumBase's pure CDP Mode, which doesn't use chromedriver, Selenium, or a Python context manager at all: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py">SeleniumBase/examples/cdp_mode/raw_cdp_gitlab.py</a></p>
|
112
|
+
|
113
|
+
```python
|
114
|
+
from seleniumbase import sb_cdp
|
115
|
+
|
116
|
+
url = "https://gitlab.com/users/sign_in"
|
117
|
+
sb = sb_cdp.Chrome(url)
|
118
|
+
sb.sleep(2.5)
|
119
|
+
sb.gui_click_captcha()
|
120
|
+
sb.highlight('h1:contains("GitLab.com")')
|
121
|
+
sb.highlight('button:contains("Sign in")')
|
122
|
+
sb.driver.stop()
|
123
|
+
```
|
124
|
+
|
125
|
+
> (Due to a change in Chrome 137 where the --load-extension switch was removed, one limitation with this format is that you can't load extensions directly. The other formats weren't affected by this change.)
|
126
|
+
|
102
127
|
--------
|
103
128
|
|
104
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">test_get_swag.py</a>, which tests an e-commerce site:</p>
|
129
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">SeleniumBase/examples/test_get_swag.py</a>, which tests an e-commerce site:</p>
|
105
130
|
|
106
131
|
```python
|
107
132
|
from seleniumbase import BaseCase
|
@@ -133,7 +158,7 @@ class MyTestClass(BaseCase):
|
|
133
158
|
|
134
159
|
--------
|
135
160
|
|
136
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
161
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">SeleniumBase/examples/test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
137
162
|
|
138
163
|
```zsh
|
139
164
|
pytest test_coffee_cart.py --demo
|
@@ -147,7 +172,7 @@ pytest test_coffee_cart.py --demo
|
|
147
172
|
|
148
173
|
<a id="multiple_examples"></a>
|
149
174
|
|
150
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">test_demo_site.py</a>, which covers several actions:</p>
|
175
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">SeleniumBase/examples/test_demo_site.py</a>, which covers several actions:</p>
|
151
176
|
|
152
177
|
```zsh
|
153
178
|
pytest test_demo_site.py
|
@@ -1191,6 +1191,15 @@ def set_attributes(context, selector, attribute, value):
|
|
1191
1191
|
sb.set_attributes(selector, attribute, value)
|
1192
1192
|
|
1193
1193
|
|
1194
|
+
@step("Save as PDF to logs")
|
1195
|
+
@step("Save as PDF to the logs")
|
1196
|
+
@step("User saves page as PDF to logs")
|
1197
|
+
@step("User saves page as PDF to the logs")
|
1198
|
+
def save_as_pdf_to_logs(context):
|
1199
|
+
sb = context.sb
|
1200
|
+
sb.save_as_pdf_to_logs()
|
1201
|
+
|
1202
|
+
|
1194
1203
|
@step("Save page source to logs")
|
1195
1204
|
@step("Save the page source to the logs")
|
1196
1205
|
@step("User saves page source to logs")
|
@@ -1,2 +1,2 @@
|
|
1
1
|
# seleniumbase package
|
2
|
-
__version__ = "4.41.
|
2
|
+
__version__ = "4.41.8"
|
@@ -522,6 +522,8 @@ def generate_gherkin(srt_actions):
|
|
522
522
|
)
|
523
523
|
elif action[0] == "ss_tl":
|
524
524
|
sb_actions.append("Save screenshot to logs")
|
525
|
+
elif action[0] == "pdftl":
|
526
|
+
sb_actions.append("Save as PDF to logs")
|
525
527
|
elif action[0] == "spstl":
|
526
528
|
sb_actions.append("Save page source to logs")
|
527
529
|
elif action[0] == "sh_fc":
|
@@ -53,7 +53,9 @@ def print_runtime(description=None, limit=None):
|
|
53
53
|
name = description
|
54
54
|
info = c1 + "<info>" + cr
|
55
55
|
# Print times with a statistically significant number of decimal places
|
56
|
-
if run_time < 0.
|
56
|
+
if run_time < 0.00001:
|
57
|
+
print("%s - {%s} ran for %.8f seconds." % (info, name, run_time))
|
58
|
+
elif run_time < 0.0001:
|
57
59
|
print("%s - {%s} ran for %.7f seconds." % (info, name, run_time))
|
58
60
|
elif run_time < 0.001:
|
59
61
|
print("%s - {%s} ran for %.6f seconds." % (info, name, run_time))
|
@@ -865,6 +865,7 @@ def uc_open_with_cdp_mode(driver, url=None, **kwargs):
|
|
865
865
|
cdp.scroll_down = CDPM.scroll_down
|
866
866
|
cdp.save_screenshot = CDPM.save_screenshot
|
867
867
|
cdp.print_to_pdf = CDPM.print_to_pdf
|
868
|
+
cdp.save_as_pdf = CDPM.save_as_pdf
|
868
869
|
cdp.page = page # async world
|
869
870
|
cdp.driver = driver.cdp_base # async world
|
870
871
|
cdp.tab = cdp.page # shortcut (original)
|
@@ -1226,6 +1227,7 @@ def _on_a_cf_turnstile_page(driver):
|
|
1226
1227
|
'data-callback="onCaptchaSuccess"' in source
|
1227
1228
|
or "/challenge-platform/scripts/" in source
|
1228
1229
|
or 'id="challenge-widget-' in source
|
1230
|
+
or "challenges.cloudf" in source
|
1229
1231
|
or "cf-turnstile-" in source
|
1230
1232
|
):
|
1231
1233
|
return True
|
@@ -556,6 +556,9 @@ def generate_sbase_code(srt_actions):
|
|
556
556
|
elif action[0] == "ss_tl":
|
557
557
|
method = "save_screenshot_to_logs"
|
558
558
|
sb_actions.append("self.%s()" % method)
|
559
|
+
elif action[0] == "pdftl":
|
560
|
+
method = "save_as_pdf_to_logs"
|
561
|
+
sb_actions.append("self.%s()" % method)
|
559
562
|
elif action[0] == "spstl":
|
560
563
|
method = "save_page_source_to_logs"
|
561
564
|
sb_actions.append("self.%s()" % method)
|
@@ -1661,11 +1661,16 @@ class CDPMethods():
|
|
1661
1661
|
self.loop.run_until_complete(self.page.wait())
|
1662
1662
|
|
1663
1663
|
def _on_a_cf_turnstile_page(self):
|
1664
|
+
time.sleep(0.042)
|
1664
1665
|
source = self.get_page_source()
|
1666
|
+
if not source or len(source) < 400:
|
1667
|
+
time.sleep(0.22)
|
1668
|
+
source = self.get_page_source()
|
1665
1669
|
if (
|
1666
1670
|
'data-callback="onCaptchaSuccess"' in source
|
1667
1671
|
or "/challenge-platform/scripts/" in source
|
1668
1672
|
or 'id="challenge-widget-' in source
|
1673
|
+
or "challenges.cloudf" in source
|
1669
1674
|
or "cf-turnstile-" in source
|
1670
1675
|
):
|
1671
1676
|
return True
|
@@ -1795,6 +1800,7 @@ class CDPMethods():
|
|
1795
1800
|
self.loop.run_until_complete(self.page.evaluate(script))
|
1796
1801
|
self.loop.run_until_complete(self.page.wait())
|
1797
1802
|
with suppress(Exception):
|
1803
|
+
time.sleep(0.08)
|
1798
1804
|
element_rect = self.get_gui_element_rect(selector, timeout=1)
|
1799
1805
|
e_x = element_rect["x"]
|
1800
1806
|
e_y = element_rect["y"]
|
@@ -1804,6 +1810,7 @@ class CDPMethods():
|
|
1804
1810
|
else:
|
1805
1811
|
y = e_y + 22
|
1806
1812
|
sb_config._saved_cf_x_y = (x, y)
|
1813
|
+
time.sleep(0.08)
|
1807
1814
|
self.gui_click_x_y(x, y)
|
1808
1815
|
|
1809
1816
|
def __gui_drag_drop(self, x1, y1, x2, y2, timeframe=0.25, uc_lock=False):
|
@@ -2571,6 +2578,9 @@ class CDPMethods():
|
|
2571
2578
|
filename = os.path.join(folder, name)
|
2572
2579
|
self.loop.run_until_complete(self.page.print_to_pdf(filename))
|
2573
2580
|
|
2581
|
+
def save_as_pdf(self, *args, **kwargs):
|
2582
|
+
self.print_to_pdf(*args, **kwargs)
|
2583
|
+
|
2574
2584
|
|
2575
2585
|
class Chrome(CDPMethods):
|
2576
2586
|
def __init__(self, url=None, **kwargs):
|
@@ -134,6 +134,7 @@ class BaseCase(unittest.TestCase):
|
|
134
134
|
self.__requests_timeout = None
|
135
135
|
self.__page_source_count = 0
|
136
136
|
self.__screenshot_count = 0
|
137
|
+
self.__saved_pdf_count = 0
|
137
138
|
self.__logs_data_count = 0
|
138
139
|
self.__last_data_file = None
|
139
140
|
self.__level_0_visual_f = False
|
@@ -4492,7 +4493,8 @@ class BaseCase(unittest.TestCase):
|
|
4492
4493
|
If a provided selector is not found, then takes a full-page screenshot.
|
4493
4494
|
(The last_page / failure screenshot is always "screenshot.png")
|
4494
4495
|
The screenshot will be in PNG format."""
|
4495
|
-
self.
|
4496
|
+
if not self.__is_cdp_swap_needed():
|
4497
|
+
self.wait_for_ready_state_complete()
|
4496
4498
|
test_logpath = os.path.join(self.log_path, self.__get_test_id())
|
4497
4499
|
self.__create_log_path_as_needed(test_logpath)
|
4498
4500
|
if name:
|
@@ -4510,6 +4512,11 @@ class BaseCase(unittest.TestCase):
|
|
4510
4512
|
if selector and by:
|
4511
4513
|
selector, by = self.__recalculate_selector(selector, by)
|
4512
4514
|
if page_actions.is_element_present(self.driver, selector, by):
|
4515
|
+
if self.__is_cdp_swap_needed():
|
4516
|
+
selector = self.convert_to_css_selector(selector, by=by)
|
4517
|
+
return self.cdp.save_screenshot(
|
4518
|
+
name, folder=test_logpath, selector=selector
|
4519
|
+
)
|
4513
4520
|
return page_actions.save_screenshot(
|
4514
4521
|
self.driver, name, test_logpath, selector, by
|
4515
4522
|
)
|
@@ -4523,8 +4530,49 @@ class BaseCase(unittest.TestCase):
|
|
4523
4530
|
action = ["ss_tl", "", origin, time_stamp]
|
4524
4531
|
self.__extra_actions.append(action)
|
4525
4532
|
sb_config._has_logs = True
|
4533
|
+
if self.__is_cdp_swap_needed():
|
4534
|
+
return self.cdp.save_screenshot(name, folder=test_logpath)
|
4526
4535
|
return page_actions.save_screenshot(self.driver, name, test_logpath)
|
4527
4536
|
|
4537
|
+
def save_as_pdf(self, name, folder=None):
|
4538
|
+
"""Same as self.print_to_pdf()"""
|
4539
|
+
return self.print_to_pdf(name, folder=folder)
|
4540
|
+
|
4541
|
+
def save_as_pdf_to_logs(self, name=None):
|
4542
|
+
"""Saves the page as a PDF to the "latest_logs/" folder.
|
4543
|
+
Naming is automatic:
|
4544
|
+
If NO NAME provided: "_1_PDF.pdf", "_2_PDF.pdf", etc.
|
4545
|
+
If NAME IS provided, then: "_1_name.pdf", "_2_name.pdf", etc."""
|
4546
|
+
if not self.__is_cdp_swap_needed():
|
4547
|
+
self.wait_for_ready_state_complete()
|
4548
|
+
test_logpath = os.path.join(self.log_path, self.__get_test_id())
|
4549
|
+
self.__create_log_path_as_needed(test_logpath)
|
4550
|
+
if name:
|
4551
|
+
name = str(name)
|
4552
|
+
self.__saved_pdf_count += 1
|
4553
|
+
if not name or len(name) == 0:
|
4554
|
+
name = "_%s_PDF.pdf" % self.__saved_pdf_count
|
4555
|
+
else:
|
4556
|
+
pre_name = "_%s_" % self.__saved_pdf_count
|
4557
|
+
if len(name) >= 4 and name[-4:].lower() == ".pdf":
|
4558
|
+
name = name[:-4]
|
4559
|
+
if len(name) == 0:
|
4560
|
+
name = "PDF"
|
4561
|
+
name = "%s%s.pdf" % (pre_name, name)
|
4562
|
+
if self.recorder_mode:
|
4563
|
+
url = self.get_current_url()
|
4564
|
+
if url and len(url) > 0:
|
4565
|
+
if ("http:") in url or ("https:") in url or ("file:") in url:
|
4566
|
+
if self.get_session_storage_item("pause_recorder") == "no":
|
4567
|
+
time_stamp = self.execute_script("return Date.now();")
|
4568
|
+
origin = self.get_origin()
|
4569
|
+
action = ["pdftl", "", origin, time_stamp]
|
4570
|
+
self.__extra_actions.append(action)
|
4571
|
+
sb_config._has_logs = True
|
4572
|
+
if self.__is_cdp_swap_needed():
|
4573
|
+
return self.cdp.print_to_pdf(name, folder=test_logpath)
|
4574
|
+
return self.print_to_pdf(name, test_logpath)
|
4575
|
+
|
4528
4576
|
def save_page_source_to_logs(self, name=None):
|
4529
4577
|
"""Saves the page HTML to the "latest_logs/" folder.
|
4530
4578
|
Naming is automatic:
|
@@ -5517,6 +5565,7 @@ class BaseCase(unittest.TestCase):
|
|
5517
5565
|
ext_actions.append("s_scr")
|
5518
5566
|
ext_actions.append("ss_tf")
|
5519
5567
|
ext_actions.append("ss_tl")
|
5568
|
+
ext_actions.append("pdftl")
|
5520
5569
|
ext_actions.append("spstl")
|
5521
5570
|
ext_actions.append("da_el")
|
5522
5571
|
ext_actions.append("da_ep")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: seleniumbase
|
3
|
-
Version: 4.41.
|
3
|
+
Version: 4.41.8
|
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
|
@@ -164,7 +164,7 @@ Provides-Extra: pdfminer
|
|
164
164
|
Requires-Dist: pdfminer.six==20250324; python_version < "3.9" and extra == "pdfminer"
|
165
165
|
Requires-Dist: pdfminer.six==20250506; python_version >= "3.9" and extra == "pdfminer"
|
166
166
|
Requires-Dist: cryptography==39.0.2; python_version < "3.9" and extra == "pdfminer"
|
167
|
-
Requires-Dist: cryptography==
|
167
|
+
Requires-Dist: cryptography==46.0.1; python_version >= "3.9" and extra == "pdfminer"
|
168
168
|
Requires-Dist: cffi==1.17.1; python_version < "3.9" and extra == "pdfminer"
|
169
169
|
Requires-Dist: cffi==2.0.0; python_version >= "3.9" and extra == "pdfminer"
|
170
170
|
Requires-Dist: pycparser==2.22; python_version < "3.9" and extra == "pdfminer"
|
@@ -177,7 +177,7 @@ Requires-Dist: pip-system-certs==4.0; platform_system == "Windows" and extra ==
|
|
177
177
|
Provides-Extra: proxy
|
178
178
|
Requires-Dist: proxy.py==2.4.3; extra == "proxy"
|
179
179
|
Provides-Extra: psutil
|
180
|
-
Requires-Dist: psutil==7.
|
180
|
+
Requires-Dist: psutil==7.1.0; extra == "psutil"
|
181
181
|
Provides-Extra: pyautogui
|
182
182
|
Requires-Dist: PyAutoGUI==0.9.54; extra == "pyautogui"
|
183
183
|
Provides-Extra: selenium-stealth
|
@@ -275,26 +275,31 @@ Dynamic: summary
|
|
275
275
|
|
276
276
|
--------
|
277
277
|
|
278
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">raw_google.py</a>, which
|
278
|
+
<p align="left">📗 For performing a Google Search without hitting the "unusual traffic" page, you can use SeleniumBase UC Mode.<br />Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py">SeleniumBase/examples/raw_google.py</a>, which exports results into different formats (PDF, HTML, PNG):</p>
|
279
279
|
|
280
280
|
```python
|
281
281
|
from seleniumbase import SB
|
282
282
|
|
283
283
|
with SB(test=True, uc=True) as sb:
|
284
284
|
sb.open("https://google.com/ncr")
|
285
|
-
sb.type('[title="Search"]', "SeleniumBase GitHub page
|
286
|
-
sb.click(
|
287
|
-
sb.save_screenshot_to_logs() # ./latest_logs/
|
285
|
+
sb.type('[title="Search"]', "SeleniumBase GitHub page")
|
286
|
+
sb.click("div:not([jsname]) > * > input")
|
288
287
|
print(sb.get_page_title())
|
288
|
+
sb.sleep(2) # Wait for the "AI Overview" result
|
289
|
+
if sb.is_text_visible("Generating"):
|
290
|
+
sb.wait_for_text("AI Overview")
|
291
|
+
sb.save_as_pdf_to_logs() # Saved to ./latest_logs/
|
292
|
+
sb.save_page_source_to_logs()
|
293
|
+
sb.save_screenshot_to_logs()
|
289
294
|
```
|
290
295
|
|
291
296
|
> `python raw_google.py`
|
292
297
|
|
293
|
-
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/
|
298
|
+
<a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/raw_google.py"><img src="https://seleniumbase.github.io/cdn/img/google_sb_result.png" alt="SeleniumBase on Google" title="SeleniumBase on Google" width="480" /></a>
|
294
299
|
|
295
300
|
--------
|
296
301
|
|
297
|
-
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
302
|
+
<p align="left">📗 Here's an example of bypassing Cloudflare's challenge page with UC Mode + CDP Mode: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_gitlab.py">SeleniumBase/examples/cdp_mode/raw_gitlab.py</a></p>
|
298
303
|
|
299
304
|
```python
|
300
305
|
from seleniumbase import SB
|
@@ -302,16 +307,36 @@ from seleniumbase import SB
|
|
302
307
|
with SB(uc=True, test=True, locale="en") as sb:
|
303
308
|
url = "https://gitlab.com/users/sign_in"
|
304
309
|
sb.activate_cdp_mode(url)
|
305
|
-
sb.sleep(
|
310
|
+
sb.sleep(2.2)
|
306
311
|
sb.uc_gui_click_captcha()
|
307
|
-
sb.
|
312
|
+
sb.assert_text("Username", '[for="user_login"]', timeout=3)
|
313
|
+
sb.assert_element('label[for="user_login"]')
|
314
|
+
sb.highlight('button:contains("Sign in")')
|
315
|
+
sb.highlight('h1:contains("GitLab.com")')
|
316
|
+
sb.post_message("SeleniumBase wasn't detected", duration=4)
|
308
317
|
```
|
309
318
|
|
310
319
|
<img src="https://seleniumbase.github.io/other/cf_sec.jpg" title="SeleniumBase" width="332"> <img src="https://seleniumbase.github.io/other/gitlab_bypass.png" title="SeleniumBase" width="288">
|
311
320
|
|
321
|
+
<p align="left">📙 You can also use SeleniumBase's pure CDP Mode, which doesn't use chromedriver, Selenium, or a Python context manager at all: <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/cdp_mode/raw_cdp_gitlab.py">SeleniumBase/examples/cdp_mode/raw_cdp_gitlab.py</a></p>
|
322
|
+
|
323
|
+
```python
|
324
|
+
from seleniumbase import sb_cdp
|
325
|
+
|
326
|
+
url = "https://gitlab.com/users/sign_in"
|
327
|
+
sb = sb_cdp.Chrome(url)
|
328
|
+
sb.sleep(2.5)
|
329
|
+
sb.gui_click_captcha()
|
330
|
+
sb.highlight('h1:contains("GitLab.com")')
|
331
|
+
sb.highlight('button:contains("Sign in")')
|
332
|
+
sb.driver.stop()
|
333
|
+
```
|
334
|
+
|
335
|
+
> (Due to a change in Chrome 137 where the --load-extension switch was removed, one limitation with this format is that you can't load extensions directly. The other formats weren't affected by this change.)
|
336
|
+
|
312
337
|
--------
|
313
338
|
|
314
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">test_get_swag.py</a>, which tests an e-commerce site:</p>
|
339
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_get_swag.py">SeleniumBase/examples/test_get_swag.py</a>, which tests an e-commerce site:</p>
|
315
340
|
|
316
341
|
```python
|
317
342
|
from seleniumbase import BaseCase
|
@@ -343,7 +368,7 @@ class MyTestClass(BaseCase):
|
|
343
368
|
|
344
369
|
--------
|
345
370
|
|
346
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
371
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_coffee_cart.py" target="_blank">SeleniumBase/examples/test_coffee_cart.py</a>, which verifies an e-commerce site:</p>
|
347
372
|
|
348
373
|
```zsh
|
349
374
|
pytest test_coffee_cart.py --demo
|
@@ -357,7 +382,7 @@ pytest test_coffee_cart.py --demo
|
|
357
382
|
|
358
383
|
<a id="multiple_examples"></a>
|
359
384
|
|
360
|
-
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">test_demo_site.py</a>, which covers several actions:</p>
|
385
|
+
<p align="left">📗 Here's <a href="https://github.com/seleniumbase/SeleniumBase/blob/master/examples/test_demo_site.py" target="_blank">SeleniumBase/examples/test_demo_site.py</a>, which covers several actions:</p>
|
361
386
|
|
362
387
|
```zsh
|
363
388
|
pytest test_demo_site.py
|
@@ -140,7 +140,7 @@ pycparser==2.22
|
|
140
140
|
|
141
141
|
[pdfminer:python_version >= "3.9"]
|
142
142
|
pdfminer.six==20250506
|
143
|
-
cryptography==
|
143
|
+
cryptography==46.0.1
|
144
144
|
cffi==2.0.0
|
145
145
|
pycparser==2.23
|
146
146
|
|
@@ -161,7 +161,7 @@ pip-system-certs==4.0
|
|
161
161
|
proxy.py==2.4.3
|
162
162
|
|
163
163
|
[psutil]
|
164
|
-
psutil==7.
|
164
|
+
psutil==7.1.0
|
165
165
|
|
166
166
|
[pyautogui]
|
167
167
|
PyAutoGUI==0.9.54
|
@@ -270,7 +270,7 @@ setup(
|
|
270
270
|
'pdfminer.six==20250324;python_version<"3.9"',
|
271
271
|
'pdfminer.six==20250506;python_version>="3.9"',
|
272
272
|
'cryptography==39.0.2;python_version<"3.9"',
|
273
|
-
'cryptography==
|
273
|
+
'cryptography==46.0.1;python_version>="3.9"',
|
274
274
|
'cffi==1.17.1;python_version<"3.9"',
|
275
275
|
'cffi==2.0.0;python_version>="3.9"',
|
276
276
|
'pycparser==2.22;python_version<"3.9"',
|
@@ -296,7 +296,7 @@ setup(
|
|
296
296
|
],
|
297
297
|
# pip install -e .[psutil]
|
298
298
|
"psutil": [
|
299
|
-
"psutil==7.
|
299
|
+
"psutil==7.1.0",
|
300
300
|
],
|
301
301
|
# pip install -e .[pyautogui]
|
302
302
|
"pyautogui": [
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/_contradict.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/undetected/cdp_driver/connection.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/grid_hub.py
RENAMED
File without changes
|
{seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/grid_node.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat
RENAMED
File without changes
|
{seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh
RENAMED
File without changes
|
File without changes
|
{seleniumbase-4.41.6 → seleniumbase-4.41.8}/seleniumbase/utilities/selenium_ide/convert_ide.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|