win_gui 0.2.10 → 0.2.12
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/HISTORY +8 -0
- data/VERSION +1 -1
- data/lib/win_gui/application.rb +82 -0
- data/lib/win_gui/convenience.rb +1 -1
- data/lib/win_gui/window.rb +6 -5
- data/lib/win_gui.rb +5 -0
- data/spec/spec_helper.rb +4 -16
- data/spec/win_gui/application_spec.rb +105 -0
- data/spec/win_gui/convenience_spec.rb +6 -4
- data/spec/win_gui/window_spec.rb +55 -64
- metadata +18 -4
data/HISTORY
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.12
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module WinGui
|
2
|
+
|
3
|
+
# This class is a wrapper around Windows App
|
4
|
+
class App
|
5
|
+
LAUNCH_TIMEOUT = 0.2
|
6
|
+
|
7
|
+
attr_accessor :main_window # Main App window (top level)
|
8
|
+
|
9
|
+
def initialize(window_or_handle)
|
10
|
+
@main_window = case window_or_handle
|
11
|
+
when Window
|
12
|
+
window_or_handle
|
13
|
+
when Integer
|
14
|
+
Window.new window_or_handle
|
15
|
+
else
|
16
|
+
raise WinGui::Errors::InitError, "Unable to create App from #{window_or_handle.inspect}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def close
|
21
|
+
@main_window.close
|
22
|
+
end
|
23
|
+
alias_method :exit, :close
|
24
|
+
|
25
|
+
class << self
|
26
|
+
# Finds already launched Application. Either title or class for main window is obligatory.
|
27
|
+
# Returns nil if no such Application found.
|
28
|
+
# Options:
|
29
|
+
# :title:: main window title
|
30
|
+
# :class:: main window class
|
31
|
+
# :timeout:: timeout (seconds) finding main window
|
32
|
+
# :raise:: raise this exception instead of returning nil if nothing found
|
33
|
+
#
|
34
|
+
def find(opts)
|
35
|
+
main_window = Window.top_level(opts)
|
36
|
+
# raise WinGui::Errors::InitError, "Unable to find App with #{opts.inspect}" unless main_window
|
37
|
+
main_window ? new(main_window) : nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# Launch new Application. Expects executable path and options to find main Window.
|
41
|
+
# Options:
|
42
|
+
# :path/:app_path:: path to App's executable file
|
43
|
+
# :dir/:cd:: change to this dir before launching App
|
44
|
+
# :title:: main window title
|
45
|
+
# :class:: main window class
|
46
|
+
# :timeout:: timeout (seconds) finding main window
|
47
|
+
# :raise:: raise this exception instead of returning nil if launched app window not found
|
48
|
+
#
|
49
|
+
def launch(opts)
|
50
|
+
app_path = opts.delete(:path) || opts.delete(:app_path)
|
51
|
+
dir_path = opts.delete(:dir) || opts.delete(:cd)
|
52
|
+
|
53
|
+
launch_app app_path, dir_path
|
54
|
+
|
55
|
+
defaults = {timeout: LAUNCH_TIMEOUT,
|
56
|
+
raise: WinGui::Errors::InitError.new("Unable to launch App with #{opts.inspect}")}
|
57
|
+
find(defaults.merge opts)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def cygwin?
|
63
|
+
RUBY_PLATFORM =~ /cygwin/
|
64
|
+
end
|
65
|
+
|
66
|
+
def launch_app(app_path, dir_path)
|
67
|
+
|
68
|
+
raise WinGui::Errors::InitError, "Unable to launch #{app_path.inspect}" unless File.exists? app_path.to_s
|
69
|
+
command = cygwin? ? "cmd /c start `cygpath -w #{app_path}`" : "start #{app_path.to_s.gsub(/\//, "\\")}"
|
70
|
+
|
71
|
+
if dir_path
|
72
|
+
raise WinGui::Errors::InitError, "Unable to change to #{dir_path.inspect}" unless File.exists? dir_path.to_s
|
73
|
+
command = "cd #{cygwin? ? dir_path : dir_path.to_s.gsub(/\//, "\\")} && #{command}"
|
74
|
+
end
|
75
|
+
|
76
|
+
# Launch App in a separate window
|
77
|
+
system command # TODO: make sure only valid commands are fed into system
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/win_gui/convenience.rb
CHANGED
@@ -25,7 +25,7 @@ module WinGui
|
|
25
25
|
|
26
26
|
# Finds top-level dialog window by title and yields found dialog window to attached block.
|
27
27
|
# We work with dialog window in a block, and then we wait for it to close before proceeding.
|
28
|
-
# That is, unless your block returns nil, in which case dialog is ignored and method immediately returns nil.
|
28
|
+
# That is, unless your block returns nil, in which case dialog is ignored (and method immediately returns nil?).
|
29
29
|
# If no block is given, method just returns found dialog window (or nil if dialog is not found).
|
30
30
|
# Options:
|
31
31
|
# :title:: dialog title
|
data/lib/win_gui/window.rb
CHANGED
@@ -41,7 +41,8 @@ module WinGui
|
|
41
41
|
lookup_window(opts) { WinGui.find_window opts[:class], opts[:title] }
|
42
42
|
end
|
43
43
|
|
44
|
-
# Finds
|
44
|
+
# Finds child window (control) by either control ID or window class/title.
|
45
|
+
# By default, only direct children are searched.
|
45
46
|
# Options:
|
46
47
|
# :id:: integer control id (such as IDOK, IDCANCEL, etc)
|
47
48
|
# :title:: window title
|
@@ -158,13 +159,13 @@ module WinGui
|
|
158
159
|
# window.visible?
|
159
160
|
# This API is much more Ruby-like compared to:
|
160
161
|
# visible?(window.handle)
|
161
|
-
# Of course, if we
|
162
|
+
# Of course, if we invoke WinGui function that DOESN'T accept handle as a first arg this way, we are screwed.
|
162
163
|
# Call such functions only like this:
|
163
164
|
# WinGui.function(*args)
|
164
165
|
# TODO: Such setup is problematic if WinGui is included into Window ancestor chain.
|
165
|
-
# TODO:
|
166
|
-
# TODO:
|
167
|
-
# TODO: instead of showing off cool meta-programming skillz.
|
166
|
+
# TODO: In this case, all WinGui functions become available as instance methods, and method_missing never fires.
|
167
|
+
# TODO: It may be a better solution to explicitly define all needed instance methods,
|
168
|
+
# TODO: instead of showing off cool meta-programming skillz. ;-)
|
168
169
|
#
|
169
170
|
def method_missing(name, *args, &block)
|
170
171
|
if WinGui.respond_to? name
|
data/lib/win_gui.rb
CHANGED
@@ -18,6 +18,11 @@ module WinGui
|
|
18
18
|
Pathname.glob(name.to_s).sort.each {|rb| require rb}
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
module Errors # :nodoc:
|
23
|
+
class InitError < RuntimeError # :nodoc:
|
24
|
+
end
|
25
|
+
end
|
21
26
|
end # module WinGui
|
22
27
|
|
23
28
|
# Require all ruby source files located under directory lib/win_gui
|
data/spec/spec_helper.rb
CHANGED
@@ -30,14 +30,9 @@ module WinGuiTest
|
|
30
30
|
KEY_DELAY = 0.001
|
31
31
|
SLEEP_DELAY = 0.01
|
32
32
|
APP_PATH = File.join(File.dirname(__FILE__), "../misc/locknote/LockNote.exe" )
|
33
|
-
APP_START = RUBY_PLATFORM =~ /cygwin/ ? "cmd /c start `cygpath -w #{APP_PATH}`" : "start #{APP_PATH}"
|
34
|
-
# 'start "" "' + APP_PATH + '"'
|
35
33
|
DIALOG_TITLE = "Save As"
|
36
34
|
WIN_TITLE = 'LockNote - Steganos LockNote'
|
37
35
|
WIN_CLASS = 'ATL:00434098'
|
38
|
-
WIN_RECT = [710, 400, 1210, 800]
|
39
|
-
MAX_RECT = [-4, -4, 1924, 1204] # on my 1920x1200 display
|
40
|
-
MIN_RECT = [-32000, -32000, -31840, -31976]
|
41
36
|
TEXTAREA_CLASS = 'ATL:00434310'
|
42
37
|
STATUSBAR_CLASS = 'msctls_statusbar32'
|
43
38
|
IMPOSSIBLE = 'Impossible'
|
@@ -61,18 +56,12 @@ module WinGuiTest
|
|
61
56
|
end
|
62
57
|
|
63
58
|
def launch_test_app
|
64
|
-
system APP_START
|
65
|
-
@test_app =
|
66
|
-
|
67
|
-
def @test_app.textarea #define singleton method retrieving app's text area
|
68
|
-
Window.new WinGui::find_window_ex(self.handle, 0, TEXTAREA_CLASS, nil)
|
69
|
-
end
|
70
|
-
|
71
|
-
@test_app
|
59
|
+
#system APP_START
|
60
|
+
@test_app = App.launch( path: APP_PATH, title: WIN_TITLE, timeout: 1)
|
72
61
|
end
|
73
62
|
|
74
63
|
def close_test_app
|
75
|
-
|
64
|
+
while @test_app && @test_app.main_window.window?
|
76
65
|
@test_app.close
|
77
66
|
# Dealing with closing confirmation modal dialog
|
78
67
|
if dialog = dialog( title: "Steganos Locknote", timeout: SLEEP_DELAY)
|
@@ -85,8 +74,7 @@ module WinGuiTest
|
|
85
74
|
|
86
75
|
# Creates test app object and yields it back to the block
|
87
76
|
def test_app
|
88
|
-
|
89
|
-
yield test_app
|
77
|
+
yield launch_test_app
|
90
78
|
close_test_app
|
91
79
|
end
|
92
80
|
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper" )
|
2
|
+
|
3
|
+
module WinGuiTest
|
4
|
+
|
5
|
+
describe App do
|
6
|
+
after(:each) do # Reliably closes launched app window (without calling close_test_app)
|
7
|
+
app = App.find(title: WIN_TITLE)
|
8
|
+
app.exit if app
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'initializing' do
|
12
|
+
context '::new' do
|
13
|
+
before(:each) { launch_test_app }
|
14
|
+
after(:each){ close_test_app }
|
15
|
+
|
16
|
+
it 'wraps new App around existing Window' do
|
17
|
+
window = Window.top_level(title: WIN_TITLE)
|
18
|
+
@app = App.new(window)
|
19
|
+
@app.should be_an App
|
20
|
+
@app.main_window.should == window
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'wraps new App around active window handle (of top-level Window)' do
|
24
|
+
window = Window.top_level(title: WIN_TITLE)
|
25
|
+
@app = App.new(window.handle)
|
26
|
+
@app.should be_an App
|
27
|
+
@app.main_window.handle.should == window.handle
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'raises error trying to create App with wrong init args' do
|
31
|
+
expect{ App.new() }.to raise_error ArgumentError, /wrong number of arguments/
|
32
|
+
[[nil], 1.2, {title: WIN_TITLE}].each do |args|
|
33
|
+
expect{ App.new(*args) }.to raise_error WinGui::Errors::InitError
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context '::find' do
|
39
|
+
before(:each) { launch_test_app }
|
40
|
+
after(:each){ close_test_app }
|
41
|
+
|
42
|
+
it 'finds already launched App given valid Window info' do
|
43
|
+
use{ @app = App.find(title: WIN_TITLE) }
|
44
|
+
@app.should be_an App
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'returns nil if asked to find App with invalid Window info' do
|
48
|
+
App.find(title: IMPOSSIBLE).should == nil
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'raises error only if asked to find App with invalid Window info and :raise option is set' do
|
52
|
+
expect{ App.find(title: IMPOSSIBLE, raise: WinGui::Errors::InitError) }.
|
53
|
+
to raise_error WinGui::Errors::InitError
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context '::launch' do
|
58
|
+
|
59
|
+
it 'launches new App given valid path and Window info' do
|
60
|
+
use{ @app = App.launch(path: APP_PATH, title: WIN_TITLE) }
|
61
|
+
@app.should be_an App
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'raises error if asked to launch App with invalid path' do
|
65
|
+
expect{ App.launch(path: IMPOSSIBLE, title: WIN_TITLE) }.
|
66
|
+
to raise_error WinGui::Errors::InitError, /Unable to launch "Impossible"/
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'raises error if asked to launch App with invalid Window info' do
|
70
|
+
expect{ App.launch(path: APP_PATH, title: IMPOSSIBLE) }.
|
71
|
+
to raise_error WinGui::Errors::InitError, /Unable to launch App with .*?:title=>"Impossible"/
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'properties:' do
|
77
|
+
before(:each) { @app = App.launch(path: APP_PATH, title: WIN_TITLE) }
|
78
|
+
after(:each) { @app.close }
|
79
|
+
|
80
|
+
it 'main_window' do
|
81
|
+
@app.main_window.should be_a Window
|
82
|
+
@app.main_window.title.should == WIN_TITLE
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'manipulating' do
|
88
|
+
before(:each) {@app = App.launch(path: APP_PATH, title: WIN_TITLE)}
|
89
|
+
|
90
|
+
it 'exits App gracefully' do
|
91
|
+
@app.exit
|
92
|
+
sleep SLEEP_DELAY # needed to ensure window had enough time to close down
|
93
|
+
@app.main_window.visible?.should == false
|
94
|
+
@app.main_window.window?.should == false
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'closes App gracefully' do
|
98
|
+
@app.close
|
99
|
+
sleep SLEEP_DELAY # needed to ensure window had enough time to close down
|
100
|
+
@app.main_window.visible?.should == false
|
101
|
+
@app.main_window.window?.should == false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), "..", "spec_helper" )
|
|
3
3
|
module WinGuiTest
|
4
4
|
|
5
5
|
describe 'Convenience methods' do
|
6
|
-
before(:each){ @
|
6
|
+
before(:each){ @win = launch_test_app.main_window }
|
7
7
|
after(:each) { close_test_app }
|
8
8
|
|
9
9
|
describe '#dialog' do
|
@@ -54,9 +54,10 @@ module WinGuiTest
|
|
54
54
|
it 'emulates combinations of keys pressed (Ctrl+Alt+P+M, etc)' do
|
55
55
|
keystroke(VK_CONTROL, 'A')
|
56
56
|
keystroke(VK_SPACE)
|
57
|
-
|
57
|
+
textarea = @win.child(class: TEXTAREA_CLASS)
|
58
|
+
textarea.text.should.should == ' '
|
58
59
|
keystroke('1', '2', 'A', 'B'.ord)
|
59
|
-
|
60
|
+
textarea.text.should.should == ' 12ab'
|
60
61
|
end
|
61
62
|
end # describe '#keystroke'
|
62
63
|
|
@@ -64,7 +65,8 @@ module WinGuiTest
|
|
64
65
|
it 'types text message into the window holding the focus' do
|
65
66
|
text = '1234 abcdefg'
|
66
67
|
type_in(text)
|
67
|
-
|
68
|
+
textarea = @win.child(class: TEXTAREA_CLASS)
|
69
|
+
textarea.text.should =~ Regexp.new(text)
|
68
70
|
end
|
69
71
|
end # describe '#type_in'
|
70
72
|
|
data/spec/win_gui/window_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), "..", "spec_helper" )
|
|
3
3
|
module WinGuiTest
|
4
4
|
|
5
5
|
describe Window do
|
6
|
-
before(:each) { @
|
6
|
+
before(:each) { @win = launch_test_app.main_window }
|
7
7
|
after(:each){ close_test_app }
|
8
8
|
|
9
9
|
context 'initializing' do
|
@@ -15,33 +15,33 @@ module WinGuiTest
|
|
15
15
|
|
16
16
|
context 'manipulating' do
|
17
17
|
it 'closes when asked nicely' do
|
18
|
-
@
|
18
|
+
@win.close
|
19
19
|
sleep SLEEP_DELAY # needed to ensure window had enough time to close down
|
20
20
|
find_window(nil, WIN_TITLE).should == nil
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'waits for window to disappear (NB: this happens before handle is released!)' do
|
24
24
|
start = Time.now
|
25
|
-
@
|
26
|
-
@
|
25
|
+
@win.close
|
26
|
+
@win.wait_for_close
|
27
27
|
(Time.now - start).should be <= CLOSE_TIMEOUT
|
28
|
-
window_visible?(@
|
29
|
-
window?(@
|
28
|
+
window_visible?(@win.handle).should be false
|
29
|
+
window?(@win.handle).should be false
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
33
|
context 'handle-related WinGui functions as instance methods' do
|
34
34
|
it 'calls all WinGui functions as instance methods (with handle as implicit first argument)' do
|
35
|
-
@
|
36
|
-
@
|
37
|
-
@
|
38
|
-
@
|
39
|
-
@
|
40
|
-
@
|
41
|
-
|
42
|
-
@
|
43
|
-
@
|
44
|
-
@
|
35
|
+
@win.window?.should == true
|
36
|
+
@win.visible?.should == true
|
37
|
+
@win.foreground?.should == true
|
38
|
+
@win.maximized?.should == false
|
39
|
+
@win.minimized?.should == false
|
40
|
+
@win.child?(any_handle).should == false
|
41
|
+
|
42
|
+
@win.window_rect.should be_an Array
|
43
|
+
@win.window_thread_process_id.should be_an Array
|
44
|
+
@win.enum_child_windows.should be_an Array
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -52,52 +52,52 @@ module WinGuiTest
|
|
52
52
|
end
|
53
53
|
|
54
54
|
it 'has class_name and text/title properties (derived from WinGui function calls)' do
|
55
|
-
@
|
55
|
+
@win.class_name.should == WIN_CLASS
|
56
56
|
# text propery accessed by sending WM_GETTEXT directly to window (convenience method in WinGui)
|
57
|
-
@
|
57
|
+
@win.text.should == WIN_TITLE
|
58
58
|
# window_text propery accessed via GetWindowText
|
59
|
-
@
|
59
|
+
@win.window_text.should == WIN_TITLE
|
60
60
|
# title property is just an alias for window_text
|
61
|
-
@
|
61
|
+
@win.title.should == WIN_TITLE
|
62
62
|
end
|
63
63
|
|
64
64
|
it 'has thread and process properties derived from get_window_thread_process_id' do
|
65
|
-
thread = @
|
66
|
-
process = @
|
67
|
-
[thread, process].should == get_window_thread_process_id(@
|
65
|
+
thread = @win.thread
|
66
|
+
process = @win.process
|
67
|
+
[thread, process].should == get_window_thread_process_id(@win.handle)
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'has id property that only makes sense for controls' do
|
71
|
-
use{ @
|
71
|
+
use{ @win.id }
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
describe '
|
75
|
+
describe '::top_level' do
|
76
76
|
it 'finds top-level window by title and wraps it in a Window object' do
|
77
|
-
|
78
|
-
|
77
|
+
window = Window.top_level( title: WIN_TITLE, timeout: 1)
|
78
|
+
window.handle.should == @win.handle
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'finds top-level window by class and wraps it in a Window object' do
|
82
|
-
|
83
|
-
|
82
|
+
window = Window.top_level( class: WIN_CLASS, timeout: 1)
|
83
|
+
window.handle.should == @win.handle
|
84
84
|
end
|
85
85
|
|
86
86
|
it 'finds ANY top-level window without args and wraps it in a Window object' do
|
87
|
-
use { @
|
88
|
-
|
87
|
+
use { @window = Window.top_level() }
|
88
|
+
@window.should be_a Window
|
89
89
|
end
|
90
90
|
|
91
91
|
it 'returns nil immediately if top-level window with given title not found' do
|
92
92
|
start = Time.now
|
93
93
|
Window.top_level( title: IMPOSSIBLE).should == nil
|
94
|
-
(Time.now - start).should be_close 0, 0.
|
94
|
+
(Time.now - start).should be_close 0, 0.03
|
95
95
|
end
|
96
96
|
|
97
97
|
it 'returns nil after timeout if top-level window with given title not found' do
|
98
98
|
start = Time.now
|
99
|
-
Window.top_level( title: IMPOSSIBLE, timeout: 0.
|
100
|
-
(Time.now - start).should be_close 0.
|
99
|
+
Window.top_level( title: IMPOSSIBLE, timeout: 0.3).should == nil
|
100
|
+
(Time.now - start).should be_close 0.3, 0.03
|
101
101
|
end
|
102
102
|
|
103
103
|
it 'raises exception if asked to' do
|
@@ -106,42 +106,40 @@ module WinGuiTest
|
|
106
106
|
end # describe .top_level
|
107
107
|
|
108
108
|
describe '#child' do
|
109
|
-
spec { use { @child = @
|
109
|
+
spec { use { @child = @win.child(title: "Title", class: "Class", id: 0) }}
|
110
110
|
|
111
111
|
it 'returns nil immediately if specific child not found' do
|
112
112
|
start = Time.now
|
113
|
-
@
|
114
|
-
(Time.now - start).should be_close 0, 0.
|
113
|
+
@win.child( title: IMPOSSIBLE).should == nil
|
114
|
+
(Time.now - start).should be_close 0, 0.03
|
115
115
|
end
|
116
116
|
|
117
117
|
it 'returns nil after timeout if specific child not found' do
|
118
118
|
start = Time.now
|
119
|
-
@
|
120
|
-
(Time.now - start).should be_close 0.5, 0.
|
119
|
+
@win.child( title: IMPOSSIBLE, timeout: 0.5).should == nil
|
120
|
+
(Time.now - start).should be_close 0.5, 0.03
|
121
121
|
end
|
122
122
|
|
123
123
|
it 'finds ANY child window without args' do
|
124
|
-
use { @child = @
|
124
|
+
use { @child = @win.child() }
|
125
125
|
@child.should_not == nil
|
126
|
-
@
|
126
|
+
@win.child?(@child.handle).should == true
|
127
127
|
end
|
128
128
|
|
129
129
|
it 'finds child window by class and returns it as a Window object (no timeout)' do
|
130
|
-
child = @
|
130
|
+
child = @win.child( class: TEXTAREA_CLASS)
|
131
131
|
child.should_not == nil
|
132
|
-
@
|
132
|
+
@win.child?(child.handle).should == true
|
133
133
|
end
|
134
134
|
|
135
135
|
it 'finds child window by class and returns it as a Window object (with timeout)' do
|
136
|
-
|
137
|
-
# p @app.find_window_ex(0, STATUSBAR_CLASS, nil)
|
138
|
-
child = @app.child( class: TEXTAREA_CLASS, timeout: 0.5)
|
136
|
+
child = @win.child( class: TEXTAREA_CLASS, timeout: 0.5)
|
139
137
|
child.should_not == nil
|
140
138
|
|
141
|
-
@
|
142
|
-
child = @
|
139
|
+
@win.child?(child.handle).should == true
|
140
|
+
child = @win.child( class: STATUSBAR_CLASS, timeout: 0.5)
|
143
141
|
child.should_not == nil
|
144
|
-
@
|
142
|
+
@win.child?(child.handle).should == true
|
145
143
|
end
|
146
144
|
|
147
145
|
it 'finds child with specific text and returns it as a Window object' do
|
@@ -169,19 +167,19 @@ module WinGuiTest
|
|
169
167
|
|
170
168
|
context 'indirect child' do
|
171
169
|
it 'returns nil if specified child not found' do
|
172
|
-
@
|
170
|
+
@win.child( title: IMPOSSIBLE, indirect: true).should == nil
|
173
171
|
end
|
174
172
|
|
175
173
|
it 'finds ANY child window without other args' do
|
176
|
-
use { @child = @
|
174
|
+
use { @child = @win.child(indirect: true) }
|
177
175
|
@child.should_not == nil
|
178
|
-
@
|
176
|
+
@win.child?(@child.handle).should == true
|
179
177
|
end
|
180
178
|
|
181
179
|
it 'finds child window by class' do
|
182
|
-
child = @
|
180
|
+
child = @win.child( class: TEXTAREA_CLASS, indirect: true)
|
183
181
|
child.should_not == nil
|
184
|
-
@
|
182
|
+
@win.child?(child.handle).should == true
|
185
183
|
end
|
186
184
|
|
187
185
|
it 'finds child with specific text' do
|
@@ -210,26 +208,19 @@ module WinGuiTest
|
|
210
208
|
end # describe child
|
211
209
|
|
212
210
|
describe '#children' do
|
213
|
-
spec { use { children = @
|
211
|
+
spec { use { children = @win.children }}
|
214
212
|
|
215
213
|
it 'returns an array of Windows that are descendants (not only DIRECT children) of a given Window' do
|
216
|
-
children = @
|
214
|
+
children = @win.children
|
217
215
|
children.should be_a_kind_of Array
|
218
216
|
children.should_not be_empty
|
219
217
|
children.should have(2).elements
|
220
|
-
children.each{|child| child?(@
|
218
|
+
children.each{|child| child?(@win.handle, child.handle).should == true }
|
221
219
|
children.last.class_name.should == TEXTAREA_CLASS
|
222
220
|
end
|
223
221
|
end # describe #children
|
224
222
|
|
225
223
|
describe '#click' do
|
226
|
-
# it 'tests' do
|
227
|
-
# with_dialog(:save) do |dialog|
|
228
|
-
# dialog.children.each{|child| puts "#{child.handle}, #{child.class_name}, #{child.window_text}, #{dialog.child?(child.handle)}"}
|
229
|
-
# true.should == false
|
230
|
-
# end
|
231
|
-
# end
|
232
|
-
|
233
224
|
it 'emulates left click of the control identified by id, returns click coords' do
|
234
225
|
with_dialog(:save) do |dialog|
|
235
226
|
point = dialog.click(id: IDCANCEL)
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win_gui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
8
|
- 2
|
8
|
-
-
|
9
|
-
version: 0.2.
|
9
|
+
- 12
|
10
|
+
version: 0.2.12
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- arvicco
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-10-02 00:00:00 +04:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: rspec
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 13
|
27
30
|
segments:
|
28
31
|
- 1
|
29
32
|
- 2
|
@@ -35,9 +38,11 @@ dependencies:
|
|
35
38
|
name: cucumber
|
36
39
|
prerelease: false
|
37
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
38
42
|
requirements:
|
39
43
|
- - ">="
|
40
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 3
|
41
46
|
segments:
|
42
47
|
- 0
|
43
48
|
version: "0"
|
@@ -47,9 +52,11 @@ dependencies:
|
|
47
52
|
name: win
|
48
53
|
prerelease: false
|
49
54
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
50
56
|
requirements:
|
51
57
|
- - ">="
|
52
58
|
- !ruby/object:Gem::Version
|
59
|
+
hash: 17
|
53
60
|
segments:
|
54
61
|
- 0
|
55
62
|
- 3
|
@@ -70,12 +77,14 @@ extra_rdoc_files:
|
|
70
77
|
files:
|
71
78
|
- lib/extension.rb
|
72
79
|
- lib/version.rb
|
80
|
+
- lib/win_gui/application.rb
|
73
81
|
- lib/win_gui/convenience.rb
|
74
82
|
- lib/win_gui/window.rb
|
75
83
|
- lib/win_gui.rb
|
76
84
|
- spec/extension_spec.rb
|
77
85
|
- spec/spec.opts
|
78
86
|
- spec/spec_helper.rb
|
87
|
+
- spec/win_gui/application_spec.rb
|
79
88
|
- spec/win_gui/convenience_spec.rb
|
80
89
|
- spec/win_gui/window_spec.rb
|
81
90
|
- features/step_definitions/win_gui_steps.rb
|
@@ -108,23 +117,27 @@ rdoc_options:
|
|
108
117
|
require_paths:
|
109
118
|
- lib
|
110
119
|
required_ruby_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
111
121
|
requirements:
|
112
122
|
- - ">="
|
113
123
|
- !ruby/object:Gem::Version
|
124
|
+
hash: 3
|
114
125
|
segments:
|
115
126
|
- 0
|
116
127
|
version: "0"
|
117
128
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
118
130
|
requirements:
|
119
131
|
- - ">="
|
120
132
|
- !ruby/object:Gem::Version
|
133
|
+
hash: 3
|
121
134
|
segments:
|
122
135
|
- 0
|
123
136
|
version: "0"
|
124
137
|
requirements: []
|
125
138
|
|
126
139
|
rubyforge_project: ""
|
127
|
-
rubygems_version: 1.3.
|
140
|
+
rubygems_version: 1.3.7
|
128
141
|
signing_key:
|
129
142
|
specification_version: 3
|
130
143
|
summary: Abstractions/wrappers around GUI-related Win32 API functions
|
@@ -132,5 +145,6 @@ test_files:
|
|
132
145
|
- spec/extension_spec.rb
|
133
146
|
- spec/spec.opts
|
134
147
|
- spec/spec_helper.rb
|
148
|
+
- spec/win_gui/application_spec.rb
|
135
149
|
- spec/win_gui/convenience_spec.rb
|
136
150
|
- spec/win_gui/window_spec.rb
|