win 0.1.27 → 0.3.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.
@@ -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