class Fastlane::Actions::MultiScanAction

Public Class Methods

authors() click to toggle source
# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 121
def self.authors
  ["Gloria Chow/@gmgchow"]
end
available_options() click to toggle source
# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 108
def self.available_options
  scan_options + [
    FastlaneCore::ConfigItem.new(
      key: :try_count,
      env_name: "FL_MULTI_SCAN_TRY_COUNT",
      description: "The number of times to retry running tests via scan",
      type: Integer,
      is_string: false,
      default_value: 1
    )
  ]
end
config_with_retry(config, count) click to toggle source

Create scan config

# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 75
def self.config_with_retry(config, count)
  folder = get_folder_root(config[:result_bundle])
  config[:result_bundle] = (folder + count.to_s)
  config[:output_directory] = (folder + count.to_s)
  config
end
description() click to toggle source

@!group Documentation

# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 96
def self.description
  "Uses scan to run Xcode tests a given number of times: only re-testing failing tests."
end
details() click to toggle source
# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 100
def self.details
  "Use this action to run your tests if you have fragile tests that fail sporadically."
end
get_folder_root(folder) click to toggle source

Get folder location

# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 83
def self.get_folder_root(folder)
  folder = folder.gsub(/ *\d+$/, '')
  folder
end
is_supported?(platform) click to toggle source
# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 125
def self.is_supported?(platform)
  platform == :ios
end
merge_reports(scan_options, final_report_path) click to toggle source

Merge results from all retries

# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 58
def self.merge_reports(scan_options, final_report_path)
  UI.header("Merging Reports")
  folder = get_folder_root(scan_options[:output_directory])
  report_files = Dir.glob("#{folder}*/**/action_TestSummaries.plist").sort
  asset_files = Dir.glob("#{folder}*/**/Attachments")
  log_files = Dir.glob("#{folder}*/**/action.xcactivitylog")
  if report_files.size > 1
    other_action.collate_junit_reports(
      reports: report_files,
      collated_report: final_report_path,
      assets: asset_files,
      logs: log_files,
    )
  end
end
parse_failures(plist, scheme_name) click to toggle source

Parse the names of the failed test cases

# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 45
def self.parse_failures(plist, scheme_name)
  failures = Array.new
  target_report = File.open(plist) {|f| Nokogiri::XML(f)}
  # Get the names of all the failed tests from the specified report
  failed = target_report.xpath("//key[contains(.,'Failure')]/../key[contains(.,'TestIdentifier')]/following-sibling::string[contains(.,'()') and contains (., '/')]")
  failed.each do |test_name|
    # Reformat the test name to be usable by the xcodebuild 'only_testing' flag
    failures << ("#{scheme_name}/" + test_name.to_s.split('(')[0].split('>')[1])
  end
  failures
end
plist_report_filepath(config) click to toggle source
# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 88
def self.plist_report_filepath(config)
  File.absolute_path(File.join(config[:output_directory], "/#{config[:scheme]}.test_result/TestSummaries.plist"))
end
run(params) click to toggle source
# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 9
def self.run(params)
  try_count = 0
  scan_options = params.values.reject { |k| k == :try_count }
  final_report_path = scan_options[:result_bundle]
  unless Helper.test?
    FastlaneCore::PrintTable.print_values(
      config: params._values.reject { |k, v| scan_options.key?(k) },
      title: "Summary for multi_scan"
    )
  end

  begin
    try_count += 1
    UI.header("Test Attempt: #{try_count}")
    scan_options = config_with_retry(scan_options, try_count)
    config = FastlaneCore::Configuration.create(Fastlane::Actions::ScanAction.available_options, scan_options)
    Fastlane::Actions::ScanAction.run(config)
  rescue FastlaneCore::Interface::FastlaneTestFailure => e
    UI.verbose("Scan failed with #{e}")
    if try_count < params[:try_count]
      report_filepath = plist_report_filepath(scan_options)
      failed_tests = parse_failures(report_filepath, params[:scheme])
      scan_options[:only_testing] = failed_tests
      retry
    end
  rescue FastlaneCore::Interface::FastlaneCommonException => e
    UI.important("Probably encountered an environment failure: #{e}")
    if try_count < params[:try_count]
      UI.important("Retrying the last run from the beginning.")
      retry
    end
  end
  merge_reports(scan_options, final_report_path)
end
scan_options() click to toggle source
# File lib/fastlane/plugin/retry/actions/multi_scan.rb, line 104
def self.scan_options
  ScanAction.available_options
end