diff --git a/lib/xcresult/export_options.rb b/lib/xcresult/export_options.rb index f27a23d..329b5ae 100644 --- a/lib/xcresult/export_options.rb +++ b/lib/xcresult/export_options.rb @@ -1,7 +1,17 @@ module XCResult class ExportOptions - AVAILABLE_OPTIONS = %i[destination by_device by_locale].freeze + AVAILABLE_OPTIONS = %i[destination by_device by_locale by_region by_language by_os_version by_test_name].freeze + # A initializer of ExportOptions class. The order of options that are prefixed with `by_` is important. + # `XCResult::Parser#export_screenshots` will create nested directories by the order you give. + # + # @option [String] destination The base directory path of exported items + # @option [Boolean] by_device If true, a nested directory under destination will be made based on device model name + # @option [Boolean] by_locale If true, a nested directory under destination will be made based on locale; i.e. "en_US" + # @option [Boolean] by_region If true, a nested directory under destination will be made based on region + # @option [Boolean] by_language If true, a nested directory under destination will be made based on language + # @option [Boolean] by_os_version If true, a nested directory under destination will be made based on OS version + # @option [Boolean] by_test_name If true, a nested directory under destination will be made based on test name in TestPlan def initialize(**options) raise ':destination option is required' unless options[:destination] @@ -13,17 +23,26 @@ def initialize(**options) @destination = options.delete(:destination) end - def output_directory(target_device_record:, action_testable_summary:) + def output_directory(target_device_record:, action_test_plan_summary:, action_testable_summary:) output_directory = @destination # keep the order of given options so that you can customize output directory path based on your needs - @options.each do |key, value| - if key == :by_device && value == true + @options.select { |key, value| key.to_s.start_with?('by_') && value == true }.each do |key, _| + case key + when :by_device output_directory = File.join(output_directory, target_device_record.model_name) - elsif key == :by_locale && value == true + when :by_language + output_directory = File.join(output_directory, action_testable_summary.test_language) + when :by_region + output_directory = File.join(output_directory, action_testable_summary.test_region) + when :by_locale locale = [action_testable_summary.test_language, action_testable_summary.test_region].compact.join('_') locale = 'UNKOWN' if locale.empty? output_directory = File.join(output_directory, locale) + when :by_os_version + output_directory = File.join(output_directory, target_device_record.operating_system_version) + when :by_test_name + output_directory = File.join(output_directory, action_test_plan_summary.name) end end diff --git a/lib/xcresult/parser.rb b/lib/xcresult/parser.rb index 674cd45..8ddb686 100644 --- a/lib/xcresult/parser.rb +++ b/lib/xcresult/parser.rb @@ -78,30 +78,34 @@ def export_screenshots(options = XCResult::ExportOptions.new(destination: Dir.pw # Iterate through each action as it represents run destination (testing device) actions.each do |action| action_test_plan_run_summaries = action.action_result.tests_ref.load_object(from: path) - action_testable_summaries = action_test_plan_run_summaries.summaries.flat_map(&:testable_summaries) - - # Iterate thorugh each action_testable_summary as it represents testing conditions such as region and language - action_testable_summaries.each do |action_testable_summary| - # Collect all attachments from a testing condition - attachments = action_testable_summary.all_tests - .map(&:summary_ref) - .map { |ref| ref.load_object(from: path) } - .flat_map(&:activity_summaries) - .flat_map(&:subactivities) - .flat_map(&:attachments) - - # Prepare output directory for each tests - output_directory = options.output_directory( - target_device_record: action.run_destination.target_device_record, - action_testable_summary: action_testable_summary - ) - FileUtils.mkdir_p(output_directory) unless Dir.exist?(output_directory) - - # Finally exports attachments - attachments.each do |attachment| - output_path = File.join(output_directory, attachment.filename) - cmd = "xcrun xcresulttool export --path #{path} --id '#{attachment.payload_ref.id}' --output-path '#{output_path}' --type file" - execute_cmd(cmd) + action_test_plan_summaries = action_test_plan_run_summaries.summaries + + # Iterate thorugh each action_test_plan_summaries as it represents test name + action_test_plan_summaries.each do |action_test_plan_summary| + # Iterate thorugh each action_testable_summary as it represents testing conditions such as region and language + action_test_plan_summary.testable_summaries.each do |action_testable_summary| + # Collect all attachments from a testing condition + attachments = action_testable_summary.all_tests + .map(&:summary_ref) + .map { |ref| ref.load_object(from: path) } + .flat_map(&:activity_summaries) + .flat_map(&:subactivities) + .flat_map(&:attachments) + + # Prepare output directory for each tests + output_directory = options.output_directory( + target_device_record: action.run_destination.target_device_record, + action_test_plan_summary: action_test_plan_summary, + action_testable_summary: action_testable_summary + ) + FileUtils.mkdir_p(output_directory) unless Dir.exist?(output_directory) + + # Finally exports attachments + attachments.each do |attachment| + output_path = File.join(output_directory, attachment.filename) + cmd = "xcrun xcresulttool export --path #{path} --id '#{attachment.payload_ref.id}' --output-path '#{output_path}' --type file" + execute_cmd(cmd) + end end end end