fastlane-plugin-test_center 3.6.2 → 3.6.3.parallelizing

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.
Files changed (22) hide show
  1. checksums.yaml +5 -5
  2. data/lib/fastlane/plugin/test_center.rb +1 -1
  3. data/lib/fastlane/plugin/test_center/actions/collate_test_result_bundles.rb +1 -1
  4. data/lib/fastlane/plugin/test_center/actions/multi_scan.rb +28 -4
  5. data/lib/fastlane/plugin/test_center/actions/restart_core_simulator_service.rb +37 -0
  6. data/lib/fastlane/plugin/test_center/actions/tests_from_xctestrun.rb +1 -1
  7. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager.rb +5 -0
  8. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/device_manager.rb +26 -0
  9. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/interstitial.rb +143 -0
  10. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/report_collator.rb +113 -0
  11. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan.rb +72 -0
  12. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan_helper.rb +236 -0
  13. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/runner.rb +272 -0
  14. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_helper.rb +59 -0
  15. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_manager.rb +317 -0
  16. data/lib/fastlane/plugin/test_center/helper/reportname_helper.rb +15 -6
  17. data/lib/fastlane/plugin/test_center/helper/test_collector.rb +47 -3
  18. data/lib/fastlane/plugin/test_center/helper/xcodebuild_string.rb +9 -0
  19. data/lib/fastlane/plugin/test_center/helper/xctestrun_info.rb +42 -0
  20. data/lib/fastlane/plugin/test_center/version.rb +1 -1
  21. metadata +21 -12
  22. data/lib/fastlane/plugin/test_center/helper/correcting_scan_helper.rb +0 -293
@@ -1,3 +1,8 @@
1
+ module TestCenter
2
+ module Helper
3
+ MUST_SHELLESCAPE_TESTIDENTIFIER = Gem::Version.new(Fastlane::VERSION) < Gem::Version.new('2.114.0')
4
+ end
5
+ end
1
6
 
2
7
  class String
3
8
  def testsuite_swift?
@@ -11,4 +16,8 @@ class String
11
16
  self
12
17
  end
13
18
  end
19
+
20
+ def shellsafe_testidentifier
21
+ TestCenter::Helper::MUST_SHELLESCAPE_TESTIDENTIFIER ? self.shellescape : self
22
+ end
14
23
  end
@@ -0,0 +1,42 @@
1
+ module TestCenter
2
+ module Helper
3
+ require 'plist'
4
+
5
+ class XCTestrunInfo
6
+ def initialize(xctestrun_filepath)
7
+ raise Errno::ENOENT, xctestrun_filepath unless File.exist?(xctestrun_filepath)
8
+
9
+ @xctestrun = Plist.parse_xml(xctestrun_filepath)
10
+ @xctestrun_rootpath = File.dirname(xctestrun_filepath)
11
+ end
12
+
13
+ def app_path_for_testable(testable)
14
+ @xctestrun[testable].fetch('UITargetAppPath') do |_|
15
+ @xctestrun[testable]['TestHostPath']
16
+ end.sub('__TESTROOT__', @xctestrun_rootpath)
17
+ end
18
+
19
+ def app_plist_for_testable(testable)
20
+ binary_plistfile = File.join(app_path_for_testable(testable), 'Info.plist')
21
+
22
+ Plist.parse_binary_xml(binary_plistfile)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ require 'plist'
29
+
30
+ class Hash
31
+ def save_binary_plist(filename, options = {})
32
+ Plist::Emit.save_plist(self, filename)
33
+ `plutil -convert binary1 \"#{filename}\"`
34
+ end
35
+ end
36
+
37
+ module Plist
38
+ def self.parse_binary_xml(filename)
39
+ `plutil -convert xml1 \"#{filename}\"`
40
+ Plist.parse_xml(filename)
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TestCenter
3
- VERSION = "3.6.2"
3
+ VERSION = "3.6.3.parallelizing"
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.6.2
4
+ version: 3.6.3.parallelizing
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-02-07 00:00:00.000000000 Z
11
+ date: 2019-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -67,13 +67,13 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.1.7
69
69
  - !ruby/object:Gem::Dependency
70
- name: bundler
70
+ name: colorize
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- type: :development
76
+ type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: colorize
84
+ name: bundler
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: 2.56.0
103
+ version: 2.108.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: 2.56.0
110
+ version: 2.108.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: pry
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -235,16 +235,26 @@ files:
235
235
  - lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb
236
236
  - lib/fastlane/plugin/test_center/actions/collate_test_result_bundles.rb
237
237
  - lib/fastlane/plugin/test_center/actions/multi_scan.rb
238
+ - lib/fastlane/plugin/test_center/actions/restart_core_simulator_service.rb
238
239
  - lib/fastlane/plugin/test_center/actions/suppress_tests.rb
239
240
  - lib/fastlane/plugin/test_center/actions/suppress_tests_from_junit.rb
240
241
  - lib/fastlane/plugin/test_center/actions/suppressed_tests.rb
241
242
  - lib/fastlane/plugin/test_center/actions/tests_from_junit.rb
242
243
  - lib/fastlane/plugin/test_center/actions/tests_from_xctestrun.rb
243
- - lib/fastlane/plugin/test_center/helper/correcting_scan_helper.rb
244
244
  - lib/fastlane/plugin/test_center/helper/junit_helper.rb
245
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager.rb
246
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/device_manager.rb
247
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/interstitial.rb
248
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/report_collator.rb
249
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan.rb
250
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan_helper.rb
251
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/runner.rb
252
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_helper.rb
253
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_manager.rb
245
254
  - lib/fastlane/plugin/test_center/helper/reportname_helper.rb
246
255
  - lib/fastlane/plugin/test_center/helper/test_collector.rb
247
256
  - lib/fastlane/plugin/test_center/helper/xcodebuild_string.rb
257
+ - lib/fastlane/plugin/test_center/helper/xctestrun_info.rb
248
258
  - lib/fastlane/plugin/test_center/version.rb
249
259
  homepage: https://github.com/lyndsey-ferguson/fastlane-plugin-test_center
250
260
  licenses:
@@ -261,12 +271,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
261
271
  version: '0'
262
272
  required_rubygems_version: !ruby/object:Gem::Requirement
263
273
  requirements:
264
- - - ">="
274
+ - - ">"
265
275
  - !ruby/object:Gem::Version
266
- version: '0'
276
+ version: 1.3.1
267
277
  requirements: []
268
- rubyforge_project:
269
- rubygems_version: 2.6.11
278
+ rubygems_version: 3.0.2
270
279
  signing_key:
271
280
  specification_version: 4
272
281
  summary: Makes testing your iOS app easier
@@ -1,293 +0,0 @@
1
- module TestCenter
2
- module Helper
3
- require 'fastlane_core/ui/ui.rb'
4
- require 'plist'
5
- require 'json'
6
- class CorrectingScanHelper
7
- attr_reader :retry_total_count
8
-
9
- def initialize(multi_scan_options)
10
- @batch_count = multi_scan_options[:batch_count] || 1
11
- @output_directory = multi_scan_options[:output_directory] || 'test_results'
12
- @try_count = multi_scan_options[:try_count]
13
- @quit_simulators = multi_scan_options[:quit_simulators]
14
- @retry_total_count = 0
15
- @testrun_completed_block = multi_scan_options[:testrun_completed_block]
16
- @given_custom_report_file_name = multi_scan_options[:custom_report_file_name]
17
- @given_output_types = multi_scan_options[:output_types]
18
- @given_output_files = multi_scan_options[:output_files]
19
- @scan_options = multi_scan_options.reject do |option, _|
20
- %i[
21
- output_directory
22
- only_testing
23
- skip_testing
24
- clean
25
- try_count
26
- batch_count
27
- quit_simulators
28
- custom_report_file_name
29
- fail_build
30
- testrun_completed_block
31
- output_types
32
- output_files
33
- ].include?(option)
34
- end
35
- @scan_options[:clean] = false
36
- @test_collector = TestCollector.new(multi_scan_options)
37
- end
38
-
39
- def scan
40
- tests_passed = true
41
- @testables_count = @test_collector.testables.size
42
- @test_collector.testables.each do |testable|
43
- tests_passed = scan_testable(testable) && tests_passed
44
- end
45
- tests_passed
46
- end
47
-
48
- def scan_testable(testable)
49
- tests_passed = true
50
- reportnamer = ReportNameHelper.new(
51
- @given_output_types,
52
- @given_output_files,
53
- @given_custom_report_file_name
54
- )
55
- output_directory = @output_directory
56
- testable_tests = @test_collector.testables_tests[testable]
57
- if testable_tests.empty?
58
- FastlaneCore::UI.important("There are no tests to run in testable '#{testable}'. Skipping")
59
- return true
60
- end
61
-
62
- if @batch_count > 1 || @testables_count > 1
63
- current_batch = 1
64
- testable_tests.each_slice((testable_tests.length / @batch_count.to_f).round).to_a.each do |tests_batch|
65
- if @testables_count > 1
66
- output_directory = File.join(@output_directory, "results-#{testable}")
67
- end
68
- FastlaneCore::UI.header("Starting test run on testable '#{testable}'")
69
- if @scan_options[:result_bundle]
70
- FastlaneCore::UI.message("Clearing out previous test_result bundles in #{output_directory}")
71
- FileUtils.rm_rf(Dir.glob("#{output_directory}/*.test_result"))
72
- end
73
-
74
- tests_passed = correcting_scan(
75
- {
76
- only_testing: tests_batch,
77
- output_directory: output_directory
78
- },
79
- current_batch,
80
- reportnamer
81
- ) && tests_passed
82
- current_batch += 1
83
- reportnamer.increment
84
- end
85
- else
86
- options = {
87
- output_directory: output_directory,
88
- only_testing: testable_tests
89
- }
90
- tests_passed = correcting_scan(options, 1, reportnamer) && tests_passed
91
- end
92
- collate_reports(output_directory, reportnamer)
93
- tests_passed
94
- end
95
-
96
- def test_result_bundlepaths(output_directory, reportnamer)
97
- [
98
- File.join(output_directory, @scan_options[:scheme]) + '.test_result',
99
- File.join(output_directory, @scan_options[:scheme]) + "_#{reportnamer.report_count}.test_result"
100
- ]
101
- end
102
-
103
- def collate_reports(output_directory, reportnamer)
104
- collate_junit_reports(output_directory, reportnamer)
105
-
106
- if reportnamer.includes_html?
107
- collate_html_reports(output_directory, reportnamer)
108
- end
109
-
110
- if reportnamer.includes_json?
111
- collate_json_reports(output_directory, reportnamer)
112
- end
113
-
114
- if @scan_options[:result_bundle]
115
- collate_test_result_bundles(output_directory, reportnamer)
116
- end
117
- end
118
-
119
- def passed_test_count_from_summary(summary)
120
- /.*Executed (?<test_count>\d+) test, with (?<test_failures>\d+) failure/ =~ summary
121
- test_count.to_i - test_failures.to_i
122
- end
123
-
124
- def collate_test_result_bundles(output_directory, reportnamer)
125
- test_result_bundlepaths = Dir.glob("#{output_directory}/#{@scan_options[:scheme]}*.test_result").map do |relative_test_result_bundle_filepath|
126
- File.absolute_path(relative_test_result_bundle_filepath)
127
- end
128
- if test_result_bundlepaths.size > 1
129
- config = FastlaneCore::Configuration.create(
130
- Fastlane::Actions::CollateTestResultBundlesAction.available_options,
131
- {
132
- bundles: test_result_bundlepaths.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
133
- collated_bundle: File.join(output_directory, @scan_options[:scheme]) + '.test_result'
134
- }
135
- )
136
- Fastlane::Actions::CollateTestResultBundlesAction.run(config)
137
- end
138
- retried_test_result_bundlepaths = Dir.glob("#{output_directory}/#{@scan_options[:scheme]}_*.test_result")
139
- FileUtils.rm_rf(retried_test_result_bundlepaths)
140
- end
141
-
142
- def collate_json_reports(output_directory, reportnamer)
143
- report_filepaths = Dir.glob("#{output_directory}/#{reportnamer.json_fileglob}").map do |relative_filepath|
144
- File.absolute_path(relative_filepath)
145
- end
146
- if report_filepaths.size > 1
147
- config = FastlaneCore::Configuration.create(
148
- Fastlane::Actions::CollateJsonReportsAction.available_options,
149
- {
150
- reports: report_filepaths.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
151
- collated_report: File.absolute_path(File.join(output_directory, reportnamer.json_reportname))
152
- }
153
- )
154
- Fastlane::Actions::CollateJsonReportsAction.run(config)
155
- end
156
- retried_json_reportfiles = Dir.glob("#{output_directory}/#{reportnamer.json_numbered_fileglob}")
157
- FileUtils.rm_f(retried_json_reportfiles)
158
- end
159
-
160
- def collate_html_reports(output_directory, reportnamer)
161
- report_files = Dir.glob("#{output_directory}/#{reportnamer.html_fileglob}").map do |relative_filepath|
162
- File.absolute_path(relative_filepath)
163
- end
164
- if report_files.size > 1
165
- config = FastlaneCore::Configuration.create(
166
- Fastlane::Actions::CollateHtmlReportsAction.available_options,
167
- {
168
- reports: report_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
169
- collated_report: File.absolute_path(File.join(output_directory, reportnamer.html_reportname))
170
- }
171
- )
172
- Fastlane::Actions::CollateHtmlReportsAction.run(config)
173
- end
174
- retried_html_reportfiles = Dir.glob("#{output_directory}/#{reportnamer.html_numbered_fileglob}")
175
- FileUtils.rm_f(retried_html_reportfiles)
176
- end
177
-
178
- def collate_junit_reports(output_directory, reportnamer)
179
- report_files = Dir.glob("#{output_directory}/#{reportnamer.junit_fileglob}").map do |relative_filepath|
180
- File.absolute_path(relative_filepath)
181
- end
182
- if report_files.size > 1
183
- config = FastlaneCore::Configuration.create(
184
- Fastlane::Actions::CollateJunitReportsAction.available_options,
185
- {
186
- reports: report_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
187
- collated_report: File.absolute_path(File.join(output_directory, reportnamer.junit_reportname))
188
- }
189
- )
190
- Fastlane::Actions::CollateJunitReportsAction.run(config)
191
- end
192
- retried_junit_reportfiles = Dir.glob("#{output_directory}/#{reportnamer.junit_numbered_fileglob}")
193
- FileUtils.rm_f(retried_junit_reportfiles)
194
- end
195
-
196
- def correcting_scan(scan_run_options, batch, reportnamer)
197
- scan_options = @scan_options.merge(scan_run_options)
198
- try_count = 0
199
- tests_passed = true
200
- xcpretty_json_file_output = ENV['XCPRETTY_JSON_FILE_OUTPUT']
201
- begin
202
- try_count += 1
203
- config = FastlaneCore::Configuration.create(
204
- Fastlane::Actions::ScanAction.available_options,
205
- scan_options.merge(reportnamer.scan_options)
206
- )
207
- quit_simulators
208
- if reportnamer.includes_json?
209
- ENV['XCPRETTY_JSON_FILE_OUTPUT'] = File.join(
210
- scan_options[:output_directory],
211
- reportnamer.json_last_reportname
212
- )
213
- end
214
- Fastlane::Actions::ScanAction.run(config)
215
- @testrun_completed_block && @testrun_completed_block.call(
216
- testrun_info(batch, try_count, reportnamer, scan_options[:output_directory])
217
- )
218
- tests_passed = true
219
- rescue FastlaneCore::Interface::FastlaneTestFailure => e
220
- FastlaneCore::UI.verbose("Scan failed with #{e}")
221
- info = testrun_info(batch, try_count, reportnamer, scan_options[:output_directory])
222
- @testrun_completed_block && @testrun_completed_block.call(
223
- info
224
- )
225
- if try_count < @try_count
226
- @retry_total_count += 1
227
- scan_options.delete(:code_coverage)
228
- scan_options[:only_testing] = info[:failed].map(&:shellescape)
229
- FastlaneCore::UI.message('Re-running scan on only failed tests')
230
- reportnamer.increment
231
- if @scan_options[:result_bundle]
232
- built_test_result, moved_test_result = test_result_bundlepaths(
233
- scan_options[:output_directory], reportnamer
234
- )
235
- FileUtils.mv(built_test_result, moved_test_result)
236
- end
237
- retry
238
- end
239
- tests_passed = false
240
- ensure
241
- ENV['XCPRETTY_JSON_FILE_OUTPUT'] = xcpretty_json_file_output
242
- end
243
- tests_passed
244
- end
245
-
246
- def testrun_info(batch, try_count, reportnamer, output_directory)
247
- report_filepath = File.join(output_directory, reportnamer.junit_last_reportname)
248
- config = FastlaneCore::Configuration.create(
249
- Fastlane::Actions::TestsFromJunitAction.available_options,
250
- {
251
- junit: File.absolute_path(report_filepath)
252
- }
253
- )
254
- junit_results = Fastlane::Actions::TestsFromJunitAction.run(config)
255
-
256
- info = {
257
- failed: junit_results[:failed],
258
- passing: junit_results[:passing],
259
- batch: batch,
260
- try_count: try_count,
261
- report_filepath: report_filepath
262
- }
263
- if reportnamer.includes_html?
264
- html_report_filepath = File.join(output_directory, reportnamer.html_last_reportname)
265
- info[:html_report_filepath] = html_report_filepath
266
- end
267
- if reportnamer.includes_json?
268
- json_report_filepath = File.join(output_directory, reportnamer.json_last_reportname)
269
- info[:json_report_filepath] = json_report_filepath
270
- end
271
- if @scan_options[:result_bundle]
272
- test_result_suffix = '.test_result'
273
- test_result_suffix.prepend("_#{reportnamer.report_count}") unless reportnamer.report_count.zero?
274
- test_result_bundlepath = File.join(output_directory, @scan_options[:scheme]) + test_result_suffix
275
- info[:test_result_bundlepath] = test_result_bundlepath
276
- end
277
- info
278
- end
279
-
280
- def quit_simulators
281
- return unless @quit_simulators
282
-
283
- Fastlane::Actions.sh("killall -9 'iPhone Simulator' 'Simulator' 'SimulatorBridge' &> /dev/null || true", log: false)
284
- launchctl_list_count = 0
285
- while Fastlane::Actions.sh('launchctl list | grep com.apple.CoreSimulator.CoreSimulatorService || true', log: false) != ''
286
- break if (launchctl_list_count += 1) > 10
287
- Fastlane::Actions.sh('launchctl remove com.apple.CoreSimulator.CoreSimulatorService &> /dev/null || true', log: false)
288
- sleep(1)
289
- end
290
- end
291
- end
292
- end
293
- end