Skip to main content
Glama

MCP Selenium WebDriver

by Nixon-Suarez
  • Linux
  • Apple
test_server.py29.1 kB
#!/usr/bin/env python3 """ Script de pruebas para validar el servidor MCP Selenium WebDriver. """ import sys import os import time import traceback from typing import Dict, Any, List # Importar módulos del servidor from config import DEFAULT_CONFIG, STEALTH_CONFIG from session_manager import SessionManager from selenium_tools import SeleniumTools from stealth_features import StealthFeatures from browser_detection import BrowserDetection from browser_manager import WebDriverManager class ServerTester: """Clase para probar las funcionalidades del servidor.""" def __init__(self): self.config = DEFAULT_CONFIG self.session_manager = SessionManager(self.config) self.selenium_tools = SeleniumTools(self.session_manager) self.stealth_features = StealthFeatures(self.session_manager) self.browser_detection = BrowserDetection() self.webdriver_manager = WebDriverManager() self.test_results = [] self.active_sessions = [] def log_test(self, test_name: str, success: bool, message: str = "", details: Any = None): """Registra el resultado de una prueba.""" result = { "test": test_name, "success": success, "message": message, "details": details, "timestamp": time.time() } self.test_results.append(result) status = "✅ PASS" if success else "❌ FAIL" print(f"{status} {test_name}: {message}") if not success and details: print(f" Detalles: {details}") def test_browser_detection(self) -> bool: """Prueba la detección de navegadores.""" print("\n=== Prueba: Detección de Navegadores ===") try: # Detectar navegadores disponibles browsers = self.browser_detection.detect_available_browsers() self.log_test( "Detección de navegadores", len(browsers) > 0, f"Detectados {len(browsers)} navegadores", browsers ) # Obtener navegador recomendado recommended = self.browser_detection.get_recommended_browser() self.log_test( "Navegador recomendado", recommended in ["chrome", "firefox"], f"Recomendado: {recommended}" ) # Verificar soporte de WebDriver support = self.browser_detection.check_webdriver_support("chrome") self.log_test( "Soporte WebDriver Chrome", support["selenium_support"], f"Selenium: {support['selenium_support']}, WebDriver Manager: {support['webdriver_manager_support']}" ) return True except Exception as e: self.log_test("Detección de navegadores", False, str(e), traceback.format_exc()) return False def test_webdriver_creation(self) -> bool: """Prueba la creación de WebDriver.""" print("\n=== Prueba: Creación de WebDriver ===") try: # Crear driver básico driver_and_data = self.webdriver_manager.create_driver( browser_type="chrome", browser_options=self.config.browser_options ) driver = driver_and_data["driver"] user_data_dir = driver_and_data.get("user_data_dir") # Puede ser None self.log_test( "Creación de WebDriver", driver is not None, "WebDriver creado exitosamente" ) # Probar navegación básica driver.get("data:text/html,<html><body><h1>Test Page</h1></body></html>") title = driver.title self.log_test( "Navegación básica", "Test Page" in driver.page_source, f"Título: {title}" ) # Cerrar driver driver.quit() return True except Exception as e: self.log_test("Creación de WebDriver", False, str(e), traceback.format_exc()) return False def test_session_management(self) -> bool: """Prueba la gestión de sesiones.""" print("\n=== Prueba: Gestión de Sesiones ===") try: # Crear sesión result = self.selenium_tools.start_browser( browser_type="chrome", options={"headless": True} ) self.log_test( "Creación de sesión", result["success"], result["message"] ) if not result["success"]: return False session_id = result["session_id"] self.active_sessions.append(session_id) # Verificar que la sesión existe session = self.session_manager.get_session(session_id) self.log_test( "Verificación de sesión", session is not None, f"Sesión {session_id} encontrada" ) # Listar sesiones sessions = self.session_manager.list_sessions() self.log_test( "Listado de sesiones", len(sessions) > 0, f"Sesiones activas: {len(sessions)}" ) return True except Exception as e: self.log_test("Gestión de sesiones", False, str(e), traceback.format_exc()) return False def test_navigation(self) -> bool: """Prueba la navegación web.""" print("\n=== Prueba: Navegación Web ===") if not self.active_sessions: self.log_test("Navegación", False, "No hay sesiones activas") return False session_id = self.active_sessions[0] try: # Navegar a página de prueba result = self.selenium_tools.navigate_to_url( session_id, "data:text/html,<html><head><title>Test Navigation</title></head><body><h1>Navigation Test</h1><p>This is a test page.</p></body></html>" ) self.log_test( "Navegación a URL", result["success"], result["message"] ) # Obtener información de la página page_info = self.selenium_tools.get_page_info(session_id) self.log_test( "Información de página", page_info["success"] and "Test Navigation" in page_info["title"], f"Título: {page_info.get('title', 'N/A')}" ) return True except Exception as e: self.log_test("Navegación", False, str(e), traceback.format_exc()) return False def test_element_interaction(self) -> bool: """Prueba la interacción con elementos.""" print("\n=== Prueba: Interacción con Elementos ===") if not self.active_sessions: self.log_test("Interacción con elementos", False, "No hay sesiones activas") return False session_id = self.active_sessions[0] try: # Navegar a página con elementos html_content = """ <html> <head><title>Element Test</title></head> <body> <h1 id="title">Element Interaction Test</h1> <input id="text-input" type="text" placeholder="Enter text here"> <button id="test-button">Click Me</button> <div class="test-div">Test Content</div> <a href="#" id="test-link">Test Link</a> </body> </html> """ nav_result = self.selenium_tools.navigate_to_url( session_id, f"data:text/html,{html_content}" ) if not nav_result["success"]: self.log_test("Navegación para elementos", False, nav_result["message"]) return False # Buscar elemento por ID find_result = self.selenium_tools.find_element( session_id, "id", "title" ) self.log_test( "Búsqueda de elemento por ID", find_result["success"], f"Elemento encontrado: {find_result.get('element', {}).get('tag_name', 'N/A')}" ) # Buscar múltiples elementos multi_result = self.selenium_tools.find_element( session_id, "tag_name", "input", multiple=True ) self.log_test( "Búsqueda múltiple de elementos", multi_result["success"], f"Elementos encontrados: {multi_result.get('elements_found', 0)}" ) # Escribir texto type_result = self.selenium_tools.type_text( session_id, "id", "text-input", "Texto de prueba" ) self.log_test( "Escritura de texto", type_result["success"], type_result["message"] ) # Hacer clic en botón click_result = self.selenium_tools.click_element( session_id, "id", "test-button" ) self.log_test( "Clic en elemento", click_result["success"], click_result["message"] ) return True except Exception as e: self.log_test("Interacción con elementos", False, str(e), traceback.format_exc()) return False def test_javascript_execution(self) -> bool: """Prueba la ejecución de JavaScript.""" print("\n=== Prueba: Ejecución de JavaScript ===") if not self.active_sessions: self.log_test("Ejecución de JavaScript", False, "No hay sesiones activas") return False session_id = self.active_sessions[0] try: # Ejecutar JavaScript simple js_result = self.selenium_tools.execute_script( session_id, "return document.title;" ) self.log_test( "JavaScript simple", js_result["success"], f"Resultado: {js_result.get('result', 'N/A')}" ) # Ejecutar JavaScript complejo complex_js = """ return { title: document.title, url: window.location.href, elements: document.querySelectorAll('*').length, timestamp: new Date().toISOString() }; """ complex_result = self.selenium_tools.execute_script(session_id, complex_js) self.log_test( "JavaScript complejo", complex_result["success"] and isinstance(complex_result.get("result"), dict), f"Elementos en página: {complex_result.get('result', {}).get('elements', 'N/A')}" ) return True except Exception as e: self.log_test("Ejecución de JavaScript", False, str(e), traceback.format_exc()) return False def test_stealth_features(self) -> bool: """Prueba las características stealth.""" print("\n=== Prueba: Características Stealth ===") if not self.active_sessions: self.log_test("Características stealth", False, "No hay sesiones activas") return False session_id = self.active_sessions[0] try: # Aplicar modo stealth stealth_result = self.stealth_features.apply_stealth_mode(session_id) self.log_test( "Aplicación de modo stealth", stealth_result["success"], f"Scripts aplicados: {len(stealth_result.get('applied_scripts', []))}" ) # Randomizar user agent ua_result = self.stealth_features.randomize_user_agent(session_id) self.log_test( "Randomización de user agent", ua_result["success"], f"Nuevo UA: {ua_result.get('new_user_agent', 'N/A')[:50]}..." ) # Randomizar viewport viewport_result = self.stealth_features.randomize_viewport(session_id) self.log_test( "Randomización de viewport", viewport_result["success"], f"Nuevo tamaño: {viewport_result.get('new_size', 'N/A')}" ) # Delay aleatorio delay_result = self.stealth_features.add_random_delay(0.1, 0.5) self.log_test( "Delay aleatorio", delay_result["success"], f"Delay aplicado: {delay_result.get('delay_seconds', 'N/A')}s" ) return True except Exception as e: self.log_test("Características stealth", False, str(e), traceback.format_exc()) return False def test_screenshot(self) -> bool: """Prueba la captura de pantalla.""" print("\n=== Prueba: Captura de Pantalla ===") if not self.active_sessions: self.log_test("Captura de pantalla", False, "No hay sesiones activas") return False session_id = self.active_sessions[0] try: # Tomar captura de pantalla screenshot_result = self.selenium_tools.take_screenshot( session_id, "/tmp/test_screenshot.png" ) self.log_test( "Captura de pantalla", screenshot_result["success"], screenshot_result["message"] ) # Verificar que el archivo se creó import os file_exists = os.path.exists("/tmp/test_screenshot.png") self.log_test( "Archivo de captura creado", file_exists, f"Archivo existe: {file_exists}" ) return True except Exception as e: self.log_test("Captura de pantalla", False, str(e), traceback.format_exc()) return False def test_cookie_management(self) -> bool: """Prueba la gestión de cookies.""" print("\n=== Prueba: Gestión de Cookies ===") if not self.active_sessions: self.log_test("Gestión de cookies", False, "No hay sesiones activas") return False session_id = self.active_sessions[0] try: # Navegar a una página real para poder agregar cookies nav_result = self.selenium_tools.navigate_to_url( session_id, "https://httpbin.org/cookies" ) if not nav_result["success"]: # Si no se puede acceder a httpbin, usar página local self.selenium_tools.navigate_to_url( session_id, "data:text/html,<html><body><h1>Cookie Test</h1></body></html>" ) # Obtener cookies iniciales initial_cookies = self.stealth_features.manage_cookies( session_id, "get_all" ) self.log_test( "Obtener cookies iniciales", initial_cookies["success"], f"Cookies iniciales: {initial_cookies.get('count', 0)}" ) # Agregar cookie de prueba add_result = self.stealth_features.manage_cookies( session_id, "add", cookie_data={ "name": "test_cookie", "value": "test_value" } ) self.log_test( "Agregar cookie", add_result["success"], add_result["message"] ) # Verificar que la cookie se agregó final_cookies = self.stealth_features.manage_cookies( session_id, "get_all" ) cookie_added = final_cookies.get("count", 0) > initial_cookies.get("count", 0) self.log_test( "Verificar cookie agregada", cookie_added, f"Cookies finales: {final_cookies.get('count', 0)}" ) return True except Exception as e: self.log_test("Gestión de cookies", False, str(e), traceback.format_exc()) return False def cleanup(self): """Limpia las sesiones de prueba.""" print("\n=== Limpieza ===") try: for session_id in self.active_sessions: result = self.selenium_tools.close_browser(session_id) print(f"Cerrando sesión {session_id}: {result.get('message', 'OK')}") self.active_sessions.clear() # Cerrar todas las sesiones restantes self.session_manager.close_all_sessions() except Exception as e: print(f"Error en limpieza: {e}") def run_all_tests(self) -> Dict[str, Any]: """Ejecuta todas las pruebas.""" print("🚀 Iniciando pruebas del Servidor MCP Selenium WebDriver\n") tests = [ ("Detección de navegadores", self.test_browser_detection), ("Creación de WebDriver", self.test_webdriver_creation), ("Gestión de sesiones", self.test_session_management), ("Navegación web", self.test_navigation), ("Interacción con elementos", self.test_element_interaction), ("Ejecución de JavaScript", self.test_javascript_execution), ("Características stealth", self.test_stealth_features), ("Captura de pantalla", self.test_screenshot), ("Gestión de cookies", self.test_cookie_management), ("Herramientas adicionales", self.test_additional_tools) ] start_time = time.time() for test_name, test_func in tests: try: test_func() except Exception as e: self.log_test(test_name, False, f"Excepción no manejada: {str(e)}") print() # Línea en blanco entre pruebas # Limpieza self.cleanup() # Resumen end_time = time.time() duration = end_time - start_time total_tests = len(self.test_results) passed_tests = sum(1 for r in self.test_results if r["success"]) failed_tests = total_tests - passed_tests success_rate = (passed_tests / total_tests) * 100 if total_tests > 0 else 0 print("="*60) print("📊 RESUMEN DE PRUEBAS") print("="*60) print(f"Tiempo total: {duration:.2f} segundos") print(f"Pruebas ejecutadas: {total_tests}") print(f"Exitosas: {passed_tests}") print(f"Fallidas: {failed_tests}") print(f"Tasa de éxito: {success_rate:.1f}%") if failed_tests > 0: print("\n❌ PRUEBAS FALLIDAS:") for result in self.test_results: if not result["success"]: print(f" - {result['test']}: {result['message']}") return { "total_tests": total_tests, "passed_tests": passed_tests, "failed_tests": failed_tests, "success_rate": success_rate, "duration": duration, "results": self.test_results } def test_additional_tools(self) -> bool: """Prueba las herramientas adicionales: is_element_empty, reescribir_HTML, handle_popup.""" print("\n=== Prueba: Herramientas Adicionales ===") if not self.active_sessions: self.log_test("Herramientas adicionales", False, "No hay sesiones activas") return False session_id = self.active_sessions[0] try: # Crear página de prueba con elementos para las nuevas herramientas test_html = """ <html> <head><title>Test Additional Tools</title></head> <body> <h1 id="main-title">Prueba de Herramientas Adicionales</h1> <!-- Elementos para is_element_empty --> <input id="empty-input" type="text" placeholder="Campo vacío"> <input id="filled-input" type="text" value="Texto existente"> <textarea id="empty-textarea"></textarea> <div id="empty-div"></div> <div id="filled-div">Contenido del div</div> <!-- Elemento para reescribir_HTML --> <div id="target-div">Contenido original</div> <!-- Popup para handle_popup --> <div id="test-popup" style="display:none; position:fixed; top:50px; left:50px; background:white; border:1px solid black; padding:20px;"> <h3 id="popup-title">Título del Popup</h3> <p id="popup-content">Este es el contenido del popup de prueba.</p> <button onclick="this.parentElement.style.display='none'">Cerrar</button> </div> <button id="show-popup" onclick="document.getElementById('test-popup').style.display='block'">Mostrar Popup</button> <script> // Mostrar popup automáticamente después de 2 segundos para la prueba setTimeout(function() { document.getElementById('test-popup').style.display = 'block'; }, 2000); </script> </body> </html> """ # Navegar a la página de prueba nav_result = self.selenium_tools.navigate_to_url( session_id, f"data:text/html,{test_html}" ) if not nav_result["success"]: self.log_test("Navegación para herramientas adicionales", False, nav_result["message"]) return False # Esperar un momento para que la página cargue import time time.sleep(1) # ===== PRUEBA: is_element_empty ===== # Probar con input vacío empty_result = self.selenium_tools.is_element_empty( session_id, "id", "empty-input" ) self.log_test( "is_element_empty - Input vacío", empty_result["success"] and empty_result.get("is_empty", False), f"Resultado: {empty_result.get('message', 'N/A')}" ) # Probar con input lleno filled_result = self.selenium_tools.is_element_empty( session_id, "id", "filled-input" ) self.log_test( "is_element_empty - Input lleno", filled_result["success"] and not filled_result.get("is_empty", True), f"Resultado: {filled_result.get('message', 'N/A')}" ) # Probar con div vacío empty_div_result = self.selenium_tools.is_element_empty( session_id, "id", "empty-div" ) self.log_test( "is_element_empty - Div vacío", empty_div_result["success"] and empty_div_result.get("is_empty", False), f"Resultado: {empty_div_result.get('message', 'N/A')}" ) # Probar con div lleno filled_div_result = self.selenium_tools.is_element_empty( session_id, "id", "filled-div" ) self.log_test( "is_element_empty - Div lleno", filled_div_result["success"] and not filled_div_result.get("is_empty", True), f"Resultado: {filled_div_result.get('message', 'N/A')}" ) # ===== PRUEBA: reescribir_HTML ===== new_html = '<div id="target-div" style="color: red; font-weight: bold;">¡Contenido reescrito exitosamente!</div>' rewrite_result = self.selenium_tools.reescribir_HTML( session_id, new_html, "id", "target-div" ) self.log_test( "reescribir_HTML", rewrite_result["success"], rewrite_result.get("message", "N/A") ) # Verificar que el HTML se cambió if rewrite_result["success"]: # Buscar el elemento modificado modified_element = self.selenium_tools.find_element( session_id, "id", "target-div" ) if modified_element["success"]: element_text = modified_element["element"]["text"] self.log_test( "Verificación HTML reescrito", "reescrito exitosamente" in element_text, f"Nuevo texto: {element_text}" ) # ===== PRUEBA: handle_popup ===== # Esperar a que aparezca el popup (el script lo muestra después de 2 segundos) time.sleep(2.5) popup_result = self.selenium_tools.handle_popup( session_id, "id", "test-popup", "popup-title", "popup-content", True ) self.log_test( "handle_popup - Detección", popup_result["success"], popup_result.get("message", "N/A") ) if popup_result["success"] and popup_result.get("popup_detected"): self.log_test( "handle_popup - Contenido", popup_result.get("title") == "Título del Popup", f"Título: {popup_result.get('title', 'N/A')}, Contenido: {popup_result.get('content', 'N/A')[:50]}..." ) # Probar handle_popup cuando no hay popup (cerrar el popup primero) self.selenium_tools.click_element(session_id, "xpath", "//button[contains(text(), 'Cerrar')]") time.sleep(0.5) no_popup_result = self.selenium_tools.handle_popup( session_id, "id", "test-popup", "popup-title", "popup-content", False ) self.log_test( "handle_popup - Sin popup", no_popup_result["success"] and not no_popup_result.get("popup_detected", True), no_popup_result.get("message", "N/A") ) return True except Exception as e: self.log_test("Herramientas adicionales", False, str(e), traceback.format_exc()) return False def main(): """Función principal.""" tester = ServerTester() try: results = tester.run_all_tests() if results["failed_tests"] > 0: sys.exit(1) else: print("\n🎉 ¡Todas las pruebas pasaron exitosamente!") sys.exit(0) except KeyboardInterrupt: print("\n\n⏹️ Pruebas interrumpidas por el usuario.") tester.cleanup() sys.exit(130) except Exception as e: print(f"\n💥 Error fatal en las pruebas: {e}") traceback.print_exc() tester.cleanup() sys.exit(1) if __name__ == "__main__": main()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Nixon-Suarez/MCP-Selenium-WebDriver'

If you have feedback or need assistance with the MCP directory API, please join our Discord server