# File lib/cucumber/formatter/html.rb, line 13 13: def initialize(step_mother, path_or_io, options) 14: @io = ensure_io(path_or_io, "html") 15: @step_mother = step_mother 16: @options = options 17: @buffer = {} 18: @builder = create_builder(@io) 19: @feature_number = 0 20: @scenario_number = 0 21: @step_number = 0 22: @header_red = nil 23: end
# File lib/cucumber/formatter/html.rb, line 136 136: def after_background(background) 137: @in_background = nil 138: @builder << '</div>' 139: end
# File lib/cucumber/formatter/html.rb, line 98 98: def after_comment(comment) 99: @builder << '</pre>' 100: end
# File lib/cucumber/formatter/html.rb, line 188 188: def after_examples(examples) 189: @builder << '</div>' 190: end
# File lib/cucumber/formatter/html.rb, line 90 90: def after_feature(feature) 91: @builder << '</div>' 92: end
# File lib/cucumber/formatter/html.rb, line 160 160: def after_feature_element(feature_element) 161: @builder << '</div>' 162: @open_step_list = true 163: end
# File lib/cucumber/formatter/html.rb, line 78 78: def after_features(features) 79: print_stats(features) 80: @builder << '</div>' 81: @builder << '</body>' 82: @builder << '</html>' 83: end
# File lib/cucumber/formatter/html.rb, line 277 277: def after_multiline_arg(multiline_arg) 278: return if @hide_this_step || @skip_step 279: if Ast::Table === multiline_arg 280: @builder << '</table>' 281: end 282: end
# File lib/cucumber/formatter/html.rb, line 179 179: def after_outline_table(outline_table) 180: @builder << '</table>' 181: @outline_row = nil 182: end
# File lib/cucumber/formatter/html.rb, line 214 214: def after_step(step) 215: move_progress 216: end
# File lib/cucumber/formatter/html.rb, line 238 238: def after_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background) 239: return if @hide_this_step 240: # print snippet for undefined steps 241: if status == :undefined 242: step_multiline_class = @step.multiline_arg ? @step.multiline_arg.class : nil 243: @builder.pre do |pre| 244: pre << @step_mother.snippet_text(@step.actual_keyword,step_match.instance_variable_get("@name") || '',step_multiline_class) 245: end 246: end 247: @builder << '</li>' 248: end
# File lib/cucumber/formatter/html.rb, line 204 204: def after_steps(steps) 205: @builder << '</ol>' 206: end
# File lib/cucumber/formatter/html.rb, line 299 299: def after_table_row(table_row) 300: return if @hide_this_step 301: @builder << '</tr>' 302: if table_row.exception 303: @builder.tr do 304: @builder.td(:colspan => @col_index.to_s, :class => 'failed') do 305: @builder.pre do |pre| 306: pre << format_exception(table_row.exception) 307: end 308: end 309: end 310: set_scenario_color_failed 311: end 312: if @outline_row 313: @outline_row += 1 314: end 315: @step_number += 1 316: move_progress 317: end
# File lib/cucumber/formatter/html.rb, line 330 330: def announce(announcement) 331: @builder.pre(announcement, :class => 'announcement') 332: end
# File lib/cucumber/formatter/html.rb, line 141 141: def background_name(keyword, name, file_colon_line, source_indent) 142: @listing_background = true 143: @builder.h3 do |h3| 144: @builder.span(keyword, :class => 'keyword') 145: @builder.text!(' ') 146: @builder.span(name, :class => 'val') 147: end 148: end
# File lib/cucumber/formatter/html.rb, line 131 131: def before_background(background) 132: @in_background = true 133: @builder << '<div class="background">' 134: end
# File lib/cucumber/formatter/html.rb, line 94 94: def before_comment(comment) 95: @builder << '<pre class="comment">' 96: end
# File lib/cucumber/formatter/html.rb, line 184 184: def before_examples(examples) 185: @builder << '<div class="examples">' 186: end
# File lib/cucumber/formatter/html.rb, line 85 85: def before_feature(feature) 86: @exceptions = [] 87: @builder << '<div class="feature">' 88: end
# File lib/cucumber/formatter/html.rb, line 150 150: def before_feature_element(feature_element) 151: @scenario_number+=1 152: @scenario_red = false 153: css_class = { 154: Ast::Scenario => 'scenario', 155: Ast::ScenarioOutline => 'scenario outline' 156: }[feature_element.class] 157: @builder << "<div class='#{css_class}'>" 158: end
# File lib/cucumber/formatter/html.rb, line 41 41: def before_features(features) 42: @step_count = get_step_count(features) 43: 44: # <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 45: @builder.declare!( 46: :DOCTYPE, 47: :html, 48: :PUBLIC, 49: '-//W3C//DTD XHTML 1.0 Strict//EN', 50: 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd' 51: ) 52: 53: @builder << '<html xmlns ="http://www.w3.org/1999/xhtml">' 54: @builder.head do 55: @builder.meta(:content => 'text/html;charset=utf-8') 56: @builder.title 'Cucumber' 57: inline_css 58: inline_js 59: end 60: @builder << '<body>' 61: @builder << "<!-- Step count #{@step_count}-->" 62: @builder << '<div class="cucumber">' 63: @builder.div(:id => 'cucumber-header') do 64: @builder.div(:id => 'label') do 65: @builder.h1('Cucumber Features') 66: end 67: @builder.div(:id => 'summary') do 68: @builder.p('',:id => 'totals') 69: @builder.p('',:id => 'duration') 70: @builder.div(:id => 'expand-collapse') do 71: @builder.p('Expand All', :id => 'expander') 72: @builder.p('Collapse All', :id => 'collapser') 73: end 74: end 75: end 76: end
# File lib/cucumber/formatter/html.rb, line 270 270: def before_multiline_arg(multiline_arg) 271: return if @hide_this_step || @skip_step 272: if Ast::Table === multiline_arg 273: @builder << '<table>' 274: end 275: end
# File lib/cucumber/formatter/html.rb, line 174 174: def before_outline_table(outline_table) 175: @outline_row = 0 176: @builder << '<table>' 177: end
# File lib/cucumber/formatter/html.rb, line 208 208: def before_step(step) 209: @step_id = step.dom_id 210: @step_number += 1 211: @step = step 212: end
# File lib/cucumber/formatter/html.rb, line 218 218: def before_step_result(keyword, step_match, multiline_arg, status, exception, source_indent, background) 219: @step_match = step_match 220: @hide_this_step = false 221: if exception 222: if @exceptions.include?(exception) 223: @hide_this_step = true 224: return 225: end 226: @exceptions << exception 227: end 228: if status != :failed && @in_background ^ background 229: @hide_this_step = true 230: return 231: end 232: @status = status 233: return if @hide_this_step 234: set_scenario_color(status) 235: @builder << "<li id='#{@step_id}' class='step #{status}'>" 236: end
# File lib/cucumber/formatter/html.rb, line 200 200: def before_steps(steps) 201: @builder << '<ol>' 202: end
# File lib/cucumber/formatter/html.rb, line 292 292: def before_table_row(table_row) 293: @row_id = table_row.dom_id 294: @col_index = 0 295: return if @hide_this_step 296: @builder << "<tr class='step' id='#{@row_id}'>" 297: end
# File lib/cucumber/formatter/html.rb, line 25 25: def embed(file, mime_type) 26: case(mime_type) 27: when /^image\/(png|gif|jpg|jpeg)/ 28: embed_image(file) 29: end 30: end
# File lib/cucumber/formatter/html.rb, line 32 32: def embed_image(file) 33: id = file.hash 34: @builder.span(:class => 'embed') do |pre| 35: pre << %{<a href="" onclick="img=document.getElementById('#{id}'); img.style.display = (img.style.display == 'none' ? 'block' : 'none');return false">Screenshot</a><br> 36: <img id="#{id}" style="display: none" src="#{file}"/>} 37: end 38: end
# File lib/cucumber/formatter/html.rb, line 192 192: def examples_name(keyword, name) 193: @builder.h4 do 194: @builder.span(keyword, :class => 'keyword') 195: @builder.text!(' ') 196: @builder.span(name, :class => 'val') 197: end 198: end
# File lib/cucumber/formatter/html.rb, line 261 261: def exception(exception, status) 262: build_exception_detail(exception) 263: end
# File lib/cucumber/formatter/html.rb, line 265 265: def extra_failure_content(file_colon_line) 266: @snippet_extractor ||= SnippetExtractor.new 267: "<pre class=\"ruby\"><code>#{@snippet_extractor.snippet(file_colon_line)}</code></pre>" 268: end
# File lib/cucumber/formatter/html.rb, line 117 117: def feature_name(keyword, name) 118: lines = name.split(/\r?\n/) 119: return if lines.empty? 120: @builder.h2 do |h2| 121: @builder.span(keyword + ': ' + lines[0], :class => 'val') 122: end 123: @builder.p(:class => 'narrative') do 124: lines[1..1].each do |line| 125: @builder.text!(line.strip) 126: @builder.br 127: end 128: end 129: end
# File lib/cucumber/formatter/html.rb, line 284 284: def py_string(string) 285: return if @hide_this_step 286: @builder.pre(:class => 'val') do |pre| 287: @builder << string.gsub("\n", '
') 288: end 289: end
# File lib/cucumber/formatter/html.rb, line 165 165: def scenario_name(keyword, name, file_colon_line, source_indent) 166: @listing_background = false 167: @builder.h3(:id => "scenario_#{@scenario_number}") do 168: @builder.span(keyword + ':', :class => 'keyword') 169: @builder.text!(' ') 170: @builder.span(name, :class => 'val') 171: end 172: end
# File lib/cucumber/formatter/html.rb, line 250 250: def step_name(keyword, step_match, status, source_indent, background) 251: @step_matches ||= [] 252: background_in_scenario = background && !@listing_background 253: @skip_step = @step_matches.index(step_match) || background_in_scenario 254: @step_matches << step_match 255: 256: unless @skip_step 257: build_step(keyword, step_match, status) 258: end 259: end
# File lib/cucumber/formatter/html.rb, line 319 319: def table_cell_value(value, status) 320: return if @hide_this_step 321: 322: @cell_type = @outline_row == 0 ? :th : :td 323: attributes = {:id => "#{@row_id}_#{@col_index}", :class => 'step'} 324: attributes[:class] += " #{status}" if status 325: build_cell(@cell_type, value, attributes) 326: set_scenario_color(status) 327: @col_index += 1 328: end
# File lib/cucumber/formatter/html.rb, line 525 525: def backtrace_line(line) 526: line.gsub(/^([^:]*\.(?:rb|feature|haml)):(\d*)/) do 527: if ENV['TM_PROJECT_DIRECTORY'] 528: "<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> " 529: else 530: line 531: end 532: end 533: end
# File lib/cucumber/formatter/html.rb, line 447 447: def build_cell(cell_type, value, attributes) 448: @builder.__send__(cell_type, attributes) do 449: @builder.div do 450: @builder.span(value,:class => 'step param') 451: end 452: end 453: end
# File lib/cucumber/formatter/html.rb, line 336 336: def build_exception_detail(exception) 337: backtrace = Array.new 338: @builder.div(:class => 'message') do 339: message = exception.message 340: if defined?(RAILS_ROOT) && message.include?('Exception caught') 341: matches = message.match(/Showing <i>(.+)<\/i>(?:.+)#(\d+)/) 342: backtrace += ["#{RAILS_ROOT}/#{matches[1]}:#{matches[2]}"] 343: message = message.match(/<code>([^(\/)]+)<\//)[1] 344: end 345: @builder.pre do 346: @builder.text!(message) 347: end 348: end 349: @builder.div(:class => 'backtrace') do 350: @builder.pre do 351: backtrace = exception.backtrace 352: backtrace.delete_if { |x| x =~ /\/gems\/(cucumber|rspec)/ } 353: @builder << backtrace_line(backtrace.join("\n")) 354: end 355: end 356: extra = extra_failure_content(backtrace) 357: @builder << extra unless extra == "" 358: end
# File lib/cucumber/formatter/html.rb, line 424 424: def build_step(keyword, step_match, status) 425: step_name = step_match.format_args(lambda{|param| %{<span class="param">#{param}</span>}}) 426: @builder.div(:class => 'step_name') do |div| 427: @builder.span(keyword, :class => 'keyword') 428: @builder.span(:class => 'step val') do |name| 429: name << h(step_name).gsub(/<span class="(.*?)">/, '<span class="\1">').gsub(/<\/span>/, '</span>') 430: end 431: end 432: 433: step_file = step_match.file_colon_line 434: step_file.gsub(/^([^:]*\.rb):(\d*)/) do 435: if ENV['TM_PROJECT_DIRECTORY'] 436: step_file = "<a href=\"txmt://open?url=file://#{File.expand_path($1)}&line=#{$2}\">#{$1}:#{$2}</a> " 437: end 438: end 439: 440: @builder.div(:class => 'step_file') do |div| 441: @builder.span do 442: @builder << step_file 443: end 444: end 445: end
# File lib/cucumber/formatter/html.rb, line 563 563: def create_builder(io) 564: OrderedXmlMarkup.new(:target => io, :indent => 0) 565: end
# File lib/cucumber/formatter/html.rb, line 559 559: def dump_count(count, what, state=nil) 560: [count, state, "#{what}#{count == 1 ? '' : 's'}"].compact.join(" ") 561: end
# File lib/cucumber/formatter/html.rb, line 521 521: def format_exception(exception) 522: (["#{exception.message}"] + exception.backtrace).join("\n") 523: end
# File lib/cucumber/formatter/html.rb, line 385 385: def get_step_count(features) 386: count = 0 387: features = features.instance_variable_get("@features") 388: features.each do |feature| 389: #get background steps 390: if feature.instance_variable_get("@background") 391: background = feature.instance_variable_get("@background") 392: background.init 393: background_steps = background.instance_variable_get("@steps").instance_variable_get("@steps") 394: count += background_steps.size 395: end 396: #get scenarios 397: feature.instance_variable_get("@feature_elements").each do |scenario| 398: scenario.init 399: #get steps 400: steps = scenario.instance_variable_get("@steps").instance_variable_get("@steps") 401: count += steps.size 402: 403: #get example table 404: examples = scenario.instance_variable_get("@examples_array") 405: unless examples.nil? 406: examples.each do |example| 407: example_matrix = example.instance_variable_get("@outline_table").instance_variable_get("@cell_matrix") 408: count += example_matrix.size 409: end 410: end 411: 412: #get multiline step tables 413: steps.each do |step| 414: multi_arg = step.instance_variable_get("@multiline_arg") 415: next if multi_arg.nil? 416: matrix = multi_arg.instance_variable_get("@cell_matrix") 417: count += matrix.size unless matrix.nil? 418: end 419: end 420: end 421: return count 422: end
# File lib/cucumber/formatter/html.rb, line 455 455: def inline_css 456: @builder.style(:type => 'text/css') do 457: @builder << File.read(File.dirname(__FILE__) + '/cucumber.css') 458: end 459: end
# File lib/cucumber/formatter/html.rb, line 468 468: def inline_jquery 469: File.read(File.dirname(__FILE__) + '/jquery-min.js') 470: end
# File lib/cucumber/formatter/html.rb, line 461 461: def inline_js 462: @builder.script(:type => 'text/javascript') do 463: @builder << inline_jquery 464: @builder << inline_js_content 465: end 466: end
# File lib/cucumber/formatter/html.rb, line 472 472: def inline_js_content 473: SCENARIOS = "h3[id^='scenario_']"; $(document).ready(function() { $(SCENARIOS).css('cursor', 'pointer'); $(SCENARIOS).click(function() { $(this).siblings().toggle(250); }); $("#collapser").css('cursor', 'pointer'); $("#collapser").click(function() { $(SCENARIOS).siblings().hide(); }); $("#expander").css('cursor', 'pointer'); $("#expander").click(function() { $(SCENARIOS).siblings().show(); }); }) function moveProgressBar(percentDone) { $("cucumber-header").css('width', percentDone +"%"); } function makeRed(element_id) { $('#'+element_id).css('background', '#C40D0D'); $('#'+element_id).css('color', '#FFFFFF'); } function makeYellow(element_id) { $('#'+element_id).css('background', '#FAF834'); $('#'+element_id).css('color', '#000000'); } 474: end
# File lib/cucumber/formatter/html.rb, line 509 509: def move_progress 510: @builder << " <script type=\"text/javascript\">moveProgressBar('#{percent_done}');</script>" 511: end
# File lib/cucumber/formatter/html.rb, line 513 513: def percent_done 514: result = 100.0 515: if @step_count != 0 516: result = ((@step_number).to_f / @step_count.to_f * 1000).to_i / 10.0 517: end 518: result 519: end
# File lib/cucumber/formatter/html.rb, line 540 540: def print_stat_string(features) 541: string = String.new 542: string << dump_count(@step_mother.scenarios.length, "scenario") 543: scenario_count = print_status_counts{|status| @step_mother.scenarios(status)} 544: string << scenario_count if scenario_count 545: string << "<br />" 546: string << dump_count(@step_mother.steps.length, "step") 547: step_count = print_status_counts{|status| @step_mother.steps(status)} 548: string << step_count if step_count 549: end
# File lib/cucumber/formatter/html.rb, line 535 535: def print_stats(features) 536: @builder << "<script type=\"text/javascript\">document.getElementById('duration').innerHTML = \"Finished in <strong>#{format_duration(features.duration)} seconds</strong>\";</script>" 537: @builder << "<script type=\"text/javascript\">document.getElementById('totals').innerHTML = \"#{print_stat_string(features)}\";</script>" 538: end
# File lib/cucumber/formatter/html.rb, line 551 551: def print_status_counts 552: counts = [:failed, :skipped, :undefined, :pending, :passed].map do |status| 553: elements = yield status 554: elements.any? ? "#{elements.length} #{status.to_s}" : nil 555: end.compact 556: return " (#{counts.join(', ')})" if counts.any? 557: end
# File lib/cucumber/formatter/html.rb, line 360 360: def set_scenario_color(status) 361: if status == :undefined 362: set_scenario_color_pending 363: end 364: if status == :failed 365: set_scenario_color_failed 366: end 367: end
# File lib/cucumber/formatter/html.rb, line 369 369: def set_scenario_color_failed 370: @builder.script do 371: @builder.text!("makeRed('cucumber-header');") unless @header_red 372: @header_red = true 373: @builder.text!("makeRed('scenario_#{@scenario_number}');") unless @scenario_red 374: @scenario_red = true 375: end 376: end
# File lib/cucumber/formatter/html.rb, line 378 378: def set_scenario_color_pending 379: @builder.script do 380: @builder.text!("makeYellow('cucumber-header');") unless @header_red 381: @builder.text!("makeYellow('scenario_#{@scenario_number}');") unless @scenario_red 382: end 383: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.