first commit
This commit is contained in:
241
agent-livekit/test_login_button_click.py
Normal file
241
agent-livekit/test_login_button_click.py
Normal file
@@ -0,0 +1,241 @@
|
||||
#!/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())
|
Reference in New Issue
Block a user