teuton 2.1.8 → 2.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -8
- data/bin/check_teuton +43 -0
- data/docs/changelog/contributions.md +32 -0
- data/docs/changelog/v2.1.md +22 -0
- data/docs/changelog/v2.2.md +29 -0
- data/docs/commands/README.md +105 -7
- data/docs/commands/example_check.md +54 -0
- data/docs/commands/example_run.md +112 -0
- data/docs/dsl/README.md +11 -9
- data/docs/dsl/definition/expect.md +25 -21
- data/docs/dsl/definition/group.md +5 -1
- data/docs/dsl/definition/result.md +45 -34
- data/docs/dsl/definition/run_local.md +34 -0
- data/docs/dsl/definition/run_remote.md +119 -0
- data/docs/dsl/definition/target.md +6 -0
- data/docs/dsl/execution/export.md +27 -19
- data/docs/dsl/execution/play.md +4 -0
- data/docs/dsl/execution/send.md +21 -2
- data/docs/dsl/execution/show.md +13 -8
- data/docs/dsl/setting/get.md +24 -8
- data/docs/dsl/setting/set.md +8 -3
- data/docs/install/README.md +19 -26
- data/docs/install/modes_of_use.md +27 -26
- data/docs/install/scripts.md +53 -36
- data/docs/install/vagrant_docker.md +56 -0
- data/docs/learn/README.md +13 -6
- data/docs/learn/example-01-target.md +78 -61
- data/docs/learn/example-02-config.md +152 -0
- data/docs/learn/example-03-remote-hosts.md +31 -25
- data/docs/learn/example-04-use.md +23 -17
- data/docs/learn/example-05-debug.md +24 -17
- data/docs/learn/example-06-log.md +70 -0
- data/lib/teuton/application.rb +7 -4
- data/lib/teuton/case_manager/case/case.rb +4 -1
- data/lib/teuton/case_manager/case/dsl/expect.rb +3 -1
- data/lib/teuton/case_manager/case/dsl/goto.rb +12 -7
- data/lib/teuton/case_manager/case/dsl/macro.rb +38 -0
- data/lib/teuton/case_manager/case/dsl/main.rb +1 -2
- data/lib/teuton/case_manager/case/dsl/target.rb +1 -1
- data/lib/teuton/case_manager/case/runner.rb +7 -7
- data/lib/teuton/case_manager/case_manager.rb +1 -20
- data/lib/teuton/case_manager/check_cases.rb +12 -2
- data/lib/teuton/case_manager/dsl.rb +4 -6
- data/lib/teuton/case_manager/export_manager.rb +29 -3
- data/lib/teuton/case_manager/report.rb +29 -8
- data/lib/teuton/case_manager/show.rb +8 -4
- data/lib/teuton/cli.rb +1 -0
- data/lib/teuton/cli/play.rb +1 -0
- data/lib/teuton/cli/version.rb +1 -4
- data/lib/teuton/files/config.yaml +0 -1
- data/lib/teuton/files/start.rb +1 -1
- data/lib/teuton/files/template/case.html +135 -0
- data/lib/teuton/files/template/resume.html +115 -0
- data/lib/teuton/project/laboratory/builtin.rb +2 -1
- data/lib/teuton/project/laboratory/dsl.rb +13 -15
- data/lib/teuton/project/laboratory/laboratory.rb +5 -1
- data/lib/teuton/project/laboratory/show.rb +21 -13
- data/lib/teuton/project/name_file_finder.rb +6 -1
- data/lib/teuton/project/project.rb +7 -3
- data/lib/teuton/project/readme/dsl.rb +3 -1
- data/lib/teuton/project/readme/readme.rb +37 -26
- data/lib/teuton/project/skeleton.rb +20 -4
- data/lib/teuton/report/close.rb +15 -11
- data/lib/teuton/report/formatter/formatter_factory.rb +10 -6
- data/lib/teuton/report/formatter/html_formatter.rb +16 -79
- data/lib/teuton/report/formatter/resume_html_formatter.rb +39 -0
- data/lib/teuton/report/formatter/resume_yaml_formatter.rb +7 -1
- data/lib/teuton/report/report.rb +5 -4
- data/lib/teuton/report/show.rb +55 -26
- metadata +26 -39
- data/docs/changelog/todo.md +0 -46
- data/docs/commands/create_skeleton.md +0 -31
- data/docs/commands/help.md +0 -13
- data/docs/commands/revise_test.md +0 -46
- data/docs/commands/run_test_unit.md +0 -78
- data/docs/commands/show_version.md +0 -9
- data/docs/developers/01-telnet.md +0 -121
- data/docs/developers/02-ssh.md +0 -93
- data/docs/developers/03-encoding.md +0 -153
- data/docs/developers/comparative.md +0 -17
- data/docs/dsl/_Sidebar.md +0 -30
- data/docs/dsl/definition/goto.md +0 -112
- data/docs/dsl/definition/run.md +0 -23
- data/docs/install/tested_os.md +0 -25
- data/docs/install/vagrant.md +0 -9
- data/docs/learn/example-02-configfile.md +0 -174
- data/docs/learn/quick-demo.md +0 -170
- data/lib/teuton/case_manager/case/dsl/check.rb +0 -24
- data/lib/teuton/case_manager/case/dsl/missing.rb +0 -12
- data/lib/teuton/files/gitignore +0 -2
|
@@ -55,10 +55,8 @@ class CaseManager
|
|
|
55
55
|
puts ' Usage: export :format => :colored_text'
|
|
56
56
|
raise '[ERROR] CaseManager#export: Argument error!'
|
|
57
57
|
end
|
|
58
|
-
#
|
|
58
|
+
# Export report files
|
|
59
59
|
ExportManager.run(@report, @cases, args)
|
|
60
|
-
# Second: preserve files if required
|
|
61
|
-
preserve_files if args[:preserve] == true
|
|
62
60
|
end
|
|
63
61
|
|
|
64
62
|
##
|
|
@@ -71,21 +69,4 @@ class CaseManager
|
|
|
71
69
|
@cases.each { |c| threads << Thread.new { c.send(args) } }
|
|
72
70
|
threads.each(&:join)
|
|
73
71
|
end
|
|
74
|
-
|
|
75
|
-
private
|
|
76
|
-
|
|
77
|
-
##
|
|
78
|
-
# Preserve output files for current project
|
|
79
|
-
def preserve_files
|
|
80
|
-
app = Application.instance
|
|
81
|
-
t = Time.now
|
|
82
|
-
subdir = "#{t.year}#{format('%02d',t.month)}#{format('%02d',t.day)}-" \
|
|
83
|
-
"#{format('%02d',t.hour)}#{format('%02d',t.min)}" \
|
|
84
|
-
"#{format('%02d',t.sec)}"
|
|
85
|
-
logdir = File.join(app.output_basedir, app.global[:tt_testname], subdir)
|
|
86
|
-
srcdir = File.join(app.output_basedir, app.global[:tt_testname])
|
|
87
|
-
puts "[INFO] Preserving files => #{logdir}"
|
|
88
|
-
FileUtils.mkdir(logdir)
|
|
89
|
-
Dir.glob(File.join(srcdir, '**.*')).each { |file| FileUtils.cp(file, logdir) }
|
|
90
|
-
end
|
|
91
72
|
end
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
class CaseManager
|
|
6
6
|
private
|
|
7
7
|
|
|
8
|
+
##
|
|
9
|
+
# Start checking every single case
|
|
8
10
|
def check_cases!
|
|
9
11
|
app = Application.instance
|
|
10
12
|
|
|
@@ -33,14 +35,16 @@ class CaseManager
|
|
|
33
35
|
close_main_report(start_time)
|
|
34
36
|
end
|
|
35
37
|
|
|
38
|
+
##
|
|
39
|
+
# Run all cases
|
|
36
40
|
def run_all_cases
|
|
37
41
|
start_time = Time.now
|
|
38
42
|
if Application.instance.global[:tt_sequence]
|
|
39
|
-
verboseln "[INFO] Running in sequence (#{start_time})"
|
|
43
|
+
verboseln Rainbow("[INFO] Running in sequence (#{start_time})").yellow.bright
|
|
40
44
|
# Run every case in sequence
|
|
41
45
|
@cases.each(&:play)
|
|
42
46
|
else
|
|
43
|
-
verboseln "[INFO] Running in parallel (#{start_time})"
|
|
47
|
+
verboseln Rainbow("[INFO] Running in parallel (#{start_time})").yellow.bright
|
|
44
48
|
threads = []
|
|
45
49
|
# Run all cases in parallel
|
|
46
50
|
@cases.each { |c| threads << Thread.new { c.play } }
|
|
@@ -49,6 +53,8 @@ class CaseManager
|
|
|
49
53
|
start_time
|
|
50
54
|
end
|
|
51
55
|
|
|
56
|
+
##
|
|
57
|
+
# Collect uniques values for all cases
|
|
52
58
|
def collect_uniques_for_all_cases
|
|
53
59
|
uniques = {} # Collect "unique" values from all cases
|
|
54
60
|
@cases.each do |c|
|
|
@@ -63,6 +69,10 @@ class CaseManager
|
|
|
63
69
|
uniques
|
|
64
70
|
end
|
|
65
71
|
|
|
72
|
+
##
|
|
73
|
+
# 1) Reevaluate every case with collected unique values
|
|
74
|
+
# 2) Close all case reports
|
|
75
|
+
# 3) And order to build hall of fame
|
|
66
76
|
def close_reports_for_all_cases(uniques)
|
|
67
77
|
threads = []
|
|
68
78
|
@cases.each { |c| threads << Thread.new { c.close uniques } }
|
|
@@ -12,13 +12,11 @@ def use(filename)
|
|
|
12
12
|
app.uses << File.basename(findfiles.first)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
def
|
|
16
|
-
Application.instance.
|
|
15
|
+
def define_macro(name, *args, &block)
|
|
16
|
+
Application.instance.macros[name] = { args: args, block: block }
|
|
17
17
|
end
|
|
18
|
-
alias
|
|
19
|
-
alias
|
|
20
|
-
alias defcheck define_check
|
|
21
|
-
alias dcheck define_check
|
|
18
|
+
alias def_macro define_macro
|
|
19
|
+
alias defmacro define_macro
|
|
22
20
|
|
|
23
21
|
def group(name, &block)
|
|
24
22
|
Application.instance.groups << { name: name, block: block }
|
|
@@ -3,24 +3,50 @@
|
|
|
3
3
|
require_relative '../application'
|
|
4
4
|
|
|
5
5
|
##
|
|
6
|
-
# ExportManager is used by CaseManager to export output reports
|
|
6
|
+
# ExportManager is used by CaseManager to export output reports
|
|
7
7
|
module ExportManager
|
|
8
8
|
##
|
|
9
9
|
# Run export function
|
|
10
10
|
# @param main_report (Report)
|
|
11
11
|
# @param cases (Array)
|
|
12
12
|
# @param args (Hash) Selected export options
|
|
13
|
+
# rubocop: disable Metrics/AbcSize
|
|
13
14
|
def self.run(main_report, cases, args)
|
|
14
15
|
# default :mode=>:all, :format=>:txt
|
|
15
16
|
format = args[:format] || Application.instance.default[:format]
|
|
16
17
|
mode = args[:mode] || :all
|
|
17
|
-
# Export case reports
|
|
18
|
+
# Step 1: Export case reports
|
|
18
19
|
if %i[details all].include? mode
|
|
19
20
|
threads = []
|
|
20
21
|
cases.each { |c| threads << Thread.new { c.export format } }
|
|
21
22
|
threads.each(&:join)
|
|
22
23
|
end
|
|
23
|
-
# Export resume report
|
|
24
|
+
# Step 2: Export resume report
|
|
24
25
|
main_report.export_resume format if %i[resume all].include? mode
|
|
26
|
+
# Step 3: Preserve files if required
|
|
27
|
+
preserve_files if args[:preserve] == true
|
|
25
28
|
end
|
|
29
|
+
# rubocop:enable Metrics/AbcSize
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Preserve output files for current project
|
|
33
|
+
# rubocop:disable Metrics/AbcSize
|
|
34
|
+
# rubocop:disable Metrics/MethodLength
|
|
35
|
+
# rubocop:disable Layout/LineLength
|
|
36
|
+
private_class_method def self.preserve_files
|
|
37
|
+
app = Application.instance
|
|
38
|
+
t = Time.now
|
|
39
|
+
data = { year: t.year, month: t.month, day: t.day,
|
|
40
|
+
hour: t.hour, min: t.min, sec: t.sec }
|
|
41
|
+
subdir = format('%<year>s%<month>02d%<day>02d-' \
|
|
42
|
+
'%<hour>02d%<min>02d%<sec>02d', data)
|
|
43
|
+
logdir = File.join(app.output_basedir, app.global[:tt_testname], subdir)
|
|
44
|
+
srcdir = File.join(app.output_basedir, app.global[:tt_testname])
|
|
45
|
+
puts "[INFO] Preserving files => #{logdir}"
|
|
46
|
+
FileUtils.mkdir(logdir)
|
|
47
|
+
Dir.glob(File.join(srcdir, '**.*')).each { |file| FileUtils.cp(file, logdir) }
|
|
48
|
+
end
|
|
49
|
+
# rubocop:enable Metrics/AbcSize
|
|
50
|
+
# rubocop:enable Metrics/MethodLength
|
|
51
|
+
# rubocop:enable Layout/LineLength
|
|
26
52
|
end
|
|
@@ -1,21 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
require 'rainbow'
|
|
2
|
+
##
|
|
3
|
+
# Class CaseManager
|
|
4
|
+
# Methods related with report
|
|
2
5
|
class CaseManager
|
|
3
6
|
|
|
4
7
|
private
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
##
|
|
10
|
+
# Open main report (resume report)
|
|
11
|
+
# @param config_filepath (String)
|
|
12
|
+
def open_main_report(config_filepath)
|
|
7
13
|
app = Application.instance
|
|
8
14
|
|
|
9
15
|
@report.head[:tt_title] = "Executing [#{app.name}] (version #{Application::VERSION})"
|
|
10
|
-
@report.head[:tt_scriptname] = app.script_path
|
|
11
|
-
@report.head[:tt_configfile] =
|
|
16
|
+
@report.head[:tt_scriptname] = trim(app.script_path)
|
|
17
|
+
@report.head[:tt_configfile] = trim(config_filepath)
|
|
18
|
+
@report.head[:tt_pwd] = app.running_basedir
|
|
12
19
|
@report.head[:tt_debug] = true if @debug
|
|
13
|
-
# @report.head[:tt_uses] = app.uses.join(', ')
|
|
20
|
+
# @report.head[:tt_uses] = app.uses.join(', ') # TO-REVISE
|
|
14
21
|
@report.head.merge!(app.global)
|
|
15
22
|
|
|
16
23
|
verboseln ' '
|
|
17
24
|
verboseln '=' * @report.head[:tt_title].length
|
|
18
|
-
verboseln @report.head[:tt_title]
|
|
25
|
+
verboseln Rainbow(@report.head[:tt_title]).yellow.bright
|
|
19
26
|
end
|
|
20
27
|
|
|
21
28
|
def close_main_report(start_time)
|
|
@@ -24,8 +31,8 @@ class CaseManager
|
|
|
24
31
|
@report.tail[:finish_time] = finish_time
|
|
25
32
|
@report.tail[:duration] = finish_time - start_time
|
|
26
33
|
|
|
27
|
-
verbose "\n[INFO] Duration = #{format('%3.3f',(finish_time - start_time))}"
|
|
28
|
-
verboseln " (#{finish_time})"
|
|
34
|
+
verbose Rainbow("\n[INFO] Duration = #{format('%3.3f',(finish_time - start_time))}").yellow.bright
|
|
35
|
+
verboseln Rainbow(" (#{finish_time})").yellow.bright
|
|
29
36
|
verboseln '=' * @report.head[:tt_title].length
|
|
30
37
|
verboseln ' '
|
|
31
38
|
|
|
@@ -49,4 +56,18 @@ class CaseManager
|
|
|
49
56
|
@report.lines << line
|
|
50
57
|
end
|
|
51
58
|
end
|
|
59
|
+
|
|
60
|
+
##
|
|
61
|
+
# Trim string text when is too long
|
|
62
|
+
# @param input (String)
|
|
63
|
+
# @return String
|
|
64
|
+
def trim(input)
|
|
65
|
+
return input unless input.to_s.start_with? Dir.pwd.to_s
|
|
66
|
+
return input if input == Dir.pwd.to_s
|
|
67
|
+
|
|
68
|
+
output = input.to_s
|
|
69
|
+
offset = (Dir.pwd).length + 1
|
|
70
|
+
output = "#{input[offset, input.size]}"
|
|
71
|
+
output.to_s
|
|
72
|
+
end
|
|
52
73
|
end
|
|
@@ -2,19 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative '../application'
|
|
4
4
|
|
|
5
|
-
# CaseManager
|
|
5
|
+
# CaseManager show method
|
|
6
6
|
class CaseManager
|
|
7
|
+
##
|
|
8
|
+
# Show cases and resume report data on screep
|
|
9
|
+
# @param mode (Symbol) Values => :resume, :cases or :all
|
|
7
10
|
def show(mode = :resume)
|
|
8
11
|
return if Application.instance.quiet?
|
|
9
12
|
|
|
13
|
+
# Show resume report data on screen
|
|
10
14
|
@report.show if %i[resume all].include? mode
|
|
11
15
|
|
|
12
|
-
|
|
16
|
+
# Show cases report data on screen
|
|
17
|
+
return if mode == :resume
|
|
13
18
|
|
|
14
19
|
@cases.each do |c|
|
|
15
|
-
puts '
|
|
20
|
+
puts '=' * 40
|
|
16
21
|
c.show
|
|
17
22
|
end
|
|
18
|
-
puts '.'
|
|
19
23
|
end
|
|
20
24
|
end
|
data/lib/teuton/cli.rb
CHANGED
data/lib/teuton/cli/play.rb
CHANGED
data/lib/teuton/cli/version.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'rainbow'
|
|
4
|
-
|
|
5
3
|
# Class method Teuton#version
|
|
6
4
|
class CLI < Thor
|
|
7
5
|
map ['v', '-v', '--version'] => 'version'
|
|
@@ -9,7 +7,6 @@ class CLI < Thor
|
|
|
9
7
|
##
|
|
10
8
|
# Display version
|
|
11
9
|
def version
|
|
12
|
-
|
|
13
|
-
puts ' (version ' + Rainbow(Application::VERSION).green + ')'
|
|
10
|
+
puts "#{Application::NAME} (version #{Application::VERSION})"
|
|
14
11
|
end
|
|
15
12
|
end
|
data/lib/teuton/files/start.rb
CHANGED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
6
|
+
<meta http-equiv="x-ua-compatible" content="IE=edge" />
|
|
7
|
+
<title>Teuton report</title>
|
|
8
|
+
<style>
|
|
9
|
+
body{margin:0;padding:0;font-family:sans-serif;font-size:12pt}a,a:visited,body{color:#303030}#content{padding-left:50px;padding-right:50px;padding-top:30px;padding-bottom:30px}#content h1{font-size:160%;margin-bottom:10px}#footer{margin-top:100px;font-size:80%;white-space:nowrap}#footer,#footer a{color:#a0a0a0}#line-wrapping-toggle{vertical-align:middle}#label-for-line-wrapping-toggle{vertical-align:middle}ul{margin-left:0}h1,h2,h3{white-space:nowrap}h2{font-size:120%}ul.tabLinks{padding-left:0;padding-top:10px;padding-bottom:10px;overflow:auto;min-width:800px;width:auto!important;width:800px}ul.tabLinks li{float:left;height:100%;list-style:none;padding-left:10px;padding-right:10px;padding-top:5px;padding-bottom:5px;margin-bottom:0;-moz-border-radius:7px;border-radius:7px;margin-right:25px;border:solid 1px #d4d4d4;background-color:#f0f0f0}ul.tabLinks li:hover{background-color:#fafafa}ul.tabLinks li.selected{background-color:#00c21b;border-color:#00c21b}ul.tabLinks a{font-size:120%;display:block;outline:0;text-decoration:none;margin:0;padding:0}ul.tabLinks li h2{margin:0;padding:0}div.selected{display:block}div.deselected{display:none}div.tab table{min-width:350px;width:auto!important;width:350px;border-collapse:collapse}div.tab table,div.tab th{border-bottom:solid #d0d0d0 1px}div.tab th{text-align:left;white-space:nowrap;padding-left:6em}div.tab th:first-child{padding-left:0}div.tab td{white-space:nowrap;padding-left:6em;padding-top:5px;padding-bottom:5px}div.tab td:first-child{padding-left:0}div.tab td.numeric,div.tab th.numeric{text-align:right}span.code{display:inline-block;margin-top:0;margin-bottom:1em}span.code pre{font-size:11pt;padding-top:10px;padding-bottom:10px;padding-left:10px;padding-right:10px;margin:0;background-color:#f7f7f7;border:solid 1px #d0d0d0;min-width:700px;width:auto!important;width:700px}span.wrapped pre{word-wrap:break-word;white-space:pre-wrap;word-break:break-all}label.hidden{display:none}div.tab td.indentPath{padding-left:3em}
|
|
10
|
+
</style>
|
|
11
|
+
<script type="text/javascript">
|
|
12
|
+
!function(e,t){"use strict";var n={};function i(e,t){e.getAttribute("className")?e.setAttribute("className",t):e.setAttribute("class",t)}function s(e){return e.getAttribute("className")?e.getAttribute("className"):e.getAttribute("class")}function r(e,t){i(e,s(e)+" "+t)}function a(e,t){i(e,s(e).replace(t,""))}function l(){var e=t.getElementById("tabs");return n.tabs=function(e){return p(e,"DIV","tab")}(e),n.titles=function(e){for(var t=[],n=0;n<e.length;n++){var i=e[n],s=p(i,"H2",null)[0];s.parentNode.removeChild(s),s.innerText?t.push(s.innerText):t.push(s.textContent)}return t}(n.tabs),n.headers=function(e){var t=p(e,"UL","tabLinks");return p(t[0],"LI",null)}(e),n.select=b,n.deselectAll=g,n.select(0),!0}function d(){return t.getElementById("line-wrapping-toggle")}function h(){for(var e=t.getElementById("tabs").getElementsByTagName("span"),n=[],i=0;i<e.length;++i)e[i].className.indexOf("code")>=0&&n.push(e[i]);return n}function c(e){for(var t=h(),n=0;n<t.length;++n)e(t[n],"wrapped")}function o(){d().checked?c(r):c(a)}function u(){if(h().length>0){var e=d(),n=t.getElementById("label-for-line-wrapping-toggle");e.onclick=o,e.checked=!1,a(n,"hidden")}}function f(){for(var e=this.id.substr(1),t=0;t<n.tabs.length;t++)if(n.tabs[t].id===e){n.select(t);break}return!1}function b(e){for(this.deselectAll(),i(this.tabs[e],"tab selected"),i(this.headers[e],"selected");this.headers[e].firstChild;)this.headers[e].removeChild(this.headers[e].firstChild);var n=t.createElement("H2");n.appendChild(t.createTextNode(this.titles[e])),this.headers[e].appendChild(n)}function g(){for(var e=0;e<this.tabs.length;e++){for(i(this.tabs[e],"tab deselected"),i(this.headers[e],"deselected");this.headers[e].firstChild;)this.headers[e].removeChild(this.headers[e].firstChild);var n=t.createElement("A");n.setAttribute("id","ltab"+e),n.setAttribute("href","#tab"+e),n.onclick=f,n.appendChild(t.createTextNode(this.titles[e])),this.headers[e].appendChild(n)}}function p(e,t,n){for(var i=[],s=e.childNodes,r=0;r<s.length;r++){var a=s.item(r);if(1===a.nodeType&&a.nodeName===t){if(n&&a.className.indexOf(n)<0)continue;i.push(a)}}return i}e.onload=function(){l(),u()}}(window,window.document);
|
|
13
|
+
</script>
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
<div id="content">
|
|
18
|
+
<h1><img title="teuton logo" alt="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAFg0lEQVQ4T23UW0yTdxgG8Pf/9UQPtIUWKJSWciiDcj4VhRoZh9iZoAJDIZuJ2wUyxS3CdMvkZmOaLFtczDJ1ajaGTBxVNEQdYRoYKBRqWTkUKAiVcmoLBaQt/aCl36LJEi94r9/8rp7nQbDDBQQEsNL2pmVa55aPURm0fNzlCiQAnIggnjIYzKZTp052t9xqmVWpVHD23Nm0J0+fKCxTlta5ubkptBOYmp162IfO+DohPUkqCheTjIZpYLAYr1+9hpHxNbNp4eH95ntnFPkKWlhUeB0JYQVeL3HJtrF0eUcwPi2pRpYi+y5DISdZzUvQ19kDVCoVZClxAICg75+ezqyU3R8+G3gmDwwJviEUC/0n9AbdJnv7ox3BDIWikC/g3GRxfDkDPVowzy4AQRAgEAVDTEIsLC1ab40Pjn0WnRT7rihcVB8RHcmYmZ4x6XWjZTuCymJlht2+cRe8XtFgvw5wFw4UKgVCJaEgkUZ4V6zLF7W92jp5bla6v79fszRWyjMZTepdcRkf7AiWV5XHmI3WO7tzFXE26xK0NNwBUZgIio+VwtTYFD6i1dVqnmou5ynz4jEfyl1xRJjI9GLmd3XHs5odwTO1ZyKfa7XNBYeUqRgJg19/vA5BIUFw6Oj7MNj/7/r44FhNf7e6IasgR8ag+9zlC3iihZfzF7raO3/YEbxy5Yqk6d7tpvyD+3ax2CxoutYIfnx/2Fe0HzRdatvMlPHT3o7eZqVSKXOTPS1MNou/Zl2p7nrc1fg2iEpLSykAQDp9+jS9uramNjo+tjI+NYE+rBkEOpMBXJ4fdLd3Gv1E4hOP6pvaD5QfiHfYN1p8GD4U74bnk7YHbW2vQVTwcUGwTW8r2qJsp3ncHnoQO9C4OD/PQyTsSEJ6EidIKIDFuQUwz5hh3bZmo3IY3w50913LKzkQRSE8LTQ6baO8+EhFWUmZGlVWVgpbB9ouLmc5i9yxiAIYADblAVovQKRLDFwaF+bNs8BmciA2Kg5IGAmM81M2p9deJwwVGtftjp+pNNrsiHqw2mKxaNDB0oMJHTZ1szefEuNH5wJGIHARm7BqWwWejgm7SOkwt2CCQH4QhAQK3+TR6XLCqHHU5rS/WmWyWGGAoVWC2G6++tPVOlRRVRWjGlCpwmXh8WWpJcD3C4Ch8WFoGLoNpG0M0tyJYDYvAofNBR6XBw6nw0uhURAiA3ppNAKTyQJeIM8zazK1X/jmfAWqqKqIURlaVYx3fOOLA/aDLFQGTVoVaNeHIIwSCmXRRWAxWwBDCCxW69bw6LA2TCJh7ZZnysbHx0nmRTNIY6ItC8vztXwavxEdLToa30p7rLLnemL2TKeAjJDCL8I/gWCRIKojADLJKYC7NgHHXRAiDNmanjE2Oh32e75+nNyc7L0VBsM4k83lGNbWVo/fvH6zCyVHJGcYsueb8UJMkjESA1KbGP5IbwOMRobCyT2QjGKhr0fzehNgf6ES1h32kRcTkyeoGFWtf6E/TkLk86ny1PaHdx58MTk5OY3kcnnSWPDLBmcplshZYgB7ggom+SpBnQB3njUTZYSlUHRDg7CFb4JCoQDP9varv/5+9Lm6U92Qsy8nd8Y4Vy2Rii51POxoA4BtlPleJtu1uVkxHW05tZFNiAjci1jPMbO/nqFFFm8sh8WJCBIEmRFCZBzH+TabbYXB8f2qv6u3PjMnM0CeIo+sv1Gvt9vty68H802wExMTA3yEzMOTjJmTHo+bI14RfM8ms5yjutFzjnWHOEQc0u92u1nL5mUZiUzCA0MCuwCRfosUSe53dnbib4/0/9VD2dnZLDqXnoU7cKp+SN+VnJacNzEx8aXLhXMFwuA+18aGYH1lXerxeHy2vR5fKp1mE4tFJTqNTvM2+B9Df2VX8nqE4QAAAABJRU5ErkJggg==" />
|
|
19
|
+
Teuton report</h1>
|
|
20
|
+
<div id="header">
|
|
21
|
+
<p><b>Test name:</b> <%= config[:tt_testname] %></p>
|
|
22
|
+
<p><b>Members:</b> <%= config[:tt_members] %></p>
|
|
23
|
+
<p><b>Grade:</b> <%= results[:grade] %></p>
|
|
24
|
+
</div>
|
|
25
|
+
<div id="tabs">
|
|
26
|
+
<ul class="tabLinks">
|
|
27
|
+
<li><a href="#tab0">Config</a></li>
|
|
28
|
+
<li><a href="#tab1">Logs</a></li>
|
|
29
|
+
<li><a href="#tab2">Groups</a></li>
|
|
30
|
+
<li><a href="#tab3">Results</a></li>
|
|
31
|
+
<li><a href="#tab4">Hall of fame</a></li>
|
|
32
|
+
</ul>
|
|
33
|
+
<div class="tab" id="tab0">
|
|
34
|
+
<h2>Config</h2>
|
|
35
|
+
<table>
|
|
36
|
+
<thead>
|
|
37
|
+
<tr>
|
|
38
|
+
<th>Property</th>
|
|
39
|
+
<th class="numeric">Value</th>
|
|
40
|
+
</tr>
|
|
41
|
+
</thead>
|
|
42
|
+
<% config.each_pair do |key, value| %>
|
|
43
|
+
<tr>
|
|
44
|
+
<td><%= key.to_s %></td>
|
|
45
|
+
<td class="numeric"><%= value.to_s %></td>
|
|
46
|
+
</tr>
|
|
47
|
+
<% end %>
|
|
48
|
+
</table>
|
|
49
|
+
</div>
|
|
50
|
+
<div class="tab" id="tab1">
|
|
51
|
+
<h2>Logs</h2>
|
|
52
|
+
<% logs.each do |line| %>
|
|
53
|
+
<p><%= line %></p>
|
|
54
|
+
<% end %>
|
|
55
|
+
</div>
|
|
56
|
+
<div class="tab" id="tab2">
|
|
57
|
+
<h2>Groups</h2>
|
|
58
|
+
<% groups.each do |group| %>
|
|
59
|
+
<h2><%= group[:title] %></h2>
|
|
60
|
+
<table>
|
|
61
|
+
<thead>
|
|
62
|
+
<tr>
|
|
63
|
+
<th>Target</th>
|
|
64
|
+
<th>Property</th>
|
|
65
|
+
<th class="numeric">Value</th>
|
|
66
|
+
</tr>
|
|
67
|
+
</thead>
|
|
68
|
+
<% group[:targets].each do |target| %>
|
|
69
|
+
<tr>
|
|
70
|
+
<td><b><%= target[:description] %></b></td>
|
|
71
|
+
<td></td>
|
|
72
|
+
<td class="numeric"></td>
|
|
73
|
+
</tr>
|
|
74
|
+
<% target.each_pair do |key, value| %>
|
|
75
|
+
<% next if key == :description %>
|
|
76
|
+
<tr>
|
|
77
|
+
<td></td>
|
|
78
|
+
<td><%= key.to_s %></td>
|
|
79
|
+
<td class="numeric"><%= value.to_s %></td>
|
|
80
|
+
</tr>
|
|
81
|
+
<% end %>
|
|
82
|
+
<% end %>
|
|
83
|
+
<% end %>
|
|
84
|
+
</table>
|
|
85
|
+
<br/>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="tab" id="tab3">
|
|
88
|
+
<h2>Results</h2>
|
|
89
|
+
<table>
|
|
90
|
+
<thead>
|
|
91
|
+
<tr>
|
|
92
|
+
<th>Property</th>
|
|
93
|
+
<th class="numeric">Value</th>
|
|
94
|
+
</tr>
|
|
95
|
+
</thead>
|
|
96
|
+
<% results.each_pair do |key, value| %>
|
|
97
|
+
<tr>
|
|
98
|
+
<td><%= key.to_s %></td>
|
|
99
|
+
<td class="numeric"><%= value.to_s %></td>
|
|
100
|
+
</tr>
|
|
101
|
+
<% end %>
|
|
102
|
+
</table>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="tab" id="tab4">
|
|
105
|
+
<h2>Hall of fame</h2>
|
|
106
|
+
<table>
|
|
107
|
+
<thead>
|
|
108
|
+
<tr>
|
|
109
|
+
<th>Grade</th>
|
|
110
|
+
<th class="numeric">Cases</th>
|
|
111
|
+
</tr>
|
|
112
|
+
</thead>
|
|
113
|
+
<% hall_of_fame.each_pair do |key, value| %>
|
|
114
|
+
<tr>
|
|
115
|
+
<td><%= key.to_s %></td>
|
|
116
|
+
<td class="numeric"><%= value.to_s %></td>
|
|
117
|
+
</tr>
|
|
118
|
+
<% end %>
|
|
119
|
+
</table>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
<div id="footer">
|
|
123
|
+
<p>
|
|
124
|
+
<div>
|
|
125
|
+
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
|
|
126
|
+
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off" />
|
|
127
|
+
</label>
|
|
128
|
+
</div>
|
|
129
|
+
Generated by <a href="http://github.com/teuton-software/teuton">Teuton <%= version %></a>
|
|
130
|
+
at <%= results[:finish_time] %>
|
|
131
|
+
</p>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
</body>
|
|
135
|
+
</html>
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
6
|
+
<meta http-equiv="x-ua-compatible" content="IE=edge" />
|
|
7
|
+
<title>Teuton report</title>
|
|
8
|
+
<style>
|
|
9
|
+
body{margin:0;padding:0;font-family:sans-serif;font-size:12pt}a,a:visited,body{color:#303030}#content{padding-left:50px;padding-right:50px;padding-top:30px;padding-bottom:30px}#content h1{font-size:160%;margin-bottom:10px}#footer{margin-top:100px;font-size:80%;white-space:nowrap}#footer,#footer a{color:#a0a0a0}#line-wrapping-toggle{vertical-align:middle}#label-for-line-wrapping-toggle{vertical-align:middle}ul{margin-left:0}h1,h2,h3{white-space:nowrap}h2{font-size:120%}ul.tabLinks{padding-left:0;padding-top:10px;padding-bottom:10px;overflow:auto;min-width:800px;width:auto!important;width:800px}ul.tabLinks li{float:left;height:100%;list-style:none;padding-left:10px;padding-right:10px;padding-top:5px;padding-bottom:5px;margin-bottom:0;-moz-border-radius:7px;border-radius:7px;margin-right:25px;border:solid 1px #d4d4d4;background-color:#f0f0f0}ul.tabLinks li:hover{background-color:#fafafa}ul.tabLinks li.selected{background-color:#00c21b;border-color:#00c21b}ul.tabLinks a{font-size:120%;display:block;outline:0;text-decoration:none;margin:0;padding:0}ul.tabLinks li h2{margin:0;padding:0}div.selected{display:block}div.deselected{display:none}div.tab table{min-width:350px;width:auto!important;width:350px;border-collapse:collapse}div.tab table,div.tab th{border-bottom:solid #d0d0d0 1px}div.tab th{text-align:left;white-space:nowrap;padding-left:6em}div.tab th:first-child{padding-left:0}div.tab td{white-space:nowrap;padding-left:6em;padding-top:5px;padding-bottom:5px}div.tab td:first-child{padding-left:0}div.tab td.numeric,div.tab th.numeric{text-align:right}span.code{display:inline-block;margin-top:0;margin-bottom:1em}span.code pre{font-size:11pt;padding-top:10px;padding-bottom:10px;padding-left:10px;padding-right:10px;margin:0;background-color:#f7f7f7;border:solid 1px #d0d0d0;min-width:700px;width:auto!important;width:700px}span.wrapped pre{word-wrap:break-word;white-space:pre-wrap;word-break:break-all}label.hidden{display:none}div.tab td.indentPath{padding-left:3em}
|
|
10
|
+
</style>
|
|
11
|
+
<script type="text/javascript">
|
|
12
|
+
!function(e,t){"use strict";var n={};function i(e,t){e.getAttribute("className")?e.setAttribute("className",t):e.setAttribute("class",t)}function s(e){return e.getAttribute("className")?e.getAttribute("className"):e.getAttribute("class")}function r(e,t){i(e,s(e)+" "+t)}function a(e,t){i(e,s(e).replace(t,""))}function l(){var e=t.getElementById("tabs");return n.tabs=function(e){return p(e,"DIV","tab")}(e),n.titles=function(e){for(var t=[],n=0;n<e.length;n++){var i=e[n],s=p(i,"H2",null)[0];s.parentNode.removeChild(s),s.innerText?t.push(s.innerText):t.push(s.textContent)}return t}(n.tabs),n.headers=function(e){var t=p(e,"UL","tabLinks");return p(t[0],"LI",null)}(e),n.select=b,n.deselectAll=g,n.select(0),!0}function d(){return t.getElementById("line-wrapping-toggle")}function h(){for(var e=t.getElementById("tabs").getElementsByTagName("span"),n=[],i=0;i<e.length;++i)e[i].className.indexOf("code")>=0&&n.push(e[i]);return n}function c(e){for(var t=h(),n=0;n<t.length;++n)e(t[n],"wrapped")}function o(){d().checked?c(r):c(a)}function u(){if(h().length>0){var e=d(),n=t.getElementById("label-for-line-wrapping-toggle");e.onclick=o,e.checked=!1,a(n,"hidden")}}function f(){for(var e=this.id.substr(1),t=0;t<n.tabs.length;t++)if(n.tabs[t].id===e){n.select(t);break}return!1}function b(e){for(this.deselectAll(),i(this.tabs[e],"tab selected"),i(this.headers[e],"selected");this.headers[e].firstChild;)this.headers[e].removeChild(this.headers[e].firstChild);var n=t.createElement("H2");n.appendChild(t.createTextNode(this.titles[e])),this.headers[e].appendChild(n)}function g(){for(var e=0;e<this.tabs.length;e++){for(i(this.tabs[e],"tab deselected"),i(this.headers[e],"deselected");this.headers[e].firstChild;)this.headers[e].removeChild(this.headers[e].firstChild);var n=t.createElement("A");n.setAttribute("id","ltab"+e),n.setAttribute("href","#tab"+e),n.onclick=f,n.appendChild(t.createTextNode(this.titles[e])),this.headers[e].appendChild(n)}}function p(e,t,n){for(var i=[],s=e.childNodes,r=0;r<s.length;r++){var a=s.item(r);if(1===a.nodeType&&a.nodeName===t){if(n&&a.className.indexOf(n)<0)continue;i.push(a)}}return i}e.onload=function(){l(),u()}}(window,window.document);
|
|
13
|
+
</script>
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
<div id="content">
|
|
18
|
+
<h1><img title="teuton logo" alt="logo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAFg0lEQVQ4T23UW0yTdxgG8Pf/9UQPtIUWKJSWciiDcj4VhRoZh9iZoAJDIZuJ2wUyxS3CdMvkZmOaLFtczDJ1ajaGTBxVNEQdYRoYKBRqWTkUKAiVcmoLBaQt/aCl36LJEi94r9/8rp7nQbDDBQQEsNL2pmVa55aPURm0fNzlCiQAnIggnjIYzKZTp052t9xqmVWpVHD23Nm0J0+fKCxTlta5ubkptBOYmp162IfO+DohPUkqCheTjIZpYLAYr1+9hpHxNbNp4eH95ntnFPkKWlhUeB0JYQVeL3HJtrF0eUcwPi2pRpYi+y5DISdZzUvQ19kDVCoVZClxAICg75+ezqyU3R8+G3gmDwwJviEUC/0n9AbdJnv7ox3BDIWikC/g3GRxfDkDPVowzy4AQRAgEAVDTEIsLC1ab40Pjn0WnRT7rihcVB8RHcmYmZ4x6XWjZTuCymJlht2+cRe8XtFgvw5wFw4UKgVCJaEgkUZ4V6zLF7W92jp5bla6v79fszRWyjMZTepdcRkf7AiWV5XHmI3WO7tzFXE26xK0NNwBUZgIio+VwtTYFD6i1dVqnmou5ynz4jEfyl1xRJjI9GLmd3XHs5odwTO1ZyKfa7XNBYeUqRgJg19/vA5BIUFw6Oj7MNj/7/r44FhNf7e6IasgR8ag+9zlC3iihZfzF7raO3/YEbxy5Yqk6d7tpvyD+3ax2CxoutYIfnx/2Fe0HzRdatvMlPHT3o7eZqVSKXOTPS1MNou/Zl2p7nrc1fg2iEpLSykAQDp9+jS9uramNjo+tjI+NYE+rBkEOpMBXJ4fdLd3Gv1E4hOP6pvaD5QfiHfYN1p8GD4U74bnk7YHbW2vQVTwcUGwTW8r2qJsp3ncHnoQO9C4OD/PQyTsSEJ6EidIKIDFuQUwz5hh3bZmo3IY3w50913LKzkQRSE8LTQ6baO8+EhFWUmZGlVWVgpbB9ouLmc5i9yxiAIYADblAVovQKRLDFwaF+bNs8BmciA2Kg5IGAmM81M2p9deJwwVGtftjp+pNNrsiHqw2mKxaNDB0oMJHTZ1szefEuNH5wJGIHARm7BqWwWejgm7SOkwt2CCQH4QhAQK3+TR6XLCqHHU5rS/WmWyWGGAoVWC2G6++tPVOlRRVRWjGlCpwmXh8WWpJcD3C4Ch8WFoGLoNpG0M0tyJYDYvAofNBR6XBw6nw0uhURAiA3ppNAKTyQJeIM8zazK1X/jmfAWqqKqIURlaVYx3fOOLA/aDLFQGTVoVaNeHIIwSCmXRRWAxWwBDCCxW69bw6LA2TCJh7ZZnysbHx0nmRTNIY6ItC8vztXwavxEdLToa30p7rLLnemL2TKeAjJDCL8I/gWCRIKojADLJKYC7NgHHXRAiDNmanjE2Oh32e75+nNyc7L0VBsM4k83lGNbWVo/fvH6zCyVHJGcYsueb8UJMkjESA1KbGP5IbwOMRobCyT2QjGKhr0fzehNgf6ES1h32kRcTkyeoGFWtf6E/TkLk86ny1PaHdx58MTk5OY3kcnnSWPDLBmcplshZYgB7ggom+SpBnQB3njUTZYSlUHRDg7CFb4JCoQDP9varv/5+9Lm6U92Qsy8nd8Y4Vy2Rii51POxoA4BtlPleJtu1uVkxHW05tZFNiAjci1jPMbO/nqFFFm8sh8WJCBIEmRFCZBzH+TabbYXB8f2qv6u3PjMnM0CeIo+sv1Gvt9vty68H802wExMTA3yEzMOTjJmTHo+bI14RfM8ms5yjutFzjnWHOEQc0u92u1nL5mUZiUzCA0MCuwCRfosUSe53dnbib4/0/9VD2dnZLDqXnoU7cKp+SN+VnJacNzEx8aXLhXMFwuA+18aGYH1lXerxeHy2vR5fKp1mE4tFJTqNTvM2+B9Df2VX8nqE4QAAAABJRU5ErkJggg==" />
|
|
19
|
+
Teuton report</h1>
|
|
20
|
+
<div id="header">
|
|
21
|
+
<p><b>Test name:</b> <%= config[:tt_testname] %></p>
|
|
22
|
+
<p><b>Case number:</b> <%= cases.size %></p>
|
|
23
|
+
</div>
|
|
24
|
+
<div id="tabs">
|
|
25
|
+
<ul class="tabLinks">
|
|
26
|
+
<li><a href="#tab0">Config</a></li>
|
|
27
|
+
<li><a href="#tab1">Cases</a></li>
|
|
28
|
+
<li><a href="#tab2">Results</a></li>
|
|
29
|
+
<li><a href="#tab3">Hall of fame</a></li>
|
|
30
|
+
</ul>
|
|
31
|
+
<div class="tab" id="tab0">
|
|
32
|
+
<h2>Config</h2>
|
|
33
|
+
<table>
|
|
34
|
+
<thead>
|
|
35
|
+
<tr>
|
|
36
|
+
<th>Property</th>
|
|
37
|
+
<th class="numeric">Value</th>
|
|
38
|
+
</tr>
|
|
39
|
+
</thead>
|
|
40
|
+
<% config.each_pair do |key, value| %>
|
|
41
|
+
<tr>
|
|
42
|
+
<td><%= key.to_s %></td>
|
|
43
|
+
<td class="numeric"><%= value.to_s %></td>
|
|
44
|
+
</tr>
|
|
45
|
+
<% end %>
|
|
46
|
+
</table>
|
|
47
|
+
</div>
|
|
48
|
+
<div class="tab" id="tab1">
|
|
49
|
+
<h2>Cases</h2>
|
|
50
|
+
<table>
|
|
51
|
+
<thead>
|
|
52
|
+
<tr>
|
|
53
|
+
<th>Target</th>
|
|
54
|
+
<th>Property</th>
|
|
55
|
+
<th class="numeric">Value</th>
|
|
56
|
+
</tr>
|
|
57
|
+
</thead>
|
|
58
|
+
<% cases.each do |item| %>
|
|
59
|
+
<tr>
|
|
60
|
+
<td><b><%= item[:id] %></b></td>
|
|
61
|
+
<td><b><%= item[:members] %></b></td>
|
|
62
|
+
<td class="numeric"><%= item[:grade] %></td>
|
|
63
|
+
</tr>
|
|
64
|
+
<% end %>
|
|
65
|
+
</table>
|
|
66
|
+
<br/>
|
|
67
|
+
</div>
|
|
68
|
+
<div class="tab" id="tab2">
|
|
69
|
+
<h2>Results</h2>
|
|
70
|
+
<table>
|
|
71
|
+
<thead>
|
|
72
|
+
<tr>
|
|
73
|
+
<th>Property</th>
|
|
74
|
+
<th class="numeric">Value</th>
|
|
75
|
+
</tr>
|
|
76
|
+
</thead>
|
|
77
|
+
<% results.each_pair do |key, value| %>
|
|
78
|
+
<tr>
|
|
79
|
+
<td><%= key.to_s %></td>
|
|
80
|
+
<td class="numeric"><%= value.to_s %></td>
|
|
81
|
+
</tr>
|
|
82
|
+
<% end %>
|
|
83
|
+
</table>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="tab" id="tab3">
|
|
86
|
+
<h2>Hall of fame</h2>
|
|
87
|
+
<table>
|
|
88
|
+
<thead>
|
|
89
|
+
<tr>
|
|
90
|
+
<th>Grade</th>
|
|
91
|
+
<th class="numeric">Cases</th>
|
|
92
|
+
</tr>
|
|
93
|
+
</thead>
|
|
94
|
+
<% hall_of_fame.each_pair do |key, value| %>
|
|
95
|
+
<tr>
|
|
96
|
+
<td><%= key.to_s %></td>
|
|
97
|
+
<td class="numeric"><%= value.to_s %></td>
|
|
98
|
+
</tr>
|
|
99
|
+
<% end %>
|
|
100
|
+
</table>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
<div id="footer">
|
|
104
|
+
<p>
|
|
105
|
+
<div>
|
|
106
|
+
<label class="hidden" id="label-for-line-wrapping-toggle" for="line-wrapping-toggle">Wrap lines
|
|
107
|
+
<input id="line-wrapping-toggle" type="checkbox" autocomplete="off" />
|
|
108
|
+
</label>
|
|
109
|
+
</div>
|
|
110
|
+
Generated by <a href="http://github.com/teuton-software/teuton">Teuton <%= version %></a> at <%= results[:finish_time] %>
|
|
111
|
+
</p>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
</body>
|
|
115
|
+
</html>
|