fastlane-plugin-test_center 3.10.3 → 3.11.4

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
  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