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/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -4,7 +4,6 @@ GEM
|
|
4
4
|
activesupport (3.2.2)
|
5
5
|
i18n (~> 0.6)
|
6
6
|
multi_json (~> 1.0)
|
7
|
-
basic_object (0.0.1)
|
8
7
|
capybara (1.1.2)
|
9
8
|
mime-types (>= 1.16)
|
10
9
|
nokogiri (>= 1.3.3)
|
@@ -76,7 +75,6 @@ PLATFORMS
|
|
76
75
|
|
77
76
|
DEPENDENCIES
|
78
77
|
activesupport (>= 3.0)
|
79
|
-
basic_object
|
80
78
|
capybara
|
81
79
|
i18n
|
82
80
|
jeweler
|
data/README.markdown
CHANGED
@@ -52,17 +52,17 @@ For [RSpec] [RSpec] integration tests, just add the following to
|
|
52
52
|
require 'my_app/kookaburra/given_driver'
|
53
53
|
require 'my_app/kookaburra/ui_driver'
|
54
54
|
|
55
|
-
#
|
55
|
+
# c.app_host below should be set to whatever the root URL of your running
|
56
56
|
# application is.
|
57
|
-
Kookaburra.
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
57
|
+
Kookaburra.configure do |c|
|
58
|
+
c.given_driver_class = MyApp::Kookaburra::GivenDriver
|
59
|
+
c.ui_driver_class = MyApp::Kookaburra::UIDriver
|
60
|
+
c.app_host = 'http://my_app.example.com:1234'
|
61
|
+
c.browser = Capybara
|
62
|
+
c.server_error_detection { |browser|
|
63
63
|
browser.has_css?('head title', :text => 'Internal Server Error')
|
64
64
|
}
|
65
|
-
|
65
|
+
end
|
66
66
|
|
67
67
|
RSpec.configure do |c|
|
68
68
|
c.include(Kookaburra::TestHelpers, :type => :request)
|
@@ -76,17 +76,17 @@ For [Cucumber] [Cucumber], add the following to `features/support/kookaburra_set
|
|
76
76
|
require 'my_app/kookaburra/given_driver'
|
77
77
|
require 'my_app/kookaburra/ui_driver'
|
78
78
|
|
79
|
-
#
|
79
|
+
# c.app_host below should be set to whatever the root URL of your running
|
80
80
|
# application is.
|
81
|
-
Kookaburra.
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
81
|
+
Kookaburra.configure do |c|
|
82
|
+
c.given_driver_class = MyApp::Kookaburra::GivenDriver
|
83
|
+
c.ui_driver_class = MyApp::Kookaburra::UIDriver
|
84
|
+
c.app_host = 'http://my_app.example.com:1234'
|
85
|
+
c.browser = Capybara
|
86
|
+
c.server_error_detection { |browser|
|
87
87
|
browser.has_css?('head title', :text => 'Internal Server Error')
|
88
88
|
}
|
89
|
-
|
89
|
+
end
|
90
90
|
|
91
91
|
World(Kookaburra::TestHelpers)
|
92
92
|
|
@@ -326,7 +326,7 @@ for your application:
|
|
326
326
|
class MyApp::Kookaburra::GivenDriver < Kookaburra::GivenDriver
|
327
327
|
# Specify the APIDriver to use
|
328
328
|
def api
|
329
|
-
@api ||= MyApp::Kookaburra::APIDriver.new(
|
329
|
+
@api ||= MyApp::Kookaburra::APIDriver.new(configuration)
|
330
330
|
end
|
331
331
|
|
332
332
|
def existing_account(nickname)
|
@@ -394,8 +394,8 @@ within your subclass:
|
|
394
394
|
ui_component :sign_in_screen, SignInScreen
|
395
395
|
|
396
396
|
def sign_in(account_nickname)
|
397
|
-
account =
|
398
|
-
sign_in_screen
|
397
|
+
account = mental_model.accounts[account_nickname]
|
398
|
+
address_bar.go_to(sign_in_screen)
|
399
399
|
sign_in_screen.submit_login(account['username'], account['password'])
|
400
400
|
end
|
401
401
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.22.0
|
data/kookaburra.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "kookaburra"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.22.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["John Wilger", "Sam Livingston-Gray", "Ravi Gadad"]
|
@@ -30,24 +30,27 @@ Gem::Specification.new do |s|
|
|
30
30
|
"kookaburra.gemspec",
|
31
31
|
"lib/kookaburra.rb",
|
32
32
|
"lib/kookaburra/api_driver.rb",
|
33
|
+
"lib/kookaburra/assertion.rb",
|
34
|
+
"lib/kookaburra/configuration.rb",
|
33
35
|
"lib/kookaburra/dependency_accessor.rb",
|
34
36
|
"lib/kookaburra/exceptions.rb",
|
35
37
|
"lib/kookaburra/given_driver.rb",
|
36
38
|
"lib/kookaburra/json_api_driver.rb",
|
37
39
|
"lib/kookaburra/mental_model.rb",
|
38
|
-
"lib/kookaburra/null_browser.rb",
|
39
40
|
"lib/kookaburra/test_helpers.rb",
|
40
41
|
"lib/kookaburra/ui_driver.rb",
|
41
42
|
"lib/kookaburra/ui_driver/ui_component.rb",
|
43
|
+
"lib/kookaburra/ui_driver/ui_component/address_bar.rb",
|
42
44
|
"spec/integration/test_a_rack_application_spec.rb",
|
43
45
|
"spec/kookaburra/api_driver_spec.rb",
|
46
|
+
"spec/kookaburra/configuration_spec.rb",
|
44
47
|
"spec/kookaburra/json_api_driver_spec.rb",
|
45
48
|
"spec/kookaburra/mental_model_spec.rb",
|
46
|
-
"spec/kookaburra/
|
47
|
-
"spec/kookaburra/test_helpers_spec.rb",
|
49
|
+
"spec/kookaburra/ui_driver/ui_component/address_bar_spec.rb",
|
48
50
|
"spec/kookaburra/ui_driver/ui_component_spec.rb",
|
49
51
|
"spec/kookaburra/ui_driver_spec.rb",
|
50
52
|
"spec/kookaburra_spec.rb",
|
53
|
+
"spec/support/shared_examples/it_can_make_assertions.rb",
|
51
54
|
"spec/support/shared_examples/it_has_a_dependency_accessor.rb"
|
52
55
|
]
|
53
56
|
s.homepage = "http://github.com/projectdx/kookaburra"
|
@@ -60,7 +63,6 @@ Gem::Specification.new do |s|
|
|
60
63
|
s.specification_version = 3
|
61
64
|
|
62
65
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
63
|
-
s.add_runtime_dependency(%q<basic_object>, [">= 0"])
|
64
66
|
s.add_runtime_dependency(%q<i18n>, [">= 0"])
|
65
67
|
s.add_runtime_dependency(%q<activesupport>, [">= 3.0"])
|
66
68
|
s.add_runtime_dependency(%q<patron>, [">= 0"])
|
@@ -73,7 +75,6 @@ Gem::Specification.new do |s|
|
|
73
75
|
s.add_development_dependency(%q<reek>, [">= 0"])
|
74
76
|
s.add_development_dependency(%q<sinatra>, [">= 0"])
|
75
77
|
else
|
76
|
-
s.add_dependency(%q<basic_object>, [">= 0"])
|
77
78
|
s.add_dependency(%q<i18n>, [">= 0"])
|
78
79
|
s.add_dependency(%q<activesupport>, [">= 3.0"])
|
79
80
|
s.add_dependency(%q<patron>, [">= 0"])
|
@@ -87,7 +88,6 @@ Gem::Specification.new do |s|
|
|
87
88
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
88
89
|
end
|
89
90
|
else
|
90
|
-
s.add_dependency(%q<basic_object>, [">= 0"])
|
91
91
|
s.add_dependency(%q<i18n>, [">= 0"])
|
92
92
|
s.add_dependency(%q<activesupport>, [">= 3.0"])
|
93
93
|
s.add_dependency(%q<patron>, [">= 0"])
|
@@ -4,17 +4,14 @@ require 'patron'
|
|
4
4
|
|
5
5
|
class Kookaburra
|
6
6
|
class APIDriver < SimpleDelegator
|
7
|
-
# Wraps
|
7
|
+
# Wraps `http_client` in a `SimpleDelegator` that causes request methods to
|
8
8
|
# either return the response body or raise an exception on an unexpected
|
9
9
|
# response status code.
|
10
10
|
#
|
11
|
-
# @
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
def initialize(options = {})
|
16
|
-
http_client = options[:http_client] || Patron::Session.new
|
17
|
-
http_client.base_url = options[:app_host] if options.has_key?(:app_host)
|
11
|
+
# @param [Kookaburra::Configuration] configuration
|
12
|
+
# @param [Patron::Session] http_client
|
13
|
+
def initialize(configuration, http_client = Patron::Session.new)
|
14
|
+
http_client.base_url = configuration.app_host
|
18
15
|
super(http_client)
|
19
16
|
end
|
20
17
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'kookaburra/exceptions'
|
2
|
+
|
3
|
+
class Kookaburra
|
4
|
+
# Include this module wherever you need to be able to make a quick,
|
5
|
+
# low-ceremony assertion.
|
6
|
+
module Assertion
|
7
|
+
protected
|
8
|
+
|
9
|
+
# Provides a mechanism to make assertions about the state of your
|
10
|
+
# UIComponent without relying on a specific testing framework. A good
|
11
|
+
# reason to use this would be to provide a more informative error message
|
12
|
+
# when a pre-condition is not met, rather than waiting on an operation
|
13
|
+
# further down the line to fail.
|
14
|
+
#
|
15
|
+
# @param [boolean expression] test an expression that will be evaluated in a boolean context
|
16
|
+
# @param [String] message the exception message that will be used if
|
17
|
+
# test is false
|
18
|
+
#
|
19
|
+
# @raise [Kookaburra::AssertionFailed] raised if test evaluates to false
|
20
|
+
def assert(test, message = "You might want to provide a better message, eh?")
|
21
|
+
test or raise AssertionFailed, message
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'delegate'
|
3
|
+
require 'kookaburra/dependency_accessor'
|
4
|
+
|
5
|
+
class Kookaburra
|
6
|
+
# Provides access to the configuration data used throughout Kookaburra
|
7
|
+
class Configuration
|
8
|
+
extend DependencyAccessor
|
9
|
+
|
10
|
+
# The class to use as your GivenDriver
|
11
|
+
#
|
12
|
+
# @attribute [rw] given_driver_class
|
13
|
+
# @raise [Kookaburra::ConfigurationError] if you try to read this attribute
|
14
|
+
# without it having been set
|
15
|
+
dependency_accessor :given_driver_class
|
16
|
+
|
17
|
+
# The class to use as your UIDriver
|
18
|
+
#
|
19
|
+
# @attribute [rw] ui_driver_class
|
20
|
+
# @raise [Kookaburra::ConfigurationError] if you try to read this attribute
|
21
|
+
# without it having been set
|
22
|
+
dependency_accessor :ui_driver_class
|
23
|
+
|
24
|
+
# This object is used by {Kookaburra::UIDriver::UIComponent} to interface
|
25
|
+
# with the web browser. Typically it should be an instance of
|
26
|
+
# `Capybara::Session`
|
27
|
+
#
|
28
|
+
# @attribute [rw] browser
|
29
|
+
# @raise [Kookaburra::ConfigurationError] if you try to read this attribute
|
30
|
+
# without it having been set
|
31
|
+
dependency_accessor :browser
|
32
|
+
|
33
|
+
# This is the root URL of your running application, including the port
|
34
|
+
# number if necessary. (e.g. "http://my.example.com:12345")
|
35
|
+
#
|
36
|
+
# @attribute [rw] app_host
|
37
|
+
# @raise [Kookaburra::ConfigurationError] if you try to read this attribute
|
38
|
+
# without it having been set
|
39
|
+
dependency_accessor :app_host
|
40
|
+
|
41
|
+
# This is the {Kookaburra::MentalModel} that is shared between your
|
42
|
+
# GivenDriver and your UIDriver. This attribute is managed by {Kookaburra},
|
43
|
+
# so you shouldn't need to change it yourself.
|
44
|
+
#
|
45
|
+
# @attribute [rw] mental_model
|
46
|
+
# @raise [Kookaburra::ConfigurationError] if you try to read this attribute
|
47
|
+
# without it having been set
|
48
|
+
dependency_accessor :mental_model
|
49
|
+
|
50
|
+
# Specify a function that can be used to determine if a server error has
|
51
|
+
# occured within your application.
|
52
|
+
#
|
53
|
+
# If the function returns `true`, then Kookaburra will assume that the
|
54
|
+
# application has responded with an error.
|
55
|
+
#
|
56
|
+
# @yield whichever object was assigned to {#browser}
|
57
|
+
#
|
58
|
+
# @example If the page title is "Internal Server Error"
|
59
|
+
# config.server_error_detection { |browser|
|
60
|
+
# browser.has_css?('head title', :text => 'Internal Server Error')
|
61
|
+
# }
|
62
|
+
def server_error_detection(&blk)
|
63
|
+
if block_given?
|
64
|
+
@server_error_detection = blk
|
65
|
+
else
|
66
|
+
@server_error_detection
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -18,7 +18,10 @@ class Kookaburra
|
|
18
18
|
instance_variable_get("@#{name}") or raise "No %s object was set on %s initialization." \
|
19
19
|
% [name, [self.class.name, 'an Anonymous Class!!!'].reject(&:blank?).first]
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
|
+
define_method("#{name}=") do |value|
|
23
|
+
instance_variable_set("@#{name}", value)
|
24
|
+
end
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
2
|
|
3
3
|
class Kookaburra
|
4
4
|
# Your GivenDriver subclass is used to define your testing DSL for setting up
|
@@ -7,15 +7,14 @@ class Kookaburra
|
|
7
7
|
# comprised of several distinct API calls as well as access to Kookaburra's
|
8
8
|
# test data store.
|
9
9
|
#
|
10
|
-
# @abstract Subclass and implement your Given DSL.
|
11
|
-
# implementation of #api that returns an instance of your APIDriver.
|
10
|
+
# @abstract Subclass and implement your Given DSL.
|
12
11
|
#
|
13
12
|
# @example GivenDriver subclass
|
14
13
|
# module MyApp
|
15
14
|
# module Kookaburra
|
16
15
|
# class GivenDriver < ::Kookaburra::GivenDriver
|
17
16
|
# def api
|
18
|
-
# @api ||= APIDriver.new(
|
17
|
+
# @api ||= APIDriver.new(configuration)
|
19
18
|
# end
|
20
19
|
#
|
21
20
|
# def a_widget(name, attributes = {})
|
@@ -34,22 +33,23 @@ class Kookaburra
|
|
34
33
|
# end
|
35
34
|
# end
|
36
35
|
class GivenDriver
|
37
|
-
extend DependencyAccessor
|
38
|
-
|
39
36
|
# It is unlikely that you would call #initialize yourself; your GivenDriver
|
40
37
|
# object is instantiated for you by {Kookaburra#given}.
|
41
38
|
#
|
42
|
-
# @
|
43
|
-
|
44
|
-
|
45
|
-
# application (e.g. "http://my_app.example.com:12345")
|
46
|
-
def initialize(options = {})
|
47
|
-
@initialization_options = options
|
48
|
-
@mental_model = options[:mental_model]
|
39
|
+
# @param [Kookaburra::Configuration] configuration
|
40
|
+
def initialize(configuration)
|
41
|
+
@configuration = configuration
|
49
42
|
end
|
50
43
|
|
51
44
|
protected
|
52
45
|
|
46
|
+
attr_reader :configuration
|
47
|
+
|
48
|
+
# Access to the shared {Kookaburra::MentalModel} instance
|
49
|
+
#
|
50
|
+
# @attribute [rw] mental_model
|
51
|
+
delegate :mental_model, :to => :configuration
|
52
|
+
|
53
53
|
# Used to access your APIDriver in your own GivenDriver implementation
|
54
54
|
#
|
55
55
|
# @abstract
|
@@ -59,18 +59,5 @@ class Kookaburra
|
|
59
59
|
def api
|
60
60
|
raise ConfigurationError, "You must implement #api in your subclass."
|
61
61
|
end
|
62
|
-
|
63
|
-
# The full set of options passed in to {#initialize}
|
64
|
-
#
|
65
|
-
# Access is provided so that you can use these when instantiating your
|
66
|
-
# {APIDriver} in your {#api} implementation.
|
67
|
-
attr_reader :initialization_options
|
68
|
-
|
69
|
-
# A reference to the {Kookaburra::MentalModel} object that this GivenDriver
|
70
|
-
# instance was created with.
|
71
|
-
#
|
72
|
-
# @attribute [r]
|
73
|
-
# @return [Kookaburra::MentalModel]
|
74
|
-
dependency_accessor :mental_model
|
75
62
|
end
|
76
63
|
end
|
@@ -14,11 +14,12 @@ class Kookaburra
|
|
14
14
|
#
|
15
15
|
# Sets both the "Content-Type" and "Accept" headers to "application/json".
|
16
16
|
#
|
17
|
-
# @
|
17
|
+
# @param [Kookaburra::Configuration] configuration
|
18
|
+
# @param [Kookaburra::APIDriver] api_driver (Kookaburra::APIDriver.new)
|
18
19
|
# The APIDriver instance to be delegated to. Changing this is probably
|
19
|
-
# only useful for testing.
|
20
|
-
def initialize(
|
21
|
-
api_driver =
|
20
|
+
# only useful for testing Kookaburra itself.
|
21
|
+
def initialize(configuration, api_driver = nil)
|
22
|
+
api_driver = api_driver || APIDriver.new(configuration)
|
22
23
|
api_driver.headers.merge!(
|
23
24
|
'Content-Type' => 'application/json',
|
24
25
|
'Accept' => 'application/json'
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'kookaburra'
|
2
|
+
require 'active_support/core_ext/module/delegation'
|
2
3
|
|
3
4
|
class Kookaburra
|
4
5
|
# This module is intended to be mixed in to your testing context to provide
|
@@ -12,15 +13,15 @@ class Kookaburra
|
|
12
13
|
# require 'my_app/kookaburra/given_driver'
|
13
14
|
# require 'my_app/kookaburra/ui_driver'
|
14
15
|
#
|
15
|
-
# Kookaburra.
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# browser.has_css?('h1', text: '
|
16
|
+
# Kookaburra.configure do |c|
|
17
|
+
# c.given_driver_class = myapp::kookaburra::givendriver,
|
18
|
+
# c.ui_driver_class = myapp::kookaburra::uidriver,
|
19
|
+
# c.app_host = 'http://my_app.example.com:12345',
|
20
|
+
# c.browser = capybara,
|
21
|
+
# c.server_error_detection { |browser|
|
22
|
+
# browser.has_css?('h1', text: 'internal server error')
|
22
23
|
# }
|
23
|
-
#
|
24
|
+
# end
|
24
25
|
#
|
25
26
|
# RSpec.configure do |c|
|
26
27
|
# c.include(Kookaburra::TestHelpers, :type => :request)
|
@@ -49,15 +50,15 @@ class Kookaburra
|
|
49
50
|
# require 'my_app/kookaburra/given_driver'
|
50
51
|
# require 'my_app/kookaburra/ui_driver'
|
51
52
|
#
|
52
|
-
# Kookaburra.
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
# browser.has_css?('h1', text: '
|
53
|
+
# Kookaburra.configure do |c|
|
54
|
+
# c.given_driver_class = myapp::kookaburra::givendriver,
|
55
|
+
# c.ui_driver_class = myapp::kookaburra::uidriver,
|
56
|
+
# c.app_host = 'http://my_app.example.com:12345',
|
57
|
+
# c.browser = capybara,
|
58
|
+
# c.server_error_detection { |browser|
|
59
|
+
# browser.has_css?('h1', text: 'internal server error')
|
59
60
|
# }
|
60
|
-
#
|
61
|
+
# end
|
61
62
|
#
|
62
63
|
# World(Kookaburra::TestHelpers)
|
63
64
|
#
|
@@ -85,7 +86,7 @@ class Kookaburra
|
|
85
86
|
#
|
86
87
|
# @return [Kookaburra]
|
87
88
|
def k
|
88
|
-
@k ||= Kookaburra.new
|
89
|
+
@k ||= Kookaburra.new
|
89
90
|
end
|
90
91
|
|
91
92
|
# @method given
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'kookaburra/ui_driver/ui_component'
|
2
|
+
|
3
|
+
class Kookaburra
|
4
|
+
class UIDriver
|
5
|
+
class UIComponent
|
6
|
+
# This represents the browser's address bar, so that you can tell your
|
7
|
+
# tests to explicitly visit a URL.
|
8
|
+
class AddressBar < UIComponent
|
9
|
+
# Causes the browser to explicitly navigate to the given url.
|
10
|
+
#
|
11
|
+
# @param [String, #url] addressable Can be either a URL string or an
|
12
|
+
# object that responds to #url and returns a URL string
|
13
|
+
def go_to(addressable)
|
14
|
+
if addressable.respond_to?(:url)
|
15
|
+
browser.visit(addressable.url)
|
16
|
+
else
|
17
|
+
browser.visit(addressable.to_s)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'kookaburra/exceptions'
|
2
|
+
require 'kookaburra/assertion'
|
2
3
|
require 'active_support/core_ext/object/try'
|
3
4
|
|
4
5
|
class Kookaburra
|
@@ -63,26 +64,21 @@ class Kookaburra
|
|
63
64
|
# element.
|
64
65
|
#
|
65
66
|
# @abstract Subclass and implement (at least) {#component_locator}. Unless
|
66
|
-
# you override the default implementation of {#
|
67
|
+
# you override the default implementation of {#url}, you must also
|
67
68
|
# override the {#component_path} method.
|
68
69
|
class UIComponent
|
70
|
+
include Assertion
|
71
|
+
|
69
72
|
# New UIComponent instances are typically created for you by your
|
70
73
|
# {Kookaburra::UIDriver} instance.
|
71
74
|
#
|
72
75
|
# @see Kookaburra::UIDriver.ui_component
|
73
76
|
#
|
74
|
-
# @
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
# the object passed in to the :browser option as an argument and must
|
80
|
-
# return `true` if the server responded with an unexpected error or
|
81
|
-
# `false` if it did not.
|
82
|
-
def initialize(options = {})
|
83
|
-
@browser = options[:browser]
|
84
|
-
@app_host = options[:app_host]
|
85
|
-
@server_error_detection = options[:server_error_detection]
|
77
|
+
# @param [Kookaburra::Configuration] configuration
|
78
|
+
def initialize(configuration)
|
79
|
+
@browser = configuration.browser
|
80
|
+
@app_host = configuration.app_host
|
81
|
+
@server_error_detection = configuration.server_error_detection
|
86
82
|
end
|
87
83
|
|
88
84
|
# If the UIComponent is sent a message it does not understand, it will
|
@@ -107,27 +103,6 @@ class Kookaburra
|
|
107
103
|
super || browser.respond_to?(name)
|
108
104
|
end
|
109
105
|
|
110
|
-
# Causes the UIComponent to be visible.
|
111
|
-
#
|
112
|
-
# The browser to navigates directly to {#component_path} (unless the
|
113
|
-
# component is already visible).
|
114
|
-
#
|
115
|
-
# You may need to override this method in your own UIComponent subclasses,
|
116
|
-
# especially for components that are dynamically added/removed on the page
|
117
|
-
# in response to user actions. The implementation should not make any
|
118
|
-
# assumptions about the current state of the user interface before it is
|
119
|
-
# invoked.
|
120
|
-
#
|
121
|
-
# @param args Any arguments are passed to the {#component_path} method.
|
122
|
-
#
|
123
|
-
# @raise [RuntimeError] if the component is not visible after attempting
|
124
|
-
# to make it so.
|
125
|
-
def show(*args)
|
126
|
-
return if visible?
|
127
|
-
browser.visit component_url(*args)
|
128
|
-
assert visible?, "The #{self.class.name} component is not visible!"
|
129
|
-
end
|
130
|
-
|
131
106
|
# Is the component's element found on the page and is it considered
|
132
107
|
# "visible" by the browser driver.
|
133
108
|
def visible?
|
@@ -138,30 +113,16 @@ class Kookaburra
|
|
138
113
|
visible
|
139
114
|
end
|
140
115
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
# If no :browser option was specified in {#initialize}, it returns a
|
146
|
-
# default {Kookaburra::NullBrowser} instance.
|
147
|
-
def browser
|
148
|
-
@browser ||= NullBrowser.new
|
116
|
+
# Returns the full URL by appending {#component_path} to the value of the
|
117
|
+
# {Kookaburra::Configuration#app_host} from the initialized configuration.
|
118
|
+
def url(*args)
|
119
|
+
"#{@app_host}#{component_path(*args)}"
|
149
120
|
end
|
150
121
|
|
151
|
-
|
152
|
-
|
153
|
-
#
|
154
|
-
|
155
|
-
# further down the line to fail.
|
156
|
-
#
|
157
|
-
# @param test an expression that will be evaluated in a boolean context
|
158
|
-
# @param [String] message the exception message that will be used if
|
159
|
-
# test is false
|
160
|
-
#
|
161
|
-
# @raise [Kookaburra::AssertionFailed] raised if test evaluates to false
|
162
|
-
def assert(test, message = "You might want to provide a better message, eh?")
|
163
|
-
test or raise AssertionFailed, message
|
164
|
-
end
|
122
|
+
protected
|
123
|
+
|
124
|
+
# The browser object from the initialized configuration
|
125
|
+
attr_reader :browser
|
165
126
|
|
166
127
|
# @abstract
|
167
128
|
# @return [String] the URL path that should be loaded in order to reach this component
|
@@ -171,12 +132,6 @@ class Kookaburra
|
|
171
132
|
raise ConfigurationError, "You must define #{self.class.name}#component_path."
|
172
133
|
end
|
173
134
|
|
174
|
-
# Returns the full URL by appending {#component_path} to the value of the
|
175
|
-
# :app_host option passed to {#initialize}.
|
176
|
-
def component_url(*args)
|
177
|
-
"#{@app_host}#{component_path(*args)}"
|
178
|
-
end
|
179
|
-
|
180
135
|
# @abstract
|
181
136
|
# @return [String] the CSS3 selector that will find the element in the DOM
|
182
137
|
# @raise [Kookaburra::ConfigurationError] raised if you haven't provided
|
@@ -185,7 +140,8 @@ class Kookaburra
|
|
185
140
|
raise ConfigurationError, "You must define #{self.class.name}#component_locator."
|
186
141
|
end
|
187
142
|
|
188
|
-
# Runs the server error detection function specified in
|
143
|
+
# Runs the server error detection function specified in
|
144
|
+
# {Kookaburra::Configuration#server_error_detection}.
|
189
145
|
#
|
190
146
|
# It's a noop if no server error detection was specified.
|
191
147
|
#
|