fastlane-plugin-retry_tests 1.2.8 → 1.2.9

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: 32c5975d7acd0ad38b357fa71192c8557609f42b
4
- data.tar.gz: 57ea614acc20fcee707d2a35f36180cc15504038
3
+ metadata.gz: 32bf848c6f9dedbbc10b83eb2c3a0b494e54ce27
4
+ data.tar.gz: f588d58c28cf698efedb32332897020f59f5db54
5
5
  SHA512:
6
- metadata.gz: 61d4605ab74ed8ac4345d4713ba057ac23b97c613efe32c4b0e39c15e8544065339ff9c5cb4c2a1cca73ea6786f9fb0e01031b902d2ad2b68f721911da4270c9
7
- data.tar.gz: de0dd075ecdd7d1339222b948f606d640a85d1970623afbff47ba53b028466287524e8dbb78061d96af24f145c576323a44b9b48deb4d6affe4490705db66fd1
6
+ metadata.gz: 95b16cd8a9c88160821a2206e853fdadb62ac7419da7b94d866ff0d12daed2cb6d4972a5cc3ee1357c3e7a6a11a9f4466bdb37c278d6564567b99ea9756b35ca
7
+ data.tar.gz: 1993130eea75cd9111e02643f9ad33a29b114b87a8dee41c08a55fa09ee8d06a6264da5fa066f743033eb937ce61d477def7ffacbd5e1592ccf8c632491e0cc1
@@ -0,0 +1,16 @@
1
+ #require 'fastlane/plugin/retry_tests/version'
2
+
3
+ module Fastlane
4
+ module TestCenter
5
+ # Return all .rb files inside the "actions" and "helper" directory
6
+ def self.all_classes
7
+ Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
8
+ end
9
+ end
10
+ end
11
+
12
+ # By default we want to import all available actions and helpers
13
+ # A plugin can contain any number of actions and plugins
14
+ Fastlane::TestCenter.all_classes.each do |current|
15
+ require current
16
+ end
@@ -0,0 +1,178 @@
1
+
2
+ require 'nokogiri'
3
+ require 'nokogiri-plist'
4
+ require 'FileUtils'
5
+ module Fastlane
6
+ module Actions
7
+ class CollateJunitReportsAction < Action
8
+
9
+ def self.run(params)
10
+ report_filepaths = params[:reports].reverse
11
+ if report_filepaths.size == 1
12
+ FileUtils.cp(report_filepaths[0], params[:collated_report])
13
+ else
14
+ target_report = File.open(report_filepaths.shift) {|f| Nokogiri::XML(f)}
15
+ file_name = params[:collated_report] + "/#{params[:scheme]}.test_result/1_Test/action_TestSummaries.plist"
16
+ reports = report_filepaths.map { |report_filepath| Nokogiri::XML(Nokogiri::PList(open(report_filepath)).to_plist_xml) }
17
+ reports.each do |retry_report|
18
+ mergeLists(target_report, retry_report, params)
19
+ end
20
+ end
21
+ merge_assets(params[:assets], params[:collated_report] + "/Attachments")
22
+ copy_log(params[:logs], params[:collated_report] + "/")
23
+ end
24
+
25
+ def self.clean_report(report)
26
+ report = report.gsub(/<(\w+): 0x(\w+)>/, '(\1: 0x\2)')
27
+ report = report.gsub(/<XCAccessibilityElement:\/>0x(\w+)/, '(XCAccessibilityElement): 0x\1')
28
+ report
29
+ end
30
+
31
+ def self.copy_log(log_files, logs_folder)
32
+ target_log = log_files.shift
33
+ FileUtils.cp_r(target_log, logs_folder)
34
+ end
35
+
36
+ def self.mergeLists(target_report, retry_report, params)
37
+ retry_report = clean_report(retry_report)
38
+ UI.verbose("Merging retried results...")
39
+ Dir.mkdir(params[:collated_report]) unless File.exists?(params[:collated_report])
40
+ file_name = params[:collated_report] + "/action_TestSummaries.plist"
41
+ retried_tests = retry_report.xpath("//key[contains(.,'TestSummaryGUID')]/..")
42
+ current_node = retried_tests.shift
43
+ while (current_node != nil)
44
+ testName = get_test_name(current_node)
45
+ matching_node = target_report.at_xpath("//string[contains(.,'#{testName}')]/..")
46
+
47
+ if (!matching_node.nil?)
48
+ matching_node.previous.next.replace(current_node)
49
+ write_report_to_file(target_report, file_name)
50
+ end
51
+ current_node = retried_tests.shift
52
+ end
53
+ end
54
+
55
+ def self.merge_assets(asset_files, assets_folder)
56
+ UI.verbose ("Merging screenshot folders...")
57
+ Dir.mkdir(assets_folder) unless File.exists?(assets_folder)
58
+ asset_files.each do |folder|
59
+ FileUtils.cp_r(Dir[folder + '/*'], assets_folder)
60
+ end
61
+ end
62
+
63
+ def self.merge_logs(log_files, logs_folder)
64
+ UI.verbose("Merging console logs...")
65
+ target_log = log_files.shift
66
+ log_files.each do |log|
67
+ to_append = File.read(log)
68
+ File.open(target_log, "a") do |handle|
69
+ handle.puts to_append
70
+ end
71
+ FileUtils.cp_r(target_log, logs_folder)
72
+ end
73
+ end
74
+
75
+ def self.write_report_to_file(report, file_name)
76
+ UI.verbose("Writing merged results to file...")
77
+ File.new(file_name, 'w')
78
+ File.open(file_name, 'w') do |f|
79
+ f.write(report.to_xml)
80
+ end
81
+ end
82
+
83
+ def self.get_test_name(test_data)
84
+ test_name = test_data.xpath("(//key[contains(.,'TestSummaryGUID')])/../key[contains(.,'TestName')]/following-sibling::string").to_a[0].to_s
85
+ test_name = test_name[8..-10]
86
+ test_name
87
+ end
88
+
89
+ #####################################################
90
+ # @!group Documentation
91
+ #####################################################
92
+
93
+ def self.description
94
+ "Combines and combines tests from multiple junit report files"
95
+ end
96
+
97
+ def self.details
98
+ "The first junit report is used as the base report. Testcases " \
99
+ "from other reports are added if they do not already exist, or " \
100
+ "if the testcases already exist, they are replaced." \
101
+ "" \
102
+ "This is done because it is assumed that fragile tests, when " \
103
+ "re-run will often succeed due to less interference from other " \
104
+ "tests and the subsequent junit reports will have more passed tests." \
105
+ "" \
106
+ "Inspired by Derek Yang's fastlane-plugin-merge_junit_report"
107
+ end
108
+
109
+ def self.available_options
110
+ [
111
+ FastlaneCore::ConfigItem.new(
112
+ key: :scheme,
113
+ env_name: 'SCHEME',
114
+ description: 'The test scheme being run',
115
+ optional: false,
116
+ default_value: '',
117
+ type: String
118
+ ),
119
+ FastlaneCore::ConfigItem.new(
120
+ key: :reports,
121
+ env_name: 'COLLATE_JUNIT_REPORTS_REPORTS',
122
+ description: 'An array of junit reports to collate. The first report is used as the base into which other reports are merged in',
123
+ optional: false,
124
+ type: Array,
125
+ verify_block: proc do |reports|
126
+ UI.user_error!('No junit report files found') if reports.empty?
127
+ reports.each do |report|
128
+ UI.user_error!("Error: junit report not found: '#{report}'") unless File.exist?(report)
129
+ end
130
+ end
131
+ ),
132
+ FastlaneCore::ConfigItem.new(
133
+ key: :collated_report,
134
+ env_name: 'COLLATE_JUNIT_REPORTS_COLLATED_REPORT',
135
+ description: 'The final junit report file where all testcases will be merged into',
136
+ optional: true,
137
+ default_value: 'result.xml',
138
+ type: String
139
+ ),
140
+ FastlaneCore::ConfigItem.new(
141
+ key: :assets,
142
+ env_name: 'COLLATE_JUNIT_REPORTS_ASSETS',
143
+ description: 'An array of junit reports to collate. The first report is used as the base into which other reports are merged in',
144
+ optional: false,
145
+ type: Array,
146
+ verify_block: proc do |assets|
147
+ UI.user_error!('No junit report files found') if assets.empty?
148
+ assets.each do |asset|
149
+ UI.user_error!("Error: junit report not found: '#{asset}'") unless File.exist?(asset)
150
+ end
151
+ end
152
+ ),
153
+ FastlaneCore::ConfigItem.new(
154
+ key: :logs,
155
+ env_name: 'COLLATE_JUNIT_REPORTS_LOGS',
156
+ description: 'An array of junit reports to collate. The first report is used as the base into which other reports are merged in',
157
+ optional: false,
158
+ type: Array,
159
+ verify_block: proc do |logs|
160
+ UI.user_error!('No junit report files found') if logs.empty?
161
+ logs.each do |log|
162
+ UI.user_error!("Error: junit report not found: '#{log}'") unless File.exist?(log)
163
+ end
164
+ end
165
+ )
166
+ ]
167
+ end
168
+
169
+ def self.authors
170
+ ["lyndsey-ferguson/@lyndseydf"]
171
+ end
172
+
173
+ def self.is_supported?(platform)
174
+ platform == :ios
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,143 @@
1
+ module Fastlane
2
+ module Actions
3
+ require 'fastlane/actions/scan'
4
+ require 'shellwords'
5
+
6
+ class MultiScanAction < Action
7
+ def self.run(params)
8
+ try_count = 0
9
+ scan_options = params.values.reject { |k| k == :try_count }
10
+ final_report_path = scan_options[:result_bundle]
11
+ unless Helper.test?
12
+ FastlaneCore::PrintTable.print_values(
13
+ config: params._values.reject { |k, v| scan_options.key?(k) },
14
+ title: "Summary for multi_scan (test_center v#{Fastlane::TestCenter::VERSION})"
15
+ )
16
+ end
17
+
18
+ scan_options = config_with_junit_report(scan_options)
19
+
20
+ begin
21
+ try_count += 1
22
+ scan_options = config_with_retry(scan_options, try_count)
23
+ config = FastlaneCore::Configuration.create(Fastlane::Actions::ScanAction.available_options, scan_options)
24
+ Fastlane::Actions::ScanAction.run(config)
25
+ rescue FastlaneCore::Interface::FastlaneTestFailure => e
26
+ UI.verbose("Scan failed with #{e}")
27
+ if try_count < params[:try_count]
28
+ report_filepath = junit_report_filepath(scan_options)
29
+ failed_tests = other_action.tests_from_junit(junit: report_filepath)[:failed]
30
+ scan_options[:only_testing] = failed_tests.map(&:shellescape)
31
+ retry
32
+ end
33
+ end
34
+ merge_reports(scan_options, final_report_path)
35
+ end
36
+
37
+ def self.merge_reports(scan_options, final_report_path)
38
+ folder = get_folder_root(scan_options[:output_directory])
39
+ report_files = Dir.glob("#{folder}*/#{scan_options[:scheme]}.test_result/1_Test/action_TestSummaries.plist")
40
+ asset_files = Dir.glob("#{folder}*/#{scan_options[:scheme]}.test_result/1_Test/Attachments")
41
+ log_files = Dir.glob("#{folder}*/#{scan_options[:scheme]}.test_result/1_Test/action.xcactivitylog")
42
+ #Merge all reports, screenshots, and logs if there were retried tests
43
+
44
+ if report_files.size > 1
45
+ other_action.collate_junit_reports(
46
+ scheme: scan_options[:scheme],
47
+ reports: report_files,
48
+ collated_report: final_report_path,
49
+ assets: asset_files,
50
+ logs: log_files,
51
+ )
52
+ end
53
+ end
54
+
55
+ def self.config_has_junit_report(config)
56
+ output_types = config.fetch(:output_types, '').to_s.split(',')
57
+ output_filenames = config.fetch(:output_files, '').to_s.split(',')
58
+
59
+ output_type_file_count_match = output_types.size == output_filenames.size
60
+ output_types.include?('junit') && (output_type_file_count_match || config[:custom_report_file_name].to_s.strip.length > 0)
61
+ end
62
+
63
+ def self.config_with_retry(config, count)
64
+ folder = get_folder_root(config[:result_bundle])
65
+ config[:result_bundle] = (folder + count.to_s)
66
+ config[:output_directory] = (folder + count.to_s)
67
+ config
68
+ end
69
+
70
+ def self.get_folder_root(folder)
71
+ folder = folder.gsub(/ *\d+$/, '')
72
+ folder
73
+ end
74
+
75
+ def self.config_with_junit_report(config)
76
+ return config if config_has_junit_report(config)
77
+
78
+ if config[:output_types].to_s.strip.empty? || config[:custom_report_file_name]
79
+ config[:custom_report_file_name] ||= 'report.xml'
80
+ config[:output_types] = 'junit'
81
+ elsif config[:output_types].strip == 'junit' && config[:output_files].to_s.strip.empty?
82
+ config[:custom_report_file_name] ||= 'report.xml'
83
+ elsif !config[:output_types].split(',').include?('junit')
84
+ config[:output_types] << ',junit'
85
+ config[:output_files] << ',report.xml'
86
+ elsif config[:output_files].nil?
87
+ config[:output_files] = config[:output_types].split(',').map { |type| "report.#{type}" }.join(',')
88
+ end
89
+ config
90
+ end
91
+
92
+ def self.junit_report_filename(config)
93
+ report_filename = config[:custom_report_file_name]
94
+ if report_filename.nil?
95
+ junit_index = config[:output_types].split(',').find_index('junit')
96
+ report_filename = config[:output_files].to_s.split(',')[junit_index]
97
+ end
98
+ report_filename
99
+ end
100
+
101
+ def self.junit_report_filepath(config)
102
+ File.absolute_path(File.join(config[:output_directory], junit_report_filename(config)))
103
+ end
104
+
105
+ #####################################################
106
+ # @!group Documentation
107
+ #####################################################
108
+
109
+ def self.description
110
+ "Uses scan to run Xcode tests a given number of times: only re-testing failing tests."
111
+ end
112
+
113
+ def self.details
114
+ "Use this action to run your tests if you have fragile tests that fail sporadically."
115
+ end
116
+
117
+ def self.scan_options
118
+ ScanAction.available_options
119
+ end
120
+
121
+ def self.available_options
122
+ scan_options + [
123
+ FastlaneCore::ConfigItem.new(
124
+ key: :try_count,
125
+ env_name: "FL_MULTI_SCAN_TRY_COUNT",
126
+ description: "The number of times to retry running tests via scan",
127
+ type: Integer,
128
+ is_string: false,
129
+ default_value: 1
130
+ )
131
+ ]
132
+ end
133
+
134
+ def self.authors
135
+ ["lyndsey-ferguson/@lyndseydf"]
136
+ end
137
+
138
+ def self.is_supported?(platform)
139
+ platform == :ios
140
+ end
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,93 @@
1
+ module Fastlane
2
+ module Actions
3
+ class SuppressTestsAction < Action
4
+ require 'xcodeproj'
5
+
6
+ def self.run(params)
7
+ project_path = params[:xcodeproj]
8
+ all_tests_to_skip = params[:tests]
9
+ scheme = params[:scheme]
10
+
11
+ scheme_filepaths = Dir.glob("#{project_path}/{xcshareddata,xcuserdata}/**/xcschemes/#{scheme || '*'}.xcscheme")
12
+ if scheme_filepaths.length.zero?
13
+ UI.user_error!("Error: cannot find any scheme named #{scheme}") unless scheme.nil?
14
+ UI.user_error!("Error: cannot find any schemes in the Xcode project")
15
+ end
16
+
17
+ scheme_filepaths.each do |scheme_filepath|
18
+ is_dirty = false
19
+ xcscheme = Xcodeproj::XCScheme.new(scheme_filepath)
20
+ xcscheme.test_action.testables.each do |testable|
21
+ buildable_name = File.basename(testable.buildable_references[0].buildable_name, '.xctest')
22
+
23
+ tests_to_skip = all_tests_to_skip.select { |test| test.start_with?(buildable_name) }
24
+ .map { |test| test.sub("#{buildable_name}/", '') }
25
+
26
+ tests_to_skip.each do |test_to_skip|
27
+ skipped_test = Xcodeproj::XCScheme::TestAction::TestableReference::SkippedTest.new
28
+ skipped_test.identifier = test_to_skip
29
+ testable.add_skipped_test(skipped_test)
30
+ is_dirty = true
31
+ end
32
+ end
33
+ xcscheme.save! if is_dirty
34
+ end
35
+ nil
36
+ end
37
+
38
+ #####################################################
39
+ # @!group Documentation
40
+ #####################################################
41
+
42
+ def self.description
43
+ "Suppresses specific tests in a specific or all Xcode Schemes in a given project"
44
+ end
45
+
46
+ def self.available_options
47
+ [
48
+ FastlaneCore::ConfigItem.new(
49
+ key: :xcodeproj,
50
+ env_name: "FL_SUPPRESS_TESTS_XCODE_PROJECT",
51
+ description: "The file path to the Xcode project file to modify",
52
+ verify_block: proc do |path|
53
+ UI.user_error!("Error: Xcode project file path not given!") unless path and !path.empty?
54
+ UI.user_error!("Error: Xcode project '#{path}' not found!") unless Dir.exist?(path)
55
+ end
56
+ ),
57
+ FastlaneCore::ConfigItem.new(
58
+ key: :tests,
59
+ env_name: "FL_SUPPRESS_TESTS_TESTS_TO_SUPPRESS",
60
+ description: "A list of tests to suppress",
61
+ verify_block: proc do |tests|
62
+ UI.user_error!("Error: no tests were given to suppress!") unless tests and !tests.empty?
63
+ tests.each do |test_identifier|
64
+ is_valid_test_identifier = %r{^[a-zA-Z][a-zA-Z0-9]+\/[a-zA-Z][a-zA-Z0-9]+(\/test[a-zA-Z0-9]+)?$} =~ test_identifier
65
+ unless is_valid_test_identifier
66
+ UI.user_error!("Error: invalid test identifier '#{test_identifier}'. It must be in the format of 'Testable/TestSuiteToSuppress' or 'Testable/TestSuiteToSuppress/testToSuppress'")
67
+ end
68
+ end
69
+ end,
70
+ type: Array
71
+ ),
72
+ FastlaneCore::ConfigItem.new(
73
+ key: :scheme,
74
+ optional: true,
75
+ env_name: "FL_SUPPRESS_TESTS_SCHEME_TO_UPDATE",
76
+ description: "The Xcode scheme where the tests should be suppressed",
77
+ verify_block: proc do |scheme_name|
78
+ UI.user_error!("Error: Xcode Scheme '#{scheme_name}' is not valid!") if scheme_name and scheme_name.empty?
79
+ end
80
+ )
81
+ ]
82
+ end
83
+
84
+ def self.authors
85
+ ["lyndsey-ferguson/@lyndseydf"]
86
+ end
87
+
88
+ def self.is_supported?(platform)
89
+ platform == :ios
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,102 @@
1
+ module Fastlane
2
+ module Actions
3
+ class SuppressTestsFromJunitAction < Action
4
+ def self.run(params)
5
+ project_path = params[:xcodeproj]
6
+ scheme = params[:scheme]
7
+
8
+ scheme_filepaths = Dir.glob("#{project_path}/{xcshareddata,xcuserdata}/**/xcschemes/#{scheme || '*'}.xcscheme")
9
+ if scheme_filepaths.length.zero?
10
+ UI.user_error!("Error: cannot find any scheme named #{scheme}") unless scheme.nil?
11
+ UI.user_error!("Error: cannot find any schemes in the Xcode project")
12
+ end
13
+
14
+ testables = Hash.new([])
15
+ desired_passed_status = (params[:suppress_type] == :passing)
16
+
17
+ report = ::TestCenter::Helper::XcodeJunit::Report.new(params[:junit])
18
+
19
+ report.testables.each do |testable|
20
+ testables[testable.name] = []
21
+ testable.testsuites.each do |testsuite|
22
+ testsuite.testcases.each do |testcase|
23
+ if testcase.passed? == desired_passed_status
24
+ testables[testable.name] << testcase.skipped_test
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ scheme_filepaths.each do |scheme_filepath|
31
+ is_dirty = false
32
+ xcscheme = Xcodeproj::XCScheme.new(scheme_filepath)
33
+
34
+ xcscheme.test_action.testables.each do |testable|
35
+ buildable_name = testable.buildable_references[0].buildable_name
36
+ testables[buildable_name].each do |skipped_test|
37
+ testable.add_skipped_test(skipped_test)
38
+ is_dirty = true
39
+ end
40
+ end
41
+ xcscheme.save! if is_dirty
42
+ end
43
+ end
44
+
45
+ #####################################################
46
+ # @!group Documentation
47
+ #####################################################
48
+
49
+ def self.description
50
+ "Uses a junit xml report file to suppress either passing or failing tests in an Xcode Scheme"
51
+ end
52
+
53
+ def self.available_options
54
+ [
55
+ FastlaneCore::ConfigItem.new(
56
+ key: :xcodeproj,
57
+ env_name: "FL_SUPPRESS_TESTS_FROM_JUNIT_XCODE_PROJECT",
58
+ description: "The file path to the Xcode project file to modify",
59
+ verify_block: proc do |path|
60
+ UI.user_error!("Error: Xcode project file path not given!") unless path and !path.empty?
61
+ UI.user_error!("Error: Xcode project '#{path}' not found!") unless Dir.exist?(path)
62
+ end
63
+ ),
64
+ FastlaneCore::ConfigItem.new(
65
+ key: :junit,
66
+ env_name: "FL_SUPPRESS_TESTS_FROM_JUNIT_JUNIT_REPORT",
67
+ description: "The junit xml report file from which to collect the tests to suppress",
68
+ verify_block: proc do |path|
69
+ UI.user_error!("Error: cannot find the junit xml report file '#{path}'") unless File.exist?(path)
70
+ end
71
+ ),
72
+ FastlaneCore::ConfigItem.new(
73
+ key: :scheme,
74
+ optional: true,
75
+ env_name: "FL_SUPPRESS_TESTS_FROM_JUNIT_SCHEME_TO_UPDATE",
76
+ description: "The Xcode scheme where the tests should be suppressed",
77
+ verify_block: proc do |scheme_name|
78
+ UI.user_error!("Error: Xcode Scheme '#{scheme_name}' is not valid!") if scheme_name and scheme_name.empty?
79
+ end
80
+ ),
81
+ FastlaneCore::ConfigItem.new(
82
+ key: :suppress_type,
83
+ type: Symbol,
84
+ env_name: "FL_SUPPRESS_TESTS_FROM_JUNIT_SUPPRESS_TYPE",
85
+ description: "Tests to suppress are either :failed or :passing",
86
+ verify_block: proc do |type|
87
+ UI.user_error!("Error: suppress type ':#{type}' is invalid! Only :failed or :passing are valid types") unless %i[failed passing].include?(type)
88
+ end
89
+ )
90
+ ]
91
+ end
92
+
93
+ def self.authors
94
+ ["lyndsey-ferguson/@lyndseydf"]
95
+ end
96
+
97
+ def self.is_supported?(platform)
98
+ platform == :ios
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,72 @@
1
+ module Fastlane
2
+ module Actions
3
+ class SuppressedTestsAction < Action
4
+ require 'set'
5
+
6
+ def self.run(params)
7
+ project_path = params[:xcodeproj]
8
+ scheme = params[:scheme]
9
+
10
+ scheme_filepaths = Dir.glob("#{project_path}/{xcshareddata,xcuserdata}/**/xcschemes/#{scheme || '*'}.xcscheme")
11
+ if scheme_filepaths.length.zero?
12
+ UI.user_error!("Error: cannot find any scheme named #{scheme}") unless scheme.nil?
13
+ UI.user_error!("Error: cannot find any schemes in the Xcode project")
14
+ end
15
+
16
+ skipped_tests = Set.new
17
+ scheme_filepaths.each do |scheme_filepath|
18
+ xcscheme = Xcodeproj::XCScheme.new(scheme_filepath)
19
+ xcscheme.test_action.testables.each do |testable|
20
+ buildable_name = testable.buildable_references[0]
21
+ .buildable_name
22
+
23
+ buildable_name = File.basename(buildable_name, '.xctest')
24
+ testable.skipped_tests.map do |skipped_test|
25
+ skipped_tests.add("#{buildable_name}/#{skipped_test.identifier}")
26
+ end
27
+ end
28
+ end
29
+ skipped_tests.to_a
30
+ end
31
+
32
+ #####################################################
33
+ # @!group Documentation
34
+ #####################################################
35
+
36
+ def self.description
37
+ "Retrieves a list of tests that are suppressed in a specific or all Xcode Schemes in a project"
38
+ end
39
+
40
+ def self.available_options
41
+ [
42
+ FastlaneCore::ConfigItem.new(
43
+ key: :xcodeproj,
44
+ env_name: "FL_SUPPRESSED_TESTS_XCODE_PROJECT",
45
+ description: "The file path to the Xcode project file to read the skipped tests from",
46
+ verify_block: proc do |path|
47
+ UI.user_error!("Error: Xcode project file path not given!") unless path and !path.empty?
48
+ UI.user_error!("Error: Xcode project '#{path}' not found!") unless Dir.exist?(path)
49
+ end
50
+ ),
51
+ FastlaneCore::ConfigItem.new(
52
+ key: :scheme,
53
+ optional: true,
54
+ env_name: "FL_SUPPRESSED_TESTS_SCHEME_TO_UPDATE",
55
+ description: "The Xcode scheme where the suppressed tests may be",
56
+ verify_block: proc do |scheme_name|
57
+ UI.user_error!("Error: Xcode Scheme '#{scheme_name}' is not valid!") if scheme_name and scheme_name.empty?
58
+ end
59
+ )
60
+ ]
61
+ end
62
+
63
+ def self.authors
64
+ ["lyndsey-ferguson/@lyndseydf"]
65
+ end
66
+
67
+ def self.is_supported?(platform)
68
+ platform == :ios
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,59 @@
1
+ module Fastlane
2
+ module Actions
3
+ class TestsFromJunitAction < Action
4
+ def self.run(params)
5
+ report = ::TestCenter::Helper::XcodeJunit::Report.new(params[:junit])
6
+ passing = []
7
+ failed = []
8
+ report.testables.each do |testable|
9
+ testable.testsuites.each do |testsuite|
10
+ testsuite.testcases.each do |testcase|
11
+ if testcase.passed?
12
+ passing << testcase.identifier
13
+ else
14
+ failed << testcase.identifier
15
+ end
16
+ end
17
+ end
18
+ end
19
+ {
20
+ failed: failed,
21
+ passing: passing
22
+ }
23
+ end
24
+
25
+ #####################################################
26
+ # @!group Documentation
27
+ #####################################################
28
+
29
+ def self.description
30
+ "Retrieves the failing and passing tests as reported in a junit xml file"
31
+ end
32
+
33
+ def self.available_options
34
+ [
35
+ FastlaneCore::ConfigItem.new(
36
+ key: :junit,
37
+ env_name: "FL_SUPPRESS_TESTS_FROM_JUNIT_JUNIT_REPORT", # The name of the environment variable
38
+ description: "The junit xml report file from which to collect the tests to suppress",
39
+ verify_block: proc do |path|
40
+ UI.user_error!("Error: cannot find the junit xml report file '#{path}'") unless File.exist?(path)
41
+ end
42
+ )
43
+ ]
44
+ end
45
+
46
+ def self.return_value
47
+ "A Hash with an Array of :passing and :failed tests"
48
+ end
49
+
50
+ def self.authors
51
+ ["lyndsey-ferguson/lyndseydf"]
52
+ end
53
+
54
+ def self.is_supported?(platform)
55
+ platform == :ios
56
+ end
57
+ end
58
+ end
59
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-retry_tests
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.8
4
+ version: 1.2.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gloria Chow
@@ -180,6 +180,13 @@ extra_rdoc_files: []
180
180
  files:
181
181
  - LICENSE
182
182
  - README.md
183
+ - lib/fastlane/plugin/retry_tests.rb
184
+ - lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb
185
+ - lib/fastlane/plugin/retry_tests/actions/multi_scan.rb
186
+ - lib/fastlane/plugin/retry_tests/actions/suppress_tests.rb
187
+ - lib/fastlane/plugin/retry_tests/actions/suppress_tests_from_junit.rb
188
+ - lib/fastlane/plugin/retry_tests/actions/suppressed_tests.rb
189
+ - lib/fastlane/plugin/retry_tests/actions/tests_from_junit.rb
183
190
  homepage: https://github.com/kouzoh/fastlane-plugin-retry_tests
184
191
  licenses:
185
192
  - MIT