Appium Failure Helper
Appium Failure Helper é um módulo Ruby destinado a automatizar diagnóstico de falhas em testes de automação mobile com Appium. O objetivo é reduzir tempo de triagem, fornecer localizadores confiáveis e coletar artefatos de depuração sem depender do Appium Inspector.
Sumário
- Visão Geral
- Funcionalidades
- Arquitetura e Fluxo
- Instalação
- Configuração (opcional)
- API Pública / Integração
- Exemplos de Uso
- Formato dos Artefatos Gerados
- Lógica de Geração de XPaths (detalhada)
- Tratamento de Dados e Deduplicação
- Relatório HTML Interativo
- Logging e Observabilidade
- Testes e Qualidade
- Roadmap e Contribuição
- Licença
Visão Geral
No momento em que um teste falha, o módulo realiza, de forma atômica e thread-safe:
- captura de screenshot,
- extração do
page_source
completo (XML), - varredura da árvore de elementos para gerar localizadores sugeridos,
- escrita de dois YAMLs (focado e completo) e um relatório HTML que agrega tudo.
Todos os artefatos são salvos em uma pasta timestamped (formato YYYY_MM_DD_HHMMSS
) dentro de reports_failure/
.
Funcionalidades
- Captura automática de screenshot PNG.
- Export completo de
page_source
em XML. - Geração de
failure_analysis_*.yaml
(focado no elemento que falhou). - Geração de
all_elements_dump_*.yaml
(todos os elementos com localizadores sugeridos). - Relatório HTML interativo que combine screenshot, XML formatado e lista de localizadores.
- Geração de XPaths otimizados para Android e iOS.
- Truncamento de atributos longos (configurável).
- Eliminação de elementos duplicados e normalização de atributos.
- Logging via
Logger
do Ruby (Níveis: DEBUG/INFO/WARN/ERROR). - Configuração via bloco
configure
(opcional).
Arquitetura e Fluxo
- Hook de Testes (Cucumber/RSpec) → invoca
Capture.handler_failure(driver, exception)
- Capture.handler_failure:
- estabelece pasta de saída com timestamp;
- chama
driver.screenshot
(salva PNG); - chama
driver.page_source
(salva XML); - percorre XML e cria árvore de elementos;
- para cada elemento gera candidate XPaths aplicando regras por plataforma;
- grava
failure_analysis_*.yaml
(prioriza elemento indicado) eall_elements_dump_*.yaml
; - monta
report_*.html
agregando tudo.
- Logs detalhados emitidos durante a execução.
Instalação
Como gem (exemplo):
Adicione ao Gemfile
do projeto:
gem 'appium_failure_helper', '~> 0.1.0'
Depois:
bundle install
Ou manual (para uso local):
Coloque o diretório appium_failure_helper/
dentro do lib/
do projeto e faça:
require_relative 'lib/appium_failure_helper'
API Pública / Integração
AppiumFailureHelper::Capture
# handler_failure(driver, exception, options = {})
# - driver: objeto de sessão Appium (Selenium::WebDriver / Appium::Driver)
# - exception: exceção capturada no momento da falha
# - options: hash com overrides (ex: output_dir:)
AppiumFailureHelper::Capture.handler_failure(appium_driver, scenario.exception)
Configuração global
AppiumFailureHelper.configure do |c|
# ver bloco de configuração acima
end
Exemplos de Uso
Cucumber (hook After
)
# features/support/hooks.rb
require 'appium_failure_helper'
After do |scenario|
if scenario.failed?
AppiumFailureHelper::Capture.handler_failure(appium_driver, scenario.exception)
end
end
Formato dos Artefatos Gerados
Pasta: reports_failure/<TIMESTAMP>/
Arquivos gerados (ex.: TIMESTAMP = 2025_09_23_173045
):
screenshot_2025_09_23_173045.png
page_source_2025_09_23_173045.xml
failure_analysis_2025_09_23_173045.yaml
all_elements_dump_2025_09_23_173045.yaml
report_2025_09_23_173045.html
Exemplo (simplificado) de failure_analysis_*.yaml
failed_element:
platform: android
summary:
class: android.widget.Button
resource_id: com.example:id/submit
text: "Enviar"
suggested_xpaths:
- "//android.widget.Button[@resource-id='com.example:id/submit']"
- "//android.widget.Button[contains(@text,'Enviar')]"
capture_metadata:
screenshot: screenshot_2025_09_23_173045.png
page_source: page_source_2025_09_23_173045.xml
timestamp: "2025-09-23T17:30:45Z"
tips: "Priorize resource-id; se ausente, use accessibility id (content-desc) e class+text como fallback."
Exemplo (simplificado) de all_elements_dump_*.yaml
elements:
- id_hash: "a1b2c3..."
class: "android.widget.EditText"
resource_id: "com.example:id/input_email"
text: "[email protected]"
truncated_attributes:
hint: "Digite seu e-mail..."
suggested_xpaths:
- "//*[@resource-id='com.example:id/input_email']"
- "//android.widget.EditText[contains(@hint,'Digite seu e-mail')]"
Lógica de Geração de XPaths (detalhada)
Princípios gerais
- Priorizar identificadores estáveis (resource-id no Android / accessibility id no iOS).
- Evitar XPaths com
index
como primeira opção (usado apenas como último recurso). - Combinar atributos quando necessário para aumentar a especificidade e evitar colisões.
- Normalizar espaços e truncar textos longos.
Estratégias por plataforma (ordem de preferência)
Android
resource-id
→//*[@resource-id='com.pkg:id/id']
content-desc
/contentDescription
(accessibility) →//*[@content-desc='x']
class
+text
→//android.widget.TextView[@class='...' and contains(normalize-space(@text),'...')]
class
+ raça de atributos (combinações: enabled, clickable, package)- fallback:
//android.widget.Button[position()=n]
(último recurso)
iOS
accessibility id
(nome accessibility) →//*[@name='Submit']
label
/value
→//*[contains(@label,'...')]
type
+label
→//XCUIElementTypeButton[@label='OK']
- fallback: hierarquia / indices
Exemplo de XPath combinado (alta especificidade):
//android.widget.Button[@resource-id='com.example:id/submit' and contains(normalize-space(@text),'Enviar') and @clickable='true']
Tratamento de Dados e Deduplicação
- Truncamento: atributos com comprimento acima de
attr_truncate_length
são truncados com sufixo...
para evitar poluição do YAML. - Hash único por elemento: é gerado um hash (sha1) baseado em conjunto de atributos relevantes (class+resource-id+content-desc+text) para identificar duplicados.
- Remoção de nulos: atributos vazios ou nulos são omitidos nos YAMLs.
- Ordenação: elementos no
all_elements_dump
são ordenados por prioridade de localizador (resource-id primeiro).
Relatório HTML Interativo
O HTML gerado possui:
- Visualização inline do
screenshot
(img tag), - Painel colapsável com o
page_source
(XML formatado e collapsible), - Lista navegável de elementos com seus
suggested_xpaths
(botões para copiar), - Ancoragem que permite focalizar: ao clicar em um XPath, realça o fragmento correspondente no XML (se possível),
- Metadados e link rápido para os YAMLs.
Observação: o HTML é gerado de forma estática — para realces dinâmicos é usado JavaScript simples embutido (sem dependências externas).
Logging e Observabilidade
- Usa
Logger
padrão do Ruby:DEBUG
para detalhamento completo (padrão em modo dev).INFO
para resumo das ações realizadas.WARN/ERROR
para problemas durante captura/escrita.
- Exemplos de mensagens:
[INFO] Creating failure report folder: reports_failure/2025_09_23_173045
[DEBUG] Captured 4123 elements from page_source
[ERROR] Failed to write screenshot: Permission denied
Testes e Qualidade
- Estrutura de testes sugerida: RSpec + fixtures com dumps de
page_source
para validar a geração de XPaths. - Testes unitários para: truncamento, hash de deduplicação, geração de strategies, output YAML válido.
- CI: incluir step que valide YAML/HTML gerados (lint) e execute testes RSpec.
Roadmap e Contribuição
Funcionalidades previstas
- Suporte a mapeamento visual (overlay) para apontar elemento sobre screenshot.
- Export para outros formatos (JSON/CSV).
- Integração com ferramentas de observabilidade (Sentry, Datadog).
- Modo headless para gerar relatórios offline em pipelines.
Como contribuir
- Fork no repositório.
- Crie branch com feature/bugfix.
- Abra PR com descrição técnica das mudanças e testes.
- Mantenha o estilo Ruby (RuboCop) e documentação atualizada.
Segurança e Privacidade
- Evite capturar dados sensíveis em ambientes com PII. Implementar filtro por regex para mascarar dados (ex.: emails/telefones) antes de salvar YAMLs.
- Recomendado: executar limpeza em ambientes de produção.
Licença
MIT — veja o arquivo LICENSE
para os termos.