zhimin-rwebspec 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,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