zhimin-rwebspec 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,49 @@
1
+ module RWebSpec
2
+ module UsingPages
3
+
4
+ # support Ruby 1.9
5
+ def self.extended(kclass)
6
+ caller_file = caller[1]
7
+ if caller_file && caller_file =~ /^(.*):\d+.*$/
8
+ file = $1
9
+ dir = File.expand_path(File.dirname(file))
10
+ kclass.const_set "TestFileDir", dir
11
+ end
12
+ end
13
+
14
+ # Example
15
+ # pages :all
16
+ # pages :login_page, :payment_page
17
+ # pages :login_page, :payment_page, :page_dir => "c:/tmp"
18
+ def pages(*args)
19
+ return if args.nil? or args.empty?
20
+
21
+ test_file_dir = class_eval{ self::TestFileDir }
22
+ default_page_dir = File.join(test_file_dir, "pages")
23
+ #puts "debug: default_page_dir :#{default_page_dir}}"
24
+ page_dir = default_page_dir
25
+
26
+ page_files = []
27
+ args.each do |x|
28
+ if x.class == Hash && x[:page_dir]
29
+ page_dir = x[:page_dir]
30
+ else
31
+ page_files << x
32
+ end
33
+ end
34
+
35
+ if page_files.size == 1 && page_files[0] == :all
36
+ Dir[File.expand_path(page_dir)+ "/*_page.rb"].each { |page_file|
37
+ load page_file
38
+ }
39
+ return
40
+ end
41
+
42
+ page_files.each do |page|
43
+ page_file = File.join(page_dir, page.to_s)
44
+ load page_file
45
+ end
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,479 @@
1
+ #***********************************************************
2
+ #* Copyright (c) 2006, Zhimin Zhan.
3
+ #* Distributed open-source, see full license in MIT-LICENSE
4
+ #***********************************************************
5
+
6
+ begin
7
+ require 'watir'
8
+ require 'watir/ie'
9
+ require 'watir/contrib/enabled_popup'
10
+ require 'watir/contrib/visible'
11
+ require 'watir/close_all'
12
+ $watir_loaded = true
13
+ rescue LoadError => e
14
+ $watir_loaded = false
15
+ end
16
+
17
+ begin
18
+ require "rubygems";
19
+ require "firewatir";
20
+ $firewatir_loaded = true
21
+ rescue LoadError => e
22
+ $firewatir_loaded = false
23
+ end
24
+
25
+ begin
26
+ require "rubygems";
27
+ require "celerity";
28
+ $celerity_loaded = true
29
+ rescue LoadError => e
30
+ $celerity_loaded = false
31
+ end
32
+
33
+ raise "You have must at least Watir or Firewatir installed" unless $watir_loaded || $firewatir_loaded || $celerity_loaded
34
+
35
+ module RWebSpec
36
+
37
+ ##
38
+ # Wrapping WATIR IE and FireWatir Firefox
39
+ #
40
+ class WebBrowser
41
+
42
+ attr_accessor :context
43
+
44
+ def initialize(base_url = nil, existing_browser = nil, options = {})
45
+ default_options = {:speed => "zippy", :visible => true,
46
+ :highlight_colour => 'yellow', :close_others => true}
47
+ options = default_options.merge options
48
+ @context = Context.new base_url if base_url
49
+
50
+ if $celerity_loaded
51
+ @browser = Celerity::Browser.new(:proxy => options[:proxy])
52
+ @browser.goto(base_url)
53
+ else
54
+ if (existing_browser) then
55
+ @browser = existing_browser
56
+ else
57
+ if (options[:firefox] && $firewatir_loaded) || ($firewatir_loaded and !$watir_loaded)
58
+ # JSSH is running, 9997
59
+ begin
60
+ require 'net/telnet'
61
+ firefox_jssh = Net::Telnet::new("Host" => "127.0.0.1", "Port" => 9997)
62
+ FireWatir::Firefox.firefox_started = true
63
+ rescue => e
64
+ # puts "debug: XXX #{e}"
65
+ sleep 1
66
+ end
67
+ @browser = FireWatir::Firefox.start(base_url)
68
+ elsif $watir_loaded
69
+ @browser = Watir::IE.new
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+ raise "rWebUnit initialiazation error, most likely Watir or Firewatir not present" if @browser.nil?
76
+ if $watir_loaded && @browser.class == Watir::IE
77
+ if $ITEST2_EMULATE_TYPING && $ITEST2_TYPING_SPEED then
78
+ @browser.set_slow_speed if $ITEST2_TYPING_SPEED == 'slow'
79
+ @browser.set_fast_speed if $ITEST2_TYPING_SPEED == 'fast'
80
+ else
81
+ @browser.speed = :zippy
82
+ end
83
+ @browser.activeObjectHighLightColor = options[:highlight_colour]
84
+ @browser.visible = options[:visible] unless $HIDE_IE
85
+
86
+ if RUBY_VERSION =~ /^1\.8/ && options[:close_others] then
87
+ puts "close other browser instances not working yet in Ruby 1.9.1 version of Watir"
88
+ @browser.close_others
89
+ end
90
+
91
+ end
92
+
93
+ end
94
+
95
+ def self.reuse(base_url, options)
96
+ if RUBY_PLATFORM.downcase.include?("mswin") && $ITEST2_BROWSER != "Firefox"
97
+ Watir::IE.each do |browser_window|
98
+ return WebBrowser.new(base_url, browser_window, options)
99
+ end
100
+ puts "no browser instance found"
101
+ WebBrowser.new(base_url, nil, options)
102
+ else
103
+ WebBrowser.new(base_url, nil, options)
104
+ end
105
+ end
106
+
107
+ # for popup windows
108
+ def self.new_from_existing(underlying_browser, web_context = nil)
109
+ return WebBrowser.new(web_context ? web_context.base_url : nil, underlying_browser, {:close_others => false})
110
+ end
111
+
112
+
113
+ ##
114
+ # Delegate to Watir
115
+ #
116
+ [:button, :cell, :checkbox, :div, :form, :frame, :h1, :h2, :h3, :h4, :h5, :h6, :hidden, :image, :li, :link, :map, :pre, :row, :radio, :select_list, :span, :table, :text_field, :paragraph, :file_field, :label].each do |method|
117
+ define_method method do |*args|
118
+ @browser.send(method, *args)
119
+ end
120
+ end
121
+ alias td cell
122
+ alias check_box checkbox # seems watir doc is wrong, checkbox not check_box
123
+ alias tr row
124
+
125
+ # FireWatir does not support area directly, treat it as text_field
126
+ def area(*args)
127
+ if is_firefox?
128
+ text_field(*args)
129
+ else
130
+ @browser.send("area", *args)
131
+ end
132
+ end
133
+
134
+ def contains_text(text)
135
+ @browser.contains_text(text);
136
+ end
137
+
138
+ def page_source
139
+ @browser.html()
140
+ #@browser.document.body
141
+ end
142
+ alias html_body page_source
143
+
144
+ def html
145
+ @browser.html
146
+ end
147
+
148
+ def text
149
+ @browser.text
150
+ end
151
+
152
+ def page_title
153
+ if is_firefox?
154
+ @browser.title
155
+ else
156
+ @browser.document.title
157
+ end
158
+ end
159
+
160
+ [:images, :links, :buttons, :select_lists, :checkboxes, :radios, :text_fields].each do |method|
161
+ define_method method do
162
+ @browser.send(method)
163
+ end
164
+ end
165
+
166
+ # current url
167
+ def url
168
+ @browser.url
169
+ end
170
+
171
+ def base_url=(new_base_url)
172
+ if @context
173
+ @conext.base_url = new_base_url
174
+ return
175
+ end
176
+ @context = Context.new base_url
177
+ end
178
+
179
+ def is_firefox?
180
+ return false unless $firewatir_loaded
181
+ begin
182
+ @browser.class == FireWatir::Firefox
183
+ rescue => e
184
+ return false
185
+ end
186
+ end
187
+
188
+ # Close the browser window. Useful for automated test suites to reduce
189
+ # test interaction.
190
+ def close_browser
191
+ if is_firefox? then
192
+ @browser.close
193
+ else
194
+ @browser.getIE.quit
195
+ end
196
+ sleep 2
197
+ end
198
+ alias close close_browser
199
+
200
+ #TODO determine browser type, check FireWatir support or not
201
+ def self.close_all_browsers
202
+ if RUBY_PLATFORM.downcase.include?("mswin")
203
+ Watir::IE.close_all
204
+ else
205
+ # raise "not supported in FireFox yet."
206
+ end
207
+ end
208
+
209
+ def full_url(relative_url)
210
+ if @context && @context.base_url
211
+ @context.base_url + relative_url
212
+ else
213
+ relative_url
214
+ end
215
+ end
216
+
217
+ def begin_at(relative_url)
218
+ @browser.goto full_url(relative_url)
219
+ end
220
+
221
+ def browser_opened?
222
+ begin
223
+ @browser != nil
224
+ rescue => e
225
+ return false
226
+ end
227
+ end
228
+
229
+ # Some browsers (i.e. IE) need to be waited on before more actions can be
230
+ # performed. Most action methods in Watir::Simple already call this before
231
+ # and after.
232
+ def wait_for_browser
233
+ if $celerity_loaded then
234
+ # puts "ignore, using celerity"
235
+ else
236
+ @browser.waitForIE unless is_firefox?
237
+ end
238
+ end
239
+
240
+
241
+ # A convenience method to wait at both ends of an operation for the browser
242
+ # to catch up.
243
+ def wait_before_and_after
244
+ wait_for_browser
245
+ yield
246
+ wait_for_browser
247
+ end
248
+
249
+
250
+ [:back, :forward, :refresh, :focus, :close_others].each do |method|
251
+ define_method(method) do
252
+ @browser.send(method)
253
+ end
254
+ end
255
+ alias refresh_page refresh
256
+ alias go_back back
257
+ alias go_forward forward
258
+
259
+ def goto_page(page)
260
+ @browser.goto full_url(page);
261
+ end
262
+
263
+ def goto_url(url)
264
+ @browser.goto url
265
+ end
266
+
267
+ # text fields
268
+ def enter_text_into_field_with_name(name, text)
269
+ if is_firefox?
270
+ wait_before_and_after { text_field(:name, name).value = text }
271
+ sleep 0.3
272
+ else
273
+ wait_before_and_after { text_field(:name, name).set(text) }
274
+ end
275
+ end
276
+ alias set_form_element enter_text_into_field_with_name
277
+ alias enter_text enter_text_into_field_with_name
278
+
279
+ #links
280
+ def click_link_with_id(link_id)
281
+ wait_before_and_after { link(:id, link_id).click }
282
+ end
283
+
284
+ def click_link_with_text(text)
285
+ wait_before_and_after { link(:text, text).click }
286
+ end
287
+
288
+ ##
289
+ # buttons
290
+
291
+ def click_button_with_id(id)
292
+ wait_before_and_after { button(:id, id).click }
293
+ end
294
+
295
+ def click_button_with_name(name)
296
+ wait_before_and_after { button(:name, name).click }
297
+ end
298
+
299
+ def click_button_with_caption(caption)
300
+ wait_before_and_after { button(:caption, caption).click }
301
+ end
302
+
303
+ def click_button_with_value(value)
304
+ wait_before_and_after { button(:value, value).click }
305
+ end
306
+
307
+ def select_option(selectName, option)
308
+ select_list(:name, selectName).select(option)
309
+ end
310
+
311
+ # submit first submit button
312
+ def submit(buttonName = nil)
313
+ if (buttonName.nil?) then
314
+ buttons.each { |button|
315
+ next if button.type != 'submit'
316
+ button.click
317
+ return
318
+ }
319
+ else
320
+ click_button_with_name(buttonName)
321
+ end
322
+ end
323
+
324
+ # checkbox
325
+ def check_checkbox(checkBoxName, values=nil)
326
+ if values
327
+ values.class == Array ? arys = values : arys = [values]
328
+ arys.each {|cbx_value|
329
+ checkbox(:name, checkBoxName, cbx_value).set
330
+ }
331
+ else
332
+ checkbox(:name, checkBoxName).set
333
+ end
334
+ end
335
+
336
+ def uncheck_checkbox(checkBoxName, values = nil)
337
+ if values
338
+ values.class == Array ? arys = values : arys = [values]
339
+ arys.each {|cbx_value|
340
+ checkbox(:name, checkBoxName, cbx_value).clear
341
+ }
342
+ else
343
+ checkbox(:name, checkBoxName).clear
344
+ end
345
+ end
346
+
347
+
348
+ # the method is protected in JWebUnit
349
+ def click_radio_option(radio_group, radio_option)
350
+ radio(:name, radio_group, radio_option).set
351
+ end
352
+
353
+ def clear_radio_option(radio_group, radio_option)
354
+ radio(:name, radio_group, radio_option).clear
355
+ end
356
+
357
+ def element_by_id(elem_id)
358
+ if is_firefox?
359
+ # elem = @browser.document.getElementById(elem_id)
360
+ elem = div(:id, elem_id) || label(:id, elem_id) || button(:id, elem_id) || span(:id, elem_id) || hidden(:id, elem_id) || link(:id, elem_id) || radio(:id, elem_id)
361
+ else
362
+ elem = @browser.document.getElementById(elem_id)
363
+ end
364
+ end
365
+
366
+ def element_value(elementId)
367
+ if is_firefox? then
368
+ elem = element_by_id(elementId)
369
+ elem ? elem.invoke('innerText') : nil
370
+ else
371
+ elem = element_by_id(elementId)
372
+ elem ? elem.invoke('innerText') : nil
373
+ end
374
+ end
375
+
376
+ def element_source(elementId)
377
+ elem = element_by_id(elementId)
378
+ assert_not_nil(elem, "HTML element: #{elementId} not exists")
379
+ elem.innerHTML
380
+ end
381
+
382
+ def select_file_for_upload(file_field, file_path)
383
+ normalized_file_path = RUBY_PLATFORM.downcase.include?("mswin") ? file_path.gsub("/", "\\") : file_path
384
+ file_field(:name, file_field).set(normalized_file_path)
385
+ end
386
+
387
+ def start_window(url = nil)
388
+ @browser.start_window(url);
389
+ end
390
+
391
+ # Attach to existing browser
392
+ #
393
+ # Usage:
394
+ # WebBrowser.attach_browser(:title, "iTest2")
395
+ # WebBrowser.attach_browser(:url, "http://www.itest2.com")
396
+ # WebBrowser.attach_browser(:url, "http://www.itest2.com", {:browser => "Firefox", :base_url => "http://www.itest2.com"})
397
+ # WebBrowser.attach_browser(:title, /agileway\.com\.au\/attachment/) # regular expression
398
+ def self.attach_browser(how, what, options={})
399
+ default_options = {:browser => "IE"}
400
+ options = default_options.merge(options)
401
+ site_context = Context.new(options[:base_url]) if options[:base_url]
402
+ if (options[:browser] == "Firefox")
403
+ return WebBrowser.new_from_existing(FireWatir::Firefox.new.attach(how, what), site_context)
404
+ else
405
+ return WebBrowser.new_from_existing(Watir::IE.attach(how, what), site_context)
406
+ end
407
+ end
408
+
409
+ # Attach a Watir::IE instance to a popup window.
410
+ #
411
+ # Typical usage
412
+ # new_popup_window(:url => "http://www.google.com/a.pdf")
413
+ def new_popup_window(options, browser = "ie")
414
+ if is_firefox?
415
+ raise "not implemented"
416
+ else
417
+ if options[:url]
418
+ Watir::IE.attach(:url, options[:url])
419
+ elsif options[:title]
420
+ Watir::IE.attach(:title, options[:title])
421
+ else
422
+ raise 'Please specify title or url of new pop up window'
423
+ end
424
+ end
425
+ end
426
+
427
+ # ---
428
+ # For deubgging
429
+ # ---
430
+ def dump_response(stream = nil)
431
+ stream.nil? ? puts(page_source) : stream.puts(page_source)
432
+ end
433
+
434
+ # A Better Popup Handler using the latest Watir version. Posted by Mark_cain@rl.gov
435
+ #
436
+ # http://wiki.openqa.org/display/WTR/FAQ#FAQ-HowdoIattachtoapopupwindow%3F
437
+ #
438
+ def start_clicker( button, waitTime= 9, user_input=nil)
439
+ # get a handle if one exists
440
+ hwnd = @browser.enabled_popup(waitTime)
441
+ if (hwnd) # yes there is a popup
442
+ w = WinClicker.new
443
+ if ( user_input )
444
+ w.setTextValueForFileNameField( hwnd, "#{user_input}" )
445
+ end
446
+ # I put this in to see the text being input it is not necessary to work
447
+ sleep 3
448
+ # "OK" or whatever the name on the button is
449
+ w.clickWindowsButton_hwnd( hwnd, "#{button}" )
450
+ #
451
+ # this is just cleanup
452
+ w = nil
453
+ end
454
+ end
455
+
456
+ # return underlying browser
457
+ def ie
458
+ raise "can't call this as it is configured to use Firefox" if is_firefox?
459
+ @browser
460
+ end
461
+
462
+ def firefox
463
+ raise "can't call this as it is configured to use IE" unless is_firefox?
464
+ @browser
465
+ end
466
+
467
+ def save_page(file_name = nil)
468
+ file_name ||= Time.now.strftime("%Y%m%d%H%M%S") + ".html"
469
+ puts "about to save page: #{File.expand_path(file_name)}"
470
+ File.open(file_name, "w").puts page_source
471
+ end
472
+
473
+
474
+ def self.is_windows?
475
+ RUBY_PLATFORM.downcase.include?("mswin") or RUBY_PLATFORM.downcase.include?("mingw")
476
+ end
477
+
478
+ end
479
+ end