#!/usr/bin/env python3 """ Login Button Click Test This script specifically tests the "click login button" scenario to debug why selectors are found but actions are not executed in the browser. """ import asyncio import logging import json import sys from mcp_chrome_client import MCPChromeClient # Configure detailed logging logging.basicConfig( level=logging.DEBUG, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.StreamHandler(sys.stdout), logging.FileHandler('login_button_test.log') ] ) logger = logging.getLogger(__name__) async def test_login_button_scenario(): """Test the specific 'click login button' scenario""" # Configuration for MCP Chrome client config = { 'mcp_server_type': 'http', 'mcp_server_url': 'http://localhost:3000/mcp', 'mcp_server_command': '', 'mcp_server_args': [] } client = MCPChromeClient(config) try: print("šŸš€ Starting Login Button Click Test...") # Step 1: Connect to MCP server print("\nšŸ“” Step 1: Connecting to MCP server...") await client.connect() print("āœ… Connected to MCP server") # Step 2: Check current page print("\nšŸ“„ Step 2: Checking current page...") try: page_info = await client._call_mcp_tool("chrome_get_web_content", { "selector": "title", "textOnly": True }) current_title = page_info.get("content", [{}])[0].get("text", "Unknown") print(f"šŸ“‹ Current page title: {current_title}") except Exception as e: print(f"āš ļø Could not get page title: {e}") # Step 3: Find all interactive elements print("\nšŸ” Step 3: Finding all interactive elements...") interactive_result = await client._call_mcp_tool("chrome_get_interactive_elements", { "types": ["button", "a", "input", "select"] }) elements = interactive_result.get("elements", []) print(f"šŸ“Š Found {len(elements)} interactive elements") # Step 4: Look for login-related elements print("\nšŸ” Step 4: Searching for login-related elements...") login_keywords = ["login", "log in", "sign in", "signin", "enter", "submit"] login_elements = [] for i, element in enumerate(elements): element_text = element.get("textContent", "").lower() element_attrs = element.get("attributes", {}) # Check if element matches login criteria is_login_element = False match_reasons = [] for keyword in login_keywords: if keyword in element_text: is_login_element = True match_reasons.append(f"text_contains_{keyword}") for attr_name, attr_value in element_attrs.items(): if isinstance(attr_value, str) and keyword in attr_value.lower(): is_login_element = True match_reasons.append(f"{attr_name}_contains_{keyword}") if is_login_element: selector = client._extract_best_selector(element) login_elements.append({ "index": i, "element": element, "selector": selector, "match_reasons": match_reasons, "tag": element.get("tagName", "unknown"), "text": element_text[:50], "attributes": {k: v for k, v in element_attrs.items() if k in ["id", "class", "name", "type", "value"]} }) print(f"šŸŽÆ Found {len(login_elements)} potential login elements:") for login_elem in login_elements: print(f" Element {login_elem['index']}: {login_elem['tag']} - '{login_elem['text']}' - {login_elem['selector']}") print(f" Match reasons: {', '.join(login_elem['match_reasons'])}") print(f" Attributes: {login_elem['attributes']}") # Step 5: Test voice command processing print("\nšŸŽ¤ Step 5: Testing voice command processing...") test_commands = [ "click login button", "click login", "press login button", "click sign in", "click log in" ] for command in test_commands: print(f"\nšŸ” Testing command: '{command}'") # Parse the command action, params = client._parse_voice_command(command) print(f" šŸ“‹ Parsed: action='{action}', params={params}") if action == "click": element_description = params.get("text", "") print(f" šŸŽÆ Looking for element: '{element_description}'") # Test the smart click logic try: result = await client._smart_click_mcp(element_description) print(f" āœ… Smart click result: {result}") except Exception as e: print(f" āŒ Smart click failed: {e}") # Step 6: Test direct selector clicking print("\nšŸ”§ Step 6: Testing direct selector clicking...") if login_elements: for login_elem in login_elements[:3]: # Test first 3 login elements selector = login_elem["selector"] print(f"\nšŸŽÆ Testing direct click on selector: {selector}") try: # First validate the selector exists validation = await client._call_mcp_tool("chrome_get_web_content", { "selector": selector, "textOnly": False }) if validation.get("content"): print(f" āœ… Selector validation: Element found") # Try clicking click_result = await client._call_mcp_tool("chrome_click_element", { "selector": selector }) print(f" āœ… Click result: {click_result}") # Wait a moment to see if anything happened await asyncio.sleep(2) # Check if page changed try: new_page_info = await client._call_mcp_tool("chrome_get_web_content", { "selector": "title", "textOnly": True }) new_title = new_page_info.get("content", [{}])[0].get("text", "Unknown") if new_title != current_title: print(f" šŸŽ‰ Page changed! New title: {new_title}") else: print(f" āš ļø Page title unchanged: {new_title}") except Exception as e: print(f" āš ļø Could not check page change: {e}") else: print(f" āŒ Selector validation: Element not found") except Exception as e: print(f" āŒ Direct click failed: {e}") # Step 7: Test common login button selectors print("\nšŸ”§ Step 7: Testing common login button selectors...") common_selectors = [ "button[type='submit']", "input[type='submit']", "button:contains('Login')", "button:contains('Sign In')", "[role='button'][aria-label*='login']", ".login-button", "#login-button", "#loginButton", ".btn-login", "button.login" ] for selector in common_selectors: print(f"\nšŸ” Testing common selector: {selector}") try: validation = await client._call_mcp_tool("chrome_get_web_content", { "selector": selector, "textOnly": False }) if validation.get("content"): print(f" āœ… Found element with selector: {selector}") # Try clicking click_result = await client._call_mcp_tool("chrome_click_element", { "selector": selector }) print(f" āœ… Click attempt result: {click_result}") else: print(f" āŒ No element found with selector: {selector}") except Exception as e: print(f" āŒ Selector test failed: {e}") print("\nāœ… Login button click test completed!") except Exception as e: print(f"šŸ’„ Test failed: {e}") logger.exception("Test failed with exception") finally: try: await client.disconnect() except Exception as e: print(f"āš ļø Cleanup warning: {e}") async def main(): """Main function""" await test_login_button_scenario() if __name__ == "__main__": asyncio.run(main())