fastlane-plugin-test_center 3.10.3 → 3.11.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '098e845a533aae1482f49c2265234f95e6b6415a6f389fca3956851f009841da'
4
- data.tar.gz: 612fa05cd1d3c550ed344ecc34f9f7a54a4d50a701711e33c7154f496d05104e
3
+ metadata.gz: cad9b8dc9f0a32d294ac1d2a854ed5245992ef5b42ab354387c8b3dba6c5571a
4
+ data.tar.gz: 6112ba8a64cf378c96c5997be419f13b57a75c156f5781b9f1d755a09d8559c1
5
5
  SHA512:
6
- metadata.gz: cd691d0fd30fc8a3a06d082f9a751a7101c1de6843819136d1fb18b66051435412bf8fe41606012ce65552096337a844ea1536896394b9ce6d679b3e80f00014
7
- data.tar.gz: 25354716d6138969a45954a0f77429be98ea188e1a8fb9c4bda0b92300ea1d85df128526b65c4ef9e76575561f1aeddcb9c7fd9a9dd1133a6dbed3031af9dd21
6
+ metadata.gz: d158818861f01c4e1d59f2625dbc40cb73df7327566f5ad933eab199530217e5bd2f97a7684e21e9fd29e0df18ad9f8c6ac0648b5d8619d81c913d2eb8427dde
7
+ data.tar.gz: 8b70dfc5f9e97937177edccbc708c3ac13a1b74be9b5035dab31fbd76cb195ad86c8ddc62a1b3efcacb052dc0d4a7fe010514d4ed48c5e8b1217189ce5f1ba21
data/README.md CHANGED
@@ -21,7 +21,7 @@ Have you ever spent too much time trying to fix fragile tests only to give up wi
21
21
 
22
22
  ## Features
23
23
 
24
- This plugin makes testing your iOS app easier by providing you actions that give you greater control over everything related to testing your app.
24
+ This plugin makes testing your iOS app easier by providing you actions that give you greater control over everything related to testing your app.
25
25
 
26
26
  `multi_scan` began when I created an action to only re-run the failed tests in order to determine if they were truly failing, or if they were failing randomly due to a fragile infrastructure. This action morphed into an entire plugin with many actions in the testing category.
27
27
 
@@ -35,6 +35,8 @@ _read the documentation on each action by clicking on the action name_
35
35
  | [`suppress_tests_from_junit`](docs/feature_details/suppress_tests_from_junit.md) | suppress tests in an Xcode Scheme using those in a Junit test report | ios, mac |
36
36
  | [`suppress_tests`](docs/feature_details/suppress_tests.md) | suppress tests in an Xcode Scheme | ios, mac |
37
37
  | [`suppressed_tests`](docs/feature_details/suppressed_tests.md) | returns a list of the suppressed tests in your Xcode Project or Scheme | ios, mac |
38
+ | [`test_options_from_testplan`](docs/feature_details/test_options_from_testplan.md) | returns the tests and test code coverage configuration for a given testplan | ios, mac |
39
+ | [`testplans_from_scheme`](docs/feature_details/testplans_from_scheme.md) | returns the testplans that an Xcode Scheme references | ios, mac |
38
40
  | [`tests_from_junit`](docs/feature_details/tests_from_junit.md) | returns the passing and failing tests in a Junit test report | ios, mac |
39
41
  | [`tests_from_xctestrun`](docs/feature_details/tests_from_xctestrun.md) | returns a list of tests for each test target in a `xctestrun` file | ios, mac |
40
42
  | [`collate_junit_reports`](docs/feature_details/collate_junit_reports.md) | combines multiple Junit test reports into one report | ios, mac |
@@ -62,7 +64,7 @@ The most popular action in the `test_center` plugin is `multi_scan`, and if you
62
64
  multi_scan(
63
65
  project: File.absolute_path('../AtomicBoy/AtomicBoy.xcodeproj'),
64
66
  scheme: 'AtomicBoy',
65
- try_count: 3, # retry _failing_ tests up to three times^1.
67
+ try_count: 3, # retry _failing_ tests up to three times^1.
66
68
  fail_build: false,
67
69
  parallel_testrun_count: 4 # run subsets of your tests on parallel simulators^2
68
70
  )
@@ -91,9 +93,10 @@ For more information about how the `fastlane` plugin system works, check out the
91
93
 
92
94
  _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
95
 
94
- ## Supporter
96
+ ## Supporters
95
97
 
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.
98
+ ![Владислав Давыдов](https://avatars1.githubusercontent.com/u/47553334?s=44&u=4691860dba898943b947180b3d28bb85851b0d7c&v=4)
99
+ [vdavydovHH](https://github.com/vdavydovHH)
97
100
 
98
101
  ## License
99
102
 
@@ -232,7 +232,7 @@ module Fastlane
232
232
  end
233
233
 
234
234
  def self.prepare_scan_options_for_build_for_testing(scan_options)
235
- build_options = scan_options.merge(build_for_testing: true).reject { |k| k == :test_without_building }
235
+ build_options = scan_options.merge(build_for_testing: true).reject { |k| %i[test_without_building, testplan, include_simulator_logs].include?(k) }
236
236
  Scan.config = FastlaneCore::Configuration.create(
237
237
  Fastlane::Actions::ScanAction.available_options,
238
238
  ScanHelper.scan_options_from_multi_scan_options(build_options)
@@ -244,7 +244,11 @@ module Fastlane
244
244
  end
245
245
 
246
246
  def self.update_xctestrun_after_build(scan_options)
247
- xctestrun_files = Dir.glob("#{Scan.config[:derived_data_path]}/Build/Products/*.xctestrun")
247
+ glob_pattern = "#{Scan.config[:derived_data_path]}/Build/Products/*.xctestrun"
248
+ if scan_options[:testplan]
249
+ glob_pattern = "#{Scan.config[:derived_data_path]}/Build/Products/*_#{scan_options[:testplan]}_*.xctestrun"
250
+ end
251
+ xctestrun_files = Dir.glob(glob_pattern)
248
252
  UI.verbose("After building, found xctestrun files #{xctestrun_files} (choosing 1st)")
249
253
  scan_options[:xctestrun] = xctestrun_files.first
250
254
  end
@@ -0,0 +1,91 @@
1
+ require 'json'
2
+
3
+ module Fastlane
4
+ module Actions
5
+ class TestOptionsFromTestplanAction < Action
6
+ def self.run(params)
7
+ testplan_path = params[:testplan]
8
+
9
+ testplan = JSON.load(File.open(testplan_path))
10
+ only_testing = []
11
+ UI.verbose("Examining testplan JSON: #{testplan}")
12
+ testplan['testTargets'].each do |test_target|
13
+ testable = test_target.dig('target', 'name')
14
+ if test_target.key?('selectedTests')
15
+ UI.verbose(" Found selectedTests")
16
+ test_identifiers = test_target['selectedTests'].each do |selected_test|
17
+ selected_test.delete!('()')
18
+ UI.verbose(" Found test: '#{selected_test}'")
19
+ only_testing << "#{testable}/#{selected_test.sub('\/', '/')}"
20
+ end
21
+ else
22
+ UI.verbose(" No selected tests, using testable '#{testable}'")
23
+ only_testing << testable
24
+ end
25
+ end
26
+ {
27
+ code_coverage: testplan.dig('defaultOptions', 'codeCoverage'),
28
+ only_testing: only_testing
29
+ }
30
+ end
31
+
32
+ #####################################################
33
+ # @!group Documentation
34
+ #####################################################
35
+
36
+ def self.description
37
+ "☑️ Gets test info from a given test plan"
38
+ end
39
+
40
+ def self.details
41
+ "Gets tests info consisting of tests to run and whether or not code coverage is enabled"
42
+ end
43
+
44
+ def self.available_options
45
+ [
46
+ FastlaneCore::ConfigItem.new(
47
+ key: :testplan,
48
+ optional: true,
49
+ env_name: "FL_TEST_OPTIONS_FROM_TESTPLAN_TESTPLAN",
50
+ description: "The Xcode testplan to read the test info from",
51
+ verify_block: proc do |test_plan|
52
+ UI.user_error!("Error: Xcode Test Plan '#{test_plan}' is not valid!") if test_plan and test_plan.empty?
53
+ UI.user_error!("Error: Test Plan does not exist at path '#{test_plan}'") unless File.exist?(test_plan)
54
+ end
55
+ )
56
+ ]
57
+ end
58
+
59
+ def self.return_value
60
+ "Returns a Hash with keys :code_coverage and :only_testing for the given testplan"
61
+ end
62
+
63
+ def self.example_code
64
+ [
65
+ "
66
+ UI.important(
67
+ 'example: ' \\
68
+ 'get the tests and the test coverage configuration from a given testplan'
69
+ )
70
+ test_options = test_options_from_testplan(
71
+ testplan: 'AtomicBoy/AtomicBoy_2.xctestplan'
72
+ )
73
+ UI.message(\"The AtomicBoy_2 testplan has the following tests: \#{test_options[:only_testing]}\")
74
+ "
75
+ ]
76
+ end
77
+
78
+ def self.authors
79
+ ["lyndsey-ferguson/lyndseydf"]
80
+ end
81
+
82
+ def self.category
83
+ :testing
84
+ end
85
+
86
+ def self.is_supported?(platform)
87
+ %i[ios mac].include?(platform)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,140 @@
1
+ module Fastlane
2
+ module Actions
3
+ class TestplansFromSchemeAction < Action
4
+ def self.run(params)
5
+ scheme_filepaths = schemes(params)
6
+ testplan_paths = []
7
+ scheme_filepaths.each do |scheme_filepath|
8
+ UI.verbose("Looking in Scheme '#{scheme_filepath}' for any testplans")
9
+ xcscheme = Xcodeproj::XCScheme.new(scheme_filepath)
10
+ next unless scheme_has_testplans?(xcscheme)
11
+ scheme_container_dir = File.absolute_path(scheme_filepath).sub(%r{/[^/]*\.(xcworkspace|xcodeproj)/.*}, '')
12
+ xcscheme.test_action.test_plans.each do |testplan|
13
+ testplan_path = File.absolute_path(File.join(scheme_container_dir, testplan.target_referenced_container.sub('container:', '')))
14
+ UI.verbose(" found testplan '#{testplan_path}'")
15
+ testplan_paths << testplan_path
16
+ end
17
+ end
18
+ testplan_paths
19
+ end
20
+
21
+ def self.scheme_has_testplans?(xcscheme)
22
+ return !(
23
+ xcscheme.test_action.nil? ||
24
+ xcscheme.test_action.testables.to_a.empty? ||
25
+ xcscheme.test_action.testables[0].buildable_references.to_a.empty? ||
26
+ xcscheme.test_action.test_plans.to_a.empty?
27
+ )
28
+ end
29
+
30
+ def self.schemes(params)
31
+ scheme = params[:scheme]
32
+ scheme_filepaths = schemes_from_project(params[:xcodeproj], scheme) || schemes_from_workspace(params[:workspace], scheme)
33
+ if scheme_filepaths.length.zero?
34
+ scheme_detail_message = ''
35
+ if scheme
36
+ scheme_detail_message = "named '#{scheme}' "
37
+ end
38
+ UI.user_error!("Error: cannot find any schemes #{scheme_detail_message}in the Xcode project") if params[:xcodeproj]
39
+ UI.user_error!("Error: cannot find any schemes #{scheme_detail_message}in the Xcode workspace") if params[:workspace]
40
+ end
41
+ scheme_filepaths
42
+ end
43
+
44
+ def self.schemes_from_project(project_path, scheme)
45
+ return nil unless project_path
46
+
47
+ Dir.glob("#{project_path}/{xcshareddata,xcuserdata}/**/xcschemes/#{scheme || '*'}.xcscheme")
48
+ end
49
+
50
+ def self.schemes_from_workspace(workspace_path, scheme)
51
+ return nil unless workspace_path
52
+
53
+ scheme_filepaths = []
54
+ scheme_filepaths.concat(schemes_from_project(workspace_path, scheme))
55
+ return scheme_filepaths unless scheme_filepaths.empty?
56
+
57
+ xcworkspace = Xcodeproj::Workspace.new_from_xcworkspace(workspace_path)
58
+ xcodeprojects = xcworkspace.file_references.select do |file_reference|
59
+ file_reference.path.end_with?('xcodeproj')
60
+ end
61
+
62
+ xcodeprojects.each do |file_reference|
63
+ next if file_reference.path.include?('Pods/Pods.xcodeproj')
64
+
65
+ project_path = file_reference.absolute_path(File.dirname(workspace_path))
66
+ scheme_filepaths.concat(schemes_from_project(project_path, scheme))
67
+ end
68
+ scheme_filepaths
69
+ end
70
+
71
+ def self.description
72
+ "☑️Gets all the testplans that a Scheme references"
73
+ end
74
+
75
+ def self.authors
76
+ ["lyndsey-ferguson/lyndseydf"]
77
+ end
78
+
79
+ def self.available_options
80
+ [
81
+ FastlaneCore::ConfigItem.new(
82
+ key: :xcodeproj,
83
+ env_name: "FL_TESTPLANS_FROM_SCHEME_XCODE_PROJECT",
84
+ optional: true,
85
+ description: "The file path to the Xcode project file that references the Scheme",
86
+ verify_block: proc do |path|
87
+ path = File.expand_path(path.to_s)
88
+ UI.user_error!("Error: Xcode project file path not given!") unless path and !path.empty?
89
+ UI.user_error!("Error: Xcode project '#{path}' not found!") unless Dir.exist?(path)
90
+ end
91
+ ),
92
+ FastlaneCore::ConfigItem.new(
93
+ key: :workspace,
94
+ env_name: "FL_TESTPLANS_FROM_SCHEME_XCODE_WORKSPACE",
95
+ optional: true,
96
+ description: "The file path to the Xcode workspace file that references the Scheme",
97
+ verify_block: proc do |value|
98
+ v = File.expand_path(value.to_s)
99
+ UI.user_error!("Error: Workspace file not found at path '#{v}'") unless Dir.exist?(v)
100
+ UI.user_error!("Error: Workspace file is not a workspace, must end with .xcworkspace") unless v.include?(".xcworkspace")
101
+ end
102
+ ),
103
+ FastlaneCore::ConfigItem.new(
104
+ key: :scheme,
105
+ optional: true,
106
+ env_name: "FL_TESTPLANS_FROM_SCHEME_XCODE_SCHEME",
107
+ description: "The Xcode scheme referencing the testplan",
108
+ verify_block: proc do |scheme_name|
109
+ UI.user_error!("Error: Xcode Scheme '#{scheme_name}' is not valid!") if scheme_name and scheme_name.empty?
110
+ end
111
+ )
112
+ ]
113
+ end
114
+
115
+ def self.example_code
116
+ [
117
+ "
118
+ UI.important(
119
+ 'example: ' \\
120
+ 'get all the testplans that an Xcode Scheme references'
121
+ )
122
+ testplans = testplans_from_scheme(
123
+ xcodeproj: 'AtomicBoy/AtomicBoy.xcodeproj',
124
+ scheme: 'AtomicBoy'
125
+ )
126
+ UI.message(\"The AtomicBoy uses the following testplans: \#{testplans}\")
127
+ "
128
+ ]
129
+ end
130
+
131
+ def self.category
132
+ :testing
133
+ end
134
+
135
+ def self.is_supported?(platform)
136
+ %i[ios mac].include?(platform)
137
+ end
138
+ end
139
+ end
140
+ end
@@ -1,3 +1,5 @@
1
+ require_relative 'reportname_helper'
2
+ require_relative 'test_collector'
1
3
  require_relative 'multi_scan_manager/device_manager'
2
4
  require_relative 'multi_scan_manager/report_collator'
3
5
  require_relative 'multi_scan_manager/retrying_scan_helper'
@@ -47,6 +47,11 @@ module TestCenter
47
47
  scan_config.set(k,v) unless v.nil?
48
48
  FastlaneCore::UI.verbose("\tSetting #{k.to_s} to #{v}")
49
49
  end
50
+ if @options[:scan_devices_override]
51
+ scan_device_names = @options[:scan_devices_override].map { |device| device.name }
52
+ FastlaneCore::UI.verbose("\tSetting Scan.devices to #{scan_device_names}")
53
+ Scan.devices.replace(@options[:scan_devices_override])
54
+ end
50
55
  end
51
56
 
52
57
  # :nocov:
@@ -45,7 +45,7 @@ module TestCenter
45
45
 
46
46
  derived_data_path = File.expand_path(@options[:derived_data_path] || Scan.config[:derived_data_path])
47
47
  xcresults = Dir.glob("#{derived_data_path}/Logs/Test/*.xcresult")
48
- if FastlaneCore::Helper.xcode_at_least?('11.0.0')
48
+ if FastlaneCore::Helper.xcode_at_least?('11')
49
49
  xcresults += Dir.glob("#{output_directory}/*.xcresult")
50
50
  end
51
51
  FastlaneCore::UI.verbose("Deleting xcresults:")
@@ -292,7 +292,7 @@ module TestCenter
292
292
  end
293
293
 
294
294
  def retrieve_test_operation_failure(test_session_last_messages)
295
- if FastlaneCore::Helper.xcode_at_least?(11)
295
+ if FastlaneCore::Helper.xcode_at_least?('11')
296
296
  retrieve_test_operation_failure_post_xcode11(test_session_last_messages)
297
297
  else
298
298
  retrieve_test_operation_failure_pre_xcode11(test_session_last_messages)
@@ -306,6 +306,8 @@ module TestCenter
306
306
  test_operation_failure = 'Test device locked'
307
307
  elsif /Test runner exited before starting test execution/ =~ test_session_last_messages
308
308
  test_operation_failure = 'Test runner exited before starting test execution'
309
+ else
310
+ test_operation_failure = 'Unknown test operation failure'
309
311
  end
310
312
  test_operation_failure
311
313
  end
@@ -335,8 +337,12 @@ module TestCenter
335
337
 
336
338
  glob_pattern = "#{output_directory}/system_logs-*.{log,logarchive}"
337
339
  logs = Dir.glob(glob_pattern)
340
+ batch_prefix = ''
341
+ if @options[:batch]
342
+ batch_prefix = "batch-#{@options[:batch]}-"
343
+ end
338
344
  logs.each do |log_filepath|
339
- new_logname = "try-#{testrun_count}-#{File.basename(log_filepath)}"
345
+ new_logname = "#{batch_prefix}try-#{testrun_count}-#{File.basename(log_filepath)}"
340
346
  new_log_filepath = "#{File.dirname(log_filepath)}/#{new_logname}"
341
347
  FastlaneCore::UI.verbose("Moving simulator log '#{log_filepath}' to '#{new_log_filepath}'")
342
348
  File.rename(log_filepath, new_log_filepath)
@@ -346,15 +352,17 @@ module TestCenter
346
352
  def move_test_result_bundle_for_next_run
347
353
  return unless @options[:result_bundle]
348
354
 
349
- glob_pattern = "#{output_directory}/*.test_result"
355
+ result_extension = FastlaneCore::Helper.xcode_at_least?('11') ? '.xcresult' : '.test_result'
356
+
357
+ glob_pattern = "#{output_directory}/*#{result_extension}"
350
358
  preexisting_test_result_bundles = Dir.glob(glob_pattern)
351
359
  unnumbered_test_result_bundles = preexisting_test_result_bundles.reject do |test_result|
352
- test_result =~ /.*-\d+\.test_result/
360
+ test_result =~ /.*-\d+\#{result_extension}/
353
361
  end
354
362
  src_test_bundle = unnumbered_test_result_bundles.first
355
363
  dst_test_bundle_parent_dir = File.dirname(src_test_bundle)
356
- dst_test_bundle_basename = File.basename(src_test_bundle, '.test_result')
357
- dst_test_bundle = "#{dst_test_bundle_parent_dir}/#{dst_test_bundle_basename}-#{@testrun_count}.test_result"
364
+ dst_test_bundle_basename = File.basename(src_test_bundle, result_extension)
365
+ dst_test_bundle = "#{dst_test_bundle_parent_dir}/#{dst_test_bundle_basename}-#{@testrun_count}#{result_extension}"
358
366
  FastlaneCore::UI.verbose("Moving test_result '#{src_test_bundle}' to '#{dst_test_bundle}'")
359
367
  File.rename(src_test_bundle, dst_test_bundle)
360
368
  end
@@ -1,4 +1,3 @@
1
-
2
1
  module TestCenter
3
2
  module Helper
4
3
  module MultiScanManager
@@ -40,7 +39,8 @@ module TestCenter
40
39
  return if @options[:invocation_based_tests] && @options[:only_testing].nil?
41
40
  return if @test_collector
42
41
 
43
- @test_collector = TestCenter::Helper::TestCollector.new(@options)
42
+ @test_collector = TestCollector.new(@options)
43
+ @options.reject! { |key| %i[testplan].include?(key) }
44
44
  @batch_count = @test_collector.test_batches.size
45
45
  end
46
46
 
@@ -224,8 +224,10 @@ module TestCenter
224
224
  src_xcresult_bundlepath = File.join(testable_output_dir, xcresult_bundlename)
225
225
  dst_xcresult_bundlepath = File.join(final_output_dir, xcresult_bundlename)
226
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)
227
+ # if there is no destination bundle to merge to, skip it as any source bundle will be copied when complete.
228
+ return if !File.exist?(dst_xcresult_bundlepath)
229
+ # if there is no source bundle to merge, skip it as there is nothing to merge.
230
+ return if !File.exist?(src_xcresult_bundlepath)
229
231
 
230
232
  config = FastlaneCore::Configuration.create(
231
233
  Fastlane::Actions::CollateXcresultsAction.available_options,
@@ -282,6 +284,9 @@ module TestCenter
282
284
  scheme: @options[:scheme],
283
285
  result_bundle: @options[:result_bundle]
284
286
  ).collate
287
+ logs_glog_pattern = "#{source_reports_directory_glob}/*system_logs-*.{log,logarchive}"
288
+ logs = Dir.glob(logs_glog_pattern)
289
+ FileUtils.mv(logs, absolute_output_directory)
285
290
  FileUtils.rm_rf(Dir.glob(source_reports_directory_glob))
286
291
  symlink_result_bundle_to_xcresult(absolute_output_directory, report_name_helper)
287
292
  true
@@ -12,34 +12,43 @@ module TestCenter
12
12
  end
13
13
  end
14
14
 
15
+ def simulator_matches_destination(simulator, destination)
16
+ match = destination.match(/id=(?<udid>[^,]+)/)
17
+ if match
18
+ found_match = (match[:udid] == simulator.udid)
19
+ else
20
+ match = destination.match(/name=(?<name>[^,]+)/)
21
+ name = match[:name] || ''
22
+ match = destination.match(/OS=(?<os_version>[^,]+)/)
23
+ os_version = match[:os_version] || ''
24
+
25
+ found_match = (name == simulator.name && os_version == simulator.os_version)
26
+ end
27
+ found_match
28
+ end
29
+
15
30
  def clone_destination_simulators
16
31
  cloned_simulators = []
17
32
 
18
33
  run_count = @options[:parallel_testrun_count] || 0
34
+ destinations = Scan.config[:destination].clone
19
35
  original_simulators = FastlaneCore::DeviceManager.simulators('iOS').find_all do |simulator|
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
36
+ found_simulator = destinations.find do |destination|
37
+ simulator_matches_destination(simulator, destination)
38
+ end
39
+ if found_simulator
40
+ destinations.delete(found_simulator)
33
41
  end
34
- found_match
42
+
43
+ !found_simulator.nil?
35
44
  end
36
45
  original_simulators.each(&:shutdown)
37
46
  (0...run_count).each do |batch_index|
38
47
  cloned_simulators << []
39
48
  original_simulators.each do |simulator|
40
- FastlaneCore::UI.verbose("Cloning simulator")
41
49
  cloned_simulator = simulator.clone
42
50
  new_first_name = simulator.name.sub(/( ?\(.*| ?$)/, " Clone #{batch_index + 1}")
51
+ FastlaneCore::UI.verbose("Cloned simulator #{simulator.name} to (name=#{new_first_name}, udid=#{cloned_simulator.udid}, OS=#{cloned_simulator.ios_version})")
43
52
  new_last_name = "#{self.class.name}<#{self.object_id}>"
44
53
  cloned_simulator.rename("#{new_first_name} #{new_last_name}")
45
54
 
@@ -46,6 +46,11 @@ module TestCenter
46
46
  end
47
47
  end
48
48
 
49
+ def simulator_devices_for_worker(worker_index)
50
+ return nil unless @options[:platform] == :ios_simulator
51
+ @clones[worker_index]
52
+ end
53
+
49
54
  def setup_parallel_workers
50
55
  setup_cloned_simulators
51
56
  desired_worker_count = @options[:parallel_testrun_count]
@@ -58,6 +63,7 @@ module TestCenter
58
63
  def parallel_scan_options(worker_index)
59
64
  options = @options.reject { |key| %i[device devices].include?(key) }
60
65
  options[:destination] = destination_for_worker(worker_index)
66
+ options[:scan_devices_override] = simulator_devices_for_worker(worker_index)
61
67
  options[:buildlog_path] = buildlog_path_for_worker(worker_index) if @options[:buildlog_path]
62
68
  options[:derived_data_path] = derived_data_path_for_worker(worker_index)
63
69
  options[:batch_index] = worker_index
@@ -15,7 +15,7 @@ module TestCenter
15
15
  unless @xctestrun_path && File.exist?(@xctestrun_path)
16
16
  FastlaneCore::UI.user_error!("Error: cannot find xctestrun file '#{@xctestrun_path}'")
17
17
  end
18
- @only_testing = options[:only_testing]
18
+ @only_testing = options[:only_testing] || only_testing_from_testplan(options)
19
19
  if @only_testing.kind_of?(String)
20
20
  @only_testing = @only_testing.split(',')
21
21
  end
@@ -27,6 +27,36 @@ module TestCenter
27
27
  end
28
28
  end
29
29
 
30
+ def only_testing_from_testplan(options)
31
+ return unless options[:testplan] && options[:scheme]
32
+
33
+ config = FastlaneCore::Configuration.create(
34
+ Fastlane::Actions::TestplansFromSchemeAction.available_options,
35
+ {
36
+ workspace: options[:workspace],
37
+ xcodeproj: options[:project],
38
+ scheme: options[:scheme]
39
+ }
40
+ )
41
+ testplans = Fastlane::Actions::TestplansFromSchemeAction.run(config)
42
+ FastlaneCore::UI.verbose("TestCollector found testplans: #{testplans}")
43
+ testplan = testplans.find do |testplan_path|
44
+ %r{(.*/?#{ options[:testplan] })\.xctestplan}.match?(testplan_path)
45
+ end
46
+ FastlaneCore::UI.verbose(" using :testplan option, #{options[:testplan]}, using found one: #{testplan}")
47
+
48
+ return if testplan.nil?
49
+
50
+ config = FastlaneCore::Configuration.create(
51
+ Fastlane::Actions::TestOptionsFromTestplanAction.available_options,
52
+ {
53
+ testplan: testplan
54
+ }
55
+ )
56
+ test_options = Fastlane::Actions::TestOptionsFromTestplanAction.run(config)
57
+ return test_options[:only_testing]
58
+ end
59
+
30
60
  def default_derived_data_path(options)
31
61
  project_derived_data_path = Scan.project.build_settings(key: "BUILT_PRODUCTS_DIR")
32
62
  File.expand_path("../../..", project_derived_data_path)
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TestCenter
3
- VERSION = "3.10.3"
3
+ VERSION = "3.11.4"
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.10.3
4
+ version: 3.11.4
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-06-06 00:00:00.000000000 Z
11
+ date: 2020-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -267,6 +267,8 @@ files:
267
267
  - lib/fastlane/plugin/test_center/actions/suppress_tests.rb
268
268
  - lib/fastlane/plugin/test_center/actions/suppress_tests_from_junit.rb
269
269
  - lib/fastlane/plugin/test_center/actions/suppressed_tests.rb
270
+ - lib/fastlane/plugin/test_center/actions/test_options_from_testplan.rb
271
+ - lib/fastlane/plugin/test_center/actions/testplans_from_scheme.rb
270
272
  - lib/fastlane/plugin/test_center/actions/tests_from_junit.rb
271
273
  - lib/fastlane/plugin/test_center/actions/tests_from_xctestrun.rb
272
274
  - lib/fastlane/plugin/test_center/helper/html_test_report.rb
@@ -307,7 +309,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
307
309
  - !ruby/object:Gem::Version
308
310
  version: '0'
309
311
  requirements: []
310
- rubygems_version: 3.0.6
312
+ rubygems_version: 3.0.3
311
313
  signing_key:
312
314
  specification_version: 4
313
315
  summary: Makes testing your iOS app easier