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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 422c6af375ea6308ceaadf40036c7e1ff5187ed660830c4a403abcea94553551
4
- data.tar.gz: 19ffb9d6d32d70274087584bce03005694fc75c6ea17d1abf2cc4c938c448d25
3
+ metadata.gz: e3ecea0ef4f0ef9f44f103bbe8c03108cbbf2200c1b3c72c27c14f41c598e463
4
+ data.tar.gz: 58b26c45f12392193baf2963a829f63504db35b8acb017774a65d8fb98e15b52
5
5
  SHA512:
6
- metadata.gz: d0ed3e523bcf4ee55edf522c4a93dbca4d1c60be1654ab87fbb625bce741dbb9df9eadd2458f33d6b9df8405cf9a8a775431982d46bb1a8d45b40983b995657b
7
- data.tar.gz: b903344bf3dbc2176f3cf21c217082e8c5a739bd7e2ff8cd9a7dda4a7b066a0a75cd74ead27e7a4a4b7a6fe557ba86f02aa6e8fdd1fd633af8b2e31396b45999
6
+ metadata.gz: 553620c60e1306d4bbdac5340556b69712343f8736697cc1f08a278ae4d60768e098021a562424e4bf0664ed77237bd1979b3e0c3a33f652178d5bbda012bf4d
7
+ data.tar.gz: 165d91270f4f0ce695d565c5c8943c5c41c8aff49337d37ea1d2e78640509b6d878d2700ed9ffa8ac6050a6aab229e85fe01a65c8de07fdb0cf2a2a83374b027
@@ -1,49 +1,24 @@
1
1
  module AppiumFailureHelper
2
2
  module Analyzer
3
- def self.triage_error(exception)
4
- case exception
5
- when Selenium::WebDriver::Error::NoSuchElementError, Selenium::WebDriver::Error::TimeoutError
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
- :unknown_issue
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
- patterns = [
29
- /element with locator ['"]?(#?\w+)['"]?/i,
30
- /(?:could not be found|cannot find element) using (.+?)=['"]?([^'"]+)['"]?/i,
31
- /no such element: Unable to locate element: {"method":"([^"]+)","selector":"([^"]+)"}/i,
32
- /(?:with the resource-id|with the accessibility-id) ['"]?(.+?)['"]?/i,
33
- /using "([^"]+)" with value "([^"]+)"/
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
- doc = Nokogiri::XML(page_source)
26
+ failed_info = Analyzer.extract_failure_details(@exception)
37
27
 
38
- # Tenta Plano A e Plano B sem reclassificar o erro.
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
- failed_info = SourceCodeAnalyzer.extract_from_exception(@exception) || {}
42
- end
43
-
44
- page_analyzer = PageAnalyzer.new(page_source, report_data[:platform].to_s)
45
- all_page_elements = page_analyzer.analyze || []
46
- similar_elements = Analyzer.find_similar_elements(failed_info, all_page_elements) || []
47
-
48
- alternative_xpaths = []
49
- if !similar_elements.empty?
50
- target_suggestion = similar_elements.first
51
- if target_suggestion[:attributes] && (target_path = target_suggestion[:attributes][:path])
52
- target_node = doc.at_xpath(target_path)
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 de diagnóstico: #{e.message}\n#{e.backtrace.join("\n")}")
48
+ Utils.logger.error("Erro fatal na GEM: #{e.message}\n#{e.backtrace.join("\n")}")
78
49
  end
79
50
  end
80
51
  end
@@ -1,3 +1,3 @@
1
1
  module AppiumFailureHelper
2
- VERSION = "1.1.4"
2
+ VERSION = "1.1.5"
3
3
  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
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-09-30 00:00:00.000000000 Z
11
+ date: 2025-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri