require 'nokogiri' require 'yaml' require_relative '../testrail'
DROMEDARY = YAML.load_file(“#{Dir.pwd}/config/dromedary.yml”)
# TASKS
# Preparation tasks
desc 'This task creates required folders and files' task :prepare_for_a_ride do
%W[create_folders create_files].each do |task_name| sh "rake #{task_name}" do #ignore errors end end
end
desc 'This task creates required folder tree for reporting' task :create_folders do
%W[artifacts artifacts/cucumber_json_reports artifacts/junit_xml_reports artifacts/testrail_reports artifacts/final_test_reports].each do |dir_name| Dir.mkdir "#{dir_name}" end
end
desc 'This task creates and updates required files for reporting' task :create_files do
%W[artifacts/cucumber_json_reports/run.json artifacts/cucumber_json_reports/rerun.json artifacts/final_test_reports/final_cucumber_json_report.json artifacts/final_test_reports/run_results_with_case_id.json artifacts/final_test_reports/rerun_results_with_case_id.json artifacts/final_test_reports/test_cases.json].each do |file_name| File.open(file_name, 'w') do |file| file.puts '[]' end end File.open('artifacts/final_test_reports/final_junit_report.xml', 'w') do |file| xml_structure.each do |line| file.puts line end end
end
desc 'Saving Test cases from remote TestRail
project' task :store_cases_titles do
@client = TestRail::APIClient.new(DROMEDARY['testrail']['url']) @client.user = DROMEDARY['testrail']['user'] @client.password = DROMEDARY['testrail']['password'] project_id = DROMEDARY['testrail']['project_id'] suite_id = DROMEDARY['testrail']['suite_id'] cases = @client.get_cases_for_suite(project_id, suite_id) @full_cases = @client.get_cases_titles(cases, project_id, suite_id) File.open('artifacts/final_test_reports/test_cases.json', 'w') do |file| require 'json' file.puts @full_cases.to_json end
end
# Runner tasks
desc 'Run Cucumber features for the first run' task :run_cucumber do
sh "cucumber -p junit_report -p rerun_formatter -p run_json_report" do #ignore errors end
end
desc 'Rerun Cucumber features according to the fails.log' task :rerun_failed do
sh "cucumber @artifacts/final_test_reports/fails.log -p junit_report -p rerun_json_report" do #ignore errors end
end
task :rerun_if_needed do
if File.file?("artifacts/final_test_reports/fails.log") if File.read("artifacts/final_test_reports/fails.log").empty? puts 'Rerun step skipped, no fails occurred during the first run' else fails = File.read("artifacts/final_test_reports/fails.log") File.open('artifacts/final_test_reports/fails.log', 'w') do |file| file.puts fails.gsub('\n', ' ') end sh "rake rerun_and_update_reports" do #ignore errors end end else puts 'Rerun step skipped, no fails occurred during the first run' end
end
desc 'Rerun failed Cucumber features and update respective reports' task :rerun_and_update_reports do
%W[clean_interim_reports rerun_failed merge_junit_reports get_case_ids[rerun]].each do |task_name| sh "rake #{task_name}" do #ignore errors end end
end
# Cleaning tasks
desc 'Cleaning all interim reports' task :clean_interim_reports do
%W[clean_test_rail clean_junit].each do |task_name| sh "rake #{task_name}" do #ignore errors end end
end
desc 'Cleaning interim TestRail
reports' task :clean_test_rail do
catalog = 'artifacts/testrail_reports' files = Dir.entries(catalog).delete_if { |entry| File.directory?(entry) } files.map! { |f| "#{catalog}/#{f}" } rm files
end
desc 'Cleaning interim JUnit reports' task :clean_junit do
catalog = 'artifacts/junit_xml_reports' files = Dir.entries(catalog).delete_if { |entry| File.directory?(entry) } files.map! { |f| "#{catalog}/#{f}" } rm files
end
desc 'Cleaning interim Cucumber JSON reports' task :clean_cucumber_json do
catalog = 'artifacts/cucumber_json_reports' files = Dir.entries(catalog).delete_if { |entry| File.directory?(entry) } files.map! { |f| "#{catalog}/#{f}" } rm files
end
desc 'Cleaning rudimentary folders' task :clean_folders do
catalog = 'artifacts' dirs = Dir.entries(catalog).drop 2 dirs.delete('final_test_reports') dirs.map! { |f| "#{catalog}/#{f}" } dirs.each do |dir_path| remove_dir dir_path end
end
desc 'Cleaning project tree from unnecessary files and folders' task :final_clean_ups do
%W[clean_test_rail clean_junit clean_cucumber_json clean_folders].each do |task_name| sh "rake #{task_name}" do #ignore errors end end
end
# Report generation tasks
desc 'Merging interim JUnit reports to final JUnit report' task :merge_junit_reports do
file_names = Dir.entries('artifacts/junit_xml_reports').delete_if { |entry| File.directory?(entry) } file_names.each do |file_name| sh "junit_merge artifacts/junit_xml_reports/#{file_name} artifacts/final_test_reports/final_junit_report.xml" do #ignore errors end end
end
desc 'Merging interim Cucumber json reports to final Cucumber json report' task :generate_cucumber_json_reports do
test_results = [] run_results = JSON.parse(File.read('artifacts/cucumber_json_reports/run.json')) rerun_results = JSON.parse(File.read('artifacts/cucumber_json_reports/rerun.json')) run_results.each do |x| rerun_results.each do |y| if y.values[0] == x.values[0] x.merge!(y) end end test_results.push(x) end File.open('artifacts/final_test_reports/final_cucumber_json_report.json', 'w') do |file| require 'json' file.puts test_results.to_json end
end
desc 'Generating interim TestRail
report for a particular run' task :get_case_ids, :run_type do |task, args|
@test_results = {} file = File.read('artifacts/final_test_reports/test_cases.json') @full_cases = JSON.parse(file) file_names = Dir.entries('artifacts/testrail_reports').delete_if { |entry| File.directory?(entry) } file_names.each do |file_name| result = JSON.parse(File.read("artifacts/testrail_reports/#{file_name}")) @test_results.update(result) end @results_json = [] @test_results.map do |full_desc,status_id| n = 0 until n == status_id.count do current_result = {:case_id => find_id(full_desc)[n], :status_id => status_id[n] } if find_id(full_desc) @results_json.push(current_result) n += 1 end end @results_json.compact! File.open("artifacts/final_test_reports/#{args[:run_type]}_results_with_case_id.json", 'w') do |file| file.write(@results_json.to_json) end
end
desc 'Creating Test Run on remote TestRail
project' task :create_run, :suite_type, :environment, :section_name do |task, args|
@client = TestRail::APIClient.new(DROMEDARY['testrail']['url']) @client.user = DROMEDARY['testrail']['user'] @client.password = DROMEDARY['testrail']['password'] project_id = DROMEDARY['testrail']['project_id'] suite_id = DROMEDARY['testrail']['suite_id'] test_run_name = DROMEDARY['testrail']['test_run_default_name'] + ' ' + args[:suite_type].capitalize + ' on ' + args[:environment].capitalize test_run = @client.add_run(project_id, suite_id, test_run_name) file = File.open('artifacts/final_test_reports/test_run_id.txt', File::CREAT|File::TRUNC|File::RDWR) file.puts test_run['id'] file.close
end
desc 'Closing Test Run on remote TestRail
project' task :close_run, :environment do
@client = TestRail::APIClient.new(DROMEDARY['testrail']['url']) @client.user = DROMEDARY['testrail']['user'] @client.password = DROMEDARY['testrail']['password'] run_results = JSON.parse(File.read('artifacts/final_test_reports/run_results_with_case_id.json')) rerun_results = JSON.parse(File.read('artifacts/final_test_reports/rerun_results_with_case_id.json')) test_results = run_results + rerun_results run_id = File.new('artifacts/final_test_reports/test_run_id.txt').read.chomp @client.add_results_for_cases(run_id, test_results) @client.mark_untested_tests_failed(run_id) @client.close_run(run_id, data = {})
end
# METHODS
def xml_structure
['<?xml version="1.0" encoding="UTF-8"?>', '<testsuite name="" tests="" failures="" errors="" time="" timestamp="">', ' <!-- Randomized with seed 00000 -->', ' <properties/>', '</testsuite>']
end
def find_id(full_title)
@ids_array = [] @full_cases.select {|c| c['title'] == full_title.gsub(' ', ' ')}.each do |e| @ids_array << e['id'] end @ids_array unless @ids_array.empty?
end