oats 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/Gemfile +15 -0
- data/README.txt +165 -0
- data/Rakefile +2 -0
- data/bin/agent +204 -0
- data/bin/oats +10 -0
- data/bin/occ +29 -0
- data/bin/results_cleanup +6 -0
- data/doc/COPYING +55 -0
- data/doc/LICENSE +55 -0
- data/doc/OATS_Framework.doc +0 -0
- data/doc/classes/ApplicationLogs.html +239 -0
- data/doc/classes/Campaign.html +843 -0
- data/doc/classes/CommandlineOptions.html +131 -0
- data/doc/classes/Driver.html +182 -0
- data/doc/classes/Hash.html +137 -0
- data/doc/classes/Ide.html +194 -0
- data/doc/classes/MapSelenium.html +197 -0
- data/doc/classes/Net.html +107 -0
- data/doc/classes/Oats/OatsFilterError.html +119 -0
- data/doc/classes/Oats.html +998 -0
- data/doc/classes/OatsAssertError.html +119 -0
- data/doc/classes/OatsBadInput.html +119 -0
- data/doc/classes/OatsData.html +290 -0
- data/doc/classes/OatsError.html +117 -0
- data/doc/classes/OatsExit.html +117 -0
- data/doc/classes/OatsLock.html +254 -0
- data/doc/classes/OatsMain.html +182 -0
- data/doc/classes/OatsMysqlError.html +113 -0
- data/doc/classes/OatsMysqlMissingInput.html +113 -0
- data/doc/classes/OatsReportError.html +113 -0
- data/doc/classes/OatsSetupError.html +119 -0
- data/doc/classes/OatsTestError.html +119 -0
- data/doc/classes/OatsTestExit.html +119 -0
- data/doc/classes/OatsTestLocateError.html +120 -0
- data/doc/classes/OatsVerifyError.html +119 -0
- data/doc/classes/Ragent.html +397 -0
- data/doc/classes/Rclient.html +236 -0
- data/doc/classes/Report.html +368 -0
- data/doc/classes/Reports.html +244 -0
- data/doc/classes/RestApi.html +333 -0
- data/doc/classes/RhttpClient.html +236 -0
- data/doc/classes/Rimap.html +170 -0
- data/doc/classes/Rmysql.html +176 -0
- data/doc/classes/Roptions.html +131 -0
- data/doc/classes/Rselenium.html +233 -0
- data/doc/classes/Rssh.html +138 -0
- data/doc/classes/Runnable.html +174 -0
- data/doc/classes/SFTriggers.html +206 -0
- data/doc/classes/Selenium/Client/Driver.html +211 -0
- data/doc/classes/Selenium/Client.html +107 -0
- data/doc/classes/Selenium.html +107 -0
- data/doc/classes/SystemCapture.html +304 -0
- data/doc/classes/TestCase.html +418 -0
- data/doc/classes/TestData.html +235 -0
- data/doc/classes/TestList.html +264 -0
- data/doc/classes/Tools.html +244 -0
- data/doc/classes/Util.html +201 -0
- data/doc/classes/Variation.html +206 -0
- data/doc/fr_class_index.html +92 -0
- data/doc/fr_method_index.html +465 -0
- data/doc/index.html +23 -0
- data/doc/oats_httpd.conf +32 -0
- data/doc/oats_user.yml +25 -0
- data/doc/rdoc-style.css +208 -0
- data/lib/deep_merge/.gitignore +2 -0
- data/lib/deep_merge/core.rb +195 -0
- data/lib/deep_merge/deep_merge.rb +1 -0
- data/lib/deep_merge/deep_merge_hash.rb +28 -0
- data/lib/deep_merge/rails_compat.rb +27 -0
- data/lib/oats/application_logs.rb +163 -0
- data/lib/oats/build_id.rb +58 -0
- data/lib/oats/commandline_options.rb +128 -0
- data/lib/oats/diff.rb +278 -0
- data/lib/oats/driver.rb +492 -0
- data/lib/oats/ide.rb +227 -0
- data/lib/oats/keywords.rb +67 -0
- data/lib/oats/log4r_init.rb +14 -0
- data/lib/oats/mysql.rb +97 -0
- data/lib/oats/oats.rb +637 -0
- data/lib/oats/oats_data.rb +400 -0
- data/lib/oats/oats_exceptions.rb +25 -0
- data/lib/oats/oats_lock.rb +261 -0
- data/lib/oats/oats_selenium_api.rb +639 -0
- data/lib/oats/oselenium.rb +189 -0
- data/lib/oats/ossh.rb +36 -0
- data/lib/oats/patches_for_eventmachine_12.10.rb +66 -0
- data/lib/oats/ragent.rb +321 -0
- data/lib/oats/rclient.rb +42 -0
- data/lib/oats/report.rb +207 -0
- data/lib/oats/roptions.rb +88 -0
- data/lib/oats/test_case.rb +510 -0
- data/lib/oats/test_data.rb +98 -0
- data/lib/oats/test_list.rb +141 -0
- data/lib/oats/unixdiff.rb +75 -0
- data/lib/oats/util.rb +125 -0
- data/lib/oats/version.rb +3 -0
- data/lib/oats.rb +36 -0
- data/nbproject/configs/agent.properties +0 -0
- data/nbproject/configs/gr.properties +0 -0
- data/nbproject/project.properties +10 -0
- data/nbproject/project.xml +17 -0
- data/oats.gemspec +42 -0
- data/oats_ini.yml +258 -0
- data/oats_tests/Gemfile +18 -0
- data/oats_tests/aut_ini.yml +30 -0
- data/oats_tests/bin/oats +8 -0
- data/oats_tests/environments/qa.yml +4 -0
- data/oats_tests/environments/qa_chrome.yml +4 -0
- data/oats_tests/examples/core/coreExamples.yml +8 -0
- data/oats_tests/examples/core/expectedException.rb +39 -0
- data/oats_tests/examples/core/ok_verify.rb +2 -0
- data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile.txt +1 -0
- data/oats_tests/examples/core/ok_verify.rb_ok/out/myfile2.txt +1 -0
- data/oats_tests/examples/core/ok_verify.rb_ok/rats_test.log +2 -0
- data/oats_tests/examples/core/unexpectedException.rb +30 -0
- data/oats_tests/examples/examples.yml +13 -0
- data/oats_tests/examples/gui/guiExamples.yml +7 -0
- data/oats_tests/examples/gui/seleniumGoogle.rb +10 -0
- data/oats_tests/examples/gui/webdriverGoogle.rb +9 -0
- data/oats_tests/examples/keywords/SampleXlList-1.xls +0 -0
- data/oats_tests/examples/keywords/SampleXlList-2.xls +0 -0
- data/oats_tests/examples/keywords/SampleXlLists.xls +0 -0
- data/oats_tests/examples/keywords/keywordsDriver.rb +1 -0
- data/oats_tests/examples/keywords/keywordsExamples.yml +8 -0
- data/oats_tests/examples/keywords/keywordsTC1.yml +5 -0
- data/oats_tests/examples/keywords/keywordsTestlist.yml +16 -0
- data/oats_tests/examples/needsWork/addTestDynamically.rb +4 -0
- data/oats_tests/examples/needsWork/emailVerify.rb +34 -0
- data/oats_tests/examples/needsWork/testSql/rtest.sql +6 -0
- data/oats_tests/examples/needsWork/testSql/rtest.yml +11 -0
- data/oats_tests/examples/occTest/occTest.rb +13 -0
- data/oats_tests/examples/occTest/occTest_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_1_4.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_2_4.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_1.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_2.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_3.rb +1 -0
- data/oats_tests/examples/occTest/occTest_3_4.rb +1 -0
- data/oats_tests/examples/occTest/occTest_4.rb +1 -0
- data/oats_tests/examples/occTest/occTestlist.yml +9 -0
- data/oats_tests/examples/occTest/occTestlist_1.yml +9 -0
- data/oats_tests/examples/occTest/occTestlist_2.yml +9 -0
- data/oats_tests/examples/occTest/occTestlist_3.yml +9 -0
- data/oats_tests/examples/occTest/variation1.yml +4 -0
- data/oats_tests/examples/occTest/variation2.yml +4 -0
- data/oats_tests/examples/testFileLocationUnitTests/extn_driver.rb +4 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder/oats.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder1/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder1/t1_1.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder2/oats.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/folder2/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/no_yaml.rb +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/post_yaml.rb +1 -0
- data/oats_tests/examples/testFileLocationUnitTests/t1.rb +4 -0
- data/oats_tests/examples/testFileLocationUnitTests/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/t1_1.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir/oats.yml +3 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.rb +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/testDir2/t1.yml +2 -0
- data/oats_tests/examples/testFileLocationUnitTests/unitTestList.yml +36 -0
- data/oats_tests/examples/testFileLocationUnitTests/yml_driver.rb +2 -0
- data/oats_tests/lib/business.rb +28 -0
- data/oats_tests/lib/sample_xl_lists.rb +37 -0
- data/test/common_test_unit_setup.rb +21 -0
- data/test/test_basic.rb +16 -0
- data/test/test_selenium.rb +16 -0
- data/test/test_xl_lists.rb +16 -0
- metadata +291 -0
data/lib/oats/ide.rb
ADDED
@@ -0,0 +1,227 @@
|
|
1
|
+
# IDE Class to run an IDE based HTML suite after transforming it based on oats_data
|
2
|
+
|
3
|
+
module Oats
|
4
|
+
|
5
|
+
# Runs an IDE based HTML suite after transforming it based on current Oats data
|
6
|
+
class Ide
|
7
|
+
def initialize()
|
8
|
+
super
|
9
|
+
@suite_base_url_signin_type = nil;
|
10
|
+
@first_test_url = nil;
|
11
|
+
end
|
12
|
+
|
13
|
+
# Run input_suite_path while in a TestData.dir . Assumes Oats.data is initialized for TestData.dir
|
14
|
+
# input_suite_path:: path to the suite HTML
|
15
|
+
# hash:: list from => to values to use for regeneration of the included test cases.
|
16
|
+
def run (input_suite_path, hash = nil )
|
17
|
+
begin
|
18
|
+
run_ide(input_suite_path, hash)
|
19
|
+
ensure
|
20
|
+
TestData.current_test.collect_downloaded_output
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def run_ide (input_suite_path, hash = nil )
|
27
|
+
suite_path = get_path(input_suite_path)
|
28
|
+
name = File.basename(suite_path)
|
29
|
+
doc = open(suite_path ) { |f| Hpricot(f) }
|
30
|
+
# FileUtils.rm Dir[File.join(TestData.current_test.dir,'*.gen.*')] # Clean previously generated files
|
31
|
+
FileUtils.rm Dir['*.gen.*'] # Clean previously generated files in pwd
|
32
|
+
if doc.search("head[@profile='http://selenium-ide.openqa.org/profiles/test-case']").empty?
|
33
|
+
regen_suite = nil
|
34
|
+
doc.search('a[@href]') do |a|
|
35
|
+
if Oats.data['execution']['run_in_dir_results']
|
36
|
+
generated_test = regenerate_html(a['href'], test.result, File.dirname(suite_path), hash)
|
37
|
+
else
|
38
|
+
generated_test = regenerate_html(a['href'], test.dir, File.dirname(suite_path), hash)
|
39
|
+
end
|
40
|
+
if generated_test
|
41
|
+
regen_suite = true
|
42
|
+
a.set_attribute(:href,generated_test)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
html_suite_path = File.join(test.dir , File.basename(suite_path,'.*') + '.gen.html')
|
46
|
+
regen_suite = true if regen_suite or html_suite_path != suite_path
|
47
|
+
html_suite_path = File.join(test.result , File.basename(suite_path,'.*') + '.gen.html') if Oats.data['execution']['run_in_dir_results']
|
48
|
+
$log.info "Creating: #{html_suite_path}"
|
49
|
+
File.open( html_suite_path, 'w' ) { |out| out.print doc } if regen_suite
|
50
|
+
else # A single test HTML, not the suite
|
51
|
+
raise OatsTestError, "Input file is not an IDE suite: " + html_suite_path
|
52
|
+
end
|
53
|
+
|
54
|
+
# Execute html_suite_path
|
55
|
+
result_file = File.join(test.result, File.basename(name, '.*') + '_results.html')
|
56
|
+
if Oats.data['selenium']['ide']['generate']
|
57
|
+
$log.warn "Option execution:ide:generate is set. Test will not be executed."
|
58
|
+
$log.debug "Target result_file was: #{result_file}"
|
59
|
+
return
|
60
|
+
end
|
61
|
+
rc_jar_file = File.join(Oats.data['_']['vendor'],'selenium-server.jar')
|
62
|
+
browser = '*' + Oats.data['selenium']['browser_type'].sub(/ .*/,'')
|
63
|
+
url = nil
|
64
|
+
if @suite_base_url_signin_type
|
65
|
+
url = Oats.data[@suite_base_url_signin_type]["SignIn"]["url"]
|
66
|
+
else
|
67
|
+
if @first_test_url
|
68
|
+
url = @first_test_url
|
69
|
+
else
|
70
|
+
raise(OatsError, "None of the tests in #{suite_path} specified a base URL.")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
if url
|
74
|
+
base_url = url.match('https?://[^/]*/?')
|
75
|
+
else
|
76
|
+
base_url = nil
|
77
|
+
end
|
78
|
+
port = Oats.data['selenium']['ide']['port']
|
79
|
+
if Oats.data['env']['web']['host']
|
80
|
+
base_url = 'http://' + Oats.data['env']['web']['host']
|
81
|
+
else
|
82
|
+
base_url = base_url[0]
|
83
|
+
end
|
84
|
+
# if base_url
|
85
|
+
# base_url = base_url[0]
|
86
|
+
# else
|
87
|
+
# base_url = 'http://' + Oats.data['env']['web']['host']
|
88
|
+
# $log.warn "Can not determine the base url from [#{url}]. Assuming base url is [#{base_url}]" \
|
89
|
+
# unless @suite_base_url_signin_type and Oats.data[@suite_base_url_signin_type]["SignIn"]
|
90
|
+
# end
|
91
|
+
command = "java -jar \"#{rc_jar_file}\" -port #{port}"
|
92
|
+
command += " -timeout #{Oats.data['selenium']['ide']['suite_timeout']}" if Oats.data['selenium']['ide']['suite_timeout']
|
93
|
+
# Don't use profiles when using RC in IDE mode
|
94
|
+
command += " -firefoxprofileTemplate \"#{$oats_global['firefox_profile_dir']}\"" \
|
95
|
+
if Oats.data['selenium']['browser_type'] =~ /firefox/ and $oats_global['firefox_profile_dir']
|
96
|
+
command += " -htmlSuite #{browser} #{base_url} \"#{html_suite_path}\" \"#{result_file}\" 2>&1"
|
97
|
+
$log.info "Starting Selenium Remote Control: #{command}"
|
98
|
+
# return # DEBUG
|
99
|
+
first_rc_try = true
|
100
|
+
failure_line = nil
|
101
|
+
catch :end_rc do
|
102
|
+
2.times do
|
103
|
+
IO.popen(command) do |io|
|
104
|
+
while io.gets do
|
105
|
+
$log.info chomp
|
106
|
+
if /Selenium is already running on port/ =~ $_
|
107
|
+
if first_rc_try
|
108
|
+
io.readlines.each {|line|$log.info line.chomp }
|
109
|
+
Util.clear_port(Oats.data['selenium']['ide']['port'],$log)
|
110
|
+
$log.info "Will attempt to restart Selenium RC..."
|
111
|
+
else
|
112
|
+
# raise(OatsError, $_, caller[1..3])
|
113
|
+
raise(OatsError, $_)
|
114
|
+
throw(:end_rc)
|
115
|
+
end
|
116
|
+
first_rc_try = false
|
117
|
+
elsif /fail/i =~ $_ and /Failed to start: SocketListener/ !~ $_
|
118
|
+
failure_line = $_
|
119
|
+
throw(:end_rc)
|
120
|
+
elsif /exception/i =~ $_ # Like server.SeleniumCommandTimedOutException
|
121
|
+
failure_line = $_
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
throw(:end_rc) if first_rc_try
|
126
|
+
end
|
127
|
+
end
|
128
|
+
# pause_val = Oats.data['execution']['ide']['pause_on_exit']
|
129
|
+
seconds = 999999
|
130
|
+
pause_val = $oats['selenium']['pause_on_exit']
|
131
|
+
if not pause_val.integer? or
|
132
|
+
pause_val <= 0
|
133
|
+
seconds = nil
|
134
|
+
elsif pause_val == 1
|
135
|
+
seconds = nil unless failure_line
|
136
|
+
elsif pause_val > 0
|
137
|
+
seconds = pause_val
|
138
|
+
end
|
139
|
+
raise(OatsError, "Result file is not readable: #{result_file}") unless File.readable?(result_file)
|
140
|
+
if seconds
|
141
|
+
# Need to quote browser path for cygwin because it may have spaces.
|
142
|
+
begin
|
143
|
+
timeout(seconds) do
|
144
|
+
# $stderr.puts "Paused because selenium:pause_on_exit is set to [#{pause_val}]"
|
145
|
+
# $stderr.puts "PLEASE HIT <ENTER> TO CONTINUE!"
|
146
|
+
successful = system( '"' +Oats.data['selenium']['ide']['result_browser'] + '" file://'+result_file)
|
147
|
+
$log.error "Error trying to open results file: #{$?}" \
|
148
|
+
unless successful or $? == 256
|
149
|
+
end
|
150
|
+
rescue Timeout::Error
|
151
|
+
end
|
152
|
+
end
|
153
|
+
TestData.pause_after_error = false
|
154
|
+
$log.info "Results are at: file://#{result_file}"
|
155
|
+
raise(OatsTestError, failure_line) if failure_line
|
156
|
+
end
|
157
|
+
|
158
|
+
# Helper method to replace HTML file contents based on oats and test data mappings.
|
159
|
+
def map_file_contents(oats_data, test_data, file_contents,key_path)
|
160
|
+
return unless test_data
|
161
|
+
# $log.debug key_path
|
162
|
+
if @suite_base_url_signin_type.nil?
|
163
|
+
@suite_base_url_signin_type = 'Campaign' if key_path == 'root:Campaign:SignIn'
|
164
|
+
@suite_base_url_signin_type = 'Admin' if key_path == 'root:Admin:SignIn'
|
165
|
+
# $log.debug "Base URL is set to #{baseUrl}"
|
166
|
+
end
|
167
|
+
test_data.each do |key,val|
|
168
|
+
repVal = oats_data[key]
|
169
|
+
next if val.nil? or repVal.nil?
|
170
|
+
if val.class == Hash
|
171
|
+
map_file_contents( repVal, val, file_contents,key_path + ':' + key)
|
172
|
+
else
|
173
|
+
file_contents.gsub!(val, repVal.to_s)
|
174
|
+
test_data[key] = repVal
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# Updates HTML file contents based on current oats_data into test_dir_out
|
180
|
+
# Returns generated file name or nil if no new file is generated
|
181
|
+
def regenerate_html(file_in, dir_out, dir_in = dir_out, hash = nil)
|
182
|
+
basename = File.basename(file_in,'.*')
|
183
|
+
file_in_absolute = File.expand_path(file_in,dir_in) # get absolute path
|
184
|
+
unless File.exist?(file_in_absolute)
|
185
|
+
file_in_absolute = Dir.glob( File.join( $oats['execution']['dir_tests'],
|
186
|
+
'/**/', file_in.sub(/^(\.\.\/)*/, ''))).first
|
187
|
+
# file_in = file_in.sub!(/[^\/]*\//,'')
|
188
|
+
raise(OatsError,"Can not locate IDE test case file: [#{file_in}]") unless file_in_absolute
|
189
|
+
end
|
190
|
+
file_in_root = file_in_absolute.sub(/(.*)\..*$/,'\1')
|
191
|
+
yaml_in = file_in_root + '.yml'
|
192
|
+
file_out_root = File.join(dir_out, basename)
|
193
|
+
file_gen = file_out_root +'.gen.html'
|
194
|
+
yml_out = file_out_root +'.gen.yml'
|
195
|
+
new_base_name = basename
|
196
|
+
if File.exist?(file_gen)
|
197
|
+
new_base_name = File.basename(File.dirname(file_in)) + '_' + new_base_name
|
198
|
+
file_gen = File.join(dir_out, new_base_name ) +'.gen.html'
|
199
|
+
yml_out = File.join(dir_out, new_base_name ) +'.gen.yml'
|
200
|
+
end
|
201
|
+
if @suite_base_url_signin_type.nil? and @first_test_url.nil?
|
202
|
+
doc = open(file_in_absolute) { |f| Hpricot(f) }
|
203
|
+
link = doc.at("link[@rel='selenium.base']")
|
204
|
+
@first_test_url = link['href'] unless link.nil?
|
205
|
+
end
|
206
|
+
unless File.exist?(yaml_in)
|
207
|
+
return nil if file_in_root == file_out_root
|
208
|
+
$log.info "Copying [#{file_in_absolute}] to: #{file_gen}]"
|
209
|
+
FileUtils.cp(file_in_absolute, file_gen)
|
210
|
+
return basename + '.gen.html'
|
211
|
+
end
|
212
|
+
$log.debug "Regenerating [#{file_in_absolute}] into [#{file_gen}] based on [#{yaml_in}]"
|
213
|
+
file_contents = IO.read(file_in_absolute)
|
214
|
+
test_data = YAML.load_file(yaml_in)
|
215
|
+
map_file_contents(Oats.data, test_data, file_contents, 'root')
|
216
|
+
hash.each { |val, rep_val| file_contents.gsub!(val, rep_val) } if hash
|
217
|
+
if Oats.data['selenium']['browser_type'] =~ /iexplore/
|
218
|
+
file_contents.sub!(/(<\/IE-ONLY>.*-->)/,'<-- \1')
|
219
|
+
file_contents.sub!(/(<!--.*<IE-ONLY>)/,'\1 -->')
|
220
|
+
end
|
221
|
+
File.open( file_gen, 'w' ) { |out| out.print file_contents }
|
222
|
+
File.open( yml_out, 'w' ) { |out| YAML.dump( test_data, out ) }
|
223
|
+
basename + '.gen.html'
|
224
|
+
end
|
225
|
+
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
|
2
|
+
module Oats
|
3
|
+
|
4
|
+
# Process keyword driven testing
|
5
|
+
class Keywords
|
6
|
+
class << self
|
7
|
+
|
8
|
+
# Same as selenium.wait_and_type, but maps key via OatsX.locator, and uses
|
9
|
+
# OatsX.data[key] for value
|
10
|
+
def wait_and_type(key, *args)
|
11
|
+
selenium.wait_and_type(locator(key), oats_data[key], *args)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Same as selenium.wait_for_element, but maps key via OatsX.locator first
|
15
|
+
def wait_and_click(key)
|
16
|
+
selenium.wait_and_click(locator(key))
|
17
|
+
end
|
18
|
+
|
19
|
+
# Same as selenium.wait_for_element, maps key via OatsX.locator first
|
20
|
+
def wait_and_text(key)
|
21
|
+
selenium.wait_for_element(locator(key)).text
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returned the key or mappings if defined in the <class>::LOCATOR_MAP
|
25
|
+
def locator(key)
|
26
|
+
self::LOCATOR_MAP[key] || key
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# Return data from XL spreadsheet entries via Oats.data('xl.data')
|
31
|
+
# OatsX.oats_data(key_string) or OatsX.oats_data[key_string]
|
32
|
+
def oats_data(cell = nil, clas = self)
|
33
|
+
xl_root = $oats[clas.name]
|
34
|
+
list = xl_root['list'] || Oats.data('keywords.list')
|
35
|
+
if list
|
36
|
+
xl_root_list = xl_root[list]
|
37
|
+
else
|
38
|
+
xl_root_list = xl_root
|
39
|
+
end
|
40
|
+
# Oats.assert list, "Oats.data keywords.list is not defined."
|
41
|
+
val = cell ? xl_root_list[cell] : xl_root_list
|
42
|
+
Oats.assert( val, "No keywords are defined for #{clas}" + (list ? ".#{list}" : '') ) if cell == 'keywords'
|
43
|
+
Marshal.load(Marshal.dump(val)) # Protect Oats.data from modification
|
44
|
+
end
|
45
|
+
|
46
|
+
# Handles keyword processing.
|
47
|
+
# Used by OATS framework to run XL driven test suites.
|
48
|
+
# Users can also call this from yaml_handlers.
|
49
|
+
def process
|
50
|
+
# Class name comes from Oats.data oats_keywords_cleass, or in the case of XL files from TestCase ID
|
51
|
+
class_name = Oats.data('keywords.class') || File.basename(File.dirname(File.dirname(Oats.test.id)))
|
52
|
+
begin
|
53
|
+
keywords_class = Kernel.const_get class_name
|
54
|
+
rescue NameError
|
55
|
+
raise OatsTestError, "Can not find class: " + class_name
|
56
|
+
end
|
57
|
+
oats_data('keywords',keywords_class).each do |action|
|
58
|
+
Oats.assert keywords_class.respond_to?(action),
|
59
|
+
"There is no method defined in #{class_name} to the handle keyword 'a#{action}'."
|
60
|
+
Oats.info "Performing " + action
|
61
|
+
keywords_class.send action
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Log4r can be configured using YAML. This example uses log4r_yaml.yaml
|
2
|
+
require 'log4r'
|
3
|
+
require 'log4r/yamlconfigurator'
|
4
|
+
# we use various outputters, so require them, otherwise config chokes
|
5
|
+
require 'log4r/outputter/datefileoutputter'
|
6
|
+
require 'log4r/outputter/emailoutputter'
|
7
|
+
include Log4r
|
8
|
+
|
9
|
+
cfg = YamlConfigurator # shorthand
|
10
|
+
cfg['HOME'] = ENV['HOME'] # the only parameter in the YAML, our HOME directory
|
11
|
+
|
12
|
+
# load the YAML file with this
|
13
|
+
cfg.load_yaml_file('log4r.yaml')
|
14
|
+
|
data/lib/oats/mysql.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
#require 'mysql' # http://www.tmtm.org/en/ruby/mysql
|
2
|
+
require "tempfile"
|
3
|
+
require 'oats/oats_exceptions'
|
4
|
+
|
5
|
+
module Oats
|
6
|
+
class OatsMysqlError < OatsTestError ; end
|
7
|
+
class OatsMysqlMissingInput < OatsMysqlError ; end
|
8
|
+
class OatsMysqlNoConnect < OatsMysqlError ; end
|
9
|
+
# Oats.mysql creates an instance of this class to interact with MySQL DBs
|
10
|
+
class Mysql
|
11
|
+
|
12
|
+
# See Oats.mysql for more accurate/detailed documentation
|
13
|
+
# sql_input:: Path to a file.sql to execute
|
14
|
+
# connect:: Override for Oats.data sql:connect
|
15
|
+
# returns array of rows of results. Each row is an array of columns.
|
16
|
+
def run(sql_input, connect = nil, sql_out_name = nil)
|
17
|
+
raise OatsMysqlNoConnect, "Oats.data sql:connect is null" unless Oats.data['sql']['connect']
|
18
|
+
test = TestData.current_test
|
19
|
+
unless /\s/ =~ sql_input # If there is space in name, assume it is not a file
|
20
|
+
abs_path = File.expand_path(sql_input,test.path)
|
21
|
+
end
|
22
|
+
if File.exist?(abs_path)
|
23
|
+
mysql_input_file = OatsData.regenerate_file(abs_path)
|
24
|
+
mysql_input_file = abs_path unless mysql_input_file
|
25
|
+
name = File.basename(sql_input,'.*')
|
26
|
+
sql_input = IO.read(mysql_input_file)
|
27
|
+
sql_input = nil if sql_input.length > 200
|
28
|
+
else
|
29
|
+
tf = Tempfile.new("OatsMysqlInput")
|
30
|
+
tf.puts(sql_input)
|
31
|
+
tf.close
|
32
|
+
mysql_input_file = Util.expand_path(tf.path)
|
33
|
+
name = 'mysql_default'
|
34
|
+
end
|
35
|
+
sql_out_name = name + '.txt' unless sql_out_name
|
36
|
+
sql_out = File.join(test.result, sql_out_name) if sql_out_name
|
37
|
+
err_file = sql_out + '.err'
|
38
|
+
command = (ENV['OS'] != 'Darwin' ? 'mysql' : '/usr/local/mysql/bin/mysql') +
|
39
|
+
" #{parameters(connect)} < #{mysql_input_file} > #{sql_out} 2> #{err_file}"
|
40
|
+
# $log.debug "Executing: #{command}"
|
41
|
+
$log.info "SQL: #{sql_input}" if sql_input
|
42
|
+
FileUtils.mkdir_p(test.out)
|
43
|
+
ok = system(command)
|
44
|
+
$log.error("MySQL failed with return code: #{$?}") unless ok
|
45
|
+
FileUtils.rm_f(err_file) unless File.size?(err_file)
|
46
|
+
FileUtils.rm_f(sql_out) unless File.size?(sql_out)
|
47
|
+
if File.exist?(err_file)
|
48
|
+
errors = IO.readlines(err_file)
|
49
|
+
errors.size == 1 or errors[0...-1].each {|line| $log.error line.chomp}
|
50
|
+
raise(OatsMysqlError,errors.last.chomp) unless errors.empty?
|
51
|
+
end
|
52
|
+
rows = IO.readlines(sql_out) if File.exist?(sql_out)
|
53
|
+
return [] unless rows
|
54
|
+
rows.shift
|
55
|
+
if rows[1] =~ /\t/
|
56
|
+
return rows.collect{|t| t.chomp.split(/\t/) }
|
57
|
+
else
|
58
|
+
return rows.collect{|t| t.chomp }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
def processlist
|
64
|
+
raise OatsMysqlNoConnect, "Oats.data sql:connect is null" unless Oats.data['sql']['connect']
|
65
|
+
sql_out = 'mysql_processlist.txt'
|
66
|
+
command = "mysqladmin #{parameters('connect',true)} processlist > #{sql_out}"
|
67
|
+
success = system(command)
|
68
|
+
$log.error("MySQL failed with return code: #{$?}") unless success
|
69
|
+
FileUtils.rm_f(sql_out) unless File.size?(sql_out)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def parameters(connect,proc_list=false)
|
75
|
+
sql = Oats.data['sql']
|
76
|
+
connect ||= sql['connect']
|
77
|
+
conn = sql[connect]
|
78
|
+
user = conn['user']
|
79
|
+
err "Oats MySQL requires input for sql:user" unless user
|
80
|
+
password = conn['password']
|
81
|
+
err "Oats MySQL requires a string input for sql:password" unless password
|
82
|
+
password = " -p#{password}" unless password == ""
|
83
|
+
host = conn['host']
|
84
|
+
err "Oats MySQL requires input for sql:host" unless host
|
85
|
+
params = "-u#{user}#{password} -h#{host}"
|
86
|
+
return params if proc_list
|
87
|
+
db = conn['database']
|
88
|
+
err "Oats MySQL requires input for sql:db" unless db
|
89
|
+
"#{params} -D#{db}"
|
90
|
+
end
|
91
|
+
|
92
|
+
def err(inp)
|
93
|
+
raise(OatsMysqlMissingInput,inp)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|