WebdriverIO MCP
Un servidor del Protocolo de Contexto de Modelo (MCP) que permite a Claude Desktop interactuar con navegadores web y aplicaciones móviles utilizando WebDriverIO. Automatiza navegadores Chrome, aplicaciones iOS y aplicaciones Android, todo a través de una interfaz unificada.
Documentación
Servidor MCP de WebDriverIO
Un servidor de Model Context Protocol (MCP) que permite a los asistentes de IA interactuar con navegadores web y aplicaciones móviles usando WebDriverIO. Automatiza los navegadores Chrome, Firefox, Edge y Safari, además de aplicaciones iOS y Android, todo a través de una interfaz unificada.
Instalación
Añade la siguiente configuración a los ajustes de tu cliente MCP:
Configuración estándar (funciona en la mayoría de los clientes):
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
Claude Desktop
Edita ~/Library/Application Support/Claude/claude_desktop_config.json (macOS),
%APPDATA%\Claude\claude_desktop_config.json (Windows) o ~/.config/Claude/claude_desktop_config.json (Linux):
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
Claude Code
claude mcp add wdio-mcp -- npx -y @wdio/mcp@latest
Cline
Añade a tu archivo settings.json o cline_mcp_settings.json de VS Code:
{
"mcpServers": {
"wdio-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
Cursor
Ve a Cursor Settings → MCP → Add new MCP Server, o crea .cursor/mcp.json:
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
Codex
Usa la CLI de Codex:
codex mcp add wdio-mcp npx "@wdio/mcp@latest"
O edita ~/.codex/config.toml:
[mcp_servers.wdio-mcp]
command = "npx"
args = ["@wdio/mcp@latest"]
Goose
Ve a Advanced settings → Extensions → Add custom extension, o ejecuta:
goose configure
O edita ~/.config/goose/config.yaml:
extensions:
wdio-mcp:
name: WebDriverIO MCP
cmd: npx
args: [ -y, "@wdio/mcp@latest" ]
enabled: true
type: stdio
Windsurf
Edita ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
Zed
Edita los ajustes de Zed (~/.config/zed/settings.json):
{
"context_servers": {
"wdio-mcp": {
"source": "custom",
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
VS Code (Copilot)
code --add-mcp '{"name":"wdio-mcp","command":"npx","args":["-y","@wdio/mcp@latest"]}'
⚠️ Reinicio requerido: Después de añadir la configuración, reinicia completamente tu cliente MCP para aplicar los cambios.
Opción 2: Instalación global
Si prefieres instalar globalmente:
npm install -g @wdio/mcp
Luego usa wdio-mcp como comando:
{
"mcpServers": {
"wdio-mcp": {
"command": "wdio-mcp"
}
}
}
📖 ¿Necesitas ayuda? Sigue la guía de instalación de MCP.
Transporte HTTP (para clientes que no usan subprocesos)
Por defecto, el servidor usa transporte stdio (subproceso). Para clientes que no pueden lanzar subprocesos (p. ej. llama.cpp, modo seguro de OpenAI Codex), habilita el transporte HTTP:
npx @wdio/mcp --http --port 3000
| Flag | Valor por defecto | Descripción |
|---|---|---|
--http | — | Habilita el modo de transporte HTTP |
--port | 3000 | Puerto de escucha |
--allowedHosts | localhost,127.0.0.1,::1 | Valores de cabecera Host permitidos (protección contra rebinding de DNS) |
--allowedOrigins | (ninguno — clientes de navegador bloqueados) | Valores Origin permitidos para CORS. Usa * para permitir todos. |
Luego apunta tu cliente MCP a http://localhost:3000/mcp.
Requisitos previos para la automatización de aplicaciones móviles
- Servidor Appium: Instálalo globalmente con
npm install -g appium - Controladores de plataforma:
- iOS:
appium driver install xcuitest(requiere Xcode en macOS) - Android:
appium driver install uiautomator2(requiere Android Studio)
- iOS:
- Dispositivos/Emuladores:
- Simulador de iOS (macOS) o dispositivo físico
- Emulador de Android o dispositivo físico
- Para dispositivos iOS reales: Necesitarás el UDID (Identificador Único de Dispositivo) del dispositivo
- Encuentra el UDID en macOS: Conecta el dispositivo → Abre Finder → Selecciona el dispositivo → Haz clic en el nombre/modelo del dispositivo para revelar el UDID
- Encuentra el UDID en Windows: Conecta el dispositivo → iTunes o la app Apple Devices → Haz clic en el icono del dispositivo → Haz clic en "Número de serie" para revelar el UDID
- Método con Xcode: Ventana → Devices and Simulators → Selecciona el dispositivo → El UDID se muestra como "Identifier"
Inicia el servidor Appium antes de usar las funciones móviles:
appium
# Server runs at http://127.0.0.1:4723 by default
Proveedores en la nube
Ejecuta pruebas de navegador y aplicaciones móviles en dispositivos y navegadores reales en la nube sin configuración local. Actualmente es compatible con BrowserStack, Sauce Labs, LambdaTest, TestingBot y Digital.ai Testing.
Requisitos previos
Establece las credenciales de tu proveedor como variables de entorno o en la configuración de tu cliente MCP:
BrowserStack
export BROWSERSTACK_USERNAME=your_username
export BROWSERSTACK_ACCESS_KEY=your_access_key
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": ["-y", "@wdio/mcp@latest"],
"env": {
"BROWSERSTACK_USERNAME": "your_username",
"BROWSERSTACK_ACCESS_KEY": "your_access_key"
}
}
}
}
Sauce Labs
export SAUCE_USERNAME=your_username
export SAUCE_ACCESS_KEY=your_access_key
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": ["-y", "@wdio/mcp@latest"],
"env": {
"SAUCE_USERNAME": "your_username",
"SAUCE_ACCESS_KEY": "your_access_key"
}
}
}
}
| SAUCE_USERNAME | Nombre de usuario de Sauce Labs (obligatorio) |
| SAUCE_ACCESS_KEY | Clave de acceso de Sauce Labs (obligatoria) |
El centro de datos se establece por sesión mediante el parámetro region en start_session (por defecto eu-central-1).
LambdaTest (TestMu)
export TESTMU_USERNAME=your_username
export TESTMU_ACCESS_KEY=your_access_key
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": ["-y", "@wdio/mcp@latest"],
"env": {
"TESTMU_USERNAME": "your_username",
"TESTMU_ACCESS_KEY": "your_access_key"
}
}
}
}
| TESTMU_USERNAME | Nombre de usuario de LambdaTest (obligatorio) |
| TESTMU_ACCESS_KEY | Clave de acceso de LambdaTest (obligatoria) |
TestingBot
export TESTINGBOT_KEY=your_key
export TESTINGBOT_SECRET=your_secret
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": ["-y", "@wdio/mcp@latest"],
"env": {
"TESTINGBOT_KEY": "your_key",
"TESTINGBOT_SECRET": "your_secret"
}
}
}
}
| TESTINGBOT_KEY | Clave de TestingBot (obligatoria) |
| TESTINGBOT_SECRET | Secreto de TestingBot (obligatorio) |
Digital.ai Testing
export DIGITALAI_CLOUD_URL=https://your-cloud.example.com
export DIGITALAI_ACCESS_KEY=your_access_key
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": ["-y", "@wdio/mcp@latest"],
"env": {
"DIGITALAI_CLOUD_URL": "https://your-cloud.example.com",
"DIGITALAI_ACCESS_KEY": "your_access_key"
}
}
}
}
| DIGITALAI_CLOUD_URL | Host de la nube de Digital.ai, p. ej. https://your-cloud.example.com (obligatorio) |
| DIGITALAI_ACCESS_KEY | Clave de acceso de Digital.ai (obligatoria) |
La clave de acceso se envía mediante la capacidad digitalai:options (móvil) o la capacidad plana digitalai:accessKey (web).
Informar estado aprobado/fallido: WebdriverIO usa por defecto el protocolo BiDi, sobre el cual la nube de Digital.ai no puede observar fallos de comandos, por lo que los informes muestran "Aprobado" por defecto. Para que la nube refleje el estado real aprobado/fallido, opta por el WebDriver clásico por sesión:
start_session({
provider: 'digitalai', platform: 'browser', browser: 'chrome', os: 'Windows 10',
capabilities: { 'wdio:enforceWebDriverClassic': true }
})
(Los fallos de aserción puramente del lado del cliente siguen informándose como "Aprobado"; solo se detectan los fallos que llegan a la nube como errores de comando WebDriver).
Móvil (Appium): configura tu proyecto de Digital.ai para ejecución con servidor Appium y elige su versión de Appium predeterminada mediante el ajuste "Manage default Appium server version" del proyecto: la versión se elige a nivel de proyecto (y sigue las versiones que admite tu nube), por lo que este MCP no fija una. Consulta Appium Server Test Execution.
Sesiones de navegador
Ejecuta un navegador en una combinación específica de SO/versión:
// BrowserStack
start_session({
provider: 'browserstack',
platform: 'browser',
browser: 'chrome', // chrome | firefox | edge | safari
browserVersion: 'latest', // default: latest
os: 'Windows', // e.g. "Windows", "OS X"
osVersion: '11', // e.g. "11", "Sequoia"
reporting: {
project: 'My Project',
build: 'v1.2.0',
session: 'Login flow'
}
})
// Sauce Labs
start_session({
provider: 'saucelabs',
platform: 'browser',
browser: 'chrome',
os: 'Windows', // combined with osVersion → platformName
osVersion: '11', // e.g. "11", "15" (numbered Mac naming)
region: 'eu-central-1', // default: eu-central-1
reporting: {
build: 'v1.2.0',
session: 'Login flow'
}
})
// LambdaTest
start_session({
provider: 'testmu',
platform: 'browser',
browser: 'chrome',
os: 'Windows', // combined with osVersion → platformName
osVersion: '11', // e.g. "11", "Sequoia" (optional)
reporting: {
project: 'My Project',
build: 'v1.2.0',
session: 'Login flow'
}
})
// TestingBot
start_session({
provider: 'testingbot',
platform: 'browser',
browser: 'chrome',
os: 'Windows', // combined with osVersion → platformName (default: Windows 11)
osVersion: '11',
reporting: {
build: 'v1.2.0',
session: 'Login flow'
}
})
// Digital.ai
start_session({
provider: 'digitalai',
platform: 'browser',
browser: 'chrome',
os: 'Windows', // combined with osVersion → digitalai:osName (optional)
osVersion: '11',
reporting: {
session: 'Login flow' // → digitalai:testName (flat capability, not nested)
}
})
Comportamiento específico de
os/osVersionpor proveedor:
- BrowserStack —
osyosVersionse asignan a camposbstack:options.os/bstack:options.osVersionseparados.- Sauce Labs / LambdaTest / TestingBot —
osyosVersionse combinan en la capacidad W3CplatformName(p. ej.,os: 'Windows'+osVersion: '11'→platformName: 'Windows 11'). Estos proveedores usan valoresplatformNamecomo"Windows 11","MacOS Sequoia"o"Linux". TestingBot usaWindows 11por defecto cuando se omiteos.- Digital.ai —
osyosVersionse combinan en la capacidad planadigitalai:osName(NOplatformName), p. ej.os: 'Windows'+osVersion: '11'→digitalai:osName: 'Windows 11'.
Sesiones de aplicaciones móviles
Prueba en dispositivos reales en la nube. Primero sube tu aplicación (o usa una URL de aplicación existente):
// BrowserStack: returns bs:// URL
upload_app({ provider: 'browserstack', path: '/path/to/app.apk' })
// Sauce Labs: returns storage:filename= reference
upload_app({ provider: 'saucelabs', path: '/path/to/app.apk' })
// LambdaTest: returns lt:// URL
upload_app({ provider: 'testmu', path: '/path/to/app.apk' })
// TestingBot: returns tb:// URL
upload_app({ provider: 'testingbot', path: '/path/to/app.apk' })
// Digital.ai: returns cloud:<package-or-bundle> reference
upload_app({ provider: 'digitalai', path: '/path/to/app.apk' })
// Start a session
start_session({
provider: 'browserstack',
platform: 'android',
app: 'bs://abc123...',
deviceName: 'Samsung Galaxy S23',
platformVersion: '13.0'
})
// Sauce Labs native app
start_session({
provider: 'saucelabs',
platform: 'android',
app: 'storage:filename=myapp.apk',
deviceName: 'Samsung.*',
platformVersion: '16'
})
// LambdaTest native app
start_session({
provider: 'testmu',
platform: 'android',
app: 'lt://abc123...',
deviceName: 'Pixel 7',
platformVersion: '13'
})
// TestingBot native app
start_session({
provider: 'testingbot',
platform: 'android',
app: 'tb://abc123...',
deviceName: 'Pixel 7',
platformVersion: '13'
})
// Digital.ai native app — devices are selected via a deviceQuery
start_session({
provider: 'digitalai',
platform: 'android',
app: 'cloud:com.example.app',
deviceQuery: "@os='android' and @version='14' and @name='.*Pixel.*'"
// or omit deviceQuery and pass deviceName / platformVersion to build one
})
Sesiones de navegador móvil
Ejecuta un navegador en un dispositivo móvil en la nube (dispositivo real o emulador/simulador) sin subir una aplicación:
// BrowserStack — Chrome on Android emulator
start_session({
provider: 'browserstack',
platform: 'android',
browser: 'chrome',
deviceName: 'Google Pixel 7',
platformVersion: '13'
})
// Sauce Labs — Safari on iOS simulator
start_session({
provider: 'saucelabs',
platform: 'ios',
browser: 'safari',
deviceName: 'iPhone 15',
platformVersion: '18',
region: 'eu-central-1'
})
// LambdaTest — Chrome on Android emulator
start_session({
provider: 'testmu',
platform: 'android',
browser: 'chrome',
deviceName: 'Pixel 7',
platformVersion: '13'
})
// TestingBot — Chrome on Android emulator
start_session({
provider: 'testingbot',
platform: 'android',
browser: 'chrome',
deviceName: 'Pixel 7',
platformVersion: '13'
})
// Digital.ai — Chrome on an Android device (real or emulator; selected via a deviceQuery)
start_session({
provider: 'digitalai',
platform: 'android',
browser: 'chrome',
deviceName: 'Pixel 7',
platformVersion: '13'
// or omit deviceName / platformVersion and pass deviceQuery directly, e.g.
// deviceQuery: "@os='android' and @emulator='true'" to force an emulator
})
Nota: Las sesiones de navegador móvil no requieren
app,appPathninoReset. El proveedor lanza un navegador directamente en el dispositivo seleccionado, ya sea real o emulador/simulador.
Usa list_apps para ver las aplicaciones subidas anteriormente:
list_apps({ provider: 'browserstack' })
list_apps({ provider: 'saucelabs', sortBy: 'app_name' })
list_apps({ provider: 'testmu' })
list_apps({ provider: 'testingbot' })
list_apps({ provider: 'digitalai' })
list_apps({ provider: 'browserstack', organizationWide: true })
Túnel local
Para probar contra URLs que solo son accesibles en tu máquina local o red interna, habilita un túnel local:
// Auto-start tunnel (provider manages lifecycle)
start_session({
provider: 'saucelabs',
platform: 'browser',
tunnel: true // auto-starts tunnel before session
})
// Use an already-running tunnel
start_session({
provider: 'saucelabs',
platform: 'browser',
tunnel: 'external' // uses existing tunnel
})
El parámetro tunnel reemplaza los parámetros obsoletos browserstackLocal, saucelabsLocal y testmuLocal. Establécelo en true para iniciar el túnel automáticamente (se detiene automáticamente después de la sesión), o en 'external' para usar un túnel que ya se esté ejecutando en tu máquina.
Nota: Con
tunnel: true, el proveedor descarga y gestiona el binario del túnel por ti. Paratunnel: 'external', lo ejecutas tú mismo: los recursoswdio://saucelabs/local-binary,wdio://testmu/local-binaryywdio://testingbot/local-binaryproporcionan URLs de descarga e instrucciones de configuración. El túnel de TestingBot es un único JAR de Java multiplataforma (requiere Java 11+) en lugar de un binario por plataforma.
Etiquetas de informes
Todos los tipos de sesión admiten etiquetas reporting que aparecen en el panel del proveedor:
| Campo | Descripción |
|---|---|
reporting.project | Agrupa sesiones bajo un nombre de proyecto |
reporting.build | Etiqueta sesiones con una etiqueta de compilación/versión |
reporting.session | Nombre para la sesión de prueba individual |
Herramientas de proveedores en la nube
| Herramienta | Descripción |
|---|---|
upload_app | Sube un .apk o .ipa local al proveedor; devuelve una URL/referencia de aplicación |
list_apps | Lista las aplicaciones subidas anteriormente al almacenamiento de aplicaciones del proveedor |
Ambas herramientas requieren un parámetro provider ('browserstack', 'saucelabs', 'testmu', 'testingbot' o 'digitalai').
Características
Automatización de navegador
- Gestión de sesiones: Inicia y cierra sesiones de navegador (Chrome, Firefox, Edge, Safari) con modos headless/con ventana
- Navegación e interacción: Navega por URLs, haz clic en elementos, rellena formularios y recupera contenido
- Análisis de página: Obtén elementos visibles, árboles de accesibilidad, capturas de pantalla
- Gestión de cookies: Obtén, establece y elimina cookies
- Desplazamiento: Desplazamiento suave con distancias configurables
- Adjuntar a Chrome en ejecución: Conéctate a una ventana de Chrome existente mediante
--remote-debugging-port— ideal para probar sesiones autenticadas o preconfiguradas - Conectar a endpoints WebDriver existentes: Reutiliza un endpoint WebDriver compatible con Selenium ya en ejecución, como un navegador gestionado por un framework o un puente de automatización de webview de escritorio (como Tauri)
- Emulación de dispositivos: Aplica ajustes preestablecidos de móvil/tableta (iPhone 15, Pixel 7, etc.) para simular diseños responsivos sin un dispositivo físico
- Grabación de sesiones: Todas las llamadas a herramientas se graban automáticamente y se pueden exportar como JS de WebdriverIO ejecutable
Automatización de aplicaciones móviles (iOS/Android)
- Pruebas de aplicaciones nativas: Prueba aplicaciones de Android (.apk) e iOS (.app/.ipa) mediante Appium
- Gestos táctiles: Tocar, deslizar, mantener pulsado, arrastrar y soltar
- Ciclo de vida de la aplicación: Iniciar, pasar a segundo plano, terminar, comprobar el estado de la aplicación
- Cambio de contexto: Cambia sin problemas entre contextos nativos y webview para aplicaciones híbridas
- Control de dispositivos: Rotar, bloquear/desbloquear, geolocalización, control de teclado, notificaciones
- Selectores multiplataforma: IDs de accesibilidad, XPath, UiAutomator (Android), Predicates (iOS)
Herramientas disponibles
Gestión de sesiones
| Herramienta | Descripción |
|---|---|
start_session | Iniciar una nueva sesión de navegador o aplicación; attach: true conserva el modo de conexión CDP de Chrome existente |
attach_session | Adjuntarse a una sesión remota existente de WebDriver/Appium por ID sin crear una sesión nueva |
launch_chrome | Lanzar una nueva instancia de Chrome con depuración remota habilitada (para usar con start_session({ attach: true })) |
close_session | Cerrar o desconectarse de la sesión actual (admite detach: true para desconectarse sin terminar) |
emulate_device | Emular un ajuste preestablecido de dispositivo móvil/tableta (viewport, DPR, UA, táctil); requiere sesión BiDi |
open_web_extension | Instalar una extensión web mediante WebDriver BiDi y abrir una de sus páginas de extensión para que las herramientas de página normales puedan controlar su interfaz |
Navegación e Interacción con la Página (Web y Móvil)
| Herramienta | Descripción |
|---|---|
navigate | Navegar a una URL |
get_elements | Obtener elementos visibles e interactuables de la página. Admite inViewportOnly (predeterminado: true) para filtrar elementos del viewport, y includeContainers (predeterminado: false) para incluir contenedores de diseño en móvil |
get_accessibility_tree | Obtener el árbol de accesibilidad de la página con roles, nombres y selectores. Admite filtrado por rol y paginación. Solo navegador. |
get_screenshot | Tomar una captura de pantalla de la página o pantalla actual (codificada en base64, redimensionada automáticamente a un máximo de 2000px / 1MB) |
get_tabs | Listar todas las pestañas abiertas del navegador con identificador, título, URL y estado activo. Solo navegador. |
scroll | Desplazarse en una dirección (arriba/abajo) por píxeles especificados. Solo navegador. |
execute_script | Ejecutar JavaScript arbitrario en el navegador, o comandos móviles de Appium en dispositivos |
switch_tab | Cambiar a una pestaña diferente del navegador por identificador o índice basado en 0. Solo navegador. |
switch_frame | Cambiar a un iframe mediante selector CSS/XPath, o volver al marco de nivel superior si no se proporciona ningún selector. Solo navegador. |
Interacción con Elementos (Web y Móvil)
| Herramienta | Descripción |
|---|---|
click_element | Hacer clic en un elemento |
set_value | Escribir texto en campos de entrada |
Gestión de Cookies (Web)
| Herramienta | Descripción |
|---|---|
get_cookies | Obtener todas las cookies de la sesión actual, o una sola cookie por nombre |
set_cookie | Establecer una cookie con nombre, valor y atributos opcionales |
delete_cookies | Eliminar todas las cookies o una cookie específica |
Gestos Móviles (iOS/Android)
| Herramienta | Descripción |
|---|---|
tap_element | Tocar un elemento por selector o coordenadas |
swipe | Deslizar en una dirección (arriba/abajo/izquierda/derecha) |
drag_and_drop | Arrastrar de una ubicación a otra |
Cambio de Contexto (Aplicaciones Híbridas)
| Herramienta | Descripción |
|---|---|
get_contexts | Listar los contextos de automatización disponibles (NATIVE_APP, WEBVIEW_*) y el activo actualmente |
switch_context | Cambiar entre contextos nativos y webview |
Control de Dispositivo (iOS/Android)
| Herramienta | Descripción |
|---|---|
get_app_state | Obtener el estado actual del ciclo de vida de una aplicación móvil (no instalada / no en ejecución / en segundo plano / en primer plano) |
rotate_device | Rotar a vertical u horizontal |
hide_keyboard | Ocultar el teclado en pantalla |
set_geolocation | Establecer la ubicación GPS del dispositivo |
Recursos MCP (solo lectura, no se necesita llamada de herramienta)
| Recurso | Descripción |
|---|---|
wdio://sessions | Índice de todas las sesiones registradas |
wdio://session/current/steps | Registro de pasos de la sesión activa |
wdio://session/current/code | JS de WebdriverIO ejecutable generado para la sesión activa |
wdio://session/{id}/steps | Registro de pasos de cualquier sesión pasada por ID |
wdio://session/{id}/code | JS generado para cualquier sesión pasada por ID |
wdio://session/current/elements | Elementos interactuables (solo viewport por defecto) |
wdio://session/current/accessibility | Árbol de accesibilidad |
wdio://session/current/screenshot | Captura de pantalla (base64) |
wdio://session/current/cookies | Cookies del navegador |
wdio://session/current/tabs | Pestañas abiertas del navegador |
wdio://session/current/contexts | Contextos nativos/webview (móvil) |
wdio://session/current/context | Contexto actualmente activo (móvil) |
wdio://session/current/app-state/{bundleId} | Estado del ciclo de vida de la aplicación móvil para un ID de paquete determinado |
wdio://session/current/geolocation | Geolocalización del dispositivo |
wdio://session/current/capabilities | Capacidades de WebDriver resueltas para la sesión activa |
wdio://session/current/logs | Registros de fallos/consola de la sesión actual. Detecta automáticamente el tipo de sesión — navegador: registros de consola + excepciones de JS; Android: logcat; iOS: crashlog + syslog |
wdio://browserstack/local-binary | URL de descarga del binario de BrowserStack Local y comando de inicio |
wdio://saucelabs/local-binary | URL de descarga del binario de Sauce Connect y comando de inicio |
wdio://testmu/local-binary | URL de descarga del binario de TestMu Tunnel y comando de inicio |
wdio://testingbot/local-binary | URL de descarga del JAR de TestingBot Tunnel y comando de inicio (Java 11+) |
Ejemplos de Uso
Casos de Prueba del Mundo Real
Ejemplo 1: Prueba de la aplicación Android de demostración (escaneo de libros)
Test the Demo Android app at C:\Users\demo-liveApiGbRegionNonMinifiedRelease-3018788.apk on emulator-5554:
1. Start the app with auto-grant permissions
2. Get visible elements on the onboarding screen
3. Tap "Skip" to bypass onboarding
4. Verify main screen loads
5. Take a screenshot
Ejemplo 2: Prueba del sitio de comercio electrónico World of Books
You are a Testing expert, and want to assess the basic workflows of worldofbooks.com:
- Open World of Books (accept all cookies)
- Get visible elements to see navigation structure
- Search for a fiction book
- Choose one and validate if there are NEW and used book options
- Report your findings at the end
Automatización de Navegador
Solicitud básica de prueba web:
You are a Testing expert, and want to assess the basic workflows of a web application:
- Open World of Books (accept all cookies)
- Search for a fiction book
- Choose one and validate if there are NEW and used book options
- Report your findings at the end
Opciones de configuración del navegador:
// Default settings (headed mode, 1280x1080)
start_session({platform: 'browser'})
// Firefox
start_session({platform: 'browser', browser: 'firefox'})
// Edge
start_session({platform: 'browser', browser: 'edge'})
// Safari (headed only; requires macOS)
start_session({platform: 'browser', browser: 'safari'})
// Headless mode
start_session({platform: 'browser', headless: true})
// Custom dimensions
start_session({platform: 'browser', windowWidth: 1920, windowHeight: 1080})
// Pass custom capabilities (e.g. Chrome extensions, profile, prefs)
start_session({
platform: 'browser',
headless: false,
capabilities: {
'goog:chromeOptions': {
args: ['--user-data-dir=/tmp/wdio-mcp-profile', '--load-extension=/path/to/unpacked-extension']
}
}
})
Adjuntarse a una instancia de Chrome en ejecución:
// First, launch Chrome with remote debugging enabled:
//
// macOS (must quit Chrome first — open -a ignores args if Chrome is already running):
// pkill -x "Google Chrome" && sleep 1
// /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
// --remote-debugging-port=9222 \
// --user-data-dir=/tmp/chrome-debug &
//
// Linux:
// google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug &
//
// Verify it's ready: curl http://localhost:9222/json/version
start_session({attach: true})
start_session({attach: true, port: 9333})
start_session({attach: true, port: 9222, navigationUrl: 'https://app.example.com'})
Conectarse a un endpoint de WebDriver existente:
Use provider: 'external' cuando otro proceso ya posee el ciclo de vida del navegador o webview y expone un endpoint
W3C WebDriver. Esto es útil para sesiones de Selenium Grid, controladores de navegador gestionados externamente, o aplicaciones de escritorio como aplicaciones Tauri que
incorporan un webview y exponen WebDriver por separado. El servidor MCP se conecta al endpoint; no inicia ni detiene la
aplicación de destino, no inicia túneles ni gestiona la configuración específica del framework.
// Defaults to http://127.0.0.1:4445/ and browserName: 'chrome'
start_session({provider: 'external', platform: 'browser'})
// Custom WebDriver endpoint and capabilities
start_session({
provider: 'external',
platform: 'browser',
webdriverConfig: {
protocol: 'http',
hostname: '127.0.0.1',
port: 4445,
path: '/'
},
capabilities: {
browserName: 'tauri'
}
})
Para aplicaciones de escritorio con webview como Tauri, primero inicie la aplicación y su puente WebDriver fuera de este servidor MCP, luego
pase el endpoint y las capacidades requeridas. Por ejemplo, un puente WebDriver de Tauri puede requerir
capabilities: {browserName: 'tauri'}.
Adjuntarse a una sesión existente de WebDriver o Appium:
Use attach_session cuando la sesión ya haya sido creada por otro proceso. El MCP reutiliza el endpoint y las
credenciales del proveedor seleccionado, registra el conjunto de comandos de navegador/móvil apropiado localmente y no emite una solicitud de nueva sesión.
Las sesiones adjuntas se gestionan externamente: close_session() se desconecta de forma predeterminada, mientras que
close_session({detach: false}) termina explícitamente la sesión remota.
// Existing BrowserStack App Automate session
attach_session({
provider: 'browserstack',
platform: 'ios',
sessionId: 'existing-browserstack-session-id',
capabilities: {
'appium:deviceName': 'iPhone 15',
'appium:automationName': 'XCUITest'
}
})
// Existing session on a local Appium server
attach_session({
provider: 'local',
platform: 'android',
sessionId: 'existing-appium-session-id',
appiumConfig: {
protocol: 'http',
host: '127.0.0.1',
port: 4723,
path: '/'
}
})
// Existing mobile session on a custom W3C WebDriver endpoint
attach_session({
provider: 'external',
platform: 'ios',
sessionId: 'existing-grid-session-id',
webdriverConfig: {
protocol: 'https',
hostname: 'grid.example.com',
port: 443,
path: '/wd/hub'
}
})
Una sesión en la nube existente debe seguir usando el túnel con el que fue creada. attach_session nunca inicia ni detiene un túnel,
así que mantenga el proceso del túnel original activo durante todo el tiempo que la sesión lo necesite.
Emulación de dispositivo (requiere sesión BiDi):
// Device emulation (requires BiDi session)
start_session({capabilities: {webSocketUrl: true}})
emulate_device() // list available presets
emulate_device({device: 'iPhone 15'}) // activate emulation
emulate_device({device: 'Pixel 7'}) // switch device
emulate_device({device: 'reset'}) // restore desktop defaults
Extensiones web (requiere sesión BiDi):
start_session({platform: 'browser', browser: 'chrome', capabilities: {webSocketUrl: true}})
open_web_extension({
extensionData: {type: 'path', path: '/path/to/unpacked-extension'},
path: 'options.html'
})
// Drive the extension UI with the normal page tools.
get_elements()
click_element({selector: '#save'})
// For remote/cloud sessions, send a packaged extension archive as base64.
open_web_extension({
extensionData: {type: 'base64', value: '<base64-encoded-zip>'},
path: 'options.html'
})
Automatización de Aplicaciones Móviles
Prueba de una aplicación iOS en simulador:
Test my iOS app located at /path/to/MyApp.app on iPhone 15 Pro simulator:
1. Start the app session
2. Tap the login button
3. Enter "testuser" in the username field
4. Take a screenshot of the home screen
5. Close the session
Preservación del estado de la aplicación entre sesiones:
Test my Android app without resetting data:
1. Start app session with noReset: true and fullReset: false
2. App launches with existing login state and user data preserved
3. Run test scenarios
4. Close session (app remains installed with data intact)
Prueba de una aplicación iOS en dispositivo real:
Test my iOS app on my physical iPhone:
1. Start app session with:
- platform: iOS
- appPath: /path/to/MyApp.ipa
- deviceName: My iPhone
- udid: 00008030-001234567890ABCD (your device's UDID)
- platformVersion: 17.0
2. Run your test scenario
3. Close the session
Prueba de una aplicación Android:
Test my Android app /path/to/app.apk on the Pixel_6_API_34 emulator:
1. Start the app with auto-grant permissions
2. Get visible elements (use inViewportOnly: false to see all elements)
3. Swipe up to scroll
4. Tap on the "Settings" button using text matching
5. Verify the settings screen is displayed
Detección avanzada de elementos:
Test my app and debug layout issues:
1. Start the app session
2. Get visible elements with includeContainers: true to see the layout hierarchy
3. Analyze ViewGroup, FrameLayout, and ScrollView containers
4. Use inViewportOnly: false to find off-screen elements that need scrolling
Prueba de aplicaciones híbridas (cambio de contextos):
Test my hybrid app:
1. Start the Android app session
2. Tap "Open Web" button in native context
3. List available contexts
4. Switch to WEBVIEW context
5. Click the login button using CSS selector
6. Switch back to NATIVE_APP context
7. Verify we're back on the home screen
Notas Importantes
⚠️ Gestión de Sesiones:
- Solo una sesión (navegador O aplicación) puede estar activa a la vez
- Cierre siempre las sesiones al terminar para liberar recursos del sistema
- Para cambiar entre navegador y móvil, cierre primero la sesión actual
- Use
close_session({ detach: true })para desconectarse sin terminar la sesión en el servidor de Appium - La preservación del estado se puede controlar con los parámetros
noResetyfullResetdurante la creación de la sesión - Las sesiones creadas con
noReset: trueo sinappPathse desconectarán automáticamente al cerrarse - Las sesiones adoptadas con
attach_sessionsiempre se desconectan al cerrarse a menos quedetach: falsese solicite explícitamente
⚠️ Planificación de Tareas:
- Divida la automatización compleja en operaciones más pequeñas y enfocadas
- Claude puede consumir rápidamente los límites de mensajes con automatización extensa
⚠️ Automatización Móvil:
- El servidor de Appium debe estar en ejecución antes de iniciar sesiones móviles
- Asegúrate de que los emuladores/simuladores estén en ejecución y los dispositivos estén conectados
- La automatización de iOS requiere macOS con Xcode instalado
- Dispositivos iOS reales: Probar en dispositivos iOS físicos requiere el UDID del dispositivo (identificador único de 40 caracteres). Consulta la sección de Requisitos previos para saber cómo encontrar tu UDID
Referencia rápida de sintaxis de selectores
Web (CSS/XPath):
- CSS:
button.my-class,#element-id - XPath:
//button[@class='my-class'] - Texto:
button=Exact text,a*=Contains text
Móvil (multiplataforma):
- ID de accesibilidad:
~loginButton(funciona tanto en iOS como en Android) - UiAutomator de Android:
android=new UiSelector().text("Login") - Predicado de iOS:
-ios predicate string:label == "Login" AND visible == 1 - XPath:
//android.widget.Button[@text="Login"]
Funciones avanzadas
Preservación del estado de la aplicación
Preservación de estado con noReset/fullReset:
Controla el estado de la aplicación al crear nuevas sesiones usando los parámetros noReset y fullReset:
| noReset | fullReset | Comportamiento |
|---|---|---|
true | false | Preservar estado: la aplicación permanece instalada, los datos se conservan |
false | false | Borrar los datos de la aplicación pero mantenerla instalada (predeterminado) |
false | true | Restablecimiento completo: desinstalar y reinstalar la aplicación (estado limpio) |
Ejemplo con preservación de estado:
// Preserve login state between test runs
start_session({
platform: 'android',
appPath: '/path/to/app.apk',
deviceName: 'emulator-5554',
noReset: true, // Don't reset app state
fullReset: false, // Don't uninstall
autoGrantPermissions: true,
capabilities: {
'appium:chromedriverExecutable': '/path/to/chromedriver',
'appium:autoWebview': true
}
})
// App launches with existing user data, login tokens, preferences intact
Desconexión de sesiones:
La herramienta close_session admite un parámetro detach que se desconecta de la sesión sin terminarla en el
servidor de Appium:
// Detach without killing the session
close_session({detach: true})
// Explicit session termination (closes the app and removes session)
close_session({detach: false})
Las sesiones creadas con noReset: true o sin appPath se desconectarán automáticamente al cerrarse.
Las sesiones adoptadas con attach_session se gestionan externamente y también se desconectan de forma predeterminada; pasa detach: false solo cuando el
MCP deba terminar deliberadamente la sesión remota existente.
Esto es particularmente útil cuando:
- Se preserva el estado de la aplicación para continuar las pruebas manuales
- Se depuran flujos de trabajo de varios pasos (dejar la sesión en ejecución entre invocaciones de herramientas)
- Se prueban escenarios donde se desea que la aplicación permanezca instalada y en su estado actual
Detección inteligente de elementos
- Clasificación de elementos específica de la plataforma: identifica automáticamente elementos interactuables frente a contenedores de diseño
- Android: Button, EditText, CheckBox frente a ViewGroup, FrameLayout, ScrollView
- iOS: Button, TextField, Switch frente a View, StackView, CollectionView
- Múltiples estrategias de localización: cada elemento proporciona ID de accesibilidad, ID de recurso, texto, XPath y selectores específicos de la plataforma
- Filtrado por viewport: controla si se obtienen solo elementos visibles o todos los elementos, incluidos los fuera de pantalla
- Depuración de diseño: incluye opcionalmente elementos contenedores para comprender la jerarquía de la interfaz de usuario
Manejo automático de permisos y alertas
Tanto las sesiones de iOS como las de Android ahora admiten el manejo automático de permisos y alertas del sistema:
autoGrantPermissions(predeterminado: true): otorga automáticamente permisos de la aplicación (cámara, ubicación, etc.)autoAcceptAlerts(predeterminado: true): acepta automáticamente alertas y diálogos del sistemaautoDismissAlerts(opcional): configúralo en true para descartar alertas en lugar de aceptarlas
Esto elimina la necesidad de manejar manualmente las ventanas emergentes de permisos durante las pruebas automatizadas.
Detalles técnicos
- Construido con: TypeScript, WebDriverIO, Appium
- Soporte de navegadores: Chrome, Firefox, Edge (con interfaz/sin interfaz, gestión automatizada de controladores), Safari (solo con interfaz; macOS)
- Soporte móvil: iOS (XCUITest) y Android (UiAutomator2/Espresso)
- Protocolo: Model Context Protocol (MCP) para la integración con Claude Desktop
- Modelo de sesión: sesión activa única (navegador o aplicación móvil)
- Formato de datos: TOON (Token-Oriented Object Notation) para una comunicación eficiente con LLM
- Detección de elementos: análisis de la fuente de la página basado en XML con filtrado inteligente y generación de localizadores de múltiples estrategias
Grabación de sesiones y exportación de código
Cada llamada a una herramienta se registra automáticamente en el historial de la sesión. Puedes inspeccionar las sesiones y exportar código ejecutable a través de los recursos de MCP, sin necesidad de llamadas adicionales a herramientas:
wdio://sessions— lista todas las sesiones grabadas con tipo, marcas de tiempo y número de pasoswdio://session/current/steps— registro de pasos de la sesión activawdio://session/current/code— JS de WebdriverIO ejecutable generado para la sesión activawdio://session/{sessionId}/steps— registro de pasos de cualquier sesión anterior por IDwdio://session/{sessionId}/code— JS generado para cualquier sesión anterior por ID
El script generado reconstruye la sesión completa, incluidas las capacidades, la navegación, los clics y las entradas, como un
archivo import { remote } from 'webdriverio' independiente. Para sesiones de proveedores en la nube, incluye el bloque try/catch/finally completo
con el marcado automático del resultado de la sesión mediante la API REST del proveedor.
Grabación de trazas
Pasar trace: true a start_session produce un zip .trace compatible con Playwright en el directorio .trace/ cuando
la sesión se cierra. El zip se puede reproducir en player.vibium.dev y muestra una tira de
capturas de pantalla junto con la línea de tiempo de las acciones.
Cómo se temporizan las capturas de pantalla
El viaje de ida y vuelta de takeScreenshot de Appium tarda entre 700 y 1300 ms en un emulador local, lo cual es suficiente para que las
animaciones de la acción anterior se asienten. Aprovechamos esto: cada captura de pantalla se toma antes de que se ejecute la siguiente acción, por lo que
lo que devuelve el servidor de Appium ya es el resultado asentado de la acción anterior.
La parte complicada es hacer que el reproductor de trazas muestre esa captura de pantalla bajo la acción correcta. El reproductor asocia un
evento screencast-frame con la ventana de tiempo de la acción que contiene el campo timestamp del fotograma. Si la marca de tiempo
se establece en "ahora" (tiempo de captura), cae antes del startTime de la acción actual y el reproductor la etiqueta como el
estado anterior de la siguiente acción, desincronizada en una acción.
La solución: sellar cada screencast-frame con lastAfterEndTime — el endTime de la acción que acaba de completarse. Esto
coloca el fotograma dentro de la ventana de la acción anterior, por lo que el reproductor lo muestra como el resultado de esa acción, no como el
precursor de la siguiente.
Timeline (monotonic ms):
prev.endTime ← frame timestamp stamped here
│
│ [screenshot captured here — shows settled state after prev action]
│
curr.startTime
│
│ [action executes]
│
curr.endTime ← next frame will be stamped here
La captura de pantalla final al cerrar la sesión se sella con el endTime de la última acción, por lo que se muestra bajo esa acción
en lugar de aparecer como un fotograma huérfano después de que termine la línea de tiempo.
Registros de sesión
El recurso wdio://session/current/logs devuelve informes de fallos, errores de consola y registros del sistema para la sesión
actual, detectando automáticamente el tipo de sesión para obtener el búfer de registro correcto:
| Tipo de sesión | Fuentes de registro | Contenidos |
|---|---|---|
| Navegador | getLogs('browser') | Salida de consola + excepciones JS no capturadas |
| Android | getLogs('logcat') | Registros del sistema, volcados de fallos, excepciones fatales |
| iOS | getLogs('crashlog') + getLogs('syslog') | Informes de fallos/pánico + diagnósticos del sistema |
Nota: Leer este recurso limpia el búfer de registro (según la especificación de WebDriver). Las lecturas posteriores devuelven solo las entradas acumuladas desde la última lectura. Los registros del navegador requieren Chromium (Chrome/Edge) — Firefox y Safari no admiten el comando
getLogs.
La respuesta es JSON con sessionType, logTypes (tipos de registro disponibles) y entries — cada entrada incluye level,
message, timestamp (ms Unix) y timestampISO.
Solución de problemas
¿La automatización del navegador no funciona?
- Asegúrate de que Chrome, Firefox, Edge o Safari estén instalados (Safari requiere macOS)
- Intenta reiniciar Claude Desktop por completo
- Comprueba que no haya otras instancias de WebDriver en ejecución
¿La automatización móvil no funciona?
- Verifica que el servidor de Appium esté en ejecución:
appium - Comprueba que el dispositivo/emulador esté en ejecución:
adb devices(Android) o Dispositivos Xcode (iOS) - Asegúrate de que los controladores de plataforma correctos estén instalados
- Verifica que la ruta de la aplicación sea correcta y accesible
¿Encontraste problemas o tienes sugerencias? ¡Comparte tus comentarios!