class Fastlane::Actions::CollateJunitReportsAction

Public Class Methods

authors() click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 175
def self.authors
  #Adapted from the "fastlane-plugin-test_center" plugin by:
  ["lyndsey-ferguson/@lyndseydf"]
end
available_options() click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 115
def self.available_options
  [
    FastlaneCore::ConfigItem.new(
      key: :scheme,
      env_name: 'SCHEME',
      description: 'The test scheme being run',
      optional: false,
      default_value: '',
      type: String
    ),
    FastlaneCore::ConfigItem.new(
      key: :reports,
      env_name: 'COLLATE_JUNIT_REPORTS_REPORTS',
      description: 'An array of junit reports to collate. The first report is used as the base into which other reports are merged in',
      optional: false,
      type: Array,
      verify_block: proc do |reports|
        UI.user_error!('No junit report files found') if reports.empty?
        reports.each do |report|
          UI.user_error!("Error: junit report not found: '#{report}'") unless File.exist?(report)
        end
      end
    ),
    FastlaneCore::ConfigItem.new(
      key: :collated_report,
      env_name: 'COLLATE_JUNIT_REPORTS_COLLATED_REPORT',
      description: 'The final junit report file where all testcases will be merged into',
      optional: true,
      default_value: 'result.xml',
      type: String
    ),
    FastlaneCore::ConfigItem.new(
      key: :assets,
      env_name: 'COLLATE_JUNIT_REPORTS_ASSETS',
      description: 'An array of junit reports to collate. The first report is used as the base into which other reports are merged in',
      optional: false,
      type: Array,
      verify_block: proc do |assets|
        UI.user_error!('No junit report files found') if assets.empty?
        assets.each do |asset|
          UI.user_error!("Error: junit report not found: '#{asset}'") unless File.exist?(asset)
        end
      end
    ),
    FastlaneCore::ConfigItem.new(
      key: :logs,
      env_name: 'COLLATE_JUNIT_REPORTS_LOGS',
      description: 'An array of junit reports to collate. The first report is used as the base into which other reports are merged in',
      optional: false,
      type: Array,
      verify_block: proc do |logs|
        UI.user_error!('No junit report files found') if logs.empty?
        logs.each do |log|
          UI.user_error!("Error: junit report not found: '#{log}'") unless File.exist?(log)
        end
      end
    )
  ]
end
clean_report(report) click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 50
def self.clean_report(report)
  report = report.inner_html
  report = report.gsub(/<(\w+): 0x(\w+)>/, '(\1: 0x\2)')
  report = report.gsub(/<XCAccessibilityElement:\/>0x(\w+)/, '(XCAccessibilityElement): 0x\1')
  report = Nokogiri::XML(report)
  report
end
copy_log(log_files, logs_folder) click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 66
def self.copy_log(log_files, logs_folder)
  target_log = log_files.shift
  FileUtils.cp_r(target_log, logs_folder)
end
description() click to toggle source

@!group Documentation

# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 99
def self.description
  "Combines and combines tests from multiple junit report files"
end
details() click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 103
def self.details
  "The first junit report is used as the base report. Testcases " \
  "from other reports are added if they do not already exist, or " \
  "if the testcases already exist, they are replaced." \
  "" \
  "This is done because it is assumed that fragile tests, when " \
  "re-run will often succeed due to less interference from other " \
  "tests and the subsequent junit reports will have more passed tests." \
  "" \
  "Inspired by Derek Yang's fastlane-plugin-merge_junit_report"
end
get_test_name(test_data) click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 89
def self.get_test_name(test_data)
  test_name = test_data.xpath("(//key[contains(.,'TestSummaryGUID')])/../key[contains(.,'TestName')]/following-sibling::string").to_a[0].to_s
  test_name = test_name[8..-10]
  test_name
end
is_supported?(platform) click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 180
def self.is_supported?(platform)
  platform == :ios
end
mergeLists(target_report, retry_report, params) click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 29
def self.mergeLists(target_report, retry_report, params)
  retry_report = clean_report(retry_report)
  Dir.mkdir(params[:collated_report]) unless File.exists?(params[:collated_report])
  file_name = params[:collated_report] + "/action_TestSummaries.plist"
  retried_tests = retry_report.xpath("//key[contains(.,'TestSummaryGUID')]/..")

  current_node = retried_tests.shift

  #Copy retried test results into the base report
  while (current_node != nil)
    testName = get_test_name(current_node)
    matching_node = target_report.at_xpath("//string[contains(.,'#{testName}')]/..")

    if (!matching_node.nil?)
      matching_node.previous.next.replace(current_node)
      write_report_to_file(target_report, file_name)
    end
    current_node = retried_tests.shift
  end
end
merge_assets(asset_files, assets_folder) click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 58
def self.merge_assets(asset_files, assets_folder)
  #copy screenshots from all retries into the results folder
  Dir.mkdir(assets_folder) unless File.exists?(assets_folder)
  asset_files.each do |folder|
    FileUtils.cp_r(Dir[folder + '/*'], assets_folder)
  end
end
merge_logs(log_files, logs_folder) click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 71
def self.merge_logs(log_files, logs_folder)
  UI.verbose("Merging console logs...")
  all = ""
  target_log = log_files.shift
  log_files.each do |log|
    all = all + log + " "
  end
  sh("cat #{all}> #{target_log}")
  FileUtils.cp_r(target_log, logs_folder)
end
run(params) click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 10
def self.run(params)
  report_filepaths = params[:reports]
  if report_filepaths.size == 1
    FileUtils.cp(report_filepaths[0], params[:collated_report])
  else
    #Convert .plist reports to Nokogiri XML objects
    target_report = File.open(report_filepaths.shift) {|f| Nokogiri::XML(f)}
    file_name = params[:collated_report] + "/#{params[:scheme]}.test_result/1_Test/action_TestSummaries.plist"
    reports = report_filepaths.map { |report_filepath| Nokogiri::XML(Nokogiri::PList(open(report_filepath)).to_plist_xml) }

    #Merge .plist reports
    reports.each do |retry_report|
      mergeLists(target_report, retry_report, params)
    end
  end
  merge_assets(params[:assets], params[:collated_report] + "/Attachments")
  copy_log(params[:logs], params[:collated_report] + "/")
end
write_report_to_file(report, file_name) click to toggle source
# File lib/fastlane/plugin/retry_tests/actions/collate_junit_reports.rb, line 82
def self.write_report_to_file(report, file_name)
  File.new(file_name, 'w')
  File.open(file_name, 'w') do |f|
    f.write(report.to_xml)
  end
end