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.
- data/.document +5 -5
- data/.gitignore +21 -21
- data/LICENSE +20 -20
- data/README.rdoc +175 -175
- data/Rakefile +58 -58
- data/VERSION +1 -1
- data/features/support/env.rb +4 -4
- data/features/win.feature +9 -9
- data/lib/win/dde.rb +1234 -1234
- data/lib/win/error.rb +1223 -1223
- data/lib/win/extensions.rb +41 -41
- data/lib/win/gui.rb +16 -16
- data/lib/win/gui/dialog.rb +50 -50
- data/lib/win/gui/input.rb +319 -319
- data/lib/win/gui/message.rb +807 -807
- data/lib/win/gui/window.rb +679 -679
- data/lib/win/library.rb +463 -463
- data/spec/spec.opts +2 -2
- data/spec/spec_helper.rb +140 -135
- data/spec/test_apps/locknote/LockNote.exe +0 -0
- data/spec/win/dde_spec.rb +528 -528
- data/spec/win/error_spec.rb +112 -112
- data/spec/win/extensions_spec.rb +73 -73
- data/spec/win/gui/dialog_spec.rb +43 -43
- data/spec/win/gui/input_spec.rb +101 -101
- data/spec/win/gui/message_spec.rb +236 -236
- data/spec/win/gui/window_spec.rb +549 -548
- data/spec/win/library_spec.rb +341 -341
- data/win.gemspec +87 -87
- metadata +34 -17
data/spec/win/gui/window_spec.rb
CHANGED
@@ -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::
|
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::
|
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(:
|
410
|
-
after(:
|
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
|
427
|
-
enum.
|
428
|
-
enum.
|
429
|
-
enum.
|
430
|
-
|
431
|
-
handle.should
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
enum
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
spec{ use{ enum_desktop_windows(0
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
enum.
|
461
|
-
enum.should
|
462
|
-
|
463
|
-
class_name(enum.
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
class_name(enum.
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
foreground?(
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
was_visible
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
text(app.
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
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
|