Class: Cukerail::JsonSender
- Inherits:
-
Object
- Object
- Cukerail::JsonSender
- Defined in:
- lib/json_sender.rb
Instance Attribute Summary collapse
-
#results ⇒ Object
readonly
Returns the value of attribute results.
-
#testrail_api_client ⇒ Object
readonly
Returns the value of attribute testrail_api_client.
Instance Method Summary collapse
- #add_case_to_test_run(testcase_id, run_id) ⇒ Object
- #create_new_case(scenario, background_steps, project_id, suite_id, sub_section_id) ⇒ Object
- #defects(scenario) ⇒ Object
- #each_feature ⇒ Object
- #extract_top_level_data(feature) ⇒ Object
- #get_id(scenario, background_steps, project_id, suite_id, sub_section_id) ⇒ Object
- #get_name(scenario) ⇒ Object
- #get_run(run_id) ⇒ Object
- #get_tests_in_a_run(run_id) ⇒ Object
-
#initialize(json_file) ⇒ JsonSender
constructor
A new instance of JsonSender.
- #prepare_data(scenario, background_steps) ⇒ Object
- #refs(scenario) ⇒ Object
- #remove_all_except_these_cases_from_suite(testcases, project_id, suite_id) ⇒ Object
- #remove_all_except_these_cases_from_testrun(testcases, run_id) ⇒ Object
- #remove_case_from_test_run(testcase, run_id) ⇒ Object
- #send_result(scenario, id, run_id) ⇒ Object
- #send_steps(scenario, background_steps, testcase_id) ⇒ Object
- #update_plan(plan_id, run_id, case_ids) ⇒ Object
- #update_run(run_id, case_ids) ⇒ Object
Constructor Details
#initialize(json_file) ⇒ JsonSender
Returns a new instance of JsonSender.
9 10 11 12 13 14 15 |
# File 'lib/json_sender.rb', line 9 def initialize(json_file) if %w(BASE_URL USER PASSWORD).map{|e| ENV["TESTRAIL_#{e}"]}.any?{|e| e=='' || !e} raise 'You need to setup Testrail environment parameters see https://bbcworldwide.atlassian.net/wiki/display/BAR/Installing+and+Running+Cukerail' end @testrail_api_client = TestRail::APIClient.new(ENV['TESTRAIL_BASE_URL'],ENV['TESTRAIL_USER'],ENV['TESTRAIL_PASSWORD']) @results = JSON.parse(File.read(json_file)).select{|f| f['tags']} end |
Instance Attribute Details
#results ⇒ Object (readonly)
Returns the value of attribute results.
8 9 10 |
# File 'lib/json_sender.rb', line 8 def results @results end |
#testrail_api_client ⇒ Object (readonly)
Returns the value of attribute testrail_api_client.
8 9 10 |
# File 'lib/json_sender.rb', line 8 def testrail_api_client @testrail_api_client end |
Instance Method Details
#add_case_to_test_run(testcase_id, run_id) ⇒ Object
206 207 208 209 210 211 212 213 |
# File 'lib/json_sender.rb', line 206 def add_case_to_test_run(testcase_id,run_id) run = get_run(run_id) unless run['include_all'] puts "add testcase #{testcase_id} to run #{run_id}" case_ids = get_tests_in_a_run(run_id).map{|h| h['case_id']} + [testcase_id] update_run(run_id,{'case_ids'=>case_ids}) end end |
#create_new_case(scenario, background_steps, project_id, suite_id, sub_section_id) ⇒ Object
82 83 84 85 86 87 88 |
# File 'lib/json_sender.rb', line 82 def create_new_case(scenario,background_steps,project_id,suite_id,sub_section_id) data = prepare_data(scenario,background_steps) testrail_api_client.send_post("add_case/#{sub_section_id || suite_id}", data) rescue StandardError => e puts "#{e.} in #{get_name(scenario)}" return nil end |
#defects(scenario) ⇒ Object
113 114 115 116 117 118 |
# File 'lib/json_sender.rb', line 113 def defects(scenario) if scenario['tags'] = [scenario['tags']].flatten.compact .select{|tag| tag['name'] =~/(?:jira|defect)_/}.map{|ticket| /(?:jira|defect)_(\w+-\d+)$/.match(ticket['name'])[1]}.uniq.join(",") end end |
#each_feature ⇒ Object
17 18 19 20 21 22 23 |
# File 'lib/json_sender.rb', line 17 def each_feature results.each do |feature| scenarios = feature['elements'].reject{|e| e['keyword']=='Background'}.select{|e| e['type'] == 'scenario'} project_id,suite_id,sub_section_id,background_steps = extract_top_level_data(feature) yield scenarios,project_id,suite_id,sub_section_id,background_steps end end |
#extract_top_level_data(feature) ⇒ Object
44 45 46 47 48 49 50 51 52 |
# File 'lib/json_sender.rb', line 44 def extract_top_level_data(feature) puts "feature file #{feature['uri']}" project_id = feature['tags'].select{|j| j['name']=~/project_\d+/}.map{|j| /project_(\d+)/.match(j['name'])[1].to_i}.first suite_id = feature['tags'].select{|j| j['name']=~/suite_\d+/}.map{|j| /suite_(\d+)/.match(j['name'])[1].to_i}.first sub_section_id = feature['tags'].select{|j| j['name']=~/sub_section_\d+/}.map{|j| /sub_section_(\d+)/.match(j['name'])[1].to_i}.first background=feature['elements'].select{|e| e['keyword']=='Background'}.first background_steps = background ? background['steps'].map{|s| s['keyword']+s['name']}.join("\n") : '' return project_id,suite_id,sub_section_id,background_steps end |
#get_id(scenario, background_steps, project_id, suite_id, sub_section_id) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/json_sender.rb', line 26 def get_id(scenario,background_steps,project_id,suite_id,sub_section_id) title = get_name(scenario) scenario_level_sub_section = scenario['tags'].select{|j| j['name']=~/sub_section_\d+/}.last if scenario_level_sub_section sub_section_id_override = /sub_section_(\d+)/.match(scenario_level_sub_section['name'])[1] else sub_section_id_override=sub_section_id end found_case = testrail_api_client.send_get("get_cases/#{project_id}&suite_id=#{suite_id}§ion_id=#{sub_section_id_override}").select{|c| c['title'] == title}.first if found_case result= found_case['id'] else test_case = create_new_case(scenario,background_steps,project_id,suite_id,sub_section_id_override) result = test_case ? test_case['id'] : nil end return result end |
#get_name(scenario) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/json_sender.rb', line 54 def get_name(scenario) base_name = scenario['name'] # We only extrapolate example data for scenario outlines is_scenario_outline = scenario['keyword'].downcase == 'scenario outline' ? true : false if is_scenario_outline # if we have scenario number then we assume this is just a JSON output without our id patch outline_number_str = scenario['id'].split(';').select{|e| e =~/^\d+$/}.first if outline_number_str outline_number = (outline_number_str.to_i) -1 else # If we do not find an outline number, then we attempt to extrapolate the example data from the # id if there is any and append to the base name. note: _ before variable means it is not going # to be used _feature, _scenario, example_data = scenario['id'].split(';') unless example_data.nil? && example_data.strip.empty? base_name = if ENV['OLD_STYLE_OUTLINE_NAMES'] "#{base_name} :: #{example_data}" else "#{base_name} #{example_data}" end end end end = [scenario['tags']].flatten.compact requirement = .select{|t| t['name'] =~/@req/}.map{|t| /@req_(\w+)/.match(t['name'])[1]}.first unless .empty? [requirement, base_name, outline_number].join(' ').strip end |
#get_run(run_id) ⇒ Object
170 171 172 |
# File 'lib/json_sender.rb', line 170 def get_run(run_id) testrail_api_client.send_get("get_run/#{run_id}") end |
#get_tests_in_a_run(run_id) ⇒ Object
174 175 176 |
# File 'lib/json_sender.rb', line 174 def get_tests_in_a_run(run_id) testrail_api_client.send_get("get_tests/#{run_id}") end |
#prepare_data(scenario, background_steps) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/json_sender.rb', line 98 def prepare_data(scenario,background_steps) steps = background_steps + "\n" + scenario['steps'].map{|s| s['keyword']+s['name']}.join("\n") type_ids = [1] type_ids << 7 if scenario['tags'].any?{|tag| tag['name'] =~/manual/} type_ids << 13 if scenario['tags'].any?{|tag| tag['name'] =~/on_hold/} #get the highest precedence type found in the tags. E.g. if it's @on_hold and @manual it selects 13 for on hold type_id = ([13,7,1] & type_ids).first data = {'title'=>get_name(scenario), 'type_id'=>type_id, 'custom_steps'=>steps, 'refs'=>refs(scenario) } end |
#refs(scenario) ⇒ Object
120 121 122 123 124 125 |
# File 'lib/json_sender.rb', line 120 def refs(scenario) if scenario['tags'] = [scenario['tags']].flatten.compact .select{|tag| tag['name'] =~/(?:jira|ref)_/}.map{|ticket| /(?:jira|ref)_(\w+-\d+)$/.match(ticket['name'])[1]}.uniq.join(",") end end |
#remove_all_except_these_cases_from_suite(testcases, project_id, suite_id) ⇒ Object
223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/json_sender.rb', line 223 def remove_all_except_these_cases_from_suite(testcases,project_id,suite_id) puts '=== testcases === ' puts testcases # get a list of automated tests, ignore manual or on hold tests existing_cases = testrail_api_client.send_get("get_cases/#{project_id}&suite_id=#{suite_id}").select{|t| t['type_id']==1}.map{|m| m['id']} puts '===== existing_cases === ' puts existing_cases (existing_cases - testcases).each do |case_to_remove| puts "case_to_remove #{case_to_remove}" testrail_api_client.send_post("delete_case/#{case_to_remove}",nil) end end |
#remove_all_except_these_cases_from_testrun(testcases, run_id) ⇒ Object
215 216 217 218 219 220 221 |
# File 'lib/json_sender.rb', line 215 def remove_all_except_these_cases_from_testrun(testcases,run_id) run = get_run(run_id) unless run['include_all'] case_ids = get_tests_in_a_run(run_id).map{|h| h['case_id']} & testcases update_run(run_id,{'case_ids'=>case_ids}) end end |
#remove_case_from_test_run(testcase, run_id) ⇒ Object
197 198 199 200 201 202 203 204 |
# File 'lib/json_sender.rb', line 197 def remove_case_from_test_run(testcase,run_id) testcase_id = get_id(testcase) run = get_run(run_id) unless run['include_all'] case_ids = get_tests_in_a_run(run_id).map{|h| h['case_id']} - [testcase_id] update_run(run_id,{'case_ids'=>case_ids}) end end |
#send_result(scenario, id, run_id) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/json_sender.rb', line 127 def send_result(scenario,id,run_id) error_line = scenario['steps'].select{|s| s['result']['status'] != 'passed'}.first if error_line #puts error_line['result'] testrail_status = case error_line['result']['status'] when 'failed' {id:5,comment: 'failed'} when 'undefined' {id:7,comment: 'undefined step'} when 'pending' {id:6,comment: 'pending step'} when 'skipped' {id:5,comment: 'failed in before hook'} end error_result = error_line['error_message'] = <<-FAILURE Error message: #{testrail_status[:comment]} #{error_result} Step: #{error_line['keyword']} #{error_line['name']} Location: #{error_line['match']['location']} FAILURE else testrail_status = {id:1,comment: 'passed'} = nil end report_on_result = {status_id:testrail_status[:id],comment:,defects:defects(scenario)} tries = 3 begin testrail_api_client.send_post("add_result_for_case/#{run_id}/#{id}",report_on_result) rescue => e if e. =~ /No \(active\) test found for the run\/case combination/ tries -= 1 add_case_to_test_run(id,run_id) if tries > 0 retry else puts "#{e.} testrun=#{run_id} test case id=#{id}" end else puts "#{e.} testrun=#{run_id} test case id=#{id}" end end end |
#send_steps(scenario, background_steps, testcase_id) ⇒ Object
90 91 92 93 94 95 96 |
# File 'lib/json_sender.rb', line 90 def send_steps(scenario,background_steps,testcase_id) data = prepare_data(scenario,background_steps) testrail_api_client.send_post("update_case/#{testcase_id}",data) rescue StandardError => e puts "#{e.} in #{get_name(scenario)}" return nil end |
#update_plan(plan_id, run_id, case_ids) ⇒ Object
191 192 193 194 195 |
# File 'lib/json_sender.rb', line 191 def update_plan(plan_id,run_id,case_ids) test_plan = testrail_api_client.send_get("get_plan/#{plan_id}") entry_id = test_plan['entries'].select{|e| e['runs'].any?{|r| r['id']==run_id}}.first['id'] testrail_api_client.send_post("update_plan_entry/#{plan_id}/#{entry_id}",case_ids) end |
#update_run(run_id, case_ids) ⇒ Object
178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/json_sender.rb', line 178 def update_run(run_id,case_ids) run = get_run(run_id) begin if run['plan_id'] update_plan(run['plan_id'],run_id,case_ids) else testrail_api_client.send_post("update_run/#{run_id}",case_ids) end rescue => e puts "#{e.} testrun=#{run_id} test case ids=#{case_ids}" end end |