appium_failure_helper 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/README.md +155 -144
- data/lib/appium_failure_helper/analyzer.rb +3 -0
- data/lib/appium_failure_helper/handler.rb +21 -17
- data/lib/appium_failure_helper/version.rb +1 -1
- data/release_gem.rb +22 -12
- metadata +2 -3
- data/appium_failure_helper-1.2.3.gem +0 -0
- data/appium_failure_helper-1.2.4.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3b1148ccbdea9b7b8446bf489a8f325e6dd4255cbeeba75ed58469f21169a126
|
4
|
+
data.tar.gz: 646ef386ee881d2f9cccf4ca3e85f8a79bd3cd132221c537e6db3f07c719f91f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f345294b82fad66aa0b47e3455a85063caef1f292225f9954d5bd10a0370f29e9ba51c15d7caeed219c4e587b84f115e4e762e7b16f9408bacdc91dbce8aaf55
|
7
|
+
data.tar.gz: 505c2e690da3d723c5afb43a7afb1f219bca682e45e1c8c14068c98072c1331c90fecbe764312fe4ad3071d95df57106068b4feea5c4ca68c736b5fcbcd647dd
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/README.md
CHANGED
@@ -1,144 +1,155 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-

|
5
|
+

|
6
|
+

|
7
|
+
|
8
|
+
Uma GEM de diagnóstico para testes Appium em Ruby, projetada para transformar falhas de automação em **insights acionáveis**. Quando um teste falha por não encontrar um elemento, a ferramenta gera um relatório HTML detalhado, identificando a causa provável e acelerando drasticamente o tempo de depuração.
|
9
|
+
|
10
|
+
---
|
11
|
+
|
12
|
+
## ✨ Principais Funcionalidades
|
13
|
+
|
14
|
+
- **Diagnóstico Inteligente de Falhas:** Identifica automaticamente o tipo de erro (`NoSuchElementError`, `TimeoutError`, falha de asserção ou erro de código Ruby) e gera relatórios personalizados para cada caso.
|
15
|
+
- **Análise de Código-Fonte:** Para erros "silenciosos", inspeciona o `stack trace` e extrai o seletor diretamente do código, apontando arquivo e linha exatos.
|
16
|
+
- **Comparação Avançada de Atributos:** Compara atributo por atributo (`resource-id`, `text`, etc.) para encontrar o candidato mais provável na tela, evitando análises superficiais.
|
17
|
+
- **Relatórios Interativos:** HTML completo com:
|
18
|
+
- Screenshot da falha
|
19
|
+
- Diagnóstico claro e sugestões acionáveis
|
20
|
+
- Abas com "Análise Avançada" e "Dump Completo" de todos os elementos da tela
|
21
|
+
- **Configuração Flexível:** Personalize caminhos e arquivos de elementos para se adaptar a diferentes estruturas de projeto.
|
22
|
+
|
23
|
+
---
|
24
|
+
|
25
|
+
## 🚀 Instalação
|
26
|
+
|
27
|
+
Adicione ao `Gemfile` do seu projeto de automação:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
gem 'appium_failure_helper', git: 'URL_DO_SEU_REPOSITORIO_GIT'
|
31
|
+
```
|
32
|
+
|
33
|
+
Depois execute:
|
34
|
+
|
35
|
+
```sh
|
36
|
+
bundle install
|
37
|
+
```
|
38
|
+
|
39
|
+
---
|
40
|
+
|
41
|
+
## 🛠️ Uso e Configuração
|
42
|
+
|
43
|
+
### 1️⃣ Configuração Inicial (Opcional)
|
44
|
+
|
45
|
+
No arquivo de inicialização (`features/support/env.rb`), configure os caminhos de elementos se necessário:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
require 'appium_failure_helper'
|
49
|
+
|
50
|
+
AppiumFailureHelper.configure do |config|
|
51
|
+
config.elements_path = 'features/elements' # Pasta de elementos
|
52
|
+
config.elements_ruby_file = 'elementLists.rb' # Arquivo Ruby de elementos
|
53
|
+
end
|
54
|
+
```
|
55
|
+
|
56
|
+
---
|
57
|
+
|
58
|
+
### 2️⃣ Enriquecer Exceções (Altamente Recomendado)
|
59
|
+
|
60
|
+
Para extrair o máximo de informações de falhas, ajuste seus métodos de busca de elementos:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
def find(el)
|
64
|
+
find_element_with_enriched_error(el)
|
65
|
+
end
|
66
|
+
|
67
|
+
def clickElement(el)
|
68
|
+
find_element_with_enriched_error(el).click
|
69
|
+
end
|
70
|
+
|
71
|
+
def waitForElementExist(el, timeout = 10)
|
72
|
+
wait = Selenium::WebDriver::Wait.new(timeout: timeout)
|
73
|
+
begin
|
74
|
+
wait.until { $driver.find_elements(el['tipoBusca'], el['value']).size > 0 }
|
75
|
+
rescue Selenium::WebDriver::Error::TimeoutError => e
|
76
|
+
raise e.class, "Timeout de #{timeout}s esperando pelo elemento: using \"\#{el['tipoBusca']}\" with value \"\#{el['value']}\""
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def find_element_with_enriched_error(el)
|
83
|
+
$driver.find_element(el['tipoBusca'], el['value'])
|
84
|
+
rescue Selenium::WebDriver::Error::NoSuchElementError => e
|
85
|
+
new_exception = e.class.new("using \"\#{el['tipoBusca']}\" with value \"\#{el['value']}\"")
|
86
|
+
new_exception.set_backtrace(e.backtrace)
|
87
|
+
raise new_exception
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
---
|
92
|
+
|
93
|
+
### 3️⃣ Integração com Cucumber
|
94
|
+
|
95
|
+
No `hooks.rb`, acione a GEM após cada cenário com falha:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
After do |scenario|
|
99
|
+
if scenario.failed? && $driver&.session_id
|
100
|
+
AppiumFailureHelper.handler_failure($driver, scenario.exception)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
---
|
106
|
+
|
107
|
+
## 📄 Relatório Gerado
|
108
|
+
|
109
|
+
A cada falha, a GEM cria uma pasta em `reports_failure/` com:
|
110
|
+
|
111
|
+
1. **Relatório Simples:** Para falhas genéricas, mostrando erro, stack trace e diagnóstico direto.
|
112
|
+
2. **Relatório Detalhado:** Para problemas de seletor:
|
113
|
+
- **Coluna Esquerda:** Elemento com falha, seletores sugeridos e screenshot.
|
114
|
+
- **Coluna Direita:** Abas interativas:
|
115
|
+
- **Análise Avançada:** Mostra o candidato mais provável, atributos comparados e sugestões acionáveis.
|
116
|
+
- **Dump Completo:** Lista todos os elementos e possíveis seletores da tela.
|
117
|
+
|
118
|
+
---
|
119
|
+
|
120
|
+
## 🏛️ Arquitetura
|
121
|
+
|
122
|
+
- **Handler:** Captura falhas e aciona o fluxo de análise.
|
123
|
+
- **SourceCodeAnalyzer:** Extrai seletores diretamente do código-fonte.
|
124
|
+
- **PageAnalyzer:** Analisa o `page_source` e sugere nomes e locators alternativos.
|
125
|
+
- **XPathFactory:** Gera estratégias de localização (diretas, combinatórias, parent-based, relativas, parciais, booleanas e posicionais).
|
126
|
+
- **ReportGenerator:** Cria relatórios HTML, XML e YAML ricos e interativos.
|
127
|
+
|
128
|
+
---
|
129
|
+
|
130
|
+
## 🔄 Fluxo Interno da GEM
|
131
|
+
|
132
|
+
```
|
133
|
+
Falha Appium
|
134
|
+
│
|
135
|
+
├─► SourceCodeAnalyzer → {selector_type, selector_value}
|
136
|
+
│
|
137
|
+
└─► PageAnalyzer → [{name, locators, attributes}, ...]
|
138
|
+
│
|
139
|
+
└─► XPathFactory → [estratégias alternativas]
|
140
|
+
│
|
141
|
+
▼
|
142
|
+
ReportGenerator → HTML / XML / YAML
|
143
|
+
```
|
144
|
+
|
145
|
+
---
|
146
|
+
|
147
|
+
## 🤝 Contribuindo
|
148
|
+
|
149
|
+
Pull requests e issues são bem-vindos! Abra uma *Issue* para bugs ou sugestões.
|
150
|
+
|
151
|
+
---
|
152
|
+
|
153
|
+
## 📜 Licença
|
154
|
+
|
155
|
+
MIT License
|
@@ -6,6 +6,9 @@ module AppiumFailureHelper
|
|
6
6
|
Selenium::WebDriver::Error::TimeoutError,
|
7
7
|
Selenium::WebDriver::Error::UnknownCommandError
|
8
8
|
:locator_issue
|
9
|
+
when Selenium::WebDriver::Error::TimeoutError,
|
10
|
+
Appium::Core::Wait::TimeoutError
|
11
|
+
:locator_issue
|
9
12
|
when Selenium::WebDriver::Error::ElementNotInteractableError
|
10
13
|
:visibility_issue
|
11
14
|
when Selenium::WebDriver::Error::StaleElementReferenceError
|
@@ -32,21 +32,24 @@ module AppiumFailureHelper
|
|
32
32
|
}
|
33
33
|
|
34
34
|
if triage_result == :locator_issue
|
35
|
-
page_source = @driver.page_source
|
35
|
+
page_source = @driver.page_source rescue nil
|
36
36
|
doc = Nokogiri::XML(page_source)
|
37
37
|
|
38
|
+
# Inicializa failed_info primeiro
|
38
39
|
failed_info = Analyzer.extract_failure_details(@exception) || {}
|
39
|
-
if failed_info.empty?
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
failed_info = SourceCodeAnalyzer.extract_from_exception(@exception) || {} if failed_info.empty?
|
41
|
+
failed_info = { selector_type: 'unknown', selector_value: 'unknown' } if failed_info.empty?
|
42
|
+
|
43
|
+
# Monta o report_data
|
44
|
+
report_data[:page_source] = page_source
|
45
|
+
report_data[:failed_element] = failed_info
|
46
|
+
|
47
|
+
# Analisa elementos similares, alternative xpaths, de_para, code search etc
|
48
|
+
unless failed_info.empty?
|
46
49
|
page_analyzer = PageAnalyzer.new(page_source, report_data[:platform].to_s)
|
47
50
|
all_page_elements = page_analyzer.analyze || []
|
48
51
|
similar_elements = Analyzer.find_similar_elements(failed_info, all_page_elements) || []
|
49
|
-
|
52
|
+
|
50
53
|
alternative_xpaths = []
|
51
54
|
if !similar_elements.empty?
|
52
55
|
target_suggestion = similar_elements.first
|
@@ -60,21 +63,22 @@ module AppiumFailureHelper
|
|
60
63
|
de_para_result = Analyzer.find_de_para_match(failed_info, unified_element_map)
|
61
64
|
code_search_results = CodeSearcher.find_similar_locators(failed_info) || []
|
62
65
|
|
63
|
-
report_data.merge!(
|
64
|
-
page_source: page_source,
|
65
|
-
failed_element: failed_info,
|
66
|
+
report_data.merge!(
|
66
67
|
similar_elements: similar_elements,
|
67
68
|
alternative_xpaths: alternative_xpaths,
|
68
69
|
de_para_analysis: de_para_result,
|
69
70
|
code_search_results: code_search_results,
|
70
71
|
all_page_elements: all_page_elements
|
71
|
-
|
72
|
+
)
|
72
73
|
end
|
73
|
-
end
|
74
74
|
|
75
|
-
|
76
|
-
|
77
|
-
|
75
|
+
# Gera o relatório
|
76
|
+
ReportGenerator.new(@output_folder, report_data).generate_all
|
77
|
+
Utils.logger.info("Relatórios gerados com sucesso em: #{@output_folder}")
|
78
|
+
|
79
|
+
report_data
|
80
|
+
return
|
81
|
+
end
|
78
82
|
rescue => e
|
79
83
|
Utils.logger.error("Erro fatal na GEM de diagnóstico: #{e.message}\n#{e.backtrace.join("\n")}")
|
80
84
|
end
|
data/release_gem.rb
CHANGED
@@ -1,9 +1,16 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
1
|
require 'fileutils'
|
3
|
-
|
2
|
+
require 'selenium-webdriver'
|
3
|
+
require_relative 'lib/appium_failure_helper'
|
4
4
|
# Caminho do arquivo de versão
|
5
5
|
VERSION_FILE = 'lib/appium_failure_helper/version.rb'
|
6
6
|
|
7
|
+
# Executa os testes e retorna true se todos passarem
|
8
|
+
def tests_pass?
|
9
|
+
puts "Rodando testes..."
|
10
|
+
system('bundle exec rspec')
|
11
|
+
$?.success?
|
12
|
+
end
|
13
|
+
|
7
14
|
# Lê a versão atual da gem
|
8
15
|
def current_version
|
9
16
|
content = File.read(VERSION_FILE)
|
@@ -56,17 +63,20 @@ def git_commit_and_tag(new_version)
|
|
56
63
|
end
|
57
64
|
|
58
65
|
# Publicar a GEM
|
59
|
-
def push_gem
|
66
|
+
def push_gem(new_version)
|
60
67
|
`gem build appium_failure_helper.gemspec`
|
61
|
-
`gem push appium_failure_helper-#{
|
68
|
+
`gem push appium_failure_helper-#{new_version.join('.')}.gem`
|
62
69
|
end
|
63
70
|
|
64
71
|
# Fluxo principal
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
puts "GEM publicada com sucesso! Nova versão: #{new_version.join('.')}"
|
72
|
+
if tests_pass?
|
73
|
+
version = current_version
|
74
|
+
type = change_type
|
75
|
+
new_version = increment_version(version, type)
|
76
|
+
update_version_file(new_version)
|
77
|
+
git_commit_and_tag(new_version)
|
78
|
+
push_gem(new_version)
|
79
|
+
puts "GEM publicada com sucesso! Nova versão: #{new_version.join('.')}"
|
80
|
+
else
|
81
|
+
puts "Testes falharam! Commit e push cancelados."
|
82
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appium_failure_helper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Nascimento
|
@@ -90,11 +90,10 @@ executables: []
|
|
90
90
|
extensions: []
|
91
91
|
extra_rdoc_files: []
|
92
92
|
files:
|
93
|
+
- ".rspec"
|
93
94
|
- LICENSE.txt
|
94
95
|
- README.md
|
95
96
|
- Rakefile
|
96
|
-
- appium_failure_helper-1.2.3.gem
|
97
|
-
- appium_failure_helper-1.2.4.gem
|
98
97
|
- elements/cadastro.yaml
|
99
98
|
- elements/login.yaml
|
100
99
|
- img/fluxo_appium_failure_helper.png
|
Binary file
|
Binary file
|