watir 1.4.1 → 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
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