class CUKES::CustomHtmlReport

Public Class Methods

new(arr_file_paths) click to toggle source

Description : invoked automatically when an object of the class type is created Author : Chandra sekaran Arguments :

arr_file_paths  : array of html report file paths
# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 19
def initialize(arr_file_paths)
  @arr_file_name = arr_file_paths
  @template_file_name = arr_file_paths.first   # take the html template from first html file

  @scenario=[]
  @scenario_pass=[]
  @scenario_fail=[]
  @scenario_skip=[]
  @scenario_pending=[]
  @scenario_undefined=[]
  @step=[]
  @step_pass=[]
  @step_fail=[]
  @step_skip=[]
  @step_pending=[]
  @step_undefined=[]

  @feature=[]
  @arr_html_file_name = []
  @arr_testcase_id = []
  @arr_feature_id = []
end

Public Instance Methods

create_child_report_table_header() click to toggle source

Description : creates header for report table for child pages Author : Chandra sekaran

# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 723
def create_child_report_table_header
  begin
    arr_table_header = ["Sr No","Scenario ID","Scenario Title","Total","Passed","Failed","Skipped","Pending","Undefined","Result"]
    tr = Nokogiri::XML::Node.new("tr", @html_template1)
    4.times do |col|
      td = Nokogiri::XML::Node.new("td", @html_template1)
      case col
        when 1
          td["colspan"] = "2"
        when 2
          td["colspan"] = "6"
          td.inner_html = "<b>Steps</b>"
          td['align'] = "center"
      end
      td['style'] = "background-color: #d3ecfc;"
      tr.add_child(td)
    end
    @scenario_table.add_child(tr)
    tr = Nokogiri::XML::Node.new("tr", @html_template1)
    arr_table_header.each do |str_header|
      th = Nokogiri::XML::Node.new("th", @html_template1)
      th.inner_html = "<b>#{str_header}</b>"
      th['style'] = "background-color: #d3ecfc;"   # light blue color
      th["font"] = "size: 15px;"
      tr.add_child(th)
    end
    @scenario_table.add_child(tr)
  rescue Exception => ex
    $log.error("Error while creating report table header for child pages : #{ex}")
    exit
  end
end
create_custom_report() click to toggle source

Description : creates new custome html report files Author : Chandra sekaran

# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 759
def create_custom_report
  create_report_directory
  @arr_file_name.each do |path|     # move screenshot directory
    path = format_file_path(path)
    arr = path.split("/")
    arr.pop                 # remove the html file name
    path = arr.join("/")
    Dir.glob(path).each do |file|
      if File.directory?("#{file}/screenshot")     # check if screenshot directory exists else create a new one and copy it to the recent log directory
        create_directory("#{$current_log_dir}/custom_report/detailed_report/screenshot")
        FileUtils.cp Dir["#{File.expand_path(file)}/screenshot/*.png"], "#{$current_log_dir}/custom_report/detailed_report/screenshot"
      end
    end
  end
  @arr_file_name.each do |path|     # create sub report
    create_sub_report(path)
  end
  create_main_report       # create consolidated home report file
  $log.success("Custom html report file has been generated successfully")
rescue Exception => ex
  $log.error("Error in creating custom html report : #{ex}")
  exit
end
create_html_template(str_file_path) click to toggle source

Description : creates new html template object based cucumber report file generated Author : Chandra sekaran Arguments :

str_file_path   : file path of html file

Return arguments :

html_template   : html object
# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 63
def create_html_template(str_file_path)
  html_template = Nokogiri::HTML(File.read(str_file_path))
  html_template.xpath("//div[@id='label']/h1").each do |t|
    t.replace("<br><div class='centr'>CUKES - TEST REPORT SUMMARY</div>")
  end

  bottom = Nokogiri::XML::Node.new("footer", html_template)
  div = html_template.at_css("div.feature")
  div.add_next_sibling(bottom)

  html_template.at('footer')["id"] = "footer"

  html_template.xpath("//div[@class='feature']").each do |n|
    n.replace(Nokogiri::XML::Node.new("p", html_template))
  end

  footer = Nokogiri::XML::Node.new("div", html_template)
  timestamp = Nokogiri::XML::Node.new("div", html_template)
  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>"
  logo = Nokogiri::XML::Node.new("img", html_template)

  footer.add_child(logo)
  footer.add_child(timestamp)

  footer['style'] = "background-color: #363636;"  # black color

  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>")
  bottom.add_child(footer)
  html_template.at('img')["src"] = "data:image/png;base64," + Base64.strict_encode64(File.open(File.absolute_path("library/generic/app_logo_1.png"), "rb").read)
  html_template.at('img')["height"] = "30px"

  html_template.xpath("//div[@id='summary']/p[1]").each do |t|
    t.replace(Nokogiri::XML::Node.new("p", html_template))   # remove pass/fail count in the report header
  end
  html_template.xpath("//div[@id='summary']/p[2]").each do |t|
    t.replace(Nokogiri::XML::Node.new("p", html_template))  # remove execution duration in the report header
  end
  return html_template
rescue Exception => ex
  $log.error("Error in creating report html template : #{ex}")
  exit
end
create_main_report() click to toggle source

Description : creates new html file holding complete execution summary Author : Chandra sekaran

# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 109
def create_main_report
  @html_template = create_html_template(@template_file_name)
  template_header  = @html_template.at_css "div#cucumber-header"
  timestamp = Nokogiri::XML::Node.new("h4", @html_template)
  timestamp.inner_html = "Executed on #{$log_env.get_formatted_datetime($start_time)}"
  logo = Nokogiri::XML::Node.new("img", @html_template)
  h1 = @html_template.at_css "h1"

  br = Nokogiri::XML::Node.new("div", @html_template)
  br.inner_html="<br><br><br>"

  @table = Nokogiri::XML::Node.new("table", @html_template)

  row_size = @feature.size

  create_report_table_header

  @tot_feature = 0
  @tot_scenario = 0
  @tot_scenario_pass = 0
  @tot_scenario_fail = 0
  @tot_scenario_skip = 0
  @tot_scenario_pending = 0
  @tot_scenario_undefined = 0
  @tot_step = 0
  @tot_step_pass = 0
  @tot_step_fail = 0
  @tot_step_skip = 0
  @tot_step_pending = 0
  @tot_step_undefined = 0

  for i in 1..row_size
    tr = Nokogiri::XML::Node.new("tr", @html_template)

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{i}"
    tr.add_child(td)
    @tot_feature = i

    if ["yes", "true"].include? INCLUDE_FEATUREID_IN_REPORT.downcase
      td = Nokogiri::XML::Node.new("td", @html_template)        # for Feature ID
      td.inner_html = @arr_feature_id[i-1].nil? ? " " : @arr_feature_id[i-1].gsub("@", "").to_s
      tr.add_child(td)
    end

    if ["yes", "true"].include? INCLUDE_SCENARIOID_IN_REPORT.downcase
      td = Nokogiri::XML::Node.new("td", @html_template)        # for Scenario ID
      td.inner_html = @arr_testcase_id[i-1].nil? ? " " : @arr_testcase_id[i-1].join(", ").to_s
      tr.add_child(td)
    end

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "<a href='detailed_report/#{@arr_html_file_name[i-1]}.html' target='_blank'>#{@feature[i-1]}</a>"
    tr.add_child(td)
    td['width'] = "40%"

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@scenario[i-1]}"
    tr.add_child(td)
    @tot_scenario += @scenario[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    num_pass_count = @scenario_pass[i-1]
    td.inner_html = "#{num_pass_count}"
    td['style'] = "background-color: #b0f9c3;" if num_pass_count > 0   # green color
    tr.add_child(td)
    @tot_scenario_pass += num_pass_count

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@scenario_fail[i-1]}"
    td['style'] = "background-color: #fbc8d5;" if @scenario_fail[i-1] > 0   # red color
    tr.add_child(td)
    @tot_scenario_fail += @scenario_fail[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@scenario_skip[i-1]}"
    td['style'] = "background-color: #f2f9b0;" if @scenario_skip[i-1] > 0   # yellow color
    tr.add_child(td)
    @tot_scenario_skip += @scenario_skip[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@scenario_pending[i-1]}"
    td['style'] = "background-color: #f2f9b0;" if @scenario_pending[i-1] > 0   # yellow color
    tr.add_child(td)
    @tot_scenario_pending += @scenario_pending[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@scenario_undefined[i-1]}"
    td['style'] = "background-color: #f2f9b0;" if @scenario_undefined[i-1] > 0   # yellow color
    tr.add_child(td)
    @tot_scenario_undefined += @scenario_undefined[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@step[i-1]}"
    tr.add_child(td)
    @tot_step += @step[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@step_pass[i-1]}"
    td['style'] = "background-color: #b0f9c3;" if @step_pass[i-1] > 0   # green color
    tr.add_child(td)
    @tot_step_pass += @step_pass[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@step_fail[i-1]}"
    td['style'] = "background-color: #fbc8d5;" if @step_fail[i-1] > 0   # red color
    tr.add_child(td)
    @tot_step_fail += @step_fail[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@step_skip[i-1]}"
    td['style'] = "background-color: #f2f9b0;" if @step_skip[i-1] > 0   # yellow color
    tr.add_child(td)
    @tot_step_skip += @step_skip[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@step_pending[i-1]}"
    td['style'] = "background-color: #f2f9b0;" if @step_pending[i-1] > 0   # yellow color
    tr.add_child(td)
    @tot_step_pending += @step_pending[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = "#{@step_undefined[i-1]}"
    td['style'] = "background-color: #f2f9b0;" if @step_undefined[i-1] > 0    # yellow color
    tr.add_child(td)
    @tot_step_undefined += @step_undefined[i-1]

    td = Nokogiri::XML::Node.new("td", @html_template)
    td.inner_html = @scenario_fail[i-1] > 0 ? "Failed" : "Passed"
    td['style'] = @scenario_fail[i-1] > 0 ? "background-color: #fbc8d5;" : "background-color: #b0f9c3;"
    tr.add_child(td)

    @table.add_child(tr)
  end

  create_report_table_footer

  @table['style'] = "width:90%; font:13px;"
  10.times { template_header.add_next_sibling("<br>") }
  template_header.add_next_sibling(@table)
  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>")
  @html_template.at('table')["border"] = 2
  @html_template.at('table')["align"] = "center"

  # set report header background color
  if @tot_scenario_fail > 0    # for red color header
    template_header.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#c40d0d'); $('#cucumber-header').css('color', '#FFFFFF');</script>")
  elsif @tot_scenario_pending > 0  # for yellow color header
    template_header.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#f2f9b0'); $('#cucumber-header').css('color', '#000000');</script>")
  else  # for green color header
    template_header.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#65c400'); $('#cucumber-header').css('color', '#FFFFFF');</script>")
  end

  @html_template.xpath("//div[@id='expand-collapse']").each do |t|
    t.replace(Nokogiri::XML::Node.new("p", @html_template))  # removes Collapse All & Expand All links
  end

  # style : .left{margin-left:50px;margin-top:20px;margin-bottom:20px;font:bold 12.5px 'Lucida Grande',Helvetica,sans-serif;}
  template_header.add_next_sibling("<div class='left' id='build_result'><b>Execution details : <b></div>")
  build_res  = @html_template.at_css "div#build_result"
  arr_build_durations = get_execution_duration
  # for getting individual build durations
  #@arr_json_report_file.each_with_index do |file, indx|
  #  build_res.add_child("<div> Build - #{indx+1} duration : #{format_nonoseconds_to_time(arr_build_durations[indx])}</div>")
  #end
  build_res.add_child("<div> Total number of executions   : #{@arr_json_report_file.size}</div>")
  build_res.add_child("<div> Total duration (DD:HH:MM:SS) : #{format_nonoseconds_to_time(@num_build_duration)}</div>")
  build_res.add_child("<div> Total build duration (DD:HH:MM:SS) : #{format_nonoseconds_to_time(arr_build_durations.max)}</div>")

  File.open("#{$current_log_dir}/custom_report/report_home.html", "w") do |f|
    f.write(@html_template)
  end
rescue Exception => ex
  $log.error("Error in creating main html report : #{ex}")
  exit
end
create_report_directory() click to toggle source

Description : creates new directory for custom report files and copies other dependents Author : Chandra sekaran

# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 45
def create_report_directory
  create_directory("#{$current_log_dir}/custom_report")
  create_directory("#{$current_log_dir}/custom_report/detailed_report")
  FileUtils.cp("library/generic/app_logo_1.png", "#{$current_log_dir}/custom_report/detailed_report")
  # copy screenshot directory to custom_report directory for image attachment of custom report html files
  FileUtils.cp_r("#{$current_log_dir}/screenshot", "#{$current_log_dir}/custom_report/detailed_report") rescue Exception
rescue Exception => ex
  $log.error("Error in creating custom report directory : #{ex}")
  exit
end
create_report_table_header() click to toggle source

Description : creates header for report table Author : Chandra sekaran

# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 580
def create_report_table_header
  arr_table_header = ["Sr No"]
  arr_table_header << "Feature ID" if ["yes", "true"].include? INCLUDE_FEATUREID_IN_REPORT.downcase
  arr_table_header << "Scenario ID" if ["yes", "true"].include? INCLUDE_SCENARIOID_IN_REPORT.downcase
  arr_table_header += ["Feature","Total","Passed","Failed","Skipped","Pending","Undefined","Total","Passed","Failed","Skipped","Pending","Undefined","Result"]
  tr = Nokogiri::XML::Node.new("tr", @html_template)
  5.times do |col|
    td = Nokogiri::XML::Node.new("td", @html_template)
    case col
      when 1
        td["colspan"] = "3"
        td["colspan"] = (td["colspan"].to_i - 1).to_s if !(["yes", "true"].include?(INCLUDE_FEATUREID_IN_REPORT.downcase))
        td["colspan"] = (td["colspan"].to_i - 1).to_s if !(["yes", "true"].include?(INCLUDE_SCENARIOID_IN_REPORT.downcase))
      when 2
        td["colspan"] = "6"
        td.inner_html = "<b>Scenarios</b>"
        td['align'] = "center"
      when 3
        td["colspan"] = "6"
        td.inner_html = "<b>Steps</b>"
        td['align'] = "center"
    end
    td['style'] = "background-color: #d3ecfc;"
    tr.add_child(td)
  end
  @table.add_child(tr)

  tr = Nokogiri::XML::Node.new("tr", @html_template)
  arr_table_header.each do |str_header|
    th = Nokogiri::XML::Node.new("th", @html_template)
    th.inner_html = "<b>#{str_header}</b>"
    th['style'] = "background-color: #d3ecfc;"   # light blue color
    th["font"] = "size: 15px;"
    tr.add_child(th)
  end
  @table.add_child(tr)
rescue Exception => ex
  $log.error("Error while creating report table header : #{ex}")
  exit
end
create_sub_report(str_file_path) click to toggle source

Description : creates new html files holding complete execution summary for each feature Author : Chandra sekaran Argument :

str_file_path   : file path of the report file
# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 291
def create_sub_report(str_file_path)
  @html_doc = Nokogiri::HTML(File.read(str_file_path))
  br = Nokogiri::XML::Node.new("p", @html_doc)

  @html_doc.xpath("//div[@class='feature']").each_with_index do |f, index|
    @scenario_name = []
    @num_step_count = []
    @num_step_pass_count = []
    @num_step_fail_count = []
    @num_step_skip_count = []
    @num_step_pending_count = []
    @num_step_undefined_count = []

    @html_template1 = create_html_template(@template_file_name)
    # @html_template1.at('img')["src"] = "app_logo_1.png"  # change the image file path for the sub-report files
    @html_template1.at('img')["src"] = "data:image/png;base64," + Base64.strict_encode64(File.open(File.absolute_path("library/generic/app_logo_1.png"), "rb").read)  # change the image file path for the sub-report files
    template_header1  = @html_template1.at_css "div#cucumber-header"

    @feature << f.xpath("./h2/span[@class='val']").text.gsub("Feature:", "")

    begin     # for feature documentation header content
      pre_old  = f.at_css "pre"
      f.xpath("./pre").each do |t|
        t.replace("<br><br><br><br><pre><font color='black'>")
      end
      font  = f.at_css "font"
      font.add_child(pre_old)
    rescue Exception => ex
    end

    @scenario_skip_count = 0

    cstep = 0
    cstep_pass = 0
    cstep_fail = 0
    cstep_skip = 0
    cstep_pending = 0
    cstep_undefined = 0

    bstep = 0
    bstep_pass = 0
    bstep_fail = 0
    bstep_skip = 0
    bstep_pending = 0

    f.search("./div[@class='scenario']/h3").each do |s|
      @scenario_name << s.inner_text.strip
    end

    f.search("./div[@class='background']").each do |s|
      bstep = s.search(".//ol/li/div[@class='step_name']").size
      bstep_pass = s.search(".//ol/li[@class='step passed']").size
      bstep_fail = s.search(".//ol/li[@class='step failed']").size
      bstep_skip = s.search(".//ol/li[@class='step skipped']").size
      bstep_pending = s.search(".//ol/li[@class='step pending']").size
    end

    @scenario << f.search("./div[@class='scenario']").size
    tmp = []
    break_count = true   # for getting scenario ID of scenario that has failed in Background itself
    @pass_step_count = 0
    @fail_step_count = 0
    if bstep_fail > 0
      f.search("./div[@class='scenario']").each_with_index do |s, indx|
        cstep += bstep
        cstep_fail = bstep_fail
        cstep_skip += bstep_skip
        cstep_pending += bstep_pending

        cstep += s.search(".//ol/li/div[@class='step_name']").size
        cstep_skip += s.search(".//ol/li[@class='step skipped']").size
        cstep_pending += s.search(".//ol/li[@class='step pending']").size

        @num_step_count << s.search(".//ol/li/div[@class='step_name']").size + bstep
        @num_step_fail_count << bstep_fail
        @num_step_skip_count << s.search(".//ol/li[@class='step skipped']").size
        @num_step_pending_count << s.search(".//ol/li[@class='step pending']").size
        @num_step_undefined_count << s.search(".//ol/li[@class='step undefined']").size

        if s.search(".//ol/li/div[@class='step_name']").size == s.search(".//ol/li[@class='step skipped']").size
          @scenario_skip_count += 1
        elsif (s.search(".//ol/li/div[@class='step_name']").size - s.search(".//ol/li[@class='step skipped']").size) > 0
          @scenario_skip_count += 1
        end

        # setting colors for the scenario IDs under the feature
        s.search("./span[@class='tag'][1]").each do |tag|
          if cstep_fail >= 1 && break_count
            tmp << "<span style='color:red'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
            break_count = false
            @fail_step_count += 1
          elsif s.search(".//ol/li[@class='step skipped']").size >= 1
            tmp << "<span style='color:#B0A914'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
          else
            tmp << "<span style='color:green'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
          end
        end
      end
      scenario_undefined_count = 0
    else
      scenario_undefined_count = 0
      f.search("./div[@class='scenario']").each_with_index do |s, indx|
        cstep += bstep
        cstep_pass += bstep_pass
        cstep_fail += bstep_fail
        cstep_skip += bstep_skip
        cstep_pending += bstep_pending

        cstep += s.search(".//ol/li/div[@class='step_name']").size
        cstep_pass += s.search(".//ol/li[@class='step passed']").size
        cstep_fail += s.search(".//ol/li[@class='step failed']").size
        cstep_skip += s.search(".//ol/li[@class='step skipped']").size
        cstep_pending += s.search(".//ol/li[@class='step pending']").size
        cstep_undefined += s.search(".//ol/li[@class='step undefined']").size

        @num_step_count << s.search(".//ol/li/div[@class='step_name']").size + bstep
        @num_step_pass_count << s.search(".//ol/li[@class='step passed']").size + bstep_pass
        @num_step_fail_count << s.search(".//ol/li[@class='step failed']").size
        @num_step_skip_count << s.search(".//ol/li[@class='step skipped']").size
        @num_step_pending_count << s.search(".//ol/li[@class='step pending']").size
        @num_step_undefined_count << s.search(".//ol/li[@class='step undefined']").size

        # setting colors for the scenario IDs under the feature
        s.search("./span[@class='tag'][1]").each do |tag|
          if s.search(".//ol/li[@class='step failed']").size >= 1
            tmp << "<span style='color:red'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
            @fail_step_count += 1
          elsif s.search(".//ol/li[@class='step skipped']").size >= 1
            tmp << "<span style='color:#B0A914'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
          else
            tmp << "<span style='color:green'>#{tag.inner_text.strip.gsub(SCENARIO_ID_PREFIX,"")}</span>"
          end
        end
        if s.search(".//ol/li[@class='step undefined']").size > 0
          scenario_undefined_count += 1 if s.search(".//ol/li[@class='step failed']").size == 0
        end
        if s.search(".//ol/li/div[@class='step_name']").size == s.search(".//ol/li[@class='step passed']").size
          @pass_step_count += 1
        end
      end
    end

    # for getting the feature ID
    f.search("./span[@class='tag']").each do |tag|
      if tag.inner_text.include? FEATURE_ID_PREFIX
        if cstep_fail >= 1
          @arr_feature_id << "<span style='color:red'>#{tag.inner_text.gsub(FEATURE_ID_PREFIX, "")}</span>"
        elsif cstep_pending >= 1
          @arr_feature_id << "<span style='color:#B0A914'>#{tag.inner_text.gsub(FEATURE_ID_PREFIX, "")}</span>"
        else
          @arr_feature_id << "<span style='color:green'>#{tag.inner_text.gsub(FEATURE_ID_PREFIX, "")}</span>"
        end
      end
    end

    @scenario_pass << @pass_step_count
    @scenario_fail << @fail_step_count

    @step << cstep
    @step_pass << cstep_pass
    @step_fail << cstep_fail
    @step_skip << cstep_skip
    @step_pending << cstep_pending

    if @scenario_skip_count - 1 < 0
      @scenario_skip << 0
    else
      @scenario_skip << @scenario_skip_count - 1
    end
    @scenario_pending << cstep_pending
    @step_undefined << cstep_undefined
    @scenario_undefined << scenario_undefined_count

    @arr_testcase_id << tmp

    feature_name = f.xpath("./div[@class='scenario']/span[@class='scenario_file']").inner_text.strip
    arr_feature_file_path = format_file_path(feature_name).split("/")
    str_feature_name = arr_feature_file_path.pop.split(".").first
    arr_feature_folder_name = arr_feature_file_path.pop(2)
    html_file_name = "#{arr_feature_folder_name[0]}_#{str_feature_name}"   # add stage name with fetaure file name
    @arr_html_file_name << html_file_name

    # table that summarises steps results for each scenario in the child html pages
    @scenario_table = Nokogiri::XML::Node.new("table", @html_template1)
    create_child_report_table_header

    for i in 1..@scenario_name.size
      tr = Nokogiri::XML::Node.new("tr", @html_template1)

      td = Nokogiri::XML::Node.new("td", @html_template1)
      td.inner_html = "#{i}"
      tr.add_child(td)

      td = Nokogiri::XML::Node.new("td", @html_template1)        # for Scenario ID
      td.inner_html = tmp[i-1].to_s
      tr.add_child(td)

      td = Nokogiri::XML::Node.new("td", @html_template1)
      td.inner_html = @scenario_name[i-1].gsub("Scenario:", "").to_s
      tr.add_child(td)
      td["width"] = "40%"

      td = Nokogiri::XML::Node.new("td", @html_template1)
      td.inner_html = @num_step_count[i-1].to_s
      tr.add_child(td)

      td = Nokogiri::XML::Node.new("td", @html_template1)
      td.inner_html = @num_step_pass_count[i-1].to_s
      td['style'] = "background-color: #b0f9c3;" if @num_step_pass_count[i-1] > 0   # green color
      tr.add_child(td)

      td = Nokogiri::XML::Node.new("td", @html_template1)
      td.inner_html = @num_step_fail_count[i-1].to_s
      td['style'] = "background-color: #fbc8d5;" if @num_step_fail_count[i-1] > 0   # red color
      tr.add_child(td)

      td = Nokogiri::XML::Node.new("td", @html_template1)
      td.inner_html = @num_step_skip_count[i-1].to_s
      td['style'] = "background-color: #f2f9b0;" if @num_step_skip_count[i-1] > 0   # yellow color
      tr.add_child(td)

      td = Nokogiri::XML::Node.new("td", @html_template1)
      td.inner_html = @num_step_pending_count[i-1].to_s
      td['style'] = "background-color: #f2f9b0;" if @num_step_pending_count[i-1] > 0   # yellow color
      tr.add_child(td)

      td = Nokogiri::XML::Node.new("td", @html_template1)
      td.inner_html = @num_step_undefined_count[i-1].to_s
      td['style'] = "background-color: #f2f9b0;" if @num_step_undefined_count[i-1] > 0   # yellow color
      tr.add_child(td)

      td = Nokogiri::XML::Node.new("td", @html_template1)
      td.inner_html = @num_step_fail_count[i-1] > 0 ? "Failed" : "Passed"
      td['style'] = @num_step_fail_count[i-1] > 0 ? "background-color: #fbc8d5;" : "background-color: #b0f9c3;"
      tr.add_child(td)

      @scenario_table.add_child(tr)
    end
    create_child_report_table_footer
    @scenario_table['style'] = "width:80%; font:13px;"
    template_header1.add_next_sibling(@scenario_table)
    template_header1.add_child("<style type='text/css'>td, th {color: black; font: normal 11.5px 'Lucida Grande', Helvetica, sans-serif;}</script>")
    @html_template1.at('table')["border"] = 2
    @html_template1.at('table')["align"] = "center"
    font  = f.at_css "font"
    font.add_next_sibling(@scenario_table)

    # try to add report table next to the feature title, but its not working
    #feature_header = @html_template1.at_xpath("//div[@id='cucumber-header']/div[3]/div[1]")
    ##feature_header.add_next_sibling(@scenario_table)
    #@html_template1.xpath("//div[@id='cucumber-header']/div[3]/div[1]").each do |t|
    #  t.add_previous_sibling(@scenario_table)
    #end
    #@html_template1.at('table')["border"] = 2
    #@html_template1.at('table')["align"] = "center"


    template_header1.add_child(f)      # add scenario with its steps as it is from cucumber report for this particular feature
    6.times { template_header1.add_child("<br>") }
    h2  = @html_template1.at_css "h2"
    h2["style"] = "color: black;"
    failed_step = @html_template1.at_css("//li[@class='step failed']")
    if !failed_step.nil?
      template_header1.add_child("<script type='text/javascript'> $('#cucumber-header').css('background', '#C40D0D'); $('#cucumber-header').css('color', '#FFFFFF');</script>")
    end
    template_header1.xpath("//div[@id='label']/div").each do |t|
      t.replace("<h1>#{html_file_name.gsub("_", " ").split.map(&:capitalize).join(' ')} - DETAILED REPORT</h1>")
    end
    template_header1.xpath("//div[@id='summary']/p[@id='duration']").each do |t|
      t.replace("<p>")           # remove duration fiels from cucumber report header
    end

    template_header1.add_child("<style type='text/css'>td, th {color: black; font: normal 11.5px 'Lucida Grande', Helvetica, sans-serif;}</script>")

    File.open("#{$current_log_dir}/custom_report/detailed_report/#{html_file_name}.html", "w") do |file|
      file.write(@html_template1)
    end
  end
  @html_doc.xpath("//div[@class='feature']/div[@class='scenario']").each do |n|
    n.replace(br)
  end
rescue Exception => ex
  $log.error("Error in creating sub report html : #{ex}")
  exit
end
get_execution_duration() click to toggle source

Description : gets the total execution duration with input data from json report file Author : Chandra sekaran Return argument :

arr_build_durations : total execution time in nanoseconds
# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 788
def get_execution_duration
  @arr_json_report_file = get_files_absolute_path("test_result", "json", $start_time - $world.get_execution_delay_time.seconds)
  $log.info("Report file names (json): #{@arr_json_report_file}")
  @num_build_duration = 0

  arr_build_durations = []

  @arr_json_report_file.each do |path|
    @arr_background_step_duration = []
    file = File.read(path)
    @json = JSON.parse(file)
    arr_build_durations << parse_json    # parse each json file and extract report data
  end
  arr_build_durations
end
parse_json() click to toggle source

Description : parses the json file and calculates the total execution duration Author : Chandra sekaran Return argument :

feature_duration    : total execution time for each execution in nanoseconds
# File lib/friendly/cukes/framework/library/generic/custom_html_report.rb, line 809
def parse_json
  unit_build_duration = 0
  feature_duration = 0
  scenario_duration = 0
  step_duration = 0
  @json.each_with_index do |json, index|         # iterate each feature
    feature_duration = 0
    json["elements"].each do |element|
      # for including the first background steps duration to the first scenario background steps as Cucumber json
      # report considers background for the first scenario and hence will have 0 duration for the background steps
      # under first scenario and the actual duration for the background will be set for the subsequent scenarios
      if index == 0
        if element["keyword"] == "Background"
          element["steps"].each do |step|
            @arr_background_step_duration << step["result"]["duration"].to_i
            @bool = true
          end
        end
      end
      if element["keyword"] == "Scenario"       # take scenario for scenario level details
        scenario_duration = 0
        element["steps"].each_with_index do |step, indx|    # iterate each steps of the current scenario
          step_duration = 0
          if (index == 0) && (indx < @arr_background_step_duration.size) && @bool
            step_duration = @arr_background_step_duration[indx]    # take duration from Background for the first scenario
          else
            step_duration = step["result"]["duration"].to_i     # take usual duration
            @bool = false
          end
          scenario_duration += step_duration
        end
        feature_duration += scenario_duration
      end
    end
    @num_build_duration += feature_duration
    unit_build_duration += feature_duration
  end
  unit_build_duration
rescue Exception => ex
  $log.error("Error while parsing JSON : #{ex}")
  exit
end