kookaburra 0.26.0 → 0.26.1

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/VERSION CHANGED
@@ -1 +1 @@
1
- 0.26.0
1
+ 0.26.1
data/kookaburra.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "kookaburra"
8
- s.version = "0.26.0"
8
+ s.version = "0.26.1"
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"]
12
- s.date = "2012-07-27"
12
+ s.date = "2012-07-28"
13
13
  s.description = "Cucumber + Capybara = Kookaburra? It made sense at the time."
14
14
  s.email = "johnwilger@gmail.com"
15
15
  s.extra_rdoc_files = [
@@ -41,6 +41,7 @@ Gem::Specification.new do |s|
41
41
  "lib/kookaburra/test_helpers.rb",
42
42
  "lib/kookaburra/ui_driver.rb",
43
43
  "lib/kookaburra/ui_driver/has_ui_components.rb",
44
+ "lib/kookaburra/ui_driver/scoped_browser.rb",
44
45
  "lib/kookaburra/ui_driver/ui_component.rb",
45
46
  "lib/kookaburra/ui_driver/ui_component/address_bar.rb",
46
47
  "spec/integration/test_a_rack_application_spec.rb",
@@ -50,6 +51,7 @@ Gem::Specification.new do |s|
50
51
  "spec/kookaburra/mental_model_matcher_spec.rb",
51
52
  "spec/kookaburra/mental_model_spec.rb",
52
53
  "spec/kookaburra/test_helpers_spec.rb",
54
+ "spec/kookaburra/ui_driver/scoped_browser_spec.rb",
53
55
  "spec/kookaburra/ui_driver/ui_component/address_bar_spec.rb",
54
56
  "spec/kookaburra/ui_driver/ui_component_spec.rb",
55
57
  "spec/kookaburra/ui_driver_spec.rb",
@@ -73,8 +73,8 @@ class Kookaburra
73
73
  #
74
74
  # @note This is semantically the same as `Hash#slice` as provided
75
75
  # by `ActiveSupport::CoreExt::Hash`
76
- # @param [Object] *keys The keys that should be copied from the
77
- # collection
76
+ # @param [Object] keys The list of keys that should be copied from
77
+ # the collection
78
78
  # @return [Hash] The resulting keys/values from the collection
79
79
  def slice(*keys)
80
80
  data = keys.inject({}) { |memo, key|
@@ -88,8 +88,8 @@ class Kookaburra
88
88
  #
89
89
  # @note This is semantically the same as `Hash#except` as provided
90
90
  # by `ActiveSupport::CoreExt::Hash`
91
- # @param [Object] *keys The keys that should *not* be copied from
92
- # the collection
91
+ # @param [Object] keys The list of keys that should *not* be
92
+ # copied from the collection
93
93
  # @return [Hash] The resulting keys/values from the collection
94
94
  def except(*keys)
95
95
  slice(*(self.keys - keys))
@@ -0,0 +1,34 @@
1
+ class Kookaburra
2
+ class UIDriver
3
+ # Wraps a Kookaburra `browser` object and changes all method calls
4
+ # to that object so that they are scoped within the specified
5
+ # `component_locator`.
6
+ class ScopedBrowser < BasicObject
7
+
8
+ # @param [Object] browser The browser driver object used by
9
+ # Kookaburra to drive the browser session
10
+ # @param [Proc] component_locator A Proc that will return the CSS
11
+ # locator used to identify the HTML element within which all
12
+ # calls to this object should be scoped. (A Proc is used rather
13
+ # than a string, because it is possible that the object creating
14
+ # this `ScopedBrowser` will not know the correct string at the
15
+ # time this object is created.)
16
+ def initialize(browser, component_locator)
17
+ @browser = browser
18
+ @component_locator = component_locator
19
+ end
20
+
21
+ private
22
+
23
+ def component_locator
24
+ @component_locator.call
25
+ end
26
+
27
+ def method_missing(name, *args, &blk)
28
+ @browser.within(component_locator) do
29
+ @browser.send(name, *args, &blk)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,6 +1,8 @@
1
+ require 'delegate'
1
2
  require 'kookaburra/exceptions'
2
3
  require 'kookaburra/assertion'
3
4
  require 'kookaburra/ui_driver/has_ui_components'
5
+ require 'kookaburra/ui_driver/scoped_browser'
4
6
 
5
7
  class Kookaburra
6
8
  class UIDriver
@@ -59,14 +61,13 @@ class Kookaburra
59
61
  # end
60
62
  #
61
63
  # Note that the "browser operation" methods such as `#fill_in` and
62
- # `#click_button` are forwarded to the {#browser} object (see
63
- # {#method_missing}) and are automatically scoped to the component's DOM
64
- # element.
64
+ # `#click_button` are delegated to a {ScopedBrowser} and are
65
+ # automatically scoped to the component's DOM element.
65
66
  #
66
67
  # @abstract Subclass and implement (at least) {#component_locator}. Unless
67
68
  # you override the default implementation of {#url}, you must also
68
69
  # override the {#component_path} method.
69
- class UIComponent
70
+ class UIComponent < SimpleDelegator
70
71
  include Assertion
71
72
  extend HasUIComponents
72
73
 
@@ -92,28 +93,8 @@ class Kookaburra
92
93
  @browser = configuration.browser
93
94
  @app_host = configuration.app_host
94
95
  @server_error_detection = configuration.server_error_detection
95
- end
96
-
97
- # If the UIComponent is sent a message it does not understand, it will
98
- # forward that message on to its {#browser} but wrap the call in a block
99
- # provided to the the browser's `#within` method. This provides convenient
100
- # access to the browser driver's DSL, automatically scoped to this
101
- # component.
102
- def method_missing(name, *args, &block)
103
- if respond_to?(name)
104
- browser.within(component_locator) do
105
- browser.send(name, *args, &block)
106
- end
107
- else
108
- super
109
- end
110
- end
111
-
112
- # @private
113
- # (Not really private, but YARD seemingly lacks RDoc's :nodoc tag, and the
114
- # semantics here don't differ from Object#respond_to?)
115
- def respond_to?(name)
116
- super || browser.respond_to?(name)
96
+ scoped_browser = ScopedBrowser.new(@browser, lambda { component_locator })
97
+ super(scoped_browser)
117
98
  end
118
99
 
119
100
  # Is the component's element found on the page and is it considered
@@ -0,0 +1,11 @@
1
+ require 'kookaburra/ui_driver/scoped_browser'
2
+
3
+ describe Kookaburra::UIDriver::ScopedBrowser do
4
+ it 'forwards all method calls to the browser but scopes them to the component locator' do
5
+ browser = mock('Browser')
6
+ browser.should_receive(:within).with('#a_component_locator').and_yield
7
+ browser.should_receive(:some_other_method).with(:foo)
8
+ subject = Kookaburra::UIDriver::ScopedBrowser.new(browser, lambda { '#a_component_locator' })
9
+ subject.some_other_method(:foo)
10
+ end
11
+ end
@@ -8,58 +8,6 @@ describe Kookaburra::UIDriver::UIComponent do
8
8
 
9
9
  it_behaves_like :it_can_have_ui_components, Kookaburra::UIDriver::UIComponent
10
10
 
11
- describe '#respond_to?' do
12
- let(:component) do
13
- klass = Class.new(Kookaburra::UIDriver::UIComponent) do
14
- def foo
15
- end
16
- end
17
- klass.new(configuration)
18
- end
19
-
20
- it 'returns true if the UIComponent defines the specified method' do
21
- component.respond_to?(:foo).should == true
22
- end
23
-
24
- it 'returns true if the #browser defines the specified method' do
25
- browser = stub('Browser Driver', :respond_to? => true)
26
- component.stub!(:browser => browser)
27
- component.respond_to?(:a_very_unlikely_method_name).should == true
28
- end
29
-
30
- it 'returns false if neither the UIComponent nor the #browser define the specified method' do
31
- browser = stub('Browser Driver', :respond_to? => false)
32
- component.stub!(:browser => browser)
33
- component.respond_to?(:a_very_unlikely_method_name).should == false
34
- end
35
- end
36
-
37
- describe '#method_missing' do
38
- context 'the component says it responds to the method' do
39
- it 'scopes the method call within the component_locator and forwards to #browser' do
40
- browser = mock('Browser Driver')
41
- browser.should_receive(:some_browser_method) \
42
- .with(:arguments) \
43
- .and_return(:answer_from_browser)
44
- browser.should_receive(:within) do |scope, &block|
45
- scope.should == '#my_component'
46
- block.call(browser)
47
- end
48
- configuration.stub!(:browser => browser)
49
- component.stub!(:component_locator => '#my_component')
50
- component.some_browser_method(:arguments).should == :answer_from_browser
51
- end
52
- end
53
-
54
- context 'the component says it does not respond to the method' do
55
- it 'raises a NoMethodError' do
56
- component.stub!(:respond_to? => false)
57
- lambda { component.no_such_method } \
58
- .should raise_error(NoMethodError)
59
- end
60
- end
61
- end
62
-
63
11
  describe '#visible?' do
64
12
  it 'returns true if the component_locator is found in the DOM and is visible' do
65
13
  browser = mock('Browser Driver')
@@ -67,7 +15,9 @@ describe Kookaburra::UIDriver::UIComponent do
67
15
  .with('#my_component', :visible) \
68
16
  .and_return(true)
69
17
  configuration.stub!(:browser => browser)
70
- component.stub!(:component_locator => '#my_component')
18
+ def component.component_locator
19
+ '#my_component'
20
+ end
71
21
  component.visible?.should == true
72
22
  end
73
23
 
@@ -78,7 +28,9 @@ describe Kookaburra::UIDriver::UIComponent do
78
28
  false
79
29
  }
80
30
  configuration.stub!(:server_error_detection => server_error_detection)
81
- component.stub!(:component_locator => '#my_component')
31
+ def component.component_locator
32
+ '#my_component'
33
+ end
82
34
  component.visible?.should == false
83
35
  end
84
36
 
@@ -89,8 +41,9 @@ describe Kookaburra::UIDriver::UIComponent do
89
41
  true
90
42
  }
91
43
  configuration.stub!(:server_error_detection => server_error_detection)
92
- component.stub!(:component_locator => '#my_component')
93
- component.stub!(:component_locator => '#my_component')
44
+ def component.component_locator
45
+ '#my_component'
46
+ end
94
47
  lambda { component.visible? } \
95
48
  .should raise_error(Kookaburra::UnexpectedResponse)
96
49
  end
@@ -99,7 +52,9 @@ describe Kookaburra::UIDriver::UIComponent do
99
52
  describe '#url' do
100
53
  it 'returns the app_host + #component_path' do
101
54
  configuration.stub!(:app_host => 'http://my.example.com')
102
- component.stub!(:component_path => '/foo/bar')
55
+ def component.component_path
56
+ '/foo/bar'
57
+ end
103
58
  component.url.should == 'http://my.example.com/foo/bar'
104
59
  end
105
60
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kookaburra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.0
4
+ version: 0.26.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-07-27 00:00:00.000000000 Z
14
+ date: 2012-07-28 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: patron
@@ -205,6 +205,7 @@ files:
205
205
  - lib/kookaburra/test_helpers.rb
206
206
  - lib/kookaburra/ui_driver.rb
207
207
  - lib/kookaburra/ui_driver/has_ui_components.rb
208
+ - lib/kookaburra/ui_driver/scoped_browser.rb
208
209
  - lib/kookaburra/ui_driver/ui_component.rb
209
210
  - lib/kookaburra/ui_driver/ui_component/address_bar.rb
210
211
  - spec/integration/test_a_rack_application_spec.rb
@@ -214,6 +215,7 @@ files:
214
215
  - spec/kookaburra/mental_model_matcher_spec.rb
215
216
  - spec/kookaburra/mental_model_spec.rb
216
217
  - spec/kookaburra/test_helpers_spec.rb
218
+ - spec/kookaburra/ui_driver/scoped_browser_spec.rb
217
219
  - spec/kookaburra/ui_driver/ui_component/address_bar_spec.rb
218
220
  - spec/kookaburra/ui_driver/ui_component_spec.rb
219
221
  - spec/kookaburra/ui_driver_spec.rb
@@ -236,7 +238,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
236
238
  version: '0'
237
239
  segments:
238
240
  - 0
239
- hash: -40301256200075417
241
+ hash: -3509025074302937225
240
242
  required_rubygems_version: !ruby/object:Gem::Requirement
241
243
  none: false
242
244
  requirements: