win32-autogui 0.2.0
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/.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
|