soda 0.0.12 → 0.0.13
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.
- data/bin/SodaSuite +24 -54
- data/bin/SodaSummaryCreator +18 -3
- data/lib/Soda.rb +149 -2
- data/lib/SodaReporter.rb +74 -0
- data/lib/SodaSuiteSummary.rb +1129 -0
- data/lib/SodaTestCheck.rb +1 -1
- metadata +5 -4
@@ -0,0 +1,1129 @@
|
|
1
|
+
###############################################################################
|
2
|
+
# Copyright (c) 2010, SugarCRM, Inc.
|
3
|
+
# All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
# * Redistributions of source code must retain the above copyright
|
8
|
+
# notice, this list of conditions and the following disclaimer.
|
9
|
+
# * Redistributions in binary form must reproduce the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer in the
|
11
|
+
# documentation and/or other materials provided with the distribution.
|
12
|
+
# * Neither the name of SugarCRM, Inc. nor the
|
13
|
+
# names of its contributors may be used to endorse or promote products
|
14
|
+
# derived from this software without specific prior written permission.
|
15
|
+
#
|
16
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
19
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL SugarCRM, Inc. BE LIABLE FOR ANY
|
20
|
+
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
21
|
+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
22
|
+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
23
|
+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
24
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
25
|
+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
26
|
+
###############################################################################
|
27
|
+
|
28
|
+
###############################################################################
|
29
|
+
# Needed Ruby libs:
|
30
|
+
###############################################################################
|
31
|
+
require 'rubygems'
|
32
|
+
require 'getoptlong'
|
33
|
+
require 'date'
|
34
|
+
require 'libxml'
|
35
|
+
require 'pp'
|
36
|
+
require 'SodaReportSummery'
|
37
|
+
|
38
|
+
class SodaSuiteSummary
|
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 dorectory 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)
|
129
|
+
files = files.sort()
|
130
|
+
return files
|
131
|
+
end
|
132
|
+
|
133
|
+
private :GetLogFiles
|
134
|
+
|
135
|
+
###############################################################################
|
136
|
+
#
|
137
|
+
###############################################################################
|
138
|
+
def GetTestInfo(kids)
|
139
|
+
test_info = {}
|
140
|
+
|
141
|
+
kids.each do |kid|
|
142
|
+
next if (kid.name =~ /text/i)
|
143
|
+
name = kid.name
|
144
|
+
name = name.gsub("_", " ")
|
145
|
+
test_info[name] = kid.content()
|
146
|
+
end
|
147
|
+
|
148
|
+
return test_info
|
149
|
+
end
|
150
|
+
|
151
|
+
###############################################################################
|
152
|
+
# GenerateReportData -- method
|
153
|
+
# This function generates needed data from each file passed in.
|
154
|
+
#
|
155
|
+
# Params:
|
156
|
+
# files: This is a list of files to read data from.
|
157
|
+
#
|
158
|
+
# Results:
|
159
|
+
# returns an array of hashed data.
|
160
|
+
#
|
161
|
+
###############################################################################
|
162
|
+
def GenerateReportData(files)
|
163
|
+
test_info = {}
|
164
|
+
|
165
|
+
files.each do |f|
|
166
|
+
print "(*)Opening file: #{f}\n"
|
167
|
+
|
168
|
+
begin
|
169
|
+
parser = LibXML::XML::Parser.file(f)
|
170
|
+
doc = parser.parse()
|
171
|
+
rescue Exception => e
|
172
|
+
print "(!)Error: Failed trying to parse XML file: '#{f}'!\n"
|
173
|
+
print "--)Exception: #{e.message}\n\n"
|
174
|
+
exit(1)
|
175
|
+
ensure
|
176
|
+
end
|
177
|
+
|
178
|
+
suites = []
|
179
|
+
doc.root.each do |suite|
|
180
|
+
next if (suite.name !~ /suite/)
|
181
|
+
suites.push(suite)
|
182
|
+
end
|
183
|
+
|
184
|
+
suites.each do |suite|
|
185
|
+
tmp_hash = {'tests' => []}
|
186
|
+
suite.children.each do |kid|
|
187
|
+
case (kid.name)
|
188
|
+
when "suitefile"
|
189
|
+
tmp_hash['suitefile'] = kid.content()
|
190
|
+
when "test"
|
191
|
+
tmp_test_data = GetTestInfo(kid.children)
|
192
|
+
tmp_hash['tests'].push(tmp_test_data)
|
193
|
+
end # end case #
|
194
|
+
end
|
195
|
+
|
196
|
+
base_name = File.basename(tmp_hash['suitefile'])
|
197
|
+
test_info[base_name] = tmp_hash
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
return test_info
|
202
|
+
end
|
203
|
+
|
204
|
+
private :GenerateReportData
|
205
|
+
|
206
|
+
###############################################################################
|
207
|
+
# GenHtmlReport -- method
|
208
|
+
# This function generates an html report from an array of hashed data.
|
209
|
+
#
|
210
|
+
# Params:
|
211
|
+
# data: A hash of suites, and their test info.
|
212
|
+
# reportfile: This is the html file to create.
|
213
|
+
#
|
214
|
+
# Results:
|
215
|
+
# Creates an html report file. Retruns -1 on error, else 0 on success.
|
216
|
+
#
|
217
|
+
###############################################################################
|
218
|
+
def GenHtmlReport(data, reportfile, create_links = false)
|
219
|
+
fd = nil
|
220
|
+
result = 0
|
221
|
+
totals = {}
|
222
|
+
log_file_td = ""
|
223
|
+
report_file = ""
|
224
|
+
now = nil
|
225
|
+
suite_totals = {}
|
226
|
+
total_failure_count = 0
|
227
|
+
total_non_ran_count = 0
|
228
|
+
|
229
|
+
begin
|
230
|
+
fd = File.new(reportfile, "w+")
|
231
|
+
rescue Exception => e
|
232
|
+
fd = nil
|
233
|
+
result = -1
|
234
|
+
print "Error: trying to open file!\n"
|
235
|
+
print "Exception: #{e.message}\n"
|
236
|
+
print "StackTrace: #{e.backtrace.join("\n")}\n"
|
237
|
+
ensure
|
238
|
+
if (result != 0)
|
239
|
+
return -1
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
now = Time.now.getlocal()
|
244
|
+
html_header = <<HTML
|
245
|
+
<html>
|
246
|
+
<style type="text/css">
|
247
|
+
|
248
|
+
.highlight {
|
249
|
+
background-color: #8888FF;
|
250
|
+
}
|
251
|
+
|
252
|
+
.unhighlight {
|
253
|
+
background: #FFFFFF;
|
254
|
+
}
|
255
|
+
|
256
|
+
.td_header_master {
|
257
|
+
whitw-space: nowrap;
|
258
|
+
background: #99CCFF;
|
259
|
+
text-align: center;
|
260
|
+
font-family: Arial;
|
261
|
+
font-weight: bold;
|
262
|
+
font-size: 12px;
|
263
|
+
border-left: 0px solid black;
|
264
|
+
border-right: 2px solid black;
|
265
|
+
border-bottom: 2px solid black;
|
266
|
+
}
|
267
|
+
|
268
|
+
.td_header_sub {
|
269
|
+
whitw-space: nowrap;
|
270
|
+
background: #99CCFF;
|
271
|
+
text-align: center;
|
272
|
+
font-family: Arial;
|
273
|
+
font-weight: bold;
|
274
|
+
font-size: 12px;
|
275
|
+
border-left: 1px solid black;
|
276
|
+
border-right: 0px solid black;
|
277
|
+
border-bottom: 2px solid black;
|
278
|
+
}
|
279
|
+
|
280
|
+
.td_header_skipped {
|
281
|
+
whitw-space: nowrap;
|
282
|
+
background: #99CCFF;
|
283
|
+
text-align: center;
|
284
|
+
font-family: Arial;
|
285
|
+
font-weight: bold;
|
286
|
+
font-size: 12px;
|
287
|
+
border-left: 1px solid black;
|
288
|
+
border-right: 2px solid black;
|
289
|
+
border-bottom: 2px solid black;
|
290
|
+
}
|
291
|
+
|
292
|
+
.td_header_watchdog {
|
293
|
+
whitw-space: nowrap;
|
294
|
+
background: #99CCFF;
|
295
|
+
text-align: center;
|
296
|
+
font-family: Arial;
|
297
|
+
font-weight: bold;
|
298
|
+
font-size: 12px;
|
299
|
+
border-left: 0px solid black;
|
300
|
+
border-right: 0px solid black;
|
301
|
+
border-bottom: 2px solid black;
|
302
|
+
}
|
303
|
+
|
304
|
+
table {
|
305
|
+
width: 100%;
|
306
|
+
border: 2px solid black;
|
307
|
+
border-collapse: collapse;
|
308
|
+
padding: 0px;
|
309
|
+
background: #FFFFFF;
|
310
|
+
}
|
311
|
+
|
312
|
+
.td_file_data {
|
313
|
+
whitw-space: nowrap;
|
314
|
+
text-align: left;
|
315
|
+
font-family: Arial;
|
316
|
+
font-weight: bold;
|
317
|
+
font-size: 12px;
|
318
|
+
border-left: 0px solid black;
|
319
|
+
border-right: 2px solid black;
|
320
|
+
border-bottom: 2px solid black;
|
321
|
+
}
|
322
|
+
|
323
|
+
.td_run_data {
|
324
|
+
whitw-space: nowrap;
|
325
|
+
text-align: center;
|
326
|
+
font-family: Arial;
|
327
|
+
font-weight: bold;
|
328
|
+
font-size: 12px;
|
329
|
+
border-left: 0px solid black;
|
330
|
+
border-right: 0px solid black;
|
331
|
+
border-bottom: 0px solid black;
|
332
|
+
}
|
333
|
+
|
334
|
+
.td_run_data_error {
|
335
|
+
whitw-space: nowrap;
|
336
|
+
text-align: center;
|
337
|
+
font-family: Arial;
|
338
|
+
font-weight: bold;
|
339
|
+
color: #FF0000;
|
340
|
+
font-size: 12px;
|
341
|
+
border-left: 0px solid black;
|
342
|
+
border-right: 0px solid black;
|
343
|
+
border-bottom: 0px solid black;
|
344
|
+
}
|
345
|
+
|
346
|
+
.td_passed_data {
|
347
|
+
whitw-space: nowrap;
|
348
|
+
text-align: center;
|
349
|
+
font-family: Arial;
|
350
|
+
font-weight: bold;
|
351
|
+
color: #00FF00;
|
352
|
+
font-size: 12px;
|
353
|
+
border-left: 0px solid black;
|
354
|
+
border-right: 0px solid black;
|
355
|
+
border-bottom: 0px solid black;
|
356
|
+
}
|
357
|
+
|
358
|
+
.td_failed_data {
|
359
|
+
whitw-space: nowrap;
|
360
|
+
text-align: center;
|
361
|
+
font-family: Arial;
|
362
|
+
font-weight: bold;
|
363
|
+
color: #FF0000;
|
364
|
+
font-size: 12px;
|
365
|
+
border-left: 0px solid black;
|
366
|
+
border-right: 0px solid black;
|
367
|
+
border-bottom: 0px solid black;
|
368
|
+
}
|
369
|
+
|
370
|
+
.td_blocked_data {
|
371
|
+
whitw-space: nowrap;
|
372
|
+
text-align: center;
|
373
|
+
font-family: Arial;
|
374
|
+
font-weight: bold;
|
375
|
+
color: #FFCF10;
|
376
|
+
font-size: 12px;
|
377
|
+
border-left: 0px solid black;
|
378
|
+
border-right: 0px solid black;
|
379
|
+
border-bottom: 0px solid black;
|
380
|
+
}
|
381
|
+
|
382
|
+
.td_skipped_data {
|
383
|
+
whitw-space: nowrap;
|
384
|
+
text-align: center;
|
385
|
+
font-family: Arial;
|
386
|
+
font-weight: bold;
|
387
|
+
color: #D9D9D9;
|
388
|
+
font-size: 12px;
|
389
|
+
border-left: 0px solid black;
|
390
|
+
border-right: 2px solid black;
|
391
|
+
border-bottom: 0px solid black;
|
392
|
+
}
|
393
|
+
|
394
|
+
.td_watchdog_data {
|
395
|
+
whitw-space: nowrap;
|
396
|
+
text-align: center;
|
397
|
+
font-family: Arial;
|
398
|
+
font-weight: normal;
|
399
|
+
font-size: 12px;
|
400
|
+
border-left: 0px solid black;
|
401
|
+
border-right: 0px solid black;
|
402
|
+
border-bottom: 0px solid black;
|
403
|
+
}
|
404
|
+
|
405
|
+
.td_watchdog_error_data {
|
406
|
+
whitw-space: nowrap;
|
407
|
+
color: #FF0000;
|
408
|
+
text-align: center;
|
409
|
+
font-family: Arial;
|
410
|
+
font-weight: bold;
|
411
|
+
font-size: 12px;
|
412
|
+
border-left: 0px solid black;
|
413
|
+
border-right: 0px solid black;
|
414
|
+
border-bottom: 0px solid black;
|
415
|
+
}
|
416
|
+
|
417
|
+
.td_exceptions_data {
|
418
|
+
whitw-space: nowrap;
|
419
|
+
text-align: center;
|
420
|
+
font-family: Arial;
|
421
|
+
font-weight: normal;
|
422
|
+
font-size: 12px;
|
423
|
+
border-left: 0px solid black;
|
424
|
+
border-right: 0px solid black;
|
425
|
+
border-bottom: 0px solid black;
|
426
|
+
}
|
427
|
+
|
428
|
+
.td_exceptions_error_data {
|
429
|
+
whitw-space: nowrap;
|
430
|
+
text-align: center;
|
431
|
+
font-family: Arial;
|
432
|
+
font-weight: bold;
|
433
|
+
color: #FF0000;
|
434
|
+
font-size: 12px;
|
435
|
+
border-left: 0px solid black;
|
436
|
+
border-right: 0px solid black;
|
437
|
+
border-bottom: 0px solid black;
|
438
|
+
}
|
439
|
+
|
440
|
+
.td_javascript_data {
|
441
|
+
whitw-space: nowrap;
|
442
|
+
text-align: center;
|
443
|
+
font-family: Arial;
|
444
|
+
font-weight: normal;
|
445
|
+
font-size: 12px;
|
446
|
+
border-left: 0px solid black;
|
447
|
+
border-right: 0px solid black;
|
448
|
+
border-bottom: 0px solid black;
|
449
|
+
}
|
450
|
+
|
451
|
+
.td_javascript_error_data {
|
452
|
+
whitw-space: nowrap;
|
453
|
+
text-align: center;
|
454
|
+
font-family: Arial;
|
455
|
+
font-weight: bold;
|
456
|
+
color: #FF0000;
|
457
|
+
font-size: 12px;
|
458
|
+
border-left: 0px solid black;
|
459
|
+
border-right: 0px solid black;
|
460
|
+
border-bottom: 0px solid black;
|
461
|
+
}
|
462
|
+
|
463
|
+
.td_assert_data {
|
464
|
+
whitw-space: nowrap;
|
465
|
+
text-align: center;
|
466
|
+
font-family: Arial;
|
467
|
+
font-weight: normal;
|
468
|
+
font-size: 12px;
|
469
|
+
border-left: 0px solid black;
|
470
|
+
border-right: 0px solid black;
|
471
|
+
border-bottom: 0px solid black;
|
472
|
+
}
|
473
|
+
|
474
|
+
.td_assert_error_data {
|
475
|
+
whitw-space: nowrap;
|
476
|
+
text-align: center;
|
477
|
+
font-family: Arial;
|
478
|
+
font-weight: bold;
|
479
|
+
color: #FF0000;
|
480
|
+
font-size: 12px;
|
481
|
+
border-left: 0px solid black;
|
482
|
+
border-right: 0px solid black;
|
483
|
+
border-bottom: 0px solid black;
|
484
|
+
}
|
485
|
+
|
486
|
+
.td_other_data {
|
487
|
+
whitw-space: nowrap;
|
488
|
+
text-align: center;
|
489
|
+
font-family: Arial;
|
490
|
+
font-weight: normal;
|
491
|
+
font-size: 12px;
|
492
|
+
border-left: 0px solid black;
|
493
|
+
border-right: 0px solid black;
|
494
|
+
border-bottom: 0px solid black;
|
495
|
+
}
|
496
|
+
|
497
|
+
.td_other_error_data {
|
498
|
+
whitw-space: nowrap;
|
499
|
+
text-align: center;
|
500
|
+
font-family: Arial;
|
501
|
+
font-weight: bold;
|
502
|
+
color: #FF0000;
|
503
|
+
font-size: 12px;
|
504
|
+
border-left: 0px solid black;
|
505
|
+
border-right: 0px solid black;
|
506
|
+
border-bottom: 0px solid black;
|
507
|
+
}
|
508
|
+
|
509
|
+
.td_total_data {
|
510
|
+
whitw-space: nowrap;
|
511
|
+
text-align: center;
|
512
|
+
font-family: Arial;
|
513
|
+
font-weight: normal;
|
514
|
+
font-size: 12px;
|
515
|
+
border-left: 0px solid black;
|
516
|
+
border-right: 2px solid black;
|
517
|
+
border-bottom: 0px solid black;
|
518
|
+
}
|
519
|
+
|
520
|
+
.td_total_error_data {
|
521
|
+
whitw-space: nowrap;
|
522
|
+
text-align: center;
|
523
|
+
font-family: Arial;
|
524
|
+
font-weight: bold;
|
525
|
+
color: #FF0000;
|
526
|
+
font-size: 12px;
|
527
|
+
border-left: 0px solid black;
|
528
|
+
border-right: 2px solid black;
|
529
|
+
border-bottom: 0px solid black;
|
530
|
+
}
|
531
|
+
|
532
|
+
.td_css_data {
|
533
|
+
whitw-space: nowrap;
|
534
|
+
text-align: center;
|
535
|
+
font-family: Arial;
|
536
|
+
font-weight: normal;
|
537
|
+
font-size: 12px;
|
538
|
+
border-left: 0px solid black;
|
539
|
+
border-right: 0px solid black;
|
540
|
+
border-bottom: 0px solid black;
|
541
|
+
}
|
542
|
+
|
543
|
+
.td_sodawarnings_data {
|
544
|
+
whitw-space: nowrap;
|
545
|
+
text-align: center;
|
546
|
+
font-family: Arial;
|
547
|
+
font-weight: normal;
|
548
|
+
font-size: 12px;
|
549
|
+
border-left: 0px solid black;
|
550
|
+
border-right: 2px solid black;
|
551
|
+
border-bottom: 0px solid black;
|
552
|
+
}
|
553
|
+
|
554
|
+
.td_time_data {
|
555
|
+
whitw-space: nowrap;
|
556
|
+
text-align: center;
|
557
|
+
font-family: Arial;
|
558
|
+
font-weight: normal;
|
559
|
+
font-size: 12px;
|
560
|
+
border-left: 0px solid black;
|
561
|
+
border-right: 1px solid black;
|
562
|
+
border-bottom: 0px solid black;
|
563
|
+
}
|
564
|
+
|
565
|
+
.td_footer_run {
|
566
|
+
whitw-space: nowrap;
|
567
|
+
background: #99CCFF;
|
568
|
+
text-align: center;
|
569
|
+
font-family: Arial;
|
570
|
+
font-weight: bold;
|
571
|
+
font-size: 12px;
|
572
|
+
color: #000000;
|
573
|
+
border-top: 2px solid black;
|
574
|
+
border-left: 0px solid black;
|
575
|
+
border-right: 2px solid black;
|
576
|
+
border-bottom: 2px solid black;
|
577
|
+
}
|
578
|
+
|
579
|
+
.td_footer_passed {
|
580
|
+
whitw-space: nowrap;
|
581
|
+
background: #99CCFF;
|
582
|
+
text-align: center;
|
583
|
+
font-family: Arial;
|
584
|
+
font-weight: bold;
|
585
|
+
font-size: 12px;
|
586
|
+
color: #00FF00;
|
587
|
+
border-top: 2px solid black;
|
588
|
+
border-left: 0px solid black;
|
589
|
+
border-right: 0px solid black;
|
590
|
+
border-bottom: 2px solid black;
|
591
|
+
}
|
592
|
+
|
593
|
+
.td_footer_failed {
|
594
|
+
whitw-space: nowrap;
|
595
|
+
background: #99CCFF;
|
596
|
+
text-align: center;
|
597
|
+
font-family: Arial;
|
598
|
+
font-weight: bold;
|
599
|
+
font-size: 12px;
|
600
|
+
color: #FF0000;
|
601
|
+
border-top: 2px solid black;
|
602
|
+
border-left: 0px solid black;
|
603
|
+
border-right: 2px solid black;
|
604
|
+
border-bottom: 2px solid black;
|
605
|
+
}
|
606
|
+
|
607
|
+
.td_footer_blocked {
|
608
|
+
whitw-space: nowrap;
|
609
|
+
background: #99CCFF;
|
610
|
+
text-align: center;
|
611
|
+
font-family: Arial;
|
612
|
+
font-weight: bold;
|
613
|
+
font-size: 12px;
|
614
|
+
color: #FFCF10;
|
615
|
+
border-top: 2px solid black;
|
616
|
+
border-left: 0px solid black;
|
617
|
+
border-right: 0px solid black;
|
618
|
+
border-bottom: 2px solid black;
|
619
|
+
}
|
620
|
+
|
621
|
+
.td_footer_skipped {
|
622
|
+
whitw-space: nowrap;
|
623
|
+
background: #99CCFF;
|
624
|
+
text-align: center;
|
625
|
+
font-family: Arial;
|
626
|
+
font-weight: bold;
|
627
|
+
font-size: 12px;
|
628
|
+
color: #D9D9D9;
|
629
|
+
border-top: 2px solid black;
|
630
|
+
border-left: 0px solid black;
|
631
|
+
border-right: 2px solid black;
|
632
|
+
border-bottom: 2px solid black;
|
633
|
+
}
|
634
|
+
|
635
|
+
.td_footer_watchdog {
|
636
|
+
whitw-space: nowrap;
|
637
|
+
background: #99CCFF;
|
638
|
+
text-align: center;
|
639
|
+
font-family: Arial;
|
640
|
+
font-weight: bold;
|
641
|
+
font-size: 12px;
|
642
|
+
color: #FF0000;
|
643
|
+
border-top: 2px solid black;
|
644
|
+
border-left: 0px solid black;
|
645
|
+
border-right: 0px solid black;
|
646
|
+
border-bottom: 2px solid black;
|
647
|
+
}
|
648
|
+
|
649
|
+
.td_footer_exceptions {
|
650
|
+
whitw-space: nowrap;
|
651
|
+
background: #99CCFF;
|
652
|
+
text-align: center;
|
653
|
+
font-family: Arial;
|
654
|
+
font-weight: bold;
|
655
|
+
font-size: 12px;
|
656
|
+
color: #FF0000;
|
657
|
+
border-top: 2px solid black;
|
658
|
+
border-left: 0px solid black;
|
659
|
+
border-right: 0px solid black;
|
660
|
+
border-bottom: 2px solid black;
|
661
|
+
}
|
662
|
+
|
663
|
+
.td_footer_javascript {
|
664
|
+
whitw-space: nowrap;
|
665
|
+
background: #99CCFF;
|
666
|
+
text-align: center;
|
667
|
+
font-family: Arial;
|
668
|
+
font-weight: bold;
|
669
|
+
font-size: 12px;
|
670
|
+
color: #FF0000;
|
671
|
+
border-top: 2px solid black;
|
672
|
+
border-left: 0px solid black;
|
673
|
+
border-right: 0px solid black;
|
674
|
+
border-bottom: 2px solid black;
|
675
|
+
}
|
676
|
+
|
677
|
+
.td_footer_assert {
|
678
|
+
whitw-space: nowrap;
|
679
|
+
background: #99CCFF;
|
680
|
+
text-align: center;
|
681
|
+
font-family: Arial;
|
682
|
+
font-weight: bold;
|
683
|
+
font-size: 12px;
|
684
|
+
color: #FF0000;
|
685
|
+
border-top: 2px solid black;
|
686
|
+
border-left: 0px solid black;
|
687
|
+
border-right: 0px solid black;
|
688
|
+
border-bottom: 2px solid black;
|
689
|
+
}
|
690
|
+
|
691
|
+
.td_footer_other {
|
692
|
+
whitw-space: nowrap;
|
693
|
+
background: #99CCFF;
|
694
|
+
text-align: center;
|
695
|
+
font-family: Arial;
|
696
|
+
font-weight: bold;
|
697
|
+
font-size: 12px;
|
698
|
+
color: #FF0000;
|
699
|
+
border-top: 2px solid black;
|
700
|
+
border-left: 0px solid black;
|
701
|
+
border-right: 0px solid black;
|
702
|
+
border-bottom: 2px solid black;
|
703
|
+
}
|
704
|
+
|
705
|
+
.td_footer_total {
|
706
|
+
whitw-space: nowrap;
|
707
|
+
background: #99CCFF;
|
708
|
+
text-align: center;
|
709
|
+
font-family: Arial;
|
710
|
+
font-weight: bold;
|
711
|
+
font-size: 12px;
|
712
|
+
color: #FF0000;
|
713
|
+
border-top: 2px solid black;
|
714
|
+
border-left: 2px solid black;
|
715
|
+
border-right: 2px solid black;
|
716
|
+
border-bottom: 2px solid black;
|
717
|
+
}
|
718
|
+
|
719
|
+
.td_footer_css {
|
720
|
+
whitw-space: nowrap;
|
721
|
+
background: #99CCFF;
|
722
|
+
text-align: center;
|
723
|
+
font-family: Arial;
|
724
|
+
font-weight: bold;
|
725
|
+
font-size: 12px;
|
726
|
+
color: #000000;
|
727
|
+
border-top: 2px solid black;
|
728
|
+
border-left: 0px solid black;
|
729
|
+
border-right: 0px solid black;
|
730
|
+
border-bottom: 2px solid black;
|
731
|
+
}
|
732
|
+
|
733
|
+
.td_footer_sodawarnings {
|
734
|
+
whitw-space: nowrap;
|
735
|
+
background: #99CCFF;
|
736
|
+
text-align: center;
|
737
|
+
font-family: Arial;
|
738
|
+
font-weight: bold;
|
739
|
+
font-size: 12px;
|
740
|
+
color: #000000;
|
741
|
+
border-top: 2px solid black;
|
742
|
+
border-left: 0px solid black;
|
743
|
+
border-right: 0px solid black;
|
744
|
+
border-bottom: 2px solid black;
|
745
|
+
}
|
746
|
+
|
747
|
+
.td_footer_times {
|
748
|
+
whitw-space: nowrap;
|
749
|
+
background: #99CCFF;
|
750
|
+
text-align: center;
|
751
|
+
font-family: Arial;
|
752
|
+
font-weight: bold;
|
753
|
+
font-size: 12px;
|
754
|
+
color: #000000;
|
755
|
+
border-top: 2px solid black;
|
756
|
+
border-left: 2px solid black;
|
757
|
+
border-right: 0px solid black;
|
758
|
+
border-bottom: 2px solid black;
|
759
|
+
}
|
760
|
+
</style>
|
761
|
+
<body>
|
762
|
+
<table>
|
763
|
+
<tr>
|
764
|
+
<td class="td_header_master" rowspan="2">Suite</br>
|
765
|
+
(click link for full report)</td>
|
766
|
+
<td class="td_header_master" colspan="5">Tests</td>
|
767
|
+
<td class="td_header_master" colspan="6">Failures</td>
|
768
|
+
<td class="td_header_master" colspan="2">Warnings</td>
|
769
|
+
<td class="td_header_master" rowspan="2">Run Time</br>(hh:mm:ss)</td>
|
770
|
+
</tr>
|
771
|
+
<tr>
|
772
|
+
<td class="td_header_sub">Run</td>
|
773
|
+
<td class="td_header_sub">Passed</td>
|
774
|
+
<td class="td_header_sub">Failed</td>
|
775
|
+
<td class="td_header_sub">Blocked</td>
|
776
|
+
<td class="td_header_skipped">Skipped</td>
|
777
|
+
<td class="td_header_watchdog">Watchdogs</td>
|
778
|
+
<td class="td_header_sub">Exceptions</td>
|
779
|
+
<td class="td_header_sub">JavaScript</br>Errors</td>
|
780
|
+
<td class="td_header_sub">Assert</br>Failures</td>
|
781
|
+
<td class="td_header_sub">Other</br>Failures</td>
|
782
|
+
<td class="td_header_skipped">Total</br>Failures</td>
|
783
|
+
<td class="td_header_watchdog">CSS Errors</td>
|
784
|
+
<td class="td_header_skipped">Soda</br>Warnings</td>
|
785
|
+
</tr>
|
786
|
+
HTML
|
787
|
+
|
788
|
+
fd.write(html_header)
|
789
|
+
|
790
|
+
data.each do |suite, suite_hash|
|
791
|
+
totals[suite] = Hash.new()
|
792
|
+
totals[suite]['Test Failure Count'] = 0
|
793
|
+
totals[suite]['Test Passed Count'] = 0
|
794
|
+
totals[suite]['Total Time'] = nil
|
795
|
+
|
796
|
+
suite_hash.each do |k, v|
|
797
|
+
next if (k !~ /tests/)
|
798
|
+
totals[suite]['Test Count'] = v.length()
|
799
|
+
|
800
|
+
v.each do |test|
|
801
|
+
time_set = false
|
802
|
+
if (test['result'].to_i != 0)
|
803
|
+
totals[suite]['Test Failure Count'] += 1
|
804
|
+
total_failure_count += 1
|
805
|
+
else
|
806
|
+
totals[suite]['Test Passed Count'] += 1
|
807
|
+
end
|
808
|
+
|
809
|
+
if (!time_set)
|
810
|
+
time_set = true
|
811
|
+
stop = test['Test Stop Time']
|
812
|
+
start = DateTime.strptime("#{test['Test Start Time']}",
|
813
|
+
"%m/%d/%Y-%H:%M:%S")
|
814
|
+
stop = DateTime.strptime("#{test['Test Stop Time']}",
|
815
|
+
"%m/%d/%Y-%H:%M:%S")
|
816
|
+
|
817
|
+
diff = (stop - start)
|
818
|
+
if (totals[suite]['Total Time'] == nil)
|
819
|
+
totals[suite]['Total Time'] = diff
|
820
|
+
else
|
821
|
+
totals[suite]['Total Time'] += diff
|
822
|
+
end
|
823
|
+
end
|
824
|
+
|
825
|
+
test.each do |test_k, test_v|
|
826
|
+
if (!totals[suite].key?(test_k))
|
827
|
+
totals[suite][test_k] = 0
|
828
|
+
else
|
829
|
+
totals[suite][test_k] += test_v.to_i if (test_k !~ /time/i)
|
830
|
+
end
|
831
|
+
end
|
832
|
+
end
|
833
|
+
end
|
834
|
+
end
|
835
|
+
|
836
|
+
totals.each do |suite, suite_hash|
|
837
|
+
suite_hash.each do |k, v|
|
838
|
+
if (!suite_totals.key?(k))
|
839
|
+
suite_totals[k] = 0
|
840
|
+
end
|
841
|
+
|
842
|
+
if (k =~ /Total Time/)
|
843
|
+
suite_totals[k] += v
|
844
|
+
else
|
845
|
+
suite_totals[k] += v.to_i()
|
846
|
+
end
|
847
|
+
end
|
848
|
+
end
|
849
|
+
|
850
|
+
row_id = 0
|
851
|
+
totals.each do |suite_name, suite_hash|
|
852
|
+
next if (suite_name =~ /Total\sFailure\sCount/i)
|
853
|
+
row_id += 1
|
854
|
+
report_file = "#{suite_name}"
|
855
|
+
hours,minutes,seconds,frac =
|
856
|
+
Date.day_fraction_to_time(suite_hash['Total Time'])
|
857
|
+
|
858
|
+
if (hours < 10)
|
859
|
+
hours = "0#{hours}"
|
860
|
+
end
|
861
|
+
|
862
|
+
if (minutes < 10)
|
863
|
+
minutes = "0#{minutes}"
|
864
|
+
end
|
865
|
+
|
866
|
+
if (seconds < 10)
|
867
|
+
seconds = "0#{seconds}"
|
868
|
+
end
|
869
|
+
|
870
|
+
suite_hash['Test Other Failures'] = 0
|
871
|
+
|
872
|
+
test_run_class = "td_run_data"
|
873
|
+
if (suite_hash['Test Assert Failures'] > 0 ||
|
874
|
+
suite_hash['Test Exceptions'] > 0)
|
875
|
+
test_run_class = "td_run_data_error"
|
876
|
+
end
|
877
|
+
|
878
|
+
exceptions_td = "td_exceptions_data"
|
879
|
+
if (suite_hash['Test Exceptions'] > 0)
|
880
|
+
exceptions_td = "td_exceptions_error_data"
|
881
|
+
end
|
882
|
+
|
883
|
+
asserts_td = "td_assert_data"
|
884
|
+
if (suite_hash['Test Assert Failures'] > 0)
|
885
|
+
asserts_td = "td_assert_error_data"
|
886
|
+
end
|
887
|
+
|
888
|
+
watchdog_td = "td_watchdog_data"
|
889
|
+
if (suite_hash['Test WatchDog Count'] > 0)
|
890
|
+
watchdog_td = "td_watchdog_error_data"
|
891
|
+
end
|
892
|
+
|
893
|
+
jscript_td = "td_javascript_data"
|
894
|
+
if (suite_hash['Test JavaScript Error Count'] > 0)
|
895
|
+
jscript_td = "td_javascript_error_data"
|
896
|
+
end
|
897
|
+
|
898
|
+
t_passedcount = suite_hash['Test Count']
|
899
|
+
t_passedcount -= suite_hash['Test Failure Count']
|
900
|
+
total_failures = 0
|
901
|
+
# total_failures += suite_hash['Test Failure Count']
|
902
|
+
total_failures += suite_hash['Test WatchDog Count']
|
903
|
+
total_failures += suite_hash['Test Assert Failures']
|
904
|
+
total_failures += suite_hash['Test Other Failures']
|
905
|
+
total_failures += suite_hash['Test JavaScript Error Count']
|
906
|
+
# total_failure_count += total_failures
|
907
|
+
|
908
|
+
ran_count = suite_hash['Test Count'].to_i()
|
909
|
+
ran_count -= suite_hash['Test WatchDog Count']
|
910
|
+
ran_count -= suite_hash['Test Blocked Count']
|
911
|
+
|
912
|
+
total_non_ran_count += suite_hash['Test WatchDog Count']
|
913
|
+
total_non_ran_count += suite_hash['Test Blocked Count']
|
914
|
+
|
915
|
+
reportdir = File.dirname(reportfile)
|
916
|
+
suite_mini_file = GenSuiteMiniSummary(data[suite_name], reportdir)
|
917
|
+
|
918
|
+
str = "<tr id=\"#{row_id}\" class=\"unhighlight\" "+
|
919
|
+
"onMouseOver=\"this.className='highlight'\" "+
|
920
|
+
"onMouseOut=\"this.className='unhighlight'\">\n"+
|
921
|
+
"\t<td class=\"td_file_data\"><a href=\"#{suite_mini_file}\">"+
|
922
|
+
"#{suite_name}</a></td>\n"+
|
923
|
+
"\t<td class=\"#{test_run_class}\">"+
|
924
|
+
"#{ran_count}/#{suite_hash['Test Count']}</td>\n"+
|
925
|
+
"\t<td class=\"td_passed_data\">"+
|
926
|
+
"#{suite_hash['Test Passed Count']}</td>\n"+
|
927
|
+
"\t<td class=\"td_failed_data\">"+
|
928
|
+
"#{suite_hash['Test Failure Count']}</td>\n"+
|
929
|
+
"\t<td class=\"td_blocked_data\">"+
|
930
|
+
"#{suite_hash['Test Blocked Count']}</td>\n"+
|
931
|
+
"\t<td class=\"td_skipped_data\">"+
|
932
|
+
"#{suite_hash['Test Skip Count']}</td>\n"+
|
933
|
+
"\t<td class=\"#{watchdog_td}\">"+
|
934
|
+
"#{suite_hash['Test WatchDog Count']}</td>\n"+
|
935
|
+
"\t<td class=\"#{exceptions_td}\">"+
|
936
|
+
"#{suite_hash['Test Exceptions']}</td>\n"+
|
937
|
+
"\t<td class=\"#{jscript_td}\">"+
|
938
|
+
"#{suite_hash['Test JavaScript Error Count']}</td>\n"+
|
939
|
+
"\t<td class=\"#{asserts_td}\">"+
|
940
|
+
"#{suite_hash['Test Assert Failures']}</td>\n"+
|
941
|
+
"\t<td class=\"td_other_data\">"+
|
942
|
+
"0</td>\n"+
|
943
|
+
"\t<td class=\"td_total_data\">#{total_failures}</td>\n"+
|
944
|
+
"\t<td class=\"td_css_data\">"+
|
945
|
+
"#{suite_hash['Test CSS Error Count']}</td>\n"+
|
946
|
+
"\t<td class=\"td_sodawarnings_data\">"+
|
947
|
+
"#{suite_hash['Test Warning Count']}</td>\n"+
|
948
|
+
"\t<td class=\"td_time_data\">"+
|
949
|
+
"#{hours}:#{minutes}:#{seconds}</td>\n</tr>\n"
|
950
|
+
fd.write(str)
|
951
|
+
end
|
952
|
+
|
953
|
+
test_totals = suite_totals['Test Count']
|
954
|
+
test_totals += suite_totals['Test Skip Count']
|
955
|
+
test_totals += suite_totals['Test Blocked Count']
|
956
|
+
|
957
|
+
hours,minutes,seconds,frac =
|
958
|
+
Date.day_fraction_to_time(suite_totals['Total Time'])
|
959
|
+
if (hours < 10)
|
960
|
+
hours = "0#{hours}"
|
961
|
+
end
|
962
|
+
|
963
|
+
if (minutes < 10)
|
964
|
+
minutes = "0#{minutes}"
|
965
|
+
end
|
966
|
+
|
967
|
+
if (seconds < 10)
|
968
|
+
seconds = "0#{seconds}"
|
969
|
+
end
|
970
|
+
|
971
|
+
sub_totals = "<tr id=\"totals\">\n"+
|
972
|
+
"\t<td class=\"td_header_master\">Totals:</td>\n"+
|
973
|
+
"\t<td class=\"td_footer_run\">#{suite_totals['Test Count']}"+
|
974
|
+
"/#{test_totals}</td>\n"+
|
975
|
+
"\t<td class=\"td_footer_passed\">#{suite_totals['Test Passed Count']}"+
|
976
|
+
"</td>\n"+
|
977
|
+
"\t<td class=\"td_footer_failed\">"+
|
978
|
+
"#{suite_totals['Test Failure Count']}</td>\n"+
|
979
|
+
"\t<td class=\"td_footer_blocked\">"+
|
980
|
+
"#{suite_totals['Test Blocked Count']}</td>\n"+
|
981
|
+
"\t<td class=\"td_footer_skipped\">"+
|
982
|
+
"#{suite_totals['Test Skip Count']}</td>\n"+
|
983
|
+
"\t<td class=\"td_footer_watchdog\">"+
|
984
|
+
"#{suite_totals['Test WatchDog Count']}</td>\n"+
|
985
|
+
"\t<td class=\"td_footer_exceptions\">"+
|
986
|
+
"#{suite_totals['Test Exceptions']}</td>\n"+
|
987
|
+
"\t<td class=\"td_footer_javascript\">"+
|
988
|
+
"#{suite_totals['Test JavaScript Error Count']}</td>\n"+
|
989
|
+
"\t<td class=\"td_footer_assert\">"+
|
990
|
+
"#{suite_totals['Test Assert Failures']}</td>\n"+
|
991
|
+
"\t<td class=\"td_footer_other\">0</td>\n"+
|
992
|
+
"\t<td class=\"td_footer_total\">"+
|
993
|
+
"#{total_failure_count}</td>\n"+
|
994
|
+
"\t<td class=\"td_footer_css\">"+
|
995
|
+
"#{suite_totals['Test CSS Error Count']}</td>\n"+
|
996
|
+
"\t<td class=\"td_footer_sodawarnings\">"+
|
997
|
+
"#{suite_totals['Test Warning Count']}</td>\n"+
|
998
|
+
"\t<td class=\"td_footer_times\">"+
|
999
|
+
"#{hours}:#{minutes}:#{seconds}</td>\n"+
|
1000
|
+
"</tr>\n"
|
1001
|
+
fd.write(sub_totals)
|
1002
|
+
fd.write("</table>\n</body>\n</html>\n")
|
1003
|
+
fd.close()
|
1004
|
+
|
1005
|
+
return 0
|
1006
|
+
|
1007
|
+
end
|
1008
|
+
private :GenHtmlReport
|
1009
|
+
|
1010
|
+
def GenSuiteMiniSummary(suite_hash, reportdir)
|
1011
|
+
suite_file = suite_hash['suitefile']
|
1012
|
+
suite_file = File.basename(suite_file, ".xml")
|
1013
|
+
suite_file << ".html"
|
1014
|
+
suite_file = "#{reportdir}/#{suite_file}"
|
1015
|
+
|
1016
|
+
html = <<HTML
|
1017
|
+
<html>
|
1018
|
+
<style type="text/css">
|
1019
|
+
table {
|
1020
|
+
width: 100%;
|
1021
|
+
border: 2px solid black;
|
1022
|
+
border-collapse: collapse;
|
1023
|
+
padding: 0px;
|
1024
|
+
background: #FFFFFF;
|
1025
|
+
}
|
1026
|
+
.td_header_master {
|
1027
|
+
whitw-space: nowrap;
|
1028
|
+
background: #99CCFF;
|
1029
|
+
text-align: center;
|
1030
|
+
font-family: Arial;
|
1031
|
+
font-weight: bold;
|
1032
|
+
font-size: 12px;
|
1033
|
+
border-left: 0px solid black;
|
1034
|
+
border-right: 2px solid black;
|
1035
|
+
border-bottom: 2px solid black;
|
1036
|
+
}
|
1037
|
+
.td_file_data {
|
1038
|
+
whitw-space: nowrap;
|
1039
|
+
text-align: left;
|
1040
|
+
font-family: Arial;
|
1041
|
+
font-weight: bold;
|
1042
|
+
font-size: 12px;
|
1043
|
+
border-left: 0px solid black;
|
1044
|
+
border-right: 2px solid black;
|
1045
|
+
border-bottom: 2px solid black;
|
1046
|
+
}
|
1047
|
+
.td_passed_data {
|
1048
|
+
whitw-space: nowrap;
|
1049
|
+
text-align: center;
|
1050
|
+
font-family: Arial;
|
1051
|
+
font-weight: bold;
|
1052
|
+
color: #00FF00;
|
1053
|
+
font-size: 12px;
|
1054
|
+
border-left: 0px solid black;
|
1055
|
+
border-right: 0px solid black;
|
1056
|
+
border-bottom: 2px solid black;
|
1057
|
+
}
|
1058
|
+
|
1059
|
+
.td_failed_data {
|
1060
|
+
whitw-space: nowrap;
|
1061
|
+
text-align: center;
|
1062
|
+
font-family: Arial;
|
1063
|
+
font-weight: bold;
|
1064
|
+
color: #FF0000;
|
1065
|
+
font-size: 12px;
|
1066
|
+
border-left: 0px solid black;
|
1067
|
+
border-right: 0px solid black;
|
1068
|
+
border-bottom: 2px solid black;
|
1069
|
+
}
|
1070
|
+
.td_report_data {
|
1071
|
+
whitw-space: nowrap;
|
1072
|
+
text-align: center;
|
1073
|
+
font-family: Arial;
|
1074
|
+
font-weight: normal;
|
1075
|
+
font-size: 12px;
|
1076
|
+
border-left: 2px solid black;
|
1077
|
+
border-right: 1px solid black;
|
1078
|
+
border-bottom: 2px solid black;
|
1079
|
+
}
|
1080
|
+
</style>
|
1081
|
+
<body>
|
1082
|
+
<table id="tests">
|
1083
|
+
<tr id="header">
|
1084
|
+
<td class="td_header_master" colspan="3">
|
1085
|
+
Suite: #{suite_hash['suitefile']} Test Results
|
1086
|
+
</td>
|
1087
|
+
</tr>
|
1088
|
+
<tr id="header_key">
|
1089
|
+
<td class="td_header_master">Test File</td>
|
1090
|
+
<td class="td_header_master">Status</td>
|
1091
|
+
<td class="td_header_master">Report Log</td>
|
1092
|
+
</tr>
|
1093
|
+
HTML
|
1094
|
+
|
1095
|
+
fd = File.new(suite_file, "w+")
|
1096
|
+
fd.write(html)
|
1097
|
+
id = 0
|
1098
|
+
suite_hash['tests'].each do |test|
|
1099
|
+
id += 1
|
1100
|
+
test_report = test['testfile']
|
1101
|
+
test_report = File.basename(test_report, ".xml")
|
1102
|
+
test_report = "Report-#{test_report}.html"
|
1103
|
+
|
1104
|
+
str = "<tr id=\"#{id}\">\n"+
|
1105
|
+
"\t<td class=\"td_file_data\">#{test['testfile']}</td>\n"
|
1106
|
+
|
1107
|
+
if (test['result'].to_i != 0)
|
1108
|
+
str << "\t<td class=\"td_failed_data\">Failed</td>\n"
|
1109
|
+
else
|
1110
|
+
str << "\t<td class=\"td_passed_data\">Passed</td>\n"
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
str << "\t<td class=\"td_report_data\">"
|
1114
|
+
str << "<a href=\"#{test_report}\">Report Log</a></td>\n"
|
1115
|
+
str << "</tr>\n"
|
1116
|
+
fd.write(str)
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
fd.write("</table>\n</body>\n</html>\n")
|
1120
|
+
fd.close()
|
1121
|
+
|
1122
|
+
return suite_file
|
1123
|
+
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
|