bryan-ash-wx-nobbie 0.0.3.5 → 0.0.4
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/{README.txt → README.rdoc} +20 -24
- data/Rakefile +59 -0
- data/features/acceptance_test.feature +39 -4
- data/features/step_definitions/acceptance_test_steps.rb +41 -4
- data/features/support/env.rb +5 -8
- data/lib/nobbie/wx.rb +5 -0
- data/lib/nobbie/wx/application_launcher.rb +12 -10
- data/lib/nobbie/wx/command.rb +0 -6
- data/lib/nobbie/wx/command/console_reporter.rb +30 -0
- data/lib/nobbie/wx/command/executor.rb +25 -0
- data/lib/nobbie/wx/command/reporter.rb +17 -0
- data/lib/nobbie/wx/command/select.rb +12 -13
- data/lib/nobbie/wx/command_factory.rb +12 -14
- data/lib/nobbie/wx/impl/element/element_path_builder.rb +7 -6
- data/lib/nobbie/wx/impl/operation/choosable.rb +2 -9
- data/lib/nobbie/wx/impl/operation/select.rb +3 -10
- data/lib/nobbie/wx/operations.rb +13 -7
- data/spec/application_launcher_spec.rb +7 -1
- data/spec/console_reporter_spec.rb +32 -0
- data/spec/executor_spec.rb +54 -0
- data/spec/reporter_spec.rb +20 -0
- data/test/all_tests.rb +11 -4
- data/test/suite/example_app.rb +111 -105
- data/test/suite/nobbie_test_case.rb +2 -11
- data/test/suite/test_type.rb +10 -10
- metadata +12 -5
- data/lib/nobbie/wx/acceptance_test.rb +0 -19
- data/lib/nobbie/wx/command_executor.rb +0 -25
- data/lib/nobbie/wx/driven.rb +0 -7
data/{README.txt → README.rdoc}
RENAMED
@@ -13,14 +13,14 @@ ways to find components and subsequently multiple ways to interact with them, No
|
|
13
13
|
(Note: if you can't sleep without the ability to find things using xpath or whatever, there are hooks to specify your
|
14
14
|
own component finding strategies).
|
15
15
|
|
16
|
-
With this in mind, Nobbie provides a simple method of
|
17
|
-
and a simple set of
|
16
|
+
With this in mind, Nobbie provides a simple method of finding components (using ElementPathBuilder)
|
17
|
+
and a simple set of <tt>Operations</tt> to perform on them.
|
18
18
|
|
19
19
|
A quick overview with examples:
|
20
20
|
|
21
21
|
* Paths ...
|
22
22
|
|
23
|
-
In order to perform operations
|
23
|
+
In order to perform operations on a component, you need to first find it.
|
24
24
|
Only very simple 'named' paths are supported by default (but you can implement your own by providing an object that
|
25
25
|
responds to 'find_component'). When specifying a path, if you do not provide an object that responds to
|
26
26
|
'find_component', Nobbie will attempt to coerce the path into the default path type: Nobbie::Wx::ElementPathBuilder.
|
@@ -35,69 +35,66 @@ A quick overview with examples:
|
|
35
35
|
:text_ctrl
|
36
36
|
|
37
37
|
|
38
|
-
* Typing
|
38
|
+
* Typing ...
|
39
39
|
|
40
40
|
type(value, path)
|
41
41
|
|
42
42
|
e.g.
|
43
43
|
|
44
44
|
type('fred', in_('first_name'))
|
45
|
-
|
45
|
+
|
46
46
|
...or if you're one of those DSL/anglification people
|
47
|
-
|
47
|
+
|
48
48
|
type 'fred', :in => 'first_name'
|
49
49
|
type 'fred', 'first_name'
|
50
50
|
type 'fred', :first_name
|
51
|
-
|
51
|
+
|
52
52
|
This will find the component named 'first_name' and type 'fred' into it.
|
53
|
-
...this works for anything you can type into
|
54
|
-
{supported components}[link:classes/Nobbie/Wx/Operations.html#type].
|
53
|
+
...this works for anything you can type into.
|
55
54
|
|
56
55
|
|
57
|
-
* Selecting
|
56
|
+
* Selecting ...
|
58
57
|
|
59
58
|
selection(path).choose(value)
|
60
59
|
|
61
60
|
e.g.
|
62
61
|
|
63
62
|
selection(in_('title')).choose('Mr')
|
64
|
-
|
63
|
+
|
65
64
|
...or
|
66
|
-
|
65
|
+
|
67
66
|
selection(:in => 'title').choose 'Mr'
|
68
67
|
selection('title').choose 'Mr'
|
69
68
|
selection(:title).choose 'Mr'
|
70
69
|
|
71
70
|
This will find the component named 'title' and select 'Mr'.
|
72
71
|
...this works for anything where you can make a selection from a number of options
|
73
|
-
(which is quite a lot of things)
|
74
|
-
{supported components}[link:classes/Nobbie/Wx/SelectOperations.html#selection].
|
72
|
+
(which is quite a lot of things).
|
75
73
|
|
76
74
|
You can get the value of the current selection using:
|
77
75
|
|
78
76
|
selection(path).selected_value
|
79
77
|
|
80
78
|
|
81
|
-
* Clicking
|
79
|
+
* Clicking ...
|
82
80
|
|
83
81
|
click(path) (for buttons you can also use the label instead of a path)
|
84
82
|
|
85
83
|
e.g.
|
86
84
|
|
87
85
|
click('save')
|
88
|
-
|
86
|
+
|
89
87
|
...or
|
90
|
-
|
88
|
+
|
91
89
|
click 'save'
|
92
90
|
click :save
|
93
91
|
etc
|
94
|
-
|
92
|
+
|
95
93
|
This will find the component named (or labelled) 'save' and click it.
|
96
|
-
...this works for anything you can click
|
97
|
-
{supported components}[link:classes/Nobbie/Wx/Operations.html#click].
|
94
|
+
...this works for anything you can click.
|
98
95
|
|
99
96
|
|
100
|
-
* Choosing
|
97
|
+
* Choosing ...
|
101
98
|
|
102
99
|
choosable(path).choose
|
103
100
|
|
@@ -112,15 +109,14 @@ A quick overview with examples:
|
|
112
109
|
choosable(:female).choose
|
113
110
|
|
114
111
|
This will find the component named 'female' and choose it
|
115
|
-
...this works for anything that has a chosen/non-chosen state
|
116
|
-
{supported components}[link:classes/Nobbie/Wx/ChoosableOperations.html#choose].
|
112
|
+
...this works for anything that has a chosen/non-chosen state.
|
117
113
|
|
118
114
|
You can determine if a component is currently chosen using:
|
119
115
|
|
120
116
|
choosable(path).chosen?
|
121
117
|
|
122
118
|
Hopefully that makes some degree of sense, there are a few other operations available, that should be self
|
123
|
-
explanatory from the documentation
|
119
|
+
explanatory from the documentation.
|
124
120
|
|
125
121
|
* Writing that first test ...
|
126
122
|
|
data/Rakefile
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
require 'cucumber/rake/task'
|
6
|
+
require 'rcov/rcovtask'
|
7
|
+
|
8
|
+
$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
9
|
+
|
10
|
+
task :verify_rcov => [:spec, :features]
|
11
|
+
task :default => :verify_rcov
|
12
|
+
|
13
|
+
desc "Run all specs"
|
14
|
+
Spec::Rake::SpecTask.new do |t|
|
15
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
16
|
+
t.spec_opts = ['--options', 'spec/spec.opts']
|
17
|
+
unless ENV['NO_RCOV']
|
18
|
+
t.rcov = true
|
19
|
+
t.rcov_opts << '--text-report'
|
20
|
+
t.rcov_opts << '--exclude features\/,spec\/'
|
21
|
+
t.rcov_opts << '--sort coverage'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Run Cucumber features"
|
26
|
+
Cucumber::Rake::Task.new do |t|
|
27
|
+
t.cucumber_opts = '--format pretty'
|
28
|
+
t.rcov = true
|
29
|
+
t.rcov_opts << '-o coverage'
|
30
|
+
t.rcov_opts << '--text-report'
|
31
|
+
t.rcov_opts << '--exclude features\/,spec\/'
|
32
|
+
t.rcov_opts << '--sort coverage'
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Run unit tests"
|
36
|
+
Rcov::RcovTask.new(:test) do |t|
|
37
|
+
t.pattern = FileList['test/all_tests.rb']
|
38
|
+
t.verbose = true
|
39
|
+
t.rcov_opts << '--sort coverage'
|
40
|
+
end
|
41
|
+
|
42
|
+
def egrep(pattern)
|
43
|
+
Dir['**/*.rb'].each do |fn|
|
44
|
+
count = 0
|
45
|
+
open(fn) do |f|
|
46
|
+
while line = f.gets
|
47
|
+
count += 1
|
48
|
+
if line =~ pattern
|
49
|
+
puts "#{fn}:#{count}:#{line}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "Look for TODO and FIXME tags in the code"
|
57
|
+
task :todo do
|
58
|
+
egrep /(FIXME|todo|TBD)/
|
59
|
+
end
|
@@ -2,7 +2,42 @@ In order to test drive a WxRuby application
|
|
2
2
|
As a developer
|
3
3
|
I want Nobbie to provide acceptance test access to the application
|
4
4
|
|
5
|
-
Scenario:
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
Scenario: Choosing a radio button
|
6
|
+
Then "radio_button" is not chosen
|
7
|
+
When I choose "radio_button"
|
8
|
+
Then "radio_button" is chosen
|
9
|
+
|
10
|
+
Scenario: Choosing a check box
|
11
|
+
Then "check_box" is not chosen
|
12
|
+
When I choose "check_box"
|
13
|
+
Then "check_box" is chosen
|
14
|
+
|
15
|
+
Scenario: Type into a text control
|
16
|
+
When I type "123" into "text_ctrl"
|
17
|
+
Then I should see "123" in "text_ctrl"
|
18
|
+
|
19
|
+
Scenario: Type into a combo box
|
20
|
+
When I type "456" into "combo_box"
|
21
|
+
Then I should see "456" in "combo_box"
|
22
|
+
|
23
|
+
Scenario: Click on a button
|
24
|
+
When I click on "button"
|
25
|
+
|
26
|
+
Scenario Outline: Working with selectables
|
27
|
+
Given "<selectable>" includes "<value>"
|
28
|
+
When I select "<value>" on the "<selectable>"
|
29
|
+
Then "<value>" on the "<selectable>" should be selected
|
30
|
+
|
31
|
+
Examples:
|
32
|
+
| selectable | value |
|
33
|
+
| combo_box_with_items | combo_box_item |
|
34
|
+
| list_box_with_items | list_box_item |
|
35
|
+
| test_notebook | click |
|
36
|
+
|
37
|
+
Scenario: Enabled controls
|
38
|
+
Then "text_ctrl" is enabled
|
39
|
+
Then "disabled_text_ctrl" is not enabled
|
40
|
+
|
41
|
+
Scenario: Working with menus
|
42
|
+
When I select "&New..." on the "&File"
|
43
|
+
|
@@ -1,11 +1,48 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
When /^I choose "(.*)"$/ do |item|
|
2
|
+
choosable(item).choose
|
3
3
|
end
|
4
4
|
|
5
|
-
When /^
|
6
|
-
|
5
|
+
When /^I type "(.*)" into "(.*)"$/ do |value, item|
|
6
|
+
type value, :in => item
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^I click on "(.*)"$/ do |item|
|
10
|
+
click item
|
11
|
+
end
|
12
|
+
|
13
|
+
When /^I select "(.*)" on the "(.*)"$/ do |value, selectable|
|
14
|
+
selection(:in => selectable).choose value
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^I should see "(.*)" in "(.*)"$/ do |value, item|
|
18
|
+
text(item).should == value
|
7
19
|
end
|
8
20
|
|
9
21
|
Then /^the application is running$/ do
|
10
22
|
@app.is_main_loop_running.should be_true
|
11
23
|
end
|
24
|
+
|
25
|
+
Then /^"(.*)" is chosen$/ do |item|
|
26
|
+
choosable(item).should be_chosen
|
27
|
+
end
|
28
|
+
|
29
|
+
Then /^"(.*)" is not chosen$/ do |item|
|
30
|
+
choosable(item).should_not be_chosen
|
31
|
+
end
|
32
|
+
|
33
|
+
Then /^"(.*)" on the "(.*)" should be selected$/ do |value, selectable|
|
34
|
+
selection(:in => selectable).selected_value.should == value
|
35
|
+
end
|
36
|
+
|
37
|
+
Then /^"(.*)" includes "(.*)"$/ do |selectable, value|
|
38
|
+
selection(:in => selectable).options.should include(value)
|
39
|
+
end
|
40
|
+
|
41
|
+
Then /^"(.*)" is enabled$/ do |item|
|
42
|
+
enabled?(item).should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
Then /^"(.*)" is not enabled$/ do |item|
|
46
|
+
enabled?(item).should_not be_true
|
47
|
+
end
|
48
|
+
|
data/features/support/env.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
|
+
require 'rubygems'
|
1
2
|
require 'spec'
|
2
3
|
|
3
|
-
$LOAD_PATH.unshift File.dirname(__FILE__) +
|
4
|
-
|
4
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
|
5
|
+
require 'nobbie/wx'
|
5
6
|
|
6
|
-
require 'example_app'
|
7
|
+
require File.dirname(__FILE__) + '/../../test/suite/example_app'
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
After do
|
11
|
-
@app.exit_main_loop unless @app.nil?
|
12
|
-
end
|
9
|
+
Nobbie::Wx::ApplicationLauncher.new(ExampleApp.new(false)).run
|
data/lib/nobbie/wx.rb
ADDED
@@ -17,22 +17,23 @@ module Nobbie
|
|
17
17
|
|
18
18
|
class ApplicationLauncher #:nodoc:
|
19
19
|
|
20
|
-
AUT_NOT_WX_APP = "
|
20
|
+
AUT_NOT_WX_APP = "application_under_test must be an instance of a Wx::App"
|
21
21
|
|
22
22
|
def initialize(application_under_test)
|
23
23
|
@app = application_under_test
|
24
24
|
Kernel.raise(AUT_NOT_WX_APP) unless @app.is_a?(Wxruby2::App)
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
27
|
+
def run
|
28
28
|
start
|
29
|
-
|
29
|
+
set_top_window_for_use_in_operations
|
30
|
+
Thread.pass
|
30
31
|
stop
|
31
|
-
result
|
32
32
|
end
|
33
33
|
|
34
|
+
private
|
35
|
+
|
34
36
|
def start
|
35
|
-
puts "\n>> Starting application: #{@app.class}"
|
36
37
|
start = Time.now
|
37
38
|
|
38
39
|
@app_thread = Thread.new {
|
@@ -44,19 +45,20 @@ module Nobbie
|
|
44
45
|
@app_thread.priority = -1
|
45
46
|
|
46
47
|
sleep 1
|
47
|
-
finish = Time.now
|
48
|
-
puts "\n>> Took #{finish-start} seconds to start application"
|
49
48
|
Thread.pass
|
50
49
|
end
|
51
50
|
|
52
51
|
def stop
|
53
|
-
|
54
|
-
|
55
|
-
#todo: tbis would seem a polite way to exit .. but causes Bus/Segmentation Errors on OSX.
|
52
|
+
#todo: this would seem a polite way to exit .. but causes Bus/Segmentation Errors on OSX.
|
56
53
|
#@app.top_window.destroy
|
57
54
|
#@app.exit_main_loop
|
58
55
|
#@app = nil
|
59
56
|
end
|
57
|
+
|
58
|
+
def set_top_window_for_use_in_operations
|
59
|
+
Nobbie::Wx::Operations.const_set("TOP_WINDOW", @app.get_top_window)
|
60
|
+
end
|
61
|
+
|
60
62
|
end
|
61
63
|
|
62
64
|
end
|
data/lib/nobbie/wx/command.rb
CHANGED
@@ -34,12 +34,8 @@ module Nobbie
|
|
34
34
|
|
35
35
|
begin
|
36
36
|
unless [Menu, Panel].include?(component.class)
|
37
|
-
#puts "highlight on: #{component.class} - #{component.name}"
|
38
37
|
original_colour = component.background_colour
|
39
38
|
component.background_colour = Colour.from_hex('#FFFF00')
|
40
|
-
|
41
|
-
#todo: these were previously disabled
|
42
|
-
# component.refresh
|
43
39
|
component.update
|
44
40
|
end
|
45
41
|
result = yield component
|
@@ -49,10 +45,8 @@ module Nobbie
|
|
49
45
|
return result
|
50
46
|
ensure
|
51
47
|
unless [Menu, Panel].include?(component.class)
|
52
|
-
#puts "highlight off: #{component.class} - #{component.name}"
|
53
48
|
component.background_colour = original_colour
|
54
49
|
component.refresh
|
55
|
-
#component.update
|
56
50
|
end
|
57
51
|
end
|
58
52
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
require 'nobbie/wx/command/reporter'
|
3
|
+
|
4
|
+
module Nobbie
|
5
|
+
module Wx
|
6
|
+
module Command
|
7
|
+
|
8
|
+
class ConsoleReporter < Reporter #:nodoc:
|
9
|
+
|
10
|
+
def before_executing_command(command)
|
11
|
+
STDOUT.puts "\n> #{command.describe}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def after_executing_command(result)
|
15
|
+
STDOUT.puts "< #{render(result)}"
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def render(component)
|
21
|
+
#todo: this needs improving to support other components
|
22
|
+
return '' if component.nil?
|
23
|
+
return component.value if component.respond_to?(:get_value)
|
24
|
+
return component.inspect
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
require 'nobbie/wx/command/reporter'
|
3
|
+
|
4
|
+
module Nobbie
|
5
|
+
module Wx
|
6
|
+
module Command
|
7
|
+
|
8
|
+
class Executor #:nodoc:
|
9
|
+
|
10
|
+
def initialize(reporter = Reporter.new)
|
11
|
+
@reporter = reporter
|
12
|
+
end
|
13
|
+
|
14
|
+
def execute(command)
|
15
|
+
@reporter.before_executing_command(command)
|
16
|
+
result = command.execute
|
17
|
+
@reporter.after_executing_command(result)
|
18
|
+
result
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|