seleniumbase 4.54.3__tar.gz → 4.54.5__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.54.3/seleniumbase.egg-info → seleniumbase-4.54.5}/PKG-INFO +2 -2
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/mcp_servers/server.py +162 -113
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/requirements.txt +1 -1
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/__version__.py +1 -1
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/sb_cdp.py +9 -5
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/base_case.py +4 -2
- {seleniumbase-4.54.3 → seleniumbase-4.54.5/seleniumbase.egg-info}/PKG-INFO +2 -2
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase.egg-info/requires.txt +1 -1
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/setup.py +1 -1
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/.gitignore +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/LICENSE +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/MANIFEST.in +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/README.md +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/install.sh +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/mcp_servers/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/pyproject.toml +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/pytest.ini +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/sbase/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/sbase/__main__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/sbase/steps.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/__main__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/behave/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/behave/behave_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/behave/behave_sb.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/behave/steps.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/common/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/common/decorators.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/common/encryption.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/common/exceptions.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/common/obfuscate.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/common/unobfuscate.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/config/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/config/ad_block_list.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/config/proxy_list.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/config/settings.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/logo_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/rich_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/run.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_behave_gui.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_caseplans.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_commander.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_install.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_mkchart.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_mkdir.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_mkfile.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_mkpres.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_mkrec.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_objectify.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_print.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/console_scripts/sb_recorder.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/application_manager.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/browser_launcher.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/capabilities_parser.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/colored_traceback.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/create_db_tables.sql +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/detect_b_ver.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/download_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/encoded_images.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/jqc_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/log_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/mysql.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/nest_asyncio.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/proxy_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/recorder_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/report_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/s3_manager.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/sb_driver.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/session_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/settings_parser.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/style_sheet.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/testcase_manager.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/tour_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/core/visual_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/drivers/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/drivers/brave_drivers/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/drivers/cft_drivers/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/drivers/chromium_drivers/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/drivers/chs_drivers/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/drivers/comet_drivers/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/drivers/opera_drivers/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/extensions/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/extensions/ad_block.zip +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/extensions/disable_csp.zip +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/extensions/recorder.zip +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/extensions/sbase_ext.zip +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/constants.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/css_to_xpath.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/errors.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/js_utils.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/page_actions.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/page_utils.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/shared_utils.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/unittest_helper.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/words.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/fixtures/xpath_to_css.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/js_code/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/js_code/active_css_js.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/js_code/live_js.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/js_code/recorder_js.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/masterqa/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/masterqa/master_qa.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/base_plugin.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/basic_test_info.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/db_reporting_plugin.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/driver_manager.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/page_source.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/pytest_plugin.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/s3_logging_plugin.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/sb_manager.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/screen_shots.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/plugins/selenium_plugin.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/resources/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/chinese.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/dutch.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/french.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/italian.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/japanese.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/korean.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/master_dict.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/portuguese.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/russian.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/spanish.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/translate/translator.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/cdp.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/cdp_driver/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/cdp_driver/_contradict.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/cdp_driver/browser.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/cdp_driver/cdp_util.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/cdp_driver/config.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/cdp_driver/connection.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/cdp_driver/element.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/cdp_driver/tab.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/dprocess.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/options.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/patcher.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/reactor.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/undetected/webelement.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/download_selenium_server.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/font_color +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/grid-hub +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/grid-node +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/grid_hub.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/grid_node.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/register-grid-node.bat +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/register-grid-node.sh +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/start-grid-hub.bat +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_grid/start-grid-hub.sh +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_ide/__init__.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase/utilities/selenium_ide/convert_ide.py +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase.egg-info/SOURCES.txt +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase.egg-info/dependency_links.txt +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase.egg-info/entry_points.txt +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/seleniumbase.egg-info/top_level.txt +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/setup.cfg +0 -0
- {seleniumbase-4.54.3 → seleniumbase-4.54.5}/virtualenv_install.sh +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.54.
|
|
3
|
+
Version: 4.54.5
|
|
4
4
|
Summary: SeleniumBase is a framework for web crawling, scraping, and testing. Supports pytest. CDP Mode adds stealth. Includes many tools.
|
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
|
6
6
|
Author: Michael Mintz
|
|
@@ -126,7 +126,7 @@ Requires-Dist: allure-pytest>=2.16.0; extra == "allure"
|
|
|
126
126
|
Requires-Dist: allure-python-commons>=2.16.0; extra == "allure"
|
|
127
127
|
Requires-Dist: allure-behave>=2.16.0; extra == "allure"
|
|
128
128
|
Provides-Extra: coverage
|
|
129
|
-
Requires-Dist: coverage>=7.16.
|
|
129
|
+
Requires-Dist: coverage>=7.16.1; extra == "coverage"
|
|
130
130
|
Requires-Dist: pytest-cov>=7.1.0; extra == "coverage"
|
|
131
131
|
Provides-Extra: flake8
|
|
132
132
|
Requires-Dist: flake8==7.3.0; extra == "flake8"
|
|
@@ -34,14 +34,15 @@ having to choose between multiple near-identical tools.
|
|
|
34
34
|
|
|
35
35
|
Tool-selection philosophy:
|
|
36
36
|
- Use 'start_browser'/'close_browser' for opening/quitting the web browser.
|
|
37
|
-
- Use '
|
|
37
|
+
- Use 'open_url'/'manage_history' for browser navigation and history
|
|
38
38
|
inspection.
|
|
39
39
|
- Use 'get_page_info' for reading browser/page metadata such as URL/title.
|
|
40
40
|
- Use 'get_content'/'get_attributes' for reading text, HTML, or attributes.
|
|
41
41
|
- Use 'find_elements' for discovering and inspecting multiple matching
|
|
42
42
|
elements as structured data.
|
|
43
|
-
- Use '
|
|
44
|
-
- Use '
|
|
43
|
+
- Use 'check_if_condition' for an immediate, non-waiting state check.
|
|
44
|
+
- Use 'wait_for_condition' when the agent needs to wait for a condition
|
|
45
|
+
to become true.
|
|
45
46
|
- Use 'assert_condition' when the agent needs to verify an expected condition
|
|
46
47
|
and treat failure as an assertion error.
|
|
47
48
|
- Use 'click_element'/'type_text'/'select_option' for standard page
|
|
@@ -111,7 +112,7 @@ def start_browser(
|
|
|
111
112
|
) -> str:
|
|
112
113
|
"""Launch a persistent SeleniumBase Pure CDP Mode browser session.
|
|
113
114
|
|
|
114
|
-
Call this before using browser interaction tools such as
|
|
115
|
+
Call this before using browser interaction tools such as open_url,
|
|
115
116
|
get_content, click_element, type_text, or find_elements. The same browser
|
|
116
117
|
session remains active across subsequent MCP tool calls until
|
|
117
118
|
close_browser is called or the server process exits.
|
|
@@ -303,8 +304,8 @@ def get_page_info() -> dict[str, Any]:
|
|
|
303
304
|
- Need URL, title, origin, or User-Agent -> use get_page_info.
|
|
304
305
|
- Need visible page text or HTML -> use get_content.
|
|
305
306
|
- Need information about matching elements -> use find_elements.
|
|
306
|
-
- Need an immediate state check -> use
|
|
307
|
-
- Need to wait for a condition -> use
|
|
307
|
+
- Need an immediate state check -> use check_if_condition.
|
|
308
|
+
- Need to wait for a condition -> use wait_for_condition.
|
|
308
309
|
- Need to verify an expected condition -> use assert_condition.
|
|
309
310
|
|
|
310
311
|
Unlike a dedicated browser-status tool, get_page_info is the single
|
|
@@ -338,8 +339,8 @@ def get_page_info() -> dict[str, Any]:
|
|
|
338
339
|
|
|
339
340
|
@mcp.tool()
|
|
340
341
|
@handle_sb_errors
|
|
341
|
-
def
|
|
342
|
-
"""Navigate the current browser tab to
|
|
342
|
+
def open_url(url: str) -> str:
|
|
343
|
+
"""Navigate the current browser tab to the URL provided.
|
|
343
344
|
|
|
344
345
|
Use this when the browser needs to visit a new URL rather than move
|
|
345
346
|
through its existing back/forward history.
|
|
@@ -350,17 +351,18 @@ def goto_url(url: str) -> str:
|
|
|
350
351
|
|
|
351
352
|
Navigation waits for the browser's navigation operation to complete
|
|
352
353
|
before returning. Dynamic content may still be loading;
|
|
353
|
-
use
|
|
354
|
+
use wait_for_condition when synchronization is required.
|
|
355
|
+
If there's an error, that gets propagated through @handle_sb_errors.
|
|
354
356
|
|
|
355
357
|
Args:
|
|
356
|
-
url:
|
|
357
|
-
"https://example.com" or a hostname such as "example.com".
|
|
358
|
+
url: The destination URL. May be a complete URL such as
|
|
359
|
+
"https://example.com", or a hostname such as "example.com".
|
|
358
360
|
|
|
359
361
|
Returns:
|
|
360
|
-
A confirmation message containing the requested URL.
|
|
362
|
+
A confirmation message containing the requested URL if successful.
|
|
361
363
|
|
|
362
364
|
Tool selection:
|
|
363
|
-
-
|
|
365
|
+
- Navigate to a new URL -> use open_url.
|
|
364
366
|
- Return to the previous page -> use manage_history(action="back").
|
|
365
367
|
- Go forward in history -> use manage_history(action="forward").
|
|
366
368
|
- Refresh the current page -> use manage_history(action="reload").
|
|
@@ -379,7 +381,7 @@ def manage_history(
|
|
|
379
381
|
|
|
380
382
|
Use 'back' or 'forward' for history navigation, 'reload' to refresh
|
|
381
383
|
while bypassing the cache, or 'list' to inspect history.
|
|
382
|
-
Use '
|
|
384
|
+
Use 'open_url' for navigation to an arbitrary URL.
|
|
383
385
|
|
|
384
386
|
Args:
|
|
385
387
|
action:
|
|
@@ -477,7 +479,7 @@ def find_elements(
|
|
|
477
479
|
use get_content.
|
|
478
480
|
- Need to click one of several matches -> use click_element with nth.
|
|
479
481
|
- Need to know whether an element is present/visible ->
|
|
480
|
-
use
|
|
482
|
+
use check_if_condition.
|
|
481
483
|
|
|
482
484
|
Notes:
|
|
483
485
|
Element handles cannot be persisted across MCP calls. If you find
|
|
@@ -542,8 +544,8 @@ def get_content(
|
|
|
542
544
|
- Need visible text, html, or URLs on a page -> use get_content.
|
|
543
545
|
- Need structured information about matching elements ->
|
|
544
546
|
use find_elements.
|
|
545
|
-
- Need to check element presence/visibility -> use
|
|
546
|
-
- Need to wait for content to appear -> use
|
|
547
|
+
- Need to check element presence/visibility -> use check_if_condition.
|
|
548
|
+
- Need to wait for content to appear -> use wait_for_condition.
|
|
547
549
|
|
|
548
550
|
If there's no matching element found within the timeout,
|
|
549
551
|
then @handle_sb_errors returns details from the exception raised.
|
|
@@ -592,7 +594,8 @@ def get_attributes(
|
|
|
592
594
|
- Need to discover multiple matching elements or inspect their text ->
|
|
593
595
|
use 'find_elements'.
|
|
594
596
|
- Need visible text or HTML content -> use 'get_content'.
|
|
595
|
-
- Need to check element presence/visibility ->
|
|
597
|
+
- Need to check element presence/visibility ->
|
|
598
|
+
use 'check_if_condition'.
|
|
596
599
|
|
|
597
600
|
This is a read-only operation.
|
|
598
601
|
|
|
@@ -609,7 +612,7 @@ def get_attributes(
|
|
|
609
612
|
|
|
610
613
|
@mcp.tool()
|
|
611
614
|
@handle_sb_errors
|
|
612
|
-
def
|
|
615
|
+
def check_if_condition(
|
|
613
616
|
check: Literal["present", "visible"] = "visible",
|
|
614
617
|
selector: str = "body",
|
|
615
618
|
text: str | None = None,
|
|
@@ -618,9 +621,10 @@ def check_condition(
|
|
|
618
621
|
for the condition to become true.
|
|
619
622
|
|
|
620
623
|
Use this tool when you need an immediate boolean observation of the current
|
|
621
|
-
page state. Use
|
|
622
|
-
workflow should wait for it. Use assert_condition when the
|
|
623
|
-
expected requirement and failure should be treated as an
|
|
624
|
+
page state. Use wait_for_condition when the condition may become true later
|
|
625
|
+
and the workflow should wait for it. Use assert_condition when the
|
|
626
|
+
condition is an expected requirement and failure should be treated as an
|
|
627
|
+
assertion error.
|
|
624
628
|
|
|
625
629
|
Args:
|
|
626
630
|
check:
|
|
@@ -645,8 +649,8 @@ def check_condition(
|
|
|
645
649
|
exception. If there's an error, returns a string with error details.
|
|
646
650
|
|
|
647
651
|
Tool selection:
|
|
648
|
-
- Immediate boolean observation -> use
|
|
649
|
-
- Wait for a state/content transition -> use
|
|
652
|
+
- Immediate boolean observation -> use check_if_condition.
|
|
653
|
+
- Wait for a state/content transition -> use wait_for_condition.
|
|
650
654
|
- Verify an expected condition -> use assert_condition.
|
|
651
655
|
- Need element details of matching elements -> use find_elements.
|
|
652
656
|
- Need to read page or element content -> use get_content.
|
|
@@ -654,7 +658,7 @@ def check_condition(
|
|
|
654
658
|
Notes:
|
|
655
659
|
This tool does not intentionally wait for elements or text to appear.
|
|
656
660
|
It is intended for checking the current state only. If page timing or
|
|
657
|
-
asynchronous loading matters, use
|
|
661
|
+
asynchronous loading matters, use wait_for_condition instead.
|
|
658
662
|
|
|
659
663
|
When `text` is provided, `check` is ignored.
|
|
660
664
|
"""
|
|
@@ -696,11 +700,11 @@ def click_element(
|
|
|
696
700
|
parent element.
|
|
697
701
|
|
|
698
702
|
Selection behavior:
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
703
|
+
- `nth` is 1-based and takes precedence over every other click mode.
|
|
704
|
+
- Otherwise, `all_matches=True` clicks every currently visible match.
|
|
705
|
+
- Otherwise, `only_if_visible=True` clicks only if a match is visible.
|
|
706
|
+
- Otherwise, `parent_selector` scopes the click to a nested element.
|
|
707
|
+
- With none of the above, performs a normal SeleniumBase click.
|
|
704
708
|
|
|
705
709
|
Args:
|
|
706
710
|
selector: CSS selector, XPath selector, or supported SeleniumBase
|
|
@@ -709,15 +713,15 @@ def click_element(
|
|
|
709
713
|
clicks; do not use them with `all_matches=True`.
|
|
710
714
|
|
|
711
715
|
nth: 1-based occurrence to click when multiple elements match.
|
|
712
|
-
Must be >= 1. Takes precedence over `all_matches`,
|
|
716
|
+
Must be >= 1 if provided. Takes precedence over `all_matches`,
|
|
713
717
|
`only_if_visible`, and `parent_selector`.
|
|
714
718
|
|
|
715
719
|
all_matches: If True, click every currently visible matching element
|
|
716
720
|
in order of appearance. Ignored when `nth` is provided. Use only
|
|
717
721
|
when multiple clicks are intentionally desired, such as for
|
|
718
722
|
clicking all the checkboxes in a section of a webpage.
|
|
719
|
-
If
|
|
720
|
-
cancelled.
|
|
723
|
+
If any of the click actions induces page navigation, then
|
|
724
|
+
subsequent clicks are cancelled without any exceptions raised.
|
|
721
725
|
|
|
722
726
|
only_if_visible: If True, click only when the target is already
|
|
723
727
|
visible; do not wait for it to become visible.
|
|
@@ -733,18 +737,27 @@ def click_element(
|
|
|
733
737
|
indexed click. Default: True.
|
|
734
738
|
|
|
735
739
|
Examples:
|
|
736
|
-
- Click
|
|
737
|
-
- Click the 2nd
|
|
738
|
-
- Click all
|
|
739
|
-
`click_element("
|
|
740
|
-
- Click
|
|
741
|
-
`click_element("
|
|
742
|
-
- Click inside
|
|
743
|
-
`click_element("
|
|
740
|
+
- Click the first button: `click_element("button")`
|
|
741
|
+
- Click the 2nd button: `click_element("button", nth=2)`
|
|
742
|
+
- Click all checkboxes:
|
|
743
|
+
`click_element('input[type="checkbox"]', all_matches=True)`
|
|
744
|
+
- Click the first visible link:
|
|
745
|
+
`click_element("a", only_if_visible=True)`
|
|
746
|
+
- Click the first button that's inside the first iframe:
|
|
747
|
+
`click_element("button", parent_selector="iframe")`
|
|
748
|
+
|
|
749
|
+
Error behavior:
|
|
750
|
+
With the exception of using 'only_if_visible=True', if there's no
|
|
751
|
+
matching element found within the timeout, then @handle_sb_errors
|
|
752
|
+
returns details from the exception raised.
|
|
753
|
+
|
|
754
|
+
When not to use:
|
|
755
|
+
- Do not use this tool if you need to hover an element first before
|
|
756
|
+
clicking; use hover_action with action="hover_and_click" instead.
|
|
744
757
|
"""
|
|
745
758
|
sb = _get_sb()
|
|
746
759
|
|
|
747
|
-
if nth
|
|
760
|
+
if nth:
|
|
748
761
|
if nth < 1:
|
|
749
762
|
return "Error: nth must be >= 1."
|
|
750
763
|
sb.click_nth_element(selector, nth, scroll=scroll)
|
|
@@ -769,9 +782,10 @@ def click_element(
|
|
|
769
782
|
@mcp.tool()
|
|
770
783
|
@handle_sb_errors
|
|
771
784
|
def hover_action(
|
|
772
|
-
|
|
773
|
-
|
|
785
|
+
selector: str,
|
|
786
|
+
secondary_selector: str | None = None,
|
|
774
787
|
action: Literal["hover", "hover_and_click", "drag_and_drop"] = "hover",
|
|
788
|
+
timeout: float = 5,
|
|
775
789
|
) -> str:
|
|
776
790
|
"""Hover over an element, optionally click another, or drag-and-drop.
|
|
777
791
|
|
|
@@ -779,51 +793,71 @@ def hover_action(
|
|
|
779
793
|
drag-and-drop operations.
|
|
780
794
|
|
|
781
795
|
Args:
|
|
782
|
-
|
|
796
|
+
selector:
|
|
783
797
|
The primary element selector.
|
|
784
798
|
For action="hover", this is the element to hover over.
|
|
785
799
|
For action="hover_and_click", this is the element to hover over
|
|
786
|
-
before clicking
|
|
800
|
+
before clicking 'secondary_selector'.
|
|
787
801
|
For action="drag_and_drop", this is the draggable source element.
|
|
788
802
|
|
|
789
|
-
|
|
803
|
+
secondary_selector:
|
|
790
804
|
The secondary element selector.
|
|
791
805
|
Required for action="hover_and_click", where it identifies
|
|
792
|
-
the element
|
|
806
|
+
the element to click after hovering 'selector'.
|
|
793
807
|
Required for action="drag_and_drop", where it identifies the
|
|
794
808
|
destination/drop target.
|
|
795
809
|
Not used for action="hover".
|
|
796
810
|
|
|
797
811
|
action:
|
|
798
|
-
- "hover": Hover over
|
|
799
|
-
- "hover_and_click": Hover over
|
|
800
|
-
|
|
812
|
+
- "hover": Hover over 'selector' only.
|
|
813
|
+
- "hover_and_click": Hover over 'selector', then click
|
|
814
|
+
'secondary_selector' after a short moment has passed.
|
|
815
|
+
- "drag_and_drop": Drag 'selector' and drop it onto
|
|
816
|
+
'secondary_selector'.
|
|
817
|
+
|
|
818
|
+
timeout: Maximum seconds to wait for 'selector'.
|
|
819
|
+
For drag_and_drop, the same timeout applies to secondary_selector.
|
|
820
|
+
For hover_and_click, SeleniumBase uses its own short wait for
|
|
821
|
+
secondary_selector; this parameter does not extend that secondary
|
|
822
|
+
wait.
|
|
801
823
|
|
|
802
824
|
Returns:
|
|
803
|
-
A confirmation message describing the performed operation.
|
|
825
|
+
A confirmation message describing the performed operation's result.
|
|
804
826
|
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
827
|
+
Error behavior:
|
|
828
|
+
If a required element cannot be found or interacted with within the
|
|
829
|
+
applicable wait period, or if an error occurs during the action, the
|
|
830
|
+
resulting exception message is returned through @handle_sb_errors.
|
|
831
|
+
Failing actions such as failed hover_and_click will raise exceptions.
|
|
832
|
+
|
|
833
|
+
When not to use:
|
|
834
|
+
- Do not use this tool to click if you don't need to hover an element
|
|
835
|
+
before clicking another; use 'click' instead.
|
|
809
836
|
"""
|
|
810
837
|
sb = _get_sb()
|
|
811
838
|
|
|
839
|
+
if timeout < 0:
|
|
840
|
+
return "Error: timeout must be >= 0."
|
|
841
|
+
|
|
812
842
|
if action == "hover":
|
|
813
|
-
sb.hover_element(
|
|
814
|
-
return f"Hovered {
|
|
843
|
+
sb.hover_element(selector, timeout=timeout)
|
|
844
|
+
return f"Hovered {selector}"
|
|
815
845
|
|
|
816
846
|
if action == "hover_and_click":
|
|
817
|
-
if
|
|
818
|
-
return
|
|
819
|
-
|
|
820
|
-
|
|
847
|
+
if not secondary_selector:
|
|
848
|
+
return (
|
|
849
|
+
"Error: action='hover_and_click' requires secondary_selector."
|
|
850
|
+
)
|
|
851
|
+
sb.hover_and_click(selector, secondary_selector, timeout=timeout)
|
|
852
|
+
return f"Hovered {selector} and clicked {secondary_selector}"
|
|
821
853
|
|
|
822
854
|
if action == "drag_and_drop":
|
|
823
|
-
if
|
|
824
|
-
return
|
|
825
|
-
|
|
826
|
-
|
|
855
|
+
if not secondary_selector:
|
|
856
|
+
return (
|
|
857
|
+
"Error: action='drag_and_drop' requires secondary_selector."
|
|
858
|
+
)
|
|
859
|
+
sb.drag_and_drop(selector, secondary_selector, timeout=timeout)
|
|
860
|
+
return f"Dragged {selector} onto {secondary_selector}"
|
|
827
861
|
|
|
828
862
|
return (
|
|
829
863
|
f"Error: unknown action '{action}'. "
|
|
@@ -998,7 +1032,7 @@ def focus_element(
|
|
|
998
1032
|
|
|
999
1033
|
@mcp.tool()
|
|
1000
1034
|
@handle_sb_errors
|
|
1001
|
-
def
|
|
1035
|
+
def wait_for_condition(
|
|
1002
1036
|
state: Literal[
|
|
1003
1037
|
"present",
|
|
1004
1038
|
"visible",
|
|
@@ -1017,7 +1051,7 @@ def wait_for(
|
|
|
1017
1051
|
condition is met or the timeout expires. It does not intentionally scroll,
|
|
1018
1052
|
click, or otherwise modify the page while waiting.
|
|
1019
1053
|
|
|
1020
|
-
Use
|
|
1054
|
+
Use check_if_condition to inspect the current state without waiting.
|
|
1021
1055
|
Use assert_condition to verify an expected condition rather than
|
|
1022
1056
|
synchronize with a changing page.
|
|
1023
1057
|
|
|
@@ -1056,8 +1090,8 @@ def wait_for(
|
|
|
1056
1090
|
the tool returns the error produced by its error handler.
|
|
1057
1091
|
|
|
1058
1092
|
Tool selection:
|
|
1059
|
-
- Inspect current state immediately ->
|
|
1060
|
-
- Wait for a state change ->
|
|
1093
|
+
- Inspect current state immediately -> check_if_condition.
|
|
1094
|
+
- Wait for a state change -> wait_for_condition.
|
|
1061
1095
|
- Verify an expectation -> assert_condition.
|
|
1062
1096
|
"""
|
|
1063
1097
|
sb = _get_sb()
|
|
@@ -1132,10 +1166,10 @@ def assert_condition(
|
|
|
1132
1166
|
handled by `handle_sb_errors` and returned as a descriptive tool error;
|
|
1133
1167
|
it is not reported as a successful result.
|
|
1134
1168
|
|
|
1135
|
-
Unlike
|
|
1169
|
+
Unlike check_if_condition, this tool does not merely return whether a
|
|
1136
1170
|
condition is true: a failed expectation is an error.
|
|
1137
|
-
Unlike
|
|
1138
|
-
synchronize with a changing page.
|
|
1171
|
+
Unlike wait_for_condition, its purpose is to verify an expectation,
|
|
1172
|
+
not merely synchronize with a changing page.
|
|
1139
1173
|
|
|
1140
1174
|
Args:
|
|
1141
1175
|
check:
|
|
@@ -1169,8 +1203,8 @@ def assert_condition(
|
|
|
1169
1203
|
instead of a success message.
|
|
1170
1204
|
|
|
1171
1205
|
Tool selection:
|
|
1172
|
-
- Inspect a condition without failing ->
|
|
1173
|
-
- Wait for a condition to become true ->
|
|
1206
|
+
- Inspect a condition without failing -> check_if_condition.
|
|
1207
|
+
- Wait for a condition to become true -> wait_for_condition.
|
|
1174
1208
|
- Verify that an expected condition is true -> assert_condition.
|
|
1175
1209
|
"""
|
|
1176
1210
|
sb = _get_sb()
|
|
@@ -1389,11 +1423,14 @@ def scroll_page(
|
|
|
1389
1423
|
up/down scrolling. For example, amount=25 scrolls approximately
|
|
1390
1424
|
one quarter of the viewport height.
|
|
1391
1425
|
|
|
1392
|
-
|
|
1393
|
-
|
|
1426
|
+
Notes:
|
|
1427
|
+
Values greater than 100 for `amount` are allowed.
|
|
1428
|
+
For example, 200 means approximately two viewport heights.
|
|
1394
1429
|
|
|
1395
|
-
|
|
1396
|
-
|
|
1430
|
+
Tool selection:
|
|
1431
|
+
- Need to reveal a specific element ->
|
|
1432
|
+
use 'focus_element' with action="scroll_to_element".
|
|
1433
|
+
- Need to scroll the page by a relative amount -> use 'scroll_page'.
|
|
1397
1434
|
"""
|
|
1398
1435
|
sb = _get_sb()
|
|
1399
1436
|
|
|
@@ -1454,8 +1491,9 @@ def manage_window(
|
|
|
1454
1491
|
|
|
1455
1492
|
height: Window height for "set_rect".
|
|
1456
1493
|
|
|
1457
|
-
|
|
1458
|
-
|
|
1494
|
+
Notes:
|
|
1495
|
+
Use this tool for browser-window geometry and state.
|
|
1496
|
+
Use `manage_tabs` for switching between browser tabs.
|
|
1459
1497
|
"""
|
|
1460
1498
|
sb = _get_sb()
|
|
1461
1499
|
|
|
@@ -1486,12 +1524,12 @@ def manage_window(
|
|
|
1486
1524
|
@handle_sb_errors
|
|
1487
1525
|
def manage_tabs(
|
|
1488
1526
|
action: Literal[
|
|
1489
|
-
"
|
|
1490
|
-
"
|
|
1491
|
-
"
|
|
1492
|
-
"
|
|
1493
|
-
"
|
|
1494
|
-
] = "
|
|
1527
|
+
"list_tabs",
|
|
1528
|
+
"open_new_tab",
|
|
1529
|
+
"switch_to_tab",
|
|
1530
|
+
"switch_to_newest_tab",
|
|
1531
|
+
"close_active_tab",
|
|
1532
|
+
] = "list_tabs",
|
|
1495
1533
|
url: str | None = None,
|
|
1496
1534
|
tab_index: int | None = None,
|
|
1497
1535
|
switch_to: bool = True,
|
|
@@ -1499,29 +1537,38 @@ def manage_tabs(
|
|
|
1499
1537
|
"""Manage browser tabs, including opening new ones.
|
|
1500
1538
|
|
|
1501
1539
|
Use this for listing, opening, switching, or closing tabs.
|
|
1502
|
-
Use `
|
|
1540
|
+
Use `open_url` and `manage_history` for navigation within the active tab.
|
|
1503
1541
|
|
|
1504
1542
|
Args:
|
|
1505
1543
|
action:
|
|
1506
|
-
- "
|
|
1507
|
-
Use this to find the tab_index for "
|
|
1508
|
-
- "
|
|
1509
|
-
- "
|
|
1510
|
-
- "
|
|
1511
|
-
- "
|
|
1544
|
+
- "list_tabs": Return each tab's index, URL, and title.
|
|
1545
|
+
Use this to find the tab_index for "switch_to_tab".
|
|
1546
|
+
- "open_new_tab": Open a new tab, optionally navigating to `url`.
|
|
1547
|
+
- "switch_to_tab": Switch to the tab at tab_index from "list_tabs".
|
|
1548
|
+
- "switch_to_newest_tab": Switch to the newest tab.
|
|
1549
|
+
- "close_active_tab": Close the active tab. This action must be
|
|
1550
|
+
followed by a 'manage_tabs' action that switches to a new
|
|
1551
|
+
tab, such as "switch_to_tab" or "switch_to_newest_tab".
|
|
1552
|
+
|
|
1553
|
+
url: URL for "open_new_tab". If not provided, "about:blank" is used.
|
|
1512
1554
|
|
|
1513
|
-
|
|
1555
|
+
tab_index: Tab index from "list_tabs" that is only used for the
|
|
1556
|
+
"switch_to_tab" action.)
|
|
1514
1557
|
|
|
1515
|
-
|
|
1558
|
+
switch_to: If using "open_new_tab", switch to the new tab when True.
|
|
1516
1559
|
|
|
1517
|
-
|
|
1560
|
+
Notes:
|
|
1561
|
+
Tab indexes are session-relative and may change after tabs are opened
|
|
1562
|
+
or closed. Use "list_tabs" to get current indexes before switching
|
|
1563
|
+
by index.
|
|
1518
1564
|
|
|
1519
|
-
|
|
1520
|
-
|
|
1565
|
+
Error behavior:
|
|
1566
|
+
If there's an error during any of the tab actions, then
|
|
1567
|
+
@handle_sb_errors will propagate the exception as an error message.
|
|
1521
1568
|
"""
|
|
1522
1569
|
sb = _get_sb()
|
|
1523
1570
|
|
|
1524
|
-
if action == "
|
|
1571
|
+
if action == "list_tabs":
|
|
1525
1572
|
tabs = sb.get_tabs()
|
|
1526
1573
|
return [
|
|
1527
1574
|
{
|
|
@@ -1532,11 +1579,13 @@ def manage_tabs(
|
|
|
1532
1579
|
for i, t in enumerate(tabs)
|
|
1533
1580
|
]
|
|
1534
1581
|
|
|
1535
|
-
if action == "
|
|
1582
|
+
if action == "open_new_tab":
|
|
1583
|
+
if not url:
|
|
1584
|
+
url = "about:blank"
|
|
1536
1585
|
sb.open_new_tab(url=url, switch_to=switch_to)
|
|
1537
1586
|
return f"Opened new tab (url={url!r}, switch_to={switch_to})"
|
|
1538
1587
|
|
|
1539
|
-
if action == "
|
|
1588
|
+
if action == "switch_to_tab":
|
|
1540
1589
|
if tab_index is None:
|
|
1541
1590
|
return (
|
|
1542
1591
|
"Error: action='switch' requires tab_index "
|
|
@@ -1554,17 +1603,17 @@ def manage_tabs(
|
|
|
1554
1603
|
sb.switch_to_tab(tabs[tab_index])
|
|
1555
1604
|
return f"Switched to tab {tab_index}"
|
|
1556
1605
|
|
|
1557
|
-
if action == "
|
|
1606
|
+
if action == "switch_to_newest_tab":
|
|
1558
1607
|
sb.switch_to_newest_tab()
|
|
1559
1608
|
return "Switched to newest tab."
|
|
1560
1609
|
|
|
1561
|
-
if action == "
|
|
1610
|
+
if action == "close_active_tab":
|
|
1562
1611
|
sb.close_active_tab()
|
|
1563
1612
|
return "Closed active tab."
|
|
1564
1613
|
|
|
1565
1614
|
return (
|
|
1566
|
-
f"Error: unknown action '{action}'. Use '
|
|
1567
|
-
f"'
|
|
1615
|
+
f"Error: unknown action '{action}'. Use 'list_tabs', 'open_new_tab', "
|
|
1616
|
+
f"'switch_to_tab', 'switch_to_newest_tab', or 'close_active_tab'."
|
|
1568
1617
|
)
|
|
1569
1618
|
|
|
1570
1619
|
|
|
@@ -1580,12 +1629,12 @@ def solve_captcha() -> str:
|
|
|
1580
1629
|
|
|
1581
1630
|
This tool attempts to interact with CAPTCHA controls such as Cloudflare
|
|
1582
1631
|
Turnstile, reCAPTCHA, hCaptcha, DataDome Slider, or FriendlyCaptcha via
|
|
1583
|
-
the Chrome DevTools Protocol (CDP), which is stealthier than
|
|
1584
|
-
|
|
1632
|
+
the Chrome DevTools Protocol (CDP), which is usually stealthier than
|
|
1633
|
+
JavaScript because CDP actions can avoid triggering `isTrusted: false`.
|
|
1585
1634
|
|
|
1586
1635
|
This tool automatically detects the coordinates of CAPTCHA checkboxes
|
|
1587
1636
|
for determining the correct location to perform the click. If no CAPTCHA
|
|
1588
|
-
is detected on the current page, then no click action is
|
|
1637
|
+
is detected on the current page, then no click action is attempted.
|
|
1589
1638
|
|
|
1590
1639
|
The tool does not guarantee that the CAPTCHA was solved. Some CAPTCHA
|
|
1591
1640
|
controls are embedded inside shadow DOM or otherwise do not expose an
|
|
@@ -1595,13 +1644,13 @@ def solve_captcha() -> str:
|
|
|
1595
1644
|
Tool workflow:
|
|
1596
1645
|
1. Inspect the webpage with get_content when you need to
|
|
1597
1646
|
determine whether CAPTCHA-related controls are present.
|
|
1598
|
-
2. Call solve_captcha to attempt the CAPTCHA interaction.
|
|
1599
|
-
3. Use get_page_info, get_content,
|
|
1600
|
-
or manage_cookies to inspect resulting page/session state.
|
|
1647
|
+
2. Call 'solve_captcha' to attempt the CAPTCHA interaction.
|
|
1648
|
+
3. Use 'get_page_info', 'get_content', 'check_if_condition',
|
|
1649
|
+
or 'manage_cookies' to inspect resulting page/session state.
|
|
1601
1650
|
|
|
1602
1651
|
Returns:
|
|
1603
1652
|
A message confirming that the CAPTCHA interaction was attempted.
|
|
1604
|
-
|
|
1653
|
+
The message is the same for both successful and failed attempts.
|
|
1605
1654
|
"""
|
|
1606
1655
|
sb = _get_sb()
|
|
1607
1656
|
sb.solve_captcha()
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# seleniumbase package
|
|
2
|
-
__version__ = "4.54.
|
|
2
|
+
__version__ = "4.54.5"
|
|
@@ -3034,8 +3034,10 @@ class CDPMethods():
|
|
|
3034
3034
|
self.__slow_mode_pause_if_set()
|
|
3035
3035
|
self.loop.run_until_complete(self.page.wait(0.1))
|
|
3036
3036
|
|
|
3037
|
-
def hover_element(self, selector, timeframe=0.27):
|
|
3038
|
-
|
|
3037
|
+
def hover_element(self, selector, timeframe=0.27, timeout=None):
|
|
3038
|
+
if not timeout:
|
|
3039
|
+
timeout = settings.SMALL_TIMEOUT
|
|
3040
|
+
element = self.select(selector, timeout=timeout)
|
|
3039
3041
|
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
|
3040
3042
|
with gui_lock:
|
|
3041
3043
|
self.bring_active_window_to_front()
|
|
@@ -3043,11 +3045,13 @@ class CDPMethods():
|
|
|
3043
3045
|
element.mouse_move()
|
|
3044
3046
|
time.sleep(timeframe)
|
|
3045
3047
|
|
|
3046
|
-
def hover_and_click(self, hover_selector, click_selector):
|
|
3048
|
+
def hover_and_click(self, hover_selector, click_selector, timeout=None):
|
|
3049
|
+
if not timeout:
|
|
3050
|
+
timeout = settings.SMALL_TIMEOUT
|
|
3047
3051
|
if getattr(sb_config, "_cdp_mobile_mode", None):
|
|
3048
|
-
self.select(click_selector).click()
|
|
3052
|
+
self.select(click_selector, timeout=timeout).click()
|
|
3049
3053
|
return
|
|
3050
|
-
hover_element = self.select(hover_selector)
|
|
3054
|
+
hover_element = self.select(hover_selector, timeout=timeout)
|
|
3051
3055
|
gui_lock = FileLock(constants.MultiBrowser.PYAUTOGUILOCK)
|
|
3052
3056
|
with gui_lock:
|
|
3053
3057
|
self.bring_active_window_to_front()
|
|
@@ -2772,7 +2772,7 @@ class BaseCase(unittest.TestCase):
|
|
|
2772
2772
|
original_by = by
|
|
2773
2773
|
selector, by = self.__recalculate_selector(selector, by)
|
|
2774
2774
|
if self.__is_cdp_swap_needed():
|
|
2775
|
-
self.cdp.hover_element(selector)
|
|
2775
|
+
self.cdp.hover_element(selector, timeout=timeout)
|
|
2776
2776
|
return
|
|
2777
2777
|
self.wait_for_element_visible(
|
|
2778
2778
|
original_selector, by=original_by, timeout=timeout
|
|
@@ -2817,7 +2817,9 @@ class BaseCase(unittest.TestCase):
|
|
|
2817
2817
|
click_selector, click_by
|
|
2818
2818
|
)
|
|
2819
2819
|
if self.__is_cdp_swap_needed():
|
|
2820
|
-
self.cdp.hover_and_click(
|
|
2820
|
+
self.cdp.hover_and_click(
|
|
2821
|
+
hover_selector, click_selector, timeout=timeout
|
|
2822
|
+
)
|
|
2821
2823
|
return
|
|
2822
2824
|
dropdown_element = self.wait_for_element_visible(
|
|
2823
2825
|
original_selector, by=original_by, timeout=timeout
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: seleniumbase
|
|
3
|
-
Version: 4.54.
|
|
3
|
+
Version: 4.54.5
|
|
4
4
|
Summary: SeleniumBase is a framework for web crawling, scraping, and testing. Supports pytest. CDP Mode adds stealth. Includes many tools.
|
|
5
5
|
Home-page: https://github.com/seleniumbase/SeleniumBase
|
|
6
6
|
Author: Michael Mintz
|
|
@@ -126,7 +126,7 @@ Requires-Dist: allure-pytest>=2.16.0; extra == "allure"
|
|
|
126
126
|
Requires-Dist: allure-python-commons>=2.16.0; extra == "allure"
|
|
127
127
|
Requires-Dist: allure-behave>=2.16.0; extra == "allure"
|
|
128
128
|
Provides-Extra: coverage
|
|
129
|
-
Requires-Dist: coverage>=7.16.
|
|
129
|
+
Requires-Dist: coverage>=7.16.1; extra == "coverage"
|
|
130
130
|
Requires-Dist: pytest-cov>=7.1.0; extra == "coverage"
|
|
131
131
|
Provides-Extra: flake8
|
|
132
132
|
Requires-Dist: flake8==7.3.0; extra == "flake8"
|