fastlane-plugin-test_center 3.9.0 → 3.10.3
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/README.md +4 -0
- data/lib/fastlane/plugin/test_center/actions/multi_scan.rb +54 -18
- data/lib/fastlane/plugin/test_center/actions/suppress_tests.rb +35 -11
- data/lib/fastlane/plugin/test_center/actions/suppressed_tests.rb +13 -6
- data/lib/fastlane/plugin/test_center/actions/tests_from_xctestrun.rb +19 -3
- data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan.rb +13 -5
- data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan_helper.rb +47 -3
- data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/runner.rb +45 -11
- data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_helper.rb +15 -4
- data/lib/fastlane/plugin/test_center/helper/test_collector.rb +3 -5
- data/lib/fastlane/plugin/test_center/helper/xcodeproj/scheme/test_action.rb +25 -0
- 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: '098e845a533aae1482f49c2265234f95e6b6415a6f389fca3956851f009841da'
|
4
|
+
data.tar.gz: 612fa05cd1d3c550ed344ecc34f9f7a54a4d50a701711e33c7154f496d05104e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd691d0fd30fc8a3a06d082f9a751a7101c1de6843819136d1fb18b66051435412bf8fe41606012ce65552096337a844ea1536896394b9ce6d679b3e80f00014
|
7
|
+
data.tar.gz: 25354716d6138969a45954a0f77429be98ea188e1a8fb9c4bda0b92300ea1d85df128526b65c4ef9e76575561f1aeddcb9c7fd9a9dd1133a6dbed3031af9dd21
|
data/README.md
CHANGED
@@ -91,6 +91,10 @@ For more information about how the `fastlane` plugin system works, check out the
|
|
91
91
|
|
92
92
|
_fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
|
93
93
|
|
94
|
+
## Supporter
|
95
|
+
|
96
|
+
I'm grateful to all of the people who contributed back to `test_center`, all the people who helped test for new features or bug fixes, but most importantly I am grateful to my wife who supports my crazy passion for making software.
|
97
|
+
|
94
98
|
## License
|
95
99
|
|
96
100
|
MIT
|
@@ -14,25 +14,21 @@ module Fastlane
|
|
14
14
|
class MultiScanAction < Action
|
15
15
|
def self.run(params)
|
16
16
|
params[:quit_simulators] = params._values[:force_quit_simulator] if params._values[:force_quit_simulator]
|
17
|
-
if params[:
|
18
|
-
|
19
|
-
|
20
|
-
if params[:output_files]
|
21
|
-
params[:output_files] = params[:output_files].split(',').map(&:strip).join(',')
|
17
|
+
if params[:try_count] < 1
|
18
|
+
UI.important('multi_scan will not test any if :try_count < 0, setting to 1')
|
19
|
+
params[:try_count] = 1
|
22
20
|
end
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
UI.important("The 'xcresult' :output_type is only supported for Xcode 11 and greater. You are using #{FastlaneCore::Helper.xcode_version}.")
|
30
|
-
end
|
22
|
+
strip_leading_and_trailing_whitespace_from_output_types(params)
|
23
|
+
|
24
|
+
warn_of_xcode11_result_bundle_incompatability(params)
|
25
|
+
warn_of_parallelism_with_circle_ci(params)
|
26
|
+
|
31
27
|
print_multi_scan_parameters(params)
|
32
28
|
force_quit_simulator_processes if params[:quit_simulators]
|
33
29
|
|
34
30
|
prepare_for_testing(params.values)
|
35
|
-
|
31
|
+
|
36
32
|
coerce_destination_to_array(params)
|
37
33
|
platform = :mac
|
38
34
|
platform = :ios_simulator if Scan.config[:destination].any? { |d| d.include?('platform=iOS Simulator') }
|
@@ -43,17 +39,43 @@ module Fastlane
|
|
43
39
|
|
44
40
|
summary = run_summary(params, tests_passed)
|
45
41
|
print_run_summary(summary)
|
46
|
-
|
42
|
+
|
47
43
|
if params[:fail_build] && !tests_passed
|
48
44
|
raise UI.test_failure!('Tests have failed')
|
49
45
|
end
|
50
46
|
summary
|
51
47
|
end
|
52
48
|
|
49
|
+
def self.warn_of_parallelism_with_circle_ci(params)
|
50
|
+
if params[:parallel_testrun_count] > 1 && Helper.is_circle_ci?
|
51
|
+
UI.important("Warning: problems have occurreed when running parallel simulators on Circle CI.")
|
52
|
+
UI.message(" See https://github.com/lyndsey-ferguson/fastlane-plugin-test_center/issues/179")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.strip_leading_and_trailing_whitespace_from_output_types(params)
|
57
|
+
if params[:output_types]
|
58
|
+
params[:output_types] = params[:output_types].split(',').map(&:strip).join(',')
|
59
|
+
end
|
60
|
+
if params[:output_files]
|
61
|
+
params[:output_files] = params[:output_files].split(',').map(&:strip).join(',')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.warn_of_xcode11_result_bundle_incompatability(params)
|
66
|
+
if FastlaneCore::Helper.xcode_at_least?('11.0.0')
|
67
|
+
if params[:result_bundle]
|
68
|
+
UI.important('As of Xcode 11, test_result bundles created in the output directory are actually symbolic links to an xcresult bundle')
|
69
|
+
end
|
70
|
+
elsif params[:output_types]&.include?('xcresult')
|
71
|
+
UI.important("The 'xcresult' :output_type is only supported for Xcode 11 and greater. You are using #{FastlaneCore::Helper.xcode_version}.")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
53
75
|
def self.coerce_destination_to_array(params)
|
54
76
|
destination = params[:destination] || Scan.config[:destination] || []
|
55
77
|
unless destination.kind_of?(Array)
|
56
|
-
params[:destination] = Scan.config[:destination] = [destination]
|
78
|
+
params[:destination] = Scan.config[:destination] = [destination]
|
57
79
|
end
|
58
80
|
end
|
59
81
|
|
@@ -68,7 +90,7 @@ module Fastlane
|
|
68
90
|
# :nocov:
|
69
91
|
end
|
70
92
|
|
71
|
-
def self.print_run_summary(summary)
|
93
|
+
def self.print_run_summary(summary)
|
72
94
|
return if Helper.test?
|
73
95
|
|
74
96
|
# :nocov:
|
@@ -147,6 +169,7 @@ module Fastlane
|
|
147
169
|
def self.prepare_for_testing(scan_options)
|
148
170
|
reset_scan_config_to_defaults
|
149
171
|
use_scanfile_to_override_settings(scan_options)
|
172
|
+
turn_off_concurrent_workers(scan_options)
|
150
173
|
ScanHelper.remove_preexisting_simulator_logs(scan_options)
|
151
174
|
if scan_options[:test_without_building] || scan_options[:skip_build]
|
152
175
|
UI.verbose("Preparing Scan config options for multi_scan testing")
|
@@ -157,6 +180,12 @@ module Fastlane
|
|
157
180
|
end
|
158
181
|
end
|
159
182
|
|
183
|
+
def self.turn_off_concurrent_workers(scan_options)
|
184
|
+
if Gem::Version.new(Fastlane::VERSION) >= Gem::Version.new('2.142.0')
|
185
|
+
scan_options.delete(:concurrent_workers) if scan_options[:concurrent_workers].to_i > 0
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
160
189
|
def self.reset_scan_config_to_defaults
|
161
190
|
return unless Scan.config
|
162
191
|
|
@@ -173,7 +202,7 @@ module Fastlane
|
|
173
202
|
overridden_options = ScanHelper.options_from_configuration_file(
|
174
203
|
ScanHelper.scan_options_from_multi_scan_options(scan_options)
|
175
204
|
)
|
176
|
-
|
205
|
+
|
177
206
|
unless overridden_options.empty?
|
178
207
|
FastlaneCore::UI.important("Scanfile found: overriding multi_scan options with it's values.")
|
179
208
|
overridden_options.each do |k,v|
|
@@ -303,6 +332,13 @@ module Fastlane
|
|
303
332
|
UI.user_error!("Error: Batch counts must be greater than zero") unless count > 0
|
304
333
|
end
|
305
334
|
),
|
335
|
+
FastlaneCore::ConfigItem.new(
|
336
|
+
key: :retry_test_runner_failures,
|
337
|
+
description: "Set to true If you want to treat build failures during testing, like 'Test runner exited before starting test execution', as 'all tests failed'",
|
338
|
+
type: Boolean,
|
339
|
+
default_value: false,
|
340
|
+
optional: true
|
341
|
+
),
|
306
342
|
FastlaneCore::ConfigItem.new(
|
307
343
|
key: :invocation_based_tests,
|
308
344
|
description: "Set to true If your test suit have invocation based tests like Kiwi",
|
@@ -374,7 +410,7 @@ module Fastlane
|
|
374
410
|
UI.important(
|
375
411
|
'example: ' \\
|
376
412
|
'split the tests into 4 batches and run each batch of tests in ' \\
|
377
|
-
'parallel up to 3 times if tests fail. Abort the testing early ' \\
|
413
|
+
'parallel up to 3 times if tests fail. Abort the testing early ' \\
|
378
414
|
'if there are too many failing tests by passing in a ' \\
|
379
415
|
':testrun_completed_block that is called by :multi_scan ' \\
|
380
416
|
'after each run of tests.'
|
@@ -17,17 +17,23 @@ module Fastlane
|
|
17
17
|
scheme_filepaths.each do |scheme_filepath|
|
18
18
|
is_dirty = false
|
19
19
|
xcscheme = Xcodeproj::XCScheme.new(scheme_filepath)
|
20
|
-
xcscheme.test_action.
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
20
|
+
testplans = xcscheme.test_action.test_plans
|
21
|
+
unless testplans.nil?
|
22
|
+
container_directory = File.absolute_path(File.dirname(params[:xcodeproj] || params[:workspace]))
|
23
|
+
update_testplans(container_directory, testplans, all_tests_to_skip)
|
24
|
+
else
|
25
|
+
xcscheme.test_action.testables.each do |testable|
|
26
|
+
buildable_name = File.basename(testable.buildable_references[0].buildable_name, '.xctest')
|
27
|
+
|
28
|
+
tests_to_skip = all_tests_to_skip.select { |test| test.start_with?(buildable_name) }
|
29
|
+
.map { |test| test.sub("#{buildable_name}/", '') }
|
30
|
+
|
31
|
+
tests_to_skip.each do |test_to_skip|
|
32
|
+
skipped_test = Xcodeproj::XCScheme::TestAction::TestableReference::SkippedTest.new
|
33
|
+
skipped_test.identifier = test_to_skip
|
34
|
+
testable.add_skipped_test(skipped_test)
|
35
|
+
is_dirty = true
|
36
|
+
end
|
31
37
|
end
|
32
38
|
end
|
33
39
|
xcscheme.save! if is_dirty
|
@@ -35,6 +41,24 @@ module Fastlane
|
|
35
41
|
nil
|
36
42
|
end
|
37
43
|
|
44
|
+
def self.update_testplans(container_directory, testplans, all_tests_to_skip)
|
45
|
+
testplans.each do |testplan_reference|
|
46
|
+
testplan_filename = testplan_reference.target_referenced_container.sub('container:', '')
|
47
|
+
testplan_filepath = File.join(container_directory, testplan_filename)
|
48
|
+
file = File.read(testplan_filepath)
|
49
|
+
testplan = JSON.parse(file)
|
50
|
+
testplan['testTargets'].each do |test_target|
|
51
|
+
buildable_name = test_target.dig('target', 'name')
|
52
|
+
tests_to_skip = all_tests_to_skip.select { |test| test.start_with?(buildable_name) }
|
53
|
+
.map { |test| test.sub("#{buildable_name}/", '') }
|
54
|
+
test_target['selectedTests'].reject! { |t| tests_to_skip.include?(t) }
|
55
|
+
end
|
56
|
+
File.open(testplan_filepath, 'w') do |f|
|
57
|
+
f.write(JSON.pretty_generate(testplan).gsub('/', '\/'))
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
38
62
|
def self.schemes_from_project(project_path, scheme)
|
39
63
|
return nil unless project_path
|
40
64
|
|
@@ -2,6 +2,7 @@ module Fastlane
|
|
2
2
|
module Actions
|
3
3
|
class SuppressedTestsAction < Action
|
4
4
|
require 'set'
|
5
|
+
require 'json'
|
5
6
|
|
6
7
|
def self.run(params)
|
7
8
|
scheme = params[:scheme]
|
@@ -15,13 +16,19 @@ module Fastlane
|
|
15
16
|
skipped_tests = Set.new
|
16
17
|
scheme_filepaths.each do |scheme_filepath|
|
17
18
|
xcscheme = Xcodeproj::XCScheme.new(scheme_filepath)
|
18
|
-
xcscheme.test_action.
|
19
|
-
|
20
|
-
|
19
|
+
testplans = xcscheme.test_action.test_plans
|
20
|
+
unless testplans.nil?
|
21
|
+
UI.important("Error: unable to read suppressed tests from Xcode Scheme #{File.basename(scheme_filepath)}.")
|
22
|
+
UI.message("The scheme is using a testplan which does not list skipped tests.")
|
23
|
+
else
|
24
|
+
xcscheme.test_action.testables.each do |testable|
|
25
|
+
buildable_name = testable.buildable_references[0]
|
26
|
+
.buildable_name
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
28
|
+
buildable_name = File.basename(buildable_name, '.xctest')
|
29
|
+
testable.skipped_tests.map do |skipped_test|
|
30
|
+
skipped_tests.add("#{buildable_name}/#{skipped_test.identifier}")
|
31
|
+
end
|
25
32
|
end
|
26
33
|
end
|
27
34
|
end
|
@@ -11,10 +11,26 @@ module Fastlane
|
|
11
11
|
def self.xctestrun_tests(xctestrun_path, invocation_based_tests)
|
12
12
|
xctestrun = Plist.parse_xml(xctestrun_path)
|
13
13
|
xctestrun_rootpath = File.dirname(xctestrun_path)
|
14
|
-
|
15
|
-
xctestrun.each do |testable_name, xctestrun_config|
|
16
|
-
next if ignoredTestables.include? testable_name
|
14
|
+
xctestrun_version = xctestrun.fetch('__xctestrun_metadata__', Hash.new).fetch('FormatVersion', 1)
|
17
15
|
|
16
|
+
test_targets = []
|
17
|
+
if xctestrun_version == 1
|
18
|
+
xctestrun.each do |testable_name, test_target_config|
|
19
|
+
next if ignoredTestables.include? testable_name
|
20
|
+
test_targets << test_target_config
|
21
|
+
end
|
22
|
+
else
|
23
|
+
test_configurations = xctestrun['TestConfigurations']
|
24
|
+
test_configurations.each do |configuration|
|
25
|
+
configuration['TestTargets'].each do |test_target|
|
26
|
+
test_targets << test_target
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
tests = Hash.new([])
|
32
|
+
test_targets.each do |xctestrun_config|
|
33
|
+
testable_name = xctestrun_config['ProductModuleName']
|
18
34
|
xctest_path = xctest_bundle_path(xctestrun_rootpath, xctestrun_config)
|
19
35
|
test_identifiers = []
|
20
36
|
if xctestrun_config.key?('OnlyTestIdentifiers')
|
@@ -17,11 +17,18 @@ module TestCenter
|
|
17
17
|
end
|
18
18
|
# :nocov:
|
19
19
|
|
20
|
-
def
|
20
|
+
def prepare_scan_config
|
21
21
|
# this allows multi_scan's `destination` option to be picked up by `scan`
|
22
22
|
scan_config._values.delete(:device)
|
23
|
+
ENV.delete('SCAN_DEVICE')
|
23
24
|
scan_config._values.delete(:devices)
|
24
|
-
|
25
|
+
ENV.delete('SCAN_DEVICES')
|
26
|
+
# this prevents double -resultBundlePath args to xcodebuild
|
27
|
+
if ReportNameHelper.includes_xcresult?(@options[:output_types])
|
28
|
+
scan_config._values.delete(:result_bundle)
|
29
|
+
ENV.delete('SCAN_RESULT_BUNDLE')
|
30
|
+
end
|
31
|
+
scan_config._values.delete(:skip_testing)
|
25
32
|
scan_cache.clear
|
26
33
|
end
|
27
34
|
|
@@ -30,12 +37,13 @@ module TestCenter
|
|
30
37
|
scan_options = @options.select { |k,v| valid_scan_keys.include?(k) }
|
31
38
|
.merge(@retrying_scan_helper.scan_options)
|
32
39
|
|
33
|
-
|
40
|
+
prepare_scan_config
|
34
41
|
scan_options[:build_for_testing] = false
|
42
|
+
scan_options.delete(:skip_testing)
|
35
43
|
FastlaneCore::UI.verbose("retrying_scan #update_scan_options")
|
36
44
|
scan_options.each do |k,v|
|
37
45
|
next if v.nil?
|
38
|
-
|
46
|
+
|
39
47
|
scan_config.set(k,v) unless v.nil?
|
40
48
|
FastlaneCore::UI.verbose("\tSetting #{k.to_s} to #{v}")
|
41
49
|
end
|
@@ -52,7 +60,7 @@ module TestCenter
|
|
52
60
|
begin
|
53
61
|
@retrying_scan_helper.before_testrun
|
54
62
|
update_scan_options
|
55
|
-
|
63
|
+
|
56
64
|
values = scan_config.values(ask: false)
|
57
65
|
values[:xcode_path] = File.expand_path("../..", FastlaneCore::Helper.xcode_path)
|
58
66
|
ScanHelper.print_scan_parameters(values)
|
@@ -88,11 +88,16 @@ module TestCenter
|
|
88
88
|
|
89
89
|
def scan_options
|
90
90
|
valid_scan_keys = Fastlane::Actions::ScanAction.available_options.map(&:key)
|
91
|
-
xcargs = @options[:xcargs]
|
91
|
+
xcargs = @options[:xcargs] || ''
|
92
92
|
if xcargs&.include?('build-for-testing')
|
93
93
|
FastlaneCore::UI.important(":xcargs, #{xcargs}, contained 'build-for-testing', removing it")
|
94
94
|
xcargs.slice!('build-for-testing')
|
95
95
|
end
|
96
|
+
if xcargs.include?('-quiet')
|
97
|
+
FastlaneCore::UI.important('Disabling -quiet as failing tests cannot be found with it enabled.')
|
98
|
+
xcargs.gsub!('-quiet', '')
|
99
|
+
end
|
100
|
+
xcargs.gsub!(/-parallel-testing-enabled(=|\s+)(YES|NO)/, '')
|
96
101
|
retrying_scan_options = @reportnamer.scan_options.merge(
|
97
102
|
{
|
98
103
|
output_directory: output_directory,
|
@@ -125,7 +130,11 @@ module TestCenter
|
|
125
130
|
after_testrun_message << " for batch ##{@options[:batch]}" unless @options[:batch].nil?
|
126
131
|
FastlaneCore::UI.verbose(after_testrun_message)
|
127
132
|
|
128
|
-
|
133
|
+
if @options[:retry_test_runner_failures]
|
134
|
+
continue_with_build_failure(exception)
|
135
|
+
else
|
136
|
+
handle_build_failure(exception)
|
137
|
+
end
|
129
138
|
else
|
130
139
|
after_testrun_message = "Scan passed the tests"
|
131
140
|
after_testrun_message << " for batch ##{@options[:batch]}" unless @options[:batch].nil?
|
@@ -240,12 +249,27 @@ module TestCenter
|
|
240
249
|
junit: File.absolute_path(report_filepath)
|
241
250
|
}
|
242
251
|
)
|
243
|
-
@options[:only_testing] = Fastlane::Actions::TestsFromJunitAction.run(config)
|
252
|
+
@options[:only_testing] = (@options[:only_testing] || []) - Fastlane::Actions::TestsFromJunitAction.run(config).fetch(:passing, Hash.new).map(&:shellsafe_testidentifier)
|
244
253
|
if @options[:invocation_based_tests]
|
245
254
|
@options[:only_testing] = @options[:only_testing].map(&:strip_testcase).uniq
|
246
255
|
end
|
247
256
|
end
|
248
257
|
|
258
|
+
def continue_with_build_failure(exception)
|
259
|
+
test_session_last_messages = last_lines_of_test_session_log
|
260
|
+
failure = retrieve_test_operation_failure(test_session_last_messages)
|
261
|
+
case failure
|
262
|
+
when /Lost connection to testmanagerd/
|
263
|
+
FastlaneCore::UI.important("com.apple.CoreSimulator.CoreSimulatorService may have become corrupt, consider quitting it")
|
264
|
+
if @options[:quit_core_simulator_service]
|
265
|
+
Fastlane::Actions::RestartCoreSimulatorServiceAction.run
|
266
|
+
end
|
267
|
+
else
|
268
|
+
FastlaneCore::UI.important(test_session_last_messages)
|
269
|
+
end
|
270
|
+
send_callback_testrun_info(test_operation_failure: failure)
|
271
|
+
end
|
272
|
+
|
249
273
|
def handle_build_failure(exception)
|
250
274
|
test_session_last_messages = last_lines_of_test_session_log
|
251
275
|
failure = retrieve_test_operation_failure(test_session_last_messages)
|
@@ -262,11 +286,31 @@ module TestCenter
|
|
262
286
|
FastlaneCore::UI.error(test_session_last_messages)
|
263
287
|
send_callback_testrun_info(test_operation_failure: failure)
|
264
288
|
raise exception
|
289
|
+
FastlaneCore::UI.important(test_session_last_messages)
|
265
290
|
end
|
266
291
|
send_callback_testrun_info(test_operation_failure: failure)
|
267
292
|
end
|
268
293
|
|
269
294
|
def retrieve_test_operation_failure(test_session_last_messages)
|
295
|
+
if FastlaneCore::Helper.xcode_at_least?(11)
|
296
|
+
retrieve_test_operation_failure_post_xcode11(test_session_last_messages)
|
297
|
+
else
|
298
|
+
retrieve_test_operation_failure_pre_xcode11(test_session_last_messages)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def retrieve_test_operation_failure_post_xcode11(test_session_last_messages)
|
303
|
+
if /Connection peer refused channel request/ =~ test_session_last_messages
|
304
|
+
test_operation_failure = 'Lost connection to testmanagerd'
|
305
|
+
elsif /Please unlock your device and reattach/ =~ test_session_last_messages
|
306
|
+
test_operation_failure = 'Test device locked'
|
307
|
+
elsif /Test runner exited before starting test execution/ =~ test_session_last_messages
|
308
|
+
test_operation_failure = 'Test runner exited before starting test execution'
|
309
|
+
end
|
310
|
+
test_operation_failure
|
311
|
+
end
|
312
|
+
|
313
|
+
def retrieve_test_operation_failure_pre_xcode11(test_session_last_messages)
|
270
314
|
test_operation_failure_match = /Test operation failure: (?<test_operation_failure>.*)$/ =~ test_session_last_messages
|
271
315
|
if test_operation_failure_match.nil?
|
272
316
|
test_operation_failure = 'Unknown test operation failure'
|
@@ -7,7 +7,7 @@ module TestCenter
|
|
7
7
|
require 'json'
|
8
8
|
require 'shellwords'
|
9
9
|
require 'snapshot/reset_simulators'
|
10
|
-
|
10
|
+
|
11
11
|
class Runner
|
12
12
|
attr_reader :retry_total_count
|
13
13
|
|
@@ -66,12 +66,12 @@ module TestCenter
|
|
66
66
|
end
|
67
67
|
|
68
68
|
unless tests_passed || @options[:try_count] < 1
|
69
|
-
setup_testcollector
|
69
|
+
setup_testcollector
|
70
70
|
tests_passed = run_test_batches
|
71
71
|
end
|
72
72
|
tests_passed
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
def should_run_tests_through_single_try?
|
76
76
|
should_run_for_invocation_tests = @options[:invocation_based_tests] && @options[:only_testing].nil?
|
77
77
|
should_run_for_skip_build = @options[:skip_build]
|
@@ -114,16 +114,16 @@ module TestCenter
|
|
114
114
|
end
|
115
115
|
@options[:output_directory] = output_directory
|
116
116
|
@options[:destination] = Scan.config[:destination]
|
117
|
-
|
117
|
+
|
118
118
|
# We do not want Scan.config to _not_ have :device :devices, we want to
|
119
119
|
# use :destination. We remove :force_quit_simulator as we do not want
|
120
120
|
# Scan to handle it as multi_scan takes care of it in its own way
|
121
121
|
options = @options.reject { |key| %i[device devices force_quit_simulator].include?(key) }
|
122
122
|
options[:try_count] = 1
|
123
|
-
|
123
|
+
|
124
124
|
tests_passed = RetryingScan.run(options)
|
125
125
|
@options[:try_count] -= 1
|
126
|
-
|
126
|
+
|
127
127
|
reportnamer = ReportNameHelper.new(
|
128
128
|
@options[:output_types],
|
129
129
|
@options[:output_files],
|
@@ -138,12 +138,12 @@ module TestCenter
|
|
138
138
|
)
|
139
139
|
@options[:only_testing] = retrieve_failed_single_try_tests
|
140
140
|
@options[:only_testing] = @options[:only_testing].map(&:strip_testcase).uniq
|
141
|
-
|
141
|
+
|
142
142
|
symlink_result_bundle_to_xcresult(output_directory, reportnamer)
|
143
143
|
|
144
144
|
tests_passed
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
def retrieve_failed_single_try_tests
|
148
148
|
reportnamer = ReportNameHelper.new(
|
149
149
|
@options[:output_types],
|
@@ -168,10 +168,10 @@ module TestCenter
|
|
168
168
|
|
169
169
|
pool = TestBatchWorkerPool.new(pool_options)
|
170
170
|
pool.setup_workers
|
171
|
-
|
171
|
+
|
172
172
|
remaining_test_batches = @test_collector.test_batches.clone
|
173
173
|
remaining_test_batches.each_with_index do |test_batch, current_batch_index|
|
174
|
-
worker = pool.wait_for_worker
|
174
|
+
worker = pool.wait_for_worker
|
175
175
|
FastlaneCore::UI.message("Starting test run #{current_batch_index + 1}")
|
176
176
|
worker.run(scan_options_for_worker(test_batch, current_batch_index))
|
177
177
|
end
|
@@ -189,7 +189,7 @@ module TestCenter
|
|
189
189
|
batch: batch_index + 1
|
190
190
|
}
|
191
191
|
end
|
192
|
-
|
192
|
+
|
193
193
|
def collate_batched_reports
|
194
194
|
return unless @batch_count > 1
|
195
195
|
return unless @options[:collate_reports]
|
@@ -207,10 +207,44 @@ module TestCenter
|
|
207
207
|
File.absolute_path(output_directory),
|
208
208
|
@test_collector.testables.first
|
209
209
|
)
|
210
|
+
merge_single_testable_xcresult_with_final_xcresult(report_files_dir, File.absolute_path(output_directory))
|
210
211
|
FileUtils.cp_r("#{report_files_dir}/.", File.absolute_path(output_directory))
|
211
212
|
FileUtils.rm_rf(report_files_dir)
|
212
213
|
end
|
213
214
|
|
215
|
+
def merge_single_testable_xcresult_with_final_xcresult(testable_output_dir, final_output_dir)
|
216
|
+
reportnamer = ReportNameHelper.new(
|
217
|
+
@options[:output_types],
|
218
|
+
@options[:output_files],
|
219
|
+
@options[:custom_report_file_name]
|
220
|
+
)
|
221
|
+
return unless reportnamer.includes_xcresult?
|
222
|
+
|
223
|
+
xcresult_bundlename = reportnamer.xcresult_bundlename
|
224
|
+
src_xcresult_bundlepath = File.join(testable_output_dir, xcresult_bundlename)
|
225
|
+
dst_xcresult_bundlepath = File.join(final_output_dir, xcresult_bundlename)
|
226
|
+
|
227
|
+
# We do not need to merge if one of these do not exist
|
228
|
+
return unless File.exist?(src_xcresult_bundlepath) || File.exist?(dst_xcresult_bundlepath)
|
229
|
+
|
230
|
+
config = FastlaneCore::Configuration.create(
|
231
|
+
Fastlane::Actions::CollateXcresultsAction.available_options,
|
232
|
+
{
|
233
|
+
xcresults: [src_xcresult_bundlepath, dst_xcresult_bundlepath],
|
234
|
+
collated_xcresult: dst_xcresult_bundlepath
|
235
|
+
}
|
236
|
+
)
|
237
|
+
FastlaneCore::UI.verbose("Merging xcresult '#{src_xcresult_bundlepath}' to '#{dst_xcresult_bundlepath}'")
|
238
|
+
Fastlane::Actions::CollateXcresultsAction.run(config)
|
239
|
+
FileUtils.rm_rf(src_xcresult_bundlepath)
|
240
|
+
if @result_bundle_desired
|
241
|
+
xcresult_bundlename = reportnamer.xcresult_bundlename
|
242
|
+
test_result_bundlename = File.basename(xcresult_bundlename, '.*') + '.test_result'
|
243
|
+
test_result_bundlename_path = File.join(testable_output_dir, test_result_bundlename)
|
244
|
+
FileUtils.rm_rf(test_result_bundlename_path)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
214
248
|
def symlink_result_bundle_to_xcresult(output_dir, reportname_helper)
|
215
249
|
return unless @result_bundle_desired && reportname_helper.includes_xcresult?
|
216
250
|
|
@@ -16,11 +16,22 @@ module TestCenter
|
|
16
16
|
cloned_simulators = []
|
17
17
|
|
18
18
|
run_count = @options[:parallel_testrun_count] || 0
|
19
|
-
destination_simulator_ids = Scan.config[:destination].map do |destination|
|
20
|
-
destination.split(',id=').last
|
21
|
-
end
|
22
19
|
original_simulators = FastlaneCore::DeviceManager.simulators('iOS').find_all do |simulator|
|
23
|
-
|
20
|
+
found_match = false
|
21
|
+
Scan.config[:destination].each do |destination|
|
22
|
+
match = destination.match(/id=(?<udid>[^,]+)/)
|
23
|
+
if match
|
24
|
+
found_match = (match[:udid] == simulator.udid)
|
25
|
+
else
|
26
|
+
match = destination.match(/name=(?<name>[^,]+)/)
|
27
|
+
name = match[:name] || ''
|
28
|
+
match = destination.match(/OS=(?<os_version>[^,]+)/)
|
29
|
+
os_version = match[:os_version] || ''
|
30
|
+
|
31
|
+
found_match = (name == simulator.name && os_version == simulator.os_version)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
found_match
|
24
35
|
end
|
25
36
|
original_simulators.each(&:shutdown)
|
26
37
|
(0...run_count).each do |batch_index|
|
@@ -42,9 +42,7 @@ module TestCenter
|
|
42
42
|
if @only_testing
|
43
43
|
@testables ||= only_testing_to_testables_tests.keys
|
44
44
|
else
|
45
|
-
@testables
|
46
|
-
key == '__xctestrun_metadata__'
|
47
|
-
end
|
45
|
+
@testables = xctestrun_known_tests.keys
|
48
46
|
end
|
49
47
|
end
|
50
48
|
@testables
|
@@ -80,7 +78,7 @@ module TestCenter
|
|
80
78
|
known_tests += xctestrun_known_tests[testable]
|
81
79
|
test_components = test.split('/')
|
82
80
|
testsuite = test_components.size == 1 ? test_components[0] : test_components[1]
|
83
|
-
@testables_tests[testable][index] = known_tests.select { |known_test| known_test.include?(testsuite) }
|
81
|
+
@testables_tests[testable][index] = known_tests.select { |known_test| known_test.include?(testsuite) }
|
84
82
|
end
|
85
83
|
end
|
86
84
|
@testables_tests[testable].flatten!
|
@@ -106,7 +104,7 @@ module TestCenter
|
|
106
104
|
end
|
107
105
|
end
|
108
106
|
end
|
109
|
-
|
107
|
+
|
110
108
|
@testables_tests
|
111
109
|
end
|
112
110
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Xcodeproj
|
2
|
+
class XCScheme
|
3
|
+
class TestAction < AbstractSchemeAction
|
4
|
+
def test_plans
|
5
|
+
return [] unless @xml_element.elements['TestPlans']
|
6
|
+
|
7
|
+
@xml_element.elements['TestPlans'].get_elements('TestPlanReference').map do |node|
|
8
|
+
TestPlanReference.new(node)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class TestPlanReference < XMLElementWrapper
|
14
|
+
def initialize(node)
|
15
|
+
create_xml_element_with_fallback(node, 'TestPlanReference') do
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def target_referenced_container
|
20
|
+
@xml_element.attributes['reference']
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
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.
|
4
|
+
version: 3.10.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lyndsey Ferguson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -285,6 +285,7 @@ files:
|
|
285
285
|
- lib/fastlane/plugin/test_center/helper/scan_helper.rb
|
286
286
|
- lib/fastlane/plugin/test_center/helper/test_collector.rb
|
287
287
|
- lib/fastlane/plugin/test_center/helper/xcodebuild_string.rb
|
288
|
+
- lib/fastlane/plugin/test_center/helper/xcodeproj/scheme/test_action.rb
|
288
289
|
- lib/fastlane/plugin/test_center/helper/xctestrun_info.rb
|
289
290
|
- lib/fastlane/plugin/test_center/version.rb
|
290
291
|
homepage: https://github.com/lyndsey-ferguson/fastlane-plugin-test_center
|