win 0.1.13 → 0.1.16
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/VERSION +1 -1
- data/lib/win/dde.rb +13 -13
- data/lib/win/error.rb +1066 -0
- data/lib/win/extensions.rb +14 -1
- data/lib/win/gui/input.rb +24 -0
- data/lib/win/gui/window.rb +88 -25
- data/lib/win/library.rb +39 -27
- data/spec/spec_helper.rb +19 -9
- data/spec/win/dde_spec.rb +2 -1
- data/spec/win/error_spec.rb +53 -0
- data/spec/win/extensions_spec.rb +12 -2
- data/spec/win/gui/input_spec.rb +7 -7
- data/spec/win/gui/window_spec.rb +414 -348
- data/win.gemspec +5 -5
- metadata +5 -5
- data/lib/win/gui/window/window.rb +0 -88
- data/spec/win/gui/window/window_spec.rb +0 -129
data/spec/win/gui/window_spec.rb
CHANGED
@@ -6,477 +6,543 @@ module WinWindowTest
|
|
6
6
|
include WinTestApp
|
7
7
|
include Win::GUI::Window
|
8
8
|
|
9
|
-
def
|
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)
|
10
14
|
cmds.each do |cmd|
|
11
15
|
test_app do |app|
|
12
16
|
show_window(app.handle, cmd)
|
13
|
-
|
17
|
+
window_should_be app.handle, tests
|
14
18
|
|
15
19
|
hide_window(app.handle) # hiding window first
|
16
20
|
show_window(app.handle, cmd)
|
17
|
-
|
21
|
+
window_should_be app.handle, tests
|
18
22
|
|
19
23
|
show_window(app.handle, SW_MAXIMIZE) # now maximizing window
|
20
24
|
show_window(app.handle, cmd)
|
21
|
-
|
25
|
+
window_should_be app.handle, tests
|
22
26
|
|
23
27
|
show_window(app.handle, SW_MINIMIZE) # now minimizing window
|
24
28
|
show_window(app.handle, cmd)
|
25
|
-
|
29
|
+
window_should_be app.handle, tests
|
26
30
|
end
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
30
34
|
describe Win::GUI::Window, ' defines a set user32 API functions related to Window manipulation' do
|
31
|
-
|
32
|
-
|
33
|
-
spec{ use{ is_window(any_handle) }}
|
34
|
-
spec{ use{ window?(any_handle) }}
|
35
|
+
context 'ensuring test app closes' do
|
36
|
+
after(:each){close_test_app if @launched_test_app}
|
35
37
|
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
describe '#window?' do
|
39
|
+
spec{ use{ IsWindow(any_handle) }}
|
40
|
+
spec{ use{ is_window(any_handle) }}
|
41
|
+
spec{ use{ window?(any_handle) }}
|
39
42
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
+
it 'returns true if window exists' do
|
44
|
+
window?(any_handle).should == true
|
45
|
+
end
|
43
46
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
50
60
|
end
|
51
|
-
window?(@app_handle).should == false
|
52
|
-
window?(@ta_handle).should == false
|
53
61
|
end
|
54
|
-
end
|
55
62
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
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) }}
|
61
68
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
71
79
|
end
|
72
80
|
end
|
73
|
-
end
|
74
81
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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) }}
|
80
87
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
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
|
88
96
|
end
|
89
97
|
end
|
90
|
-
end
|
91
98
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
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) }}
|
97
104
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
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
|
105
113
|
end
|
106
114
|
end
|
107
|
-
end
|
108
115
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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) }}
|
113
120
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
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
|
118
126
|
end
|
119
127
|
end
|
120
|
-
end
|
121
128
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
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) }}
|
128
135
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
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
|
133
140
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
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
|
142
149
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
147
154
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
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
|
154
162
|
end
|
155
163
|
end
|
156
|
-
end
|
157
164
|
|
158
|
-
|
159
|
-
|
160
|
-
|
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) }}
|
161
168
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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
|
167
174
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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
|
173
181
|
end
|
174
|
-
end
|
175
182
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
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
|
184
192
|
end
|
185
193
|
end
|
186
|
-
end
|
187
194
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
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 }}
|
193
200
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
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
|
199
209
|
end
|
200
|
-
fg2 = foreground_window
|
201
|
-
@app_handle.should_not == fg2
|
202
|
-
end
|
203
210
|
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
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
|
208
217
|
end
|
209
|
-
foreground?(@app_handle).should == false
|
210
218
|
end
|
211
|
-
end
|
212
219
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
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 }}
|
218
225
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
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
|
225
235
|
end
|
226
|
-
fg2 = active_window
|
227
|
-
@app_handle.should_not == fg2
|
228
236
|
end
|
229
|
-
end
|
230
237
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
it 'returns nil if incorrect window handle given' do
|
242
|
-
get_window_text(not_a_handle).should == nil
|
243
|
-
get_window_text_w(not_a_handle).should == nil
|
244
|
-
end
|
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)}}
|
245
247
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
get_window_text_w(app.handle).should == TEST_WIN_TITLE
|
250
|
-
window_text(app.handle).should == TEST_WIN_TITLE
|
251
|
-
window_text_w(app.handle).should == TEST_WIN_TITLE
|
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
|
252
251
|
end
|
253
|
-
end
|
254
|
-
end
|
255
252
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
spec{ use{ class_name = get_class_name_w(handle = 0)}} # result encoded as utf-8
|
264
|
-
spec{ use{ class_name = class_name_w(any_handle)}}
|
265
|
-
|
266
|
-
it 'returns correct window class name' do
|
267
|
-
test_app do |app|
|
268
|
-
get_class_name(app.handle).should == TEST_WIN_CLASS
|
269
|
-
class_name(app.handle).should == TEST_WIN_CLASS
|
270
|
-
class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!!!!! nil?
|
271
|
-
get_class_name_w(app.handle).should == TEST_WIN_CLASS #!!!!!! nil?
|
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
|
272
260
|
end
|
273
261
|
end
|
274
|
-
end
|
275
262
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
process.should be_a_kind_of Integer
|
286
|
-
process.should be > 0
|
287
|
-
end
|
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)}}
|
288
272
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
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
|
293
281
|
end
|
294
|
-
end
|
295
282
|
|
296
|
-
|
297
|
-
|
298
|
-
|
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]
|
299
287
|
|
300
|
-
|
301
|
-
|
302
|
-
|
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
|
303
295
|
|
304
|
-
|
305
|
-
|
306
|
-
|
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
|
307
300
|
end
|
308
301
|
end
|
309
|
-
end
|
310
302
|
|
311
|
-
|
312
|
-
|
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)}}
|
313
306
|
|
314
|
-
|
315
|
-
|
316
|
-
hide_window(app.handle)
|
317
|
-
use{show_window(app.handle)}
|
318
|
-
visible?(app.handle).should == true
|
307
|
+
it 'returns array of nils for invalid window' do
|
308
|
+
get_window_rect(not_a_handle).should == [nil, nil, nil, nil]
|
319
309
|
end
|
320
|
-
end
|
321
310
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
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
|
326
315
|
end
|
327
316
|
end
|
328
317
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
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
|
333
328
|
end
|
334
|
-
end
|
335
329
|
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
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
|
341
335
|
end
|
342
|
-
end
|
343
336
|
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
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
|
348
343
|
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
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
|
353
351
|
|
354
|
-
|
355
|
-
|
356
|
-
|
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 ?
|
357
373
|
end
|
358
374
|
|
359
|
-
|
360
|
-
|
361
|
-
|
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
|
362
386
|
end
|
363
387
|
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
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'
|
368
403
|
|
369
|
-
|
404
|
+
context 'with single test app' do
|
370
405
|
before(:all){@app = launch_test_app}
|
371
406
|
after(:all){close_test_app}
|
372
407
|
|
373
|
-
|
374
|
-
|
375
|
-
|
408
|
+
describe '#enum_windows' do
|
409
|
+
before(:all){@app = launch_test_app}
|
410
|
+
after(:all){close_test_app}
|
376
411
|
|
377
|
-
|
378
|
-
enum_windows
|
379
|
-
|
380
|
-
|
381
|
-
|
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
|
382
422
|
end
|
383
|
-
end
|
384
423
|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
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
|
393
434
|
end
|
394
|
-
enum.any?{|handle| handle == @app.handle}.should == true
|
395
|
-
end
|
396
435
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
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
|
401
440
|
|
402
|
-
|
403
|
-
|
404
|
-
|
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
|
405
445
|
end
|
406
446
|
end
|
407
|
-
end
|
408
447
|
|
409
|
-
|
410
|
-
|
411
|
-
|
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|} }}
|
412
451
|
|
413
|
-
|
414
|
-
|
415
|
-
end }}
|
452
|
+
it 'iterates through all the top-level windows for a given desktop'
|
453
|
+
end
|
416
454
|
|
417
|
-
|
418
|
-
|
455
|
+
describe '#enum_child_windows' do
|
456
|
+
spec{ use{ enum_child_windows(parent = any_handle, value = 13) }}
|
419
457
|
|
420
|
-
|
421
|
-
|
422
|
-
|
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
|
423
465
|
|
424
|
-
|
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
|
425
476
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
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
|
433
486
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
message.should == 13
|
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
|
439
491
|
end
|
440
|
-
enum.should have(2).elements
|
441
|
-
class_name(enum.first).should == TEST_STATUSBAR_CLASS
|
442
|
-
class_name(enum.last).should == TEST_TEXTAREA_CLASS
|
443
492
|
end
|
444
493
|
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
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
|
453
506
|
end
|
507
|
+
end
|
508
|
+
|
509
|
+
describe '#hide_window' do
|
510
|
+
spec{ use{ was_visible = hide_window(any_handle) }}
|
454
511
|
|
455
|
-
it '
|
456
|
-
|
457
|
-
|
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
|
458
519
|
end
|
459
520
|
end
|
460
521
|
end
|
461
522
|
|
462
|
-
describe
|
463
|
-
|
464
|
-
|
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
|
465
533
|
end
|
534
|
+
end
|
466
535
|
|
467
|
-
|
468
|
-
|
536
|
+
describe '#text' do
|
537
|
+
spec{ use{ text = text(any_handle) }}
|
469
538
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
hide_window(app.handle).should == false
|
476
|
-
visible?(app.handle).should == false
|
477
|
-
end
|
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/
|
478
544
|
end
|
479
545
|
end
|
480
|
-
end
|
481
|
-
end
|
482
|
-
end
|
546
|
+
end # describe '#text'
|
547
|
+
end # Win::GUI::Window, ' defines convenience/service methods on top of Windows API'
|
548
|
+
end
|