teuton 2.1.8 → 2.1.9
Sign up to get free protection for your applications and to get access to all the features.
- 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>
|