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.
@@ -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
+