soda 0.0.1 → 0.0.2

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.
Files changed (2) hide show
  1. data/bin/SodaSuite +700 -0
  2. metadata +6 -5
@@ -0,0 +1,700 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ###############################################################################
4
+ # Copyright (c) 2010, SugarCRM, Inc.
5
+ # All rights reserved.
6
+ #
7
+ # Redistribution and use in source and binary forms, with or without
8
+ # modification, are permitted provided that the following conditions are met:
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above copyright
12
+ # notice, this list of conditions and the following disclaimer in the
13
+ # documentation and/or other materials provided with the distribution.
14
+ # * Neither the name of SugarCRM, Inc. nor the
15
+ # names of its contributors may be used to endorse or promote products
16
+ # derived from this software without specific prior written permission.
17
+ #
18
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
+ # ARE DISCLAIMED. IN NO EVENT SHALL SugarCRM, Inc. BE LIABLE FOR ANY
22
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ ###############################################################################
29
+
30
+ ###############################################################################
31
+ # Needed Ruby libs:
32
+ ###############################################################################
33
+ require 'Soda'
34
+ require 'getoptlong'
35
+ require 'libxml'
36
+ require 'watir'
37
+ require 'SodaReportSummery'
38
+ require 'pp'
39
+
40
+ ###############################################################################
41
+ # SodaSuite -- Class
42
+ # This is a simple class to run soda tests.
43
+ #
44
+ # Params:
45
+ # params: This is a hash of parameters to pass in.
46
+ #
47
+ # Valid params:
48
+ # browser => [true, false]
49
+ # flavor => [ce pro, ent]
50
+ # savehtml => [true, false]
51
+ # hijacks => {}
52
+ # resultsdir => some directory
53
+ # profile => a firefox profile name
54
+ #
55
+ # Notes:
56
+ # It seems over kill to have this as a class, but I can't think of a good
57
+ # enough reason to change it. Yet....
58
+ #
59
+ ###############################################################################
60
+ class SodaSuite
61
+ attr_accessor :scripts, :soda
62
+
63
+ NEEDED_SODA_VERSION = 1.1
64
+
65
+ def initialize(params)
66
+ @SodaParams = params
67
+ @soda = nil
68
+
69
+ if (NEEDED_SODA_VERSION != Soda::SODA_VERSION)
70
+ print "(!)Failed matching Soda Class Versions!\n" +
71
+ "--)Required Version: #{NEEDED_SODA_VERSION}\n" +
72
+ "--)Found Version : #{Soda::SODA_VERSION}\n\n"
73
+ exit(-1)
74
+ end
75
+
76
+ if ("#{Watir::VERSION}" != "#{Soda::SODA_WATIR_VERSION}")
77
+ print "(!)Failed matching installed Watir version to Soda's" +
78
+ " required version!\n" +
79
+ "--)Required Version: #{Soda::SODA_WATIR_VERSION}\n" +
80
+ "--)Found Version : #{Watir::VERSION}\n\n"
81
+ exit(-1)
82
+ end
83
+ end
84
+
85
+ ###############################################################################
86
+ # ExecuteSodaTest -- Method
87
+ # This method will execute a single specific soda XML test.
88
+ #
89
+ # Params:
90
+ # sodatest: This is the soda XML test to execute.
91
+ #
92
+ # Results:
93
+ # reutns a SodaReport object... THis should be changed later!
94
+ #
95
+ ###############################################################################
96
+ def ExecuteSodaTest(sodatest)
97
+ result = {}
98
+ failed_tests = nil
99
+ soda = nil
100
+
101
+ soda = Soda::Soda.new(@SodaParams)
102
+ result['error'] = soda.run(sodatest)
103
+ result['failed_tests'] = soda.GetFailedTests()
104
+
105
+ return result
106
+ end
107
+
108
+ ###############################################################################
109
+ # ExecuteTestSuite -- Method
110
+ # This method executes a test suite in a single browsers, really this is
111
+ # a hack so all the old soda tests still work without lots of mods...
112
+ #
113
+ # Prams:
114
+ # suite: This is an array of tests to run.
115
+ # rerun: true/false, tells soda that these tests are reruns.
116
+ # reruntest: this is the test to run before starting the rerun tests.
117
+ #
118
+ # Results:
119
+ # None.
120
+ #
121
+ ###############################################################################
122
+ def ExecuteTestSuite(suite, rerun = false, reruntest = nil)
123
+ soda = nil
124
+ master_result = 0
125
+ result = nil
126
+
127
+ soda = Soda::Soda.new(@SodaParams)
128
+
129
+ if (reruntest != nil)
130
+ SodaUtils.PrintSoda("Running rerun test setup script: "+
131
+ "'#{reruntest}'.\n")
132
+ soda.run(reruntest)
133
+ end
134
+
135
+ suite.each do |test|
136
+ result = soda.run(test, rerun)
137
+ if (result == -1)
138
+ SodaUtils.PrintSoda("Failed executing test file: #{test}!\n",
139
+ SodaUtils::ERROR)
140
+ master_result = -1
141
+
142
+ begin
143
+ soda.browser.close()
144
+ rescue Exception => e
145
+ print "Exception: #{e.message}\n"
146
+ ensure
147
+ end
148
+ soda = Soda::Soda.new(@SodaParams)
149
+ end
150
+ end
151
+
152
+ begin
153
+ soda.browser.close()
154
+ rescue Exception => e
155
+ print "Exception: #{e.message}\n"
156
+ ensure
157
+ end
158
+
159
+ soda = nil
160
+ return master_result
161
+ end
162
+
163
+ ###############################################################################
164
+ # Execute -- Medhod
165
+ # This method executes a soda XML scripts. If the files is a directory it
166
+ # will execute all XML scripts in that directory, if it is a file it will
167
+ # execute just that script.
168
+ #
169
+ # Params:
170
+ # file: This is the soda test file or a directory containing soda test
171
+ # files.
172
+ #
173
+ # Results:
174
+ # Returns -1 on error or 0 on success.
175
+ #
176
+ ###############################################################################
177
+ def Execute(file)
178
+ report = nil
179
+
180
+ if (File.directory?(file))
181
+ scriptFiles = File.join("#{file}", "*.xml")
182
+ files = Dir.glob(scriptFiles)
183
+
184
+ for testfile in files
185
+ SodaUtils.PrintSoda("Executing test file: #{testfile}\n")
186
+ report = ExecuteSodaTest(testfile)
187
+
188
+ if (report['error'] == -1)
189
+ return report
190
+ end
191
+ end
192
+ elsif(File.file?(file))
193
+ SodaUtils.PrintSoda("Executing test file: #{file}\n")
194
+ report = ExecuteSodaTest(file)
195
+ SodaUtils.PrintSoda("Finished executing test file: #{file}\n")
196
+
197
+ if (report['error'] == -1)
198
+ return report
199
+ end
200
+ else
201
+ SodaUtils.PrintSoda("Failed To Load File: '#{file}'\n",
202
+ SodaUtils::ERROR)
203
+ end
204
+
205
+ return report
206
+ end
207
+
208
+ end
209
+
210
+ ###############################################################################
211
+ # PrintHelp --
212
+ # This function will print the help message for this script, then exit
213
+ # with an error code, which is anything other then 0.
214
+ #
215
+ # Params:
216
+ # None.
217
+ #
218
+ # Results:
219
+ # None.
220
+ #
221
+ ###############################################################################
222
+ def PrintHelp
223
+ hlp_msg = <<HLP
224
+ #{$0}
225
+ Usage:
226
+ #{$0} --browser="supported browser" --test="sodatest1.xml"
227
+ --test="sodatest2.xml" ...
228
+
229
+ Required Flags:
230
+ --browser: This is any of the following supported web browser name.
231
+ [ firefox, safari, ie ]
232
+
233
+ --test: This is a soda test file. This argument can be used more then
234
+ once when there are more then one soda tests to run.
235
+
236
+ Optional Flags:
237
+ --flavor: This tells Soda which flavor of Sugar you are testing.
238
+ [ent, ce, pro, express] The default is ent when this flag is not set.
239
+
240
+ --savehtml: This flag will cause html pages to be saved when there is an
241
+ error testing the page.
242
+
243
+ --hijack: This is a key/value pair that is used to hi jack any csv file
244
+ values of the same name. The key and value are split using "::".
245
+ Example: --hijack="username::sugaruser"
246
+
247
+ --resultdir: This allows you to override the default results directory.
248
+
249
+ --profile: The name of a Firefox profile to use, other then the default.
250
+
251
+ --gvar: This is a global var key/value pair to be injected into Soda.
252
+ The key and value are split using "::".
253
+ Example: --gvar="slayerurl::http://www.slayer.net"
254
+
255
+ --suite: This is a Soda suite xml test file.
256
+
257
+ --summary: This the the name of the summary file to output.
258
+
259
+ --debug: This turns on debug messages.
260
+
261
+ --rerun: This will cause failed tests to be rerun.
262
+
263
+ --reruntest: This is the test to run before all failed tests are reran, this
264
+ is an optional argument to be used with --rerun for test setup.
265
+
266
+ --sugarwait: This enables the auto sugarwait functionality for every click.
267
+
268
+ --restartcount: This tells soda to restart the web browser after so many
269
+ tests have been ran.
270
+
271
+ --restarttest: This is a soda test that will be ran right after the browser
272
+ is restarted.
273
+
274
+ --help: Prints this message and exits.
275
+
276
+ HLP
277
+
278
+ print "#{hlp_msg}"
279
+ exit(1)
280
+
281
+ end
282
+
283
+ ###############################################################################
284
+ # InstallSigs -- Function
285
+ # This function installs trap handlers to kill the ruby process.
286
+ #
287
+ # Params:
288
+ # None.
289
+ #
290
+ # Results:
291
+ # None.
292
+ #
293
+ # Notes:
294
+ # This is mostly useless as the Watir code doesn't respect signals at all.
295
+ #
296
+ ###############################################################################
297
+ def InstallSigs
298
+ sigs = [
299
+ "INT",
300
+ "ABRT",
301
+ "KILL"
302
+ ]
303
+
304
+ sigs.each do |s|
305
+ Signal.trap(s, proc { Process.kill(INT, Process.pid) } )
306
+ end
307
+
308
+ end
309
+
310
+ ###############################################################################
311
+ # AddCmdArg2Hash - function
312
+ #
313
+ #
314
+ ###############################################################################
315
+ def AddCmdArg2Hash(arg, hash)
316
+ data = arg.split(/::/)
317
+
318
+ if (data.length == 2)
319
+ hash["#{data[0]}"] = "#{data[1]}"
320
+ end
321
+
322
+ return hash
323
+ end
324
+
325
+ ###############################################################################
326
+ # CreateResultsDir - function
327
+ # Creates needed results dir.
328
+ #
329
+ # Params:
330
+ # dir: This is the directory to create.
331
+ #
332
+ # Results:
333
+ # returns 0 on success, or -1 on error.
334
+ #
335
+ ###############################################################################
336
+ def CreateResultsDir(dir)
337
+ result = -1
338
+
339
+ if (File.directory?(dir))
340
+ return 0
341
+ end
342
+
343
+ begin
344
+ FileUtils::mkdir_p(dir)
345
+ result = 0
346
+ rescue Exception => e
347
+ print "(!)Failed to create results directory: #{dir}!\n"
348
+ print "--)Reason: #{e.message}\n\n"
349
+ result = -1
350
+ end
351
+
352
+ return result
353
+
354
+ end
355
+
356
+ ###############################################################################
357
+ # GetFileSetFiles - function
358
+ # This function expands filesets into a list of files.
359
+ #
360
+ # Params:
361
+ # dir: The directory to get soda xml files from.
362
+ #
363
+ # Results:
364
+ # returns an array of files.
365
+ #
366
+ ###############################################################################
367
+ def GetFileSetFiles(dir)
368
+ files = nil
369
+ test_files = []
370
+
371
+ files = File.join("#{dir}", "*.xml")
372
+ test_files = Dir.glob(files)
373
+
374
+ return test_files
375
+ end
376
+
377
+ ###############################################################################
378
+ # GetSuiteTestFiles - function
379
+ # This function reads a sode suite file and creates a list of tests from
380
+ # the file, by expanding on filesets and files.
381
+ #
382
+ # Params:
383
+ # suite_file: This is the suite xml file.
384
+ #
385
+ # Results:
386
+ # returns an array of files.
387
+ #
388
+ ###############################################################################
389
+ def GetSuiteTestFiles(suite_file)
390
+ test_files = []
391
+ parser = nil
392
+ doc = nil
393
+
394
+ parser = LibXML::XML::Parser.file(suite_file)
395
+ doc = parser.parse()
396
+
397
+ doc.root.each do |node|
398
+ if (node.name != 'script')
399
+ next
400
+ end
401
+
402
+ attrs = node.attributes()
403
+ attrs.each do |a|
404
+ h = attrs.to_h()
405
+ if (h.key?("file"))
406
+ test_files.push(h['file'])
407
+ elsif (h.key?('fileset'))
408
+ fs = h['fileset']
409
+ if (File.directory?(fs))
410
+ fs_set = GetFileSetFiles(fs)
411
+ test_files.concat(fs_set)
412
+ fs_set = nil
413
+ end
414
+ end
415
+ end
416
+ end
417
+
418
+ return test_files
419
+ end
420
+
421
+ ###############################################################################
422
+ # ReadConfigFile - function
423
+ # This functions reads the soda config file into a hash.
424
+ #
425
+ # Params:
426
+ # configfile: This is the config xml file to read.
427
+ #
428
+ # Results:
429
+ # Returns a hash containing the config file parsed into sub hashes and
430
+ # arrays.
431
+ #
432
+ ###############################################################################
433
+ def ReadConfigFile(configfile)
434
+ parser = nil
435
+ doc = nil
436
+ data = {
437
+ "gvars" => {},
438
+ "cmdopts" => [],
439
+ "errorskip" => []
440
+ }
441
+
442
+ parser = LibXML::XML::Parser.file(configfile)
443
+ doc = parser.parse()
444
+
445
+ doc.root.each do |node|
446
+ attrs = node.attributes()
447
+ attrs = attrs.to_h()
448
+ name = attrs['name']
449
+ content = node.content()
450
+ case node.name
451
+ when "errorskip"
452
+ data['errorskip'].push("#{attrs['type']}")
453
+ when "gvar"
454
+ data['gvars']["#{name}"] = "#{content}"
455
+ when "cmdopt"
456
+ data['cmdopts'].push({"#{name}" => "#{content}"})
457
+ when "text"
458
+ next
459
+ else
460
+ SodaUtils.PrintSoda("Found unknown xml tag: \"#{node.name}\"!\n",
461
+ SodaUtils::ERROR)
462
+ end
463
+ end
464
+
465
+ return data
466
+ end
467
+
468
+ ###############################################################################
469
+ # Main --
470
+ # This is a C like main function that is being used to help with debugging
471
+ # and code readabality in general. Yes spelling errors in comments are
472
+ # lame...
473
+ #
474
+ # Params:
475
+ # None.
476
+ #
477
+ # Results:
478
+ # A;lways returns 0
479
+ #
480
+ ###############################################################################
481
+ def Main
482
+ master_result = 0
483
+ result = 0
484
+ config_file = "soda-config.xml"
485
+ config_data = nil
486
+ sweet = nil
487
+ verbose = false
488
+ browser = nil
489
+ flavor = "ent"
490
+ savehtml = false
491
+ resultsdir = nil
492
+ profile = nil
493
+ rerun_failed_test = false
494
+ rerun_test_script = nil
495
+ failed_tests = []
496
+ test_files = []
497
+ hijacks = {}
498
+ params = {
499
+ 'sugarwait' => false,
500
+ 'verbose' => false,
501
+ 'browser' => nil,
502
+ 'debug' => false,
503
+ 'flavor' => "ent",
504
+ 'savehtml' => false,
505
+ 'resultsdir' => nil,
506
+ 'profile' => nil,
507
+ 'summaryfile' => nil,
508
+ 'suites' => [],
509
+ 'test_files' => [],
510
+ 'hijacks' => {},
511
+ 'gvars' => [],
512
+ 'errorskip' => [],
513
+ 'restart_count' => 0,
514
+ 'restart_test' => ""
515
+ }
516
+
517
+ # turn off ruby i/o buffering #
518
+ $stdout.sync = true;
519
+ $stderr.sync = true;
520
+
521
+ InstallSigs()
522
+
523
+ if (File.file?(config_file))
524
+ config_data = ReadConfigFile(config_file)
525
+ params['gvars'] = config_data['gvars']
526
+ params['errorskip'] = config_data['errorskip']
527
+ else
528
+ config_data = nil
529
+ end
530
+
531
+ if ((config_data != nil) && (config_data.key?('cmdopts')))
532
+ config_data['cmdopts'].each do |o|
533
+ if (o.key?('browser'))
534
+ params['browser'] = o['browser']
535
+ break
536
+ end
537
+ end
538
+ end
539
+
540
+ begin
541
+ opts = GetoptLong.new(
542
+ [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
543
+ [ '--browser', '-b', GetoptLong::OPTIONAL_ARGUMENT ],
544
+ [ '--debug', '-d', GetoptLong::NO_ARGUMENT ],
545
+ [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
546
+ [ '--test', '-t', GetoptLong::REQUIRED_ARGUMENT ],
547
+ [ '--flavor', '-f', GetoptLong::OPTIONAL_ARGUMENT ],
548
+ [ '--hijack', '-j', GetoptLong::OPTIONAL_ARGUMENT ],
549
+ [ '--savehtml', '-s', GetoptLong::NO_ARGUMENT ],
550
+ [ '--resultdir', '-r', GetoptLong::OPTIONAL_ARGUMENT ],
551
+ [ '--profile', '-p', GetoptLong::OPTIONAL_ARGUMENT ],
552
+ [ '--gvar', '-g', GetoptLong::OPTIONAL_ARGUMENT ],
553
+ [ '--suite', '-u', GetoptLong::OPTIONAL_ARGUMENT ],
554
+ [ '--summary', '-k', GetoptLong::OPTIONAL_ARGUMENT ],
555
+ [ '--rerun', '-e', GetoptLong::OPTIONAL_ARGUMENT ],
556
+ [ '--sugarwait', '-w', GetoptLong::OPTIONAL_ARGUMENT ],
557
+ [ '--restartcount', '-1', GetoptLong::OPTIONAL_ARGUMENT ],
558
+ [ '--restarttest', '-2', GetoptLong::OPTIONAL_ARGUMENT],
559
+ [ '--reruntest', '-3', GetoptLong::OPTIONAL_ARGUMENT ]
560
+ )
561
+
562
+ opts.quiet = true
563
+ opts.each do |opt, arg|
564
+ case opt
565
+ when "--restartcount"
566
+ params['restart_count'] = arg.to_i()
567
+ when "--restarttest"
568
+ params['restart_test'] = arg
569
+ when "--sugarwait"
570
+ params['sugarwait'] = true
571
+ when "--help"
572
+ PrintHelp()
573
+ when "--browser"
574
+ params['browser'] = arg
575
+ when "--debug"
576
+ params['debug'] = true
577
+ when "--verbose"
578
+ params['verbose'] = true
579
+ when "--test"
580
+ params['test_files'].push(arg)
581
+ when "--flavor"
582
+ params['flavor'] = arg
583
+ when "--savehtml"
584
+ params['savehtml'] = true
585
+ when "--hijack"
586
+ params['hijacks'] = AddCmdArg2Hash(arg, hijacks)
587
+ when "--resultdir"
588
+ params['resultsdir'] = arg
589
+ when "--profile"
590
+ params['profile'] = arg
591
+ when "--suite"
592
+ params['suites'].push(arg)
593
+ when "--summary"
594
+ params['summaryfile'] = arg.to_s()
595
+ when "--gvar"
596
+ params['gvars'] = AddCmdArg2Hash(arg, params['gvars'])
597
+ when "--rerun"
598
+ rerun_failed_test = true
599
+ when "--reruntest"
600
+ rerun_test_script = arg
601
+ end
602
+ end
603
+ rescue Exception => e
604
+ SodaUtils.PrintSoda("Error: #{e.message}\n", SodaUtils::ERROR)
605
+ exit(-1)
606
+ end
607
+
608
+ if (!params['browser'])
609
+ SodaUtils.PrintSoda("Missing argument --browser!\n\n", 1)
610
+ PrintHelp()
611
+ end
612
+
613
+ if ( (params['test_files'].length < 1) && (params['suites'].length < 1) )
614
+ SodaUtils.PrintSoda("Missing soda tests to run, try using --test=" +
615
+ "<sodatestfile>!\n\n")
616
+ PrintHelp()
617
+ end
618
+
619
+ if (params['debug'])
620
+ SodaUtils.PrintSoda("SodaSuite Params:\n")
621
+ params.each do |k, v|
622
+ SodaUtils.PrintSoda("'#{k}' => '#{v}'\n")
623
+ end
624
+ end
625
+
626
+ SodaUtils.PrintSoda("SodaSuite Settings:\n--)Browser:" +
627
+ " #{params['browser']}\n--)Debug: #{params['debug']}\n--)Verbose:"+
628
+ " #{params['verbose']}\n" +
629
+ "--)Watir Version: #{Watir::VERSION}\n")
630
+ SodaUtils.PrintSoda("Starting testing...\n")
631
+
632
+ if (params['resultsdir'] != nil)
633
+ err = CreateResultsDir(params['resultsdir'])
634
+ print "Result: #{err}\n"
635
+ if (err != 0)
636
+ exit(-1)
637
+ end
638
+
639
+ if (params['summaryfile'] == nil)
640
+ params['summaryfile'] = "#{params['resultsdir']}/summary.html"
641
+ end
642
+
643
+ end
644
+
645
+ if (params['suites'].length > 0)
646
+ sweet = SodaSuite.new(params)
647
+ params['suites'].each do |swt|
648
+ result = sweet.ExecuteTestSuite(swt)
649
+ if (result != 0)
650
+ master_result = -1
651
+ end
652
+ end
653
+ end
654
+
655
+ if (params['test_files'].length > 0)
656
+ sweet = SodaSuite.new(params)
657
+ params['test_files'].each do |testfile|
658
+ result = sweet.Execute(testfile)
659
+ failed_tests = failed_tests.concat(result['failed_tests'])
660
+
661
+ if (result['error'] != 0)
662
+ master_result = -1
663
+ SodaUtils.PrintSoda("Failed executing soda test:"+
664
+ "\"#{testfile}\"!\n")
665
+ sweet = SodaSuite.new(params)
666
+ end
667
+ end
668
+ end
669
+
670
+ # see if we should rerun failed tests #
671
+ if (rerun_failed_test && failed_tests.length > 0)
672
+ SodaUtils.PrintSoda("Rerunning failed tests.\n")
673
+ sweet.ExecuteTestSuite(failed_tests, true, rerun_test_script)
674
+ SodaUtils.PrintSoda("Finished rerunning failed tests.\n")
675
+ end
676
+
677
+ if (params['resultsdir'] != nil)
678
+ begin
679
+ summery = SodaReportSummery.new(params['resultsdir'],
680
+ params['summaryfile'], true)
681
+ rescue Exception => e
682
+ print "Error: calling: SodaReportSummery!\n"
683
+ print "StackTrace: #{e.backtrace}\n\n"
684
+ exit(-1)
685
+ ensure
686
+ end
687
+ end
688
+
689
+ SodaUtils.PrintSoda("Finished testing.\n")
690
+ exit(master_result)
691
+ end
692
+
693
+ ###############################################################################
694
+ # Start executing code here -->
695
+ ###############################################################################
696
+ Main()
697
+ exit(0)
698
+
699
+
700
+
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: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Trampus Richmond
@@ -50,8 +50,8 @@ dependencies:
50
50
  version_requirements: *id002
51
51
  description: This is a wrapper around the watir api for web testing.
52
52
  email: trichmond@sugarcrm.com
53
- executables: []
54
-
53
+ executables:
54
+ - SodaSuite
55
55
  extensions: []
56
56
 
57
57
  extra_rdoc_files: []
@@ -68,6 +68,7 @@ files:
68
68
  - lib/SodaFireFox.rb
69
69
  - lib/SodaReporter.rb
70
70
  - lib/SodaLogReporter.rb
71
+ - bin/SodaSuite
71
72
  - lib/utils/sodalookups.rb
72
73
  - lib/fields/SelectField.rb
73
74
  - lib/fields/TextField.rb