fastlane-plugin-test_center 3.1.3 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0486d5117e1539891943e8ea57c81984fbf67b3
4
- data.tar.gz: 255a3287ae7045eb149d5009e38bb68dd4c6767c
3
+ metadata.gz: 1d20795b34c16cec61b3f6356cda1307dd6dc849
4
+ data.tar.gz: 0171b56560823d9da202a0caa98cfec51d897e3e
5
5
  SHA512:
6
- metadata.gz: a44d876d906e83f449dd63f09c335b1bad8db33e3006b02b18cdbef9bc122a5b9dbe1ee35020414c1f3143644aa5e29125285baa041c6d564082eaa66b98c896
7
- data.tar.gz: 6963a55aaac02d7ce83fdf5d98a7d2ffb998f3b26f276318308c4f2e8c84211c6e518e7ab5ebe75ce5c4b855c079e6391fc1d5565cf96702d02fb0730faba7ac
6
+ metadata.gz: 531270afbe621592914946811f17f69bc5798198dfa53466ba9c312551f33c7412a1b9be1c2f4ceebc74f399ed0eca83a30b2a10d39db98889437a829c5f1413
7
+ data.tar.gz: 2168773f546018afa810fc5c66984081448b22886ed7f846c091625519ff558827562b51d1732cfd6ed4eb5968c74719b73eee8699c7510c74dd2b9850b80805
@@ -0,0 +1,169 @@
1
+ module Fastlane
2
+ module Actions
3
+ class CollateHtmlReportsAction < Action
4
+ def self.run(params)
5
+ report_filepaths = params[:reports]
6
+ if report_filepaths.size == 1
7
+ FileUtils.cp(report_filepaths[0], params[:collated_report])
8
+ else
9
+ reports = report_filepaths.map { |report_filepath| REXML::Document.new(File.new(report_filepath)) }
10
+
11
+ # copy any missing testsuites
12
+ target_report = reports.shift
13
+ reports.each do |report|
14
+ report.elements.each("//section[contains(@class, 'test-suite')]") do |testsuite|
15
+ collate_testsuite(testsuite_from_report(target_report, testsuite), testsuite)
16
+ end
17
+ end
18
+ update_testsuites_status(target_report)
19
+ update_test_counts(target_report)
20
+
21
+ FileUtils.mkdir_p(File.dirname(params[:collated_report]))
22
+
23
+ File.open(params[:collated_report], 'w') do |f|
24
+ target_report.write(f, 2)
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.testsuite_from_report(report, testsuite)
30
+ testsuite_name = testsuite.attributes['id']
31
+ REXML::XPath.first(report, "//section[contains(@class, 'test-suite') and @id='#{testsuite_name}']")
32
+ end
33
+
34
+ def self.testcases_from_testsuite(testsuite)
35
+ REXML::XPath.match(testsuite, ".//*[contains(@class, 'tests')]//*[contains(@class, 'test')]//*[contains(@class, 'title')]")
36
+ end
37
+
38
+ def self.testcase_from_testsuite(testsuite, testcase_name)
39
+ REXML::XPath.first(testsuite, "*[contains(@class, 'test')]//*[text()='#{testcase_name}']/../..")
40
+ end
41
+
42
+ def self.collate_testsuite(target_testsuite, testsuite)
43
+ if target_testsuite
44
+ testcases = testcases_from_testsuite(testsuite)
45
+ testcases.each do |testcase|
46
+ testresult = testcase.parent.parent
47
+ target_testresult = testcase_from_testsuite(target_testsuite, testcase.text)
48
+ collate_testresults(target_testresult, testresult)
49
+ end
50
+ else
51
+ testable = REXML::XPath.first(target_report, "//section[@id='test-suites']")
52
+ testable << testsuite
53
+ end
54
+ end
55
+
56
+ def self.collate_testresults(target_testresult, testresult)
57
+ if target_testresult
58
+ collate_testresult_details(target_testresult, testresult)
59
+ target_testresult.parent.replace_child(target_testresult, testresult)
60
+ else
61
+ target_testresult << testresult
62
+ end
63
+ end
64
+
65
+ def self.collate_testresult_details(target_testresult, testresult)
66
+ target_testdetails = details_for_testresult(target_testresult)
67
+ testdetails = details_for_testresult(testresult)
68
+
69
+ if target_testdetails
70
+ if testdetails
71
+ target_testresult.parent.replace_child(target_testdetails, testdetails)
72
+ else
73
+ target_testresult.parent.delete_element(target_testdetails)
74
+ end
75
+ end
76
+ end
77
+
78
+ def self.update_testsuites_status(report)
79
+ report.elements.each("//section[contains(@class, 'test-suite')]") do |testsuite|
80
+ failing_tests_xpath = "./*[contains(@class, 'tests')]//*[" \
81
+ "contains(@class, 'failing')]"
82
+
83
+ class_attributes = testsuite.attributes['class']
84
+ test_failures = REXML::XPath.match(testsuite, failing_tests_xpath)
85
+ test_status = test_failures.size.zero? ? 'passing' : 'failing'
86
+
87
+ testsuite.attributes['class'] = class_attributes.sub('failing', test_status)
88
+ end
89
+ end
90
+
91
+ def self.update_test_counts(report)
92
+ tests_xpath = "//*[contains(@class, 'tests')]//*[contains(@class, 'test')]//*[contains(@class, 'title')]"
93
+ tests = REXML::XPath.match(report, tests_xpath)
94
+
95
+ failing_tests_xpath = "//*[contains(@class, 'tests')]//*[" \
96
+ "contains(@class, 'details') and " \
97
+ "contains(@class, 'failing')]"
98
+
99
+ test_failures = REXML::XPath.match(report, failing_tests_xpath)
100
+ REXML::XPath.first(report, ".//*[@id='test-count']/span").text = tests.size
101
+ REXML::XPath.first(report, ".//*[@id='fail-count']/span").text = test_failures.size
102
+ end
103
+
104
+ def self.details_for_testresult(testresult)
105
+ testcase = REXML::XPath.first(testresult, ".//*[contains(@class, 'title')]")
106
+
107
+ xpath = "../*[" \
108
+ "contains(@class, 'details') and " \
109
+ "contains(@class, 'failing') and " \
110
+ "contains(@class, '#{testcase.text}')]"
111
+
112
+ REXML::XPath.first(testresult, xpath)
113
+ end
114
+
115
+ #####################################################
116
+ # @!group Documentation
117
+ #####################################################
118
+
119
+ def self.description
120
+ "Combines and combines tests from multiple html report files"
121
+ end
122
+
123
+ def self.details
124
+ "The first HTML report is used as the base report. Testcases " \
125
+ "from other reports are added if they do not already exist, or " \
126
+ "if the testcases already exist, they are replaced." \
127
+ "" \
128
+ "This is done because it is assumed that fragile tests, when " \
129
+ "re-run will often succeed due to less interference from other " \
130
+ "tests and the subsequent HTML reports will have more passed tests." \
131
+ ""
132
+ end
133
+
134
+ def self.available_options
135
+ [
136
+ FastlaneCore::ConfigItem.new(
137
+ key: :reports,
138
+ env_name: 'COLLATE_HTML_REPORTS_REPORTS',
139
+ description: 'An array of HTML reports to collate. The first report is used as the base into which other reports are merged in',
140
+ optional: false,
141
+ type: Array,
142
+ verify_block: proc do |reports|
143
+ UI.user_error!('No HTML report files found') if reports.empty?
144
+ reports.each do |report|
145
+ UI.user_error!("Error: HTML report not found: '#{report}'") unless File.exist?(report)
146
+ end
147
+ end
148
+ ),
149
+ FastlaneCore::ConfigItem.new(
150
+ key: :collated_report,
151
+ env_name: 'COLLATE_HTML_REPORTS_COLLATED_REPORT',
152
+ description: 'The final HTML report file where all testcases will be merged into',
153
+ optional: true,
154
+ default_value: 'result.html',
155
+ type: String
156
+ )
157
+ ]
158
+ end
159
+
160
+ def self.authors
161
+ ["lyndsey-ferguson/@lyndseydf"]
162
+ end
163
+
164
+ def self.is_supported?(platform)
165
+ platform == :ios
166
+ end
167
+ end
168
+ end
169
+ end
@@ -52,6 +52,12 @@ module Fastlane
52
52
  passing_testcount += junit_results[:passing].size
53
53
  failure_details.merge!(junit_results[:failure_details])
54
54
  end
55
+
56
+ if reportnamer.includes_html?
57
+ report_files += Dir.glob("#{scan_options[:output_directory]}/**/*#{reportnamer.html_filextension}").map do |relative_filepath|
58
+ File.absolute_path(relative_filepath)
59
+ end
60
+ end
55
61
  {
56
62
  result: tests_passed,
57
63
  total_tests: passing_testcount + failed_tests.size,
@@ -107,6 +107,24 @@ module TestCenter
107
107
  end
108
108
  retried_junit_reportfiles = Dir.glob("#{output_directory}/**/*-[1-9]*#{reportnamer.junit_filextension}")
109
109
  FileUtils.rm_f(retried_junit_reportfiles)
110
+
111
+ if reportnamer.includes_html?
112
+ report_files = Dir.glob("#{output_directory}/*#{reportnamer.html_filextension}").map do |relative_filepath|
113
+ File.absolute_path(relative_filepath)
114
+ end
115
+ if report_files.size > 1
116
+ config = FastlaneCore::Configuration.create(
117
+ Fastlane::Actions::CollateHtmlReportsAction.available_options,
118
+ {
119
+ reports: report_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
120
+ collated_report: File.absolute_path(File.join(output_directory, reportnamer.html_reportname))
121
+ }
122
+ )
123
+ Fastlane::Actions::CollateHtmlReportsAction.run(config)
124
+ end
125
+ retried_html_reportfiles = Dir.glob("#{output_directory}/**/*-[1-9]*#{reportnamer.html_filextension}")
126
+ FileUtils.rm_f(retried_html_reportfiles)
127
+ end
110
128
  end
111
129
 
112
130
  def correcting_scan(scan_run_options, batch, reportnamer)
@@ -64,6 +64,26 @@ module TestCenter
64
64
  File.extname(junit_reportname)
65
65
  end
66
66
 
67
+ # --- HTML ---
68
+ # TODO: what to do when there are no html output types?
69
+ def includes_html?
70
+ @output_types.split(',').find_index('html') != nil
71
+ end
72
+
73
+ def html_last_reportname
74
+ html_index = @output_types.split(',').find_index('html')
75
+ numbered_filename(@output_files.to_s.split(',')[html_index])
76
+ end
77
+
78
+ def html_reportname
79
+ html_index = @output_types.split(',').find_index('html')
80
+ @output_files.to_s.split(',')[html_index]
81
+ end
82
+
83
+ def html_filextension
84
+ File.extname(html_reportname)
85
+ end
86
+
67
87
  def increment
68
88
  @report_count += 1
69
89
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TestCenter
3
- VERSION = "3.1.3"
3
+ VERSION = "3.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-test_center
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.3
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lyndsey Ferguson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-27 00:00:00.000000000 Z
11
+ date: 2018-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: plist
@@ -195,6 +195,7 @@ files:
195
195
  - LICENSE
196
196
  - README.md
197
197
  - lib/fastlane/plugin/test_center.rb
198
+ - lib/fastlane/plugin/test_center/actions/collate_html_reports.rb
198
199
  - lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb
199
200
  - lib/fastlane/plugin/test_center/actions/multi_scan.rb
200
201
  - lib/fastlane/plugin/test_center/actions/suppress_tests.rb