appium_failure_helper 1.1.4 → 1.1.5
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/lib/appium_failure_helper/analyzer.rb +11 -36
- data/lib/appium_failure_helper/handler.rb +18 -47
- data/lib/appium_failure_helper/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3ecea0ef4f0ef9f44f103bbe8c03108cbbf2200c1b3c72c27c14f41c598e463
|
4
|
+
data.tar.gz: 58b26c45f12392193baf2963a829f63504db35b8acb017774a65d8fb98e15b52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 553620c60e1306d4bbdac5340556b69712343f8736697cc1f08a278ae4d60768e098021a562424e4bf0664ed77237bd1979b3e0c3a33f652178d5bbda012bf4d
|
7
|
+
data.tar.gz: 165d91270f4f0ce695d565c5c8943c5c41c8aff49337d37ea1d2e78640509b6d878d2700ed9ffa8ac6050a6aab229e85fe01a65c8de07fdb0cf2a2a83374b027
|
@@ -1,49 +1,24 @@
|
|
1
1
|
module AppiumFailureHelper
|
2
2
|
module Analyzer
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
def self.triage_error(exception)
|
4
|
+
# Simples e direto: se for um desses erros, é um problema de seletor.
|
5
|
+
if exception.is_a?(Selenium::WebDriver::Error::NoSuchElementError) || exception.is_a?(Selenium::WebDriver::Error::TimeoutError)
|
6
6
|
:locator_issue
|
7
|
-
when Selenium::WebDriver::Error::ElementNotInteractableError
|
8
|
-
:visibility_issue
|
9
|
-
when Selenium::WebDriver::Error::StaleElementReferenceError
|
10
|
-
:stale_element_issue
|
11
|
-
when defined?(RSpec::Expectations::ExpectationNotMetError) ? RSpec::Expectations::ExpectationNotMetError : Class.new
|
12
|
-
:assertion_failure
|
13
|
-
when NoMethodError, NameError, ArgumentError, TypeError
|
14
|
-
:ruby_code_issue
|
15
|
-
when Selenium::WebDriver::Error::SessionNotCreatedError, Errno::ECONNREFUSED
|
16
|
-
:session_startup_issue
|
17
|
-
when Selenium::WebDriver::Error::WebDriverError
|
18
|
-
return :app_crash_issue if exception.message.include?('session deleted because of page crash')
|
19
|
-
:unknown_appium_issue
|
20
7
|
else
|
21
|
-
:
|
8
|
+
:generic_issue # Para todos os outros casos
|
22
9
|
end
|
23
10
|
end
|
24
11
|
|
25
12
|
def self.extract_failure_details(exception)
|
26
13
|
message = exception.message
|
27
14
|
info = {}
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
patterns.each do |pattern|
|
36
|
-
match = message.match(pattern)
|
37
|
-
if match
|
38
|
-
if match.captures.size == 2
|
39
|
-
info[:selector_type] = match.captures[0].strip.gsub(/['"]/, '')
|
40
|
-
info[:selector_value] = match.captures[1].strip.gsub(/['"]/, '')
|
41
|
-
else
|
42
|
-
info[:selector_value] = match.captures.last.strip.gsub(/['"]/, '')
|
43
|
-
info[:selector_type] = 'id' # Padrão para regex com 1 captura
|
44
|
-
end
|
45
|
-
return info
|
46
|
-
end
|
15
|
+
# único padrão que precisa, para ler a mensagem enriquecida
|
16
|
+
pattern = /using "([^"]+)" with value "([^"]+)"/
|
17
|
+
|
18
|
+
match = message.match(pattern)
|
19
|
+
if match
|
20
|
+
info[:selector_type] = match.captures[0]
|
21
|
+
info[:selector_value] = match.captures[1]
|
47
22
|
end
|
48
23
|
info
|
49
24
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# lib/appium_failure_helper/handler.rb
|
1
2
|
module AppiumFailureHelper
|
2
3
|
class Handler
|
3
4
|
def self.call(driver, exception)
|
@@ -5,10 +6,7 @@ module AppiumFailureHelper
|
|
5
6
|
end
|
6
7
|
|
7
8
|
def initialize(driver, exception)
|
8
|
-
@driver = driver
|
9
|
-
@exception = exception
|
10
|
-
@timestamp = Time.now.strftime('%Ym%d_%H%M%S')
|
11
|
-
@output_folder = "reports_failure/failure_#{@timestamp}"
|
9
|
+
@driver = driver; @exception = exception; @timestamp = Time.now.strftime('%Y%m%d_%H%M%S'); @output_folder = "reports_failure/failure_#{@timestamp}"
|
12
10
|
end
|
13
11
|
|
14
12
|
def call
|
@@ -19,62 +17,35 @@ module AppiumFailureHelper
|
|
19
17
|
end
|
20
18
|
|
21
19
|
FileUtils.mkdir_p(@output_folder)
|
22
|
-
|
23
20
|
triage_result = Analyzer.triage_error(@exception)
|
24
21
|
|
25
|
-
report_data = {
|
26
|
-
exception: @exception,
|
27
|
-
triage_result: triage_result,
|
28
|
-
timestamp: @timestamp,
|
29
|
-
platform: @driver.capabilities['platformName'] || @driver.capabilities[:platformName] || 'unknown',
|
30
|
-
screenshot_base64: @driver.screenshot_as(:base64)
|
31
|
-
}
|
22
|
+
report_data = { exception: @exception, triage_result: triage_result, timestamp: @timestamp, platform: @driver.capabilities[:platformName], screenshot_base64: @driver.screenshot_as(:base64) }
|
32
23
|
|
33
|
-
# A análise profunda agora é executada para QUALQUER :locator_issue.
|
34
24
|
if triage_result == :locator_issue
|
35
25
|
page_source = @driver.page_source
|
36
|
-
|
26
|
+
failed_info = Analyzer.extract_failure_details(@exception)
|
37
27
|
|
38
|
-
#
|
39
|
-
failed_info = Analyzer.extract_failure_details(@exception) || {}
|
28
|
+
# Se a extração da mensagem falhou, geramos o relatório simples
|
40
29
|
if failed_info.empty?
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
alternative_xpaths = XPathFactory.generate_for_node(target_node) if target_node
|
54
|
-
end
|
30
|
+
report_data[:triage_result] = :unidentified_locator_issue
|
31
|
+
else
|
32
|
+
page_analyzer = PageAnalyzer.new(page_source, report_data[:platform].to_s)
|
33
|
+
all_page_elements = page_analyzer.analyze
|
34
|
+
best_candidate_analysis = Analyzer.perform_advanced_analysis(failed_info, all_page_elements)
|
35
|
+
|
36
|
+
report_data.merge!({
|
37
|
+
page_source: page_source,
|
38
|
+
failed_element: failed_info,
|
39
|
+
best_candidate_analysis: best_candidate_analysis,
|
40
|
+
all_page_elements: all_page_elements
|
41
|
+
})
|
55
42
|
end
|
56
|
-
|
57
|
-
unified_element_map = ElementRepository.load_all
|
58
|
-
de_para_result = Analyzer.find_de_para_match(failed_info, unified_element_map)
|
59
|
-
code_search_results = CodeSearcher.find_similar_locators(failed_info) || []
|
60
|
-
|
61
|
-
# Adiciona os dados (mesmo que vazios) ao pacote.
|
62
|
-
report_data.merge!({
|
63
|
-
page_source: page_source,
|
64
|
-
failed_element: failed_info,
|
65
|
-
similar_elements: similar_elements,
|
66
|
-
alternative_xpaths: alternative_xpaths,
|
67
|
-
de_para_analysis: de_para_result,
|
68
|
-
code_search_results: code_search_results,
|
69
|
-
all_page_elements: all_page_elements
|
70
|
-
})
|
71
43
|
end
|
72
44
|
|
73
45
|
ReportGenerator.new(@output_folder, report_data).generate_all
|
74
46
|
Utils.logger.info("Relatórios gerados com sucesso em: #{@output_folder}")
|
75
|
-
|
76
47
|
rescue => e
|
77
|
-
Utils.logger.error("Erro fatal na GEM
|
48
|
+
Utils.logger.error("Erro fatal na GEM: #{e.message}\n#{e.backtrace.join("\n")}")
|
78
49
|
end
|
79
50
|
end
|
80
51
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appium_failure_helper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Nascimento
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|