rwebspec 3.1.4 → 4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,735 @@
1
+ #***********************************************************
2
+ #* Copyright (c) 2006, Zhimin Zhan.
3
+ #* Distributed open-source, see full license in MIT-LICENSE
4
+ #***********************************************************
5
+
6
+ begin
7
+ require "selenium-webdriver"
8
+ rescue LoadError => e
9
+ raise "You have must at least WebDriver installed"
10
+ end
11
+
12
+ require File.join(File.dirname(__FILE__), "element_locator.rb")
13
+
14
+ module RWebSpec
15
+
16
+ class WebBrowser
17
+
18
+ include ElementLocator
19
+
20
+ attr_accessor :context
21
+
22
+ def initialize(base_url = nil, existing_browser = nil, options = {})
23
+ default_options = {:speed => "zippy",
24
+ :visible => true,
25
+ :highlight_colour => 'yellow',
26
+ :close_others => true
27
+ }
28
+ options = default_options.merge options
29
+ @context = Context.new base_url if base_url
30
+
31
+ options[:browser] ||= "ie" if RUBY_PLATFORM =~ /mingw/
32
+ case options[:browser].to_s.downcase
33
+ when "firefox"
34
+ initialize_firefox_browser(existing_browser, base_url, options)
35
+ when "chrome"
36
+ initialize_chrome_browser(existing_browser, base_url, options)
37
+ when "ie"
38
+ initialize_ie_browser(existing_browser, options)
39
+ when "htmlunit"
40
+ initialize_htmlunit_browser(base_url, options)
41
+ end
42
+ end
43
+
44
+ def initialize_firefox_browser(existing_browser, base_url, options)
45
+ if existing_browser then
46
+ @browser = existing_browser
47
+ return
48
+ end
49
+
50
+ @browser = Selenium::WebDriver.for :firefox
51
+ @browser.navigate.to base_url
52
+ end
53
+
54
+ def initialize_chrome_browser(existing_browser, base_url, options)
55
+ if existing_browser then
56
+ @browser = existing_browser
57
+ return
58
+ end
59
+
60
+ @browser = Selenium::WebDriver.for :chrome
61
+ @browser.navigate.to base_url
62
+ end
63
+
64
+ def initialize_htmlunit_browser(base_url, options)
65
+ puts "XXXXX start HtmlUnit..."
66
+ require 'json'
67
+ caps = Selenium::WebDriver::Remote::Capabilities.htmlunit(:javascript_enabled => false)
68
+ client = Selenium::WebDriver::Remote::Http::Default.new
69
+ # client.proxy = Selenium::WebDriver::Proxy.new(:http => "web-proxy.qdot.qld.gov.au:3128")
70
+
71
+ @browser = Selenium::WebDriver.for(:remote, :http_client => client , :desired_capabilities => caps)
72
+ if options[:go]
73
+ @browser.navigate.to(base_url)
74
+ end
75
+ end
76
+
77
+ def initialize_ie_browser(existing_browser, options)
78
+ if existing_browser then
79
+ @browser = existing_browser
80
+ if $TESTWISE_EMULATE_TYPING && $TESTWISE_TYPING_SPEED then
81
+ @browser.set_slow_speed if $TESTWISE_TYPING_SPEED == 'slow'
82
+ @browser.set_fast_speed if $TESTWISE_TYPING_SPEED == 'fast'
83
+ else
84
+ @browser.speed = :zippy
85
+ end
86
+ return
87
+ end
88
+
89
+ @browser = Selenium::WebDriver.for :ie
90
+ # if $TESTWISE_EMULATE_TYPING && $TESTWISE_TYPING_SPEED then
91
+ # @browser.set_slow_speed if $TESTWISE_TYPING_SPEED == 'slow'
92
+ # @browser.set_fast_speed if $TESTWISE_TYPING_SPEED == 'fast'
93
+ # else
94
+ # @browser.speed = :zippy
95
+ # end
96
+ # @browser.activeObjectHighLightColor = options[:highlight_colour]
97
+ # @browser.visible = options[:visible] unless $HIDE_IE
98
+ # #NOTE: close_others fails
99
+ # if RUBY_VERSION =~ /^1\.8/ && options[:close_others] then
100
+ # @browser.close_others
101
+ # else
102
+ # puts "close other browser instances not working yet in Ruby 1.9.1 version of Watir"
103
+ # end
104
+ end
105
+
106
+ # TODO resuse not working yet
107
+ def self.reuse(base_url, options)
108
+ if self.is_windows? && $TESTWISE_BROWSER != "Firefox"
109
+ Watir::IE.each do |browser_window|
110
+ return WebBrowser.new(base_url, browser_window, options)
111
+ end
112
+ #puts "no browser instance found"
113
+ WebBrowser.new(base_url, nil, options)
114
+ else
115
+ WebBrowser.new(base_url, nil, options)
116
+ end
117
+ end
118
+
119
+ # for popup windows
120
+ def self.new_from_existing(underlying_browser, web_context = nil)
121
+ return WebBrowser.new(web_context ? web_context.base_url : nil, underlying_browser, {:close_others => false})
122
+ end
123
+
124
+ def find_element(* args)
125
+ @browser.send("find_element", *args)
126
+ end
127
+
128
+ def find_elements(* args)
129
+ @browser.send("find_elements", *args)
130
+ end
131
+
132
+ ##
133
+ # Delegate to WebDriver
134
+ #
135
+ [: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|
136
+ tag_name = method
137
+ define_method method do |* args|
138
+ if args.size == 2 then
139
+ find_element(args[0].to_sym, args[1])
140
+ end
141
+ end
142
+ end
143
+ alias td cell
144
+ alias check_box checkbox # seems watir doc is wrong, checkbox not check_box
145
+ alias tr row
146
+
147
+ # Wrapp of Watir's area to support Firefox and Watir
148
+ def area(* args)
149
+ if is_firefox?
150
+ text_field(* args)
151
+ else
152
+ @browser.send("area", * args)
153
+ end
154
+ end
155
+
156
+ def modal_dialog(how=nil, what=nil)
157
+ @browser.modal_dialog(how, what)
158
+ end
159
+
160
+ # This is the main method for accessing a generic element with a given attibute
161
+ # * how - symbol - how we access the element. Supports all values except :index and :xpath
162
+ # * what - string, integer or regular expression - what we are looking for,
163
+ #
164
+ # Valid values for 'how' are listed in the Watir Wiki - http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
165
+ #
166
+ # returns an Watir::Element object
167
+ #
168
+ # Typical Usage
169
+ #
170
+ # element(:class, /foo/) # access the first element with class 'foo'. We can use a string in place of the regular expression
171
+ # element(:id, "11") # access the first element that matches an id
172
+ def element(how, what)
173
+ return @browser.element(how, what)
174
+ end
175
+
176
+ # this is the main method for accessing generic html elements by an attribute
177
+ #
178
+ # Returns a HTMLElements object
179
+ #
180
+ # Typical usage:
181
+ #
182
+ # elements(:class, 'test').each { |l| puts l.to_s } # iterate through all elements of a given attribute
183
+ # elements(:alt, 'foo')[1].to_s # get the first element of a given attribute
184
+ # elements(:id, 'foo').length # show how many elements are foung in the collection
185
+ #
186
+ def elements(how, what)
187
+ return @browser.elements(how, what)
188
+ end
189
+
190
+ def show_all_objects
191
+ @browser.show_all_objects
192
+ end
193
+
194
+ # Returns the specified ole object for input elements on a web page.
195
+ #
196
+ # This method is used internally by Watir and should not be used externally. It cannot be marked as private because of the way mixins and inheritance work in watir
197
+ #
198
+ # * how - symbol - the way we look for the object. Supported values are
199
+ # - :name
200
+ # - :id
201
+ # - :index
202
+ # - :value etc
203
+ # * what - string that we are looking for, ex. the name, or id tag attribute or index of the object we are looking for.
204
+ # * types - what object types we will look at.
205
+ # * value - used for objects that have one name, but many values. ex. radio lists and checkboxes
206
+ def locate_input_element(how, what, types, value=nil)
207
+ @browser.locate_input_element(how, what, types, value)
208
+ end
209
+
210
+ # This is the main method for accessing map tags - http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/map.asp?frame=true
211
+ # * how - symbol - how we access the map,
212
+ # * what - string, integer or regular expression - what we are looking for,
213
+ #
214
+ # Valid values for 'how' are listed in the Watir Wiki - http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
215
+ #
216
+ # returns a map object
217
+ #
218
+ # Typical Usage
219
+ #
220
+ # map(:id, /list/) # access the first map that matches list.
221
+ # map(:index,2) # access the second map on the page
222
+ # map(:title, "A Picture") # access a map using the tooltip text. See http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/title_1.asp?frame=true
223
+ #
224
+ def map(how, what=nil)
225
+ @browser.map(how, what)
226
+ end
227
+
228
+ def contains_text(text)
229
+ @browser.contains_text(text);
230
+ end
231
+
232
+ # return HTML of current web page
233
+ def page_source
234
+ @browser.page_source
235
+ end
236
+ alias html_body page_source
237
+ alias html page_source
238
+
239
+ def page_title
240
+ @browser.title
241
+ end
242
+
243
+ def text(squeeze_spaces = true)
244
+ @browser.find_element(:tag_name, "body").text
245
+ end
246
+
247
+ # @deprecated
248
+ def text_with_sanitize
249
+ begin
250
+ require 'sanitize'
251
+ page_text_string = Sanitize.clean(html)
252
+ page_text_string = page_text_string.squeeze(" ") if squeeze_spaces
253
+ # remove duplicated (spaces)
254
+ return page_text_string
255
+ rescue => e
256
+ puts "failed to santize html source => text, #{e}"
257
+ return @browser.html
258
+ end
259
+ end
260
+
261
+ [:images, :links, :buttons, :select_lists, :checkboxes, :radios, :text_fields, :divs, :dls, :dds, :dts, :ems, :lis, :maps, :spans, :strongs, :ps, :pres, :labels].each do |method|
262
+ define_method method do
263
+ @browser.send(method)
264
+ end
265
+ end
266
+
267
+ # current url
268
+ def current_url
269
+ @browser.current_url
270
+ end
271
+ alias url current_url
272
+
273
+ def base_url=(new_base_url)
274
+ if @context
275
+ @conext.base_url = new_base_url
276
+ return
277
+ end
278
+ @context = Context.new base_url
279
+ end
280
+
281
+ def driver
282
+ @browser
283
+ end
284
+
285
+ def underlying_browser
286
+ @browser
287
+ end
288
+
289
+ def is_ie?
290
+ @browser.browser.to_s == "ie"
291
+ end
292
+
293
+ def is_firefox?
294
+ @browser.browser.to_s == "firefox"
295
+ end
296
+
297
+ # Close the browser window. Useful for automated test suites to reduce
298
+ # test interaction.
299
+ def close_browser
300
+ @browser.quit
301
+ sleep 1
302
+ end
303
+ alias close close_browser
304
+
305
+ #TODO determine browser type, check FireWatir support or not
306
+ def self.close_all_browsers
307
+ raise "not implemented"
308
+ end
309
+
310
+ def full_url(relative_url)
311
+ if @context && @context.base_url
312
+ @context.base_url + relative_url
313
+ else
314
+ relative_url
315
+ end
316
+ end
317
+
318
+ # Crahses where http:///ssshtttp:///
319
+ def begin_at(relative_url)
320
+ if relative_url =~ /\s*^http/
321
+ @browser.navigate.to relative_url
322
+ else
323
+ @browser.navigate.to full_url(relative_url)
324
+ end
325
+ end
326
+
327
+ def browser_opened?
328
+ begin
329
+ @browser != nil
330
+ rescue => e
331
+ return false
332
+ end
333
+ end
334
+
335
+ # Some browsers (i.e. IE) need to be waited on before more actions can be
336
+ # performed. Most action methods in Watir::Simple already call this before
337
+ # and after.
338
+ def wait_for_browser
339
+ # NOTE: no need any more
340
+ end
341
+
342
+
343
+ # A convenience method to wait at both ends of an operation for the browser
344
+ # to catch up.
345
+ def wait_before_and_after
346
+ wait_for_browser
347
+ yield
348
+ wait_for_browser
349
+ end
350
+
351
+
352
+ [:focus, :close_others].each do |method|
353
+ define_method(method) do
354
+ @browser.send(method)
355
+ end
356
+ end
357
+
358
+ def forward
359
+ @browser.navigate().forward
360
+ end
361
+ alias go_forward forward
362
+
363
+ # TODO can't browse back if on invalid page
364
+ def back
365
+ @browser.navigate.back
366
+ end
367
+ alias go_back back
368
+
369
+ def refresh
370
+ @browser.navigate().refresh
371
+ end
372
+ alias refresh_page refresh
373
+
374
+ # Go to a page
375
+ # Usage:
376
+ # open_browser("http://www.itest2.com"
377
+ # ....
378
+ # goto_page("/purchase") # full url => http://www.itest.com/purchase
379
+ def goto_page(page)
380
+ goto_url full_url(page);
381
+ end
382
+
383
+ # Go to a URL directly
384
+ # goto_url("http://www.itest2.com/downloads")
385
+ def goto_url(url)
386
+ @browser.navigate.to url
387
+ end
388
+
389
+ # text fields
390
+ def enter_text_into_field_with_name(name, text)
391
+ the_element = find_element(:name, name)
392
+ if the_element.tag_name == "input" || the_element.tag_name == "textarea" then
393
+ the_element.clear
394
+ the_element.send_keys(text)
395
+ else
396
+ elements = find_elements(:name, name)
397
+ if elements.size == 1 then
398
+ elements[0].send_keys(text)
399
+ else
400
+ element_set = elements.select {|x| x.tag_name == "textarea" || (x.tag_name == "input" && x.attribute("text")) }
401
+ element_set[0].send_keys(text)
402
+ end
403
+ end
404
+ return true
405
+ end
406
+
407
+ alias set_form_element enter_text_into_field_with_name
408
+ alias enter_text enter_text_into_field_with_name
409
+ alias set_hidden_field set_form_element
410
+
411
+ #links
412
+ def click_link_with_id(link_id, opts = {})
413
+ if opts && opts[:index]
414
+ elements = find_elements(:id, link_id)
415
+ elements[opts[:index]-1].click
416
+ else
417
+ find_element(:id, link_id).click
418
+ end
419
+ end
420
+
421
+ ##
422
+ # click_link_with_text("Login")
423
+ # click_link_with_text("Show", :index => 2)
424
+ def click_link_with_text(link_text, opts = {})
425
+ if opts && opts[:index]
426
+ elements = find_elements(:link_text, link_text)
427
+ elements[opts[:index]-1].click
428
+ else
429
+ find_element(:link_text, link_text).click
430
+ end
431
+ end
432
+ alias click_link click_link_with_text
433
+
434
+
435
+ # Click a button with give HTML id
436
+ # Usage:
437
+ # click_button_with_id("btn_sumbit")
438
+ def click_button_with_id(id, opts = {})
439
+ find_element(:id, id).click
440
+ end
441
+
442
+ # Click a button with give name
443
+ # Usage:
444
+ # click_button_with_name("confirm")
445
+ # click_button_with_name("confirm", :index => 2)
446
+ def click_button_with_name(name, opts={})
447
+ find_element(:name, name).click
448
+ end
449
+
450
+ # Click a button with caption
451
+ #
452
+ # TODO: Caption is same as value
453
+ #
454
+ # Usage:
455
+ # click_button_with_caption("Confirm payment")
456
+ def click_button_with_caption(caption, opts={})
457
+ all_buttons = button_elements
458
+ matching_buttons = all_buttons.select{|x| x.attribute('value') == caption}
459
+ if matching_buttons.size > 0
460
+
461
+ if opts && opts[:index]
462
+ puts "Call matching buttons: #{matching_buttons.inspect}"
463
+ first_match = matching_buttons[opts[:index].to_i() - 1]
464
+ first_match.click
465
+ end
466
+
467
+ the_button = matching_buttons[0]
468
+ the_button.click
469
+
470
+ else
471
+ raise "No button with value: #{caption} found"
472
+ end
473
+ end
474
+ alias click_button click_button_with_caption
475
+ alias click_button_with_text click_button_with_caption
476
+
477
+
478
+ # click_button_with_caption("Confirm payment")
479
+ def click_button_with_value(value, opts={})
480
+ all_buttons = button_elements
481
+ if opts && opts[:index]
482
+ all_buttons.select{|x| x.attribute('value') == caption}[index]
483
+ else
484
+ all_buttons.each do |button|
485
+ if button.attribute('value') == value then
486
+ button.click
487
+ return
488
+ end
489
+ end
490
+ end
491
+ end
492
+
493
+ # Click image buttion with image source name
494
+ #
495
+ # For an image submit button <input name="submit" type="image" src="/images/search_button.gif">
496
+ # click_button_with_image("search_button.gif")
497
+ def click_button_with_image_src_contains(image_filename)
498
+ all_buttons = button_elements
499
+ found = nil
500
+ all_buttons.select do |x|
501
+ if x["src"] =~ /#{Regexp.escape(image_filename)}/
502
+ found = x
503
+ break
504
+ end
505
+ end
506
+
507
+ raise "not image button with src: #{image_filename} found" if found.nil?
508
+ found.click
509
+ end
510
+
511
+ alias click_button_with_image click_button_with_image_src_contains
512
+ # Select a dropdown list by name
513
+ # Usage:
514
+ # select_option("country", "Australia")
515
+ def select_option(selectName, text)
516
+ Selenium::WebDriver::Support::Select.new(find_element(:name, selectName)).select_by(:text, text)
517
+ end
518
+
519
+ # submit first submit button
520
+ def submit(buttonName = nil)
521
+ if (buttonName.nil?) then
522
+ buttons.each { |button|
523
+ next if button.type != 'submit'
524
+ button.click
525
+ return
526
+ }
527
+ else
528
+ click_button_with_name(buttonName)
529
+ end
530
+ end
531
+
532
+ # Check a checkbox
533
+ # Usage:
534
+ # check_checkbox("agree")
535
+ # check_checkbox("agree", "true")
536
+ def check_checkbox(checkBoxName, values=nil)
537
+ if values
538
+ values.class == Array ? arys = values : arys = [values]
539
+ elements = find_elements(:name, checkBoxName)
540
+ the_checkbox = elements[0] if elements.size == 1
541
+ if the_checkbox
542
+ the_checkbox.click unless the_checkbox.selected?
543
+ return
544
+ end
545
+
546
+ arys.each { |cbx_value|
547
+ elements.each do |elem|
548
+ elem.click if elem.attribute('value') == cbx_value && !elem.selected?
549
+ end
550
+ }
551
+ else
552
+ the_checkbox = find_element(:name, checkBoxName)
553
+ the_checkbox.click unless the_checkbox.selected?
554
+ end
555
+ end
556
+
557
+ # Check a checkbox
558
+ # Usage:
559
+ # uncheck_checkbox("agree")
560
+ # uncheck_checkbox("agree", "false")
561
+ def uncheck_checkbox(checkBoxName, values = nil)
562
+ if values
563
+ values.class == Array ? arys = values : arys = [values]
564
+ elements = find_elements(:name, checkBoxName)
565
+ the_checkbox = elements[0] if elements.size == 1
566
+ if the_checkbox
567
+ the_checkbox.click if the_checkbox.selected?
568
+ return
569
+ end
570
+
571
+ arys.each { |cbx_value|
572
+ elements.each do |elem|
573
+ elem.click if elem.attribute('value') == cbx_value && the_checkbox && the_checkbox.selected?
574
+ end
575
+ }
576
+ else
577
+ the_checkbox = find_element(:name, checkBoxName)
578
+ the_checkbox.click if the_checkbox.selected?
579
+ end
580
+ end
581
+
582
+
583
+ # Click a radio button
584
+ # Usage:
585
+ # click_radio_option("country", "Australia")
586
+ def click_radio_option(radio_group, radio_option)
587
+ the_radio_button = find_element(:xpath, "//input[@type='radio' and @name='#{radio_group}' and @value='#{radio_option}']")
588
+ the_radio_button.click
589
+ end
590
+ alias click_radio_button click_radio_option
591
+
592
+ # Clear a radio button
593
+ # Usage:
594
+ # click_radio_option("country", "Australia")
595
+ def clear_radio_option(radio_group, radio_option)
596
+ the_radio_button = find_element(:xpath, "//input[@type='radio' and @name='#{radio_group}' and @value='#{radio_option}']")
597
+ the_radio_button.clear
598
+ end
599
+ alias clear_radio_button clear_radio_option
600
+
601
+ def element_by_id(elem_id)
602
+ @browser.find_element(:id, elem_id)
603
+ end
604
+
605
+ def element_value(elementId)
606
+ find_element(:id, elementId).attribute('value')
607
+ end
608
+
609
+ def element_source(elementId)
610
+ elem = element_by_id(elementId)
611
+ assert_not_nil(elem, "HTML element: #{elementId} not exists")
612
+ elem.innerHTML
613
+ end
614
+
615
+ def select_file_for_upload(file_field_name, file_path)
616
+ is_on_windows = RUBY_PLATFORM.downcase.include?("mingw") || RUBY_PLATFORM.downcase.include?("mswin")
617
+ normalized_file_path = is_on_windows ? file_path.gsub("/", "\\") : file_path
618
+ find_element(:name, file_field_name).click
619
+ find_element(:name, file_field_name).send_keys(normalized_file_path)
620
+ end
621
+
622
+ def start_window(url = nil)
623
+ @browser.start_window(url);
624
+ end
625
+
626
+ # Attach to existing browser
627
+ #
628
+ # Usage:
629
+ # WebBrowser.attach_browser(:title, "iTest2")
630
+ # WebBrowser.attach_browser(:url, "http://www.itest2.com")
631
+ # WebBrowser.attach_browser(:url, "http://www.itest2.com", {:browser => "Firefox", :base_url => "http://www.itest2.com"})
632
+ # WebBrowser.attach_browser(:title, /agileway\.com\.au\/attachment/) # regular expression
633
+ def self.attach_browser(how, what, options={})
634
+ default_options = {:browser => "IE"}
635
+ options = default_options.merge(options)
636
+ site_context = Context.new(options[:base_url]) if options[:base_url]
637
+ if (options[:browser].to_s == "firefox")
638
+ return WebBrowser.new_from_existing(ff, site_context)
639
+ else
640
+ return WebBrowser.new_from_existing(Watir::IE.attach(how, what), site_context)
641
+ end
642
+ end
643
+
644
+ # Attach a Watir::IE instance to a popup window.
645
+ #
646
+ # Typical usage
647
+ # new_popup_window(:url => "http://www.google.com/a.pdf")
648
+ def new_popup_window(options, browser = "ie")
649
+ if is_firefox?
650
+ raise "not implemented"
651
+ else
652
+ if options[:url]
653
+ Watir::IE.attach(:url, options[:url])
654
+ elsif options[:title]
655
+ Watir::IE.attach(:title, options[:title])
656
+ else
657
+ raise 'Please specify title or url of new pop up window'
658
+ end
659
+ end
660
+ end
661
+
662
+ # ---
663
+ # For deubgging
664
+ # ---
665
+ def dump_response(stream = nil)
666
+ stream.nil? ? puts(page_source) : stream.puts(page_source)
667
+ end
668
+
669
+ # A Better Popup Handler using the latest Watir version. Posted by Mark_cain@rl.gov
670
+ #
671
+ # http://wiki.openqa.org/display/WTR/FAQ#FAQ-HowdoIattachtoapopupwindow%3F
672
+ #
673
+ def start_clicker(button, waitTime= 9, user_input=nil)
674
+ # get a handle if one exists
675
+ hwnd = @browser.enabled_popup(waitTime)
676
+ if (hwnd) # yes there is a popup
677
+ w = WinClicker.new
678
+ if (user_input)
679
+ w.setTextValueForFileNameField(hwnd, "#{user_input}")
680
+ end
681
+ # I put this in to see the text being input it is not necessary to work
682
+ sleep 3
683
+ # "OK" or whatever the name on the button is
684
+ w.clickWindowsButton_hwnd(hwnd, "#{button}")
685
+ #
686
+ # this is just cleanup
687
+ w = nil
688
+ end
689
+ end
690
+
691
+ # return underlying browser
692
+ def ie
693
+ @browser.class == "internet_explorer" ? @browser : nil;
694
+ end
695
+
696
+ # return underlying firefox browser object, raise error if not running using Firefox
697
+ def firefox
698
+ is_firefox? ? @browser : nil;
699
+ end
700
+
701
+ def htmlunit
702
+ raise "can't call this as it is configured to use Celerity" unless RUBY_PLATFORM =~ /java/
703
+ @browser
704
+ end
705
+
706
+ # Save current web page source to file
707
+ # usage:
708
+ # save_page("/tmp/01.html")
709
+ # save_page() => # will save to "20090830112200.html"
710
+ def save_page(file_name = nil)
711
+ file_name ||= Time.now.strftime("%Y%m%d%H%M%S") + ".html"
712
+ puts "about to save page: #{File.expand_path(file_name)}" if $DEBUG
713
+ File.open(file_name, "w").puts page_source
714
+ end
715
+
716
+
717
+ # Verify the next page following an operation.
718
+ #
719
+ # Typical usage:
720
+ # browser.expect_page HomePage
721
+ def expect_page(page_clazz, argument = nil)
722
+ if argument
723
+ page_clazz.new(self, argument)
724
+ else
725
+ page_clazz.new(self)
726
+ end
727
+ end
728
+
729
+ # is it running in MS Windows platforms?
730
+ def self.is_windows?
731
+ RUBY_PLATFORM.downcase.include?("mswin") or RUBY_PLATFORM.downcase.include?("mingw")
732
+ end
733
+
734
+ end
735
+ end