Files
wehub-resource-sync 4cd2d4af2b
Test Browser Use CLI Install / uv pip install (macos-latest) (push) Waiting to run
Test Browser Use CLI Install / uv pip install (windows-latest) (push) Waiting to run
Test Browser Use CLI Install / uv pip install (ubuntu-latest) (push) Failing after 1s
Test Browser Use CLI Install / uvx browser-use from local wheel (push) Failing after 1s
Test Browser Use CLI Install / uvx browser-use[cli] from PyPI (push) Failing after 1s
package / pip-install-on-macos-latest-py-3.11 (push) Has been skipped
package / pip-install-on-macos-latest-py-3.13 (push) Has been skipped
package / pip-install-on-ubuntu-latest-py-3.11 (push) Has been skipped
package / pip-install-on-windows-latest-py-3.13 (push) Has been skipped
cloud_evals / trigger_cloud_eval_image_build (push) Failing after 1s
docker / build_publish_image (push) Failing after 1s
Test Browser Use CLI Install / browser-use skill sync (push) Failing after 1s
lint / code-style (push) Failing after 0s
lint / type-checker (push) Failing after 1s
package / pip-build (push) Failing after 1s
lint / syntax-errors (push) Failing after 3s
package / pip-install-on-ubuntu-latest-py-3.13 (push) Has been skipped
package / pip-install-on-windows-latest-py-3.11 (push) Has been skipped
test / ${{ matrix.test_filename }} (push) Has been skipped
test / evaluate-tasks (push) Has been skipped
test / setup-chromium (push) Failing after 2s
test / find_tests (push) Failing after 2s
chore: import upstream snapshot with attribution
2026-07-13 12:02:32 +08:00

276 lines
10 KiB
Python

import pytest
from pytest_httpserver import HTTPServer
from browser_use.agent.views import ActionResult
from browser_use.browser import BrowserSession
from browser_use.browser.profile import BrowserProfile
from browser_use.tools.service import Tools
@pytest.fixture(scope='session')
def http_server():
"""Create and provide a test HTTP server that serves static content."""
server = HTTPServer()
server.start()
# Add route for ARIA menu test page
server.expect_request('/aria-menu').respond_with_data(
"""
<!DOCTYPE html>
<html>
<head>
<title>ARIA Menu Test</title>
<style>
.menu {
list-style: none;
padding: 0;
margin: 0;
border: 1px solid #ccc;
background: white;
width: 200px;
}
.menu-item {
padding: 10px 20px;
border-bottom: 1px solid #eee;
}
.menu-item:hover {
background: #f0f0f0;
}
.menu-item-anchor {
text-decoration: none;
color: #333;
display: block;
}
#result {
margin-top: 20px;
padding: 10px;
border: 1px solid #ddd;
min-height: 20px;
}
</style>
</head>
<body>
<h1>ARIA Menu Test</h1>
<p>This menu uses ARIA roles instead of native select elements</p>
<!-- Exactly like the HTML provided in the issue -->
<ul class="menu menu-format-standard menu-regular" role="menu" id="pyNavigation1752753375773" style="display: block;">
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor" tabindex="0" role="menuitem">
<span class="menu-item-title-wrap"><span class="menu-item-title">Filter</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation" id="menu-item-$PpyNavigation1752753375773$ppyElements$l2">
<a href="#" onclick="pd(event);" class="menu-item-anchor menu-item-expand" tabindex="0" role="menuitem" aria-haspopup="true">
<span class="menu-item-title-wrap"><span class="menu-item-title">Sort</span></span>
</a>
<div class="menu-panel-wrapper">
<ul class="menu menu-format-standard menu-regular" role="menu" id="$PpyNavigation1752753375773$ppyElements$l2">
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor" tabindex="0" role="menuitem">
<span class="menu-item-title-wrap"><span class="menu-item-title">Lowest to highest</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor" tabindex="0" role="menuitem">
<span class="menu-item-title-wrap"><span class="menu-item-title">Highest to lowest</span></span>
</a>
</li>
</ul>
</div>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor" tabindex="0" role="menuitem">
<span class="menu-item-title-wrap"><span class="menu-item-title">Appearance</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor" tabindex="0" role="menuitem">
<span class="menu-item-title-wrap"><span class="menu-item-title">Summarize</span></span>
</a>
</li>
<li class="menu-item menu-item-enabled" role="presentation">
<a href="#" onclick="pd(event);" class="menu-item-anchor" tabindex="0" role="menuitem">
<span class="menu-item-title-wrap"><span class="menu-item-title">Delete</span></span>
</a>
</li>
</ul>
<div id="result">Click an option to see the result</div>
<script>
// Mock the pd function that prevents default
function pd(event) {
event.preventDefault();
const text = event.target.closest('[role="menuitem"]').textContent.trim();
document.getElementById('result').textContent = 'Clicked: ' + text;
}
</script>
</body>
</html>
""",
content_type='text/html',
)
yield server
server.stop()
@pytest.fixture(scope='session')
def base_url(http_server):
"""Return the base URL for the test HTTP server."""
return f'http://{http_server.host}:{http_server.port}'
@pytest.fixture(scope='module')
async def browser_session():
"""Create and provide a Browser instance with security disabled."""
browser_session = BrowserSession(
browser_profile=BrowserProfile(
headless=True,
user_data_dir=None,
keep_alive=True,
chromium_sandbox=False, # Disable sandbox for CI environment
)
)
await browser_session.start()
yield browser_session
await browser_session.kill()
@pytest.fixture(scope='function')
def tools():
"""Create and provide a Tools instance."""
return Tools()
class TestARIAMenuDropdown:
"""Test ARIA menu support for get_dropdown_options and select_dropdown_option."""
@pytest.mark.skip(reason='TODO: fix')
async def test_get_dropdown_options_with_aria_menu(self, tools, browser_session: BrowserSession, base_url):
"""Test that get_dropdown_options can retrieve options from ARIA menus."""
# Navigate to the ARIA menu test page
await tools.navigate(url=f'{base_url}/aria-menu', new_tab=False, browser_session=browser_session)
# Wait for the page to load
from browser_use.browser.events import NavigationCompleteEvent
await browser_session.event_bus.expect(NavigationCompleteEvent, timeout=10.0)
# Initialize the DOM state to populate the selector map
await browser_session.get_browser_state_summary()
# Find the ARIA menu element by ID
menu_index = await browser_session.get_index_by_id('pyNavigation1752753375773')
assert menu_index is not None, 'Could not find ARIA menu element'
# Execute the action with the menu index
result = await tools.dropdown_options(index=menu_index, browser_session=browser_session)
# Verify the result structure
assert isinstance(result, ActionResult)
assert result.extracted_content is not None
# Expected ARIA menu options
expected_options = ['Filter', 'Sort', 'Appearance', 'Summarize', 'Delete']
# Verify all options are returned
for option in expected_options:
assert option in result.extracted_content, f"Option '{option}' not found in result content"
# Verify the instruction for using the text in select_dropdown is included
assert 'Use the exact text string in select_dropdown' in result.extracted_content
@pytest.mark.skip(reason='TODO: fix')
async def test_select_dropdown_option_with_aria_menu(self, tools, browser_session: BrowserSession, base_url):
"""Test that select_dropdown_option can select an option from ARIA menus."""
# Navigate to the ARIA menu test page
await tools.navigate(url=f'{base_url}/aria-menu', new_tab=False, browser_session=browser_session)
# Wait for the page to load
from browser_use.browser.events import NavigationCompleteEvent
await browser_session.event_bus.expect(NavigationCompleteEvent, timeout=10.0)
# Initialize the DOM state to populate the selector map
await browser_session.get_browser_state_summary()
# Find the ARIA menu element by ID
menu_index = await browser_session.get_index_by_id('pyNavigation1752753375773')
assert menu_index is not None, 'Could not find ARIA menu element'
# Execute the action with the menu index to select "Filter"
result = await tools.select_dropdown(index=menu_index, text='Filter', browser_session=browser_session)
# Verify the result structure
assert isinstance(result, ActionResult)
# Core logic validation: Verify selection was successful
assert result.extracted_content is not None
assert 'selected option' in result.extracted_content.lower() or 'clicked' in result.extracted_content.lower()
assert 'Filter' in result.extracted_content
# Verify the click actually had an effect on the page using CDP
cdp_session = await browser_session.get_or_create_cdp_session()
result = await cdp_session.cdp_client.send.Runtime.evaluate(
params={'expression': "document.getElementById('result').textContent", 'returnByValue': True},
session_id=cdp_session.session_id,
)
result_text = result.get('result', {}).get('value', '')
assert 'Filter' in result_text, f"Expected 'Filter' in result text, got '{result_text}'"
@pytest.mark.skip(reason='TODO: fix')
async def test_get_dropdown_options_with_nested_aria_menu(self, tools, browser_session: BrowserSession, base_url):
"""Test that get_dropdown_options can handle nested ARIA menus (like Sort submenu)."""
# Navigate to the ARIA menu test page
await tools.navigate(url=f'{base_url}/aria-menu', new_tab=False, browser_session=browser_session)
# Wait for the page to load
from browser_use.browser.events import NavigationCompleteEvent
await browser_session.event_bus.expect(NavigationCompleteEvent, timeout=10.0)
# Initialize the DOM state to populate the selector map
await browser_session.get_browser_state_summary()
# Get the selector map
selector_map = await browser_session.get_selector_map()
# Find the nested ARIA menu element in the selector map
nested_menu_index = None
for idx, element in selector_map.items():
# Look for the nested UL with id containing "$PpyNavigation"
if (
element.tag_name.lower() == 'ul'
and '$PpyNavigation' in str(element.attributes.get('id', ''))
and element.attributes.get('role') == 'menu'
):
nested_menu_index = idx
break
# The nested menu might not be in the selector map initially if it's hidden
# In that case, we should test the main menu
if nested_menu_index is None:
# Find the main menu instead
for idx, element in selector_map.items():
if element.tag_name.lower() == 'ul' and element.attributes.get('id') == 'pyNavigation1752753375773':
nested_menu_index = idx
break
assert nested_menu_index is not None, (
f'Could not find any ARIA menu element in selector map. Available elements: {[f"{idx}: {element.tag_name}" for idx, element in selector_map.items()]}'
)
# Execute the action with the menu index
result = await tools.dropdown_options(index=nested_menu_index, browser_session=browser_session)
# Verify the result structure
assert isinstance(result, ActionResult)
assert result.extracted_content is not None
# The action should return some menu options
assert 'Use the exact text string in select_dropdown' in result.extracted_content