docbrown/spec/support/initializers/ci_csv_formatter.rb
Michael Kohl 521f1d26bc
Upgrade to Ruby 3.0.2 (#12103)
Co-authored-by: rhymes <rhymes@hey.com>
Co-authored-by: Mac Siri <krairit.siri@gmail.com>
2021-08-25 14:26:33 -04:00

113 lines
4.5 KiB
Ruby

return unless ENV["CI"]
require "csv"
require "rspec/retry"
require "singleton"
class CSVFormatter
RSpec::Core::Formatters.register self, :example_passed, :example_failed, :example_pending, :close
HEADERS = ["Description", "File", "Status", "Start Date", "Start Time", "Run Time", "Exception",
"Backtrace", "Retry #", "Suite Status", "Suite Run Time", "Travis URL", "Travis Branch"].freeze
def initialize(_output)
@rows = []
@suite_start_time = Time.zone.now
@suite_status = :passed
end
def example_pending(notification)
description = notification.example.metadata[:full_description]
file = notification.example.metadata[:location]
status = :pending
started_at = notification.example.metadata[:execution_result].started_at
start_date = started_at.strftime("%m-%d-%Y")
start_time = started_at.strftime("%H-%M-%S.%3N")
run_time = notification.example.metadata[:execution_result].run_time.round(3)
@rows << [description, file, status, start_date, start_time, run_time, nil, nil, nil]
end
def example_passed(notification)
description = notification.example.metadata[:full_description]
file = notification.example.metadata[:location]
status = :passed
started_at = notification.example.metadata[:execution_result].started_at
start_date = started_at.strftime("%m-%d-%Y")
start_time = started_at.strftime("%H-%M-%S.%3N")
run_time = notification.example.metadata[:execution_result].run_time.round(3)
retry_attempt = notification.example.metadata[:retry_attempts]
@rows << [description, file, status, start_date, start_time, run_time, nil, nil, retry_attempt]
end
def example_failed(notification)
@suite_status = :failed # If we're in here at all it means the entire run will count as failed
description = notification.example.metadata[:full_description]
file = notification.example.metadata[:location]
status = :failed
started_at = notification.example.metadata[:execution_result].started_at
start_date = started_at.strftime("%m-%d-%Y")
start_time = started_at.strftime("%H-%M-%S.%3N")
run_time = notification.example.metadata[:execution_result].run_time.round(3)
exception = notification.example.metadata[:execution_result].exception.inspect
backtrace = notification.example.metadata[:execution_result].exception.backtrace
backtrace = backtrace.join(" ") if backtrace
retry_attempt = notification.example.metadata[:retry_attempts]
@rows << [description, file, status, start_date, start_time, run_time, exception, backtrace, retry_attempt]
end
def close(_notification)
csvs_dir = File.join(Dir.pwd, "tmp", "csvs")
FileUtils.mkdir_p(csvs_dir)
timestamp = Time.current.utc.iso8601.tr(":", "-")
csv_filename = File.join(csvs_dir, "#{timestamp}.csv")
suite_runtime = (Time.zone.now - @suite_start_time).round(3)
with_headers = { write_headers: true, headers: HEADERS }
CSV.open(csv_filename, "w", **with_headers) do |csv|
(@rows + RSpecRetryFormatterHelper.instance.rows).each do |row|
row += [@suite_status, suite_runtime, ENV["TRAVIS_BUILD_WEB_URL"], ENV["TRAVIS_BRANCH"]]
csv << row
end
end
end
end
# This singleton exists so that we can get retry data from the retry_callback in the CSVFormatter
class RSpecRetryFormatterHelper
include Singleton
attr_accessor :rows
def initialize
@rows = []
end
end
RSpec.configure do |config|
config.add_formatter(CSVFormatter)
config.verbose_retry = true
config.display_try_failure_messages = true
config.around :each, :js do |ex|
ex.run_with_retry retry: 3
end
# None of the rspec formatter hooks are invoked in the case of a retry, so the only way to get data
# from retried tests is to store it in a singleton
config.retry_callback = proc do |ex|
description = ex.metadata[:full_description]
file = ex.metadata[:location]
status = :failed
started_at = ex.metadata[:execution_result].started_at
start_date = started_at.strftime("%m-%d-%Y")
start_time = started_at.strftime("%H-%M-%S.%3N")
run_time = (Time.zone.now - started_at).round(3)
exception = ex.metadata[:retry_exceptions].last.inspect
backtrace = ex.metadata[:retry_exceptions].last.backtrace
backtrace = backtrace.join(" ") if backtrace
retry_attempt = ex.metadata[:retry_attempts]
RSpecRetryFormatterHelper.instance.rows << [description, file, status, start_date, start_time, run_time,
exception, backtrace, retry_attempt]
end
end