Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
library/generic/custom_html_report.rb | 821 | 529 | 91.47%
|
86.77%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
2 =begin |
3 *Name : CustomHtmlReport |
4 *Description : class that holds custom report file generator methods |
5 *Author : Chandra sekaran |
6 *Creation Date : 11/11/2014 |
7 *Updation Date : 19/02/2015 |
8 =end |
9 |
10 module CUKES |
11 class CustomHtmlReport |
12 include FileLibrary |
13 include DateTimeLibrary |
14 |
15 # Description : invoked automatically when an object of the class type is created |
16 # Author : Chandra sekaran |
17 # Arguments : |
18 # arr_file_paths : array of html report file paths |
19 # |
20 def initialize(arr_file_paths) |
21 @arr_file_name = arr_file_paths |
22 @template_file_name = arr_file_paths.first # take the html template from first html file |
23 |
24 @scenario=[] |
25 @scenario_pass=[] |
26 @scenario_fail=[] |
27 @scenario_skip=[] |
28 @scenario_pending=[] |
29 @scenario_undefined=[] |
30 @step=[] |
31 @step_pass=[] |
32 @step_fail=[] |
33 @step_skip=[] |
34 @step_pending=[] |
35 @step_undefined=[] |
36 |
37 @feature=[] |
38 @arr_html_file_name = [] |
39 @arr_testcase_id = [] |
40 @arr_feature_id = [] |
41 end |
42 |
43 # Description : creates new directory for custom report files and copies other dependents |
44 # Author : Chandra sekaran |
45 # |
46 def create_report_directory |
47 create_directory("#{$current_log_dir}/custom_report") |
48 create_directory("#{$current_log_dir}/custom_report/detailed_report") |
49 FileUtils.cp("library/generic/app_logo_1.png", "#{$current_log_dir}/custom_report/detailed_report") |
50 # copy screenshot directory to custom_report directory for image attachment of custom report html files |
51 FileUtils.cp_r("#{$current_log_dir}/screenshot", "#{$current_log_dir}/custom_report/detailed_report") rescue Exception |
52 rescue Exception => ex |
53 $log.error("Error in creating custom report directory : #{ex}") |
54 exit |
55 end |
56 |
57 # Description : creates new html template object based cucumber report file generated |
58 # Author : Chandra sekaran |
59 # Arguments : |
60 # str_file_path : file path of html file |
61 # Return arguments : |
62 # html_template : html object |
63 # |
64 def create_html_template(str_file_path) |
65 html_template = Nokogiri::HTML(File.read(str_file_path)) |
66 html_template.xpath("//div[@id='label']/h1").each do |t| |
67 t.replace("<br><div class='centr'>CUKES - TEST REPORT SUMMARY</div>") |
68 end |
69 |
70 bottom = Nokogiri::XML::Node.new("footer", html_template) |
71 div = html_template.at_css("div.feature") |
72 div.add_next_sibling(bottom) |
73 |
74 html_template.at('footer')["id"] = "footer" |
75 |
76 html_template.xpath("//div[@class='feature']").each do |n| |
77 n.replace(Nokogiri::XML::Node.new("p", html_template)) |
78 end |
79 |
80 footer = Nokogiri::XML::Node.new("div", html_template) |
81 timestamp = Nokogiri::XML::Node.new("div", html_template) |
82 timestamp.inner_html = "<font color='white' size='2'>Executed on #{Time.now.strftime('%m-%d-%Y %I:%M:%S')} <br> Executed in #{ENV['COMPUTERNAME']} (#{ENV['OS']}) / #{BROWSER.capitalize} (#{$browser_version})</font>" |
83 logo = Nokogiri::XML::Node.new("img", html_template) |
84 |
85 footer.add_child(logo) |
86 footer.add_child(timestamp) |
87 |
88 footer['style'] = "background-color: #363636;" # black color |
89 |
90 footer.add_child("<style type='text/css'>#footer {position : fixed;margin-top : 35px;text-align:center;width: 100%;height: 63px;bottom: 0px; left: 0px;}</style>") |
91 bottom.add_child(footer) |
92 html_template.at('img')["src"] = "detailed_report/app_logo_1.png" |
93 html_template.at('img')["height"] = "30px" |
94 |
95 html_template.xpath("//div[@id='summary']/p[1]").each do |t| |
96 t.replace(Nokogiri::XML::Node.new("p", html_template)) # remove pass/fail count in the report header |
97 #t.inner_html = " " |
98 end |
99 html_template.xpath("//div[@id='summary']/p[2]").each do |t| |
100 t.replace(Nokogiri::XML::Node.new("p", html_template)) # remove execution duration in the report header |
101 end |
102 return html_template |
103 rescue Exception => ex |
104 $log.error("Error in creating report html template : #{ex}") |
105 exit |
106 end |
107 |
108 # Description : creates new html file holding complete execution summary |
109 # Author : Chandra sekaran |
110 # |
111 def create_main_report |
112 @html_template = create_html_template(@template_file_name) |
113 template_header = @html_template.at_css "div#cucumber-header" |
114 timestamp = Nokogiri::XML::Node.new("h4", @html_template) |
115 timestamp.inner_html = "Executed on #{$log_env.get_formatted_datetime($start_time)}" |
116 logo = Nokogiri::XML::Node.new("img", @html_template) |
117 h1 = @html_template.at_css "h1" |
118 |
119 br = Nokogiri::XML::Node.new("div", @html_template) |
120 br.inner_html="<br><br><br>" |
121 |
122 @table = Nokogiri::XML::Node.new("table", @html_template) |
123 |
124 row_size = @feature.size |
125 |
126 create_report_table_header |
127 |
128 @tot_feature = 0 |
129 @tot_scenario = 0 |
130 @tot_scenario_pass = 0 |
131 @tot_scenario_fail = 0 |
132 @tot_scenario_skip = 0 |
133 @tot_scenario_pending = 0 |
134 @tot_scenario_undefined = 0 |
135 @tot_step = 0 |
136 @tot_step_pass = 0 |
137 @tot_step_fail = 0 |
138 @tot_step_skip = 0 |
139 @tot_step_pending = 0 |
140 @tot_step_undefined = 0 |
141 |
142 for i in 1..row_size |
143 tr = Nokogiri::XML::Node.new("tr", @html_template) |
144 |
145 td = Nokogiri::XML::Node.new("td", @html_template) |
146 td.inner_html = "#{i}" |
147 tr.add_child(td) |
148 @tot_feature = i |
149 |
150 td = Nokogiri::XML::Node.new("td", @html_template) # for Feature ID |
151 td.inner_html = @arr_feature_id[i-1].gsub("@", "").to_s |
152 tr.add_child(td) |
153 |
154 td = Nokogiri::XML::Node.new("td", @html_template) # for Scenario ID |
155 td.inner_html = @arr_testcase_id[i-1].join(", ").to_s |
156 tr.add_child(td) |
157 |
158 td = Nokogiri::XML::Node.new("td", @html_template) |
159 td.inner_html = "<a href='detailed_report/#{@arr_html_file_name[i-1]}.html' target='_blank'>#{@feature[i-1]}</a>" |
160 tr.add_child(td) |
161 td['width'] = "40%" |
162 |
163 td = Nokogiri::XML::Node.new("td", @html_template) |
164 td.inner_html = "#{@scenario[i-1]}" |
165 tr.add_child(td) |
166 @tot_scenario += @scenario[i-1] |
167 |
168 td = Nokogiri::XML::Node.new("td", @html_template) |
169 num_pass_count = @scenario_pass[i-1] |
170 td.inner_html = "#{num_pass_count}" |
171 td['style'] = "background-color: #b0f9c3;" if num_pass_count > 0 # green color |
172 tr.add_child(td) |
173 @tot_scenario_pass += num_pass_count |
174 |
175 td = Nokogiri::XML::Node.new("td", @html_template) |
176 td.inner_html = "#{@scenario_fail[i-1]}" |
177 td['style'] = "background-color: #fbc8d5;" if @scenario_fail[i-1] > 0 # red color |
178 tr.add_child(td) |
179 @tot_scenario_fail += @scenario_fail[i-1] |
180 |
181 td = Nokogiri::XML::Node.new("td", @html_template) |
182 td.inner_html = "#{@scenario_skip[i-1]}" |
183 td['style'] = "background-color: #f2f9b0;" if @scenario_skip[i-1] > 0 # yellow color |
184 tr.add_child(td) |
185 @tot_scenario_skip += @scenario_skip[i-1] |
186 |
187 td = Nokogiri::XML::Node.new("td", @html_template) |
188 td.inner_html = "#{@scenario_pending[i-1]}" |
189 td['style'] = "background-color: #f2f9b0;" if @scenario_pending[i-1] > 0 # yellow color |
190 tr.add_child(td) |
191 @tot_scenario_pending += @scenario_pending[i-1] |
192 |
193 td = Nokogiri::XML::Node.new("td", @html_template) |
194 td.inner_html = "#{@scenario_undefined[i-1]}" |
195 td['style'] = "background-color: #f2f9b0;" if @scenario_undefined[i-1] > 0 # yellow color |
196 tr.add_child(td) |
197 @tot_scenario_undefined += @scenario_undefined[i-1] |
198 |
199 td = Nokogiri::XML::Node.new("td", @html_template) |
200 td.inner_html = "#{@step[i-1]}" |
201 tr.add_child(td) |
202 @tot_step += @step[i-1] |
203 |
204 td = Nokogiri::XML::Node.new("td", @html_template) |
205 td.inner_html = "#{@step_pass[i-1]}" |
206 td['style'] = "background-color: #b0f9c3;" if @step_pass[i-1] > 0 # green color |
207 tr.add_child(td) |
208 @tot_step_pass += @step_pass[i-1] |
209 |
210 td = Nokogiri::XML::Node.new("td", @html_template) |
211 td.inner_html = "#{@step_fail[i-1]}" |
212 td['style'] = "background-color: #fbc8d5;" if @step_fail[i-1] > 0 # red color |
213 tr.add_child(td) |
214 @tot_step_fail += @step_fail[i-1] |
215 |
216 td = Nokogiri::XML::Node.new("td", @html_template) |
217 td.inner_html = "#{@step_skip[i-1]}" |
218 td['style'] = "background-color: #f2f9b0;" if @step_skip[i-1] > 0 # yellow color |
219 tr.add_child(td) |
220 @tot_step_skip += @step_skip[i-1] |
221 |
222 td = Nokogiri::XML::Node.new("td", @html_template) |
223 td.inner_html = "#{@step_pending[i-1]}" |
224 td['style'] = "background-color: #f2f9b0;" if @step_pending[i-1] > 0 # yellow color |
225 tr.add_child(td) |
226 @tot_step_pending += @step_pending[i-1] |
227 |
228 td = Nokogiri::XML::Node.new("td", @html_template) |
229 td.inner_html = "#{@step_undefined[i-1]}" |
230 td['style'] = "background-color: #f2f9b0;" if @step_undefined[i-1] > 0 # yellow color |
231 tr.add_child(td) |
232 @tot_step_undefined += @step_undefined[i-1] |
233 |
234 td = Nokogiri::XML::Node.new("td", @html_template) |
235 td.inner_html = @scenario_fail[i-1] > 0 ? "Failed" : "Passed" |
236 td['style'] = @scenario_fail[i-1] > 0 ? "background-color: #fbc8d5;" : "background-color: #b0f9c3;" |
237 tr.add_child(td) |
238 |
239 @table.add_child(tr) |
240 end |
241 |
242 create_report_table_footer |
243 |
244 @table['style'] = "width:90%; font:13px;" |
245 10.times { template_header.add_next_sibling("<br>") } |
246 template_header.add_next_sibling(@table) |
247 template_header.add_child("<style type='text/css'>td, th {color: black; font: normal 11.5px 'Lucida Grande', Helvetica, sans-serif;} .left{margin-left:50px;margin-top:20px;margin-bottom:20px;font:bold 12.5px 'Lucida Grande',Helvetica,sans-serif;} .centr{font-size:200%;font-weight:bold;text-align:center;}</script>") |
248 @html_template.at('table')["border"] = 2 |
249 @html_template.at('table')["align"] = "center" |
250 |
251 # set report header background color |
252 if @tot_scenario_fail > 0 # for red color header |
253 template_header.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#c40d0d'); $('#cucumber-header').css('color', '#FFFFFF');</script>") |
254 elsif @tot_scenario_pending > 0 # for yellow color header |
255 template_header.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#f2f9b0'); $('#cucumber-header').css('color', '#000000');</script>") |
256 else # for green color header |
257 template_header.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#65c400'); $('#cucumber-header').css('color', '#FFFFFF');</script>") |
258 end |
259 |
260 @html_template.xpath("//div[@id='expand-collapse']").each do |t| |
261 t.replace(Nokogiri::XML::Node.new("p", @html_template)) # removes Collapse All & Expand All links |
262 end |
263 |
264 # style : .left{margin-left:50px;margin-top:20px;margin-bottom:20px;font:bold 12.5px 'Lucida Grande',Helvetica,sans-serif;} |
265 template_header.add_next_sibling("<div class='left' id='build_result'><b>Execution details : <b></div>") |
266 build_res = @html_template.at_css "div#build_result" |
267 get_execution_duration |
268 #@arr_json_report_file.each_with_index do |file, indx| |
269 # build_res.add_child("<div> Build - #{indx+1} duration : #{format_nonoseconds_to_time(arr_build_durations[indx])}</div>") |
270 #end |
271 build_res.add_child("<div> Total number of executions : #{@arr_json_report_file.size}</div>") |
272 build_res.add_child("<div> Total duration (DD:HH:MM:SS) : #{format_nonoseconds_to_time(@num_build_duration)}</div>") |
273 |
274 File.open("#{$current_log_dir}/custom_report/report_home.html", "w") do |f| |
275 f.write(@html_template) |
276 end |
277 rescue Exception => ex |
278 $log.error("Error in creating main html report : #{ex}") |
279 exit |
280 end |
281 |
282 # Description : creates new html files holding complete execution summary for each feature |
283 # Author : Chandra sekaran |
284 # Argument : |
285 # str_file_path : file path of the report file |
286 # |
287 def create_sub_report(str_file_path) |
288 @html_doc = Nokogiri::HTML(File.read(str_file_path)) |
289 br = Nokogiri::XML::Node.new("p", @html_doc) |
290 |
291 @html_doc.xpath("//div[@class='feature']").each_with_index do |f, index| |
292 @scenario_name = [] |
293 @num_step_count = [] |
294 @num_step_pass_count = [] |
295 @num_step_fail_count = [] |
296 @num_step_skip_count = [] |
297 @num_step_pending_count = [] |
298 @num_step_undefined_count = [] |
299 |
300 @html_template1 = create_html_template(@template_file_name) |
301 @html_template1.at('img')["src"] = "app_logo_1.png" # change the image file path for the sub-report files |
302 template_header1 = @html_template1.at_css "div#cucumber-header" |
303 |
304 @feature << f.xpath("./h2/span[@class='val']").text.gsub("Feature:", "") |
305 |
306 begin # for feature documentation header content |
307 pre_old = f.at_css "pre" |
308 f.xpath("./pre").each do |t| |
309 t.replace("<br><br><br><br><pre><font color='black'>") |
310 end |
311 font = f.at_css "font" |
312 font.add_child(pre_old) |
313 rescue Exception => ex |
314 end |
315 |
316 @scenario_skip_count = 0 |
317 |
318 cstep = 0 |
319 cstep_pass = 0 |
320 cstep_fail = 0 |
321 cstep_skip = 0 |
322 cstep_pending = 0 |
323 cstep_undefined = 0 |
324 |
325 bstep = 0 |
326 bstep_pass = 0 |
327 bstep_fail = 0 |
328 bstep_skip = 0 |
329 bstep_pending = 0 |
330 |
331 f.search("./div[@class='scenario']/h3").each do |s| |
332 @scenario_name << s.inner_text.strip |
333 end |
334 |
335 f.search("./div[@class='background']").each do |s| |
336 bstep = s.search(".//ol/li/div[@class='step_name']").size |
337 bstep_pass = s.search(".//ol/li[@class='step passed']").size |
338 bstep_fail = s.search(".//ol/li[@class='step failed']").size |
339 bstep_skip = s.search(".//ol/li[@class='step skipped']").size |
340 bstep_pending = s.search(".//ol/li[@class='step pending']").size |
341 end |
342 |
343 @scenario << f.search("./div[@class='scenario']").size |
344 tmp = [] |
345 break_count = true # for getting scenario ID of scenario that has failed in Background itself |
346 @pass_step_count = 0 |
347 @fail_step_count = 0 |
348 if bstep_fail > 0 |
349 f.search("./div[@class='scenario']").each_with_index do |s, indx| |
350 cstep += bstep |
351 cstep_fail = bstep_fail |
352 cstep_skip += bstep_skip |
353 cstep_pending += bstep_pending |
354 |
355 cstep += s.search(".//ol/li/div[@class='step_name']").size |
356 cstep_skip += s.search(".//ol/li[@class='step skipped']").size |
357 cstep_pending += s.search(".//ol/li[@class='step pending']").size |
358 |
359 @num_step_count << s.search(".//ol/li/div[@class='step_name']").size + bstep |
360 @num_step_fail_count << bstep_fail |
361 @num_step_skip_count << s.search(".//ol/li[@class='step skipped']").size |
362 @num_step_pending_count << s.search(".//ol/li[@class='step pending']").size |
363 @num_step_undefined_count << s.search(".//ol/li[@class='step undefined']").size |
364 |
365 if s.search(".//ol/li/div[@class='step_name']").size == s.search(".//ol/li[@class='step skipped']").size |
366 @scenario_skip_count += 1 |
367 elsif (s.search(".//ol/li/div[@class='step_name']").size - s.search(".//ol/li[@class='step skipped']").size) > 0 |
368 @scenario_skip_count += 1 |
369 end |
370 |
371 # setting colors for the scenario IDs under the feature |
372 s.search("./span[@class='tag'][1]").each do |tag| |
373 if cstep_fail >= 1 && break_count |
374 tmp << "<span style='color:red'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>" |
375 break_count = false |
376 @fail_step_count += 1 |
377 elsif s.search(".//ol/li[@class='step skipped']").size >= 1 |
378 tmp << "<span style='color:#B0A914'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>" |
379 else |
380 tmp << "<span style='color:green'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>" |
381 end |
382 end |
383 end |
384 scenario_undefined_count = 0 |
385 else |
386 scenario_undefined_count = 0 |
387 f.search("./div[@class='scenario']").each_with_index do |s, indx| |
388 cstep += bstep |
389 cstep_pass += bstep_pass |
390 cstep_fail += bstep_fail |
391 cstep_skip += bstep_skip |
392 cstep_pending += bstep_pending |
393 |
394 cstep += s.search(".//ol/li/div[@class='step_name']").size |
395 cstep_pass += s.search(".//ol/li[@class='step passed']").size |
396 cstep_fail += s.search(".//ol/li[@class='step failed']").size |
397 cstep_skip += s.search(".//ol/li[@class='step skipped']").size |
398 cstep_pending += s.search(".//ol/li[@class='step pending']").size |
399 cstep_undefined += s.search(".//ol/li[@class='step undefined']").size |
400 |
401 @num_step_count << s.search(".//ol/li/div[@class='step_name']").size + bstep |
402 @num_step_pass_count << s.search(".//ol/li[@class='step passed']").size + bstep_pass |
403 @num_step_fail_count << s.search(".//ol/li[@class='step failed']").size |
404 @num_step_skip_count << s.search(".//ol/li[@class='step skipped']").size |
405 @num_step_pending_count << s.search(".//ol/li[@class='step pending']").size |
406 @num_step_undefined_count << s.search(".//ol/li[@class='step undefined']").size |
407 |
408 # setting colors for the scenario IDs under the feature |
409 s.search("./span[@class='tag'][1]").each do |tag| |
410 if s.search(".//ol/li[@class='step failed']").size >= 1 |
411 tmp << "<span style='color:red'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>" |
412 @fail_step_count += 1 |
413 elsif s.search(".//ol/li[@class='step skipped']").size >= 1 |
414 tmp << "<span style='color:#B0A914'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>" |
415 else |
416 tmp << "<span style='color:green'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>" |
417 end |
418 end |
419 if s.search(".//ol/li[@class='step undefined']").size > 0 |
420 scenario_undefined_count += 1 if s.search(".//ol/li[@class='step failed']").size == 0 |
421 end |
422 if s.search(".//ol/li/div[@class='step_name']").size == s.search(".//ol/li[@class='step passed']").size |
423 @pass_step_count += 1 |
424 end |
425 end |
426 end |
427 |
428 # for getting the feature ID |
429 f.search("./span[@class='tag']").each do |tag| |
430 if tag.inner_text.include? FEATURE_ID_PREFIX |
431 if cstep_fail >= 1 |
432 @arr_feature_id << "<span style='color:red'>#{tag.inner_text.gsub(FEATURE_ID_PREFIX, "")}</span>" |
433 elsif cstep_pending >= 1 |
434 @arr_feature_id << "<span style='color:#B0A914'>#{tag.inner_text.gsub(FEATURE_ID_PREFIX, "")}</span>" |
435 else |
436 @arr_feature_id << "<span style='color:green'>#{tag.inner_text.gsub(FEATURE_ID_PREFIX, "")}</span>" |
437 end |
438 end |
439 end |
440 |
441 @scenario_pass << @pass_step_count |
442 @scenario_fail << @fail_step_count |
443 |
444 @step << cstep |
445 @step_pass << cstep_pass |
446 @step_fail << cstep_fail |
447 @step_skip << cstep_skip |
448 @step_pending << cstep_pending |
449 |
450 if @scenario_skip_count - 1 < 0 |
451 @scenario_skip << 0 |
452 else |
453 @scenario_skip << @scenario_skip_count - 1 |
454 end |
455 @scenario_pending << cstep_pending |
456 @step_undefined << cstep_undefined |
457 @scenario_undefined << scenario_undefined_count |
458 |
459 @arr_testcase_id << tmp |
460 |
461 feature_name = f.xpath("./div[@class='scenario']/span[@class='scenario_file']").inner_text.strip |
462 arr_feature_file_path = format_file_path(feature_name).split("/") |
463 str_feature_name = arr_feature_file_path.pop.split(".").first |
464 arr_feature_folder_name = arr_feature_file_path.pop(2) |
465 html_file_name = "#{arr_feature_folder_name[0]}_#{str_feature_name}" # add stage name with fetaure file name |
466 @arr_html_file_name << html_file_name |
467 |
468 # table that summarises steps results for each scenario in the child html pages |
469 @scenario_table = Nokogiri::XML::Node.new("table", @html_template1) |
470 create_child_report_table_header |
471 |
472 for i in 1..@scenario_name.size |
473 tr = Nokogiri::XML::Node.new("tr", @html_template1) |
474 |
475 td = Nokogiri::XML::Node.new("td", @html_template1) |
476 td.inner_html = "#{i}" |
477 tr.add_child(td) |
478 |
479 td = Nokogiri::XML::Node.new("td", @html_template1) # for Scenario ID |
480 td.inner_html = tmp[i-1].to_s |
481 tr.add_child(td) |
482 |
483 td = Nokogiri::XML::Node.new("td", @html_template1) |
484 td.inner_html = @scenario_name[i-1].gsub("Scenario:", "").to_s |
485 tr.add_child(td) |
486 td["width"] = "40%" |
487 |
488 td = Nokogiri::XML::Node.new("td", @html_template1) |
489 td.inner_html = @num_step_count[i-1].to_s |
490 tr.add_child(td) |
491 |
492 td = Nokogiri::XML::Node.new("td", @html_template1) |
493 td.inner_html = @num_step_pass_count[i-1].to_s |
494 td['style'] = "background-color: #b0f9c3;" if @num_step_pass_count[i-1] > 0 # green color |
495 tr.add_child(td) |
496 |
497 td = Nokogiri::XML::Node.new("td", @html_template1) |
498 td.inner_html = @num_step_fail_count[i-1].to_s |
499 td['style'] = "background-color: #fbc8d5;" if @num_step_fail_count[i-1] > 0 # red color |
500 tr.add_child(td) |
501 |
502 td = Nokogiri::XML::Node.new("td", @html_template1) |
503 td.inner_html = @num_step_skip_count[i-1].to_s |
504 td['style'] = "background-color: #f2f9b0;" if @num_step_skip_count[i-1] > 0 # yellow color |
505 tr.add_child(td) |
506 |
507 td = Nokogiri::XML::Node.new("td", @html_template1) |
508 td.inner_html = @num_step_pending_count[i-1].to_s |
509 td['style'] = "background-color: #f2f9b0;" if @num_step_pending_count[i-1] > 0 # yellow color |
510 tr.add_child(td) |
511 |
512 td = Nokogiri::XML::Node.new("td", @html_template1) |
513 td.inner_html = @num_step_undefined_count[i-1].to_s |
514 td['style'] = "background-color: #f2f9b0;" if @num_step_undefined_count[i-1] > 0 # yellow color |
515 tr.add_child(td) |
516 |
517 td = Nokogiri::XML::Node.new("td", @html_template1) |
518 td.inner_html = @num_step_fail_count[i-1] > 0 ? "Failed" : "Passed" |
519 td['style'] = @num_step_fail_count[i-1] > 0 ? "background-color: #fbc8d5;" : "background-color: #b0f9c3;" |
520 tr.add_child(td) |
521 |
522 @scenario_table.add_child(tr) |
523 end |
524 create_child_report_table_footer |
525 @scenario_table['style'] = "width:80%; font:13px;" |
526 template_header1.add_next_sibling(@scenario_table) |
527 template_header1.add_child("<style type='text/css'>td, th {color: black; font: normal 11.5px 'Lucida Grande', Helvetica, sans-serif;}</script>") |
528 @html_template1.at('table')["border"] = 2 |
529 @html_template1.at('table')["align"] = "center" |
530 font = f.at_css "font" |
531 font.add_next_sibling(@scenario_table) |
532 |
533 # try to add report table next to the feature title |
534 #feature_header = @html_template1.at_xpath("//div[@id='cucumber-header']/div[3]/div[1]") |
535 ##feature_header.add_next_sibling(@scenario_table) |
536 #@html_template1.xpath("//div[@id='cucumber-header']/div[3]/div[1]").each do |t| |
537 # t.add_previous_sibling(@scenario_table) |
538 #end |
539 #@html_template1.at('table')["border"] = 2 |
540 #@html_template1.at('table')["align"] = "center" |
541 |
542 |
543 template_header1.add_child(f) # add scenario with its steps as it is from cucumber report for this particular feature |
544 6.times { template_header1.add_child("<br>") } |
545 h2 = @html_template1.at_css "h2" |
546 h2["style"] = "color: black;" |
547 failed_step = @html_template1.at_css("//li[@class='step failed']") |
548 if !failed_step.nil? |
549 template_header1.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#C40D0D'); $('#cucumber-header').css('color', '#FFFFFF');</script>") |
550 end |
551 template_header1.xpath("//div[@id='label']/div").each do |t| |
552 t.replace("<h1>#{html_file_name.gsub("_", " ").split.map(&:capitalize).join(' ')} - DETAILED REPORT</h1>") |
553 end |
554 template_header1.xpath("//div[@id='summary']/p[@id='duration']").each do |t| |
555 t.replace("<p>") # remove duration fiels from cucumber report header |
556 end |
557 |
558 template_header1.add_child("<style type='text/css'>td, th {color: black; font: normal 11.5px 'Lucida Grande', Helvetica, sans-serif;}</script>") |
559 |
560 File.open("#{$current_log_dir}/custom_report/detailed_report/#{html_file_name}.html", "w") do |file| |
561 file.write(@html_template1) |
562 end |
563 end |
564 @html_doc.xpath("//div[@class='feature']/div[@class='scenario']").each do |n| |
565 n.replace(br) |
566 end |
567 rescue Exception => ex |
568 $log.error("Error in creating sub report html : #{ex}") |
569 exit |
570 end |
571 |
572 # Description : creates header for report table |
573 # Author : Chandra sekaran |
574 # |
575 def create_report_table_header |
576 arr_table_header = ["Sr No","Feature ID","Scenario ID","Feature","Total","Passed","Failed","Skipped","Pending","Undefined","Total","Passed","Failed","Skipped","Pending","Undefined","Result"] |
577 |
578 tr = Nokogiri::XML::Node.new("tr", @html_template) |
579 5.times do |col| |
580 td = Nokogiri::XML::Node.new("td", @html_template) |
581 case col |
582 when 1 |
583 td["colspan"] = "3" |
584 when 2 |
585 td["colspan"] = "6" |
586 td.inner_html = "<b>Scenarios</b>" |
587 td['align'] = "center" |
588 when 3 |
589 td["colspan"] = "6" |
590 td.inner_html = "<b>Steps</b>" |
591 td['align'] = "center" |
592 end |
593 td['style'] = "background-color: #d3ecfc;" |
594 tr.add_child(td) |
595 end |
596 @table.add_child(tr) |
597 |
598 tr = Nokogiri::XML::Node.new("tr", @html_template) |
599 arr_table_header.each do |str_header| |
600 th = Nokogiri::XML::Node.new("th", @html_template) |
601 th.inner_html = "<b>#{str_header}</b>" |
602 th['style'] = "background-color: #d3ecfc;" # light blue color |
603 th["font"] = "size: 15px;" |
604 tr.add_child(th) |
605 end |
606 @table.add_child(tr) |
607 rescue Exception => ex |
608 $log.error("Error while creating report table header : #{ex}") |
609 exit |
610 end |
611 |
612 # Description : creates footer for report table |
613 # Author : Chandra sekaran |
614 # |
615 def create_report_table_footer |
616 tr = Nokogiri::XML::Node.new("tr", @html_template) |
617 17.times do |col| |
618 td = Nokogiri::XML::Node.new("td", @html_template) |
619 case col |
620 when 3 |
621 td.inner_html = "<b>Total<b>" |
622 td["align"] = "right" |
623 when 4 |
624 td.inner_html = "<b>#{@tot_scenario.to_s}</b>" |
625 when 5 |
626 td.inner_html = "<b>#{@tot_scenario_pass.to_s}</b>" |
627 when 6 |
628 td.inner_html = "<b>#{@tot_scenario_fail.to_s}</b>" |
629 when 7 |
630 td.inner_html = "<b>#{@tot_scenario_skip.to_s}</b>" |
631 when 8 |
632 td.inner_html = "<b>#{@tot_scenario_pending.to_s}</b>" |
633 when 9 |
634 td.inner_html = "<b>#{@tot_scenario_undefined.to_s}</b>" |
635 when 10 |
636 td.inner_html = "<b>#{@tot_step.to_s}</b>" |
637 when 11 |
638 td.inner_html = "<b>#{@tot_step_pass.to_s}<b>" |
639 when 12 |
640 td.inner_html = "<b>#{@tot_step_fail.to_s}</b>" |
641 when 13 |
642 td.inner_html = "<b>#{@tot_step_skip.to_s}</b>" |
643 when 14 |
644 td.inner_html = "<b>#{@tot_step_pending.to_s}</b>" |
645 when 15 |
646 td.inner_html = "<b>#{@tot_step_undefined.to_s}</b>" |
647 end |
648 td['style'] = "background-color: #d3ecfc;" |
649 tr.add_child(td) |
650 end |
651 @table.add_child(tr) |
652 rescue Exception => ex |
653 $log.error("Error while creating report table footer : #{ex}") |
654 exit |
655 end |
656 |
657 # Description : creates footer for report table for child pages |
658 # Author : Chandra sekaran |
659 # |
660 def create_child_report_table_footer |
661 begin |
662 tr = Nokogiri::XML::Node.new("tr", @html_template1) |
663 10.times do |col| |
664 td = Nokogiri::XML::Node.new("td", @html_template1) |
665 case col |
666 when 2 |
667 td.inner_html = "<b>Total<b>" |
668 td["align"] = "right" |
669 when 3 |
670 td.inner_html = "<b>#{@num_step_count.inject(:+).to_s}</b>" |
671 when 4 |
672 td.inner_html = "<b>#{@num_step_pass_count.inject(:+).to_s}</b>" |
673 when 5 |
674 td.inner_html = "<b>#{@num_step_fail_count.inject(:+).to_s}</b>" |
675 when 6 |
676 td.inner_html = "<b>#{@num_step_skip_count.inject(:+).to_s}</b>" |
677 when 7 |
678 td.inner_html = "<b>#{@num_step_pending_count.inject(:+).to_s}</b>" |
679 when 8 |
680 td.inner_html = "<b>#{@num_step_undefined_count.inject(:+).to_s}</b>" |
681 end |
682 td['style'] = "background-color: #d3ecfc;" |
683 tr.add_child(td) |
684 end |
685 @scenario_table.add_child(tr) |
686 rescue Exception => ex |
687 $log.error("Error while creating report table footer (for child pages): #{ex}") |
688 exit |
689 end |
690 end |
691 |
692 # Description : creates header for report table for child pages |
693 # Author : Chandra sekaran |
694 # |
695 def create_child_report_table_header |
696 begin |
697 arr_table_header = ["Sr No","Scenario ID","Scenario Title","Total","Passed","Failed","Skipped","Pending","Undefined","Result"] |
698 tr = Nokogiri::XML::Node.new("tr", @html_template1) |
699 4.times do |col| |
700 td = Nokogiri::XML::Node.new("td", @html_template1) |
701 case col |
702 when 1 |
703 td["colspan"] = "2" |
704 when 2 |
705 td["colspan"] = "6" |
706 td.inner_html = "<b>Steps</b>" |
707 td['align'] = "center" |
708 end |
709 td['style'] = "background-color: #d3ecfc;" |
710 tr.add_child(td) |
711 end |
712 @scenario_table.add_child(tr) |
713 tr = Nokogiri::XML::Node.new("tr", @html_template1) |
714 arr_table_header.each do |str_header| |
715 th = Nokogiri::XML::Node.new("th", @html_template1) |
716 th.inner_html = "<b>#{str_header}</b>" |
717 th['style'] = "background-color: #d3ecfc;" # light blue color |
718 th["font"] = "size: 15px;" |
719 tr.add_child(th) |
720 end |
721 @scenario_table.add_child(tr) |
722 rescue Exception => ex |
723 $log.error("Error while creating report table header for child pages : #{ex}") |
724 exit |
725 end |
726 end |
727 |
728 # Description : creates new custome html report files |
729 # Author : Chandra sekaran |
730 # |
731 def create_custom_report |
732 create_report_directory |
733 @arr_file_name.each do |path| # move screenshot directory |
734 path = format_file_path(path) |
735 arr = path.split("/") |
736 arr.pop # remove the html file name |
737 path = arr.join("/") |
738 Dir.glob(path).each do |file| |
739 if File.directory?("#{file}/screenshot") # check if screenshot directory exists else create a new one and copy it to the recent log directory |
740 create_directory("#{$current_log_dir}/custom_report/detailed_report/screenshot") |
741 FileUtils.cp Dir["#{File.expand_path(file)}/screenshot/*.png"], "#{$current_log_dir}/custom_report/detailed_report/screenshot" |
742 end |
743 end |
744 end |
745 @arr_file_name.each do |path| # create sub report |
746 create_sub_report(path) |
747 end |
748 create_main_report # create consolidated home report file |
749 $log.success("Custom html report file has been generated successfully") |
750 rescue Exception => ex |
751 $log.error("Error in creating custom html report : #{ex}") |
752 exit |
753 end |
754 |
755 # Description : gets the total execution duration with input data from json report file |
756 # Author : Chandra sekaran |
757 # Return argument : |
758 # arr_build_durations : total execution time in nanoseconds |
759 # |
760 def get_execution_duration |
761 @arr_json_report_file = get_files_absolute_path("test_result", "json", $start_time - $world.get_execution_delay_time.seconds) |
762 $log.info("#{@arr_json_report_file}") |
763 @num_build_duration = 0 |
764 |
765 arr_build_durations = [] |
766 |
767 @arr_json_report_file.each do |path| |
768 @arr_background_step_duration = [] |
769 file = File.read(path) |
770 @json = JSON.parse(file) |
771 arr_build_durations << parse_json # parse each json file and extract report data |
772 end |
773 arr_build_durations |
774 end |
775 |
776 # Description : parses the json file and calculates the total execution duration |
777 # Author : Chandra sekaran |
778 # Return argument : |
779 # feature_duration : total execution time for each execution in nanoseconds |
780 # |
781 def parse_json |
782 feature_duration = 0 |
783 scenario_duration = 0 |
784 step_duration = 0 |
785 @json.each_with_index do |json, index| # iterate each feature |
786 feature_duration = 0 |
787 json["elements"].each do |element| |
788 # for including the first background steps duration to the first scenario background steps as Cucumber json |
789 # report considers background for the first scenario and hence will have 0 duration for the background steps |
790 # under first scenario and the actual duration for the background will be set for the subsequent scenarios |
791 if index == 0 |
792 if element["keyword"] == "Background" |
793 element["steps"].each do |step| |
794 @arr_background_step_duration << step["result"]["duration"].to_i |
795 @bool = true |
796 end |
797 end |
798 end |
799 if element["keyword"] == "Scenario" # take scenario for scenario level details |
800 scenario_duration = 0 |
801 element["steps"].each_with_index do |step, indx| # iterate each steps of the current scenario |
802 step_duration = 0 |
803 if (index == 0) && (indx < @arr_background_step_duration.size) && @bool |
804 step_duration = @arr_background_step_duration[indx] # take duration from Background for the first scenario |
805 else |
806 step_duration = step["result"]["duration"].to_i # take usual duration |
807 @bool = false |
808 end |
809 scenario_duration += step_duration |
810 end |
811 feature_duration += scenario_duration |
812 end |
813 end |
814 @num_build_duration += feature_duration |
815 end |
816 feature_duration |
817 rescue Exception => ex |
818 $log.error("Error while parsing JSON : #{ex}") |
819 exit |
820 end |
821 end |
822 end |
Generated on 2015-05-08 10:40:30 +0530 with SimpleCov-RCov 0.2.3