watir 1.4.1 → 1.5.2

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 (151) hide show
  1. data/bin/watir-console +1 -0
  2. data/changes.rb +119 -0
  3. data/license.rb +37 -0
  4. data/readme.rb +55 -120
  5. data/unittests/buttons_test.rb +107 -104
  6. data/unittests/buttons_xpath_test.rb +69 -0
  7. data/unittests/checkbox_test.rb +154 -141
  8. data/unittests/checkbox_xpath_test.rb +107 -0
  9. data/unittests/core_tests.rb +6 -2
  10. data/unittests/css_test.rb +50 -50
  11. data/unittests/defer_test.rb +47 -0
  12. data/unittests/dialog_test.rb +78 -0
  13. data/unittests/div2_xpath_test.rb +22 -0
  14. data/unittests/div_test.rb +159 -159
  15. data/unittests/div_xpath_test.rb +96 -0
  16. data/unittests/errorchecker_test.rb +22 -22
  17. data/unittests/filefield_test.rb +30 -23
  18. data/unittests/filefield_xpath_test.rb +35 -0
  19. data/unittests/form_test.rb +250 -229
  20. data/unittests/form_xpath_test.rb +253 -0
  21. data/unittests/frame_test.rb +123 -108
  22. data/unittests/google_form_test.rb +17 -0
  23. data/unittests/html/JavascriptClick.html +39 -0
  24. data/unittests/html/buttons1.html +3 -2
  25. data/unittests/html/checkboxes1.html +32 -14
  26. data/unittests/html/complex_table.html +1 -1
  27. data/unittests/html/depot_store.html +59 -0
  28. data/unittests/html/div.html +3 -21
  29. data/unittests/html/div_xml.html +21 -0
  30. data/unittests/html/fileupload.html +2 -2
  31. data/unittests/html/forms2.html +3 -3
  32. data/unittests/html/forms3.html +2 -2
  33. data/unittests/html/frame_links.html +2 -2
  34. data/unittests/html/google_india.html +119 -0
  35. data/unittests/html/iframeTest.html +2 -2
  36. data/unittests/html/images/map.GIF +0 -0
  37. data/unittests/html/images/map2.gif +0 -0
  38. data/unittests/html/images1.html +17 -2
  39. data/unittests/html/javascriptevents.html +3 -7
  40. data/unittests/html/links1.html +9 -8
  41. data/unittests/html/links_multi.html +14 -0
  42. data/unittests/html/list_matters.html +720 -0
  43. data/unittests/html/lists.html +18 -0
  44. data/unittests/html/map_test.html +31 -0
  45. data/unittests/html/modal_dialog.html +10 -0
  46. data/unittests/html/modal_dialog_launcher.html +12 -0
  47. data/unittests/html/new_browser.html +17 -0
  48. data/unittests/html/pass.html +3 -0
  49. data/unittests/html/popups1.html +1 -1
  50. data/unittests/html/pre.html +28 -0
  51. data/unittests/html/radioButtons1.html +6 -5
  52. data/unittests/html/selectboxes1.html +12 -11
  53. data/unittests/html/simple_table.html +1 -1
  54. data/unittests/html/simple_table_columns.html +1 -1
  55. data/unittests/html/table1.html +1 -1
  56. data/unittests/html/tableCell_using_xpath.html +19 -0
  57. data/unittests/html/textfields1.html +6 -4
  58. data/unittests/html/xpath_nbsp.html +12 -0
  59. data/unittests/ie_exists_test.rb +32 -0
  60. data/unittests/ie_mock.rb +78 -79
  61. data/unittests/ie_test.rb +39 -39
  62. data/unittests/images_test.rb +132 -155
  63. data/unittests/images_xpath_test.rb +91 -0
  64. data/unittests/links_multi_test.rb +36 -0
  65. data/unittests/links_test.rb +158 -152
  66. data/unittests/links_xpath_test.rb +40 -0
  67. data/unittests/lists_test.rb +29 -0
  68. data/unittests/map_test.rb +99 -0
  69. data/unittests/minmax_test.rb +23 -23
  70. data/unittests/navigate_test.rb +43 -51
  71. data/unittests/nbsp_xpath_test.rb +18 -0
  72. data/unittests/other/WindowLogonExample.rb +28 -0
  73. data/unittests/{WindowLogonExtra.rb → other/WindowLogonExtra.rb} +0 -0
  74. data/unittests/{all_tests_concurrent.rb → other/all_tests_concurrent.rb} +23 -23
  75. data/unittests/other/navigate_exception_test.rb +14 -0
  76. data/unittests/other/rexml_unit_test.rb +24 -0
  77. data/unittests/other/testcase_method_order_test.rb +36 -0
  78. data/unittests/other/testcase_verify_test.rb +25 -0
  79. data/unittests/other/wait_until_test.rb +99 -0
  80. data/unittests/pagecontainstext_test.rb +56 -37
  81. data/unittests/parent_child_test.rb +55 -0
  82. data/unittests/popups_test.rb +37 -37
  83. data/unittests/pre_test.rb +52 -0
  84. data/unittests/radios_test.rb +186 -155
  85. data/unittests/radios_xpath_test.rb +101 -0
  86. data/unittests/screen_capture_test.rb +41 -41
  87. data/unittests/selectbox_test.rb +223 -181
  88. data/unittests/selectbox_xpath_test.rb +113 -0
  89. data/unittests/setup.rb +29 -25
  90. data/unittests/speed_settings_test.rb +22 -0
  91. data/unittests/table_cell_using_xpath_test.rb +40 -0
  92. data/unittests/table_test.rb +315 -284
  93. data/unittests/table_xpath_test.rb +114 -0
  94. data/unittests/textarea_test.rb +81 -0
  95. data/unittests/textarea_xpath_test.rb +82 -0
  96. data/unittests/textfields_test.rb +205 -229
  97. data/unittests/textfields_xpath_test.rb +111 -0
  98. data/unittests/window_tests.rb +7 -0
  99. data/unittests/windows/attach_to_existing_window_test.rb +52 -0
  100. data/unittests/windows/attach_to_new_window_test.rb +82 -0
  101. data/unittests/windows/close_window_test.rb +22 -0
  102. data/unittests/windows/frame_links_test.rb +25 -0
  103. data/unittests/windows/ie-each_test.rb +48 -0
  104. data/unittests/windows/iedialog_test.rb +55 -0
  105. data/unittests/windows/js_events_test.rb +57 -0
  106. data/unittests/windows/jscriptExtraAlert.rb +6 -0
  107. data/unittests/windows/jscriptExtraConfirmCancel.rb +7 -0
  108. data/unittests/windows/jscriptExtraConfirmOk.rb +7 -0
  109. data/unittests/{jscriptPushButton.rb → windows/jscriptPushButton.rb} +1 -1
  110. data/unittests/windows/jscript_test.rb +64 -0
  111. data/unittests/windows/modal_dialog_test.rb +127 -0
  112. data/unittests/windows/new.rb +56 -0
  113. data/unittests/windows/open_close_test.rb +22 -0
  114. data/unittests/windows/send_keys_test.rb +34 -0
  115. data/unittests/xpath_tests.rb +10 -0
  116. data/watir.rb +4344 -3565
  117. data/watir/IEDialog/Release/IEDialog.dll +0 -0
  118. data/watir/WindowHelper.rb +13 -11
  119. data/watir/assertions.rb +36 -0
  120. data/watir/camel_case.rb +14 -5
  121. data/watir/close_all.rb +38 -0
  122. data/watir/contrib/enabled_popup.rb +21 -0
  123. data/watir/contrib/ie-new-process.rb +27 -0
  124. data/watir/contrib/page_checker.rb +29 -0
  125. data/watir/contrib/visible.rb +47 -0
  126. data/watir/cookiemanager.rb +4 -4
  127. data/watir/datahandler.rb +107 -0
  128. data/watir/dialog.rb +46 -0
  129. data/watir/elements.rb +65 -0
  130. data/watir/exceptions.rb +18 -36
  131. data/watir/ie-process.rb +40 -0
  132. data/watir/irb-history.rb +31 -0
  133. data/watir/process.rb +20 -0
  134. data/watir/testUnitAddons.rb +3 -42
  135. data/watir/testcase.rb +58 -0
  136. data/watir/utils.rb +20 -0
  137. data/watir/waiter.rb +88 -0
  138. data/watir/watir_simple.rb +4 -4
  139. data/watir/win32ole.rb +8 -0
  140. data/watir/win32ole/win32ole.so +0 -0
  141. data/watir/winClicker.rb +374 -400
  142. metadata +209 -128
  143. data/unittests/WindowLogonExample.rb +0 -30
  144. data/unittests/attachToExistingWindow_test.rb +0 -40
  145. data/unittests/js_events_test.rb +0 -77
  146. data/unittests/jscriptExtraAlert.rb +0 -6
  147. data/unittests/jscriptExtraConfirmCancel.rb +0 -7
  148. data/unittests/jscriptExtraConfirmOk.rb +0 -7
  149. data/unittests/jscript_test.rb +0 -57
  150. data/unittests/send_keys_test.rb +0 -29
  151. data/unittests/textAreafields_test.rb +0 -81
@@ -49,7 +49,7 @@ module Watir
49
49
  # Most action methods in Watir::Simple will automatically wait for the browser
50
50
  # not to be busy before and after they perform the specified action.
51
51
  #
52
- # revision: $Revision: 1.1 $
52
+ # revision: $Revision: 1007 $
53
53
  module Simple
54
54
 
55
55
  # Open up a browser and point it at a certain URL.
@@ -71,7 +71,7 @@ module Watir
71
71
  def navigate_to_link_with_url(url)
72
72
  # FIXME: this should be moved into Watir!
73
73
  wait_before_and_after do
74
- doc = @@browser.getDocument()
74
+ doc = @@browser.getDocument
75
75
  links = doc.links
76
76
  link = nil
77
77
  links.each do |n|
@@ -97,7 +97,7 @@ module Watir
97
97
  def navigate_to_link_with_id(id)
98
98
  # FIXME: this should be moved into Watir!
99
99
  wait_before_and_after do
100
- doc = @@browser.getDocument()
100
+ doc = @@browser.getDocument
101
101
  links = doc.links
102
102
  link = nil
103
103
  links.each do |n|
@@ -259,7 +259,7 @@ module Watir
259
259
  # * mesg - An assertion-failed message.
260
260
  def assert_text_not_in_body(text,mesg=nil)
261
261
  if mesg.nil? then
262
- assert(! @@browser.pageContainsText(text), "couldn't find in body: [#{text}]")
262
+ assert(! @@browser.pageContainsText(text), "found in body: [#{text}]")
263
263
  else
264
264
  assert(! @@browser.pageContainsText(text), mesg)
265
265
  end
@@ -0,0 +1,8 @@
1
+ # load the correct version of win32ole
2
+
3
+ # Use our modified win32ole library for Ruby 1.8.2 only
4
+ if RUBY_VERSION == '1.8.2'
5
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'watir', 'win32ole')
6
+ end
7
+ require 'win32ole'
8
+
@@ -1,4 +1,53 @@
1
- # winClickers.rb
1
+ =begin
2
+ license
3
+ ---------------------------------------------------------------------------
4
+ Copyright (c) 2004-2006, Paul Rogers and Bret Pettichord
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 names Paul Rogers, nor Bret Pettichord nor the names of any
18
+ other contributors to this software may be used to endorse or promote
19
+ products derived from this software without specific prior written
20
+ permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
23
+ IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
26
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
29
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
31
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
32
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
+ --------------------------------------------------------------------------
34
+ (based on BSD Open Source License)
35
+ =end
36
+
37
+ =begin rdoc
38
+ This is Watir's window clicker helper class, uses Win32 api
39
+ calls to access buttons and windows.
40
+
41
+ Typical usage:
42
+ # include this file in your script
43
+ require "watir/winClicker.rb"
44
+
45
+ # create a new instance of WinClicker and use it
46
+ wc = WinClicker.new
47
+ wc.clickWindowsButton("My Window", "Click Me", 30)
48
+
49
+ =end
50
+
2
51
  #
3
52
  # class to click javascript dialog boxes, file requester dialogs etc
4
53
  require 'dl/import'
@@ -33,473 +82,398 @@ class WinClicker
33
82
 
34
83
  # these are the most used methods
35
84
 
36
- def initialize()
37
- @User32 = DL.dlopen("user32")
38
-
39
- # we must determine the path we are in
40
- @path_to_clicker = File.expand_path(File.dirname(__FILE__))
85
+ def initialize
86
+ @User32 = DL.dlopen("user32")
87
+ # we must determine the path we are in
88
+ @path_to_clicker = '"' + File.expand_path(File.dirname(__FILE__)) + '"'
41
89
  end
42
90
 
43
91
 
44
-
92
+ # The system function passes command to the command interpreter, which executes the string as an operating-system command
93
+ # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt_system.2c_._wsystem.asp
94
+ # using win32api
45
95
  def winsystem(command)
46
-
47
-
48
- # http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt_system.2c_._wsystem.asp
49
- # using win32api
50
96
  pid = Win32API.new("crtdll", "system", ['P'], 'L').Call(command)
51
-
52
- # using DL
53
- #winapi= DL.dlopen("crtdll")
54
- #sys = winapi['system' , '??']
55
-
56
97
  end
57
98
 
99
+ # returns the short path version of a long path
100
+ # 8.3 style
58
101
  def getShortFileName(longName)
59
- size = 255
60
- buffer = " " * 255
61
- returnSize = Win32API.new("kernel32" , "GetShortPathNameA" , 'ppl' , 'L').Call(longName , buffer , size )
62
- a = ""
63
- a = a + buffer[0...returnSize]
64
-
65
- return a
66
-
102
+ size = 255
103
+ buffer = " " * 255
104
+ returnSize = Win32API.new("kernel32" , "GetShortPathNameA" , 'ppl' , 'L').Call(longName , buffer , size )
105
+ a = ""
106
+ a = a + buffer[0...returnSize]
107
+ return a
67
108
  end
68
109
 
110
+ # Set the first edit box in the Choose file dialog to textToSet
69
111
  # we may need to play with the default try count. 3 is a reasonably safe value.
70
112
  def setFileRequesterFileName( textToSet, tryCount = 3 )
71
- for i in (1..tryCount)
72
- # first set the Choose File Window to be active
73
- hWnd = getWindowHandle("Choose file" )
74
- if hWnd != -1
75
- makeWindowActive(hWnd)
76
- setTextValueForFileNameField( hWnd , textToSet)
77
- clickWindowsButton_hwnd(hWnd, "&Open")
78
- return true
79
- end
80
- end
81
- puts 'File Requester not found'
82
- return false
83
- end
84
-
85
- def setFileRequesterFileName_newProcess ( textToSet )
86
- myapp = "#{@path_to_clicker}/setFileDialog.rb #{textToSet}"
87
- puts "Starting win setFileDialog in new process. Setting text #{textToSet}"
88
- puts "Starting app: #{myapp}"
89
- winsystem( "start #{myapp}" )
90
- end
91
-
92
-
93
-
94
- def getFileRequesterFileName ( )
95
-
113
+ for i in (1..tryCount)
96
114
  # first set the Choose File Window to be active
97
115
  hWnd = getWindowHandle("Choose file" )
98
116
  if hWnd != -1
99
-
100
- makeWindowActive (hWnd)
101
- return getTextValueForFileNameField( hWnd )
102
-
103
- else
104
- puts 'File Requester not found'
105
- return nil
106
- end
117
+ makeWindowActive(hWnd)
118
+ setTextValueForFileNameField( hWnd , textToSet)
119
+ clickWindowsButton_hwnd(hWnd, "&Open")
120
+ return true
121
+ end
122
+ end
123
+ return false
107
124
  end
108
125
 
109
- # Click Javascript Dialog
110
-
111
- def clickJavaScriptDialog(button="Ok" , parenthWnd = -1)
112
-
113
- clickWindowsButton("Microsoft Internet Explorer" , button )
114
-
126
+ # fire off setting the file name for the Choose file dialog
127
+ # in a new process
128
+ def setFileRequesterFileName_newProcess ( textToSet )
129
+ myapp = "rubyw #{@path_to_clicker}/setFileDialog.rb #{textToSet}"
130
+ # first argument to system call is a window title, in this case blank ""
131
+ winsystem( "start \"\" #{myapp}" )
115
132
  end
116
133
 
134
+ # Return the text value from the first combo box
135
+ # on the Choose file dialog or nil if not found
136
+ def getFileRequesterFileName()
137
+ # first set the Choose File Window to be active
138
+ hWnd = getWindowHandle("Choose file" )
139
+ if hWnd != -1
140
+ makeWindowActive(hWnd)
141
+ return getTextValueForFileNameField( hWnd )
142
+ else
143
+ return nil
144
+ end
145
+ end
117
146
 
147
+ # Click on a dialog with title of "Internet Explorer"
148
+ # Default button to click is "OK"
149
+ # parenthWnd not used
150
+ def clickJavaScriptDialog(button="OK" , parenthWnd = -1)
151
+ clickWindowsButton("Internet Explorer" , button )
152
+ end
118
153
 
119
- # use this method to launch a clicker in a new process
120
-
154
+ # Calls system to launch a new process to click on the button
155
+ # defaults to "OK" button
121
156
  def clickJSDialog_NewProcess(button = "OK" )
122
-
123
- myapp = "#{@path_to_clicker}clickJSDialog.rb #{button}"
124
- log "Starting win clicker in a new process. Looking for button #{button}"
125
- log "Starting app: #{myapp}"
126
- winsystem( "start #{myapp}" )
127
-
128
- #if winsystem( myapp ) == false
129
- # log "Clicker failed to start..."
130
- # log $? # some sort of lasterror ?????
131
- #end
157
+ myapp = "rubyw #{@path_to_clicker}/clickJSDialog.rb #{button}"
158
+ log "Starting win clicker in a new process. Looking for button #{button}"
159
+ log "Starting app: #{myapp}"
160
+ # first argument to system call is a window title, in this case blank ""
161
+ winsystem( "start \"\" #{myapp}" )
132
162
  end
133
163
 
134
164
 
135
165
  # as a thread
136
166
  def clickJSDialog_Thread(button = "OK" )
137
-
138
- puts "clickJSDialog_Thread Starting waiting.."
139
- sleep 3
140
- puts " clickJSDialog_Thread ... resuming"
141
- n = 0
142
- while n < 3
143
- sleep 1
144
- clickWindowsButton("Microsoft Internet Explorer" , button )
145
- n=n+1
146
- end
147
-
167
+ sleep 3
168
+ n = 0
169
+ while n < 3
170
+ sleep 1
171
+ clickWindowsButton("Internet Explorer" , button )
172
+ n=n+1
173
+ end
148
174
  end
149
175
 
150
-
151
- def clearSecurityAlertBox()
152
- clickWindowsButton("Security Alert" , "&Yes" )
176
+ # Looks for a window titled "Security Alert", clicks
177
+ # on Yes button
178
+ def clearSecurityAlertBox
179
+ clickWindowsButton("Security Alert" , "&Yes" )
153
180
  end
181
+ alias :clear_security_alert :clearSecurityAlertBox
154
182
 
155
-
156
- # the following methods are used internally, they may have uses elsewhere
157
-
183
+ # Returns the parent handle for the given child handle
158
184
  def getParent (childhWnd )
159
- # pass a hWnd into this function and it will return the parent hWnd
160
- getParentWindow = @User32['GetParent' , 'II' ]
161
-
162
- puts " Finding Parent for: " + childhWnd.to_s
163
- a , b = getParentWindow.call(childhWnd )
164
- #puts "a = " a.to_s , b.to_s
165
- return a
166
-
185
+ # pass a hWnd into this function and it will return the parent hWnd
186
+ getParentWindow = @User32['GetParent' , 'II' ]
187
+ a , b = getParentWindow.call(childhWnd )
188
+ return a
167
189
  end
190
+ alias :get_parent :getParent
168
191
 
192
+ # Enumerates open windows and
193
+ # returns a window handle from a given title and window class
194
+ # Window class and title are matched regexes
169
195
  def getWindowHandle(title, winclass = "" )
170
-
171
- enum_windows = @User32['EnumWindows', 'IPL']
172
- get_class_name = @User32['GetClassName', 'ILpI']
173
- get_caption_length = @User32['GetWindowTextLengthA' ,'LI' ] # format here - return value type (Long) followed by parameter types - int in this case - see http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/ext/dl/doc/dl.txt?
174
- get_caption = @User32['GetWindowTextA', 'iLsL' ]
175
-
176
- #if winclass != ""
177
- # len = winclass.length + 1
178
- #else
179
- len = 32
180
- #end
181
- buff = " " * len
182
- classMatch = false
196
+ enum_windows = @User32['EnumWindows', 'IPL']
197
+ get_class_name = @User32['GetClassName', 'ILpI']
198
+ get_caption_length = @User32['GetWindowTextLengthA' ,'LI' ] # format here - return value type (Long) followed by parameter types - int in this case - see http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/ext/dl/doc/dl.txt?
199
+ get_caption = @User32['GetWindowTextA', 'iLsL' ]
200
+
201
+ len = 32
202
+ buff = " " * len
203
+ classMatch = false
183
204
 
184
- puts("getWindowHandle - looking for: " + title.to_s )
185
-
186
- bContinueEnum = -1
187
-
188
- enum_windows_proc = DL.callback('ILL') {|hwnd,lparam|
189
- sleep 0.05
190
- r,rs = get_class_name.call(hwnd, buff, buff.size)
191
- puts "Found window: " + rs[1].to_s
192
-
193
- if winclass != "" then
194
- if /#{winclass}/ =~ rs[1].to_s
195
- classMatch = true
196
- end
197
- else
198
- classMatch = true
199
- end
200
-
201
- if classMatch ==true
202
- textLength, a = get_caption_length.call(hwnd)
203
- captionBuffer = " " * (textLength+1)
204
-
205
- t , textCaption = get_caption.call(hwnd, captionBuffer , textLength+1)
206
- puts "Caption =" + textCaption[1].to_s
207
-
208
- if /#{title}/ =~ textCaption[1].to_s
209
- puts "Found Window with correct caption (" + textCaption[1].to_s + " hwnd=" + hwnd.to_s + ")"
210
- return hwnd
211
- end
212
- bContinueEnum
213
- else
214
- bContinueEnum
215
- end
216
- }
217
- r,rs = enum_windows.call(enum_windows_proc, 0)
218
- return bContinueEnum
219
- end
205
+ bContinueEnum = -1 # Windows "true" to continue enum_windows.
206
+ found_hwnd = -1
207
+ enum_windows_proc = DL.callback('ILL') {|hwnd,lparam|
208
+ sleep 0.05
209
+ r,rs = get_class_name.call(hwnd, buff, buff.size)
210
+
211
+ if winclass != "" then
212
+ if /#{winclass}/ =~ rs[1].to_s
213
+ classMatch = true
214
+ end
215
+ else
216
+ classMatch = true
217
+ end
220
218
 
219
+ if classMatch ==true
220
+ textLength, a = get_caption_length.call(hwnd)
221
+ captionBuffer = " " * (textLength+1)
222
+ t , textCaption = get_caption.call(hwnd, captionBuffer , textLength+1)
223
+ if /#{title}/ =~ textCaption[1].to_s
224
+ found_hwnd = hwnd
225
+ bContinueEnum = 0 # False, discontinue enum_windows
226
+ end
227
+ bContinueEnum
228
+ else
229
+ bContinueEnum
230
+ end
231
+ }
232
+ r,rs = enum_windows.call(enum_windows_proc, 0)
233
+ DL.remove_callback(enum_windows_proc)
234
+ return found_hwnd
235
+ end
236
+ alias :get_window_handle :getWindowHandle
221
237
 
238
+ # Call SwitchToThisWindow win32api which will
239
+ # The SwitchToThisWindow function is called to switch focus to a specified window
240
+ # and bring it to the foreground
222
241
  def makeWindowActive (hWnd)
223
-
224
- switch_to_window = @User32['SwitchToThisWindow' , 'pLI' ]
225
-
226
- # set it to be the one with focus
227
- switch_to_window.call(hWnd , 1)
228
-
242
+ switch_to_window = @User32['SwitchToThisWindow' , 'pLI' ]
243
+ # set it to be the one with focus
244
+ switch_to_window.call(hWnd , 1)
229
245
  end
230
-
246
+ alias :make_window_active :makeWindowActive
247
+
248
+ # Posts a message to the handle passed in to click
231
249
  def clickButtonWithHandle(buttonhWnd)
232
-
233
- post_message = @User32['PostMessage', 'ILILL']
234
- #post_message = @User32['SendMessage', 'ILILL']
235
- puts "posting mesage"
236
- r,rs = post_message.call(buttonhWnd, BM_CLICK, 0, 0)
237
-
238
- puts "return #{r} #{rs} "
250
+ post_message = @User32['PostMessage', 'ILILL']
251
+ r,rs = post_message.call(buttonhWnd, BM_CLICK, 0, 0)
239
252
  end
240
-
241
-
242
- def clickWindowsButton_hwnd (hwnd , buttonCaption )
243
-
253
+ alias :click_button_with_handle :clickButtonWithHandle
254
+
255
+ # Based on the parent window handle passed in,
256
+ # click on the button with the given caption.
257
+ def clickWindowsButton_hwnd (hwnd , buttonCaption )
258
+ makeWindowActive(hwnd)
259
+ d = getChildHandle( hwnd , buttonCaption )
260
+ if d != -1
244
261
  makeWindowActive(hwnd)
245
-
246
- d = getChildHandle( hwnd , buttonCaption )
247
- puts ("clickWindowsButton: handle for button: " + buttonCaption + " is " + d.to_s )
248
-
249
- if d != -1
250
- makeWindowActive(hwnd)
251
- clickButtonWithHandle (d)
252
- else
253
- return false
254
- end
255
-
256
- return true
257
- end
258
-
259
-
260
- # this clicks the button with the name in the window with the caption. It keeps looking for the button until
261
- # until the timeout expires
262
- def clickWindowsButton (windowCaption , buttonCaption , maxWaitTime=30 )
263
-
264
- sleep 1
265
-
266
- hwnd = -1
267
- begin
268
- timeout(maxWaitTime) do
269
-
270
- hwnd = getWindowHandle(windowCaption)
271
-
272
- while hwnd == -1
273
- hwnd = getWindowHandle(windowCaption)
274
- sleep 0.5
275
- end
276
- makeWindowActive(hwnd)
277
- end
278
- rescue
279
- puts "clickWindowsButton: Cant make window active in specified time ( " + maxWaitTime.to_s + ") - no handle"
280
- return false
281
- end
282
-
283
- puts ' Window handle is : ' + hwnd.to_s
284
- if hwnd != -1
285
- puts "clickWindowsButton: Handle for window: " + windowCaption + " is: " + hwnd.to_s
286
- makeWindowActive(hwnd)
287
- else
288
- end
289
-
290
- d = getChildHandle( hwnd , buttonCaption )
291
- puts ("clickWindowsButton: handle for button: " + buttonCaption + " is " + d.to_s )
292
-
293
- if d != -1
294
- makeWindowActive(hwnd)
295
- clickButtonWithHandle (d)
296
- else
297
- return false
298
- end
299
-
300
- return true
301
-
262
+ clickButtonWithHandle(d)
263
+ else
264
+ return false
265
+ end
266
+ return true
302
267
  end
268
+ alias :click_windows_button_hwnd :clickWindowsButton_hwnd
269
+
270
+ # this clicks the button with the name in the window with the caption. It keeps looking for the button until
271
+ # until the timeout expires
272
+ def clickWindowsButton (windowCaption , buttonCaption , maxWaitTime=30 )
273
+ sleep 1
274
+ hwnd = -1
275
+ begin
276
+ timeout(maxWaitTime) do
277
+ hwnd = getWindowHandle(windowCaption)
278
+ while hwnd == -1
279
+ hwnd = getWindowHandle(windowCaption)
280
+ sleep 0.5
281
+ end
282
+ makeWindowActive(hwnd)
283
+ end
284
+ rescue
285
+ return false
286
+ end
287
+ if hwnd != -1
288
+ makeWindowActive(hwnd)
289
+ else
290
+ end
291
+ d = getChildHandle( hwnd , buttonCaption )
292
+ if d != -1
293
+ makeWindowActive(hwnd)
294
+ clickButtonWithHandle(d)
295
+ else
296
+ return false
297
+ end
298
+ return true
299
+ end
300
+ alias :click_windows_button :clickWindowsButton
303
301
 
304
-
302
+ # Enumerate through children of the parent hwnd, pass back
303
+ # the handle for the control with the given caption
304
+ # the caption is compared as a regex
305
305
  def getChildHandle ( hWnd , childCaption )
306
-
307
- enum_childWindows = @User32['EnumChildWindows' , 'IIPL' ]
308
- get_caption_length = @User32['GetWindowTextLengthA' ,'LI' ] # format here - return value type (Long) followed by parameter types - int in this case - see http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/ext/dl/doc/dl.txt?
309
- get_caption = @User32['GetWindowTextA', 'iLsL' ]
310
-
311
- buff = " " * 16
312
- get_class_name = @User32['GetClassName', 'ILpI']
313
-
314
- bContinueEnum = -1
315
- enum_childWindows_proc = DL.callback('ILL') {|chwnd,lparam|
316
- r,rs = get_class_name.call(chwnd, buff, buff.size)
317
- puts "Found window: " + rs[1].to_s + " Handle: " + chwnd.to_s
318
-
319
- textLength, a = get_caption_length.call(chwnd)
320
- captionBuffer = " " * (textLength+1)
321
-
322
- t , textCaption = get_caption.call(chwnd, captionBuffer , textLength+1)
323
- puts "Caption =" + textCaption[1].to_s
324
-
325
- if /#{childCaption}/ =~ textCaption[1].to_s then
326
- return chwnd
327
- end
328
- bContinueEnum
329
- }
330
- r = enum_childWindows.call(hWnd, enum_childWindows_proc ,0)
331
- return -1
332
-
306
+ enum_childWindows = @User32['EnumChildWindows' , 'IIPL' ]
307
+ get_caption_length = @User32['GetWindowTextLengthA' ,'LI' ] # format here - return value type (Long) followed by parameter types - int in this case - see http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/ext/dl/doc/dl.txt?
308
+ get_caption = @User32['GetWindowTextA', 'iLsL' ]
309
+ match_hwnd = -1 # hWnd of handle matching childCaption
310
+ buff = " " * 16
311
+ get_class_name = @User32['GetClassName', 'ILpI']
312
+
313
+ bContinueEnum = -1
314
+ enum_childWindows_proc = DL.callback('ILL') {|chwnd,lparam|
315
+ r,rs = get_class_name.call(chwnd, buff, buff.size)
316
+ textLength, a = get_caption_length.call(chwnd)
317
+ captionBuffer = " " * (textLength+1)
318
+
319
+ t , textCaption = get_caption.call(chwnd, captionBuffer , textLength+1)
320
+ if /#{childCaption}/ =~ textCaption[1].to_s then
321
+ match_hwnd = chwnd
322
+ bContinueEnum = 0 # Windows "false" to discontinue enum_childWindow
323
+ end
324
+ bContinueEnum
325
+ }
326
+ r = enum_childWindows.call(hWnd, enum_childWindows_proc ,0)
327
+ DL.remove_callback(enum_childWindows_proc)
328
+ return match_hwnd
333
329
  end
330
+ alias :get_chwnd :getChildHandle
334
331
 
335
-
336
-
337
-
332
+ # Convenience method to return Static text for
333
+ # children of the window with the given caption
338
334
  def getStaticText(caption)
339
335
  return getStaticTextFromWindow(caption, -1)
340
336
  end
337
+ alias :get_static_text :getStaticText
341
338
 
339
+ # Convenience method to return Static text for
340
+ # children of the window handle
342
341
  def getStaticText_hWnd (hWnd)
343
342
  return getStaticTextFromWindow("" , hWnd)
344
343
  end
344
+ alias :get_static_text_hwnd :getStaticText_hWnd
345
345
 
346
-
346
+ # Return text as an array from child controls of the window
347
+ # given as either a handle or with the given caption
348
+ # that have a class type of Static
347
349
  def getStaticTextFromWindow( windowCaption , hWnd)
348
-
349
- enum_childWindows = @User32['EnumChildWindows' , 'IIPL' ]
350
- get_caption_length = @User32['GetWindowTextLengthA' ,'LI' ] # format here - return value type (Long) followed by parameter types - int in this case - see http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/ext/dl/doc/dl.txt?
351
- get_caption = @User32['GetWindowTextA', 'iLsL' ]
352
-
353
- staticText = []
354
- buff = " " * 16
355
- get_class_name = @User32['GetClassName', 'ILpI']
356
-
357
- if hWnd == -1
358
- hWnd = getWindowHandle(windowCaption)
359
- end
360
-
361
- if hWnd == -1
362
- return staticText
363
- end
364
-
365
- bContinueEnum = -1
366
- enum_childWindows_proc = DL.callback('ILL') {|hWnd,lparam|
367
- r,rs = get_class_name.call(hWnd, buff, buff.size)
368
- puts "Found window: " + rs[1].to_s + " Handle: " + hWnd.to_s
369
-
370
- if rs[1].to_s == "Static" # there must be a better way of detecting this
371
-
372
- textLength, a = get_caption_length.call(hWnd)
373
- captionBuffer = " " * (textLength+1)
374
-
375
- t , textCaption = get_caption.call(hWnd, captionBuffer , textLength+1)
376
- #puts "Caption =" + textCaption[1].to_s
377
- staticText << textCaption[1].to_s
378
- end
379
- bContinueEnum
380
- }
381
- r = enum_childWindows.call(hWnd, enum_childWindows_proc ,0)
382
- return staticText
350
+ enum_childWindows = @User32['EnumChildWindows' , 'IIPL' ]
351
+ get_caption_length = @User32['GetWindowTextLengthA' ,'LI' ] # format here - return value type (Long) followed by parameter types - int in this case - see http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/ext/dl/doc/dl.txt?
352
+ get_caption = @User32['GetWindowTextA', 'iLsL' ]
353
+
354
+ staticText = []
355
+ buff = " " * 16
356
+ get_class_name = @User32['GetClassName', 'ILpI']
357
+
358
+ if hWnd == -1
359
+ hWnd = getWindowHandle(windowCaption)
360
+ end
361
+
362
+ if hWnd == -1
363
+ return staticText
364
+ end
365
+
366
+ bContinueEnum = -1
367
+ enum_childWindows_proc = DL.callback('ILL') {|hWnd,lparam|
368
+ r,rs = get_class_name.call(hWnd, buff, buff.size)
369
+ if rs[1].to_s == "Static" # there must be a better way of detecting this
370
+ textLength, a = get_caption_length.call(hWnd)
371
+ captionBuffer = " " * (textLength+1)
372
+ t , textCaption = get_caption.call(hWnd, captionBuffer , textLength+1)
373
+ staticText << textCaption[1].to_s
374
+ end
375
+ bContinueEnum
376
+ }
377
+ r = enum_childWindows.call(hWnd, enum_childWindows_proc ,0)
378
+ DL.remove_callback(enum_childWindows_proc)
379
+ return staticText
383
380
  end
381
+ alias :get_static_text_from_window :getStaticTextFromWindow
384
382
 
385
-
383
+ # returns the handle (or -1 if its not found) of the
384
+ # nth control of this class in the parent window specified
385
+ # by the window handle
386
386
  def getHandleOfControl (hWnd , controlClass, position )
387
-
388
- # returns the handle (or -1 if its not found) of the nth control of this class
389
- enum_childWindows = @User32['EnumChildWindows' , 'IIPL' ]
390
- get_caption_length = @User32['GetWindowTextLengthA' ,'LI' ] # format here - return value type (Long) followed by parameter types - int in this case - see http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/ext/dl/doc/dl.txt?
391
- get_caption = @User32['GetWindowTextA', 'iLsL' ]
392
-
393
- control_hWnd = []
394
-
395
- buff = " " * 16
396
- get_class_name = @User32['GetClassName', 'ILpI']
397
-
398
- bContinueEnum = -1
399
- enum_childWindows_proc = DL.callback('ILL') {|hWnd,lparam|
400
- r,rs = get_class_name.call(hWnd, buff, buff.size)
401
- puts "Found window: " + rs[1].to_s + " Handle: " + hWnd.to_s
402
-
403
- if rs[1].to_s == controlClass # there must be a better way of detecting this
404
-
405
- # we have found a control of the specified type - add it to an array of hwnd
406
- control_hWnd << hWnd
407
-
408
- end
409
- bContinueEnum
410
- }
411
- r = enum_childWindows.call(hWnd, enum_childWindows_proc ,0)
412
- controlHwnd = control_hWnd[position]
413
- if controlHwnd == nil then
414
- controlHwnd = -1
415
- end
416
-
417
- return controlHwnd
387
+ enum_childWindows = @User32['EnumChildWindows' , 'IIPL' ]
388
+ get_caption_length = @User32['GetWindowTextLengthA' ,'LI' ] # format here - return value type (Long) followed by parameter types - int in this case - see http://www.ruby-lang.org/cgi-bin/cvsweb.cgi/~checkout~/ruby/ext/dl/doc/dl.txt?
389
+ get_caption = @User32['GetWindowTextA', 'iLsL' ]
390
+ control_hWnd = []
391
+ buff = " " * 16
392
+ get_class_name = @User32['GetClassName', 'ILpI']
393
+
394
+ bContinueEnum = -1
395
+ enum_childWindows_proc = DL.callback('ILL') {|hWnd,lparam|
396
+ r,rs = get_class_name.call(hWnd, buff, buff.size)
397
+ if rs[1].to_s == controlClass # there must be a better way of detecting this
398
+ control_hWnd << hWnd
399
+ end
400
+ bContinueEnum
401
+ }
402
+ r = enum_childWindows.call(hWnd, enum_childWindows_proc ,0)
403
+ DL.remove_callback(enum_childWindows_proc)
404
+ controlHwnd = control_hWnd[position]
405
+ if controlHwnd == nil then
406
+ controlHwnd = -1
407
+ end
408
+ return controlHwnd
418
409
  end
419
-
420
-
410
+ alias :get_handle_of_ctrl :getHandleOfControl
411
+
412
+ # Call set text on the given window handle
421
413
  def setComboBoxText(hWnd , textToSet)
422
-
423
- send_message = @User32['SendMessage', 'ILISS']
424
- r ,rs = send_message.call(hWnd , WM_SETTEXT , '' , textToSet )
425
- puts 'send message returned: ' + r.to_s
426
-
414
+ set_text(hWnd, textToSet)
427
415
  end
428
-
416
+ alias :set_combo_txt :setComboBoxText
417
+
418
+ # Call set text on the given window handle
429
419
  def setTextBoxText(hWnd , textToSet)
430
-
431
- send_message = @User32['SendMessage', 'ILISS']
432
- r ,rs = send_message.call(hWnd , WM_SETTEXT , '' , textToSet )
433
- puts 'setTextBoxText: send message returned: ' + r.to_s
434
-
420
+ set_text(hWnd, textToSet)
435
421
  end
436
-
437
- def getControlText( hWnd)
438
- buff = " " * 256
439
-
440
- send_message = @User32['SendMessage', 'ILIIS']
441
- r ,rs = send_message.call(hWnd , WM_GETTEXT , 256 , buff )
442
- puts 'send message returned: ' + r.to_s + ' text is: ' + buff.to_s
443
- return buff.to_s
422
+ alias :set_textbox_txt :setTextBoxText
423
+
424
+ # Private method to set text called by the two methods above
425
+ def set_text(hWnd, textToSet)
426
+ send_message = @User32['SendMessage', 'ILISS']
427
+ r ,rs = send_message.call(hWnd , WM_SETTEXT ,'',textToSet)
444
428
  end
445
-
446
-
447
-
448
- def getWindowTitle(hWnd )
449
- # get the title for the specified hwnd
450
-
451
- buff = " " * 256
452
- getWindowText = @User32['GetWindowText' , 'ILSI']
453
- r , rs = getWindowText.call( hWnd , buff , 256 )
454
- puts 'send message returned: ' + r.to_s + ' text is: ' + buff.to_s
455
- return buff.to_s
456
-
429
+ private :set_text
430
+
431
+ # Get the text in the handle for the given control
432
+ def getControlText(hWnd)
433
+ buff = " " * 256
434
+ send_message = @User32['SendMessage', 'ILIIS']
435
+ r ,rs = send_message.call(hWnd , WM_GETTEXT , 256 , buff )
436
+ return buff.to_s
457
437
  end
458
-
459
-
460
-
461
-
462
-
463
- # file requester methods
464
- def getTextValueForFileNameField( parenthWnd )
465
-
466
- # this sets the filename field to text to set
467
-
468
- # get the handle of the nth control that is a combo box
469
- f = getHandleOfControl(parenthWnd, "ComboBox" , 1 )
470
-
471
- puts "Handle for filename field is: " + f.to_s
472
-
473
- if f == -1 then
474
- puts "Unable to obtain handle for filename chooser"
475
- else
476
- # we can now send it some messages
477
- return getWinText(f )
478
- end
438
+ alias :get_ctrl_txt :getControlText
439
+
440
+ # get the title for the specified hwnd
441
+ def getWindowTitle(hWnd)
442
+ buff = " " * 256
443
+ getWindowText = @User32['GetWindowText' , 'ILSI']
444
+ r , rs = getWindowText.call( hWnd , buff , 256 )
445
+ return buff.to_s
479
446
  end
447
+ alias :get_win_title :getWindowTitle
448
+
449
+ # Get the text in the first combo box
450
+ # file requester methods returns nil on failure to
451
+ # locate the 1st combobox
452
+ def getTextValueForFileNameField(parenthWnd)
453
+ f = getHandleOfControl(parenthWnd, "ComboBox", 1)
454
+ if f == -1 then
455
+ # unable to find the first combobox
456
+ return nil
457
+ else
458
+ # we have the control and now
459
+ # can send it some messages
460
+ return getWinText(f )
461
+ end
462
+ end
463
+ alias :get_file_name :getTextValueForFileNameField
480
464
 
481
-
465
+ # this sets the filename field to text to set
482
466
  def setTextValueForFileNameField( parenthWnd , textToSet )
483
-
484
- # this sets the filename field to text to set
485
-
486
- # get the handle of the nth control that is a combo box
487
- f = getHandleOfControl(parenthWnd, "Edit" , 0 )
488
-
489
- puts "Handle for filename field is: " + f.to_s
490
-
491
- if f == -1 then
492
- puts "Unable to obtain handle for filename chooser"
493
- return false
494
- else
495
- # we can now send it some messages
496
- setComboBoxText(f , textToSet)
497
- return true
498
- end
467
+ # get the handle of the nth control that is an Edit box
468
+ f = getHandleOfControl(parenthWnd, "Edit" , 0 )
469
+ if f == -1 then
470
+ # unable to get a handle on the first edit control
471
+ return false
472
+ else
473
+ # we found the control and can now send it some messages
474
+ setComboBoxText(f , textToSet)
475
+ return true
476
+ end
499
477
  end
500
-
501
-
502
-
503
-
504
-
505
- end #winClicker
478
+ alias :set_file_name :setTextValueForFileNameField
479
+ end