#!/usr/bin/env python3 """ Test script for REAL-TIME form discovery capabilities. This script tests the enhanced form filling system that: 1. NEVER uses cached selectors 2. Always uses real-time MCP tools for discovery 3. Gets fresh selectors on every request 4. Uses chrome_get_interactive_elements and chrome_get_content_web_form """ import asyncio import logging import sys import os # Add the current directory to the path so we can import our modules sys.path.append(os.path.dirname(os.path.abspath(__file__))) from mcp_chrome_client import MCPChromeClient # Set up logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) async def test_realtime_discovery(): """Test the real-time form discovery capabilities""" # Initialize MCP Chrome client client = MCPChromeClient( server_type="http", server_url="http://127.0.0.1:12306/mcp" ) try: # Connect to MCP server logger.info("Connecting to MCP server...") await client.connect() logger.info("Connected successfully!") # Test 1: Navigate to Google (fresh page) logger.info("=== Test 1: Navigate to Google ===") result = await client._navigate_mcp("https://www.google.com") logger.info(f"Navigation result: {result}") await asyncio.sleep(3) # Wait for page to load # Test 2: Real-time discovery for search field (NO CACHE) logger.info("=== Test 2: Real-time discovery for search field ===") discovery_result = await client._discover_form_fields_dynamically("search", "python programming") logger.info(f"Real-time discovery result: {discovery_result}") # Test 3: Fill field using ONLY real-time discovery logger.info("=== Test 3: Fill field using ONLY real-time discovery ===") fill_result = await client.fill_field_by_name("search", "machine learning") logger.info(f"Real-time fill result: {fill_result}") # Test 4: Direct MCP element search logger.info("=== Test 4: Direct MCP element search ===") direct_result = await client._direct_mcp_element_search("search", "artificial intelligence") logger.info(f"Direct search result: {direct_result}") # Test 5: Navigate to different site and test real-time discovery logger.info("=== Test 5: Test real-time discovery on GitHub ===") result = await client._navigate_mcp("https://www.github.com") logger.info(f"GitHub navigation result: {result}") await asyncio.sleep(3) # Real-time discovery on GitHub github_discovery = await client._discover_form_fields_dynamically("search", "python") logger.info(f"GitHub real-time discovery: {github_discovery}") # Test 6: Test very flexible matching logger.info("=== Test 6: Test very flexible matching ===") flexible_result = await client._direct_mcp_element_search("query", "test search") logger.info(f"Flexible matching result: {flexible_result}") # Test 7: Test common selectors generation logger.info("=== Test 7: Test common selectors generation ===") common_selectors = client._generate_common_selectors("search") logger.info(f"Generated common selectors: {common_selectors[:10]}") # Show first 10 # Test 8: Navigate to a form-heavy site logger.info("=== Test 8: Test on form-heavy site ===") result = await client._navigate_mcp("https://httpbin.org/forms/post") logger.info(f"Form site navigation result: {result}") await asyncio.sleep(3) # Test real-time discovery on form fields form_fields = ["email", "password", "comment"] for field in form_fields: logger.info(f"Testing real-time discovery for field: {field}") field_result = await client._discover_form_fields_dynamically(field, f"test_{field}") logger.info(f"Field '{field}' discovery: {field_result}") logger.info("=== All real-time discovery tests completed! ===") except Exception as e: logger.error(f"Test failed with error: {e}") import traceback traceback.print_exc() finally: # Disconnect from MCP server try: await client.disconnect() logger.info("Disconnected from MCP server") except Exception as e: logger.error(f"Error disconnecting: {e}") async def test_mcp_tools_directly(): """Test MCP tools directly to verify real-time capabilities""" logger.info("=== Testing MCP tools directly ===") client = MCPChromeClient(server_type="http", server_url="http://127.0.0.1:12306/mcp") try: await client.connect() # Navigate to Google await client._navigate_mcp("https://www.google.com") await asyncio.sleep(3) # Test chrome_get_interactive_elements directly logger.info("Testing chrome_get_interactive_elements...") interactive_result = await client._call_mcp_tool("chrome_get_interactive_elements", { "types": ["input", "textarea", "select"] }) if interactive_result and "elements" in interactive_result: elements = interactive_result["elements"] logger.info(f"Found {len(elements)} interactive elements") for i, element in enumerate(elements[:5]): # Show first 5 attrs = element.get("attributes", {}) logger.info(f"Element {i+1}: {element.get('tagName')} - name: {attrs.get('name')}, id: {attrs.get('id')}, type: {attrs.get('type')}") # Test chrome_get_content_web_form directly logger.info("Testing chrome_get_content_web_form...") form_result = await client._call_mcp_tool("chrome_get_content_web_form", {}) if form_result: logger.info(f"Form content result: {str(form_result)[:200]}...") # Show first 200 chars # Test chrome_get_web_content for all inputs logger.info("Testing chrome_get_web_content for all inputs...") content_result = await client._call_mcp_tool("chrome_get_web_content", { "selector": "input, textarea, select", "textOnly": False }) if content_result: logger.info(f"Web content result: {str(content_result)[:200]}...") # Show first 200 chars except Exception as e: logger.error(f"Direct MCP tool test failed: {e}") import traceback traceback.print_exc() finally: try: await client.disconnect() except Exception: pass async def test_field_matching_algorithms(): """Test the field matching algorithms""" logger.info("=== Testing field matching algorithms ===") client = MCPChromeClient(server_type="http", server_url="http://127.0.0.1:12306/mcp") # Test elements (simulated) test_elements = [ { "tagName": "input", "attributes": { "name": "q", "type": "search", "placeholder": "Search Google or type a URL", "aria-label": "Search" } }, { "tagName": "input", "attributes": { "name": "email", "type": "email", "placeholder": "Enter your email address" } }, { "tagName": "input", "attributes": { "name": "user_password", "type": "password", "placeholder": "Password" } }, { "tagName": "textarea", "attributes": { "name": "message", "placeholder": "Type your message here", "aria-label": "Message" } } ] test_field_names = [ "search", "query", "q", "email", "mail", "e-mail", "password", "pass", "user password", "message", "comment", "text" ] logger.info("Testing standard field matching...") for field_name in test_field_names: logger.info(f"\nTesting field name: '{field_name}'") for i, element in enumerate(test_elements): is_match = client._is_field_match(element, field_name.lower()) selector = client._extract_best_selector(element) logger.info(f" Element {i+1} ({element['tagName']}): Match={is_match}, Selector={selector}") logger.info("\nTesting very flexible matching...") for field_name in test_field_names: logger.info(f"\nTesting flexible field name: '{field_name}'") for i, element in enumerate(test_elements): is_match = client._is_very_flexible_match(element, field_name.lower()) logger.info(f" Element {i+1} ({element['tagName']}): Flexible Match={is_match}") def main(): """Main function to run the tests""" logger.info("Starting REAL-TIME form discovery tests...") # Check if MCP server is likely running import socket try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(1) result = sock.connect_ex(('127.0.0.1', 12306)) sock.close() if result != 0: logger.warning("MCP server doesn't appear to be running on port 12306") logger.warning("Please start the MCP server before running this test") return except Exception as e: logger.warning(f"Could not check MCP server status: {e}") # Run the tests asyncio.run(test_field_matching_algorithms()) asyncio.run(test_mcp_tools_directly()) asyncio.run(test_realtime_discovery()) if __name__ == "__main__": main()