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
@@ -0,0 +1,505 @@
1
+ # winClickers.rb
2
+ #
3
+ # class to click javascript dialog boxes, file requester dialogs etc
4
+ require 'dl/import'
5
+ require 'dl/struct'
6
+ require "timeout"
7
+ require 'Win32API'
8
+
9
+ class WinClicker
10
+
11
+ WM_CLOSE = 0x0010
12
+ WM_KEYDOWN = 0x0100
13
+ WM_KEYUP = 0x0101
14
+ WM_CHAR = 0x0102
15
+ BM_CLICK = 0x00F5
16
+ WM_COMMAND = 0x0111
17
+ WM_SETTEXT = 0x000C
18
+ WM_GETTEXT = 0x000D
19
+
20
+ HWND_TOP = 0
21
+ HWND_BOTTOM = 1
22
+ HWND_TOPMOST = -1
23
+ HWND_NOTOPMOST = -2
24
+
25
+ SWP_SHOWWINDOW = 0x40
26
+ SWP_NOSIZE = 1
27
+ SWP_NOMOVE = 2
28
+
29
+ TRUE_1 = 1
30
+
31
+ # these are constants for commonly used windows windows
32
+ WINCLASS_DIALOG = "32770"
33
+
34
+ # these are the most used methods
35
+
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__))
41
+ end
42
+
43
+
44
+
45
+ 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
+ pid = Win32API.new("crtdll", "system", ['P'], 'L').Call(command)
51
+
52
+ # using DL
53
+ #winapi= DL.dlopen("crtdll")
54
+ #sys = winapi['system' , '??']
55
+
56
+ end
57
+
58
+ 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
+
67
+ end
68
+
69
+ # we may need to play with the default try count. 3 is a reasonably safe value.
70
+ 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
+
96
+ # first set the Choose File Window to be active
97
+ hWnd = getWindowHandle("Choose file" )
98
+ 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
107
+ end
108
+
109
+ # Click Javascript Dialog
110
+
111
+ def clickJavaScriptDialog(button="Ok" , parenthWnd = -1)
112
+
113
+ clickWindowsButton("Microsoft Internet Explorer" , button )
114
+
115
+ end
116
+
117
+
118
+
119
+ # use this method to launch a clicker in a new process
120
+
121
+ 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
132
+ end
133
+
134
+
135
+ # as a thread
136
+ 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
+
148
+ end
149
+
150
+
151
+ def clearSecurityAlertBox()
152
+ clickWindowsButton("Security Alert" , "&Yes" )
153
+ end
154
+
155
+
156
+ # the following methods are used internally, they may have uses elsewhere
157
+
158
+ 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
+
167
+ end
168
+
169
+ 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
183
+
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
220
+
221
+
222
+ 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
+
229
+ end
230
+
231
+ 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} "
239
+ end
240
+
241
+
242
+ def clickWindowsButton_hwnd (hwnd , buttonCaption )
243
+
244
+ 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
+
302
+ end
303
+
304
+
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
+
333
+ end
334
+
335
+
336
+
337
+
338
+ def getStaticText(caption)
339
+ return getStaticTextFromWindow(caption, -1)
340
+ end
341
+
342
+ def getStaticText_hWnd (hWnd)
343
+ return getStaticTextFromWindow("" , hWnd)
344
+ end
345
+
346
+
347
+ 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
383
+ end
384
+
385
+
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
418
+ end
419
+
420
+
421
+ 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
+
427
+ end
428
+
429
+ 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
+
435
+ 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
444
+ 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
+
457
+ 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
479
+ end
480
+
481
+
482
+ 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
499
+ end
500
+
501
+
502
+
503
+
504
+
505
+ end #winClicker