win32-autogui 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitattributes +1 -0
- data/.gitignore +10 -0
- data/.yardopts +6 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +60 -0
- data/HISTORY.markdown +11 -0
- data/LICENSE +20 -0
- data/README.markdown +265 -0
- data/Rakefile +55 -0
- data/TODO.markdown +9 -0
- data/VERSION +1 -0
- data/config/cucumber.yml +7 -0
- data/examples/quicknote/.gitignore +8 -0
- data/examples/quicknote/FormAboutU.dfm +44 -0
- data/examples/quicknote/FormAboutU.pas +36 -0
- data/examples/quicknote/FormMainU.dfm +110 -0
- data/examples/quicknote/FormMainU.pas +268 -0
- data/examples/quicknote/FormSplashU.dfm +32 -0
- data/examples/quicknote/FormSplashU.pas +52 -0
- data/examples/quicknote/LICENSE +20 -0
- data/examples/quicknote/README.markdown +28 -0
- data/examples/quicknote/Rakefile +12 -0
- data/examples/quicknote/TODO.markdown +15 -0
- data/examples/quicknote/dcu/.gitignore +1 -0
- data/examples/quicknote/exe/.gitignore +0 -0
- data/examples/quicknote/exe/quicknote.exe +0 -0
- data/examples/quicknote/lib/quicknote.rb +140 -0
- data/examples/quicknote/quicknote.cfg +37 -0
- data/examples/quicknote/quicknote.dof +158 -0
- data/examples/quicknote/quicknote.dpr +16 -0
- data/examples/quicknote/quicknote.res +0 -0
- data/examples/quicknote/spec/quicknote/form_about_spec.rb +50 -0
- data/examples/quicknote/spec/quicknote/form_main_spec.rb +274 -0
- data/examples/quicknote/spec/quicknote/form_splash_spec.rb +44 -0
- data/examples/quicknote/spec/spec.opts +2 -0
- data/examples/quicknote/spec/spec_helper.rb +34 -0
- data/examples/quicknote/spec/watchr.rb +143 -0
- data/examples/skeleton/.gitignore +8 -0
- data/examples/skeleton/LICENSE +20 -0
- data/examples/skeleton/README.markdown +62 -0
- data/examples/skeleton/Rakefile +21 -0
- data/examples/skeleton/TODO.markdown +9 -0
- data/examples/skeleton/config/cucumber.yml +7 -0
- data/examples/skeleton/dcu/.gitignore +1 -0
- data/examples/skeleton/exe/.gitignore +1 -0
- data/examples/skeleton/features/basic.feature +6 -0
- data/examples/skeleton/features/step_definitions/.gitignore +0 -0
- data/examples/skeleton/features/step_definitions/application_steps.rb +43 -0
- data/examples/skeleton/features/support/env.rb +5 -0
- data/examples/skeleton/lib/myapp.rb +73 -0
- data/examples/skeleton/spec/myapp/form_about_spec.rb +50 -0
- data/examples/skeleton/spec/myapp/form_main_spec.rb +60 -0
- data/examples/skeleton/spec/spec.opts +2 -0
- data/examples/skeleton/spec/spec_helper.rb +29 -0
- data/examples/skeleton/spec/watchr.rb +143 -0
- data/features/automating_an_application.feature +11 -0
- data/features/step_definitions/.gitignore +0 -0
- data/features/step_definitions/calculator_steps.rb +37 -0
- data/features/support/env.rb +4 -0
- data/lib/win32/autogui.rb +27 -0
- data/lib/win32/autogui/application.rb +249 -0
- data/lib/win32/autogui/input.rb +238 -0
- data/lib/win32/autogui/window.rb +191 -0
- data/lib/win32/autogui/windows/window.rb +22 -0
- data/spec/applications/calculator.rb +34 -0
- data/spec/auto_gui/application_spec.rb +132 -0
- data/spec/basic_gem/basic_gem_spec.rb +13 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +31 -0
- data/spec/watchr.rb +144 -0
- data/win32-autogui.gemspec +43 -0
- metadata +329 -0
data/.gitattributes
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.rb diff=ruby
|
data/.gitignore
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
win32-autogui (0.2.0)
|
5
|
+
win32-clipboard (>= 0.5.2)
|
6
|
+
win32-process (>= 0.6.2)
|
7
|
+
windows-api (>= 0.4.0)
|
8
|
+
windows-pr (>= 1.0.9)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: http://rubygems.org/
|
12
|
+
specs:
|
13
|
+
aruba (0.2.3)
|
14
|
+
background_process
|
15
|
+
cucumber (~> 0.9.0)
|
16
|
+
background_process (1.2)
|
17
|
+
builder (2.1.2)
|
18
|
+
cucumber (0.9.3)
|
19
|
+
builder (~> 2.1.2)
|
20
|
+
diff-lcs (~> 1.1.2)
|
21
|
+
gherkin (~> 2.2.9)
|
22
|
+
json (~> 1.4.6)
|
23
|
+
term-ansicolor (~> 1.0.5)
|
24
|
+
diff-lcs (1.1.2)
|
25
|
+
gherkin (2.2.9)
|
26
|
+
json (~> 1.4.6)
|
27
|
+
term-ansicolor (~> 1.0.5)
|
28
|
+
json (1.4.6)
|
29
|
+
rake (0.8.7)
|
30
|
+
rdiscount (1.6.5)
|
31
|
+
rspec (1.3.1)
|
32
|
+
term-ansicolor (1.0.5)
|
33
|
+
win32-api (1.4.6)
|
34
|
+
win32-clipboard (0.5.2)
|
35
|
+
windows-pr (>= 1.0.3)
|
36
|
+
win32-process (0.6.2)
|
37
|
+
windows-pr (>= 1.0.5)
|
38
|
+
windows-api (0.4.0)
|
39
|
+
win32-api (>= 1.4.5)
|
40
|
+
windows-pr (1.0.9)
|
41
|
+
win32-api (>= 1.4.5)
|
42
|
+
windows-api (>= 0.3.0)
|
43
|
+
yard (0.6.1)
|
44
|
+
|
45
|
+
PLATFORMS
|
46
|
+
ruby
|
47
|
+
|
48
|
+
DEPENDENCIES
|
49
|
+
aruba (>= 0.2.3)
|
50
|
+
bundler (>= 1.0.3)
|
51
|
+
cucumber (>= 0.9.2)
|
52
|
+
rake (>= 0.8.7)
|
53
|
+
rdiscount (>= 1.6.5)
|
54
|
+
rspec (= 1.3.1)
|
55
|
+
win32-autogui!
|
56
|
+
win32-clipboard (>= 0.5.2)
|
57
|
+
win32-process (>= 0.6.2)
|
58
|
+
windows-api (>= 0.4.0)
|
59
|
+
windows-pr (>= 1.0.9)
|
60
|
+
yard (>= 0.6.1)
|
data/HISTORY.markdown
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 GearheadForHire, LLC
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,265 @@
|
|
1
|
+
Win32-Autogui
|
2
|
+
=============
|
3
|
+
|
4
|
+
A Win32 GUI testing framework packaged as a [RubyGem](http://rubygems.org/).
|
5
|
+
|
6
|
+
|
7
|
+
Overview
|
8
|
+
--------
|
9
|
+
Win32-autogui provides a framework to enable GUI application testing
|
10
|
+
with Ruby. This facilitates integration testing of Windows binaries using
|
11
|
+
Ruby based tools like [RSpec](http://github.com/dchelimsky/rspec)
|
12
|
+
and [Cucumber](http://github.com/aslakhellesoy/cucumber). Examples of
|
13
|
+
using both these tools are provided with this gem.
|
14
|
+
|
15
|
+
|
16
|
+
Quick Start
|
17
|
+
-----------
|
18
|
+
See [examples/skeleton/README.markdown](examples/skeleton/README.markdown) for
|
19
|
+
a template of the file structure needed for jump-starting GUI testing with
|
20
|
+
the Win32-autogui RubyGem.
|
21
|
+
|
22
|
+
|
23
|
+
Example Usage: Driving Calc.exe
|
24
|
+
-------------------------------
|
25
|
+
|
26
|
+
Using [RSpec](http://github.com/dchelimsky/rspec) to test drive the stock
|
27
|
+
Window's calculator application. This example is used as Win32-autogui's
|
28
|
+
internal spec. See [spec/auto_gui/application_spec.rb](spec/auto_gui/application_spec.rb).
|
29
|
+
|
30
|
+
A more complete example of testing a Window's Delphi program is presented with
|
31
|
+
source and binaries in [examples/quicknote/](examples/quicknote/).
|
32
|
+
|
33
|
+
### Wrap the application to be tested ###
|
34
|
+
The first step is to subclass Win32-autogui's application class.
|
35
|
+
|
36
|
+
require 'win32/autogui'
|
37
|
+
|
38
|
+
class Calculator < Autogui::Application
|
39
|
+
|
40
|
+
# initialize with the binary name 'calc' and the window title
|
41
|
+
# 'Calculator' used along with the application pid to find the
|
42
|
+
# main application window
|
43
|
+
def initialize(options = {})
|
44
|
+
defaults = {
|
45
|
+
:name => "calc",
|
46
|
+
:title => "Calculator"
|
47
|
+
}
|
48
|
+
super defaults.merge(options)
|
49
|
+
end
|
50
|
+
|
51
|
+
# the calculator's results window
|
52
|
+
def edit_window
|
53
|
+
main_window.children.find {|w| w.window_class == 'Edit'}
|
54
|
+
end
|
55
|
+
|
56
|
+
# About dialog, hotkey (VK_MENU, VK_H, VK_A)
|
57
|
+
def dialog_about
|
58
|
+
Autogui::EnumerateDesktopWindows.new.find do |w|
|
59
|
+
w.title.match(/About Calculator/) && (w.pid == pid)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# the 'CE' button
|
64
|
+
def clear_entry
|
65
|
+
keystroke(VK_DELETE)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
### Write specs ###
|
71
|
+
The following RSpec code describes driving the Windows calculator for testing.
|
72
|
+
Multiple instances running simultaneously are supported. See "should control
|
73
|
+
focus with set_focus."
|
74
|
+
|
75
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
76
|
+
|
77
|
+
include Autogui::Input
|
78
|
+
|
79
|
+
describe Autogui::Application do
|
80
|
+
|
81
|
+
describe "driving calc.exe" do
|
82
|
+
|
83
|
+
before(:all) do
|
84
|
+
@calculator = Calculator.new
|
85
|
+
end
|
86
|
+
|
87
|
+
after(:all) do
|
88
|
+
@calculator.close(:wait_for_close => true) if @calculator.running?
|
89
|
+
@calculator.should_not be_running
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should start when initialized" do
|
93
|
+
@calculator.should be_running
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should have the title 'Calculator' that matches the main_window title" do
|
97
|
+
@calculator.main_window.title.should == 'Calculator'
|
98
|
+
@calculator.main_window.title.should == @calculator.title
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should have an inspect method showing child window information" do
|
102
|
+
@calculator.inspect.should match(/children=</)
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should calculate '2+2=4' using the keystroke method" do
|
106
|
+
@calculator.set_focus
|
107
|
+
keystroke(VK_2, VK_ADD, VK_2, VK_RETURN)
|
108
|
+
@calculator.edit_window.text.strip.should == "4."
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should calculate '2+12=14' using the type_in method" do
|
112
|
+
@calculator.set_focus
|
113
|
+
type_in("2+12=")
|
114
|
+
@calculator.edit_window.text.strip.should == "14."
|
115
|
+
end
|
116
|
+
|
117
|
+
it "should control the focus with 'set_focus'" do
|
118
|
+
@calculator.set_focus
|
119
|
+
keystroke(VK_9)
|
120
|
+
@calculator.edit_window.text.strip.should == "9."
|
121
|
+
|
122
|
+
calculator2 = Calculator.new
|
123
|
+
calculator2.pid.should_not == @calculator.pid
|
124
|
+
calculator2.set_focus
|
125
|
+
keystroke(VK_1, VK_0)
|
126
|
+
calculator2.edit_window.text.strip.should == "10."
|
127
|
+
|
128
|
+
@calculator.set_focus
|
129
|
+
@calculator.edit_window.text.strip.should == "9."
|
130
|
+
|
131
|
+
calculator2.close(:wait_for_close => true)
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should open and close the 'About Calculator' dialog via (VK_MENU, VK_H, VK_A)" do
|
135
|
+
@calculator.set_focus
|
136
|
+
dialog_about = @calculator.dialog_about
|
137
|
+
dialog_about.should be_nil
|
138
|
+
keystroke(VK_MENU, VK_H, VK_A)
|
139
|
+
dialog_about = @calculator.dialog_about
|
140
|
+
dialog_about.title.should == "About Calculator"
|
141
|
+
dialog_about.combined_text.should match(/Microsoft . Calculator/)
|
142
|
+
dialog_about.close
|
143
|
+
@calculator.dialog_about.should be_nil
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "clipboard" do
|
147
|
+
before(:each) do
|
148
|
+
@calculator.clear_entry
|
149
|
+
@calculator.clipboard.text = ""
|
150
|
+
@calculator.clipboard.text.should == ""
|
151
|
+
end
|
152
|
+
|
153
|
+
describe "copy (VK_CONTROL, VK_C)" do
|
154
|
+
it "should copy the edit window" do
|
155
|
+
@calculator.set_focus
|
156
|
+
type_in("3002")
|
157
|
+
@calculator.edit_window.text.strip.should == "3,002."
|
158
|
+
@calculator.edit_window.set_focus
|
159
|
+
keystroke(VK_CONTROL, VK_C)
|
160
|
+
@calculator.clipboard.text.should == "3002"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "paste (VK_CONTROL, VK_V)" do
|
165
|
+
it "should paste into the edit window" do
|
166
|
+
@calculator.edit_window.set_focus
|
167
|
+
@calculator.clipboard.text = "12345"
|
168
|
+
@calculator.edit_window.text.strip.should == "0."
|
169
|
+
keystroke(VK_CONTROL, VK_V)
|
170
|
+
@calculator.edit_window.text.strip.should == "12,345."
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
|
180
|
+
System Requirements
|
181
|
+
-------------------
|
182
|
+
|
183
|
+
Windows OS, version 2000 or higher, testing was done via Cygwin <http://www.cygwin.com/>
|
184
|
+
|
185
|
+
|
186
|
+
Dependencies
|
187
|
+
------------
|
188
|
+
Win32-autogui depends on the following RubyGems
|
189
|
+
|
190
|
+
* Windows-api <http://github.com/djberg96/win32-api>
|
191
|
+
* Windows-pr <http://github.com/djberg96/windows-pr>
|
192
|
+
* Win32-process <http://github.com/djberg96/win32-process>
|
193
|
+
* Win32-clipboard <http://github.com/djberg96/win32-clipboard>
|
194
|
+
|
195
|
+
|
196
|
+
Installation
|
197
|
+
------------
|
198
|
+
Win32-autogui is available on [RubyGems.org](http://rubygems.org/gems/win32-autogui)
|
199
|
+
|
200
|
+
gem install win32-autogui
|
201
|
+
|
202
|
+
|
203
|
+
References and Alternative Libraries
|
204
|
+
------------------------------------
|
205
|
+
|
206
|
+
* Scripted GUI Testing with Ruby by Ian Dees <http://pragprog.com/titles/idgtr/scripted-gui-testing-with-ruby>
|
207
|
+
* RAA - win32-guitest <http://raa.ruby-lang.org/project/win32-guitest>
|
208
|
+
* Updated win32-guitest <http://rubyforge.org/projects/guitest>
|
209
|
+
|
210
|
+
|
211
|
+
Development
|
212
|
+
-----------
|
213
|
+
Win32-autogui development was jump-started by cloning [BasicGem](http://github.com/robertwahler/basic_gem).
|
214
|
+
|
215
|
+
### Dependencies ###
|
216
|
+
|
217
|
+
* Bundler for dependency management <http://github.com/carlhuda/bundler>
|
218
|
+
* RSpec for unit testing <http://github.com/dchelimsky/rspec>
|
219
|
+
* Cucumber for functional testing <http://github.com/aslakhellesoy/cucumber>
|
220
|
+
* Aruba for CLI testing <http://github.com/aslakhellesoy/aruba>
|
221
|
+
* YARD for documentation generation <http://github.com/lsegal/yard>
|
222
|
+
|
223
|
+
### Rake tasks ###
|
224
|
+
|
225
|
+
rake -T
|
226
|
+
|
227
|
+
rake build # Build win32-autogui-0.0.1.gem into the pkg directory
|
228
|
+
rake doc:clean # Remove generated documenation
|
229
|
+
rake doc:generate # Generate YARD Documentation
|
230
|
+
rake features # Run Cucumber features
|
231
|
+
rake install # Build and install win32-autogui-0.0.1.gem into system gems
|
232
|
+
rake release # Create tag v0.0.1 and build and push win32-autogui-0.0.1.gem to Rubygems
|
233
|
+
rake spec # Run specs
|
234
|
+
rake test # Run specs and features
|
235
|
+
|
236
|
+
|
237
|
+
### Autotesting with Watchr ###
|
238
|
+
|
239
|
+
[Watchr](http://github.com/mynyml/watchr) provides a flexible alternative to Autotest. A
|
240
|
+
jump start script is provided in spec/watchr.rb.
|
241
|
+
|
242
|
+
#### Install watchr ###
|
243
|
+
|
244
|
+
gem install watchr
|
245
|
+
|
246
|
+
#### Run watchr ###
|
247
|
+
|
248
|
+
watchr spec/watchr.rb
|
249
|
+
|
250
|
+
outputs a menu
|
251
|
+
|
252
|
+
Ctrl-\ for menu, Ctrl-C to quit
|
253
|
+
|
254
|
+
Watchr will now watch the files defined in 'spec/watchr.rb' and run RSpec or Cucumber, as appropriate.
|
255
|
+
The watchr script provides a simple menu.
|
256
|
+
|
257
|
+
Ctrl-\
|
258
|
+
|
259
|
+
MENU: a = all , f = features s = specs, l = last feature (none), q = quit
|
260
|
+
|
261
|
+
|
262
|
+
Copyright
|
263
|
+
---------
|
264
|
+
|
265
|
+
Copyright (c) 2010 GearheadForHire, LLC. See [LICENSE](LICENSE) for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# bundler/setup is managing $LOAD_PATH, any gem needed by this Rakefile must
|
4
|
+
# be listed as a development dependency in the gemspec
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'bundler/setup'
|
8
|
+
|
9
|
+
Bundler::GemHelper.install_tasks
|
10
|
+
|
11
|
+
def gemspec
|
12
|
+
@gemspec ||= begin
|
13
|
+
file = File.expand_path('../win32-autogui.gemspec', __FILE__)
|
14
|
+
eval(File.read(file), binding, file)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'spec'
|
19
|
+
require 'spec/rake/spectask'
|
20
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
21
|
+
spec.libs << 'lib' << 'spec'
|
22
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'cucumber'
|
26
|
+
require 'cucumber/rake/task'
|
27
|
+
Cucumber::Rake::Task.new(:features) do |task|
|
28
|
+
task.cucumber_opts = ["features"]
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Run specs and features"
|
32
|
+
task :test => [:spec, :features]
|
33
|
+
|
34
|
+
task :default => :test
|
35
|
+
|
36
|
+
namespace :doc do
|
37
|
+
project_root = File.expand_path(File.dirname(__FILE__))
|
38
|
+
doc_destination = File.join(project_root, 'rdoc')
|
39
|
+
|
40
|
+
require 'yard'
|
41
|
+
require 'yard/rake/yardoc_task'
|
42
|
+
|
43
|
+
YARD::Rake::YardocTask.new(:generate) do |yt|
|
44
|
+
yt.options = ['--markup-provider', 'rdiscount',
|
45
|
+
'--output-dir', doc_destination
|
46
|
+
] +
|
47
|
+
gemspec.rdoc_options - ['--line-numbers', '--inline-source']
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Remove generated documenation"
|
51
|
+
task :clean do
|
52
|
+
rm_r doc_destination if File.exists?(doc_destination)
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
data/TODO.markdown
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
TODO
|
2
|
+
====
|
3
|
+
|
4
|
+
general
|
5
|
+
-------
|
6
|
+
|
7
|
+
* (1.0) stop changing $LOAD_PATH in specs and features, modify ENV[] in before and afters
|
8
|
+
* (1.0) implement Application.find and add option to not start application automatically, allows driving already running applications
|
9
|
+
* (1.0) application class should be a mixin, not classical inheritance
|