fastlane-plugin-test_center 3.8.4 → 3.8.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/fastlane/plugin/test_center/actions/collate_html_reports.rb +3 -102
- data/lib/fastlane/plugin/test_center/helper/html_test_report.rb +282 -0
- data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/report_collator.rb +4 -4
- data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan.rb +5 -0
- data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan_helper.rb +6 -2
- data/lib/fastlane/plugin/test_center/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ea22b1e286af67f521152ef2ba5862103ff5f3c75602ff03ac7d9a2641008dc6
|
|
4
|
+
data.tar.gz: e74c7f19184c067e0640f7fd8c4cf05724e7419dd8814dab498931b5b42f8fa0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 18c8938a1f216b4754f905c2402299d642855fb639b05d0e1c7dcfcea3bffb9452b7cd45c117daf639b079677dd51a82726d6cf2e016d4fe6ab119ccfaa298b6
|
|
7
|
+
data.tar.gz: ea8206538bf8c600ca725a1c2cceb3e1c697b16c2f895ea01c0b194422a9c4c835de47aa1240ada12f55aa2170b28c90684b638a233993548415f307bad08720
|
|
@@ -11,18 +11,11 @@ module Fastlane
|
|
|
11
11
|
# copy any missing testsuites
|
|
12
12
|
target_report = reports.shift
|
|
13
13
|
reports.each do |report|
|
|
14
|
-
|
|
15
|
-
collate_testsuite(testsuite_from_report(target_report, testsuite), testsuite)
|
|
16
|
-
end
|
|
14
|
+
target_report.collate_report(report)
|
|
17
15
|
end
|
|
18
|
-
update_testsuites_status(target_report)
|
|
19
|
-
update_test_counts(target_report)
|
|
20
16
|
|
|
21
17
|
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
|
|
18
|
+
target_report.save_report(params[:collated_report])
|
|
26
19
|
end
|
|
27
20
|
end
|
|
28
21
|
|
|
@@ -31,7 +24,7 @@ module Fastlane
|
|
|
31
24
|
report = nil
|
|
32
25
|
repair_attempted = false
|
|
33
26
|
begin
|
|
34
|
-
report = REXML::Document.new(File.new(report_filepath))
|
|
27
|
+
report = ::TestCenter::Helper::HtmlTestReport::Report.new(REXML::Document.new(File.new(report_filepath)))
|
|
35
28
|
rescue REXML::ParseException => e
|
|
36
29
|
if repair_attempted
|
|
37
30
|
UI.important("'#{report_filepath}' is malformed and :collate_html_reports cannot repair it")
|
|
@@ -63,98 +56,6 @@ module Fastlane
|
|
|
63
56
|
end
|
|
64
57
|
end
|
|
65
58
|
|
|
66
|
-
def self.testsuite_from_report(report, testsuite)
|
|
67
|
-
testsuite_name = testsuite.attribute('id').value
|
|
68
|
-
REXML::XPath.first(report, "//section[contains(@class, 'test-suite') and @id='#{testsuite_name}']")
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def self.testcases_from_testsuite(testsuite)
|
|
72
|
-
REXML::XPath.match(testsuite, ".//*[contains(@class, 'tests')]//*[contains(@class, 'test')]//*[contains(@class, 'title')]")
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
def self.testcase_from_testsuite(testsuite, testcase_name)
|
|
76
|
-
REXML::XPath.first(testsuite, "*[contains(@class, 'test')]//*[text()='#{testcase_name}']/../..")
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def self.collate_testsuite(target_testsuite, testsuite)
|
|
80
|
-
if target_testsuite
|
|
81
|
-
testcases = testcases_from_testsuite(testsuite)
|
|
82
|
-
testcases.each do |testcase|
|
|
83
|
-
testresult = testcase.parent.parent
|
|
84
|
-
target_testresult = testcase_from_testsuite(target_testsuite, testcase.text)
|
|
85
|
-
collate_testresults(target_testsuite, target_testresult, testresult)
|
|
86
|
-
end
|
|
87
|
-
else
|
|
88
|
-
testable = testsuite.parent
|
|
89
|
-
testable << testsuite
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def self.collate_testresults(target_testsuite, target_testresult, testresult)
|
|
94
|
-
if target_testresult
|
|
95
|
-
collate_testresult_details(target_testresult, testresult)
|
|
96
|
-
target_testresult.parent.replace_child(target_testresult, testresult)
|
|
97
|
-
else
|
|
98
|
-
target_testsuite << testresult
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def self.collate_testresult_details(target_testresult, testresult)
|
|
103
|
-
target_testdetails = details_for_testresult(target_testresult)
|
|
104
|
-
testdetails = details_for_testresult(testresult)
|
|
105
|
-
|
|
106
|
-
if target_testdetails
|
|
107
|
-
if testdetails
|
|
108
|
-
target_testresult.parent.replace_child(target_testdetails, testdetails)
|
|
109
|
-
else
|
|
110
|
-
target_testresult.parent.delete_element(target_testdetails)
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def self.update_testsuites_status(report)
|
|
116
|
-
report.elements.each("//section[contains(@class, 'test-suite')]") do |testsuite|
|
|
117
|
-
failing_tests_xpath = "./*[contains(@class, 'tests')]//*[" \
|
|
118
|
-
"contains(@class, 'failing')]"
|
|
119
|
-
|
|
120
|
-
class_attributes = testsuite.attribute('class').value
|
|
121
|
-
test_failures = REXML::XPath.match(testsuite, failing_tests_xpath)
|
|
122
|
-
test_status = test_failures.size.zero? ? 'passing' : 'failing'
|
|
123
|
-
|
|
124
|
-
testsuite.add_attribute('class', class_attributes.sub('failing', test_status))
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def self.update_test_counts(report)
|
|
129
|
-
tests_xpath = "//*[contains(@class, 'tests')]//*[contains(@class, 'test')]//*[contains(@class, 'title')]"
|
|
130
|
-
tests = REXML::XPath.match(report, tests_xpath)
|
|
131
|
-
|
|
132
|
-
failing_tests_xpath = "//*[contains(@class, 'tests')]//*[" \
|
|
133
|
-
"contains(@class, 'details') and " \
|
|
134
|
-
"contains(@class, 'failing')]"
|
|
135
|
-
|
|
136
|
-
test_failures = REXML::XPath.match(report, failing_tests_xpath)
|
|
137
|
-
test_count = REXML::XPath.first(report, ".//*[@id='test-count']/span")
|
|
138
|
-
if test_count
|
|
139
|
-
test_count.text = tests.size
|
|
140
|
-
end
|
|
141
|
-
fail_count = REXML::XPath.first(report, ".//*[@id='fail-count']/span")
|
|
142
|
-
if fail_count
|
|
143
|
-
fail_count.text = test_failures.size
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def self.details_for_testresult(testresult)
|
|
148
|
-
testcase = REXML::XPath.first(testresult, ".//*[contains(@class, 'title')]")
|
|
149
|
-
|
|
150
|
-
xpath = "../*[" \
|
|
151
|
-
"contains(@class, 'details') and " \
|
|
152
|
-
"contains(@class, 'failing') and " \
|
|
153
|
-
"contains(@class, '#{testcase.text}')]"
|
|
154
|
-
|
|
155
|
-
REXML::XPath.first(testresult, xpath)
|
|
156
|
-
end
|
|
157
|
-
|
|
158
59
|
#####################################################
|
|
159
60
|
# @!group Documentation
|
|
160
61
|
#####################################################
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
module TestCenter
|
|
2
|
+
module Helper
|
|
3
|
+
module HtmlTestReport
|
|
4
|
+
class Report
|
|
5
|
+
require 'rexml/formatters/transitive'
|
|
6
|
+
|
|
7
|
+
attr_reader :root
|
|
8
|
+
def initialize(html_file)
|
|
9
|
+
@root = html_file.root
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def testsuites
|
|
13
|
+
testsuite_elements = REXML::XPath.match(@root, "//section[contains(@class, 'test-suite')]")
|
|
14
|
+
testsuite_elements.map do |testsuite_element|
|
|
15
|
+
TestSuite.new(testsuite_element)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def add_testsuite(testsuite)
|
|
20
|
+
testsuites_element = REXML::XPath.first(@root, ".//*[@id='test-suites']")
|
|
21
|
+
testsuites_element.push(testsuite.root)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def collate_report(report)
|
|
25
|
+
testsuites.each(&:remove_duplicate_testcases)
|
|
26
|
+
report.testsuites.each(&:remove_duplicate_testcases)
|
|
27
|
+
FastlaneCore::UI.verbose("TestCenter::Helper::HtmlTestReport::Report.collate_report to report:\n\t#{@root}")
|
|
28
|
+
report.testsuites.each do |given_testsuite|
|
|
29
|
+
existing_testsuite = testsuite_with_title(given_testsuite.title)
|
|
30
|
+
if existing_testsuite.nil?
|
|
31
|
+
FastlaneCore::UI.verbose("\tadding testsuite\n\t\t#{given_testsuite}")
|
|
32
|
+
add_testsuite(given_testsuite)
|
|
33
|
+
else
|
|
34
|
+
FastlaneCore::UI.verbose("\tcollating testsuite\n\t\t#{given_testsuite.root}")
|
|
35
|
+
existing_testsuite.collate_testsuite(given_testsuite)
|
|
36
|
+
FastlaneCore::UI.verbose("\tafter collation exiting testsuite\n\t\t#{existing_testsuite.root}")
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
update_test_count
|
|
40
|
+
update_fail_count
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def testsuite_with_title(title)
|
|
44
|
+
testsuite_element = REXML::XPath.first(@root, ".//*[contains(@id, 'test-suites')]//*[@id='#{title}' and contains(concat(' ', @class, ' '), ' test-suite ')]")
|
|
45
|
+
TestSuite.new(testsuite_element) unless testsuite_element.nil?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_count
|
|
49
|
+
REXML::XPath.first(@root, ".//*[@id = 'counters']//*[@id='test-count']/*[@class = 'number']/text()").to_s.to_i
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def set_test_count(test_count)
|
|
53
|
+
test_count_element = REXML::XPath.first(@root, ".//*[@id = 'counters']//*[@id='test-count']/*[@class = 'number']/text()")
|
|
54
|
+
test_count_element.value = test_count.to_s
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def update_test_count
|
|
58
|
+
testcase_elements = REXML::XPath.match(@root, ".//*[contains(@class, 'tests')]//*[contains(concat(' ', @class, ' '), ' test ')]")
|
|
59
|
+
set_test_count(testcase_elements.size)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def fail_count
|
|
63
|
+
fail_count_element = REXML::XPath.first(@root, ".//*[@id = 'counters']//*[@id='fail-count']/*[@class = 'number']/text()")
|
|
64
|
+
return fail_count_element.to_s.to_i if fail_count_element
|
|
65
|
+
return 0
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def set_fail_count(fail_count)
|
|
69
|
+
counters_element = REXML::XPath.first(@root, ".//*[@id = 'counters']")
|
|
70
|
+
fail_count_number_element = REXML::XPath.first(counters_element, ".//*[@id='fail-count']/*[@class = 'number']/text()")
|
|
71
|
+
if fail_count_number_element
|
|
72
|
+
fail_count_number_element.value = fail_count.to_s
|
|
73
|
+
else
|
|
74
|
+
test_count_element = REXML::XPath.first(counters_element, ".//*[@id='test-count']")
|
|
75
|
+
fail_count_element = test_count_element.clone
|
|
76
|
+
fail_count_element.add_attribute('id', 'fail-count')
|
|
77
|
+
|
|
78
|
+
test_count_element.each_element do |element|
|
|
79
|
+
fail_count_element.add_element(element.clone)
|
|
80
|
+
end
|
|
81
|
+
REXML::XPath.first(fail_count_element, ".//*[@class = 'number']").text = fail_count
|
|
82
|
+
counters_element.add_element(fail_count_element)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def update_fail_count
|
|
87
|
+
xpath_class_attributes = [
|
|
88
|
+
"contains(concat(' ', @class, ' '), ' test ')",
|
|
89
|
+
"contains(concat(' ', @class, ' '), ' failing ')"
|
|
90
|
+
].join(' and ')
|
|
91
|
+
|
|
92
|
+
failing_testcase_elements = REXML::XPath.match(@root, ".//[#{xpath_class_attributes}]")
|
|
93
|
+
set_fail_count(failing_testcase_elements.size)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def add_test_center_footer
|
|
97
|
+
test_center_footer = REXML::XPath.first(@root, ".//footer[@id = 'test-center-footer']")
|
|
98
|
+
return if test_center_footer
|
|
99
|
+
|
|
100
|
+
test_center_anchor = REXML::Element.new('a')
|
|
101
|
+
test_center_anchor.text = 'collate_html_reports'
|
|
102
|
+
test_center_anchor.add_attribute('href', 'https://github.com/lyndsey-ferguson/fastlane-plugin-test_center#collate_html_reports')
|
|
103
|
+
|
|
104
|
+
test_center_footer = REXML::Element.new('footer')
|
|
105
|
+
test_center_footer.add_attribute('id', 'test-center-footer')
|
|
106
|
+
test_center_footer.text = 'Collated by the '
|
|
107
|
+
test_center_footer.add_element(test_center_anchor)
|
|
108
|
+
test_center_footer.add_text(' action from the test_center fastlane plugin')
|
|
109
|
+
|
|
110
|
+
body_element = REXML::XPath.first(@root, "//body")
|
|
111
|
+
body_element.elements.add(test_center_footer)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def save_report(report_path)
|
|
115
|
+
add_test_center_footer
|
|
116
|
+
|
|
117
|
+
output = ''
|
|
118
|
+
formatter = REXML::Formatters::Transitive.new
|
|
119
|
+
formatter.write(@root, output)
|
|
120
|
+
|
|
121
|
+
File.open(report_path, 'w') do |f|
|
|
122
|
+
f.puts output
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
class TestSuite
|
|
128
|
+
attr_reader :root
|
|
129
|
+
|
|
130
|
+
def initialize(testsuite_element)
|
|
131
|
+
@root = testsuite_element
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def title
|
|
135
|
+
@root.attribute('id').value
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def testcases
|
|
139
|
+
testcase_elements = REXML::XPath.match(@root, ".//*[contains(@class, 'tests')]//*[contains(concat(' ', @class, ' '), ' test ')]")
|
|
140
|
+
testcase_elements.map do |testcase_element|
|
|
141
|
+
TestCase.new(testcase_element)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def testcase_with_title(title)
|
|
146
|
+
testcase_element = REXML::XPath.first(@root, ".//*[contains(@class, 'tests')]//*[contains(concat(' ', @class, ' '), ' test ')]//*[@class='title']/[normalize-space()='#{title}']/../../..")
|
|
147
|
+
TestCase.new(testcase_element) unless testcase_element.nil?
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def passing?
|
|
151
|
+
@root.attribute('class').value.include?('passing')
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def set_passing(status)
|
|
155
|
+
desired_status = status ? ' passing ' : ' failing '
|
|
156
|
+
to_replace = status ? /\bfailing\b/ : /\bpassing\b/
|
|
157
|
+
|
|
158
|
+
attribute = @root.attribute('class').value.sub(to_replace, desired_status)
|
|
159
|
+
attribute.gsub!(/\s{2,}/, ' ')
|
|
160
|
+
@root.add_attribute('class', attribute)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def add_testcase(testcase)
|
|
164
|
+
tests_table = REXML::XPath.first(@root, ".//*[contains(@class, 'tests')]/table")
|
|
165
|
+
details = testcase.failure_details
|
|
166
|
+
if details
|
|
167
|
+
tests_table.push(details)
|
|
168
|
+
tests_table.insert_before(details, testcase.root)
|
|
169
|
+
else
|
|
170
|
+
tests_table.push(testcase.root)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def duplicate_testcases?
|
|
175
|
+
nonuniq_testcases = testcases
|
|
176
|
+
uniq_testcases = nonuniq_testcases.uniq { |tc| tc.title }
|
|
177
|
+
nonuniq_testcases != uniq_testcases
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def remove_duplicate_testcases
|
|
181
|
+
nonuniq_testcases = testcases
|
|
182
|
+
uniq_testcases = nonuniq_testcases.uniq { |tc| tc.title }
|
|
183
|
+
(nonuniq_testcases - uniq_testcases).each do |tc|
|
|
184
|
+
failure_details = tc.failure_details
|
|
185
|
+
tc.root.parent.delete_element(failure_details)
|
|
186
|
+
tc.root.parent.delete_element(tc.root)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def collate_testsuite(testsuite)
|
|
191
|
+
given_testcases = testsuite.testcases
|
|
192
|
+
given_testcases.each do |given_testcase|
|
|
193
|
+
existing_testcase = testcase_with_title(given_testcase.title)
|
|
194
|
+
if existing_testcase.nil?
|
|
195
|
+
FastlaneCore::UI.verbose("\t\tadding testcase\n\t\t\t#{given_testcase.root}")
|
|
196
|
+
unless given_testcase.passing?
|
|
197
|
+
FastlaneCore::UI.verbose("\t\t\twith failure:\n\t\t\t\t#{given_testcase.failure_details}")
|
|
198
|
+
end
|
|
199
|
+
add_testcase(given_testcase)
|
|
200
|
+
else
|
|
201
|
+
FastlaneCore::UI.verbose("\t\tupdating testcase\n\t\t\t#{existing_testcase.root}")
|
|
202
|
+
unless given_testcase.passing?
|
|
203
|
+
FastlaneCore::UI.verbose("\t\t\twith failure:\n\t\t\t\t#{given_testcase.failure_details}")
|
|
204
|
+
end
|
|
205
|
+
existing_testcase.update_testcase(given_testcase)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
set_passing(testcases.all?(&:passing?))
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
class TestCase
|
|
213
|
+
attr_reader :root
|
|
214
|
+
|
|
215
|
+
def initialize(testcase_element)
|
|
216
|
+
@root = testcase_element
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def title
|
|
220
|
+
REXML::XPath.first(@root, ".//h3[contains(@class, 'title')]/text()").to_s.strip
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def passing?
|
|
224
|
+
@root.attribute('class').value.include?('passing')
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def row_color
|
|
228
|
+
@root.attribute('class').value.include?('odd') ? 'odd' : ''
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def set_row_color(row_color)
|
|
232
|
+
raise 'row_color must either be "odd" or ""' unless ['odd', ''].include?(row_color)
|
|
233
|
+
|
|
234
|
+
current_class_attribute = @root.attribute('class').value.sub(/\bodd\b/, '')
|
|
235
|
+
@root.add_attribute('class', current_class_attribute << ' ' << row_color)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def failure_details
|
|
239
|
+
return nil if @root.attribute('class').value.include?('passing')
|
|
240
|
+
|
|
241
|
+
xpath_class_attributes = [
|
|
242
|
+
"contains(concat(' ', @class, ' '), ' details ')",
|
|
243
|
+
"contains(concat(' ', @class, ' '), ' failing ')",
|
|
244
|
+
"contains(concat(' ', @class, ' '), ' #{title} ')"
|
|
245
|
+
].join(' and ')
|
|
246
|
+
|
|
247
|
+
REXML::XPath.first(@root.parent, ".//[#{xpath_class_attributes}]")
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def remove_failure_details
|
|
251
|
+
details = failure_details
|
|
252
|
+
return if details.nil?
|
|
253
|
+
|
|
254
|
+
details.parent.delete_element(details)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def update_testcase(testcase)
|
|
258
|
+
color = row_color
|
|
259
|
+
failure = failure_details
|
|
260
|
+
if failure.nil? && !passing?
|
|
261
|
+
FastlaneCore::UI.error("\t\t\t\tupdating failing test case that does not have failure_details")
|
|
262
|
+
end
|
|
263
|
+
parent = @root.parent
|
|
264
|
+
|
|
265
|
+
failure.parent.delete(failure) unless failure.nil?
|
|
266
|
+
|
|
267
|
+
new_failure = testcase.failure_details
|
|
268
|
+
if new_failure && testcase.passing?
|
|
269
|
+
FastlaneCore::UI.error("\t\t\t\tswapping passing failing test case that _does_have_ failure_details")
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
parent.replace_child(@root, testcase.root)
|
|
273
|
+
@root = testcase.root
|
|
274
|
+
unless new_failure.nil?
|
|
275
|
+
parent.insert_after(@root, new_failure)
|
|
276
|
+
end
|
|
277
|
+
set_row_color(color)
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
@@ -57,7 +57,7 @@ module TestCenter
|
|
|
57
57
|
)
|
|
58
58
|
CollateJunitReportsAction.run(config)
|
|
59
59
|
FileUtils.rm_rf(report_files - [collated_file])
|
|
60
|
-
elsif report_files.size == 1 && report_files.first
|
|
60
|
+
elsif report_files.size == 1 && ! File.identical?(report_files.first, collated_file)
|
|
61
61
|
FastlaneCore::UI.verbose("Copying junit report file #{report_files.first}")
|
|
62
62
|
FileUtils.mkdir_p(File.dirname(collated_file))
|
|
63
63
|
FileUtils.mv(report_files.first, collated_file)
|
|
@@ -80,7 +80,7 @@ module TestCenter
|
|
|
80
80
|
)
|
|
81
81
|
CollateHtmlReportsAction.run(config)
|
|
82
82
|
FileUtils.rm_rf(report_files - [collated_file])
|
|
83
|
-
elsif report_files.size == 1 && report_files.first
|
|
83
|
+
elsif report_files.size == 1 && ! File.identical?(report_files.first, collated_file)
|
|
84
84
|
FastlaneCore::UI.verbose("Copying html report file #{report_files.first}")
|
|
85
85
|
FileUtils.mkdir_p(File.dirname(collated_file))
|
|
86
86
|
FileUtils.mv(report_files.first, collated_file)
|
|
@@ -103,7 +103,7 @@ module TestCenter
|
|
|
103
103
|
)
|
|
104
104
|
CollateJsonReportsAction.run(config)
|
|
105
105
|
FileUtils.rm_rf(report_files - [collated_file])
|
|
106
|
-
elsif report_files.size == 1 && report_files.first
|
|
106
|
+
elsif report_files.size == 1 && ! File.identical?(report_files.first, collated_file)
|
|
107
107
|
FastlaneCore::UI.verbose("Copying json report file #{report_files.first}")
|
|
108
108
|
FileUtils.mkdir_p(File.dirname(collated_file))
|
|
109
109
|
FileUtils.mv(report_files.first, collated_file)
|
|
@@ -126,7 +126,7 @@ module TestCenter
|
|
|
126
126
|
)
|
|
127
127
|
CollateTestResultBundlesAction.run(config)
|
|
128
128
|
FileUtils.rm_rf(test_result_bundlepaths - [collated_test_result_bundlepath])
|
|
129
|
-
elsif test_result_bundlepaths.size == 1 && test_result_bundlepaths.first != collated_test_result_bundlepath
|
|
129
|
+
elsif test_result_bundlepaths.size == 1 && File.realdirpath(test_result_bundlepaths.first) != File.realdirpath(collated_test_result_bundlepath)
|
|
130
130
|
FastlaneCore::UI.verbose("Copying test_result bundle #{test_result_bundlepaths.first}")
|
|
131
131
|
FileUtils.mkdir_p(File.dirname(collated_test_result_bundlepath))
|
|
132
132
|
FileUtils.mv(test_result_bundlepaths.first, collated_test_result_bundlepath)
|
|
@@ -30,8 +30,13 @@ module TestCenter
|
|
|
30
30
|
.merge(@retrying_scan_helper.scan_options)
|
|
31
31
|
|
|
32
32
|
prepare_scan_config_for_destination
|
|
33
|
+
scan_options[:build_for_testing] = false
|
|
34
|
+
FastlaneCore::UI.verbose("retrying_scan #update_scan_options")
|
|
33
35
|
scan_options.each do |k,v|
|
|
36
|
+
next if v.nil?
|
|
37
|
+
|
|
34
38
|
scan_config.set(k,v) unless v.nil?
|
|
39
|
+
FastlaneCore::UI.verbose("\tSetting #{k.to_s} to #{v}")
|
|
35
40
|
end
|
|
36
41
|
end
|
|
37
42
|
|
|
@@ -81,6 +81,10 @@ module TestCenter
|
|
|
81
81
|
def scan_options
|
|
82
82
|
valid_scan_keys = Fastlane::Actions::ScanAction.available_options.map(&:key)
|
|
83
83
|
xcargs = @options[:xcargs]
|
|
84
|
+
if xcargs&.include?('build-for-testing')
|
|
85
|
+
FastlaneCore::UI.important(":xcargs, #{xcargs}, contained 'build-for-testing', removing it")
|
|
86
|
+
xcargs.slice!('build-for-testing')
|
|
87
|
+
end
|
|
84
88
|
retrying_scan_options = @reportnamer.scan_options.merge(
|
|
85
89
|
{
|
|
86
90
|
output_directory: output_directory,
|
|
@@ -153,8 +157,8 @@ module TestCenter
|
|
|
153
157
|
junit_results, report_filepath = failure_details(additional_info)
|
|
154
158
|
|
|
155
159
|
info = {
|
|
156
|
-
failed: junit_results
|
|
157
|
-
passing: junit_results
|
|
160
|
+
failed: junit_results.fetch(:failed, []),
|
|
161
|
+
passing: junit_results.fetch(:passing, []),
|
|
158
162
|
batch: @options[:batch] || 1,
|
|
159
163
|
try_count: @testrun_count,
|
|
160
164
|
report_filepath: report_filepath
|
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.8.
|
|
4
|
+
version: 3.8.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lyndsey Ferguson
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2019-09-
|
|
11
|
+
date: 2019-09-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: json
|
|
@@ -255,6 +255,7 @@ files:
|
|
|
255
255
|
- lib/fastlane/plugin/test_center/actions/suppressed_tests.rb
|
|
256
256
|
- lib/fastlane/plugin/test_center/actions/tests_from_junit.rb
|
|
257
257
|
- lib/fastlane/plugin/test_center/actions/tests_from_xctestrun.rb
|
|
258
|
+
- lib/fastlane/plugin/test_center/helper/html_test_report.rb
|
|
258
259
|
- lib/fastlane/plugin/test_center/helper/junit_helper.rb
|
|
259
260
|
- lib/fastlane/plugin/test_center/helper/multi_scan_manager.rb
|
|
260
261
|
- lib/fastlane/plugin/test_center/helper/multi_scan_manager/device_manager.rb
|