"""Test GetDropdownOptionsEvent and SelectDropdownOptionEvent functionality. This file consolidates all tests related to dropdown functionality including: - Native
No selection made
""", content_type='text/html', ) # Add route for ARIA menu test page server.expect_request('/aria-menu').respond_with_data( """ ARIA Menu Test

ARIA Menu Test

This menu uses ARIA roles instead of native select elements

Click an option to see the result
""", content_type='text/html', ) # Add route for custom dropdown test page server.expect_request('/custom-dropdown').respond_with_data( """ Custom Dropdown Test

Custom Dropdown Test

This is a custom dropdown implementation (like Semantic UI)

No selection made
""", 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 TestGetDropdownOptionsEvent: """Test GetDropdownOptionsEvent functionality for various dropdown types.""" @pytest.mark.skip(reason='Dropdown text assertion issue - test expects specific text format') async def test_native_select_dropdown(self, tools, browser_session: BrowserSession, base_url): """Test get_dropdown_options with native HTML select element.""" # Navigate to the native dropdown test page await tools.navigate(url=f'{base_url}/native-dropdown', new_tab=False, browser_session=browser_session) # Initialize the DOM state to populate the selector map await browser_session.get_browser_state_summary() # Find the select element by ID dropdown_index = await browser_session.get_index_by_id('test-dropdown') assert dropdown_index is not None, 'Could not find select element' # Test via tools action result = await tools.dropdown_options(index=dropdown_index, browser_session=browser_session) # Verify the result assert isinstance(result, ActionResult) assert result.extracted_content is not None # Verify all expected options are present expected_options = ['Please select', 'First Option', 'Second Option', 'Third Option'] for option in expected_options: assert option in result.extracted_content, f"Option '{option}' not found in result content" # Verify instruction is included assert 'Use the exact text string' in result.extracted_content and 'select_dropdown' in result.extracted_content # Also test direct event dispatch node = await browser_session.get_element_by_index(dropdown_index) assert node is not None event = browser_session.event_bus.dispatch(GetDropdownOptionsEvent(node=node)) dropdown_data = await event.event_result(timeout=3.0) assert dropdown_data is not None assert 'options' in dropdown_data assert 'type' in dropdown_data assert dropdown_data['type'] == 'select' @pytest.mark.skip(reason='ARIA menu detection issue - element not found in selector map') async def test_aria_menu_dropdown(self, tools, browser_session: BrowserSession, base_url): """Test get_dropdown_options with ARIA role='menu' element.""" # Navigate to the ARIA menu test page await tools.navigate(url=f'{base_url}/aria-menu', new_tab=False, browser_session=browser_session) # Initialize the DOM state await browser_session.get_browser_state_summary() # Find the ARIA menu by ID menu_index = await browser_session.get_index_by_id('pyNavigation1752753375773') assert menu_index is not None, 'Could not find ARIA menu element' # Test via tools action result = await tools.dropdown_options(index=menu_index, browser_session=browser_session) # Verify the result assert isinstance(result, ActionResult) assert result.extracted_content is not None # Verify expected ARIA menu options are present expected_options = ['Filter', 'Sort', 'Appearance', 'Summarize', 'Delete'] for option in expected_options: assert option in result.extracted_content, f"Option '{option}' not found in result content" # Also test direct event dispatch node = await browser_session.get_element_by_index(menu_index) assert node is not None event = browser_session.event_bus.dispatch(GetDropdownOptionsEvent(node=node)) dropdown_data = await event.event_result(timeout=3.0) assert dropdown_data is not None assert 'options' in dropdown_data assert 'type' in dropdown_data assert dropdown_data['type'] == 'aria' @pytest.mark.skip(reason='Custom dropdown detection issue - element not found in selector map') async def test_custom_dropdown(self, tools, browser_session: BrowserSession, base_url): """Test get_dropdown_options with custom dropdown implementation.""" # Navigate to the custom dropdown test page await tools.navigate(url=f'{base_url}/custom-dropdown', new_tab=False, browser_session=browser_session) # Initialize the DOM state await browser_session.get_browser_state_summary() # Find the custom dropdown by ID dropdown_index = await browser_session.get_index_by_id('custom-dropdown') assert dropdown_index is not None, 'Could not find custom dropdown element' # Test via tools action result = await tools.dropdown_options(index=dropdown_index, browser_session=browser_session) # Verify the result assert isinstance(result, ActionResult) assert result.extracted_content is not None # Verify expected custom dropdown options are present expected_options = ['Red', 'Green', 'Blue', 'Yellow'] for option in expected_options: assert option in result.extracted_content, f"Option '{option}' not found in result content" # Also test direct event dispatch node = await browser_session.get_element_by_index(dropdown_index) assert node is not None event = browser_session.event_bus.dispatch(GetDropdownOptionsEvent(node=node)) dropdown_data = await event.event_result(timeout=3.0) assert dropdown_data is not None assert 'options' in dropdown_data assert 'type' in dropdown_data assert dropdown_data['type'] == 'custom' class TestSelectDropdownOptionEvent: """Test SelectDropdownOptionEvent functionality for various dropdown types.""" @pytest.mark.skip(reason='Timeout issue - test takes too long to complete') async def test_select_native_dropdown_option(self, tools, browser_session: BrowserSession, base_url): """Test select_dropdown_option with native HTML select element.""" # Navigate to the native dropdown test page await tools.navigate(url=f'{base_url}/native-dropdown', new_tab=False, browser_session=browser_session) await browser_session.event_bus.expect(NavigationCompleteEvent, timeout=10.0) # Initialize the DOM state await browser_session.get_browser_state_summary() # Find the select element by ID dropdown_index = await browser_session.get_index_by_id('test-dropdown') assert dropdown_index is not None # Test via tools action result = await tools.select_dropdown(index=dropdown_index, text='Second Option', browser_session=browser_session) # Verify the result assert isinstance(result, ActionResult) assert result.extracted_content is not None assert 'Second Option' in result.extracted_content # Verify the selection actually worked 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('test-dropdown').selectedIndex", 'returnByValue': True}, session_id=cdp_session.session_id, ) selected_index = result.get('result', {}).get('value', -1) assert selected_index == 2, f'Expected selected index 2, got {selected_index}' @pytest.mark.skip(reason='Timeout issue - test takes too long to complete') async def test_select_aria_menu_option(self, tools, browser_session: BrowserSession, base_url): """Test select_dropdown_option with ARIA menu.""" # Navigate to the ARIA menu test page await tools.navigate(url=f'{base_url}/aria-menu', new_tab=False, browser_session=browser_session) await browser_session.event_bus.expect(NavigationCompleteEvent, timeout=10.0) # Initialize the DOM state await browser_session.get_browser_state_summary() # Find the ARIA menu by ID menu_index = await browser_session.get_index_by_id('pyNavigation1752753375773') assert menu_index is not None # Test via tools action result = await tools.select_dropdown(index=menu_index, text='Filter', browser_session=browser_session) # Verify the result assert isinstance(result, ActionResult) assert result.extracted_content is not None assert 'Filter' in result.extracted_content # Verify the click had an effect 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='Timeout issue - test takes too long to complete') async def test_select_custom_dropdown_option(self, tools, browser_session: BrowserSession, base_url): """Test select_dropdown_option with custom dropdown.""" # Navigate to the custom dropdown test page await tools.navigate(url=f'{base_url}/custom-dropdown', new_tab=False, browser_session=browser_session) await browser_session.event_bus.expect(NavigationCompleteEvent, timeout=10.0) # Initialize the DOM state await browser_session.get_browser_state_summary() # Find the custom dropdown by ID dropdown_index = await browser_session.get_index_by_id('custom-dropdown') assert dropdown_index is not None # Test via tools action result = await tools.select_dropdown(index=dropdown_index, text='Blue', browser_session=browser_session) # Verify the result assert isinstance(result, ActionResult) assert result.extracted_content is not None assert 'Blue' in result.extracted_content # Verify the selection worked 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 'Blue' in result_text, f"Expected 'Blue' in result text, got '{result_text}'" @pytest.mark.skip(reason='Timeout issue - test takes too long to complete') async def test_select_invalid_option_error(self, tools, browser_session: BrowserSession, base_url): """Test select_dropdown_option with non-existent option text.""" # Navigate to the native dropdown test page await tools.navigate(url=f'{base_url}/native-dropdown', new_tab=False, browser_session=browser_session) await browser_session.event_bus.expect(NavigationCompleteEvent, timeout=10.0) # Initialize the DOM state await browser_session.get_browser_state_summary() # Find the select element by ID dropdown_index = await browser_session.get_index_by_id('test-dropdown') assert dropdown_index is not None # Try to select non-existent option via direct event node = await browser_session.get_element_by_index(dropdown_index) assert node is not None event = browser_session.event_bus.dispatch(SelectDropdownOptionEvent(node=node, text='Non-existent Option')) try: selection_data = await event.event_result(timeout=3.0) # Should have an error in the result assert selection_data is not None assert 'error' in selection_data or 'not found' in str(selection_data).lower() except Exception as e: # Or raise an exception assert 'not found' in str(e).lower() or 'no option' in str(e).lower()