soda 1.1.17 → 1.1.18
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/SodaSuite +1 -0
- data/lib/Soda.rb +19 -10
- data/lib/SodaScreenShot.rb +5 -2
- data/lib/SodaSuiteSummary.rb +398 -368
- data/lib/sodainfo.rb +1 -1
- metadata +4 -4
data/bin/SodaSuite
CHANGED
data/lib/Soda.rb
CHANGED
@@ -2110,10 +2110,11 @@ JSCode
|
|
2110
2110
|
# eventFieldAction -- Method
|
2111
2111
|
#
|
2112
2112
|
#
|
2113
|
-
#
|
2113
|
+
# returns true of jsevent was fired.
|
2114
2114
|
###############################################################################
|
2115
2115
|
def eventFieldAction(event, fieldType)
|
2116
2116
|
js = nil
|
2117
|
+
js_fired = false
|
2117
2118
|
result = nil
|
2118
2119
|
foundaction = nil
|
2119
2120
|
foundvalue = nil
|
@@ -2133,7 +2134,9 @@ JSCode
|
|
2133
2134
|
'exists',
|
2134
2135
|
'link',
|
2135
2136
|
'append',
|
2136
|
-
'disabled'
|
2137
|
+
'disabled',
|
2138
|
+
'jscriptevent'
|
2139
|
+
]
|
2137
2140
|
|
2138
2141
|
if (@SIGNAL_STOP != false)
|
2139
2142
|
exit(-1)
|
@@ -2167,6 +2170,9 @@ JSCode
|
|
2167
2170
|
end
|
2168
2171
|
|
2169
2172
|
case (foundaction)
|
2173
|
+
when "jscriptevent"
|
2174
|
+
fieldType.jsevent(@curEl, js, true)
|
2175
|
+
js_fired = true
|
2170
2176
|
when "append"
|
2171
2177
|
result = fieldType.append(@curEl, replaceVars(event['append']))
|
2172
2178
|
if (result != 0)
|
@@ -2285,6 +2291,8 @@ JSCode
|
|
2285
2291
|
e_dump = SodaUtils.DumpEvent(event)
|
2286
2292
|
@rep.log("Event Dump: #{e_dump}\n", SodaUtils::EVENT)
|
2287
2293
|
end
|
2294
|
+
|
2295
|
+
return js_fired
|
2288
2296
|
end
|
2289
2297
|
|
2290
2298
|
###############################################################################
|
@@ -2417,6 +2425,7 @@ JSCode
|
|
2417
2425
|
result = 0
|
2418
2426
|
jswait = true
|
2419
2427
|
result = 0
|
2428
|
+
js_fired = false
|
2420
2429
|
exception_event = nil
|
2421
2430
|
|
2422
2431
|
for next_event in events
|
@@ -2603,8 +2612,14 @@ JSCode
|
|
2603
2612
|
next
|
2604
2613
|
end
|
2605
2614
|
|
2615
|
+
# If we have a field here is the default actions
|
2616
|
+
# that can be done on it
|
2617
|
+
if (@curEl)
|
2618
|
+
js_fired = eventFieldAction(event, fieldType)
|
2619
|
+
end
|
2620
|
+
|
2606
2621
|
jswait = true
|
2607
|
-
if (event.key?("jscriptevent") &&
|
2622
|
+
if (event.key?("jscriptevent") && (js_fired != true) &&
|
2608
2623
|
(replaceVars(event['jscriptevent']) == "onkeyup"))
|
2609
2624
|
if (event.key?('jswait'))
|
2610
2625
|
jswait = false if (event['jswait'] =~ /false/i)
|
@@ -2612,7 +2627,7 @@ JSCode
|
|
2612
2627
|
|
2613
2628
|
js = replaceVars(event['jscriptevent'])
|
2614
2629
|
fieldType.jsevent(@curEl, js, jswait)
|
2615
|
-
elsif (event.key?("jscriptevent"))
|
2630
|
+
elsif (event.key?("jscriptevent") && (js_fired != true))
|
2616
2631
|
if (event.key?('jswait'))
|
2617
2632
|
jswait = false if (event['jswait'] =~ /false/i)
|
2618
2633
|
end
|
@@ -2620,12 +2635,6 @@ JSCode
|
|
2620
2635
|
fieldType.jsevent(@curEl, js, jswait)
|
2621
2636
|
end
|
2622
2637
|
|
2623
|
-
# If we have a field here is the default actions
|
2624
|
-
# that can be done on it
|
2625
|
-
if (@curEl)
|
2626
|
-
eventFieldAction(event, fieldType)
|
2627
|
-
end
|
2628
|
-
|
2629
2638
|
if (browser_closed != true && jswait != false)
|
2630
2639
|
CheckJavaScriptErrors()
|
2631
2640
|
end
|
data/lib/SodaScreenShot.rb
CHANGED
@@ -92,8 +92,11 @@ class SodaScreenShot
|
|
92
92
|
when /windows/i
|
93
93
|
require 'win32/screenshot'
|
94
94
|
@outputfile = "#{dir}/#{OUTPUT_FILE}#{time}-#{hostname}.bmp"
|
95
|
-
|
96
|
-
|
95
|
+
begin
|
96
|
+
img = Win32::Screenshot::Take.of(:desktop)
|
97
|
+
img.write(@outputfile)
|
98
|
+
rescue Exception => e
|
99
|
+
end
|
97
100
|
end
|
98
101
|
end
|
99
102
|
|
data/lib/SodaSuiteSummary.rb
CHANGED
@@ -35,225 +35,7 @@ require 'libxml'
|
|
35
35
|
require 'pp'
|
36
36
|
require 'SodaReportSummery'
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
###############################################################################
|
41
|
-
# initialize -- constructor
|
42
|
-
# This is the class constructor. Really this does all the needed work.
|
43
|
-
#
|
44
|
-
# Params:
|
45
|
-
# dir: This is the directory with raw soda logs in it.
|
46
|
-
# outfile: This is the new summery html file to create.
|
47
|
-
# create_links: This will create links to the soda report files in the
|
48
|
-
# summery.
|
49
|
-
#
|
50
|
-
# Results:
|
51
|
-
# Creates a new class and html summery file. Will raise and exception on
|
52
|
-
# any errors.
|
53
|
-
#
|
54
|
-
###############################################################################
|
55
|
-
def initialize(dir ="", outfile = "", create_links = false)
|
56
|
-
log_files = nil
|
57
|
-
report_data = nil
|
58
|
-
result = 0
|
59
|
-
html_tmp_file = ""
|
60
|
-
timout = true
|
61
|
-
|
62
|
-
if (dir.empty?)
|
63
|
-
raise "Empty 'dir' param!\n"
|
64
|
-
elsif (outfile.empty?)
|
65
|
-
raise "Empty 'outfile param!"
|
66
|
-
end
|
67
|
-
|
68
|
-
html_tmp_file = File.dirname(outfile)
|
69
|
-
html_tmp_file += "/summery.tmp"
|
70
|
-
|
71
|
-
for i in 0..120
|
72
|
-
if (!File.exist?(html_tmp_file))
|
73
|
-
timeout = false
|
74
|
-
break
|
75
|
-
end
|
76
|
-
|
77
|
-
timeout = true
|
78
|
-
sleep(1)
|
79
|
-
end
|
80
|
-
|
81
|
-
# This should go back into production after moving away from our
|
82
|
-
# internal nfs sever we are using for reporting...
|
83
|
-
#
|
84
|
-
# if (timeout != false)
|
85
|
-
# raise "Timed out waiting for lock to be released on file:"+
|
86
|
-
# " \"#{html_tmp_file}\"!\n"
|
87
|
-
# end
|
88
|
-
|
89
|
-
log_files = GetLogFiles(dir)
|
90
|
-
if ( (log_files == nil) || (log_files.length < 1) )
|
91
|
-
raise "Failed calling: GetLogFiles(#{dir})!"
|
92
|
-
end
|
93
|
-
|
94
|
-
report_data = GenerateReportData(log_files)
|
95
|
-
if (report_data.length < 1)
|
96
|
-
raise "No report data found when calling: GenerateReportData()!"
|
97
|
-
end
|
98
|
-
|
99
|
-
result = GenHtmlReport(report_data, html_tmp_file, create_links)
|
100
|
-
if (result != 0)
|
101
|
-
raise "Failed calling: GenHtmlReport()!"
|
102
|
-
end
|
103
|
-
|
104
|
-
File.rename(html_tmp_file, outfile)
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
###############################################################################
|
109
|
-
# GetLogFiles -- method
|
110
|
-
# This function gets all the log files in a given dir puts them in a list.
|
111
|
-
#
|
112
|
-
# Params:
|
113
|
-
# dir: this is the directory that holds the log files.
|
114
|
-
#
|
115
|
-
# Results:
|
116
|
-
# returns nil on error, else a list of all the log files in the dir.
|
117
|
-
#
|
118
|
-
###############################################################################
|
119
|
-
def GetLogFiles(dir)
|
120
|
-
files = nil
|
121
|
-
|
122
|
-
if (!File.directory?(dir))
|
123
|
-
print "(!)Error: #{dir} is not a directory!\n"
|
124
|
-
return nil
|
125
|
-
end
|
126
|
-
|
127
|
-
files = File.join("#{dir}", "*.xml")
|
128
|
-
files = Dir.glob(files).sort_by{|f| File.stat(f).mtime}
|
129
|
-
|
130
|
-
return files
|
131
|
-
end
|
132
|
-
|
133
|
-
private :GetLogFiles
|
134
|
-
|
135
|
-
###############################################################################
|
136
|
-
# GetTestInfo -- method
|
137
|
-
# This method reads the suite xml report and converts it into a hash.
|
138
|
-
#
|
139
|
-
# Input:
|
140
|
-
# kids: The XML node for the <test> element.
|
141
|
-
#
|
142
|
-
# Output:
|
143
|
-
# returns a hash of data.
|
144
|
-
#
|
145
|
-
###############################################################################
|
146
|
-
def GetTestInfo(kids)
|
147
|
-
test_info = {}
|
148
|
-
|
149
|
-
kids.each do |kid|
|
150
|
-
next if (kid.name =~ /text/i)
|
151
|
-
name = kid.name
|
152
|
-
name = name.gsub("_", " ")
|
153
|
-
test_info[name] = kid.content()
|
154
|
-
end
|
155
|
-
|
156
|
-
return test_info
|
157
|
-
end
|
158
|
-
|
159
|
-
###############################################################################
|
160
|
-
# GenerateReportData -- method
|
161
|
-
# This function generates needed data from each file passed in.
|
162
|
-
#
|
163
|
-
# Params:
|
164
|
-
# files: This is a list of files to read data from.
|
165
|
-
#
|
166
|
-
# Results:
|
167
|
-
# returns an array of hashed data.
|
168
|
-
#
|
169
|
-
###############################################################################
|
170
|
-
def GenerateReportData(files)
|
171
|
-
test_info = {}
|
172
|
-
test_info_list = []
|
173
|
-
|
174
|
-
files.each do |f|
|
175
|
-
print "(*)Opening file: #{f}\n"
|
176
|
-
|
177
|
-
begin
|
178
|
-
parser = LibXML::XML::Parser.file(f)
|
179
|
-
LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER)
|
180
|
-
doc = parser.parse()
|
181
|
-
rescue Exception => e
|
182
|
-
print "(!)Error: Failed trying to parse XML file: '#{f}'!\n"
|
183
|
-
print "--)Exception: #{e.message}\n"
|
184
|
-
print "--)Skipping file!\n"
|
185
|
-
next
|
186
|
-
ensure
|
187
|
-
end
|
188
|
-
|
189
|
-
suites = []
|
190
|
-
doc.root.each do |suite|
|
191
|
-
next if (suite.name !~ /suite/)
|
192
|
-
suites.push(suite)
|
193
|
-
end
|
194
|
-
|
195
|
-
suites.each do |suite|
|
196
|
-
tmp_hash = {'tests' => []}
|
197
|
-
suite.children.each do |kid|
|
198
|
-
case (kid.name)
|
199
|
-
when "suitefile"
|
200
|
-
tmp_hash['suitefile'] = kid.content()
|
201
|
-
when "test"
|
202
|
-
tmp_test_data = GetTestInfo(kid.children)
|
203
|
-
tmp_hash['tests'].push(tmp_test_data)
|
204
|
-
end # end case #
|
205
|
-
end
|
206
|
-
|
207
|
-
base_name = File.basename(tmp_hash['suitefile'])
|
208
|
-
test_info[base_name] = tmp_hash
|
209
|
-
test_info_list.push(tmp_hash)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
return test_info
|
214
|
-
end
|
215
|
-
|
216
|
-
private :GenerateReportData
|
217
|
-
|
218
|
-
###############################################################################
|
219
|
-
# GenHtmlReport -- method
|
220
|
-
# This function generates an html report from an array of hashed data.
|
221
|
-
#
|
222
|
-
# Params:
|
223
|
-
# data: A hash of suites, and their test info.
|
224
|
-
# reportfile: This is the html file to create.
|
225
|
-
#
|
226
|
-
# Results:
|
227
|
-
# Creates an html report file. Retruns -1 on error, else 0 on success.
|
228
|
-
#
|
229
|
-
###############################################################################
|
230
|
-
def GenHtmlReport(data, reportfile, create_links = false)
|
231
|
-
fd = nil
|
232
|
-
result = 0
|
233
|
-
totals = {}
|
234
|
-
log_file_td = ""
|
235
|
-
report_file = ""
|
236
|
-
now = nil
|
237
|
-
suite_totals = {}
|
238
|
-
total_failure_count = 0
|
239
|
-
total_non_ran_count = 0
|
240
|
-
|
241
|
-
begin
|
242
|
-
fd = File.new(reportfile, "w+")
|
243
|
-
rescue Exception => e
|
244
|
-
fd = nil
|
245
|
-
result = -1
|
246
|
-
print "Error: trying to open file!\n"
|
247
|
-
print "Exception: #{e.message}\n"
|
248
|
-
print "StackTrace: #{e.backtrace.join("\n")}\n"
|
249
|
-
ensure
|
250
|
-
if (result != 0)
|
251
|
-
return -1
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
now = Time.now.getlocal()
|
256
|
-
html_header = <<HTML
|
38
|
+
$HTML_HEADER = <<HTML
|
257
39
|
<html>
|
258
40
|
<style type="text/css">
|
259
41
|
body {
|
@@ -811,160 +593,381 @@ table {
|
|
811
593
|
</tr>
|
812
594
|
HTML
|
813
595
|
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
596
|
+
class SodaSuiteSummary
|
597
|
+
|
598
|
+
###############################################################################
|
599
|
+
# initialize -- constructor
|
600
|
+
# This is the class constructor. Really this does all the needed work.
|
601
|
+
#
|
602
|
+
# Params:
|
603
|
+
# dir: This is the directory with raw soda logs in it.
|
604
|
+
# outfile: This is the new summery html file to create.
|
605
|
+
# create_links: This will create links to the soda report files in the
|
606
|
+
# summery.
|
607
|
+
#
|
608
|
+
# Results:
|
609
|
+
# Creates a new class and html summery file. Will raise and exception on
|
610
|
+
# any errors.
|
611
|
+
#
|
612
|
+
###############################################################################
|
613
|
+
def initialize(dir ="", outfile = "", create_links = false)
|
614
|
+
log_files = nil
|
615
|
+
report_data = nil
|
616
|
+
result = 0
|
617
|
+
html_tmp_file = ""
|
618
|
+
timout = true
|
619
|
+
|
620
|
+
if (dir.empty?)
|
621
|
+
raise "Empty 'dir' param!\n"
|
622
|
+
elsif (outfile.empty?)
|
623
|
+
raise "Empty 'outfile param!"
|
624
|
+
end
|
625
|
+
|
626
|
+
html_tmp_file = File.dirname(outfile)
|
627
|
+
html_tmp_file += "/summery.tmp"
|
628
|
+
|
629
|
+
for i in 0..120
|
630
|
+
if (!File.exist?(html_tmp_file))
|
631
|
+
timeout = false
|
632
|
+
break
|
633
|
+
end
|
634
|
+
|
635
|
+
timeout = true
|
636
|
+
sleep(1)
|
637
|
+
end
|
638
|
+
|
639
|
+
# This should go back into production after moving away from our
|
640
|
+
# internal nfs sever we are using for reporting...
|
641
|
+
#
|
642
|
+
# if (timeout != false)
|
643
|
+
# raise "Timed out waiting for lock to be released on file:"+
|
644
|
+
# " \"#{html_tmp_file}\"!\n"
|
645
|
+
# end
|
646
|
+
|
647
|
+
log_files = GetLogFiles(dir)
|
648
|
+
if ( (log_files == nil) || (log_files.length < 1) )
|
649
|
+
raise "Failed calling: GetLogFiles(#{dir})!"
|
650
|
+
end
|
651
|
+
|
652
|
+
report_data = GenerateReportData(log_files)
|
653
|
+
if (report_data.length < 1)
|
654
|
+
raise "No report data found when calling: GenerateReportData()!"
|
655
|
+
end
|
656
|
+
|
657
|
+
result = GenHtmlReport2(report_data, html_tmp_file, create_links)
|
658
|
+
if (result != 0)
|
659
|
+
raise "Failed calling: GenHtmlReport2()!"
|
660
|
+
end
|
661
|
+
|
662
|
+
File.rename(html_tmp_file, outfile)
|
663
|
+
|
664
|
+
end
|
665
|
+
|
666
|
+
###############################################################################
|
667
|
+
# GetLogFiles -- method
|
668
|
+
# This function gets all the log files in a given dir puts them in a list.
|
669
|
+
#
|
670
|
+
# Params:
|
671
|
+
# dir: this is the directory that holds the log files.
|
672
|
+
#
|
673
|
+
# Results:
|
674
|
+
# returns nil on error, else a list of all the log files in the dir.
|
675
|
+
#
|
676
|
+
###############################################################################
|
677
|
+
def GetLogFiles(dir)
|
678
|
+
files = nil
|
679
|
+
|
680
|
+
if (!File.directory?(dir))
|
681
|
+
print "(!)Error: #{dir} is not a directory!\n"
|
682
|
+
return nil
|
683
|
+
end
|
684
|
+
|
685
|
+
files = File.join("#{dir}", "*.xml")
|
686
|
+
files = Dir.glob(files).sort_by{|f| File.stat(f).mtime}
|
687
|
+
|
688
|
+
return files
|
689
|
+
end
|
690
|
+
|
691
|
+
private :GetLogFiles
|
692
|
+
|
693
|
+
###############################################################################
|
694
|
+
# GetTestInfo -- method
|
695
|
+
# This method reads the suite xml report and converts it into a hash.
|
696
|
+
#
|
697
|
+
# Input:
|
698
|
+
# kids: The XML node for the <test> element.
|
699
|
+
#
|
700
|
+
# Output:
|
701
|
+
# returns a hash of data.
|
702
|
+
#
|
703
|
+
###############################################################################
|
704
|
+
def GetTestInfo(kids)
|
705
|
+
test_info = {}
|
706
|
+
|
707
|
+
kids.each do |kid|
|
708
|
+
next if (kid.name =~ /text/i)
|
709
|
+
name = kid.name
|
710
|
+
name = name.gsub("_", " ")
|
711
|
+
test_info[name] = kid.content()
|
712
|
+
end
|
713
|
+
|
714
|
+
return test_info
|
715
|
+
end
|
716
|
+
|
717
|
+
###############################################################################
|
718
|
+
# GenerateReportData -- method
|
719
|
+
# This function generates needed data from each file passed in.
|
720
|
+
#
|
721
|
+
# Params:
|
722
|
+
# files: This is a list of files to read data from.
|
723
|
+
#
|
724
|
+
# Results:
|
725
|
+
# returns an array of hashed data.
|
726
|
+
#
|
727
|
+
###############################################################################
|
728
|
+
def GenerateReportData(files)
|
729
|
+
test_info = {}
|
730
|
+
test_info_list = []
|
731
|
+
|
732
|
+
files.each do |f|
|
733
|
+
print "(*)Reading XML file: #{f}\n"
|
734
|
+
|
735
|
+
begin
|
736
|
+
parser = LibXML::XML::Parser.file(f)
|
737
|
+
LibXML::XML::Error.set_handler(&LibXML::XML::Error::QUIET_HANDLER)
|
738
|
+
doc = parser.parse()
|
739
|
+
rescue Exception => e
|
740
|
+
print "(!)Error: Failed trying to parse XML file: '#{f}'!\n"
|
741
|
+
print "--)Exception: #{e.message}\n"
|
742
|
+
print "--)Skipping file!\n"
|
743
|
+
next
|
744
|
+
ensure
|
745
|
+
end
|
746
|
+
|
747
|
+
suites = []
|
748
|
+
doc.root.each do |suite|
|
749
|
+
next if (suite.name !~ /suite/)
|
750
|
+
suites.push(suite)
|
751
|
+
end
|
752
|
+
|
753
|
+
suites.each do |suite|
|
754
|
+
tmp_hash = {'tests' => []}
|
755
|
+
suite.children.each do |kid|
|
756
|
+
case (kid.name)
|
757
|
+
when "suitefile"
|
758
|
+
tmp_hash['suitefile'] = kid.content()
|
759
|
+
when "test"
|
760
|
+
tmp_test_data = GetTestInfo(kid.children)
|
761
|
+
tmp_hash['tests'].push(tmp_test_data)
|
762
|
+
end # end case #
|
866
763
|
end
|
764
|
+
|
765
|
+
base_name = File.basename(tmp_hash['suitefile'])
|
766
|
+
test_info[base_name] = tmp_hash
|
767
|
+
test_info_list.push(tmp_hash)
|
768
|
+
end
|
769
|
+
|
770
|
+
print "(*)Finished.\n"
|
771
|
+
end
|
772
|
+
|
773
|
+
return test_info
|
774
|
+
end
|
775
|
+
private :GenerateReportData
|
776
|
+
|
777
|
+
|
778
|
+
def SumSuiteTests(tests, suitename)
|
779
|
+
lib_file_count = 0
|
780
|
+
report = {
|
781
|
+
'Total Time' => nil
|
782
|
+
}
|
783
|
+
summary_int_fields = [
|
784
|
+
'Test JavaScript Error Count',
|
785
|
+
'Test WatchDog Count',
|
786
|
+
'Test Assert Failures',
|
787
|
+
'Test CSS Error Count',
|
788
|
+
'Test Blocked Count',
|
789
|
+
'Test Assert Count',
|
790
|
+
'Test Warning Count',
|
791
|
+
'Test Skip Count',
|
792
|
+
'Test Event Count',
|
793
|
+
'Test Exceptions',
|
794
|
+
'Test Pass Count',
|
795
|
+
'Test Failed Count',
|
796
|
+
'Test Ran Count',
|
797
|
+
'Test Failure Count'
|
798
|
+
]
|
799
|
+
|
800
|
+
print "(*)Summing #{suitename}..."
|
801
|
+
|
802
|
+
# zero out all of the int keys, and make sure they are int's and not
|
803
|
+
# strings.
|
804
|
+
summary_int_fields.each do |key|
|
805
|
+
report[key] = 0
|
806
|
+
end
|
807
|
+
|
808
|
+
tests.sort_by{|h| h['Test Order'].to_i}.each do |test|
|
809
|
+
dir_name = File.dirname(test['testfile'])
|
810
|
+
if (dir_name =~ /lib/i)
|
811
|
+
lib_file_count += 1
|
812
|
+
# skip libs david doesn't want them.
|
813
|
+
next
|
814
|
+
end
|
815
|
+
|
816
|
+
summary_int_fields.each do |total_field|
|
817
|
+
report[total_field] += test[total_field].to_i()
|
818
|
+
end
|
819
|
+
|
820
|
+
report['Test Ran Count'] += 1
|
821
|
+
|
822
|
+
# count tests that pass and fail. #
|
823
|
+
if (test['result'].to_i != 0)
|
824
|
+
report['Test Failed Count'] += 1
|
825
|
+
else
|
826
|
+
report['Test Pass Count'] += 1
|
827
|
+
end
|
828
|
+
|
829
|
+
# add up times #
|
830
|
+
stop_time = test['Test Stop Time']
|
831
|
+
start_time = DateTime.strptime("#{test['Test Start Time']}",
|
832
|
+
"%m/%d/%Y-%H:%M:%S")
|
833
|
+
stop_time = DateTime.strptime("#{test['Test Stop Time']}",
|
834
|
+
"%m/%d/%Y-%H:%M:%S")
|
835
|
+
|
836
|
+
diff = (stop_time - start_time)
|
837
|
+
if (report['Total Time'] == nil)
|
838
|
+
report['Total Time'] = diff
|
839
|
+
else
|
840
|
+
report['Total Time'] += diff
|
867
841
|
end
|
868
842
|
end
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
843
|
+
|
844
|
+
# need to do away with tests that did not run for a good reason #
|
845
|
+
report['Test Ran Count'] -= report['Test Blocked Count']
|
846
|
+
report['Test Ran Count'] -= report['Test Skip Count']
|
847
|
+
|
848
|
+
report['Total Test Count'] = tests.length()
|
849
|
+
if (lib_file_count > 0)
|
850
|
+
report['Total Test Count'] -= lib_file_count
|
851
|
+
end
|
852
|
+
|
853
|
+
print "\b\b\b: Done.\n"
|
854
|
+
|
855
|
+
return report
|
856
|
+
end
|
857
|
+
|
858
|
+
###############################################################################
|
859
|
+
# GenHtmlReport2 -- method
|
860
|
+
# This function generates an html report from an array of hashed data.
|
861
|
+
#
|
862
|
+
# Params:
|
863
|
+
# data: A hash of suites, and their test info.
|
864
|
+
# reportfile: This is the html file to create.
|
865
|
+
#
|
866
|
+
# Results:
|
867
|
+
# Creates an html report file. Retruns -1 on error, else 0 on success.
|
868
|
+
#
|
869
|
+
###############################################################################
|
870
|
+
def GenHtmlReport2(data, reportfile, create_links = false)
|
871
|
+
suites_totals = {}
|
872
|
+
summary_totals = {}
|
873
|
+
|
874
|
+
print "(*)Processing data...\n"
|
875
|
+
|
876
|
+
# first sum up all of the test results for each suite #
|
877
|
+
suites = data.keys.sort()
|
878
|
+
suites.each do |suite_name|
|
879
|
+
suites_totals[suite_name] = {} # new suite name for the totals #
|
880
|
+
suite_data = data[suite_name]
|
881
|
+
suites_totals[suite_name] = SumSuiteTests(suite_data['tests'], suite_name)
|
882
|
+
end
|
883
|
+
|
884
|
+
# second sum up all of the suite sums for the totals for the summary #
|
885
|
+
suites_totals.keys.each do |suite_name|
|
886
|
+
suite_data = suites_totals[suite_name]
|
887
|
+
suite_data.each do |suite_key, suite_val|
|
888
|
+
# make sure it is set to an int if it doesn't exist #
|
889
|
+
if (suite_key !~ /time/i && !summary_totals.key?(suite_key))
|
890
|
+
summary_totals[suite_key] = 0
|
874
891
|
end
|
875
892
|
|
876
|
-
if (
|
877
|
-
|
893
|
+
if (suite_key =~ /time/i && !summary_totals.key?(suite_key))
|
894
|
+
summary_totals[suite_key] = suite_val
|
878
895
|
else
|
879
|
-
|
896
|
+
# we can see a nil time if the suite only ran modules, and not
|
897
|
+
# any tests. Once again this is because david doesn't want reports
|
898
|
+
# on modules.... Lame... Lame...
|
899
|
+
summary_totals[suite_key] += suite_val if (suite_val != nil)
|
880
900
|
end
|
881
901
|
end
|
882
902
|
end
|
883
903
|
|
904
|
+
# create a new summary file #
|
905
|
+
fd = File.new(reportfile, "w+")
|
906
|
+
fd.write($HTML_HEADER)
|
907
|
+
|
884
908
|
row_id = 0
|
885
|
-
|
886
|
-
suite_hash = totals[suite_name]
|
909
|
+
suites_totals.sort.each do |suite_name, suite_data|
|
887
910
|
row_id += 1
|
888
911
|
report_file = "#{suite_name}"
|
889
|
-
hours,minutes,seconds,frac =
|
890
|
-
Date.day_fraction_to_time(suite_hash['Total Time'])
|
891
|
-
|
892
|
-
if (hours < 10)
|
893
|
-
hours = "0#{hours}"
|
894
|
-
end
|
895
912
|
|
896
|
-
|
897
|
-
|
898
|
-
|
913
|
+
# again another hack to avoid lib files in the reports... #
|
914
|
+
if (suite_data['Total Time'] != nil)
|
915
|
+
hours,minutes,seconds,frac =
|
916
|
+
Date.day_fraction_to_time(suite_data['Total Time'])
|
917
|
+
|
918
|
+
if (hours < 10)
|
919
|
+
hours = "0#{hours}"
|
920
|
+
end
|
899
921
|
|
900
|
-
|
901
|
-
|
902
|
-
|
922
|
+
if (minutes < 10)
|
923
|
+
minutes = "0#{minutes}"
|
924
|
+
end
|
903
925
|
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
926
|
+
if (seconds < 10)
|
927
|
+
seconds = "0#{seconds}"
|
928
|
+
end
|
929
|
+
else
|
930
|
+
hours = 0
|
931
|
+
minutes = 0
|
932
|
+
seconds = 0
|
933
|
+
end
|
908
934
|
|
909
935
|
test_run_class = "td_run_data"
|
910
|
-
if (
|
911
|
-
|
912
|
-
end
|
913
|
-
if (suite_hash['Test Assert Failures'] > 0 ||
|
914
|
-
suite_hash['Test Exceptions'] > 0)
|
936
|
+
if (suite_data['Test Assert Failures'] > 0 ||
|
937
|
+
suite_data['Test Exceptions'] > 0)
|
915
938
|
test_run_class = "td_run_data_error"
|
916
939
|
end
|
917
940
|
|
918
941
|
exceptions_td = "td_exceptions_data"
|
919
|
-
if (
|
942
|
+
if (suite_data['Test Exceptions'] > 0)
|
920
943
|
exceptions_td = "td_exceptions_error_data"
|
921
944
|
end
|
922
945
|
|
923
946
|
asserts_td = "td_assert_data"
|
924
|
-
if (
|
947
|
+
if (suite_data['Test Assert Failures'] > 0)
|
925
948
|
asserts_td = "td_assert_error_data"
|
926
949
|
end
|
927
950
|
|
928
951
|
watchdog_td = "td_watchdog_data"
|
929
|
-
if (
|
952
|
+
if (suite_data['Test WatchDog Count'] > 0)
|
930
953
|
watchdog_td = "td_watchdog_error_data"
|
931
954
|
end
|
932
955
|
|
933
956
|
jscript_td = "td_javascript_data"
|
934
|
-
if (
|
957
|
+
if (suite_data['Test JavaScript Error Count'] > 0)
|
935
958
|
jscript_td = "td_javascript_error_data"
|
936
959
|
end
|
937
960
|
|
938
961
|
other_td = "td_other_data"
|
939
|
-
if (
|
962
|
+
if (suite_data['Test Failure Count'] > 0)
|
940
963
|
other_td = "td_other_error_data"
|
941
964
|
end
|
942
965
|
|
943
|
-
t_passedcount = suite_hash['Test Count']
|
944
|
-
t_passedcount -= suite_hash['Test Failure Count']
|
945
|
-
|
946
966
|
total_failures = 0
|
947
|
-
total_failures +=
|
948
|
-
total_failures +=
|
949
|
-
total_failures +=
|
950
|
-
total_failures +=
|
951
|
-
total_failures += suite_hash['Test Other Failures']
|
952
|
-
total_failures += suite_hash['Test JavaScript Error Count']
|
953
|
-
total_failure_count += total_failures
|
954
|
-
|
955
|
-
# debug #
|
956
|
-
suite_hash['Test Other Failures'] = suite_hash['Test Failure Count']
|
957
|
-
# end debug #
|
958
|
-
|
959
|
-
ran_count = suite_hash['Test Count'].to_i()
|
960
|
-
ran_count -= suite_hash['Test WatchDog Count']
|
961
|
-
ran_count -= suite_hash['Test Blocked Count']
|
962
|
-
ran_count -= suite_hash['Lib File Count']
|
963
|
-
|
964
|
-
total_non_ran_count += suite_hash['Test WatchDog Count']
|
965
|
-
total_non_ran_count += suite_hash['Test Blocked Count']
|
966
|
-
total_non_lib_count = suite_hash['Test Count']
|
967
|
-
total_non_lib_count -= suite_hash['Lib File Count']
|
967
|
+
total_failures += suite_data['Test Failure Count']
|
968
|
+
total_failures += suite_data['Test Exceptions']
|
969
|
+
total_failures += suite_data['Test Assert Failures']
|
970
|
+
total_failures += suite_data['Test JavaScript Error Count']
|
968
971
|
|
969
972
|
total_failures_td = "td_total_data"
|
970
973
|
if (total_failures > 0)
|
@@ -980,41 +983,39 @@ HTML
|
|
980
983
|
"\t<td class=\"td_file_data\"><a href=\"#{suite_mini_file}\">"+
|
981
984
|
"#{suite_name}</a></td>\n"+
|
982
985
|
"\t<td class=\"#{test_run_class}\">"+
|
983
|
-
|
986
|
+
"#{suite_data['Test Ran Count']}/"+
|
987
|
+
"#{suite_data['Total Test Count']}</td>\n"+
|
984
988
|
"\t<td class=\"td_passed_data\">"+
|
985
|
-
"#{
|
989
|
+
"#{suite_data['Test Pass Count']}</td>\n"+
|
986
990
|
"\t<td class=\"td_failed_data\">"+
|
987
|
-
"#{
|
991
|
+
"#{suite_data['Test Failed Count']}</td>\n"+
|
988
992
|
"\t<td class=\"td_blocked_data\">"+
|
989
|
-
"#{
|
993
|
+
"#{suite_data['Test Blocked Count']}</td>\n"+
|
990
994
|
"\t<td class=\"td_skipped_data\">"+
|
991
|
-
"#{
|
995
|
+
"#{suite_data['Test Skip Count']}</td>\n"+
|
992
996
|
"\t<td class=\"#{watchdog_td}\">"+
|
993
|
-
"#{
|
997
|
+
"#{suite_data['Test WatchDog Count']}</td>\n"+
|
994
998
|
"\t<td class=\"#{exceptions_td}\">"+
|
995
|
-
"#{
|
999
|
+
"#{suite_data['Test Exceptions']}</td>\n"+
|
996
1000
|
"\t<td class=\"#{jscript_td}\">"+
|
997
|
-
"#{
|
1001
|
+
"#{suite_data['Test JavaScript Error Count']}</td>\n"+
|
998
1002
|
"\t<td class=\"#{asserts_td}\">"+
|
999
|
-
"#{
|
1003
|
+
"#{suite_data['Test Assert Failures']}</td>\n"+
|
1000
1004
|
"\t<td class=\"#{other_td}\">"+
|
1001
|
-
"#{
|
1005
|
+
"#{suite_data['Test Failure Count']}</td>\n"+
|
1002
1006
|
"\t<td class=\"#{total_failures_td}\">#{total_failures}</td>\n"+
|
1003
1007
|
"\t<td class=\"td_css_data\">"+
|
1004
|
-
"#{
|
1008
|
+
"#{suite_data['Test CSS Error Count']}</td>\n"+
|
1005
1009
|
"\t<td class=\"td_sodawarnings_data\">"+
|
1006
|
-
"#{
|
1010
|
+
"#{suite_data['Test Warning Count']}</td>\n"+
|
1007
1011
|
"\t<td class=\"td_time_data\">"+
|
1008
1012
|
"#{hours}:#{minutes}:#{seconds}</td>\n</tr>\n"
|
1009
1013
|
fd.write(str)
|
1010
|
-
|
1011
|
-
|
1012
|
-
test_totals = suite_totals['Test Count']
|
1013
|
-
test_totals += suite_totals['Test Skip Count']
|
1014
|
-
test_totals += suite_totals['Test Blocked Count']
|
1014
|
+
end # end suites_totals loop #
|
1015
1015
|
|
1016
1016
|
hours,minutes,seconds,frac =
|
1017
|
-
Date.day_fraction_to_time(
|
1017
|
+
Date.day_fraction_to_time(summary_totals['Total Time'])
|
1018
|
+
|
1018
1019
|
if (hours < 10)
|
1019
1020
|
hours = "0#{hours}"
|
1020
1021
|
end
|
@@ -1027,34 +1028,44 @@ HTML
|
|
1027
1028
|
seconds = "0#{seconds}"
|
1028
1029
|
end
|
1029
1030
|
|
1031
|
+
test_totals = summary_totals['Total Test Count']
|
1032
|
+
test_totals -= summary_totals['Test Skip Count']
|
1033
|
+
test_totals -= summary_totals['Test Blocked Count']
|
1034
|
+
|
1035
|
+
total_failures = 0
|
1036
|
+
total_failures += summary_totals['Test Failure Count']
|
1037
|
+
total_failures += summary_totals['Test Exceptions']
|
1038
|
+
total_failures += summary_totals['Test Assert Failures']
|
1039
|
+
total_failures += summary_totals['Test JavaScript Error Count']
|
1040
|
+
|
1030
1041
|
sub_totals = "<tr id=\"totals\">\n"+
|
1031
1042
|
"\t<td class=\"td_header_master\">Totals:</td>\n"+
|
1032
|
-
"\t<td class=\"td_footer_run\">#{
|
1033
|
-
"/#{
|
1034
|
-
"\t<td class=\"td_footer_passed\">#{
|
1043
|
+
"\t<td class=\"td_footer_run\">#{test_totals}"+
|
1044
|
+
"/#{summary_totals['Total Test Count']}</td>\n"+
|
1045
|
+
"\t<td class=\"td_footer_passed\">#{summary_totals['Test Pass Count']}"+
|
1035
1046
|
"</td>\n"+
|
1036
1047
|
"\t<td class=\"td_footer_failed\">"+
|
1037
|
-
"#{
|
1048
|
+
"#{summary_totals['Test Failed Count']}</td>\n"+
|
1038
1049
|
"\t<td class=\"td_footer_blocked\">"+
|
1039
|
-
"#{
|
1050
|
+
"#{summary_totals['Test Blocked Count']}</td>\n"+
|
1040
1051
|
"\t<td class=\"td_footer_skipped\">"+
|
1041
|
-
"#{
|
1052
|
+
"#{summary_totals['Test Skip Count']}</td>\n"+
|
1042
1053
|
"\t<td class=\"td_footer_watchdog\">"+
|
1043
|
-
"#{
|
1054
|
+
"#{summary_totals['Test WatchDog Count']}</td>\n"+
|
1044
1055
|
"\t<td class=\"td_footer_exceptions\">"+
|
1045
|
-
"#{
|
1056
|
+
"#{summary_totals['Test Exceptions']}</td>\n"+
|
1046
1057
|
"\t<td class=\"td_footer_javascript\">"+
|
1047
|
-
"#{
|
1058
|
+
"#{summary_totals['Test JavaScript Error Count']}</td>\n"+
|
1048
1059
|
"\t<td class=\"td_footer_assert\">"+
|
1049
|
-
"#{
|
1060
|
+
"#{summary_totals['Test Assert Failures']}</td>\n"+
|
1050
1061
|
"\t<td class=\"td_footer_other\">"+
|
1051
|
-
"#{
|
1062
|
+
"#{summary_totals['Test Failure Count']}</td>\n"+
|
1052
1063
|
"\t<td class=\"td_footer_total\">"+
|
1053
|
-
"#{
|
1064
|
+
"#{total_failures}</td>\n"+
|
1054
1065
|
"\t<td class=\"td_footer_css\">"+
|
1055
|
-
"#{
|
1066
|
+
"#{summary_totals['Test CSS Error Count']}</td>\n"+
|
1056
1067
|
"\t<td class=\"td_footer_sodawarnings\">"+
|
1057
|
-
"#{
|
1068
|
+
"#{summary_totals['Test Warning Count']}</td>\n"+
|
1058
1069
|
"\t<td class=\"td_footer_times\">"+
|
1059
1070
|
"#{hours}:#{minutes}:#{seconds}</td>\n"+
|
1060
1071
|
"</tr>\n"
|
@@ -1062,10 +1073,12 @@ HTML
|
|
1062
1073
|
fd.write("</table>\n</body>\n</html>\n")
|
1063
1074
|
fd.close()
|
1064
1075
|
|
1065
|
-
|
1076
|
+
print "(*)Processing finished.\n"
|
1066
1077
|
|
1078
|
+
return 0
|
1067
1079
|
end
|
1068
|
-
private :
|
1080
|
+
private :GenHtmlReport2
|
1081
|
+
|
1069
1082
|
|
1070
1083
|
def GenSuiteMiniSummary(suite_hash, reportdir)
|
1071
1084
|
suite_file = suite_hash['suitefile']
|
@@ -1074,7 +1087,6 @@ def GenSuiteMiniSummary(suite_hash, reportdir)
|
|
1074
1087
|
suite_file << ".html"
|
1075
1088
|
href = "#{suite_name}/#{suite_file}"
|
1076
1089
|
suite_file = "#{reportdir}/#{suite_name}/#{suite_file}"
|
1077
|
-
|
1078
1090
|
html = <<HTML
|
1079
1091
|
<html>
|
1080
1092
|
<style type="text/css">
|
@@ -1117,6 +1129,17 @@ table {
|
|
1117
1129
|
border-right: 0px solid black;
|
1118
1130
|
border-bottom: 2px solid black;
|
1119
1131
|
}
|
1132
|
+
.td_blocked_data {
|
1133
|
+
white-space: nowrap;
|
1134
|
+
text-align: center;
|
1135
|
+
font-family: Arial;
|
1136
|
+
font-weight: bold;
|
1137
|
+
color: #FFCF10;
|
1138
|
+
font-size: 12px;
|
1139
|
+
border-left: 0px solid black;
|
1140
|
+
border-right: 0px solid black;
|
1141
|
+
border-bottom: 2px solid black;
|
1142
|
+
}
|
1120
1143
|
.td_failed_data {
|
1121
1144
|
white-space: nowrap;
|
1122
1145
|
text-align: center;
|
@@ -1169,6 +1192,7 @@ HTML
|
|
1169
1192
|
|
1170
1193
|
suite_hash['tests'].sort_by { |h| h['Test Order'].to_i }.each do |test|
|
1171
1194
|
id += 1
|
1195
|
+
result_str = ""
|
1172
1196
|
test_report = test['Test Log File']
|
1173
1197
|
test_report = File.basename(test_report, ".log")
|
1174
1198
|
test_report = "Report-#{test_report}.html"
|
@@ -1178,11 +1202,17 @@ HTML
|
|
1178
1202
|
"\t<td class=\"td_file_data\">#{test['testfile']}</td>\n"
|
1179
1203
|
|
1180
1204
|
if (test['result'].to_i != 0)
|
1181
|
-
|
1205
|
+
result_str = "\t<td class=\"td_failed_data\">Failed</td>\n"
|
1182
1206
|
else
|
1183
|
-
|
1207
|
+
result_str = "\t<td class=\"td_passed_data\">Passed</td>\n"
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
# hack #
|
1211
|
+
if (test['Test Blocked Count'].to_i > 0)
|
1212
|
+
result_str = "\t<td class=\"td_blocked_data\">Blocked</td>\n"
|
1184
1213
|
end
|
1185
1214
|
|
1215
|
+
str << "#{result_str}"
|
1186
1216
|
str << "\t<td class=\"td_report_data\">"
|
1187
1217
|
str << "<a href=\"#{test_report}\">Report Log</a></td>\n"
|
1188
1218
|
str << "</tr>\n"
|
data/lib/sodainfo.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: soda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 55
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 1.1.
|
9
|
+
- 18
|
10
|
+
version: 1.1.18
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Trampus Richmond
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-03-
|
18
|
+
date: 2011-03-07 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|