kookaburra 0.26.0 → 0.26.1

Sign up to get free protection for your applications and to get access to all the features.
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: