win 0.1.27 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,548 +1,549 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
- require 'win/gui/window'
3
-
4
- module WinWindowTest
5
-
6
- include WinTestApp
7
- include Win::GUI::Window
8
-
9
- def window_should_be(handle, tests)
10
- tests.each{|test, result| send(test.to_sym, handle).should == result}
11
- end
12
-
13
- def commands_should_show_window( *cmds, tests)
14
- cmds.each do |cmd|
15
- test_app do |app|
16
- show_window(app.handle, cmd)
17
- window_should_be app.handle, tests
18
-
19
- hide_window(app.handle) # hiding window first
20
- show_window(app.handle, cmd)
21
- window_should_be app.handle, tests
22
-
23
- show_window(app.handle, SW_MAXIMIZE) # now maximizing window
24
- show_window(app.handle, cmd)
25
- window_should_be app.handle, tests
26
-
27
- show_window(app.handle, SW_MINIMIZE) # now minimizing window
28
- show_window(app.handle, cmd)
29
- window_should_be app.handle, tests
30
- end
31
- end
32
- end
33
-
34
- describe Win::GUI::Window, ' defines a set of API functions related to Window manipulation' do
35
- context 'ensuring test app closes' do
36
- after(:each){close_test_app if @launched_test_app}
37
-
38
- describe '#window?' do
39
- spec{ use{ IsWindow(any_handle) }}
40
- spec{ use{ is_window(any_handle) }}
41
- spec{ use{ window?(any_handle) }}
42
-
43
- it 'returns true if window exists' do
44
- window?(any_handle).should == true
45
- end
46
-
47
- it 'returns false for invalid window handle' do
48
- window?(not_a_handle).should == false
49
- end
50
-
51
- it 'changes from true to false when existing window is closed' do
52
- test_app do |app|
53
- @app_handle = app.handle
54
- @ta_handle = app.textarea
55
- window?(@app_handle).should == true
56
- window?(@ta_handle).should == true
57
- end
58
- window?(@app_handle).should == false
59
- window?(@ta_handle).should == false
60
- end
61
- end
62
-
63
- describe '#window_visible?' do
64
- spec{ use{ IsWindowVisible(any_handle) }}
65
- spec{ use{ is_window_visible(any_handle) }}
66
- spec{ use{ window_visible?(any_handle) }}
67
- spec{ use{ visible?(any_handle) }}
68
-
69
- it 'returns true when window is visible, false when window is hidden' do
70
- test_app do |app|
71
- visible?(app.handle).should == true
72
- window_visible?(app.handle).should == true
73
- window_visible?(app.textarea).should == true
74
- hide_window(app.handle)
75
- visible?(app.handle).should == false
76
- window_visible?(app.handle).should == false
77
- window_visible?(app.textarea).should == false
78
- end
79
- end
80
- end
81
-
82
- describe '#maximized?' do
83
- spec{ use{ IsZoomed(any_handle) }}
84
- spec{ use{ is_zoomed(any_handle) }}
85
- spec{ use{ zoomed?(any_handle) }}
86
- spec{ use{ maximized?(any_handle) }}
87
-
88
- it 'returns true if the window is maximized, false otherwise' do
89
- test_app do |app|
90
- zoomed?(app.handle).should == false
91
- maximized?(app.handle).should == false
92
- show_window(app.handle, SW_MAXIMIZE)
93
- maximized?(app.handle).should == true
94
- zoomed?(app.handle).should == true
95
- end
96
- end
97
- end
98
-
99
- describe '#minimized?' do
100
- spec{ use{ IsIconic(any_handle) }}
101
- spec{ use{ is_iconic(any_handle) }}
102
- spec{ use{ iconic?(any_handle) }}
103
- spec{ use{ minimized?(any_handle) }}
104
-
105
- it 'returns true if the window is minimized, false otherwise' do
106
- test_app do |app|
107
- iconic?(app.handle).should == false
108
- minimized?(app.handle).should == false
109
- show_window(app.handle, SW_MINIMIZE)
110
- iconic?(app.handle).should == true # !
111
- minimized?(app.handle).should == true
112
- end
113
- end
114
- end
115
-
116
- describe '#child?' do
117
- spec{ use{ IsChild(parent_handle = any_handle, handle = any_handle) }}
118
- spec{ use{ is_child(parent_handle = any_handle, handle = any_handle) }}
119
- spec{ use{ child?(parent_handle = any_handle, handle = any_handle) }}
120
-
121
- it 'returns true if the window is a child of given parent, false otherwise' do
122
- test_app do |app|
123
- child?(app.handle, app.textarea).should == true
124
- child?(app.handle, any_handle).should == false
125
- end
126
- end
127
- end
128
-
129
- describe '#find_window(w)' do
130
- spec{ use{ FindWindow(class_name = nil, win_name = nil) }}
131
- spec{ use{ find_window(class_name = nil, win_name = nil) }}
132
- # Widebyte (unicode) version
133
- spec{ use{ FindWindowW(class_name = nil, win_name = nil) }}
134
- spec{ use{ find_window_w(class_name = nil, win_name = nil) }}
135
-
136
- it 'returns either Integer Window handle or nil' do
137
- find_window(nil, nil).should be_a_kind_of Integer
138
- find_window(TEST_IMPOSSIBLE, nil).should == nil
139
- end
140
-
141
- it 'returns nil if Window is not found' do
142
- find_window(TEST_IMPOSSIBLE, nil).should == nil
143
- find_window(nil, TEST_IMPOSSIBLE).should == nil
144
- find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == nil
145
- find_window_w(TEST_IMPOSSIBLE, nil).should == nil
146
- find_window_w(nil, TEST_IMPOSSIBLE).should == nil
147
- find_window_w(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == nil
148
- end
149
-
150
- it 'finds at least one window if both args are nils' do
151
- find_window(nil, nil).should_not == nil
152
- find_window_w(nil, nil).should_not == nil
153
- end
154
-
155
- it 'finds top-level window by window class or title' do
156
- test_app do |app|
157
- find_window(TEST_WIN_CLASS, nil).should == app.handle
158
- find_window(nil, TEST_WIN_TITLE).should == app.handle
159
- find_window_w(TEST_WIN_CLASS.to_w, nil).should == app.handle
160
- find_window_w(nil, TEST_WIN_TITLE.to_w).should == app.handle
161
- end
162
- end
163
- end
164
-
165
- describe '#find_window_ex' do
166
- spec{ use{ FindWindowEx(parent = any_handle, after_child = 0, win_class = nil, win_title = nil) }}
167
- spec{ use{ find_window_ex(parent = any_handle, after_child = 0, win_class = nil, win_title = nil) }}
168
-
169
- it 'returns nil if wrong control is given' do
170
- parent_handle = any_handle
171
- find_window_ex(parent_handle, 0, TEST_IMPOSSIBLE, nil).should == nil
172
- find_window_ex(parent_handle, 0, nil, TEST_IMPOSSIBLE).should == nil
173
- end
174
-
175
- it 'finds child window/control by class' do
176
- test_app do |app|
177
- ta_handle = find_window_ex(app.handle, 0, TEST_TEXTAREA_CLASS, nil)
178
- ta_handle.should_not == nil
179
- ta_handle.should == app.textarea
180
- end
181
- end
182
-
183
- it 'finds child window/control by text/title' do
184
- pending 'Identify appropriate (short name) control'
185
- test_app do |app|
186
- keystroke(VK_CONTROL, 'A'.ord)
187
- keystroke('1'.ord, '2'.ord)
188
- ta_handle = find_window_ex(app.handle, 0, nil, '12')
189
- ta_handle.should_not == 0
190
- ta_handle.should == app.textarea.handle
191
- end
192
- end
193
- end
194
-
195
- describe '#get_foreground_window' do
196
- # ! Different from GetActiveWindow !
197
- spec{ use{ handle = GetForegroundWindow() }}
198
- spec{ use{ handle = get_foreground_window }}
199
- spec{ use{ handle = foreground_window }}
200
-
201
- it 'returns handle to window that is currently in foreground' do
202
- test_app do |app|
203
- @app_handle = app.handle
204
- fg1 = foreground_window
205
- @app_handle.should == fg1
206
- end
207
- fg2 = foreground_window
208
- @app_handle.should_not == fg2
209
- end
210
-
211
- it 'defines #foreground? test function ' do
212
- test_app do |app|
213
- @app_handle = app.handle
214
- foreground?(@app_handle).should == true
215
- end
216
- foreground?(@app_handle).should == false
217
- end
218
- end
219
-
220
- describe '#get_active_window' do
221
- # ! Different from GetForegroundWindow !
222
- spec{ use{ handle = GetActiveWindow() }}
223
- spec{ use{ handle = get_active_window }}
224
- spec{ use{ handle = active_window }}
225
-
226
- it 'returns handle to the active window attached to the calling thread`s message queue' do
227
- pending 'No idea how to test it'
228
- test_app do |app|
229
- @app_handle = app.handle
230
- fg1 = active_window
231
- @app_handle.should == fg1
232
- end
233
- fg2 = active_window
234
- @app_handle.should_not == fg2
235
- end
236
- end
237
-
238
- describe '#get_window_text(w)' do
239
- spec{ use{ GetWindowText(any_handle, buffer, buffer.size)}}
240
- # Improved with block to accept window handle as a single arg and return (rstripped) text string
241
- spec{ use{ text = get_window_text(handle = 0)}}
242
- spec{ use{ text = window_text(handle = 0)}}
243
- # Unicode version of get_window_text (strings returned encoded as utf-8)
244
- spec{ use{ GetWindowTextW(any_handle, buffer, buffer.size)}}
245
- spec{ use{ text = get_window_text_w(any_handle)}} # result encoded as utf-8
246
- spec{ use{ text = window_text_w(handle = 0)}}
247
-
248
- it 'returns nil if incorrect window handle given' do
249
- get_window_text(not_a_handle).should == nil
250
- get_window_text_w(not_a_handle).should == nil
251
- end
252
-
253
- it 'returns correct window text' do
254
- test_app do |app|
255
- get_window_text(app.handle).should == TEST_WIN_TITLE
256
- get_window_text_w(app.handle).should == TEST_WIN_TITLE
257
- window_text(app.handle).should == TEST_WIN_TITLE
258
- window_text_w(app.handle).should == TEST_WIN_TITLE
259
- end
260
- end
261
- end
262
-
263
- describe '#get_class_name(w)' do
264
- spec{ use{ GetClassName(any_handle, buffer, buffer.size)}}
265
- # Improved with block to accept window handle as a single arg and return class name string
266
- spec{ use{ class_name = get_class_name(any_handle)}}
267
- spec{ use{ class_name = class_name(any_handle)}}
268
- # Unicode version of get_class_name (strings returned encoded as utf-8)
269
- spec{ use{ GetClassNameW(any_handle, buffer, buffer.size)}}
270
- spec{ use{ class_name = get_class_name_w(handle = 0)}} # result encoded as utf-8
271
- spec{ use{ class_name = class_name_w(any_handle)}}
272
-
273
- it 'returns correct window class name' do
274
- test_app do |app|
275
- get_class_name(app.handle).should == TEST_WIN_CLASS
276
- class_name(app.handle).should == TEST_WIN_CLASS
277
- class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!!!!!!! nil?
278
- get_class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!! nil?
279
- end
280
- end
281
- end
282
-
283
- describe '#get_window_thread_process_id' do
284
- spec{ use{ thread = GetWindowThreadProcessId(any_handle, process = FFI::MemoryPointer.new(:long).write_long(1)) }}
285
- spec{ use{ thread, process = get_window_thread_process_id(any_handle) }}
286
- # Improved with block to accept window handle as a single arg and return a pair of [thread, process]
287
-
288
- it 'returns a pair of nonzero Integer ids (thread and process) for valid window' do
289
- thread, process = get_window_thread_process_id(any_handle)
290
- thread.should be_a_kind_of Integer
291
- thread.should be > 0
292
- process.should be_a_kind_of Integer
293
- process.should be > 0
294
- end
295
-
296
- it 'returns a pair of nils (thread and process) for invalid window' do
297
- thread, process = get_window_thread_process_id(not_a_handle)
298
- thread.should == nil
299
- process.should == nil
300
- end
301
- end
302
-
303
- describe '#get_window_rect' do
304
- spec{ use{ success = GetWindowRect(any_handle, rectangle = FFI::MemoryPointer.new(:long, 4))}}
305
- spec{ use{ left, top, right, bottom = get_window_rect(any_handle)}}
306
-
307
- it 'returns array of nils for invalid window' do
308
- get_window_rect(not_a_handle).should == [nil, nil, nil, nil]
309
- end
310
-
311
- it 'returns window`s border rectangle' do
312
- test_app do |app|
313
- get_window_rect(app.handle).should == TEST_WIN_RECT
314
- end
315
- end
316
- end
317
-
318
- describe '#show_window' do
319
- spec{ use{ was_visible = ShowWindow(handle = any_handle, cmd = SW_SHOW) }}
320
- spec{ use{ was_visible = show_window(handle = any_handle) }}
321
-
322
- it 'defaults to SW_SHOW if no command given' do
323
- test_app do |app|
324
- hide_window(app.handle)
325
- use{show_window(app.handle)}
326
- visible?(app.handle).should == true
327
- end
328
- end
329
-
330
- it 'returns true if the window was PREVIOUSLY visible, false otherwise' do
331
- test_app do |app|
332
- show_window(app.handle, SW_HIDE).should == true
333
- show_window(app.handle, SW_HIDE).should == false
334
- end
335
- end
336
-
337
- it 'hides window with SW_HIDE command ' do
338
- test_app do |app|
339
- show_window(app.handle, SW_HIDE)
340
- visible?(app.handle).should == false
341
- end
342
- end
343
-
344
- it 'shows hidden window with SW_SHOW command' do
345
- test_app do |app|
346
- hide_window(app.handle)
347
- show_window(app.handle, SW_SHOW)
348
- visible?(app.handle).should == true
349
- end
350
- end
351
-
352
- it 'SW_MAXIMIZE, SW_SHOWMAXIMIZED maximize window and activate it' do
353
- commands_should_show_window SW_MAXIMIZE, SW_SHOWMAXIMIZED,
354
- :minimized? => false, :maximized? => true, :visible? => true, :foreground? => true
355
- end
356
-
357
- it 'SW_MINIMIZE minimizes window and activates the next top-level window in the Z order' do
358
- commands_should_show_window SW_MINIMIZE,
359
- :minimized? => true, :maximized? => false, :visible? => true, :foreground? => false
360
- end
361
-
362
- it 'SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED displays the window as a minimized foreground window' do
363
- commands_should_show_window SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED, #!
364
- :minimized? => true, :maximized? => false, :visible? => true, :foreground? => true
365
- end
366
-
367
- it 'SW_SHOWNORMAL, SW_RESTORE, SW_SHOWNOACTIVATE activate/display a window(if min/maximized it is restored' do
368
- commands_should_show_window SW_SHOWNORMAL, SW_RESTORE, SW_SHOWNOACTIVATE,
369
- :minimized? => false, :maximized? => false, :visible? => true, :foreground? => true
370
- end
371
-
372
- # what about SW_SHOWNA, SW_SHOWDEFAULT, SW_FORCEMINIMIZE ?
373
- end
374
-
375
- describe '#close_window' do
376
- spec{ use{ success = CloseWindow(handle = any_handle) }}
377
- spec{ use{ success = close_window(handle = any_handle) }}
378
-
379
- it 'minimizes (but does not destroy!) the specified window' do
380
- test_app do |app|
381
- close_window(app.handle).should == true
382
- window_should_be app.handle,
383
- :minimized? => true, :maximized? => false, :visible? => true, :foreground? => true
384
- end
385
- end
386
- end
387
-
388
- describe 'destroy_window' do
389
- spec{ use{ success = DestroyWindow(handle = 0) }}
390
- spec{ use{ success = destroy_window(handle = 0) }}
391
-
392
- it 'destroys window created by current thread'
393
-
394
- it 'cannot destroy window created by other thread' do
395
- test_app do |app|
396
- destroy_window(app.handle).should == false
397
- window?(app.handle).should == true
398
- end
399
- end
400
- end # describe 'destroy_window'
401
-
402
- end # context 'ensuring test app closes'
403
-
404
- context 'with single test app' do
405
- before(:all){@app = launch_test_app}
406
- after(:all){close_test_app}
407
-
408
- describe '#enum_windows' do
409
- before(:all){@app = launch_test_app}
410
- after(:all){close_test_app}
411
-
412
- spec{ use{ handles = enum_windows(value = 13) }}
413
- spec{ use{ enum_windows do |handle, message|
414
- end }}
415
-
416
- it 'iterates through all the top-level windows, passing each top level window handle and value to a given block' do
417
- enum_windows(13) do |handle, message|
418
- handle.should be_an Integer
419
- handle.should be > 0
420
- message.should == 13
421
- end
422
- end
423
-
424
- it 'returns an array of top-level window handles if block is not given' do
425
- enum = enum_windows(13)
426
- enum.should be_a_kind_of Array
427
- enum.should_not be_empty
428
- enum.should have_at_least(50).elements # typical number of top windows in WinXP system?
429
- enum.each do |handle|
430
- handle.should be_an Integer
431
- handle.should be > 0
432
- end
433
- enum.any?{|handle| handle == @app.handle}.should == true
434
- end
435
-
436
- it 'returned array that contains handle of launched test app' do
437
- enum = enum_windows(13)
438
- enum.any?{|handle| handle == @app.handle}.should == true
439
- end
440
-
441
- it 'defaults message to 0 if it is omitted from method call' do
442
- enum_windows do |handle, message|
443
- message.should == 0
444
- end
445
- end
446
- end
447
-
448
- describe '#enum_desktop_windows' do
449
- spec{ use{ handles = enum_desktop_windows(0, value = 13) }}
450
- spec{ use{ enum_desktop_windows(0) {|handle, message|} }}
451
-
452
- it 'iterates through all the top-level windows for a given desktop'
453
- end
454
-
455
- describe '#enum_child_windows' do
456
- spec{ use{ enum_child_windows(parent = any_handle, value = 13) }}
457
-
458
- it 'return an array of child window handles if block is not given' do
459
- enum = enum_child_windows(@app.handle, 13)
460
- enum.should be_a_kind_of Array
461
- enum.should have(2).elements
462
- class_name(enum.first).should == TEST_STATUSBAR_CLASS
463
- class_name(enum.last).should == TEST_TEXTAREA_CLASS
464
- end
465
-
466
- it 'loops through all children of given window, passing each found window handle and a message to a given block' do
467
- enum = []
468
- enum_child_windows(@app.handle, 13) do |handle, message|
469
- enum << handle
470
- message.should == 13
471
- end
472
- enum.should have(2).elements
473
- class_name(enum.first).should == TEST_STATUSBAR_CLASS
474
- class_name(enum.last).should == TEST_TEXTAREA_CLASS
475
- end
476
-
477
- it 'breaks loop if given block returns false' do
478
- enum = []
479
- enum_child_windows(@app.handle) do |handle, message|
480
- enum << handle
481
- false
482
- end
483
- enum.should have(1).element
484
- class_name(enum.first).should == TEST_STATUSBAR_CLASS
485
- end
486
-
487
- it 'defaults message to 0 if it is omitted from method call' do
488
- enum_child_windows(@app.handle) do |handle, message|
489
- message.should == 0
490
- end
491
- end
492
- end
493
-
494
- end # context 'with single test app'
495
- end # Win::GUI::Window, ' defines a set user32 API functions related to Window manipulation'
496
-
497
- describe Win::GUI::Window, ' defines convenience/service methods on top of Windows API' do
498
- after(:each){close_test_app if @launched_test_app}
499
-
500
- describe '#foreground?' do
501
- spec{ use{ foreground?( any_handle) }}
502
-
503
- it 'tests if the given window is foreground' do
504
- foreground?(foreground_window).should == true
505
- foreground?(any_handle).should == false
506
- end
507
- end
508
-
509
- describe '#hide_window' do
510
- spec{ use{ was_visible = hide_window(any_handle) }}
511
-
512
- it 'hides window: same as show_window(handle, SW_HIDE)' do
513
- test_app do |app|
514
- was_visible = hide_window(app.handle)
515
- was_visible.should == true #!
516
- visible?(app.handle).should == false
517
- hide_window(app.handle).should == false
518
- visible?(app.handle).should == false
519
- end
520
- end
521
- end
522
-
523
- describe '#shut_window' do
524
- spec{ use{ success = shut_window(handle=0) }}
525
-
526
- it 'destroys window in another thread by sending WM_SYSCOMMAND, SC_CLOSE message to it' do
527
- app = launch_test_app
528
-
529
- shut_window(app.handle).should == true
530
- sleep TEST_SLEEP_DELAY
531
-
532
- window?(app.handle).should == false
533
- end
534
- end
535
-
536
- describe '#text' do
537
- spec{ use{ text = text(any_handle) }}
538
-
539
- it 'returns text associated with window by sending WM_GETTEXT message to it' do
540
- test_app do |app|
541
-
542
- text(app.handle).should == TEST_WIN_TITLE
543
- text(app.textarea).should =~ /Welcome to Steganos LockNote/
544
- end
545
- end
546
- end # describe '#text'
547
- end # Win::GUI::Window, ' defines convenience/service methods on top of Windows API'
548
- end
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
+ require 'win/gui/window'
3
+
4
+ module WinWindowTest
5
+
6
+ include WinTestApp
7
+ include Win::Gui::Window
8
+
9
+ def window_should_be(handle, tests)
10
+ tests.each{|test, result| send(test.to_sym, handle).should == result}
11
+ end
12
+
13
+ def commands_should_show_window( *cmds, tests)
14
+ cmds.each do |cmd|
15
+ test_app do |app|
16
+ show_window(app.handle, cmd)
17
+ window_should_be app.handle, tests
18
+
19
+ hide_window(app.handle) # hiding window first
20
+ show_window(app.handle, cmd)
21
+ window_should_be app.handle, tests
22
+
23
+ show_window(app.handle, SW_MAXIMIZE) # now maximizing window
24
+ show_window(app.handle, cmd)
25
+ window_should_be app.handle, tests
26
+
27
+ show_window(app.handle, SW_MINIMIZE) # now minimizing window
28
+ show_window(app.handle, cmd)
29
+ window_should_be app.handle, tests
30
+ end
31
+ end
32
+ end
33
+
34
+ describe Win::Gui::Window, ' defines a set of API functions related to Window manipulation' do
35
+ context 'ensuring test app closes' do
36
+ after(:each){close_test_app if @launched_test_app}
37
+
38
+ describe '#window?' do
39
+ spec{ use{ IsWindow(any_handle) }}
40
+ spec{ use{ is_window(any_handle) }}
41
+ spec{ use{ window?(any_handle) }}
42
+
43
+ it 'returns true if window exists' do
44
+ window?(any_handle).should == true
45
+ end
46
+
47
+ it 'returns false for invalid window handle' do
48
+ window?(not_a_handle).should == false
49
+ end
50
+
51
+ it 'changes from true to false when existing window is closed' do
52
+ test_app do |app|
53
+ @app_handle = app.handle
54
+ @ta_handle = app.textarea
55
+ window?(@app_handle).should == true
56
+ window?(@ta_handle).should == true
57
+ end
58
+ window?(@app_handle).should == false
59
+ window?(@ta_handle).should == false
60
+ end
61
+ end
62
+
63
+ describe '#window_visible?' do
64
+ spec{ use{ IsWindowVisible(any_handle) }}
65
+ spec{ use{ is_window_visible(any_handle) }}
66
+ spec{ use{ window_visible?(any_handle) }}
67
+ spec{ use{ visible?(any_handle) }}
68
+
69
+ it 'returns true when window is visible, false when window is hidden' do
70
+ test_app do |app|
71
+ visible?(app.handle).should == true
72
+ window_visible?(app.handle).should == true
73
+ window_visible?(app.textarea).should == true
74
+ hide_window(app.handle)
75
+ visible?(app.handle).should == false
76
+ window_visible?(app.handle).should == false
77
+ window_visible?(app.textarea).should == false
78
+ end
79
+ end
80
+ end
81
+
82
+ describe '#maximized?' do
83
+ spec{ use{ IsZoomed(any_handle) }}
84
+ spec{ use{ is_zoomed(any_handle) }}
85
+ spec{ use{ zoomed?(any_handle) }}
86
+ spec{ use{ maximized?(any_handle) }}
87
+
88
+ it 'returns true if the window is maximized, false otherwise' do
89
+ test_app do |app|
90
+ zoomed?(app.handle).should == false
91
+ maximized?(app.handle).should == false
92
+ show_window(app.handle, SW_MAXIMIZE)
93
+ maximized?(app.handle).should == true
94
+ zoomed?(app.handle).should == true
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '#minimized?' do
100
+ spec{ use{ IsIconic(any_handle) }}
101
+ spec{ use{ is_iconic(any_handle) }}
102
+ spec{ use{ iconic?(any_handle) }}
103
+ spec{ use{ minimized?(any_handle) }}
104
+
105
+ it 'returns true if the window is minimized, false otherwise' do
106
+ test_app do |app|
107
+ iconic?(app.handle).should == false
108
+ minimized?(app.handle).should == false
109
+ show_window(app.handle, SW_MINIMIZE)
110
+ iconic?(app.handle).should == true # !
111
+ minimized?(app.handle).should == true
112
+ end
113
+ end
114
+ end
115
+
116
+ describe '#child?' do
117
+ spec{ use{ IsChild(parent_handle = any_handle, handle = any_handle) }}
118
+ spec{ use{ is_child(parent_handle = any_handle, handle = any_handle) }}
119
+ spec{ use{ child?(parent_handle = any_handle, handle = any_handle) }}
120
+
121
+ it 'returns true if the window is a child of given parent, false otherwise' do
122
+ test_app do |app|
123
+ child?(app.handle, app.textarea).should == true
124
+ child?(app.handle, any_handle).should == false
125
+ end
126
+ end
127
+ end
128
+
129
+ describe '#find_window(w)' do
130
+ spec{ use{ FindWindow(class_name = nil, win_name = nil) }}
131
+ spec{ use{ find_window(class_name = nil, win_name = nil) }}
132
+ # Widebyte (unicode) version
133
+ spec{ use{ FindWindowW(class_name = nil, win_name = nil) }}
134
+ spec{ use{ find_window_w(class_name = nil, win_name = nil) }}
135
+
136
+ it 'returns either Integer Window handle or nil' do
137
+ find_window(nil, nil).should be_a_kind_of Integer
138
+ find_window(TEST_IMPOSSIBLE, nil).should == nil
139
+ end
140
+
141
+ it 'returns nil if Window is not found' do
142
+ find_window(TEST_IMPOSSIBLE, nil).should == nil
143
+ find_window(nil, TEST_IMPOSSIBLE).should == nil
144
+ find_window(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == nil
145
+ find_window_w(TEST_IMPOSSIBLE, nil).should == nil
146
+ find_window_w(nil, TEST_IMPOSSIBLE).should == nil
147
+ find_window_w(TEST_IMPOSSIBLE, TEST_IMPOSSIBLE).should == nil
148
+ end
149
+
150
+ it 'finds at least one window if both args are nils' do
151
+ find_window(nil, nil).should_not == nil
152
+ find_window_w(nil, nil).should_not == nil
153
+ end
154
+
155
+ it 'finds top-level window by window class or title' do
156
+ test_app do |app|
157
+ find_window(TEST_WIN_CLASS, nil).should == app.handle
158
+ find_window(nil, TEST_WIN_TITLE).should == app.handle
159
+ find_window_w(TEST_WIN_CLASS.to_w, nil).should == app.handle
160
+ find_window_w(nil, TEST_WIN_TITLE.to_w).should == app.handle
161
+ end
162
+ end
163
+ end
164
+
165
+ describe '#find_window_ex' do
166
+ spec{ use{ FindWindowEx(parent = any_handle, after_child = 0, win_class = nil, win_title = nil) }}
167
+ spec{ use{ find_window_ex(parent = any_handle, after_child = 0, win_class = nil, win_title = nil) }}
168
+
169
+ it 'returns nil if wrong control is given' do
170
+ parent_handle = any_handle
171
+ find_window_ex(parent_handle, 0, TEST_IMPOSSIBLE, nil).should == nil
172
+ find_window_ex(parent_handle, 0, nil, TEST_IMPOSSIBLE).should == nil
173
+ end
174
+
175
+ it 'finds child window/control by class' do
176
+ test_app do |app|
177
+ ta_handle = find_window_ex(app.handle, 0, TEST_TEXTAREA_CLASS, nil)
178
+ ta_handle.should_not == nil
179
+ ta_handle.should == app.textarea
180
+ end
181
+ end
182
+
183
+ it 'finds child window/control by text/title' do
184
+ pending 'Identify appropriate (short name) control'
185
+ test_app do |app|
186
+ keystroke(VK_CONTROL, 'A'.ord)
187
+ keystroke('1'.ord, '2'.ord)
188
+ ta_handle = find_window_ex(app.handle, 0, nil, '12')
189
+ ta_handle.should_not == 0
190
+ ta_handle.should == app.textarea.handle
191
+ end
192
+ end
193
+ end
194
+
195
+ describe '#get_foreground_window' do
196
+ # ! Different from GetActiveWindow !
197
+ spec{ use{ handle = GetForegroundWindow() }}
198
+ spec{ use{ handle = get_foreground_window }}
199
+ spec{ use{ handle = foreground_window }}
200
+
201
+ it 'returns handle to window that is currently in foreground' do
202
+ test_app do |app|
203
+ @app_handle = app.handle
204
+ fg1 = foreground_window
205
+ @app_handle.should == fg1
206
+ end
207
+ fg2 = foreground_window
208
+ @app_handle.should_not == fg2
209
+ end
210
+
211
+ it 'defines #foreground? test function ' do
212
+ test_app do |app|
213
+ @app_handle = app.handle
214
+ foreground?(@app_handle).should == true
215
+ end
216
+ foreground?(@app_handle).should == false
217
+ end
218
+ end
219
+
220
+ describe '#get_active_window' do
221
+ # ! Different from GetForegroundWindow !
222
+ spec{ use{ handle = GetActiveWindow() }}
223
+ spec{ use{ handle = get_active_window }}
224
+ spec{ use{ handle = active_window }}
225
+
226
+ it 'returns handle to the active window attached to the calling thread`s message queue' do
227
+ pending 'No idea how to test it'
228
+ test_app do |app|
229
+ @app_handle = app.handle
230
+ fg1 = active_window
231
+ @app_handle.should == fg1
232
+ end
233
+ fg2 = active_window
234
+ @app_handle.should_not == fg2
235
+ end
236
+ end
237
+
238
+ describe '#get_window_text(w)' do
239
+ spec{ use{ GetWindowText(any_handle, buffer, buffer.size)}}
240
+ # Improved with block to accept window handle as a single arg and return (rstripped) text string
241
+ spec{ use{ text = get_window_text(handle = 0)}}
242
+ spec{ use{ text = window_text(handle = 0)}}
243
+ # Unicode version of get_window_text (strings returned encoded as utf-8)
244
+ spec{ use{ GetWindowTextW(any_handle, buffer, buffer.size)}}
245
+ spec{ use{ text = get_window_text_w(any_handle)}} # result encoded as utf-8
246
+ spec{ use{ text = window_text_w(handle = 0)}}
247
+
248
+ it 'returns nil if incorrect window handle given' do
249
+ get_window_text(not_a_handle).should == nil
250
+ get_window_text_w(not_a_handle).should == nil
251
+ end
252
+
253
+ it 'returns correct window text' do
254
+ test_app do |app|
255
+ get_window_text(app.handle).should == TEST_WIN_TITLE
256
+ get_window_text_w(app.handle).should == TEST_WIN_TITLE
257
+ window_text(app.handle).should == TEST_WIN_TITLE
258
+ window_text_w(app.handle).should == TEST_WIN_TITLE
259
+ end
260
+ end
261
+ end
262
+
263
+ describe '#get_class_name(w)' do
264
+ spec{ use{ GetClassName(any_handle, buffer, buffer.size)}}
265
+ # Improved with block to accept window handle as a single arg and return class name string
266
+ spec{ use{ class_name = get_class_name(any_handle)}}
267
+ spec{ use{ class_name = class_name(any_handle)}}
268
+ # Unicode version of get_class_name (strings returned encoded as utf-8)
269
+ spec{ use{ GetClassNameW(any_handle, buffer, buffer.size)}}
270
+ spec{ use{ class_name = get_class_name_w(handle = 0)}} # result encoded as utf-8
271
+ spec{ use{ class_name = class_name_w(any_handle)}}
272
+
273
+ it 'returns correct window class name' do
274
+ test_app do |app|
275
+ get_class_name(app.handle).should == TEST_WIN_CLASS
276
+ class_name(app.handle).should == TEST_WIN_CLASS
277
+ class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!!!!!!! nil?
278
+ get_class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!! nil?
279
+ end
280
+ end
281
+ end
282
+
283
+ describe '#get_window_thread_process_id' do
284
+ spec{ use{ thread = GetWindowThreadProcessId(any_handle, process = FFI::MemoryPointer.new(:long).write_long(1)) }}
285
+ spec{ use{ thread, process = get_window_thread_process_id(any_handle) }}
286
+ # Improved with block to accept window handle as a single arg and return a pair of [thread, process]
287
+
288
+ it 'returns a pair of nonzero Integer ids (thread and process) for valid window' do
289
+ thread, process = get_window_thread_process_id(any_handle)
290
+ thread.should be_a_kind_of Integer
291
+ thread.should be > 0
292
+ process.should be_a_kind_of Integer
293
+ process.should be > 0
294
+ end
295
+
296
+ it 'returns a pair of nils (thread and process) for invalid window' do
297
+ thread, process = get_window_thread_process_id(not_a_handle)
298
+ thread.should == nil
299
+ process.should == nil
300
+ end
301
+ end
302
+
303
+ describe '#get_window_rect' do
304
+ spec{ use{ success = GetWindowRect(any_handle, rectangle = FFI::MemoryPointer.new(:long, 4))}}
305
+ spec{ use{ left, top, right, bottom = get_window_rect(any_handle)}}
306
+
307
+ it 'returns array of nils for invalid window' do
308
+ get_window_rect(not_a_handle).should == [nil, nil, nil, nil]
309
+ end
310
+
311
+ it 'returns window`s border rectangle' do
312
+ test_app do |app|
313
+ get_window_rect(app.handle).should == TEST_WIN_RECT
314
+ end
315
+ end
316
+ end
317
+
318
+ describe '#show_window' do
319
+ spec{ use{ was_visible = ShowWindow(handle = any_handle, cmd = SW_SHOW) }}
320
+ spec{ use{ was_visible = show_window(handle = any_handle) }}
321
+
322
+ it 'defaults to SW_SHOW if no command given' do
323
+ test_app do |app|
324
+ hide_window(app.handle)
325
+ use{show_window(app.handle)}
326
+ visible?(app.handle).should == true
327
+ end
328
+ end
329
+
330
+ it 'returns true if the window was PREVIOUSLY visible, false otherwise' do
331
+ test_app do |app|
332
+ show_window(app.handle, SW_HIDE).should == true
333
+ show_window(app.handle, SW_HIDE).should == false
334
+ end
335
+ end
336
+
337
+ it 'hides window with SW_HIDE command ' do
338
+ test_app do |app|
339
+ show_window(app.handle, SW_HIDE)
340
+ visible?(app.handle).should == false
341
+ end
342
+ end
343
+
344
+ it 'shows hidden window with SW_SHOW command' do
345
+ test_app do |app|
346
+ hide_window(app.handle)
347
+ show_window(app.handle, SW_SHOW)
348
+ visible?(app.handle).should == true
349
+ end
350
+ end
351
+
352
+ it 'SW_MAXIMIZE, SW_SHOWMAXIMIZED maximize window and activate it' do
353
+ commands_should_show_window SW_MAXIMIZE, SW_SHOWMAXIMIZED,
354
+ :minimized? => false, :maximized? => true, :visible? => true, :foreground? => true
355
+ end
356
+
357
+ it 'SW_MINIMIZE minimizes window and activates the next top-level window in the Z order' do
358
+ commands_should_show_window SW_MINIMIZE,
359
+ :minimized? => true, :maximized? => false, :visible? => true, :foreground? => false
360
+ end
361
+
362
+ it 'SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED displays the window as a minimized foreground window' do
363
+ commands_should_show_window SW_SHOWMINNOACTIVE, SW_SHOWMINIMIZED, #!
364
+ :minimized? => true, :maximized? => false, :visible? => true, :foreground? => true
365
+ end
366
+
367
+ it 'SW_SHOWNORMAL, SW_RESTORE, SW_SHOWNOACTIVATE activate/display a window(if min/maximized it is restored' do
368
+ commands_should_show_window SW_SHOWNORMAL, SW_RESTORE, SW_SHOWNOACTIVATE,
369
+ :minimized? => false, :maximized? => false, :visible? => true, :foreground? => true
370
+ end
371
+
372
+ # what about SW_SHOWNA, SW_SHOWDEFAULT, SW_FORCEMINIMIZE ?
373
+ end
374
+
375
+ describe '#close_window' do
376
+ spec{ use{ success = CloseWindow(handle = any_handle) }}
377
+ spec{ use{ success = close_window(handle = any_handle) }}
378
+
379
+ it 'minimizes (but does not destroy!) the specified window' do
380
+ test_app do |app|
381
+ close_window(app.handle).should == true
382
+ window_should_be app.handle,
383
+ :minimized? => true, :maximized? => false, :visible? => true, :foreground? => true
384
+ end
385
+ end
386
+ end
387
+
388
+ describe 'destroy_window' do
389
+ spec{ use{ success = DestroyWindow(handle = 0) }}
390
+ spec{ use{ success = destroy_window(handle = 0) }}
391
+
392
+ it 'destroys window created by current thread'
393
+
394
+ it 'cannot destroy window created by other thread' do
395
+ test_app do |app|
396
+ destroy_window(app.handle).should == false
397
+ window?(app.handle).should == true
398
+ end
399
+ end
400
+ end # describe 'destroy_window'
401
+
402
+ end # context 'ensuring test app closes'
403
+
404
+ context 'with single test app' do
405
+ before(:all){@app = launch_test_app}
406
+ after(:all){close_test_app}
407
+
408
+ describe '#enum_windows' do
409
+ # before(:each){@app = launch_test_app}
410
+ # after(:each){close_test_app}
411
+
412
+ spec{ use{ handles = enum_windows(value = 13) }}
413
+ spec{ use{ enum_windows do |handle, message|
414
+ end }}
415
+
416
+ it 'iterates through all the top-level windows, passing each top level window handle and value to a given block' do
417
+ enum_windows(13) do |handle, message|
418
+ handle.should be_an Integer
419
+ handle.should be > 0
420
+ message.should == 13
421
+ end
422
+ end
423
+
424
+ it 'returns an array of top-level window handles if block is not given' do
425
+ enum = enum_windows(13)
426
+ # p enum
427
+ enum.should be_a_kind_of Array
428
+ enum.should_not be_empty
429
+ enum.should have_at_least(5).elements # typical number of top windows in WinXP system?
430
+ enum.each do |handle|
431
+ handle.should be_an Integer
432
+ handle.should be > 0
433
+ end
434
+ enum.any?{|handle| handle == @app.handle}.should == true
435
+ end
436
+
437
+ it 'returned array that contains handle of launched test app' do
438
+ enum = enum_windows(13)
439
+ enum.any?{|handle| handle == @app.handle}.should == true
440
+ end
441
+
442
+ it 'defaults message to 0 if it is omitted from method call' do
443
+ enum_windows do |handle, message|
444
+ message.should == 0
445
+ end
446
+ end
447
+ end
448
+
449
+ describe '#enum_desktop_windows' do
450
+ spec{ use{ handles = enum_desktop_windows(0, value = 13) }}
451
+ spec{ use{ enum_desktop_windows(0) {|handle, message|} }}
452
+
453
+ it 'iterates through all the top-level windows for a given desktop'
454
+ end
455
+
456
+ describe '#enum_child_windows' do
457
+ spec{ use{ enum_child_windows(parent = any_handle, value = 13) }}
458
+
459
+ it 'return an array of child window handles if block is not given' do
460
+ enum = enum_child_windows(@app.handle, 13)
461
+ enum.should be_a_kind_of Array
462
+ enum.should have(2).elements
463
+ class_name(enum.first).should == TEST_STATUSBAR_CLASS
464
+ class_name(enum.last).should == TEST_TEXTAREA_CLASS
465
+ end
466
+
467
+ it 'loops through all children of given window, passing each found window handle and a message to a given block' do
468
+ enum = []
469
+ enum_child_windows(@app.handle, 13) do |handle, message|
470
+ enum << handle
471
+ message.should == 13
472
+ end
473
+ enum.should have(2).elements
474
+ class_name(enum.first).should == TEST_STATUSBAR_CLASS
475
+ class_name(enum.last).should == TEST_TEXTAREA_CLASS
476
+ end
477
+
478
+ it 'breaks loop if given block returns false' do
479
+ enum = []
480
+ enum_child_windows(@app.handle) do |handle, message|
481
+ enum << handle
482
+ false
483
+ end
484
+ enum.should have(1).element
485
+ class_name(enum.first).should == TEST_STATUSBAR_CLASS
486
+ end
487
+
488
+ it 'defaults message to 0 if it is omitted from method call' do
489
+ enum_child_windows(@app.handle) do |handle, message|
490
+ message.should == 0
491
+ end
492
+ end
493
+ end
494
+
495
+ end # context 'with single test app'
496
+ end # Win::Gui::Window, ' defines a set user32 API functions related to Window manipulation'
497
+
498
+ describe Win::Gui::Window, ' defines convenience/service methods on top of Windows API' do
499
+ after(:each){close_test_app if @launched_test_app}
500
+
501
+ describe '#foreground?' do
502
+ spec{ use{ foreground?( any_handle) }}
503
+
504
+ it 'tests if the given window is foreground' do
505
+ foreground?(foreground_window).should == true
506
+ foreground?(any_handle).should == false
507
+ end
508
+ end
509
+
510
+ describe '#hide_window' do
511
+ spec{ use{ was_visible = hide_window(any_handle) }}
512
+
513
+ it 'hides window: same as show_window(handle, SW_HIDE)' do
514
+ test_app do |app|
515
+ was_visible = hide_window(app.handle)
516
+ was_visible.should == true #!
517
+ visible?(app.handle).should == false
518
+ hide_window(app.handle).should == false
519
+ visible?(app.handle).should == false
520
+ end
521
+ end
522
+ end
523
+
524
+ describe '#shut_window' do
525
+ spec{ use{ success = shut_window(handle=0) }}
526
+
527
+ it 'destroys window in another thread by sending WM_SYSCOMMAND, SC_CLOSE message to it' do
528
+ app = launch_test_app
529
+
530
+ shut_window(app.handle).should == true
531
+ sleep TEST_SLEEP_DELAY
532
+
533
+ window?(app.handle).should == false
534
+ end
535
+ end
536
+
537
+ describe '#text' do
538
+ spec{ use{ text = text(any_handle) }}
539
+
540
+ it 'returns text associated with window by sending WM_GETTEXT message to it' do
541
+ test_app do |app|
542
+
543
+ text(app.handle).should == TEST_WIN_TITLE
544
+ text(app.textarea).should =~ /Welcome to Steganos LockNote/
545
+ end
546
+ end
547
+ end # describe '#text'
548
+ end # Win::Gui::Window, ' defines convenience/service methods on top of Windows API'
549
+ end