soda 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/FieldUtils.rb +102 -0
- data/lib/Soda.rb +2628 -0
- data/lib/SodaCSV.rb +88 -0
- data/lib/SodaFireFox.rb +118 -0
- data/lib/SodaLogReporter.rb +810 -0
- data/lib/SodaReportSummery.rb +470 -0
- data/lib/SodaReporter.rb +452 -0
- data/lib/SodaTestCheck.rb +347 -0
- data/lib/SodaUtils.rb +931 -0
- data/lib/SodaXML.rb +129 -0
- data/lib/fields/CheckBoxField.rb +87 -0
- data/lib/fields/FileField.rb +37 -0
- data/lib/fields/LiField.rb +40 -0
- data/lib/fields/RadioField.rb +44 -0
- data/lib/fields/SelectField.rb +59 -0
- data/lib/fields/SodaField.rb +363 -0
- data/lib/fields/TextField.rb +31 -0
- data/lib/soda.rb +2 -0
- data/lib/utils/sodalookups.rb +465 -0
- metadata +114 -0
data/lib/SodaUtils.rb
ADDED
@@ -0,0 +1,931 @@
|
|
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 'rbconfig'
|
32
|
+
require 'time'
|
33
|
+
require 'rubygems'
|
34
|
+
require 'libxml'
|
35
|
+
require 'uri'
|
36
|
+
|
37
|
+
###############################################################################
|
38
|
+
# SodaUtils -- Module
|
39
|
+
# This module is to provide useful functions for soda that do not need
|
40
|
+
# to create an object to use this functionality. The whole point to this
|
41
|
+
# module is to be fast, simple, and useful.
|
42
|
+
#
|
43
|
+
###############################################################################
|
44
|
+
module SodaUtils
|
45
|
+
|
46
|
+
###############################################################################
|
47
|
+
# Module global data:
|
48
|
+
###############################################################################
|
49
|
+
VERSION = "1.0"
|
50
|
+
LOG = 0
|
51
|
+
ERROR = 1
|
52
|
+
WARN = 2
|
53
|
+
EVENT = 3
|
54
|
+
FIREFOX_JS_ERROR_CHECK_SRC = <<JS
|
55
|
+
var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
|
56
|
+
var msg = {};
|
57
|
+
var msg_count = {};
|
58
|
+
aConsoleService.getMessageArray(msg, {});
|
59
|
+
msg.value.forEach(function(m) {
|
60
|
+
if (m instanceof Components.interfaces.nsIScriptError) {
|
61
|
+
m.QueryInterface(Components.interfaces.nsIScriptError);
|
62
|
+
var txt = "--Error::" + m.errorMessage +
|
63
|
+
"--Line::" + m.lineNumber +
|
64
|
+
"--Col::" + m.columnNumber +
|
65
|
+
"--Flags::" + m.flags +
|
66
|
+
"--Cat::" + m.category+
|
67
|
+
"--SrcName::" + m.sourceName;
|
68
|
+
print("######" + txt);
|
69
|
+
}
|
70
|
+
});
|
71
|
+
|
72
|
+
aConsoleService.reset();
|
73
|
+
|
74
|
+
JS
|
75
|
+
|
76
|
+
FIREFOX_JS_ERROR_CLEAR = <<JS
|
77
|
+
var aConsoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
|
78
|
+
|
79
|
+
aConsoleService.reset();
|
80
|
+
|
81
|
+
JS
|
82
|
+
|
83
|
+
###############################################################################
|
84
|
+
# GetOsType --
|
85
|
+
# This function checks the internal ruby config to see what os we are
|
86
|
+
# running on. We should never use the RUBY_PLATFORM as it will not aways
|
87
|
+
# give us the info we need.
|
88
|
+
#
|
89
|
+
# Currently this function only checks for supported OS's and will return
|
90
|
+
# and error if run on an unsupported os.
|
91
|
+
#
|
92
|
+
# Params:
|
93
|
+
# None.
|
94
|
+
#
|
95
|
+
# Results:
|
96
|
+
# returns nil on error, or one of the supported os names in generic
|
97
|
+
# format.
|
98
|
+
#
|
99
|
+
# Supported OS return values:
|
100
|
+
# 1.) WINDOWS
|
101
|
+
# 2.) LINUX
|
102
|
+
# 3.) OSX
|
103
|
+
#
|
104
|
+
###############################################################################
|
105
|
+
def SodaUtils.GetOsType
|
106
|
+
os = ""
|
107
|
+
|
108
|
+
if Config::CONFIG['host_os'] =~ /mswin/i
|
109
|
+
os = "WINDOWS"
|
110
|
+
elsif Config::CONFIG['host_os'] =~ /linux/i
|
111
|
+
os = "LINUX"
|
112
|
+
elsif Config::CONFIG['host_os'] =~ /darwin/i
|
113
|
+
os = "OSX"
|
114
|
+
else
|
115
|
+
os = Config::CONFIG['host_os'];
|
116
|
+
PrintSoda("Found unsupported OS: #{os}!\n", 1)
|
117
|
+
os = nil
|
118
|
+
end
|
119
|
+
|
120
|
+
return os
|
121
|
+
end
|
122
|
+
|
123
|
+
###############################################################################
|
124
|
+
# PrintSoda --
|
125
|
+
# This is a print function that creates standard formatting when printing
|
126
|
+
# Soda message.
|
127
|
+
#
|
128
|
+
# Params:
|
129
|
+
# str: This is the user message that will be printed after being formatted.
|
130
|
+
#
|
131
|
+
# error: If set to 1 then all message will start "(!)" to note an error
|
132
|
+
# is being reported. Anything passed other then 1 will result in a
|
133
|
+
# "(*)" being used for the message start.
|
134
|
+
#
|
135
|
+
# file: A valid open writable file handle. If this isn't nil then all
|
136
|
+
# this message will be writen to the file. Passing nil will bypass
|
137
|
+
# this and cause all message to go to STDOUT.
|
138
|
+
#
|
139
|
+
# debug: This will print the caller stack before the message so you can
|
140
|
+
# have more useful info for debugging. Also a datetime stamp will be
|
141
|
+
# added to the beginning of the message.
|
142
|
+
#
|
143
|
+
# notime: Setting this to anything other then 0 will remove the datetime
|
144
|
+
# stamp from the stdout message, but never from the file message.
|
145
|
+
#
|
146
|
+
# Results:
|
147
|
+
# Always returns the message that is printed.
|
148
|
+
#
|
149
|
+
###############################################################################
|
150
|
+
def SodaUtils.PrintSoda (str, error = 0, file = nil, debug = 0, notime = 0,
|
151
|
+
callback = nil)
|
152
|
+
header = ""
|
153
|
+
error_header = ""
|
154
|
+
msg = nil
|
155
|
+
datetime = nil
|
156
|
+
stackmsg = ""
|
157
|
+
now = nil
|
158
|
+
|
159
|
+
now = Time.now().strftime("%m/%d/%Y-%H:%M:%S")
|
160
|
+
header = "[#{now}]"
|
161
|
+
|
162
|
+
if (debug != 0)
|
163
|
+
cstak = caller()
|
164
|
+
stackmsg = "[Call Stack]:\n"
|
165
|
+
cstak.each do |stack|
|
166
|
+
stackmsg = stackmsg + "--#{stack}"
|
167
|
+
end
|
168
|
+
stackmsg = stackmsg + "\n"
|
169
|
+
end
|
170
|
+
|
171
|
+
case error
|
172
|
+
when SodaUtils::LOG
|
173
|
+
error_header = "(*)"
|
174
|
+
when SodaUtils::ERROR
|
175
|
+
error_header = "(!)"
|
176
|
+
when SodaUtils::WARN
|
177
|
+
error_header = "(W)"
|
178
|
+
when SodaUtils::EVENT
|
179
|
+
error_header = "(E)"
|
180
|
+
else
|
181
|
+
error_header = "(*)"
|
182
|
+
end
|
183
|
+
|
184
|
+
if ( (debug != 1) && (error != 1) )
|
185
|
+
msg = header + "#{error_header}#{str}"
|
186
|
+
elsif (debug != 0)
|
187
|
+
msg = header + "#{error_header}#{str}#{stackmsg}\n"
|
188
|
+
else
|
189
|
+
msg = "#{header}#{error_header}#{str}"
|
190
|
+
end
|
191
|
+
|
192
|
+
if (file)
|
193
|
+
file.write(msg)
|
194
|
+
else
|
195
|
+
if (notime != 0)
|
196
|
+
msg = msg.gsub("[#{now}]", "")
|
197
|
+
end
|
198
|
+
|
199
|
+
print "#{msg}"
|
200
|
+
end
|
201
|
+
|
202
|
+
if (callback != nil)
|
203
|
+
callback.call("#{msg}")
|
204
|
+
end
|
205
|
+
|
206
|
+
return msg
|
207
|
+
|
208
|
+
end
|
209
|
+
|
210
|
+
###############################################################################
|
211
|
+
# DumpEvent -- Function
|
212
|
+
# This function dumps a Soda event into a nice log format that can be
|
213
|
+
# parsed by our friendly SodaLogReporter class into html.
|
214
|
+
#
|
215
|
+
# Params:
|
216
|
+
# event: This is the soda event to dump. Really this can be an ruby hash.
|
217
|
+
#
|
218
|
+
# Results:
|
219
|
+
# returns a formatted string on success, or an empty string when there is
|
220
|
+
# no hash pairs.
|
221
|
+
#
|
222
|
+
# Notes:
|
223
|
+
# The formatted string results will look like this:
|
224
|
+
# str = "--do=>puts--text=>Closing browser"
|
225
|
+
#
|
226
|
+
###############################################################################
|
227
|
+
def SodaUtils.DumpEvent(event)
|
228
|
+
str = ""
|
229
|
+
|
230
|
+
if (event.length < 1)
|
231
|
+
return str
|
232
|
+
end
|
233
|
+
|
234
|
+
event.each do |key, val|
|
235
|
+
str << "--#{key}=>#{val}"
|
236
|
+
end
|
237
|
+
|
238
|
+
return str
|
239
|
+
end
|
240
|
+
|
241
|
+
###############################################################################
|
242
|
+
# Base64FileEncode - function
|
243
|
+
# This function encodes a file in base64 encoding, without modifying the
|
244
|
+
# source file. So a new file is created that is the encoded version of
|
245
|
+
# the source file.
|
246
|
+
#
|
247
|
+
# Params:
|
248
|
+
# inputfile: The file to encode.
|
249
|
+
# outputfile: The dest for the encoded file.
|
250
|
+
# tostream: Setting this to true will cause this function to notw write to
|
251
|
+
# a file, but to return an encoded stream of bytes insted.
|
252
|
+
#
|
253
|
+
# Results:
|
254
|
+
# When tostream is set, will return a stream of encoded bytes.
|
255
|
+
#
|
256
|
+
###############################################################################
|
257
|
+
def SodaUtils.Base64FileEncode(inputfile, outputfile, tostream = false)
|
258
|
+
buffer = ""
|
259
|
+
stream = ""
|
260
|
+
base64_stream = ""
|
261
|
+
|
262
|
+
src_file = File.new(inputfile, "r")
|
263
|
+
|
264
|
+
if (tostream != true)
|
265
|
+
out_file = File.new(outputfile, "w+")
|
266
|
+
out_file.binmode
|
267
|
+
out_file.sync = true
|
268
|
+
end
|
269
|
+
|
270
|
+
src_file.sync = true
|
271
|
+
src_file.binmode
|
272
|
+
|
273
|
+
while (src_file.read(1024, buffer) != nil)
|
274
|
+
stream << buffer
|
275
|
+
end
|
276
|
+
buffer = nil
|
277
|
+
src_file.close
|
278
|
+
|
279
|
+
base64_stream = [stream].pack('m')
|
280
|
+
stream = nil
|
281
|
+
|
282
|
+
if (tostream != true)
|
283
|
+
out_file.write(base64_stream)
|
284
|
+
base64_stream = nil
|
285
|
+
out_file.close
|
286
|
+
base64_stream = nil
|
287
|
+
end
|
288
|
+
|
289
|
+
return base64_stream
|
290
|
+
|
291
|
+
end
|
292
|
+
|
293
|
+
###############################################################################
|
294
|
+
# Base64FileDecode - function
|
295
|
+
# This function decodes a file from base64 encoding, without modifying the
|
296
|
+
# source file. So a new file is created that is the decoded version of
|
297
|
+
# the source file.
|
298
|
+
#
|
299
|
+
# Params:
|
300
|
+
# inputfile: The file to decode.
|
301
|
+
# outputfile: The dest for the decoded file.
|
302
|
+
#
|
303
|
+
# Results:
|
304
|
+
# None.
|
305
|
+
#
|
306
|
+
###############################################################################
|
307
|
+
def SodaUtils.Base64FileDecode(inputfile, outputfile)
|
308
|
+
src_file = File.new(inputfile, "r")
|
309
|
+
out_file = File.new(outputfile, "w+")
|
310
|
+
buffer = ""
|
311
|
+
base64_stream = ""
|
312
|
+
stream = ""
|
313
|
+
|
314
|
+
src_file.sync = true
|
315
|
+
out_file.sync = true
|
316
|
+
src_file.binmode
|
317
|
+
out_file.binmode
|
318
|
+
|
319
|
+
while (src_file.read(1024, buffer) != nil)
|
320
|
+
base64_stream << buffer
|
321
|
+
end
|
322
|
+
buffer = nil
|
323
|
+
src_file.close
|
324
|
+
|
325
|
+
stream = base64_stream.unpack('m')
|
326
|
+
out_file.write(stream)
|
327
|
+
stream = nil
|
328
|
+
out_file.close
|
329
|
+
|
330
|
+
end
|
331
|
+
|
332
|
+
###############################################################################
|
333
|
+
# ParseBlockFile -- Function
|
334
|
+
# This function parses Soda block xml files.
|
335
|
+
#
|
336
|
+
# Params:
|
337
|
+
# block_file: The xml file with blocks
|
338
|
+
#
|
339
|
+
# Results:
|
340
|
+
# returns an array of hashs.
|
341
|
+
#
|
342
|
+
###############################################################################
|
343
|
+
def SodaUtils.ParseBlockFile(block_file)
|
344
|
+
parser = nil
|
345
|
+
error = false
|
346
|
+
data = []
|
347
|
+
doc = nil
|
348
|
+
|
349
|
+
begin
|
350
|
+
parser = LibXML::XML::Parser.file(block_file)
|
351
|
+
doc = parser.parse()
|
352
|
+
rescue Exception => e
|
353
|
+
error = true
|
354
|
+
data = []
|
355
|
+
print "Error: #{e.message}!\n"
|
356
|
+
print "BackTrace: #{e.backtrace}!\n"
|
357
|
+
ensure
|
358
|
+
if (error != false)
|
359
|
+
return data
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
doc.root.each do |node|
|
364
|
+
hash = Hash.new
|
365
|
+
|
366
|
+
if (node.name != "block")
|
367
|
+
next
|
368
|
+
end
|
369
|
+
|
370
|
+
for child in node.children()
|
371
|
+
hash[child.name] = "#{child.content}"
|
372
|
+
end
|
373
|
+
|
374
|
+
if (hash['testfile'].empty?)
|
375
|
+
next
|
376
|
+
end
|
377
|
+
|
378
|
+
data.push(hash)
|
379
|
+
end
|
380
|
+
|
381
|
+
return data
|
382
|
+
end
|
383
|
+
|
384
|
+
###############################################################################
|
385
|
+
# ParseWhiteFile -- Function
|
386
|
+
# This function parses Soda white xml files.
|
387
|
+
#
|
388
|
+
# Params:
|
389
|
+
# white_file: The xml file with white list.
|
390
|
+
#
|
391
|
+
# Results:
|
392
|
+
# returns an array of hashs.
|
393
|
+
#
|
394
|
+
###############################################################################
|
395
|
+
def SodaUtils.ParseWhiteFile(white_file)
|
396
|
+
parser = nil
|
397
|
+
error = false
|
398
|
+
data = []
|
399
|
+
doc = nil
|
400
|
+
|
401
|
+
begin
|
402
|
+
parser = LibXML::XML::Parser.file(white_file)
|
403
|
+
doc = parser.parse()
|
404
|
+
rescue Exception => e
|
405
|
+
error = true
|
406
|
+
data = []
|
407
|
+
print "Error: #{e.message}!\n"
|
408
|
+
print "BackTrace: #{e.backtrace}!\n"
|
409
|
+
ensure
|
410
|
+
if (error != false)
|
411
|
+
return data
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
doc.root.each do |node|
|
416
|
+
hash = Hash.new
|
417
|
+
|
418
|
+
if (node.name != "white")
|
419
|
+
next
|
420
|
+
end
|
421
|
+
|
422
|
+
for child in node.children()
|
423
|
+
hash[child.name] = "#{child.content}"
|
424
|
+
end
|
425
|
+
|
426
|
+
data.push(hash)
|
427
|
+
end
|
428
|
+
|
429
|
+
return data
|
430
|
+
end
|
431
|
+
|
432
|
+
###############################################################################
|
433
|
+
# ParseOldBlockListFile -- Function
|
434
|
+
# This function parses the old style txt blocklist files.
|
435
|
+
#
|
436
|
+
# Params:
|
437
|
+
# block_file: This is the blocklist file to parse.
|
438
|
+
#
|
439
|
+
# Results:
|
440
|
+
# Returns an array of all the files to block, or an empty array on error.
|
441
|
+
#
|
442
|
+
###############################################################################
|
443
|
+
def SodaUtils.ParseOldBlockListFile(block_file)
|
444
|
+
result = []
|
445
|
+
block_file = File.expand_path(block_file)
|
446
|
+
|
447
|
+
if (FileTest.exist?(block_file))
|
448
|
+
file_array = IO.readlines(block_file)
|
449
|
+
file_array.each do |line|
|
450
|
+
line = line.chomp
|
451
|
+
bfiles = line.split(',')
|
452
|
+
|
453
|
+
for bf in bfiles
|
454
|
+
if (bf == "")
|
455
|
+
next
|
456
|
+
end
|
457
|
+
result.push(bf)
|
458
|
+
end
|
459
|
+
end
|
460
|
+
else
|
461
|
+
result = []
|
462
|
+
end
|
463
|
+
|
464
|
+
return result
|
465
|
+
end
|
466
|
+
|
467
|
+
###############################################################################
|
468
|
+
# ConvertOldBrowserClose -- Function
|
469
|
+
# This function converts all the old style soda browser closes to the
|
470
|
+
# new proper way to close the browser as an action.
|
471
|
+
#
|
472
|
+
# Params:
|
473
|
+
# event: a soda event.
|
474
|
+
# reportobj: The soda report object.
|
475
|
+
# testfile: The file with the issue.
|
476
|
+
#
|
477
|
+
# Results:
|
478
|
+
# Always returns a soda event.
|
479
|
+
#
|
480
|
+
###############################################################################
|
481
|
+
def SodaUtils.ConvertOldBrowserClose(event, reportobj, testfile)
|
482
|
+
|
483
|
+
if (event.key?('close'))
|
484
|
+
event['action'] = "close"
|
485
|
+
event.delete('close')
|
486
|
+
reportobj.log("You are using a deprecated Soda feature: <browser close" +
|
487
|
+
"=\"true\" /> Test file: \"#{testfile}\", Line: "+
|
488
|
+
"#{event['line_number']}!\n",
|
489
|
+
SodaUtils::WARN)
|
490
|
+
reportobj.log("Use <browser action=\"close\" />.\n", SodaUtils::WARN)
|
491
|
+
end
|
492
|
+
|
493
|
+
return event
|
494
|
+
end
|
495
|
+
|
496
|
+
###############################################################################
|
497
|
+
# ConvertOldAssert -- function
|
498
|
+
# This function is to handle all the old tests that use the old way to
|
499
|
+
# assertnot, which was a total hack! So this function just looks for the
|
500
|
+
# old style assert & exist=false code and converts it to a proper
|
501
|
+
# assertnot call.
|
502
|
+
#
|
503
|
+
# Params:
|
504
|
+
# event: This is a soda event.
|
505
|
+
# reportobj: This is soda's report object for logging.
|
506
|
+
# testfile: This is the test file that the event came from.
|
507
|
+
#
|
508
|
+
# Results:
|
509
|
+
# Always returns a soda event.
|
510
|
+
#
|
511
|
+
###############################################################################
|
512
|
+
def SodaUtils.ConvertOldAssert(event, reportobj, testfile)
|
513
|
+
msg = nil
|
514
|
+
|
515
|
+
if ( (event.key?('exist')) && (event.key?('assert')) )
|
516
|
+
event['exist'] = getStringBool(event['exist'])
|
517
|
+
|
518
|
+
if (event['exist'] == false)
|
519
|
+
event['assertnot'] = event['assert']
|
520
|
+
end
|
521
|
+
|
522
|
+
msg = "You are using a deprecated Soda feature: " +
|
523
|
+
"< assert=\"something\" exist=\"false\" />" +
|
524
|
+
" Test file: \"#{testfile}\", Line: #{event['line_number']}\n."
|
525
|
+
reportobj.log(msg, SodaUtils::WARN)
|
526
|
+
|
527
|
+
msg = "Use: < assertnot=\"something\" />\n"
|
528
|
+
reportobj.log(msg, SodaUtils::WARN)
|
529
|
+
|
530
|
+
event.delete('exist')
|
531
|
+
event.delete('assert')
|
532
|
+
end
|
533
|
+
|
534
|
+
return event
|
535
|
+
end
|
536
|
+
|
537
|
+
###############################################################################
|
538
|
+
# isRegex -- Function
|
539
|
+
# This function checks to see if a string is a perl looking regex.
|
540
|
+
#
|
541
|
+
# Input:
|
542
|
+
# str: The string to check.
|
543
|
+
#
|
544
|
+
# Output:
|
545
|
+
# returns true if it is a regex, else false.
|
546
|
+
#
|
547
|
+
###############################################################################
|
548
|
+
def SodaUtils.isRegex(str)
|
549
|
+
result = false
|
550
|
+
|
551
|
+
if ( (str =~ /^\//) && (str =~ /\/$|\/\w+$/) )
|
552
|
+
result = true
|
553
|
+
else
|
554
|
+
result = false
|
555
|
+
end
|
556
|
+
|
557
|
+
return result
|
558
|
+
end
|
559
|
+
|
560
|
+
###############################################################################
|
561
|
+
# CreateRegexFromStr -- Function
|
562
|
+
# This function creates a regexp object from a string.
|
563
|
+
#
|
564
|
+
# Input:
|
565
|
+
# str: This is the regex string.
|
566
|
+
#
|
567
|
+
# Output:
|
568
|
+
# returns nil on error, or a Regexp object on success.
|
569
|
+
#
|
570
|
+
###############################################################################
|
571
|
+
def SodaUtils.CreateRegexFromStr(str)
|
572
|
+
options = 0
|
573
|
+
items = ""
|
574
|
+
|
575
|
+
return nil if (!isRegex(str))
|
576
|
+
|
577
|
+
str = str.gsub(/^\//,"")
|
578
|
+
str =~ /\/(\w+)$/
|
579
|
+
items = $1
|
580
|
+
str = str.gsub(/\/#{items}$/, "")
|
581
|
+
|
582
|
+
if ((items != nil) && (!items.empty?))
|
583
|
+
items = items.split(//)
|
584
|
+
items.each do |i|
|
585
|
+
case (i)
|
586
|
+
when "i"
|
587
|
+
options = options | Regexp::IGNORECASE
|
588
|
+
when "m"
|
589
|
+
options = options | Regexp::MULTILINE
|
590
|
+
when "x"
|
591
|
+
options = options | Regexp::EXTENDED
|
592
|
+
end
|
593
|
+
end
|
594
|
+
end
|
595
|
+
|
596
|
+
reg = Regexp.new(str, options)
|
597
|
+
|
598
|
+
return reg
|
599
|
+
end
|
600
|
+
|
601
|
+
###############################################################################
|
602
|
+
# XmlSafeStr -- Function
|
603
|
+
#
|
604
|
+
#
|
605
|
+
###############################################################################
|
606
|
+
def SodaUtils.XmlSafeStr(str)
|
607
|
+
str = str.gsub(/&/, "&")
|
608
|
+
str = str.gsub(/"/, """)
|
609
|
+
str = str.gsub(/'/, "'")
|
610
|
+
str = str.gsub(/</, "<")
|
611
|
+
str = str.gsub(/>/, ">")
|
612
|
+
|
613
|
+
return str
|
614
|
+
end
|
615
|
+
|
616
|
+
###############################################################################
|
617
|
+
# getStringBool -- Function
|
618
|
+
# This function checks to see of the value passed to it proves to be
|
619
|
+
# positive in most any way.
|
620
|
+
#
|
621
|
+
# Params:
|
622
|
+
# value: This is a string that will prove something true or false.
|
623
|
+
#
|
624
|
+
# Results:
|
625
|
+
# returns true if the value is a form of being 'positive', or false.
|
626
|
+
# If the value isn't a string then the value is just returned....
|
627
|
+
#
|
628
|
+
# Notes:
|
629
|
+
# This is a total hack, we should be throw an exception if the value is
|
630
|
+
# something other then a string... Will come back to this later...
|
631
|
+
#
|
632
|
+
###############################################################################
|
633
|
+
def SodaUtils.getStringBool(value)
|
634
|
+
results = nil
|
635
|
+
|
636
|
+
if (value.is_a?(String))
|
637
|
+
value.downcase!
|
638
|
+
|
639
|
+
if (value == 'true' or value == 'yes' or value == '1')
|
640
|
+
results = true
|
641
|
+
else
|
642
|
+
results = false
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
return results
|
647
|
+
end
|
648
|
+
|
649
|
+
###############################################################################
|
650
|
+
# ReadSodaConfig - function
|
651
|
+
# This functions reads the soda config file into a hash.
|
652
|
+
#
|
653
|
+
# Params:
|
654
|
+
# configfile: This is the config xml file to read.
|
655
|
+
#
|
656
|
+
# Results:
|
657
|
+
# Returns a hash containing the config file parsed into sub hashes and
|
658
|
+
# arrays.
|
659
|
+
#
|
660
|
+
###############################################################################
|
661
|
+
def SodaUtils.ReadSodaConfig(configfile)
|
662
|
+
parser = nil
|
663
|
+
doc = nil
|
664
|
+
data = {
|
665
|
+
"gvars" => {},
|
666
|
+
"cmdopts" => [],
|
667
|
+
"errorskip" => []
|
668
|
+
}
|
669
|
+
|
670
|
+
parser = LibXML::XML::Parser.file(configfile)
|
671
|
+
doc = parser.parse()
|
672
|
+
|
673
|
+
doc.root.each do |node|
|
674
|
+
attrs = node.attributes()
|
675
|
+
attrs = attrs.to_h()
|
676
|
+
name = attrs['name']
|
677
|
+
content = node.content()
|
678
|
+
case node.name
|
679
|
+
when "errorskip"
|
680
|
+
data['errorskip'].push("#{attrs['type']}")
|
681
|
+
when "gvar"
|
682
|
+
data['gvars']["#{name}"] = "#{content}"
|
683
|
+
when "cmdopt"
|
684
|
+
data['cmdopts'].push({"#{name}" => "#{content}"})
|
685
|
+
when "text"
|
686
|
+
next
|
687
|
+
else
|
688
|
+
SodaUtils.PrintSoda("Found unknown xml tag: \"#{node.name}\"!\n",
|
689
|
+
SodaUtils::ERROR)
|
690
|
+
end
|
691
|
+
end
|
692
|
+
|
693
|
+
return data
|
694
|
+
end
|
695
|
+
|
696
|
+
###############################################################################
|
697
|
+
# IEConvertHref -- function
|
698
|
+
# This function converts a firefox friendly url to an IE one.
|
699
|
+
#
|
700
|
+
# Input:
|
701
|
+
# event: This is the soda event hash.
|
702
|
+
# url: This is the current browser url.
|
703
|
+
#
|
704
|
+
# Output:
|
705
|
+
# returns a updated href key value in the event half.
|
706
|
+
#
|
707
|
+
###############################################################################
|
708
|
+
def SodaUtils.IEConvertHref(event, url)
|
709
|
+
href = event['href']
|
710
|
+
new_url = ""
|
711
|
+
uri = nil
|
712
|
+
path = nil
|
713
|
+
|
714
|
+
uri = URI::split(url)
|
715
|
+
path = uri[5]
|
716
|
+
path =~ /(.*\/).*$/
|
717
|
+
path = $1
|
718
|
+
|
719
|
+
new_url = "#{uri[0]}://#{uri[2]}#{path}#{href}"
|
720
|
+
event['href'] = new_url
|
721
|
+
|
722
|
+
return event
|
723
|
+
end
|
724
|
+
|
725
|
+
###############################################################################
|
726
|
+
# WaitSugarAjaxDone -- function
|
727
|
+
# This function waits to make sure that sugar has finished all ajax
|
728
|
+
# actions.
|
729
|
+
#
|
730
|
+
# Input:
|
731
|
+
# browser: This is a watir browser object.
|
732
|
+
# reportobj: This is an active SodaReporter object.
|
733
|
+
#
|
734
|
+
# Returns:
|
735
|
+
# -1 on error else 0.
|
736
|
+
#
|
737
|
+
# Notes:
|
738
|
+
# I had to split up how Windows OS finds the windows, because Watir's
|
739
|
+
# browser.url() method returns '' every time if there are more then
|
740
|
+
# one window open. This is not the cause it Linux, as linux seems to
|
741
|
+
# know what the current active browser is and returns the expected url.
|
742
|
+
#
|
743
|
+
###############################################################################
|
744
|
+
def SodaUtils.WaitSugarAjaxDone(browser, reportobj)
|
745
|
+
done = false
|
746
|
+
result = 0
|
747
|
+
undef_count = 0
|
748
|
+
url = browser.url()
|
749
|
+
os = ""
|
750
|
+
str_res = ""
|
751
|
+
t1 = nil
|
752
|
+
t2 = nil
|
753
|
+
|
754
|
+
os = GetOsType()
|
755
|
+
|
756
|
+
linux_js = <<JAVA
|
757
|
+
var windows = getWindows();
|
758
|
+
var win_count = windows.length -1;
|
759
|
+
var current_browser_id = -1;
|
760
|
+
var result = "undefined";
|
761
|
+
|
762
|
+
for (var i = 0; i <= win_count; i++) {
|
763
|
+
var tmp_win = windows[i];
|
764
|
+
var tmp_url = tmp_win.getBrowser().contentDocument.URL;
|
765
|
+
|
766
|
+
if (tmp_url == "#{url}") {
|
767
|
+
current_browser_id = i;
|
768
|
+
break;
|
769
|
+
}
|
770
|
+
}
|
771
|
+
JAVA
|
772
|
+
|
773
|
+
other_js = <<JAVA
|
774
|
+
var current_browser_id = 0;
|
775
|
+
JAVA
|
776
|
+
|
777
|
+
if (os =~ /linux/i)
|
778
|
+
js = "#{linux_js}\n"
|
779
|
+
else
|
780
|
+
js = "#{other_js}\n"
|
781
|
+
end
|
782
|
+
|
783
|
+
js += <<JAVA
|
784
|
+
current_browser_id = 0;
|
785
|
+
if (current_browser_id > -1) {
|
786
|
+
var target = getWindows()[current_browser_id];
|
787
|
+
var browser = target.getBrowser();
|
788
|
+
var content = target.content;
|
789
|
+
var doc = browser.contentDocument;
|
790
|
+
var d = doc.createElement("script");
|
791
|
+
var tmp = null;
|
792
|
+
|
793
|
+
tmp = doc.getElementById("Sodahack");
|
794
|
+
if (tmp != null) {
|
795
|
+
doc.body.removeChild(tmp);
|
796
|
+
}
|
797
|
+
|
798
|
+
d.setAttribute("id", "Sodahack");
|
799
|
+
var src = "if (typeof SUGAR == 'undefined') {\n";
|
800
|
+
src += " document.soda_sugar_done = 'undefined';\n";
|
801
|
+
src += "} else {\n";
|
802
|
+
src += " document.soda_sugar_done = SUGAR.util.ajaxCallInProgress();\n";
|
803
|
+
src += "}";
|
804
|
+
|
805
|
+
d.innerHTML = src;
|
806
|
+
doc.body.appendChild(d);
|
807
|
+
print(doc.soda_sugar_done);
|
808
|
+
result = doc.soda_sugar_done;
|
809
|
+
} else {
|
810
|
+
result = "undefined";
|
811
|
+
}
|
812
|
+
|
813
|
+
print(result);
|
814
|
+
JAVA
|
815
|
+
|
816
|
+
reportobj.log("Calling: SugarWait.\n")
|
817
|
+
t1 = Time.now()
|
818
|
+
|
819
|
+
for i in 0..300
|
820
|
+
tmp = browser.js_eval(js)
|
821
|
+
tmp = tmp.chomp()
|
822
|
+
|
823
|
+
case (tmp)
|
824
|
+
when /false/i
|
825
|
+
tmp = false
|
826
|
+
str_res = "false"
|
827
|
+
when /true/i
|
828
|
+
tmp = true
|
829
|
+
str_res = "true"
|
830
|
+
when /undefined/i
|
831
|
+
str_res = "Undefined"
|
832
|
+
tmp = nil
|
833
|
+
undef_count += 1
|
834
|
+
else
|
835
|
+
reportobj.log("WaitSugarAjaxDone: Unknown result: '#{tmp}'!\n",
|
836
|
+
SodaUtils::WARN)
|
837
|
+
end
|
838
|
+
|
839
|
+
if (tmp == false)
|
840
|
+
done = true
|
841
|
+
break
|
842
|
+
end
|
843
|
+
|
844
|
+
if (undef_count > 30)
|
845
|
+
msg = "WaitSugarAjaxDone: Can't find SUGAR object after 30 tries!\n"
|
846
|
+
reportobj.ReportFailure(msg)
|
847
|
+
done = false
|
848
|
+
break
|
849
|
+
end
|
850
|
+
|
851
|
+
sleep(0.5)
|
852
|
+
end
|
853
|
+
|
854
|
+
t2 = Time.now()
|
855
|
+
t1 = t2 - t1
|
856
|
+
|
857
|
+
msg = "WaitSugarAjaxDone: Result: #{str_res}, Total Time: #{t1}\n"
|
858
|
+
reportobj.log(msg)
|
859
|
+
|
860
|
+
if (done)
|
861
|
+
result = 0
|
862
|
+
else
|
863
|
+
result = -1
|
864
|
+
end
|
865
|
+
|
866
|
+
return result
|
867
|
+
end
|
868
|
+
|
869
|
+
|
870
|
+
###############################################################################
|
871
|
+
###############################################################################
|
872
|
+
def SodaUtils.getSodaJS()
|
873
|
+
return <<JSCode
|
874
|
+
(function() {
|
875
|
+
var Dom = YAHOO.util.Dom, DDM = YAHOO.util.DDM;
|
876
|
+
|
877
|
+
SUGAR.soda = {
|
878
|
+
fakeDrag : function(fromEl, toEl)
|
879
|
+
{
|
880
|
+
if(typeof fromEl == "string") {
|
881
|
+
fromEl = Dom.get(fromEl);
|
882
|
+
}
|
883
|
+
|
884
|
+
if(typeof toEl == "string") {
|
885
|
+
toEl = Dom.get(toEl);
|
886
|
+
}
|
887
|
+
|
888
|
+
var dd = DDM.getDDById(fromEl.id);
|
889
|
+
|
890
|
+
var startXY = Dom.getXY(fromEl);
|
891
|
+
var endXY = Dom.getXY(toEl);
|
892
|
+
|
893
|
+
var startEvent = {
|
894
|
+
target : fromEl,
|
895
|
+
pageX : startXY[0],
|
896
|
+
pageY : startXY[1],
|
897
|
+
clientX : startXY[0],
|
898
|
+
clientY : startXY[1],
|
899
|
+
button : 0
|
900
|
+
};
|
901
|
+
|
902
|
+
var enterEvent = {
|
903
|
+
target : fromEl,
|
904
|
+
pageX : endXY[0],
|
905
|
+
pageY : endXY[1],
|
906
|
+
clientX : endXY[0],
|
907
|
+
clientY : endXY[1],
|
908
|
+
button : 0
|
909
|
+
};
|
910
|
+
|
911
|
+
var endEvent = {
|
912
|
+
target : fromEl,
|
913
|
+
pageX : endXY[0] + 1,
|
914
|
+
pageY : endXY[1] + 1,
|
915
|
+
clientX : endXY[0] + 1,
|
916
|
+
clientY : endXY[1] + 1,
|
917
|
+
button : 0
|
918
|
+
};
|
919
|
+
|
920
|
+
DDM.handleMouseDown(startEvent, dd);
|
921
|
+
DDM.handleMouseMove(enterEvent);
|
922
|
+
DDM.handleMouseMove(endEvent);
|
923
|
+
DDM.handleMouseUp(endEvent);
|
924
|
+
}
|
925
|
+
};
|
926
|
+
})();
|
927
|
+
JSCode
|
928
|
+
end
|
929
|
+
|
930
|
+
end
|
931
|
+
|