WebdriverIO MCP
Um servidor Model Context
Documentação
Servidor MCP WebdriverIO
Um servidor Model Context Protocol (MCP) que permite que assistentes de IA interajam com navegadores web, aplicativos Electron locais e aplicativos móveis usando WebdriverIO. Automatize Chrome, Firefox, Edge, Safari, Electron, iOS e Android por meio de uma interface unificada.
Instalação
Adicione a seguinte configuração às configurações do seu cliente MCP:
Configuração padrão (funciona na maioria dos clientes):
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
Claude Desktop
Edite ~/Library/Application Support/Claude/claude_desktop_config.json (macOS),
%APPDATA%\Claude\claude_desktop_config.json (Windows) ou ~/.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
Adicione ao seu arquivo settings.json ou cline_mcp_settings.json do VS Code:
{
"mcpServers": {
"wdio-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
Cursor
Vá para Cursor Settings → MCP → Add new MCP Server, ou crie .cursor/mcp.json:
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
Codex
Use o Codex CLI:
codex mcp add wdio-mcp npx "@wdio/mcp@latest"
Ou edite ~/.codex/config.toml:
[mcp_servers.wdio-mcp]
command = "npx"
args = ["@wdio/mcp@latest"]
Goose
Vá para Advanced settings → Extensions → Add custom extension, ou execute:
goose configure
Ou edite ~/.config/goose/config.yaml:
extensions:
wdio-mcp:
name: WebDriverIO MCP
cmd: npx
args: [ -y, "@wdio/mcp@latest" ]
enabled: true
type: stdio
Windsurf
Edite ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"wdio-mcp": {
"command": "npx",
"args": [
"-y",
"@wdio/mcp@latest"
]
}
}
}
Zed
Edite as configurações do 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"]}'
⚠️ Reinicialização necessária: Após adicionar a configuração, reinicie completamente o seu cliente MCP para aplicar as alterações.
Opção 2: Instalação Global
Se você preferir instalar globalmente:
npm install -g @wdio/mcp
Em seguida, use wdio-mcp como o comando:
{
"mcpServers": {
"wdio-mcp": {
"command": "wdio-mcp"
}
}
}
📖 Precisa de ajuda? Siga o guia de instalação do MCP.
Transporte HTTP (para clientes que não usam subprocessos)
Por padrão, o servidor usa transporte stdio (subprocesso). Para clientes que não podem iniciar subprocessos (por exemplo, llama.cpp, modo seguro do OpenAI Codex), habilite o transporte HTTP:
npx @wdio/mcp --http --port 3000
| Sinalizador | Padrão | Descrição |
|---|---|---|
--http | — | Habilita o modo de transporte HTTP |
--port | 3000 | Porta para escutar |
--allowedHosts | localhost,127.0.0.1,::1 | Valores de cabeçalho Host permitidos (proteção contra rebinding de DNS) |
--allowedOrigins | (nenhum — clientes de navegador bloqueados) | Valores de Origin permitidos para CORS. Use * para permitir todos. |
Em seguida, aponte seu cliente MCP para http://localhost:3000/mcp.
Pré-requisitos para Automação de Aplicativos Móveis
- Servidor Appium: Instale globalmente com
npm install -g appium - Drivers de Plataforma:
- iOS:
appium driver install xcuitest(requer Xcode no macOS) - Android:
appium driver install uiautomator2(requer Android Studio)
- iOS:
- Dispositivos/Emuladores:
- Simulador iOS (macOS) ou dispositivo físico
- Emulador Android ou dispositivo físico
- Para Dispositivos iOS Reais: Você precisará do UDID (Identificador Único de Dispositivo) do dispositivo
- Encontre o UDID no macOS: Conecte o dispositivo → Abra o Finder → Selecione o dispositivo → Clique no nome/modelo do dispositivo para revelar o UDID
- Encontre o UDID no Windows: Conecte o dispositivo → iTunes ou aplicativo Apple Devices → Clique no ícone do dispositivo → Clique em "Número de Série" para revelar o UDID
- Método Xcode: Janela → Dispositivos e Simuladores → Selecione o dispositivo → O UDID aparece como "Identificador"
Inicie o servidor Appium antes de usar os recursos móveis:
appium
# Server runs at http://127.0.0.1:4723 by default
Provedores de Nuvem
Execute testes de navegador e aplicativos móveis em dispositivos e navegadores reais na nuvem sem qualquer configuração local. Atualmente suporta BrowserStack, Sauce Labs, LambdaTest, TestingBot e Digital.ai Testing.
Pré-requisitos
Defina suas credenciais do provedor como variáveis de ambiente ou na configuração do seu 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 | Nome de usuário do Sauce Labs (obrigatório) |
| SAUCE_ACCESS_KEY | Chave de acesso do Sauce Labs (obrigatória) |
O data center é definido por sessão por meio do parâmetro region em start_session (padrão: 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 | Nome de usuário do LambdaTest (obrigatório) |
| TESTMU_ACCESS_KEY | Chave de acesso do LambdaTest (obrigatória) |
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 | Chave do TestingBot (obrigatória) |
| TESTINGBOT_SECRET | Segredo do TestingBot (obrigatório) |
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 da nuvem Digital.ai, ex.: https://your-cloud.example.com (obrigatório) |
| DIGITALAI_ACCESS_KEY | Chave de acesso do Digital.ai (obrigatória) |
A chave de acesso é enviada por meio da capacidade digitalai:options (móvel) ou da capacidade plana digitalai:accessKey (web).
Relatar status de aprovação/reprovação: O WebdriverIO usa por padrão o protocolo BiDi, sobre o qual a nuvem do Digital.ai não pode observar falhas de comando — portanto, os relatórios são padronizados como "Aprovado". Para fazer a nuvem refletir a aprovação/reprovação real, opte pelo WebDriver clássico por sessão:
start_session({
provider: 'digitalai', platform: 'browser', browser: 'chrome', os: 'Windows 10',
capabilities: { 'wdio:enforceWebDriverClassic': true }
})
(Falhas de asserção puramente no lado do cliente ainda são relatadas como "Aprovado" — apenas falhas que chegam à nuvem como erros de comando do WebDriver são detectadas.)
Móvel (Appium): configure seu projeto Digital.ai para execução do servidor Appium e escolha a versão padrão do Appium por meio da configuração "Gerenciar versão padrão do servidor Appium" do projeto — a versão é escolhida no nível do projeto (e acompanha as versões que sua nuvem suporta), portanto, este MCP não fixa uma. Consulte Execução de Teste do Servidor Appium.
Sessões de Navegador
Execute um navegador em uma combinação específica de SO/versão:
// 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)
}
})
Comportamento específico do provedor para
os/osVersion:
- BrowserStack —
oseosVersionsão mapeados para campos separados debstack:options.os/bstack:options.osVersion.- Sauce Labs / LambdaTest / TestingBot —
oseosVersionsão combinados na capacidade W3CplatformName(ex.:os: 'Windows'+osVersion: '11'→platformName: 'Windows 11'). Esses provedores usam valores deplatformNamecomo"Windows 11","MacOS Sequoia"ou"Linux". O TestingBot usa como padrãoWindows 11quandoosé omitido.- Digital.ai —
oseosVersionsão combinados na capacidade planadigitalai:osName(NÃOplatformName), ex.:os: 'Windows'+osVersion: '11'→digitalai:osName: 'Windows 11'.
Sessões de Aplicativos Móveis
Teste em dispositivos reais na nuvem. Primeiro, envie seu aplicativo (ou use uma URL de aplicativo 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
})
Sessões de Navegador Móvel
Execute um navegador em um dispositivo móvel na nuvem — dispositivo real ou emulador/simulador — sem enviar um aplicativo:
// 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
})
Observação: Sessões de navegador móvel não exigem
app,appPathounoReset. O provedor inicia um navegador diretamente no dispositivo selecionado — real ou emulador/simulador.
Use list_apps para ver aplicativos enviados 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 testar URLs que são acessíveis apenas na sua máquina local ou rede interna, habilite um 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
})
O parâmetro tunnel substitui os parâmetros obsoletos browserstackLocal, saucelabsLocal e testmuLocal. Defina-o como true para iniciar automaticamente o túnel (interrompido automaticamente após a sessão), ou 'external' para usar um túnel já em execução na sua máquina.
Observação: Com
tunnel: true, o provedor baixa e gerencia o binário do túnel para você. Paratunnel: 'external', você mesmo o executa — os recursoswdio://saucelabs/local-binary,wdio://testmu/local-binaryewdio://testingbot/local-binaryfornecem URLs de download e instruções de configuração. O TestingBot Tunnel é um único JAR Java multiplataforma (requer Java 11+) em vez de um binário por plataforma.
Rótulos de Relatório
Todos os tipos de sessão suportam rótulos reporting que aparecem no painel do provedor:
| Campo | Descrição |
|---|---|
reporting.project | Agrupa sessões sob um nome de projeto |
reporting.build | Marca sessões com um rótulo de build/versão |
reporting.session | Nome para a sessão de teste individual |
Ferramentas do Provedor de Nuvem
| Ferramenta | Descrição |
|---|---|
upload_app | Envia um .apk ou .ipa local para o provedor; retorna uma URL/referência do aplicativo |
list_apps | Lista aplicativos enviados anteriormente para o armazenamento de aplicativos do provedor |
Ambas as ferramentas exigem um parâmetro provider ('browserstack', 'saucelabs', 'testmu', 'testingbot' ou 'digitalai').
Recursos
Automação de Navegador
- Gerenciamento de Sessão: Inicie e feche sessões de navegador (Chrome, Firefox, Edge, Safari) com modos headless/com interface
- Navegação e Interação: Navegue por URLs, clique em elementos, preencha formulários e recupere conteúdo
- Análise de Página: Obtenha elementos visíveis, árvores de acessibilidade, tire capturas de tela
- Gerenciamento de Cookies: Obtenha, defina e exclua cookies
- Rolagem: Rolagem suave com distâncias configuráveis
- Anexar ao Chrome em execução: Conecte-se a uma janela existente do Chrome via
--remote-debugging-port— ideal para testar sessões autenticadas ou pré-configuradas - Conectar a endpoints WebDriver existentes: Reutilize um endpoint WebDriver compatível com Selenium já em execução, como um navegador gerenciado por framework ou uma ponte de automação de webview de desktop (como Tauri)
- Emulação de dispositivo: Aplique predefinições de mobile/tablet (iPhone 15, Pixel 7, etc.) para simular layouts responsivos sem um dispositivo físico
- Gravação de Sessão: Todas as chamadas de ferramenta são gravadas automaticamente e exportáveis como JS WebdriverIO executável
Automação de Aplicativos Móveis (iOS/Android)
- Teste de Aplicativos Nativos: Teste aplicativos iOS (.app/.ipa) e Android (.apk) via Appium
- Gestos de Toque: Toque, deslize, toque longo, arrastar e soltar
- Ciclo de Vida do Aplicativo: Inicie, coloque em segundo plano, encerre, verifique o estado do aplicativo
- Alternância de Contexto: Alterne perfeitamente entre contextos nativos e webview para aplicativos híbridos
- Controle de Dispositivo: Gire, bloqueie/desbloqueie, geolocalização, controle de teclado, notificações
- Seletores Multiplataforma: IDs de acessibilidade, XPath, UiAutomator (Android), Predicados (iOS)
Ferramentas Disponíveis
Gerenciamento de Sessão
| Ferramenta | Descrição |
|---|---|
start_session | Iniciar um navegador, aplicativo Electron local ou sessão de aplicativo móvel; attach: true mantém o modo de conexão CDP existente do Chrome |
attach_session | Anexar a uma sessão remota existente de WebDriver/Appium por ID sem criar uma nova sessão |
launch_chrome | Iniciar uma nova instância do Chrome com depuração remota habilitada (para uso com start_session({ attach: true })) |
close_session | Fechar ou desconectar da sessão atual (suporta detach: true para desconectar sem encerrar) |
emulate_device | Emular um preset de dispositivo móvel/tablet (viewport, DPR, UA, toque); requer sessão BiDi |
open_web_extension | Instalar uma extensão web via WebDriver BiDi e abrir uma de suas páginas de extensão para que ferramentas normais de página possam controlar sua interface |
Navegação e Interação com Páginas (Web e Mobile)
| Ferramenta | Descrição |
|---|---|
navigate | Navegar para uma URL |
get_elements | Obter elementos visíveis e interativos na página. Suporta inViewportOnly (padrão: true) para filtrar elementos do viewport, e includeContainers (padrão: false) para incluir contêineres de layout no mobile |
get_accessibility_tree | Obter a árvore de acessibilidade da página com papéis, nomes e seletores. Suporta filtragem por papel e paginação. Somente navegador. |
get_screenshot | Tirar uma captura de tela da página ou tela atual (codificada em base64, redimensionada automaticamente para no máximo 2000px / 1MB) |
get_tabs | Listar todas as abas abertas do navegador com identificador, título, URL e status ativo. Somente navegador. |
scroll | Rolar em uma direção (cima/baixo) por pixels especificados. Somente navegador. |
execute_script | Executar JavaScript arbitrário no navegador, ou comandos móveis do Appium em dispositivos |
execute_electron_script | Executar JavaScript privilegiado no processo principal do Electron (somente sessões Electron) |
trigger_electron_deeplink | Acionar um deeplink do Electron cujo esquema foi explicitamente configurado no início da sessão |
mock | Configurar um mock no escopo da sessão: uma função de API do processo principal do Electron ou uma solicitação de rede do navegador |
get_mock_calls | Inspecionar argumentos de chamada (Electron) ou registros de solicitações interceptadas (navegador) para um mock no escopo da sessão |
manage_mock | Limpar, redefinir ou restaurar um mock no escopo da sessão |
switch_tab | Alternar para uma aba diferente do navegador por identificador ou índice baseado em 0. Somente navegador. |
switch_frame | Alternar para um iframe por seletor CSS/XPath, ou voltar ao frame de nível superior se nenhum seletor for fornecido. Somente navegador. |
Interação com Elementos (Web e Mobile)
| Ferramenta | Descrição |
|---|---|
click_element | Clicar em um elemento |
set_value | Digitar texto em campos de entrada |
Gerenciamento de Cookies (Web)
| Ferramenta | Descrição |
|---|---|
get_cookies | Obter todos os cookies da sessão atual, ou um único cookie por nome |
set_cookie | Definir um cookie com nome, valor e atributos opcionais |
delete_cookies | Excluir todos os cookies ou um cookie específico |
Gestos Móveis (iOS/Android)
| Ferramenta | Descrição |
|---|---|
tap_element | Tocar em um elemento por seletor ou coordenadas |
swipe | Deslizar em uma direção (cima/baixo/esquerda/direita) |
drag_and_drop | Arrastar de um local para outro |
Alternância de Contexto (Aplicativos Híbridos)
| Ferramenta | Descrição |
|---|---|
get_contexts | Listar contextos de automação disponíveis (NATIVE_APP, WEBVIEW_*) e o atualmente ativo |
switch_context | Alternar entre contextos nativos e webview |
Controle de Dispositivo (iOS/Android)
| Ferramenta | Descrição |
|---|---|
get_app_state | Obter o estado atual do ciclo de vida de um aplicativo móvel (não instalado / não em execução / em segundo plano / em primeiro plano) |
rotate_device | Girar para retrato ou paisagem |
hide_keyboard | Ocultar teclado na tela |
set_geolocation | Definir localização GPS do dispositivo |
Pesquisa na Documentação
| Ferramenta | Descrição |
|---|---|
query_docs | Pesquisar a documentação oficial do WebdriverIO e retornar os trechos mais relevantes com página, seção e URL de origem. query é obrigatório (2-3 palavras-chave distintas — uma frase dilui a classificação); limit padrão é 5 (máx. 20); fullPage (padrão: false) retorna as páginas correspondentes completas em vez de trechos. Independente de sessão |
Recursos MCP (somente leitura, nenhuma chamada de ferramenta necessária)
| Recurso | Descrição |
|---|---|
wdio://sessions | Índice de todas as sessões registradas |
wdio://session/current/steps | Registro de etapas da sessão ativa |
wdio://session/current/code | JS WebdriverIO executável gerado para a sessão ativa |
wdio://session/{id}/steps | Registro de etapas de qualquer sessão anterior por ID |
wdio://session/{id}/code | JS gerado para qualquer sessão anterior por ID |
wdio://session/current/elements | Elementos interativos (somente viewport por padrão) |
wdio://session/current/accessibility | Árvore de acessibilidade |
wdio://session/current/screenshot | Captura de tela (base64) |
wdio://session/current/cookies | Cookies do navegador |
wdio://session/current/tabs | Abas abertas do navegador |
wdio://session/current/contexts | Contextos nativos/webview (mobile) |
wdio://session/current/context | Contexto atualmente ativo (mobile) |
wdio://session/current/app-state/{bundleId} | Estado do ciclo de vida do aplicativo móvel para um determinado ID de pacote |
wdio://session/current/geolocation | Geolocalização do dispositivo |
wdio://session/current/capabilities | Capacidades WebDriver resolvidas para a sessão ativa |
wdio://session/current/logs | Registros de falhas/console da sessão atual. Detecta automaticamente o tipo de sessão — navegador: registros de console + exceções JS; Android: logcat; iOS: crashlog + syslog |
wdio://browserstack/local-binary | URL de download do binário BrowserStack Local e comando de início |
wdio://saucelabs/local-binary | URL de download do binário Sauce Connect e comando de início |
wdio://testmu/local-binary | URL de download do binário TestMu Tunnel e comando de início |
wdio://testingbot/local-binary | URL de download do JAR TestingBot Tunnel e comando de início (Java 11+) |
wdio://docs/index | Cada página da documentação oficial do WebdriverIO como título separado por tabulação, caminho de origem e slug |
wdio://docs/page/{slug} | Markdown completo de uma página de documentação, truncado em 40000 caracteres. Slugs vêm de wdio://docs/index ("~" no lugar de "/") |
Exemplos de Uso
Casos de Teste do Mundo Real
Exemplo 1: Testando o Aplicativo Android de Demonstração (Digitalização de Livros)
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
Exemplo 2: Testando o Site de Comércio Eletrô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
Automação de Navegador
Prompt básico de teste 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
Opções de configuração do 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']
}
}
})
Mocking
Mocking está disponível através de mock, get_mock_calls e manage_mock, tanto para funções de API do processo principal do Electron quanto para solicitações de rede do navegador.
mockType aceita 'electron' ou 'browser'. Mocks de navegador são o padrão em sessões WebDriver quando mockType é omitido. Sessões Electron exigem uma seleção explícita porque podem direcionar ambos os tipos de mocks. Sessões Appium iOS/Android não suportam mocking.
mock({
mockType: 'electron', apiName: 'dialog', funcName: 'showOpenDialog',
behavior: 'mockResolvedValue', value: { canceled: false, filePaths: ['/tmp/example.txt'] }
})
// Interact with the renderer to open the application's file picker, then inspect its calls.
get_mock_calls({ mockType: 'electron', apiName: 'dialog', funcName: 'showOpenDialog' })
manage_mock({ mockType: 'electron', apiName: 'dialog', funcName: 'showOpenDialog', action: 'restore' })
Electron behavior padrão é mockReturnValue; mockResolvedValue e mockRejectedValue suportam APIs assíncronas. Cada um tem uma variante Once para respostas em fila. Configuração repetida preserva o mock existente e o histórico de chamadas. Valores devem ser JSON; omita value para undefined. clear remove o histórico de chamadas, reset também remove comportamento e respostas em fila, e restore restaura a função original. Essas ferramentas suportam funções de API individuais; mocks de classe e implementações de mock arbitrárias não são expostos.
Browser mocks interceptam requisições de rede que correspondem a um glob url (por exemplo, **/api/todos) com um filtro opcional method. behavior é opcional: omita-o para registrar passivamente requisições correspondentes sem alterá-las — o mock ainda continua cada requisição. respond e respondOnce exigem value (o corpo da resposta JSON) e aceitam statusCode e headers opcionais; abort/abortOnce falham a requisição, e redirect/redirectOnce a enviam para a URL em value. get_mock_calls retorna { calls, callCount } para as requisições interceptadas, e manage_mock aceita clear, reset ou restore.
start_session({ platform: 'browser', browser: 'chrome', capabilities: { webSocketUrl: true } })
// Observe-only: record every request to /api/todos without changing responses.
mock({ mockType: 'browser', url: '**/api/todos' })
navigate({ url: 'https://example.com/todos' })
get_mock_calls({ mockType: 'browser', url: '**/api/todos' })
// Or overwrite the response instead.
mock({ mockType: 'browser', url: '**/api/todos', method: 'GET', behavior: 'respond', value: [{ id: 1, title: 'Buy milk' }], statusCode: 200 })
// Interact with the page, then inspect the intercepted requests.
get_mock_calls({ mockType: 'browser', url: '**/api/todos', method: 'GET' })
manage_mock({ mockType: 'browser', url: '**/api/todos', method: 'GET', action: 'restore' })
Browser mocks exigem uma sessão com BiDi habilitado — inicie-a com capabilities: { webSocketUrl: true }. Sessões anexadas usam BiDi desativado por padrão, então browser mocks não funcionam nelas, a menos que a sessão anexada tenha negociado BiDi; em sessões Electron, browser mocks também exigem BiDi. Os handles pertencem à sessão de navegador ativa e não podem ser reutilizados após ela ser fechada ou substituída. Todas as três ferramentas participam do rastreamento e da reprodução gerada.
Aplicações Electron
O suporte a Electron é apenas local e usa o ciclo de vida autônomo oficial @wdio/electron-service. Ele exige Node.js 22.12 ou mais recente. Coloque opções de serviço como appBinaryPath, appEntryPoint e appArgs em capabilities['wdio:electronServiceOptions']; use electronRootDir de nível superior para a descoberta de Electron Builder/Electron Forge do serviço. Ao testar um binário fora do projeto, defina browserVersion para a versão do Electron, para que o serviço possa selecionar um Chromedriver compatível.
start_session({
platform: 'electron',
browserVersion: '33.2.1',
capabilities: {
'wdio:electronServiceOptions': {
appBinaryPath: '/path/to/MyApp.app/Contents/MacOS/MyApp',
appArgs: ['--disable-gpu']
}
}
})
// Privileged: this code runs in the Electron main process, not the renderer.
execute_electron_script({ script: 'return electron.app.getName()' })
As ferramentas DOM existentes do navegador funcionam no renderizador Electron. close_session sempre encerra sessões Electron gerenciadas pelo MCP; detach: true não é suportado intencionalmente. A captura de logs do processo principal/renderizador pode ser habilitada com captureMainProcessLogs ou captureRendererLogs mais logDir. Para acionar um deeplink do aplicativo, configure explicitamente o esquema de URI ao iniciar a sessão Electron. O esquema não tem dois-pontos, e apenas URLs com exatamente esse esquema podem ser despachadas:
start_session({
platform: 'electron',
electronDeeplinkScheme: 'myapp',
capabilities: {
'wdio:electronServiceOptions': {
appBinaryPath: '/path/to/MyApp.app/Contents/MacOS/MyApp'
}
}
})
trigger_electron_deeplink({ url: 'myapp://open/item' })
Anexar a uma instância Chrome em execução:
// 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'})
Conectar a um endpoint WebDriver existente:
Use provider: 'external' quando outro processo já possui o ciclo de vida do navegador ou webview e expõe um endpoint W3C
WebDriver. Isso é útil para sessões Selenium Grid, drivers de navegador gerenciados externamente ou aplicativos de desktop como apps Tauri que
incorporam um webview e expõem o WebDriver separadamente. O servidor MCP conecta-se ao endpoint; ele não inicia nem encerra o
aplicativo de destino, não abre túneis nem gerencia configuração específica do 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 aplicativos desktop com webview, como Tauri, primeiro inicie o aplicativo e sua ponte WebDriver fora deste servidor MCP; depois
passe o endpoint e as capabilities necessárias. Por exemplo, uma ponte WebDriver Tauri pode exigir
capabilities: {browserName: 'tauri'}.
Anexar a uma sessão WebDriver ou Appium existente:
Use attach_session quando a sessão já foi criada por outro processo. O MCP reutiliza o endpoint e as credenciais do
provedor selecionado, registra localmente o conjunto apropriado de comandos de navegador/mobile e não emite uma nova solicitação
de sessão. Sessões anexadas são gerenciadas externamente: close_session() desanexa por padrão, enquanto
close_session({detach: false}) encerra explicitamente a sessão 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'
}
})
Uma sessão de nuvem existente deve continuar usando o túnel com o qual foi criada. attach_session nunca inicia nem encerra um túnel;
portanto, mantenha o processo do túnel original ativo enquanto a sessão precisar dele.
Emulação de dispositivo (exige sessão 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
Extensões web (exigem sessão 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'
})
Automação de Aplicativos Mobile
Testando um app iOS no 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
Preservando o estado do app entre sessões:
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)
Testando um app iOS em 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
Testando um app 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
Detecção avançada 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
Teste de app híbrido (alternando 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
⚠️ Gerenciamento de Sessão:
- Apenas uma sessão (navegador OU app) pode estar ativa por vez
- Sempre feche as sessões ao terminar para liberar recursos do sistema
- Para alternar entre navegador e mobile, feche a sessão atual primeiro
- Use
close_session({ detach: true })para desconectar sem encerrar a sessão no servidor Appium - A preservação de estado pode ser controlada com os parâmetros
noResetefullResetdurante a criação da sessão - Sessões criadas com
noReset: trueou semappPathserão desanexadas automaticamente ao fechar - Sessões adotadas com
attach_sessionsempre desanexam ao fechar, a menos quedetach: falseseja solicitado explicitamente
⚠️ Planejamento de Tarefas:
- Divida automações complexas em operações menores e focadas
- O Claude pode consumir rapidamente os limites de mensagens com automação extensa
⚠️ Automação Mobile:
- O servidor Appium deve estar em execução antes de iniciar sessões mobile
- Garanta que emuladores/simuladores estejam em execução e que os dispositivos estejam conectados
- A automação iOS exige macOS com Xcode instalado
- Dispositivos iOS Reais: Testar em dispositivos iOS físicos exige o UDID do dispositivo (identificador único de 40 caracteres). Veja a seção Pré-requisitos para saber como encontrar seu UDID
Referência Rápida de Sintaxe de Seletores
Web (CSS/XPath):
- CSS:
button.my-class,#element-id - XPath:
//button[@class='my-class'] - Texto:
button=Exact text,a*=Contains text
Mobile (Multiplataforma):
- Accessibility ID:
~loginButton(funciona em iOS e Android) - Android UiAutomator:
android=new UiSelector().text("Login") - iOS Predicate:
-ios predicate string:label == "Login" AND visible == 1 - XPath:
//android.widget.Button[@text="Login"]
Recursos Avançados
Preservação de Estado do App
Preservação de estado com noReset/fullReset:
Controle o estado do app ao criar novas sessões usando os parâmetros noReset e fullReset:
| noReset | fullReset | Comportamento |
|---|---|---|
true | false | Preservar estado: o app permanece instalado, dados preservados |
false | false | Limpar dados do app, mas mantê-lo instalado (padrão) |
false | true | Reset completo: desinstalar e reinstalar o app (estado limpo) |
Exemplo com preservação 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
Desanexar de sessões:
A ferramenta close_session suporta um parâmetro detach que desconecta da sessão sem encerrá-la no
servidor Appium:
// Detach without killing the session
close_session({detach: true})
// Explicit session termination (closes the app and removes session)
close_session({detach: false})
Sessões criadas com noReset: true ou sem appPath serão desanexadas automaticamente ao fechar.
Sessões adotadas com attach_session são gerenciadas externamente e também desanexam por padrão; passe detach: false apenas quando o
MCP deve encerrar deliberadamente a sessão remota existente.
Isso é particularmente útil quando:
- Preservar o estado do app para continuar testes manuais
- Depurar fluxos de trabalho de várias etapas (deixar a sessão em execução entre invocações de ferramentas)
- Testar cenários em que você quer que o app permaneça instalado e no estado atual
Detecção Inteligente de Elementos
- Classificação de elementos específica da plataforma: identifica automaticamente elementos interativos versus contêineres de layout
- Android: Button, EditText, CheckBox versus ViewGroup, FrameLayout, ScrollView
- iOS: Button, TextField, Switch versus View, StackView, CollectionView
- Múltiplas estratégias de localizador: cada elemento fornece accessibility ID, resource ID, texto, XPath e seletores específicos da plataforma
- Filtragem por viewport: controle se deseja obter apenas elementos visíveis ou todos, incluindo os fora da tela
- Depuração de layout: inclua opcionalmente elementos contêiner para entender a hierarquia da interface
Tratamento Automático de Permissões e Alertas
Sessões iOS e Android agora suportam tratamento automático de permissões do sistema e alertas:
autoGrantPermissions(padrão: true): concede automaticamente permissões do app (câmera, localização etc.)autoAcceptAlerts(padrão: true): aceita automaticamente alertas e diálogos do sistemaautoDismissAlerts(opcional): defina como true para dispensar alertas em vez de aceitá-los
Isso elimina a necessidade de lidar manualmente com pop-ups de permissão durante testes automatizados.
Detalhes Técnicos
- Construído com: TypeScript, WebDriverIO, Appium
- Suporte a navegadores: Chrome, Firefox, Edge (com/sem interface, gerenciamento automático de driver), Safari (apenas com interface; macOS)
- Suporte mobile: iOS (XCUITest) e Android (UiAutomator2/Espresso)
- Protocolo: Model Context Protocol (MCP) para integração com Claude Desktop
- Modelo de sessão: sessão ativa única (navegador ou app mobile)
- Formato de dados: TOON (Token-Oriented Object Notation) para comunicação eficiente com LLM
- Detecção de elementos: análise de fonte de página baseada em XML com filtragem inteligente e geração de localizadores com múltiplas estratégias
Gravação de Sessão e Exportação de Código
Cada chamada de ferramenta é registrada automaticamente no histórico da sessão. Você pode inspecionar sessões e exportar código executável via recursos MCP — sem chamadas extras de ferramentas:
wdio://sessions— lista todas as sessões gravadas com tipo, carimbos de data/hora e contagem de etapaswdio://session/current/steps— log de etapas da sessão ativawdio://session/current/code— JS WebdriverIO executável gerado para a sessão ativawdio://session/{sessionId}/steps— log de etapas de qualquer sessão passada por IDwdio://session/{sessionId}/code— JS gerado para qualquer sessão passada por ID
O script gerado reconstrói a sessão completa — incluindo capabilities, navegação, cliques e entradas — como um
arquivo import { remote } from 'webdriverio' autônomo. Para sessões de provedores de nuvem, ele inclui o try/catch/finally completo
com marcação automática de resultado da sessão via API REST do provedor.
Gravação de Trace
Passar trace: true para start_session produz um zip .trace compatível com Playwright no diretório .trace/ quando
a sessão é encerrada. O zip pode ser reproduzido em player.vibium.dev e mostra uma tira de
capturas de tela junto com a linha do tempo das ações.
Como as capturas de tela são cronometradas
O round-trip takeScreenshot do Appium leva de 700 a 1300 ms em um emulador local, o que é tempo suficiente para as
animações da ação anterior se estabilizarem. Exploramos isso: cada captura de tela é feita antes da próxima ação ser disparada, então o que
o servidor Appium retorna já é o resultado estabilizado da ação anterior.
A parte complicada é fazer o player do trace mostrar essa captura sob a ação correta. O player associa um
evento screencast-frame à janela de tempo da ação que contém o campo timestamp do frame. Se o carimbo de data/hora
for definido como "agora" (momento da captura), ele cai antes do startTime da ação atual, e o player o rotula como o
estado antes da próxima ação — uma ação fora de sincronia.
A correção: carimbar cada screencast-frame com lastAfterEndTime — o endTime da ação que acabou de ser concluída. Isso
coloca o frame dentro da janela da ação anterior, então o player o mostra como o resultado dessa ação, não como o
precursor da próxima.
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
A captura de tela final no encerramento da sessão é carimbada com o endTime da última ação, então ela é renderizada sob essa ação
em vez de aparecer como um frame órfão após o fim da linha do tempo.
Logs de Sessão
O recurso wdio://session/current/logs retorna relatórios de falha, erros de console e logs do sistema da sessão
atual, detectando automaticamente o tipo de sessão para buscar o buffer de log correto:
| Tipo de Sessão | Fontes de Log | Conteúdos |
|---|---|---|
| Navegador | getLogs('browser') | Saída do console + exceções JS não capturadas |
| Android | getLogs('logcat') | Logs do sistema, dumps de crash, exceções fatais |
| iOS | getLogs('crashlog') + getLogs('syslog') | Relatórios de crash/panic + diagnósticos do sistema |
Nota: Ler este recurso limpa o buffer de log (conforme a especificação do WebDriver). Leituras subsequentes retornam apenas entradas acumuladas desde a última leitura. Logs do navegador exigem Chromium (Chrome/Edge) — Firefox e Safari não suportam o comando
getLogs.
A resposta é JSON com sessionType, logTypes (tipos de log disponíveis) e entries — cada entrada inclui level,
message, timestamp (ms Unix) e timestampISO.
Solução de Problemas
Automação de navegador não funcionando?
- Garanta que Chrome, Firefox, Edge ou Safari esteja instalado (Safari requer macOS)
- Tente reiniciar o Claude Desktop completamente
- Verifique se nenhuma outra instância do WebDriver está em execução
Automação mobile não funcionando?
- Verifique se o servidor Appium está em execução:
appium - Verifique se o dispositivo/emulador está em execução:
adb devices(Android) ou Xcode Devices (iOS) - Garanta que os drivers de plataforma corretos estejam instalados
- Verifique se o caminho do aplicativo está correto e acessível
Encontrou problemas ou tem sugestões? Compartilhe seu feedback!