class Bauxite::Loggers::HtmlLogger
Html logger.
This logger creates an HTML report of the test execution, linking to the captures taken, if any.
Html logger options include:
html
-
Name of the outpus HTML report file. If not present, defaults to “test.html”.
html_package
-
If set, embed captures into the HTML report file using the data URI scheme (base64 encoded). The captures embedded into the report are deleted from the filesystem.
Public Class Methods
new(options)
click to toggle source
Constructs a new null logger instance.
Calls superclass method
Bauxite::Loggers::ReportLogger.new
# File lib/bauxite/loggers/html.rb, line 42 def initialize(options) super(options) @file = options[:html] || 'test.html' @imgs = [] end
Public Instance Methods
finalize(ctx)
click to toggle source
Completes the log execution.
# File lib/bauxite/loggers/html.rb, line 50 def finalize(ctx) output = ctx.variables['__OUTPUT__'] || '' html = "<!DOCTYPE html> <html> <head> <style type='text/css'> body { font: 10pt sans-serif; } .action div { display: inline-block; } .cmd { width: 100px } .status { float: right; text-align: center; } .status .text { width: 100px; font-weight: bold } .test { background-color: #DFDFFF; margin-top: 20px } .ok .status .text { background-color: #DFFFDF } .error .status .text { background-color: #FFDFDF } .skip .status .text { background-color: #FFDFFF } .capture { border: 1px solid black } .capture img { max-width: 100% } .odd { background-color: #EEEEEE } .summary th { background-color: #DFDFFF; text-align: left } .summary td { cursor: pointer; } .top { position: absolute; top: 0px; right: 0px; background-color: #DFDFFF; padding: 5px; border-radius: 0px 0px 0px 5px; } </style> <script type='text/javascript'> function show(target) { var e = document.getElementById(target+'_content'); window.location.href = '#'+target; } </script> </head> <body>" html << _d(2, "<div class='top'>Created using <a href='https://github.com/pzavolinsky/bauxite'>bauxite</a> on #{Time.new}</div>") if ctx.tests.any? html << _d(2, "<h1>Test Summary</h1>") html << _d(2, "<table class='summary'>") html << _d(3, "<tr><th>Name</th><th>Time</th><th>Status</th><th>Error</th></tr>") ctx.tests.each_with_index do |t,idx| error = t[:error] error = error ? error.message : '' html << _d(3, "<tr class='#{t[:status].downcase} #{(idx % 2) == 1 ? 'odd' : 'even'}' onclick='show(\"#{t[:name]}\")'>") html << _d(4, "<td>#{t[:name]}</td><td>#{t[:time].round(2)}</td><td class='status'>#{t[:status]}</td><td>#{error}</td>") html << _d(3, "</tr>") end html << _d(2, "</table>") end html << _d(2, "<h1>Test Details</h1>") @data.each do |test| name = test[:name] status = test[:actions].find { |a| a[:status] == :error } ? :error : :ok html << _d(2, "<a name='#{name}'></a>") html << _d(2, "<div class='test #{status}'>#{name}<div class='status'><div class='text'>#{status.upcase}</div></div></div>") html << _d(2, "<div id='#{name}_content' class='test-content'>") test[:actions].each_with_index do |action,idx| html << _d(3, "<div class='action #{action[:status]} #{(idx % 2) == 1 ? 'odd' : 'even'}'>") html << _d(4, "<div class='cmd'>#{action[:cmd]}</div>") html << _d(4, "<div class='args'>#{action[:args].join(' ')}</div>") html << _d(4, "<div class='status'>") html << _d(5, "<div class='time'>(#{action[:time].round(2).to_s}s)</div>") html << _d(5, "<div class='text'>#{action[:status].upcase}</div>") html << _d(4, "</div>") html << _d(3, "</div>") capture = action[:capture] if capture html << _d(3, "<div class='capture'>#{_img(output, capture)}</div>") end end item = ctx.tests.find { |t| t[:name] == name } if item and item[:error] capture = item[:error].variables['__CAPTURE__'] if capture html << _d(3, "<div class='capture'>#{_img(output, capture)}</div>") end end html << _d(2, "</div>") end html << " </body> </html>" file = ctx.output_path(@file) File.open(file, 'w') { |f| f.write html } File.delete(*@imgs) if @imgs.size > 0 end