watir 1.4.1

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.
Files changed (98) hide show
  1. data/readme.rb +211 -0
  2. data/unittests/WindowLogonExample.rb +30 -0
  3. data/unittests/WindowLogonExtra.rb +7 -0
  4. data/unittests/all_tests.rb +10 -0
  5. data/unittests/all_tests_concurrent.rb +57 -0
  6. data/unittests/attachToExistingWindow_test.rb +40 -0
  7. data/unittests/buttons_test.rb +131 -0
  8. data/unittests/checkbox_test.rb +149 -0
  9. data/unittests/core_tests.rb +9 -0
  10. data/unittests/css_test.rb +60 -0
  11. data/unittests/div_test.rb +179 -0
  12. data/unittests/errorchecker_test.rb +29 -0
  13. data/unittests/filefield_test.rb +35 -0
  14. data/unittests/form_test.rb +279 -0
  15. data/unittests/frame_test.rb +141 -0
  16. data/unittests/html/blankpage.html +12 -0
  17. data/unittests/html/buttons1.html +40 -0
  18. data/unittests/html/checkboxes1.html +69 -0
  19. data/unittests/html/complex_table.html +36 -0
  20. data/unittests/html/cssTest.html +42 -0
  21. data/unittests/html/div.html +105 -0
  22. data/unittests/html/fileupload.html +45 -0
  23. data/unittests/html/formTest1.html +39 -0
  24. data/unittests/html/forms2.html +45 -0
  25. data/unittests/html/forms3.html +132 -0
  26. data/unittests/html/forms4.html +27 -0
  27. data/unittests/html/frame_buttons.html +4 -0
  28. data/unittests/html/frame_links.html +4 -0
  29. data/unittests/html/frame_multi.html +5 -0
  30. data/unittests/html/iframeTest.html +13 -0
  31. data/unittests/html/iframeTest1.html +7 -0
  32. data/unittests/html/iframeTest2.html +6 -0
  33. data/unittests/html/images/1.gif +0 -0
  34. data/unittests/html/images/2.GIF +0 -0
  35. data/unittests/html/images/3.GIF +0 -0
  36. data/unittests/html/images/button.jpg +0 -0
  37. data/unittests/html/images/circle.jpg +0 -0
  38. data/unittests/html/images/minus.GIF +0 -0
  39. data/unittests/html/images/originaltriangle.jpg +0 -0
  40. data/unittests/html/images/plus.gif +0 -0
  41. data/unittests/html/images/square.jpg +0 -0
  42. data/unittests/html/images/triangle.jpg +0 -0
  43. data/unittests/html/images1.html +52 -0
  44. data/unittests/html/javascriptevents.html +39 -0
  45. data/unittests/html/link_pass.html +11 -0
  46. data/unittests/html/links1.html +37 -0
  47. data/unittests/html/links2.html +11 -0
  48. data/unittests/html/nestedFrames.html +6 -0
  49. data/unittests/html/pass.html +10 -0
  50. data/unittests/html/popups1.html +60 -0
  51. data/unittests/html/radioButtons1.html +71 -0
  52. data/unittests/html/select_tealeaf.html +54 -0
  53. data/unittests/html/selectboxes1.html +55 -0
  54. data/unittests/html/simple_table.html +26 -0
  55. data/unittests/html/simple_table_buttons.html +104 -0
  56. data/unittests/html/simple_table_columns.html +76 -0
  57. data/unittests/html/table1.html +142 -0
  58. data/unittests/html/textarea.html +30 -0
  59. data/unittests/html/textfields1.html +87 -0
  60. data/unittests/html/textsearch.html +44 -0
  61. data/unittests/ie_mock.rb +93 -0
  62. data/unittests/ie_test.rb +50 -0
  63. data/unittests/images_test.rb +179 -0
  64. data/unittests/iostring.rb +30 -0
  65. data/unittests/iostring_test.rb +48 -0
  66. data/unittests/js_events_test.rb +77 -0
  67. data/unittests/jscriptExtraAlert.rb +6 -0
  68. data/unittests/jscriptExtraConfirmCancel.rb +7 -0
  69. data/unittests/jscriptExtraConfirmOk.rb +7 -0
  70. data/unittests/jscriptPushButton.rb +5 -0
  71. data/unittests/jscript_test.rb +57 -0
  72. data/unittests/links_test.rb +169 -0
  73. data/unittests/minmax_test.rb +31 -0
  74. data/unittests/navigate_test.rb +56 -0
  75. data/unittests/non_core_tests.rb +9 -0
  76. data/unittests/pagecontainstext_test.rb +49 -0
  77. data/unittests/popups_test.rb +44 -0
  78. data/unittests/radios_test.rb +164 -0
  79. data/unittests/screen_capture_test.rb +53 -0
  80. data/unittests/selectbox_test.rb +197 -0
  81. data/unittests/send_keys_test.rb +29 -0
  82. data/unittests/setup.rb +47 -0
  83. data/unittests/table_test.rb +306 -0
  84. data/unittests/textAreafields_test.rb +81 -0
  85. data/unittests/textfields_test.rb +239 -0
  86. data/watir.rb +3744 -0
  87. data/watir/AutoItX3.dll +0 -0
  88. data/watir/WindowHelper.rb +47 -0
  89. data/watir/camel_case.rb +37 -0
  90. data/watir/clickJSDialog.rb +19 -0
  91. data/watir/cookiemanager.rb +53 -0
  92. data/watir/exceptions.rb +60 -0
  93. data/watir/screen_capture.rb +115 -0
  94. data/watir/setFileDialog.rb +16 -0
  95. data/watir/testUnitAddons.rb +47 -0
  96. data/watir/watir_simple.rb +475 -0
  97. data/watir/winClicker.rb +505 -0
  98. metadata +152 -0
Binary file
@@ -0,0 +1,47 @@
1
+ require 'win32ole'
2
+
3
+ class WindowHelper
4
+ def initialize( )
5
+ @autoit = WIN32OLE.new('AutoItX3.Control')
6
+ end
7
+
8
+ def push_alert_button()
9
+ @autoit.WinWait "Microsoft Internet Explorer", ""
10
+ @autoit.Send "{ENTER}"
11
+ end
12
+
13
+ def push_confirm_button_ok()
14
+ @autoit.WinWait "Microsoft Internet Explorer", ""
15
+ @autoit.Send "{ENTER}"
16
+ end
17
+
18
+ def push_confirm_button_cancel()
19
+ @autoit.WinWait "Microsoft Internet Explorer", ""
20
+ @autoit.Send "{ESCAPE}"
21
+ end
22
+
23
+ def push_security_alert_yes()
24
+ @autoit.WinWait "Security Alert", ""
25
+ @autoit.Send "{TAB}"
26
+ @autoit.Send "{TAB}"
27
+ @autoit.Send "{SPACE}"
28
+ end
29
+
30
+ def logon(title,name = 'john doe',password = 'john doe')
31
+ @autoit.WinWait title, ""
32
+ @autoit.Send name
33
+ @autoit.Send "{TAB}"
34
+ @autoit.Send password
35
+ @autoit.Send "{ENTER}"
36
+ end
37
+
38
+ def WindowHelper.check_autoit_installed
39
+ begin
40
+ WIN32OLE.new('AutoItX3.Control')
41
+ rescue
42
+ raise Watir::Exception::WatirException, "The AutoIt dll must be correctly registered for this feature to work properly"
43
+ end
44
+ end
45
+ end
46
+
47
+
@@ -0,0 +1,37 @@
1
+ # These are provided for backwards compatability with Watir 1.1
2
+
3
+ module Watir
4
+ module SupportsSubElements
5
+ alias waitForIE wait
6
+ alias fileField file_field
7
+ alias textField text_field
8
+ alias selectBox select_list
9
+ alias checkBox checkbox
10
+ end
11
+ class IE
12
+ alias getStatus status
13
+ alias getDocument document
14
+ alias pageContainsText contains_text
15
+ alias waitForIE wait
16
+ alias getHTML html
17
+ alias getText text
18
+ alias showFrames show_frames
19
+ alias showForms show_forms
20
+ alias showImages show_images
21
+ alias showLinks show_links
22
+ alias showActive show_active
23
+ alias showAllObjects show_all_objects
24
+ end
25
+ class Frame
26
+ alias getDocument document
27
+ alias waitForIE wait
28
+ end
29
+ class Form
30
+ alias waitForIE wait
31
+ end
32
+
33
+ class SpanDivCommon
34
+ alias innerText text
35
+ end
36
+
37
+ end
@@ -0,0 +1,19 @@
1
+ #
2
+ # clickJSDialog.rb
3
+ #
4
+ #
5
+ # This file contains the JS clicker when it runs as a separate process
6
+
7
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..'))
8
+ puts $LOAD_PATH
9
+ require 'watir/winClicker'
10
+
11
+ button = "OK"
12
+ button = ARGV[0] unless ARGV[0] == nil
13
+ sleepTime = 0
14
+ sleepTime = ARGV[1] unless ARGV[1] == nil
15
+
16
+
17
+ clicker= WinClicker.new
18
+ result = clicker.clickJavaScriptDialog( button )
19
+ clicker = nil
@@ -0,0 +1,53 @@
1
+
2
+ class Dir
3
+ def Dir.visit(dir = '.', files_first = false, &block)
4
+ if files_first
5
+ paths = []
6
+ Find.find(dir) { |path| paths << path }
7
+ paths.reverse_each {|path| yield path}
8
+ else
9
+ Find.find(dir, &block)
10
+ end
11
+ end
12
+ # simulates unix rm -rf command
13
+ def Dir.rm_rf(dir)
14
+ Dir.visit(dir, true) do |path|
15
+ if FileTest.directory?(path)
16
+ begin
17
+ Dir.unlink(path)
18
+ rescue # Security Exception for Content.IE
19
+ end
20
+ else
21
+ begin
22
+ File.unlink(path)
23
+ rescue #Security exception index.dat etc.
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ module Watir
31
+ module CookieManager
32
+
33
+ class WatirHelper
34
+ #taken from shlObj.h used in win32 SHGetSpecialFolderLocation
35
+ #define CSIDL_INTERNET_CACHE 0x0020
36
+ #define CSIDL_COOKIES 0x0021
37
+ #define CSIDL_HISTORY 0x0022
38
+ COOKIES = 0x0021
39
+ INTERNET_CACHE = 0x0020
40
+
41
+ def WatirHelper.getSpecialFolderLocation(specFolderName)
42
+ shell = WIN32OLE.new("Shell.Application")
43
+ folder = shell.Namespace(specFolderName)
44
+ folderItem = folder.Self
45
+ folderPath = folderItem.Path
46
+ end
47
+ def WatirHelper.deleteSpecialFolderContents(specFolderName)
48
+ Dir.rm_rf(self.getSpecialFolderLocation(specFolderName))
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,60 @@
1
+ module Watir
2
+ module Exception
3
+
4
+ # Root class for all Watir Exceptions
5
+ class WatirException < RuntimeError
6
+ def initialize(message="")
7
+ super(message)
8
+ end
9
+ end
10
+
11
+ # This exception is thrown if an attempt is made to access an object that doesn't exist
12
+ class UnknownObjectException < WatirException
13
+ end
14
+
15
+ # This exception is thrown if an attempt is made to access an object that is in a disabled state
16
+ class ObjectDisabledException < WatirException
17
+ end
18
+
19
+ # This exception is thrown if an attempt is made to access a frame that cannot be found
20
+ class UnknownFrameException< WatirException
21
+ end
22
+
23
+ # This exception is thrown if an attempt is made to access a form that cannot be found
24
+ class UnknownFormException< WatirException
25
+ end
26
+
27
+ # This exception is thrown if an attempt is made to access an object that is in a read only state
28
+ class ObjectReadOnlyException < WatirException
29
+ end
30
+
31
+ # This exception is thrown if an attempt is made to access an object when the specified value cannot be found
32
+ class NoValueFoundException < WatirException
33
+ end
34
+
35
+ # This exception gets raised if part of finding an object is missing
36
+ class MissingWayOfFindingObjectException < WatirException
37
+ end
38
+
39
+ # This exception is raised if an attempt is made to access a table that doesn't exist
40
+ class UnknownTableException < WatirException
41
+ end
42
+
43
+ # this exception is raised if an attempt is made to access a table cell that doesnt exist
44
+ class UnknownCellException < WatirException
45
+ end
46
+
47
+ # This exception is thrown if the window cannot be found
48
+ class NoMatchingWindowFoundException < WatirException
49
+ end
50
+
51
+ # This exception is thrown if an attemp is made to acces the status bar of the browser when it doesnt exist
52
+ class NoStatusBarException < WatirException
53
+ end
54
+
55
+ # This exception is thrown if an http error, such as a 404, 500 etc is encountered while navigating
56
+ class NavigationException < WatirException
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,115 @@
1
+
2
+ require 'Win32API'
3
+
4
+ module Watir
5
+ module ScreenCapture
6
+
7
+ KEYEVENTF_KEYUP = 0x2
8
+ SW_HIDE = 0
9
+ SW_SHOW = 5
10
+ SW_SHOWNORMAL = 1
11
+ VK_CONTROL = 0x11
12
+ VK_F4 = 0x73
13
+ VK_MENU = 0x12
14
+ VK_RETURN = 0x0D
15
+ VK_SHIFT = 0x10
16
+ VK_SNAPSHOT = 0x2C
17
+ VK_TAB = 0x09
18
+ GMEM_MOVEABLE = 0x0002
19
+ CF_TEXT = 1
20
+
21
+ # this method saves the current window or whole screen as either a bitmap or a jpeg
22
+ # It uses paint to save the file, so will barf if a duplicate filename is selected, or the path doesnt exist etc
23
+ # * filename - string - the name of the file to save. If its not fully qualified the current directory is used
24
+ # * active_window - boolean - if true, the whole screen is captured, if false, just the active window is captured
25
+ # * save_as_bmp - boolean - if true saves the file as a bitmap, saves it as a jpeg otherwise
26
+ def screen_capture(filename , active_window_only=false, save_as_bmp=false)
27
+
28
+
29
+ keybd_event = Win32API.new("user32", "keybd_event", ['I','I','L','L'], 'V')
30
+ vkKeyScan = Win32API.new("user32", "VkKeyScan", ['I'], 'I')
31
+ winExec = Win32API.new("kernel32", "WinExec", ['P','L'], 'L')
32
+ openClipboard = Win32API.new('user32', 'OpenClipboard', ['L'], 'I')
33
+ setClipboardData = Win32API.new('user32', 'SetClipboardData', ['I', 'I'], 'I')
34
+ closeClipboard = Win32API.new('user32', 'CloseClipboard', [], 'I')
35
+ globalAlloc = Win32API.new('kernel32', 'GlobalAlloc', ['I', 'I'], 'I')
36
+ globalLock = Win32API.new('kernel32', 'GlobalLock', ['I'], 'I')
37
+ globalUnlock = Win32API.new('kernel32', 'GlobalUnlock', ['I'], 'I')
38
+ memcpy = Win32API.new('msvcrt', 'memcpy', ['I', 'P', 'I'], 'I')
39
+
40
+
41
+ filename = Dir.getwd.tr('/','\\') + '\\' + filename unless filename.index('\\')
42
+
43
+ if active_window_only ==false
44
+ keybd_event.Call(VK_SNAPSHOT,0,0,0) # Print Screen
45
+ else
46
+ keybd_event.Call(VK_SNAPSHOT,1,0,0) # Alt+Print Screen
47
+ end
48
+
49
+ winExec.Call('mspaint.exe', SW_SHOW)
50
+ sleep(1)
51
+
52
+ # Ctrl + V : Paste
53
+ keybd_event.Call(VK_CONTROL, 1, 0, 0)
54
+ keybd_event.Call(vkKeyScan.Call(?V), 1, 0, 0)
55
+ keybd_event.Call(vkKeyScan.Call(?V), 1, KEYEVENTF_KEYUP, 0)
56
+ keybd_event.Call(VK_CONTROL, 1, KEYEVENTF_KEYUP, 0)
57
+
58
+
59
+ # Alt F + A : Save As
60
+ keybd_event.Call(VK_MENU, 1, 0, 0)
61
+ keybd_event.Call(vkKeyScan.Call(?F), 1, 0, 0)
62
+ keybd_event.Call(vkKeyScan.Call(?F), 1, KEYEVENTF_KEYUP, 0)
63
+ keybd_event.Call(VK_MENU, 1, KEYEVENTF_KEYUP, 0)
64
+ keybd_event.Call(vkKeyScan.Call(?A), 1, 0, 0)
65
+ keybd_event.Call(vkKeyScan.Call(?A), 1, KEYEVENTF_KEYUP, 0)
66
+ sleep(1)
67
+
68
+ # copy filename to clipboard
69
+ hmem = globalAlloc.Call(GMEM_MOVEABLE, filename.length+1)
70
+ mem = globalLock.Call(hmem)
71
+ memcpy.Call(mem, filename, filename.length+1)
72
+ globalUnlock.Call(hmem)
73
+ openClipboard.Call(0)
74
+ setClipboardData.Call(CF_TEXT, hmem)
75
+ closeClipboard.Call
76
+ sleep(1)
77
+
78
+ # Ctrl + V : Paste
79
+ keybd_event.Call(VK_CONTROL, 1, 0, 0)
80
+ keybd_event.Call(vkKeyScan.Call(?V), 1, 0, 0)
81
+ keybd_event.Call(vkKeyScan.Call(?V), 1, KEYEVENTF_KEYUP, 0)
82
+ keybd_event.Call(VK_CONTROL, 1, KEYEVENTF_KEYUP, 0)
83
+
84
+ if save_as_bmp == false
85
+ # goto the combo box
86
+ keybd_event.Call(VK_TAB, 1, 0, 0)
87
+ keybd_event.Call(VK_TAB, 1, KEYEVENTF_KEYUP, 0)
88
+ sleep(0.5)
89
+
90
+ # select the first entry with J
91
+ keybd_event.Call(vkKeyScan.Call(?J), 1, 0, 0)
92
+ keybd_event.Call(vkKeyScan.Call(?J), 1, KEYEVENTF_KEYUP, 0)
93
+ sleep(0.5)
94
+ end
95
+
96
+ # Enter key
97
+ keybd_event.Call(VK_RETURN, 1, 0, 0)
98
+ keybd_event.Call(VK_RETURN, 1, KEYEVENTF_KEYUP, 0)
99
+ sleep(1)
100
+
101
+ # Alt + F4 : Exit
102
+ keybd_event.Call(VK_MENU, 1, 0, 0)
103
+ keybd_event.Call(VK_F4, 1, 0, 0)
104
+ keybd_event.Call(VK_F4, 1, KEYEVENTF_KEYUP, 0)
105
+ keybd_event.Call(VK_MENU, 1, KEYEVENTF_KEYUP, 0)
106
+ sleep(1)
107
+
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+
114
+ #screenCapture( "f.bmp", false , true)
115
+
@@ -0,0 +1,16 @@
1
+ #
2
+ # setFileDialog.rb
3
+ #
4
+ #
5
+ # This file contains the file dialog when it runs as a separate process
6
+
7
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..'))
8
+ puts $LOAD_PATH
9
+ require 'watir/winClicker'
10
+
11
+ filepath = "invalid path passed to setFileDialog.rb"
12
+ filepath = ARGV[0] unless ARGV[0] == nil
13
+
14
+ clicker= WinClicker.new
15
+ clicker.setFileRequesterFileName(filepath)
16
+ clicker = nil
@@ -0,0 +1,47 @@
1
+
2
+
3
+ module Test::Unit::Assertions
4
+
5
+
6
+ def assert_false(boolean, message=nil)
7
+ _wrap_assertion do
8
+ assert_block("assert should not be called with a block.") { !block_given? }
9
+ assert_block(build_message(message, "<?> is not false.", boolean)) { !boolean }
10
+ end
11
+ end
12
+
13
+
14
+ def compareArrays( expectArray, actualArray)
15
+ result = true
16
+ expectArray.each_with_index do |element,i|
17
+ #puts "Comparing #{element} #{element.class} with #{actualArray[i]} #{actualArray[i].class} "
18
+ if element != actualArray[i]
19
+ result = false
20
+ break
21
+ end
22
+ end
23
+
24
+ return result
25
+
26
+ end
27
+
28
+ def assert_arrayEquals(expectArray, actualArray, message = nil )
29
+ _wrap_assertion do
30
+ assert_block("assert should not be called with a block.") { !block_given? }
31
+ assert_equal(expectArray.length, actualArray.length, "Lengths did not match")
32
+
33
+ assert_block("contents are different." ){ compareArrays( expectArray, actualArray) }
34
+ end #_wrap
35
+ end #def
36
+
37
+
38
+ def assert_arrayContains(array, string , message =nil)
39
+
40
+ _wrap_assertion do
41
+ assert_block("assert should not be called with a block.") { !block_given? }
42
+ assert(array.kind_of?(Array) , "Must have an array")
43
+ assert(array.include?(string) , message)
44
+ end
45
+ end
46
+
47
+ end # module test
@@ -0,0 +1,475 @@
1
+ =begin
2
+ license
3
+ ---------------------------------------------------------------------------
4
+ Copyright (c) 2004-2005, Atomic Object LLC
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ 1. Redistributions of source code must retain the above copyright notice,
11
+ this list of conditions and the following disclaimer.
12
+
13
+ 2. Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the distribution.
16
+
17
+ 3. Neither the name "Atomic Object LLC" nor the names of contributors to
18
+ this software may be used to endorse or promote products derived from this
19
+ software without specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22
+ IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
25
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ --------------------------------------------------------------------------
33
+ (based on BSD Open Source License)
34
+ =end
35
+
36
+ require 'test/unit/assertions'
37
+ require 'watir'
38
+
39
+ module Watir
40
+ # = Description
41
+ # Watir::Simple is a simple wrapper around the Watir module. It provides a
42
+ # similar set of operations while simplifying them and removing as much syntax
43
+ # and test-framework context code as possible.
44
+ # The goal is to allow toolsmiths to write domain-language frameworks on top of
45
+ # Watir, using Watir::Simple as an easier, lightweight interface to the power
46
+ # of Watir.
47
+ #
48
+ # = Note
49
+ # Most action methods in Watir::Simple will automatically wait for the browser
50
+ # not to be busy before and after they perform the specified action.
51
+ #
52
+ # revision: $Revision: 1.1 $
53
+ module Simple
54
+
55
+ # Open up a browser and point it at a certain URL.
56
+ def new_browser_at(url)
57
+ @@browser = IE.new
58
+ @@browser.typingspeed = 0
59
+ @@browser.goto url
60
+ end
61
+
62
+
63
+ # Tell the browser to load a particular URL.
64
+ def navigate_to(url)
65
+ @@browser.goto url
66
+ end
67
+
68
+
69
+ # Much like click_link_with_url but navigates to link instead of clicking it,
70
+ # thereby not invoking OnClick for links.
71
+ def navigate_to_link_with_url(url)
72
+ # FIXME: this should be moved into Watir!
73
+ wait_before_and_after do
74
+ doc = @@browser.getDocument()
75
+ links = doc.links
76
+ link = nil
77
+ links.each do |n|
78
+ match = false
79
+ case url
80
+ when Regexp
81
+ match = (n.invoke("href") =~ url)
82
+ when String
83
+ match = (n.invoke("href") == url)
84
+ end
85
+ if match
86
+ link = n
87
+ break
88
+ end
89
+ end
90
+ raise "Couldn't find link with url #{url}" unless link
91
+ @@browser.goto link
92
+ end
93
+ end
94
+
95
+ # Much like click_link_with_id but navigates to link instead of clicking it,
96
+ # thereby not invoking OnClick for links.
97
+ def navigate_to_link_with_id(id)
98
+ # FIXME: this should be moved into Watir!
99
+ wait_before_and_after do
100
+ doc = @@browser.getDocument()
101
+ links = doc.links
102
+ link = nil
103
+ links.each do |n|
104
+ match = false
105
+ case id
106
+ when Regexp
107
+ match = (n.invoke("id") =~ id)
108
+ when String
109
+ match = (n.invoke("id") == id)
110
+ end
111
+ if match
112
+ link = n
113
+ break
114
+ end
115
+ end
116
+ raise "Couldn't find link with id #{id}" unless link
117
+ @@browser.goto link
118
+ end
119
+ end
120
+
121
+ # Tell the browser to click on the first link with the specified URL.
122
+ # This takes the address of the link instead of the text displayed.
123
+ # * url - can be a string to match exactly, or a regular expression.
124
+ #
125
+ # Example:
126
+ # click_link_with_url "http://google.com"
127
+ # or:
128
+ # click_link_with_url /goo*/
129
+ def click_link_with_url(url)
130
+ wait_before_and_after { @@browser.link(:url, url).click }
131
+ end
132
+
133
+
134
+ # Tell the browser to click on the first link with the specified id attribute
135
+ # (the preferred method.)
136
+ def click_link_with_id(id)
137
+ wait_before_and_after { @@browser.link(:id, id).click }
138
+ end
139
+
140
+
141
+ # Tell the browser to click on the first link with the specified name attribute
142
+ def click_link_with_name(name)
143
+ wait_before_and_after { @@browser.link(:name, name).click }
144
+ end
145
+
146
+
147
+ # Tell the browser to click on the specified link as determined by the
148
+ # sequential ordering of links on the document.
149
+ def click_link_with_index(index)
150
+ wait_before_and_after { @@browser.link(:index, index).click }
151
+ end
152
+
153
+
154
+ # Tell the browser to click on the first link with the specified text in the
155
+ # link body.
156
+ def click_link_with_text(text)
157
+ wait_before_and_after { @@browser.link(:text, text).click }
158
+ end
159
+
160
+
161
+ # Set the text of the field with a given name (the preferred method.)
162
+ # This only types characters into the field and does not submit the form.
163
+ def enter_text_into_field_with_name(name, text)
164
+ wait_before_and_after { @@browser.textField(:name, name).set(text) }
165
+ end
166
+
167
+
168
+ # Set the text of the field with a given id attribute (the preferred method.)
169
+ # This only types characters into the field and does not submit the form.
170
+ def enter_text_into_field_with_id(id, text)
171
+ wait_before_and_after { @@browser.textField(:id, id).set(text) }
172
+ end
173
+
174
+
175
+ # Set the text of the indexed field. This only types characters
176
+ # into the field and does not submit the form.
177
+ def enter_text_into_field_with_index(index, text)
178
+ wait_before_and_after { @@browser.textField(:index, index).set(text) }
179
+ end
180
+
181
+
182
+ # Select an item from a selectbox (a.k.a "combo box", or "pulldown")
183
+ # The selectbox is chose by matching its name attribute.
184
+ # The item is selected based on the text content of <OPTION> tags.
185
+ def select_from_combobox_with_name(name, text)
186
+ wait_before_and_after { @@browser.selectBox(:name, name).select(text) }
187
+ end
188
+
189
+
190
+ # Select an item from a selectbox (a.k.a "combo box", or "pulldown")
191
+ # The selectbox is chose by matching its id attribute.
192
+ # The item is selected based on the text content of <OPTION> tags.
193
+ def select_from_combobox_with_id(id, text)
194
+ wait_before_and_after { @@browser.selectBox(:id, id).select(text) }
195
+ end
196
+
197
+
198
+ # Select an item from a selectbox (a.k.a "combo box", or "pulldown")
199
+ # The selectbox is chose by matching its order of appearance in the
200
+ # document.
201
+ # The item is selected based on the text content of <OPTION> tags.
202
+ def select_from_combobox_with_index(index, text)
203
+ wait_before_and_after { @@browser.selectBox(:index, index).select(text) }
204
+ end
205
+
206
+
207
+ # Select an item (+value+) from the radio button collection with +name+.
208
+ def select_radio_button_with_name(name, value)
209
+ wait_before_and_after { @@browser.radio(:name, name, value).click }
210
+ end
211
+
212
+
213
+ # Select an item (+value+) from the +index+'th radio button collection.
214
+ def select_radio_button_with_name(index, value)
215
+ wait_before_and_after { @@browser.radio(:index, index, value).click }
216
+ end
217
+
218
+
219
+ # Select an item (+value+) from the radio button collection with a matching
220
+ # +id+ attribute.
221
+ def select_radio_button_with_id(id, value)
222
+ wait_before_and_after { @@browser.radio(:id, id, value).click }
223
+ end
224
+
225
+
226
+ # Tell the browser to click on a form button with +name+.
227
+ def click_button_with_name(name)
228
+ wait_before_and_after { @@browser.button(:name, name).click }
229
+ end
230
+
231
+
232
+ # Tell the browser to click on a form button with the specified id attribute.
233
+ def click_button_with_id(id)
234
+ wait_before_and_after { @@browser.button(:id, id).click }
235
+ end
236
+
237
+
238
+ # Tell the browser to click on a form button with the specified value attribute.
239
+ def click_button_with_value(value)
240
+ wait_before_and_after { @@browser.button(:value, value).click }
241
+ end
242
+
243
+
244
+ # Tell the browser to click on a form button with the specified caption text.
245
+ def click_button_with_caption(caption)
246
+ wait_before_and_after { @@browser.button(:caption, caption).click }
247
+ end
248
+
249
+
250
+ # Tell the browser to click on the +index+'th form button on the page.
251
+ def click_button_with_index(index)
252
+ wait_before_and_after { @@browser.button(:index, index).click }
253
+ end
254
+
255
+
256
+ # Make a Test::Unit assertion that the given +text+ does not appear in the text
257
+ # body.
258
+ #
259
+ # * mesg - An assertion-failed message.
260
+ def assert_text_not_in_body(text,mesg=nil)
261
+ if mesg.nil? then
262
+ assert(! @@browser.pageContainsText(text), "couldn't find in body: [#{text}]")
263
+ else
264
+ assert(! @@browser.pageContainsText(text), mesg)
265
+ end
266
+ end
267
+
268
+
269
+ # Make a Test::Unit assertion that the given +text+ appears in the text
270
+ # body.
271
+ #
272
+ # * text - +String+ or +RegExp+ - The text or regular expression to search for.
273
+ # * mesg - +String+ - An optional assertion-failed message.
274
+ def assert_text_in_body(text,mesg=nil)
275
+ if mesg.nil? then
276
+ assert(@@browser.pageContainsText(text), "couldn't find in body: [#{text}]")
277
+ else
278
+ assert(@@browser.pageContainsText(text), mesg)
279
+ end
280
+ end
281
+
282
+
283
+ # This method returns true|false if the text/reg exp supplied is in a the text field "name".
284
+ #
285
+ # * name - +String+ - Name of field to examine.
286
+ # * text - +String+ or +RegExp+ - The text or regular expression to search for.
287
+ # * mesg - +String+ - An optional assertion-failed message.
288
+ def assert_text_in_field(name, text, mesg=nil)
289
+ if mesg.nil? then
290
+ assert(@@browser.textField(:name, name).verify_contains(text), "couldn't find in field #{name}: [#{text}]")
291
+ else
292
+ assert(@@browser.textField(:name, name).verify_contains(text), mesg)
293
+ end
294
+ end
295
+
296
+ #
297
+ # * how - symbol - the way we look for the object. Supported values are
298
+ # - :name
299
+ # - :id
300
+ # - :index
301
+ # * what - string - What field, id or name to examine.
302
+ # * text - string/Array of Strings - The string or array of strings to search for.
303
+ # * mesg - Optional! string - Set this if you want to supply your own error message
304
+ def assert_text_in_combobox_wrapper(how, what, text, mesg=nil)
305
+ assert(@@browser.selectBox(how, what), "could not find a combobox with what: #{what} and how: #{how}")
306
+ selectedItems = @@browser.selectBox(how, what).getSelectedItems
307
+
308
+ if text.kind_of? String
309
+ if mesg.nil? then
310
+ assert(selectedItems[0] == text, "couldn't find text in combobox with #{how}: #{what} - [#{text}], had [#{selectedItems[0]}]")
311
+ else
312
+ assert(selectedItems[0] == text, mesg)
313
+ end
314
+
315
+ elsif text.kind_of? Array
316
+ if mesg.nil? then
317
+ text.each do |item|
318
+ assert(selectedItems.include?(item), "couldn't find text in combobox with #{how}: #{what} - [#{text}], had [#{selectedItems}]")
319
+ end
320
+ else
321
+ text.each do |item|
322
+ assert(selectedItems.include?(item), mesg)
323
+ end
324
+ end
325
+ end
326
+ end
327
+
328
+
329
+ # This method returns true|false if the text is selected in the combobox
330
+ # with the supplied name.
331
+ #
332
+ # * name - string - Name of field to examine.
333
+ # * text - string/Array of Strings - The string or array of strings to search for.
334
+ # * mesg - Optional! string - Set this if you want to supply your own error message
335
+ def assert_text_in_combobox_by_name(name, text, mesg=nil)
336
+ assert_text_in_combobox_wrapper(:name, name, text, mesg)
337
+ end
338
+
339
+ # FIXME: how to use?
340
+ # This method returns true|false if the text is selected in the combobox
341
+ # with the supplied index.
342
+ #
343
+ # * index - string - Index of field to examine.
344
+ # * text - string/Array of Strings - The string or array of strings to search for.
345
+ # * mesg - Optional! string - Set this if you want to supply your own error message
346
+ #def assert_text_in_combobox_by_index(index, text, mesg=nil)
347
+ # assert_text_in_combobox_wrapper(:index, name, text, mesg)
348
+ #end
349
+
350
+ # This method returns true|false if the text is selected in the combobox
351
+ # with the supplied id.
352
+ #
353
+ # * id - string - Id of field to examine.
354
+ # * text - string/Array of Strings - The string or array of strings to search for.
355
+ # * mesg - Optional! string - Set this if you want to supply your own error message
356
+ def assert_text_in_combobox_by_id(id, text, mesg=nil)
357
+ assert_text_in_combobox_wrapper(:id, name, text, mesg)
358
+ end
359
+
360
+
361
+
362
+ # Close the browser window. Useful for automated test suites to reduce
363
+ # test interaction.
364
+ def close_browser
365
+ @@browser.getIE.quit
366
+ sleep 2
367
+ end
368
+
369
+
370
+ # Tell the browser to cick the Back button.
371
+ def go_back
372
+ @@browser.back
373
+ end
374
+
375
+
376
+ # Tell the browser to cick the Forward button.
377
+ def go_forward
378
+ @@browser.forward
379
+ end
380
+
381
+
382
+ # Fill a series of text fields. This takes a hash of textfield names to
383
+ # values for those fields.
384
+ #
385
+ # Example:
386
+ #
387
+ # fill_text_fields {
388
+ # 'username' => 'joe',
389
+ # 'password' => 'blahblah',
390
+ # 'email' => 'joe@blahblah.com',
391
+ # 'favorite_num' => 42
392
+ # }
393
+ def fill_text_fields(data)
394
+ data.each do |field, value|
395
+ @@browser.textField(:name, field).set(value)
396
+ end
397
+ end
398
+
399
+
400
+ # Fill a single textfield with a value
401
+ def fill_text_field(field_name, text)
402
+ @@browser.textField(:name, field_name).set(text)
403
+ end
404
+
405
+
406
+ # Some browsers (i.e. IE) need to be waited on before more actions can be
407
+ # performed. Most action methods in Watir::Simple already call this before
408
+ # and after.
409
+ def wait_for_browser
410
+ @@browser.waitForIE
411
+ end
412
+
413
+
414
+ def combobox_default_selection(name)
415
+ # FIXME _where_ is this used?
416
+ @@browser.selectBox(:name, name).value
417
+ end
418
+
419
+
420
+ # Returns the number of times +text+ appears in the body text of the page.
421
+ def count_instances_of(text)
422
+ @@browser.getDocument.body.innerText.scan(text).size
423
+ end
424
+
425
+
426
+ # Make a Test::Unit assertion that an image exists on the page with the given
427
+ # +src+ attribute.
428
+ #
429
+ # * mesg - +String+ - An optional assertion-failed message.
430
+ def assert_image_with_src(src, mesg=nil)
431
+ if mesg.nil? then
432
+ assert( get_image_with_src(src) != nil, "image with src: [#{src}] is not present")
433
+ else
434
+ assert( get_image_with_src(src) != nil, mesg)
435
+ end
436
+ end
437
+
438
+
439
+ # Make a Test::Unit assertion that an image exists on the page with the given
440
+ # +id+ attribute. (Preferred method)
441
+ #
442
+ # * mesg - +String+ - An optional assertion-failed message.
443
+ def assert_image_with_id(id, mesg=nil)
444
+ if mesg.nil? then
445
+ assert( get_image_with_id(id) != nil, "image with id: [#{id}] is not present")
446
+ else
447
+ assert( get_image_with_id(id) != nil, mesg)
448
+ end
449
+ end
450
+
451
+
452
+ # A convenience method to wait at both ends of an operation for the browser
453
+ # to catch up.
454
+ def wait_before_and_after
455
+ wait_for_browser
456
+ yield
457
+ wait_for_browser
458
+ end
459
+
460
+
461
+ #### PRIVATE METHODS BEYOND THIS POINT
462
+ private
463
+ ####
464
+
465
+ def get_image_with_src(src)
466
+ @@browser.image(:src, src)
467
+ end
468
+
469
+
470
+ def get_image_with_id(id)
471
+ @@browser.image(:id, id)
472
+ end
473
+
474
+ end
475
+ end