kookaburra 0.21.1 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -3
- data/Gemfile.lock +0 -2
- data/README.markdown +19 -19
- data/VERSION +1 -1
- data/kookaburra.gemspec +7 -7
- data/lib/kookaburra/api_driver.rb +5 -8
- data/lib/kookaburra/assertion.rb +24 -0
- data/lib/kookaburra/configuration.rb +70 -0
- data/lib/kookaburra/dependency_accessor.rb +4 -1
- data/lib/kookaburra/given_driver.rb +13 -26
- data/lib/kookaburra/json_api_driver.rb +5 -4
- data/lib/kookaburra/test_helpers.rb +18 -17
- data/lib/kookaburra/ui_driver/ui_component/address_bar.rb +23 -0
- data/lib/kookaburra/ui_driver/ui_component.rb +19 -63
- data/lib/kookaburra/ui_driver.rb +17 -21
- data/lib/kookaburra.rb +29 -50
- data/spec/integration/test_a_rack_application_spec.rb +34 -30
- data/spec/kookaburra/api_driver_spec.rb +6 -4
- data/spec/kookaburra/configuration_spec.rb +18 -0
- data/spec/kookaburra/json_api_driver_spec.rb +12 -8
- data/spec/kookaburra/ui_driver/ui_component/address_bar_spec.rb +32 -0
- data/spec/kookaburra/ui_driver/ui_component_spec.rb +30 -64
- data/spec/kookaburra/ui_driver_spec.rb +7 -12
- data/spec/kookaburra_spec.rb +33 -29
- data/spec/support/shared_examples/it_can_make_assertions.rb +12 -0
- data/spec/support/shared_examples/it_has_a_dependency_accessor.rb +6 -9
- metadata +30 -41
- data/lib/kookaburra/null_browser.rb +0 -15
- data/spec/kookaburra/null_browser_spec.rb +0 -15
- data/spec/kookaburra/test_helpers_spec.rb +0 -48
data/lib/kookaburra/ui_driver.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'active_support/core_ext/hash'
|
2
|
-
require '
|
2
|
+
require 'active_support/core_ext/module/delegation'
|
3
|
+
require 'kookaburra/assertion'
|
3
4
|
require 'kookaburra/ui_driver/ui_component'
|
5
|
+
require 'kookaburra/ui_driver/ui_component/address_bar'
|
4
6
|
|
5
7
|
class Kookaburra
|
6
8
|
# You UIDriver subclass is where you define the DSL for testing your
|
@@ -20,15 +22,15 @@ class Kookaburra
|
|
20
22
|
# ui_component :questionnaire, Questionnaire
|
21
23
|
#
|
22
24
|
# def view_the_widgets
|
23
|
-
# widget_list
|
25
|
+
# address_bar.go_to(widget_list)
|
24
26
|
# end
|
25
27
|
#
|
26
28
|
# def view_all_of_the_widgets
|
27
|
-
# widget_list.
|
29
|
+
# address_bar.go_to(widget_list.url(:include_hidden => true))
|
28
30
|
# end
|
29
31
|
#
|
30
32
|
# def complete_the_widget_questionnaire(answers = {})
|
31
|
-
# questionnaire
|
33
|
+
# address_bar.go_to(questionnaire)
|
32
34
|
# questionnaire.page_1.submit(answers[:page_1])
|
33
35
|
# questionnaire.page_2.submit(answers[:page_2])
|
34
36
|
# questionnaire.page_3.submit(answers[:page_3])
|
@@ -57,7 +59,7 @@ class Kookaburra
|
|
57
59
|
#
|
58
60
|
# ui.account_management.account_list.should be_visible
|
59
61
|
class UIDriver
|
60
|
-
|
62
|
+
include Assertion
|
61
63
|
|
62
64
|
class << self
|
63
65
|
# Tells the UIDriver about your {UIComponent} subclasses.
|
@@ -68,7 +70,7 @@ class Kookaburra
|
|
68
70
|
# this component.
|
69
71
|
def ui_component(component_name, component_class)
|
70
72
|
define_method(component_name) do
|
71
|
-
component_class.new(
|
73
|
+
component_class.new(@configuration)
|
72
74
|
end
|
73
75
|
end
|
74
76
|
|
@@ -80,7 +82,7 @@ class Kookaburra
|
|
80
82
|
# this driver.
|
81
83
|
def ui_driver(driver_name, driver_class)
|
82
84
|
define_method(driver_name) do
|
83
|
-
driver_class.new(
|
85
|
+
driver_class.new(@configuration)
|
84
86
|
end
|
85
87
|
end
|
86
88
|
end
|
@@ -88,25 +90,19 @@ class Kookaburra
|
|
88
90
|
# It is unlikely that you would instantiate your UIDriver on your own; the
|
89
91
|
# object is configured for you when you call {Kookaburra#ui}.
|
90
92
|
#
|
91
|
-
# @
|
92
|
-
|
93
|
-
|
94
|
-
# @option options [String] :app_host The root URL of your running
|
95
|
-
# application (e.g. "http://my_app.example.com:12345")
|
96
|
-
# @option options [Proc] :server_error_detection A lambda that is passed the
|
97
|
-
# `:browser` object and should return `true` if the page indicates a server
|
98
|
-
# error has occured
|
99
|
-
def initialize(options = {})
|
100
|
-
@options = options
|
101
|
-
@mental_model = options[:mental_model]
|
93
|
+
# @param [Kookaburra::Configuration] configuration (Kookaburra.configuration)
|
94
|
+
def initialize(configuration)
|
95
|
+
@configuration = configuration
|
102
96
|
end
|
103
97
|
|
104
98
|
protected
|
105
99
|
|
106
|
-
#
|
107
|
-
|
100
|
+
# @attribute [r] address_bar
|
101
|
+
# @return [Kookaburra::UIComponent::UIComponent::AddressBar]
|
102
|
+
ui_component :address_bar, UIComponent::AddressBar
|
108
103
|
|
109
104
|
# @attribute [r] mental_model
|
110
|
-
|
105
|
+
# @return [Kookaburra::MentalModel]
|
106
|
+
delegate :mental_model, :to => :@configuration
|
111
107
|
end
|
112
108
|
end
|
data/lib/kookaburra.rb
CHANGED
@@ -2,52 +2,47 @@ require 'kookaburra/exceptions'
|
|
2
2
|
require 'kookaburra/mental_model'
|
3
3
|
require 'kookaburra/given_driver'
|
4
4
|
require 'kookaburra/ui_driver'
|
5
|
+
require 'kookaburra/configuration'
|
5
6
|
|
6
7
|
# Kookaburra provides the top-level API that you will access in your test
|
7
8
|
# implementation, namely the {#given}, {#ui}, and the {#get_data} methods.
|
8
9
|
#
|
9
10
|
# The Kookaburra object ensures that your GivenDriver and UIDriver share the
|
10
|
-
# same state with regard to any
|
11
|
-
# run. As such, it is important to ensure that a new instance
|
12
|
-
# created for each individual test, otherwise you may wind up
|
13
|
-
# bleeding over from one test to the next. The
|
14
|
-
# is intended to be mixed in to your testing
|
11
|
+
# same state with regard to any {Kookaburra::MentalModel} data that is created
|
12
|
+
# during your test run. As such, it is important to ensure that a new instance
|
13
|
+
# of Kookaburra is created for each individual test, otherwise you may wind up
|
14
|
+
# with test state bleeding over from one test to the next. The
|
15
|
+
# {Kookaburra::TestHelpers} module is intended to be mixed in to your testing
|
16
|
+
# context for this purpose.
|
15
17
|
#
|
16
18
|
# @see Kookaburra::TestHelpers
|
17
19
|
class Kookaburra
|
18
20
|
class << self
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
|
23
|
-
|
21
|
+
# Stores the configuration object that is used by default when creating new
|
22
|
+
# instances of Kookaburra
|
23
|
+
#
|
24
|
+
# @return [Kookaburra::Configuration] return value is memoized
|
24
25
|
def configuration
|
25
|
-
@configuration ||=
|
26
|
+
@configuration ||= Configuration.new
|
27
|
+
end
|
28
|
+
|
29
|
+
# Yields the current configuration so that it can be modified
|
30
|
+
#
|
31
|
+
# @yield [Kookaburra::Configuration]
|
32
|
+
def configure(&blk)
|
33
|
+
blk.call(configuration)
|
26
34
|
end
|
27
35
|
end
|
28
36
|
|
29
37
|
# Returns a new Kookaburra instance that wires together your application's
|
30
|
-
#
|
38
|
+
# GivenDriver and UIDriver with a shared {Kookaburra::MentalModel}.
|
31
39
|
#
|
32
|
-
# @
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
# @option options [String] :app_host The URL of your running application
|
39
|
-
# server against which the tests will be run (e.g.
|
40
|
-
# "http://my_app.example.com:12345")
|
41
|
-
# @option options [Proc] :server_error_detection A proc that will receive the
|
42
|
-
# object passed in to the :browser option as an argument and must return
|
43
|
-
# `true` if the server responded with an unexpected error or `false` if it
|
44
|
-
# did not.
|
45
|
-
def initialize(options = {})
|
46
|
-
@given_driver_class = options[:given_driver_class]
|
47
|
-
@ui_driver_class = options[:ui_driver_class]
|
48
|
-
@browser = options[:browser]
|
49
|
-
@app_host = options[:app_host]
|
50
|
-
@server_error_detection = options[:server_error_detection]
|
40
|
+
# @param [Kookaburra::Configuration] configuration (Kookaburra.configuration)
|
41
|
+
def initialize(configuration = Kookaburra.configuration)
|
42
|
+
@configuration = configuration
|
43
|
+
@configuration.mental_model = MentalModel.new
|
44
|
+
@given_driver_class = configuration.given_driver_class
|
45
|
+
@ui_driver_class = configuration.ui_driver_class
|
51
46
|
end
|
52
47
|
|
53
48
|
# Returns an instance of your GivenDriver class configured to share test
|
@@ -55,7 +50,7 @@ class Kookaburra
|
|
55
50
|
#
|
56
51
|
# @return [Kookaburra::GivenDriver]
|
57
52
|
def given
|
58
|
-
given_driver_class.new(
|
53
|
+
@given ||= @given_driver_class.new(@configuration)
|
59
54
|
end
|
60
55
|
|
61
56
|
# Returns an instance of your UIDriver class configured to share test fixture
|
@@ -64,10 +59,7 @@ class Kookaburra
|
|
64
59
|
#
|
65
60
|
# @return [Kookaburra::UIDriver]
|
66
61
|
def ui
|
67
|
-
ui_driver_class.new(
|
68
|
-
:browser => browser,
|
69
|
-
:app_host => @app_host,
|
70
|
-
:server_error_detection => @server_error_detection)
|
62
|
+
@ui ||= @ui_driver_class.new(@configuration)
|
71
63
|
end
|
72
64
|
|
73
65
|
# Returns a frozen copy of the specified {MentalModel::Collection}.
|
@@ -86,19 +78,6 @@ class Kookaburra
|
|
86
78
|
#
|
87
79
|
# @return [Kookaburra::MentalModel::Collection]
|
88
80
|
def get_data(collection_name)
|
89
|
-
mental_model.send(collection_name).dup.freeze
|
90
|
-
end
|
91
|
-
|
92
|
-
private
|
93
|
-
|
94
|
-
extend DependencyAccessor
|
95
|
-
dependency_accessor :given_driver_class, :ui_driver_class
|
96
|
-
|
97
|
-
def mental_model
|
98
|
-
@mental_model ||= MentalModel.new
|
99
|
-
end
|
100
|
-
|
101
|
-
def browser
|
102
|
-
@browser ||= NullBrowser.new
|
81
|
+
@configuration.mental_model.send(collection_name).dup.freeze
|
103
82
|
end
|
104
83
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'kookaburra'
|
1
|
+
require 'kookaburra/test_helpers'
|
2
2
|
require 'kookaburra/json_api_driver'
|
3
3
|
require 'capybara'
|
4
4
|
|
@@ -190,7 +190,7 @@ describe "testing a Rack application with Kookaburra" do
|
|
190
190
|
|
191
191
|
class MyGivenDriver < Kookaburra::GivenDriver
|
192
192
|
def api
|
193
|
-
MyAPIDriver.new(
|
193
|
+
MyAPIDriver.new(configuration)
|
194
194
|
end
|
195
195
|
|
196
196
|
def a_user(name)
|
@@ -277,19 +277,23 @@ describe "testing a Rack application with Kookaburra" do
|
|
277
277
|
ui_component :widget_form, WidgetForm
|
278
278
|
|
279
279
|
def sign_in(name)
|
280
|
-
sign_in_screen
|
280
|
+
address_bar.go_to sign_in_screen
|
281
281
|
sign_in_screen.sign_in(mental_model.users[name])
|
282
282
|
end
|
283
283
|
|
284
|
+
def view_widget_list
|
285
|
+
address_bar.go_to widget_list
|
286
|
+
end
|
287
|
+
|
284
288
|
def create_new_widget(name, attributes = {})
|
285
|
-
widget_list.
|
289
|
+
assert widget_list.visible?, "Widget list is not visible!"
|
286
290
|
widget_list.choose_to_create_new_widget
|
287
291
|
widget_form.submit('name' => 'My Widget')
|
288
292
|
mental_model.widgets[name] = widget_list.last_widget_created
|
289
293
|
end
|
290
294
|
|
291
295
|
def delete_widget(name)
|
292
|
-
widget_list.
|
296
|
+
assert widget_list.visible?, "Widget list is not visible!"
|
293
297
|
widget_list.choose_to_delete_widget(mental_model.widgets[name])
|
294
298
|
end
|
295
299
|
end
|
@@ -314,31 +318,31 @@ describe "testing a Rack application with Kookaburra" do
|
|
314
318
|
end
|
315
319
|
|
316
320
|
it "runs the tests against the app" do
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
321
|
+
Kookaburra.configure do |c|
|
322
|
+
c.ui_driver_class = MyUIDriver
|
323
|
+
c.given_driver_class = MyGivenDriver
|
324
|
+
c.app_host = 'http://127.0.0.1:%d' % @rack_server_port
|
325
|
+
c.browser = Capybara::Session.new(:selenium)
|
326
|
+
c.server_error_detection do |browser|
|
327
|
+
browser.has_css?('head title', :text => 'Internal Server Error')
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
extend Kookaburra::TestHelpers
|
332
|
+
|
333
|
+
given.a_user(:bob)
|
334
|
+
given.a_widget(:widget_a)
|
335
|
+
given.a_widget(:widget_b, :name => 'Foo')
|
336
|
+
|
337
|
+
ui.sign_in(:bob)
|
338
|
+
ui.view_widget_list
|
339
|
+
ui.widget_list.widgets.should == k.get_data(:widgets).slice(:widget_a, :widget_b)
|
340
|
+
|
341
|
+
ui.create_new_widget(:widget_c, :name => 'Bar')
|
342
|
+
ui.widget_list.widgets.should == k.get_data(:widgets).slice(:widget_a, :widget_b, :widget_c)
|
343
|
+
|
344
|
+
ui.delete_widget(:widget_b)
|
345
|
+
ui.widget_list.widgets.should == k.get_data(:widgets).slice(:widget_a, :widget_c)
|
342
346
|
end
|
343
347
|
end
|
344
348
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'kookaburra/api_driver'
|
2
2
|
|
3
3
|
describe Kookaburra::APIDriver do
|
4
|
-
let(:
|
4
|
+
let(:configuration) { stub('Configuration', :app_host => 'http://example.com') }
|
5
|
+
|
6
|
+
let(:api) { Kookaburra::APIDriver.new(configuration, client) }
|
5
7
|
|
6
8
|
let(:response) {
|
7
9
|
stub('Patron::Response', :body => 'foo', :status => 200, :url => '/foo')
|
@@ -9,18 +11,18 @@ describe Kookaburra::APIDriver do
|
|
9
11
|
|
10
12
|
let(:client) {
|
11
13
|
mock('Patron::Session', :post => response, :get => response,
|
12
|
-
:put => response, :delete => response)
|
14
|
+
:put => response, :delete => response, :base_url= => nil)
|
13
15
|
}
|
14
16
|
|
15
17
|
describe '#initialize' do
|
16
18
|
it 'instantiates a new http client if no :http_client option is passed' do
|
17
19
|
Patron::Session.should_receive(:new).and_return(stub.as_null_object)
|
18
|
-
Kookaburra::APIDriver.new(
|
20
|
+
Kookaburra::APIDriver.new(configuration)
|
19
21
|
end
|
20
22
|
|
21
23
|
it 'does not instantiate a new http client if an :http_client option is passed' do
|
22
24
|
Patron::Session.should_receive(:new).never
|
23
|
-
Kookaburra::APIDriver.new(
|
25
|
+
Kookaburra::APIDriver.new(configuration, client)
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'kookaburra/configuration'
|
2
|
+
require 'support/shared_examples/it_has_a_dependency_accessor'
|
3
|
+
|
4
|
+
describe Kookaburra::Configuration do
|
5
|
+
it_behaves_like :it_has_a_dependency_accessor, :given_driver_class
|
6
|
+
it_behaves_like :it_has_a_dependency_accessor, :ui_driver_class
|
7
|
+
it_behaves_like :it_has_a_dependency_accessor, :browser
|
8
|
+
it_behaves_like :it_has_a_dependency_accessor, :app_host
|
9
|
+
it_behaves_like :it_has_a_dependency_accessor, :mental_model
|
10
|
+
|
11
|
+
describe '#server_error_detection' do
|
12
|
+
it 'returns the block that it was last given' do
|
13
|
+
block = lambda { 'foo' }
|
14
|
+
subject.server_error_detection(&block)
|
15
|
+
subject.server_error_detection.should == block
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -8,21 +8,27 @@ describe Kookaburra::JsonApiDriver do
|
|
8
8
|
:delete => response, :headers => {})
|
9
9
|
}
|
10
10
|
|
11
|
-
let(:
|
11
|
+
let(:configuration) {
|
12
|
+
stub('Configuration')
|
13
|
+
}
|
14
|
+
|
15
|
+
let(:json) { Kookaburra::JsonApiDriver.new(stub('Configuration'), api) }
|
12
16
|
|
13
17
|
describe '#initialize' do
|
14
18
|
it 'instantiates a new APIDriver if no :api_driver option is passed' do
|
15
|
-
Kookaburra::APIDriver.should_receive(:new)
|
16
|
-
|
19
|
+
Kookaburra::APIDriver.should_receive(:new) \
|
20
|
+
.with(configuration) \
|
21
|
+
.and_return(api)
|
22
|
+
Kookaburra::JsonApiDriver.new(configuration)
|
17
23
|
end
|
18
24
|
|
19
25
|
it 'does not instantiate a new APIDriver if an :api_driver option is passed' do
|
20
26
|
Kookaburra::APIDriver.should_receive(:new).never
|
21
|
-
Kookaburra::JsonApiDriver.new(
|
27
|
+
Kookaburra::JsonApiDriver.new(configuration, api)
|
22
28
|
end
|
23
29
|
|
24
30
|
it 'sets appropriate headers for a JSON API request' do
|
25
|
-
Kookaburra::JsonApiDriver.new(
|
31
|
+
Kookaburra::JsonApiDriver.new(configuration, api)
|
26
32
|
api.headers.should == {
|
27
33
|
'Content-Type' => 'application/json',
|
28
34
|
'Accept' => 'application/json'
|
@@ -31,9 +37,7 @@ describe Kookaburra::JsonApiDriver do
|
|
31
37
|
end
|
32
38
|
|
33
39
|
it 'delegates to a Kookaburra::APIDriver by default' do
|
34
|
-
|
35
|
-
Kookaburra::APIDriver.should_receive(:new).once.and_return(delegate)
|
36
|
-
json = Kookaburra::JsonApiDriver.new
|
40
|
+
api.stub!(:foo => :bar)
|
37
41
|
json.foo.should == :bar
|
38
42
|
end
|
39
43
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'kookaburra/ui_driver/ui_component/address_bar'
|
2
|
+
|
3
|
+
describe Kookaburra::UIDriver::UIComponent::AddressBar do
|
4
|
+
describe '#go_to' do
|
5
|
+
let(:browser) {
|
6
|
+
mock('Capybara::Session').tap do |b|
|
7
|
+
b.should_receive(:visit).with('http://site.example.com')
|
8
|
+
end
|
9
|
+
}
|
10
|
+
|
11
|
+
let(:configuration) {
|
12
|
+
stub('Configuration', :browser => browser, :app_host => nil, :server_error_detection => nil)
|
13
|
+
}
|
14
|
+
|
15
|
+
let(:address_bar) {
|
16
|
+
address_bar = Kookaburra::UIDriver::UIComponent::AddressBar.new(configuration)
|
17
|
+
}
|
18
|
+
|
19
|
+
context 'when given a string' do
|
20
|
+
it 'causes the browser to navigate to the (presumably URL) string' do
|
21
|
+
address_bar.go_to 'http://site.example.com'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when given a string' do
|
26
|
+
it 'causes the browser to navigate to the (presumably URL) string' do
|
27
|
+
addressable = stub('addressable', :url => 'http://site.example.com')
|
28
|
+
address_bar.go_to addressable
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,60 +1,31 @@
|
|
1
1
|
require 'kookaburra/ui_driver/ui_component'
|
2
|
+
require 'support/shared_examples/it_can_make_assertions'
|
2
3
|
|
3
4
|
describe Kookaburra::UIDriver::UIComponent do
|
4
|
-
|
5
|
-
|
6
|
-
it 'causes the browser to navigate to the value of #component_path' do
|
7
|
-
browser = mock('Browser Session')
|
8
|
-
browser.should_receive(:visit).with('/foo')
|
9
|
-
component = Kookaburra::UIDriver::UIComponent.new(:browser => browser)
|
10
|
-
component.stub!(:component_path => '/foo')
|
11
|
-
component.stub!(:visible?).and_return(false, true)
|
12
|
-
component.show
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'passes any arguments to the #component_path for processing' do
|
16
|
-
browser = mock('Browser Session', :visit => nil)
|
17
|
-
component = Kookaburra::UIDriver::UIComponent.new(:browser => browser)
|
18
|
-
component.should_receive(:component_path).with(:foo => :bar, :baz => :bam)
|
19
|
-
component.stub!(:visible?).and_return(false, true)
|
20
|
-
component.show(:foo => :bar, :baz => :bam)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context 'the component is already visible' do
|
25
|
-
it 'does not navigate to #component path' do
|
26
|
-
browser = mock('Browser Session')
|
27
|
-
browser.should_receive(:visit).never
|
28
|
-
component = Kookaburra::UIDriver::UIComponent.new(:browser => browser)
|
29
|
-
component.stub!(:component_path => '/foo', :visible? => true)
|
30
|
-
component.show
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
5
|
+
let(:configuration) { stub('Configuration', :browser => nil, :app_host => nil, :server_error_detection => nil) }
|
6
|
+
let(:component) { Kookaburra::UIDriver::UIComponent.new(configuration) }
|
34
7
|
|
35
8
|
describe '#respond_to?' do
|
36
|
-
let(:
|
37
|
-
Class.new(Kookaburra::UIDriver::UIComponent) do
|
9
|
+
let(:component) do
|
10
|
+
klass = Class.new(Kookaburra::UIDriver::UIComponent) do
|
38
11
|
def foo
|
39
12
|
end
|
40
13
|
end
|
14
|
+
klass.new(configuration)
|
41
15
|
end
|
42
16
|
|
43
17
|
it 'returns true if the UIComponent defines the specified method' do
|
44
|
-
component = component_class.new
|
45
18
|
component.respond_to?(:foo).should == true
|
46
19
|
end
|
47
20
|
|
48
21
|
it 'returns true if the #browser defines the specified method' do
|
49
22
|
browser = stub('Browser Driver', :respond_to? => true)
|
50
|
-
component = component_class.new
|
51
23
|
component.stub!(:browser => browser)
|
52
24
|
component.respond_to?(:a_very_unlikely_method_name).should == true
|
53
25
|
end
|
54
26
|
|
55
27
|
it 'returns false if neither the UIComponent nor the #browser define the specified method' do
|
56
28
|
browser = stub('Browser Driver', :respond_to? => false)
|
57
|
-
component = component_class.new
|
58
29
|
component.stub!(:browser => browser)
|
59
30
|
component.respond_to?(:a_very_unlikely_method_name).should == false
|
60
31
|
end
|
@@ -71,7 +42,7 @@ describe Kookaburra::UIDriver::UIComponent do
|
|
71
42
|
scope.should == '#my_component'
|
72
43
|
block.call(browser)
|
73
44
|
end
|
74
|
-
|
45
|
+
configuration.stub!(:browser => browser)
|
75
46
|
component.stub!(:component_locator => '#my_component')
|
76
47
|
component.some_browser_method(:arguments).should == :answer_from_browser
|
77
48
|
end
|
@@ -79,7 +50,6 @@ describe Kookaburra::UIDriver::UIComponent do
|
|
79
50
|
|
80
51
|
context 'the component says it does not respond to the method' do
|
81
52
|
it 'raises a NoMethodError' do
|
82
|
-
component = Kookaburra::UIDriver::UIComponent.new
|
83
53
|
component.stub!(:respond_to? => false)
|
84
54
|
lambda { component.no_such_method } \
|
85
55
|
.should raise_error(NoMethodError)
|
@@ -93,41 +63,47 @@ describe Kookaburra::UIDriver::UIComponent do
|
|
93
63
|
browser.should_receive(:has_css?) \
|
94
64
|
.with('#my_component', :visible) \
|
95
65
|
.and_return(true)
|
96
|
-
|
66
|
+
configuration.stub!(:browser => browser)
|
97
67
|
component.stub!(:component_locator => '#my_component')
|
98
68
|
component.visible?.should == true
|
99
69
|
end
|
100
70
|
|
101
71
|
it 'returns false if the component_locator id not found in the DOM' do
|
102
72
|
browser = stub('Browser Driver', :has_css? => false)
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
)
|
73
|
+
configuration.stub!(:browser => browser)
|
74
|
+
server_error_detection = lambda { |browser|
|
75
|
+
false
|
76
|
+
}
|
77
|
+
configuration.stub!(:server_error_detection => server_error_detection)
|
109
78
|
component.stub!(:component_locator => '#my_component')
|
110
79
|
component.visible?.should == false
|
111
80
|
end
|
112
81
|
|
113
82
|
it 'raises UnexpectedResponse if the component_locator is not found and a server error is detected' do
|
114
83
|
browser = stub('Browser Driver', :has_css? => false)
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
)
|
84
|
+
configuration.stub!(:browser => browser)
|
85
|
+
server_error_detection = lambda { |browser|
|
86
|
+
true
|
87
|
+
}
|
88
|
+
configuration.stub!(:server_error_detection => server_error_detection)
|
89
|
+
component.stub!(:component_locator => '#my_component')
|
121
90
|
component.stub!(:component_locator => '#my_component')
|
122
91
|
lambda { component.visible? } \
|
123
92
|
.should raise_error(Kookaburra::UnexpectedResponse)
|
124
93
|
end
|
125
94
|
end
|
126
95
|
|
127
|
-
describe '
|
96
|
+
describe '#url' do
|
97
|
+
it 'returns the app_host + #component_path' do
|
98
|
+
configuration.stub!(:app_host => 'http://my.example.com')
|
99
|
+
component.stub!(:component_path => '/foo/bar')
|
100
|
+
component.url.should == 'http://my.example.com/foo/bar'
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe 'protected methods (for use by subclasses)' do
|
128
105
|
describe '#component_path' do
|
129
106
|
it 'must be defined by subclasses' do
|
130
|
-
component = Kookaburra::UIDriver::UIComponent.new
|
131
107
|
lambda { component.send(:component_path) } \
|
132
108
|
.should raise_error(Kookaburra::ConfigurationError)
|
133
109
|
end
|
@@ -135,23 +111,13 @@ describe Kookaburra::UIDriver::UIComponent do
|
|
135
111
|
|
136
112
|
describe '#component_locator' do
|
137
113
|
it 'must be defined by subclasses' do
|
138
|
-
component = Kookaburra::UIDriver::UIComponent.new
|
139
114
|
lambda { component.send(:component_locator) } \
|
140
115
|
.should raise_error(Kookaburra::ConfigurationError)
|
141
116
|
end
|
142
117
|
end
|
143
118
|
|
144
|
-
|
145
|
-
|
146
|
-
component = Kookaburra::UIDriver::UIComponent.new
|
147
|
-
component.send(:assert, true, "Shouldn't see this message").should == true
|
148
|
-
end
|
149
|
-
|
150
|
-
it 'raises a Kookaburra::AssertionFailed exception if the condition is not truthy' do
|
151
|
-
component = Kookaburra::UIDriver::UIComponent.new
|
152
|
-
lambda { component.send(:assert, false, "False isn't true, dummy.") } \
|
153
|
-
.should raise_error(Kookaburra::AssertionFailed, "False isn't true, dummy.")
|
154
|
-
end
|
119
|
+
it_behaves_like :it_can_make_assertions do
|
120
|
+
let(:subject) { component }
|
155
121
|
end
|
156
122
|
end
|
157
123
|
end
|
@@ -1,21 +1,20 @@
|
|
1
1
|
require 'kookaburra/ui_driver'
|
2
2
|
require 'support/shared_examples/it_has_a_dependency_accessor'
|
3
|
+
require 'support/shared_examples/it_can_make_assertions'
|
3
4
|
|
4
5
|
describe Kookaburra::UIDriver do
|
5
6
|
describe '.ui_component' do
|
6
7
|
it 'adds an accessor method for the named component that defaults to an instance of the specified class' do
|
7
8
|
foo_component_class = mock(Class)
|
8
9
|
foo_component_class.should_receive(:new) \
|
9
|
-
.with(:
|
10
|
-
:app_host => :a_url) \
|
10
|
+
.with(:configuration) \
|
11
11
|
.and_return(:a_foo_component)
|
12
12
|
|
13
13
|
ui_driver_class = Class.new(Kookaburra::UIDriver) do
|
14
14
|
ui_component :foo, foo_component_class
|
15
15
|
end
|
16
16
|
|
17
|
-
ui = ui_driver_class.new(:
|
18
|
-
:app_host => :a_url)
|
17
|
+
ui = ui_driver_class.new(:configuration)
|
19
18
|
ui.foo.should == :a_foo_component
|
20
19
|
end
|
21
20
|
end
|
@@ -24,23 +23,19 @@ describe Kookaburra::UIDriver do
|
|
24
23
|
it 'adds an accessor method for the named driver that defaults to an instance of the specified class' do
|
25
24
|
foo_driver_class = mock(Class)
|
26
25
|
foo_driver_class.should_receive(:new) \
|
27
|
-
.with(:
|
28
|
-
:app_host => :a_url, :mental_model => :a_mental_model) \
|
26
|
+
.with(:configuration) \
|
29
27
|
.and_return(:a_foo_driver)
|
30
28
|
|
31
29
|
ui_driver_class = Class.new(Kookaburra::UIDriver) do
|
32
30
|
ui_driver :foo, foo_driver_class
|
33
31
|
end
|
34
32
|
|
35
|
-
ui = ui_driver_class.new(:
|
36
|
-
:app_host => :a_url, :mental_model => :a_mental_model)
|
33
|
+
ui = ui_driver_class.new(:configuration)
|
37
34
|
ui.foo.should == :a_foo_driver
|
38
35
|
end
|
39
36
|
end
|
40
37
|
|
41
|
-
|
42
|
-
let(:
|
43
|
-
|
44
|
-
it_behaves_like :it_has_a_dependency_accessor, :mental_model
|
38
|
+
it_behaves_like :it_can_make_assertions do
|
39
|
+
let(:subject) { Kookaburra::UIDriver.new(stub('Configuration')) }
|
45
40
|
end
|
46
41
|
end
|