class Fastlane::Actions::RescanFlakyTestsAction

Public Class Methods

authors() click to toggle source
# File lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb, line 54
def self.authors
  ["Ichiko Moro"]
end
available_options() click to toggle source
# File lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb, line 63
def self.available_options
  containing = FastlaneCore::Helper.fastlane_enabled_folder_path

  [
    FastlaneCore::ConfigItem.new(key: :report_file,
                                 env_name: 'RESCAN_REPORT_FILE',
                                 description: "JUnit report file path generated by scan, rescan target test cases extract from the file",
                                 type: String,
                                 default_value: File.join(containing, "test_output", "report.junit"),
                                 default_value_dynamic: true),
    FastlaneCore::ConfigItem.new(key: :output_directory,
                                 env_name: 'RESCAN_OUTPUT_DIRECTORY',
                                 description: "Each rescaned report and build log is saved in rescan_NN under the path",
                                 type: String,
                                 default_value: File.join(containing, "test_output"),
                                 default_value_dynamic: true,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :failed_test_limit,
                                 env_name: 'RESCAN_FAILED_TEST_LIMIT',
                                 description: "Stop rescan if faild test cases count is greater than this threshold. No limitation if this value is ZERO",
                                 type: Integer,
                                 default_value: 0,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :scan,
                                 description: "Parameters that are passed to the scan action",
                                 type: Hash,
                                 default_value: {},
                                 optional: true)
  ]
end
description() click to toggle source
# File lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb, line 50
def self.description
  "Re-run `scan` action for each failed test case."
end
details() click to toggle source
# File lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb, line 58
      def self.details
        "When you running UI tests (XCUITest, EarlGrey or others), sometime that failed with un clear reason. \n\
This plugin re-scan each failed test cases. And report result under `\#{output_directory}/rescan/NN`."
      end
example_code() click to toggle source
# File lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb, line 98
def self.example_code
  [
    '# shoud run `scan` before to get first test result.',
    'begin
      scan
    rescue
      rescan_flaky_tests
    end',
    '# use rescue block or `fail_build` option',
    'scan(fail_build: false)
    rescan_flaky_tests',
    '# recommend to pack scan options',
    'scan_options = {
      ...
    }
    begin
      scan(scan_options)
    rescue
      rescan_flaky_tests(
        scan_options.merge {
          report_file: "path/to/report.junit"
        }
      )
    end'
  ]
end
is_supported?(platform) click to toggle source
# File lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb, line 94
def self.is_supported?(platform)
  [:ios, :mac].include?(platform)
end
run(params) click to toggle source
# File lib/fastlane/plugin/rescan_flaky_tests/actions/rescan_flaky_tests_action.rb, line 4
def self.run(params)
  first_report_path = params[:report_file]
  unless File.exist?(first_report_path)
    UI.user_error!("The report file '#{first_report_path}' is not found.")
  end

  test_cases = Helper::RescanFlakyTestsHelper.extract_failed_test_cases(first_report_path)
  if test_cases.nil?
    UI.user_error!("The report should be junit xml file.")
  end
  if test_cases.empty?
    UI.important("There is no test to retry.")
    return true
  end

  failed_test_limit = params[:failed_test_limit]
  if failed_test_limit > 0 && failed_test_limit < test_cases.count
    UI.error("Stop rescan because there are too many faild cases, #{test_cases.count} > #{failed_test_limit} (threshold).")
    exit 0
  end

  rescan_output_root = params[:output_directory]

  last_exception = nil

  test_cases.each_with_index do |test_case, i|
    retry_output_directory = File.join(rescan_output_root, "rescan", (i + 1).to_s)
    UI.important("Rescan '#{test_case}'.")
    UI.important("Reports are saved '#{retry_output_directory}'.")

    begin
      scan_options = params[:scan]
      scan_options[:only_testing] = [test_case]
      scan_options[:output_directory] = retry_output_directory
      scan_options[:buildlog_path] = retry_output_directory

      scan_params = FastlaneCore::Configuration.create(ScanAction.available_options, scan_options)
      ::Fastlane::Actions::ScanAction.run(scan_params)
    rescue => e
      last_exception = e
    end
  end

  raise last_exception unless last_exception.nil?
end