capybara-wheel 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -10,11 +10,28 @@ Capybara wheel is a page model framework which natively and (hopefully) easily e
10
10
  - Enforces single point of reference to selectors / elements.
11
11
  - Also helps reducing memoizations.
12
12
 
13
- - Subelements structure to scope finds to a specific section of the page.
13
+ - Element hierarchy structure to scope finds to a specific section of the page.
14
14
  - Reduces ambiguity.
15
15
 
16
16
  *A special thank you to @woollyams for the initial concept*
17
17
 
18
+ ## Why Wheel?
19
+
20
+ Browser driven acceptance tests are notorious for being unstable and hard to maintain. The main culprits are:
21
+
22
+ 1. Timing issues which result in unstable waits and "is the page loaded?" queries accross the specs.
23
+
24
+ 2. Memoizing the state of the page (e.g. `search_result = Capybara.find('li')` ) at a certain time. Each spec run might memoize a different state, leading to unstable tests.
25
+
26
+ 3. No convention around page interactions (e.g. sometimes calling a page model, sometimes a native find with a selector).
27
+
28
+ Wheel solves all these by forcing the spec to always act or query the currect state of the page.
29
+ If the page is not in a state that the spec expects, the native Capybara wait will be used until it is; removing the need to `sleep` or build mechanics to test for page loads.
30
+
31
+ Specs are always written in one uniform, clean, way - always calling the same model when dealing with the same page / element. No more hunting multiple specs to change a selector.
32
+
33
+ The Element model DSL is still eaily customisable just like "normal" page model classes so domain specfic applications are just as easy, resulting in descriptive, easy to read specs.
34
+
18
35
  ## Installation
19
36
 
20
37
  Add this line to your application's Gemfile:
@@ -46,7 +63,7 @@ To model a new page:
46
63
 
47
64
  class NewPage < Capybara::Wheel::Page
48
65
 
49
- A page needs to implament two methods:
66
+ A page needs to implement two methods:
50
67
 
51
68
  def path
52
69
  # implament to support visiting the page directly
@@ -65,22 +82,22 @@ A page needs to implament two methods:
65
82
  # e.g. Capybara.find('h1', text: 'Login Page')
66
83
  end
67
84
 
68
- > Example:
69
- >
70
- > class SuperVillanConsole << Capybara::Wheel::Page
71
- >
72
- > def path
73
- > super_villan_console_path
74
- > end
75
- >
76
- > def on_page?
77
- > has_title?('Destroy all humans')
78
- > end
79
- > end
85
+ **_Example:_**
86
+
87
+ class SuperVillanConsole << Capybara::Wheel::Page
88
+
89
+ def path
90
+ super_villan_console_path
91
+ end
92
+
93
+ def on_page?
94
+ has_title?('Destroy all humans')
95
+ end
96
+ end
80
97
 
81
98
  ***
82
99
 
83
- ### Element and Subelement model
100
+ ### Element model
84
101
 
85
102
  #### Element
86
103
 
@@ -96,54 +113,69 @@ The `element` method does several important things:
96
113
  1. It defines a Page method element_name which allows access and initializes...
97
114
  2. an Element model
98
115
 
99
- Out of the box, Element accepts all the old familar Capybara Element actions / queries (e.g. click, set, text, visible?).Once an action or query is sent to a Wheel element it then finds the native Capybara element and passes it on. This ensures that each method call is executed on the newset version of the element.
116
+ Out of the box, Element accepts all the old familar Capybara Element actions / queries (e.g. click, set, text, visible?). Once an action or query is sent to a Wheel element it then finds the native Capybara element and passes it on. This ensures that each method call is executed on the newset version of the element.
100
117
 
101
- Passing a block to element gives access to the Element object for the purpose of implamenting SubElements (see below) or rolling your own methods:
118
+ Passing a block to element gives access to the Element object for the purpose of implamenting a subelement (see below) or rolling your own customised methods:
102
119
 
103
120
  **The `capybara_element` method is the direct accessor to the native Capybara element callback.**
104
121
 
105
- > Example
106
- >
107
- > element 'ButtonOfDoom', '#doom-button' do
108
- >
109
- > def armed?
110
- > capybara_element.text == 'Armed'
111
- > end
112
- >
113
- > end
114
- >
115
- > element 'MissleTracker', '.missle-tracker'
116
- >
117
- >
118
- > #=> SuperVillanConsole.new.button_of_doom.armed?
119
- >
120
- > #=> SuperVillanConsole.new.missle_tracker.visible?
121
- >
122
-
123
-
124
- #### Subelement
125
-
126
- An element block also accepts the `subelement` method.
127
-
128
- subelement 'SubElementName', 'selector' *optional block*
129
-
130
- A subelement behaves exactly like element with one difference, the find is scoped to the containing (or parent) element which reduces ambiguity.
131
-
132
- > Example
133
- >
134
- > element 'ButtonOfDoom', '#doom-button' do
135
- >
136
- > subelement 'ArmingKey', '#key' do
137
- >
138
- > def turn
139
- > capybara_element.click
140
- > end
141
- >
142
- > end
143
- > end
144
- >
145
- > #=> SuperVillanConsole.new.button_of_doom.turn
122
+ **_Example:_**
123
+
124
+ element 'ButtonOfDoom', '#doom-button' do
125
+
126
+ def armed?
127
+ capybara_element.text == 'Armed'
128
+ end
129
+
130
+ end
131
+
132
+ element 'MissleTracker', '.missle-tracker'
133
+
134
+
135
+ #=> SuperVillanConsole.new.button_of_doom.armed?
136
+
137
+ #=> SuperVillanConsole.new.missle_tracker.visible?
138
+
139
+
140
+
141
+ #### (Sub)Element
142
+
143
+ An element block also accepts the `element` method.
144
+
145
+ element 'SubElementName', 'selector' *optional block*
146
+
147
+ When called inside an element block, the element behaves like an Element but is now scoped to the containing (or parent) element, which reduces ambiguity.
148
+
149
+ **_Example:_**
150
+
151
+ Two buttons have an `li` element with the `.key` class. We want to be able to find one and turn it without accidently causing world peace:
152
+
153
+ element 'ButtonOfDoom', '#doom-button' do
154
+
155
+ # reference to this key is scoped inside the #doom-button element
156
+ element 'ArmingKey', 'li.key' do
157
+
158
+ def turn
159
+ capybara_element.click
160
+ end
161
+
162
+ end
163
+ end
164
+
165
+ element 'ButtonOfWorldPeace', '#peace-button' do
166
+
167
+ # reference to this key is scoped inside the #peace-button element
168
+ element 'ArmingKey', 'li.key' do
169
+
170
+ def turn
171
+ capybara_element.click
172
+ end
173
+
174
+ end
175
+ end
146
176
 
177
+ #=> SuperVillanConsole.new.button_of_world_peace.arming_key.turn
178
+ #=> SuperVillanConsole.new.button_of_doom.arming_key.turn
147
179
  ***
148
180
  ***
149
181
  ***
@@ -156,4 +188,4 @@ A subelement behaves exactly like element with one difference, the find is scope
156
188
  2. Create your feature branch (`git checkout -b my-new-feature`)
157
189
  3. Commit your changes (`git commit -am 'Add some feature'`)
158
190
  4. Push to the branch (`git push origin my-new-feature`)
159
- 5. Create new Pull Request
191
+ 5. Create new Pull Request
@@ -1,5 +1,5 @@
1
1
  Dir.glob(File.join(File.dirname(__FILE__), 'wheel', '*.rb')).each {|file| require file}
2
- require "capybara"
2
+ require 'capybara'
3
3
  require 'capybara/dsl'
4
4
  require 'rspec'
5
5
 
@@ -9,8 +9,11 @@ module Capybara
9
9
  include Capybara::Wheel::Includes
10
10
  extend Capybara::Wheel::Includes::ClassIncludes
11
11
 
12
- def initialize(selector = nil)
12
+ attr_reader :scope
13
+
14
+ def initialize(selector = nil, scope = nil)
13
15
  @selector = selector if selector
16
+ @scope = scope
14
17
  end
15
18
 
16
19
  def_delegators :capybara_element,
@@ -46,17 +49,30 @@ module Capybara
46
49
  false
47
50
  end
48
51
 
49
- def self.subelement(name, selector, block = nil)
52
+ def self.element(name, selector, block = nil)
50
53
  subelement_factory = lambda do |parent_element|
51
- Capybara::Wheel::ElementFactory.create_subelement(selector, parent_element, block)
54
+ Capybara::Wheel::ElementFactory.create_element(selector, parent_element, block)
52
55
  end
53
56
 
54
57
  define_method(underscore(name).to_sym) { subelement_factory.call(self) }
55
58
  self
56
59
  end
57
60
 
61
+ def element(name, selector, &block)
62
+ self.class.element(name, selector, block)
63
+ end
64
+
65
+ #TODO: deprecated in 0.0.5
58
66
  def subelement(name, selector, &block)
59
- self.class.subelement(name, selector, block)
67
+ puts "subelement will be deprecated in future versions."
68
+ puts "Calling element inside an element block will scope it to the parent element"
69
+ element(name, selector, block)
70
+ end
71
+
72
+ def self.subelement(name, selector, &block)
73
+ puts "subelement will be deprecated in future versions."
74
+ puts "Calling element inside an element block will scope it to the parent element"
75
+ element(name, selector, &block)
60
76
  end
61
77
 
62
78
  def selector
@@ -65,9 +81,14 @@ module Capybara
65
81
 
66
82
  protected
67
83
 
84
+
68
85
  # Finds a capybara element representing this thing
69
86
  def capybara_element
70
- capybara.find(selector)
87
+ scope_capybara.find(selector)
88
+ end
89
+
90
+ def scope_capybara
91
+ scope.nil? ? capybara : scope.send(:capybara_element)
71
92
  end
72
93
 
73
94
  end
@@ -10,7 +10,7 @@ module Capybara
10
10
  _selector = selector
11
11
 
12
12
  subclass.class_exec do
13
- define_method(:selector) { @selector = _selector}
13
+ define_method(:selector) { @selector = _selector }
14
14
  end
15
15
 
16
16
  subclass.class_eval(&block) if block
@@ -19,8 +19,8 @@ module Capybara
19
19
  end
20
20
 
21
21
  #TODO: Pass object not an instance
22
- def self.create_subelement(selector, parent_element, block = nil)
23
- subelement = Capybara::Wheel::SubElement.new(selector, parent_element)
22
+ def self.create_element(selector, parent_element, block = nil)
23
+ subelement = Capybara::Wheel::Element.new(selector, parent_element)
24
24
  subelement.instance_eval(&block) if block
25
25
 
26
26
  subelement
@@ -37,7 +37,6 @@ module Capybara
37
37
  raise NotImplementedError, "implement me, e.g. using #has_title?"
38
38
  end
39
39
 
40
- # callback commonly used for on_page?
41
40
  def has_title?(expected_title)
42
41
  capybara.has_css?("head title", :text => expected_title)
43
42
  end
@@ -1,5 +1,5 @@
1
1
  module Capybara
2
2
  module Wheel
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'ElementFactory' do
4
+ let(:subject) { Capybara::Wheel::ElementFactory }
5
+ let(:selector) { '#rad-selector'}
6
+ let(:created_element_klass) { subject.create_element_klass(selector) }
7
+
8
+
9
+ it 'creates an element' do
10
+ created_element_klass.superclass.should == Capybara::Wheel::Element
11
+ end
12
+
13
+ it 'allows access to the selector' do
14
+ created_element_klass.new.selector.should == selector
15
+ end
16
+
17
+ it 'generated instance evalutes block' do
18
+ test_block = Proc.new do
19
+ def evaled_method
20
+ end
21
+ end
22
+
23
+ subject.create_element_klass(selector, test_block).new.should respond_to(:evaled_method)
24
+ end
25
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Element' do
4
+ let(:element_selector) { '#some-selector' }
5
+ let(:element) { Capybara::Wheel::Element }
6
+ let(:element_instance) { element.new(element_selector) }
7
+
8
+ it 'has access to capybara' do
9
+ element_instance.methods.include?(:capybara).should be_true
10
+ end
11
+
12
+ it 'has delegators for Capybara actions' do
13
+ pending 'grab all the actions from Capybara and ensure delegators are implemented'
14
+ end
15
+
16
+ context 'self.element' do
17
+ let(:element_selector) { '#rad-parent-selector' }
18
+
19
+ let(:subelement_name) { 'RadSubElement' }
20
+ let(:subelement_selector) { '#rad-sub-selector' }
21
+
22
+ before do
23
+ element_instance.instance_eval do
24
+ element('RadSubElement', '#rad-sub-selector')
25
+ end
26
+ end
27
+
28
+ it 'created a method for calling the element' do
29
+ element_instance.should respond_to(:rad_sub_element)
30
+ end
31
+
32
+ it 'create a (sub)element with parent element context' do
33
+ element_instance.send(:rad_sub_element).scope.should == element_instance
34
+ end
35
+
36
+ it 'the find would be scoped to parent' do
37
+ subelement = element_instance.send(:rad_sub_element)
38
+ mock_capybara_session = mock(Capybara::Session)
39
+ mock_capybara_element = mock('Capybara::Element')
40
+ Capybara.stub!(:current_session).and_return(mock_capybara_session)
41
+ mock_capybara_session.stub(:find).with(element_selector).and_return(mock_capybara_element)
42
+ mock_capybara_element.stub(:find).with(subelement_selector).and_return(mock_capybara_element)
43
+
44
+ element_instance.should_receive(:capybara_element).once.and_return(mock_capybara_element)
45
+
46
+ subelement.send(:capybara_element)
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.configure do |config|
4
+ config.before(:each, :some_hook) do
5
+ @hook_passed_on = true
6
+ end
7
+ end
8
+
9
+ feature 'runs as a wheel feature', :some_hook do
10
+
11
+ it 'should pass' do
12
+ end
13
+
14
+ it 'should be set as a wheel feature' do
15
+ example.metadata[:type].should == :wheel_feature
16
+ end
17
+
18
+ it 'should pass the right hook' do
19
+ @hook_passed_on.should be_true
20
+ end
21
+ end
data/spec/page_spec.rb ADDED
@@ -0,0 +1,16 @@
1
+ require 'spec_helper'
2
+
3
+ feature 'Page' do
4
+ let(:page) { Capybara::Wheel::Page }
5
+
6
+ it 'has access to capybara' do
7
+ page.new.methods.include?(:capybara).should be_true
8
+ end
9
+
10
+ context 'can create an element instance' do
11
+ it 'and create a method for it' do
12
+ page.element('RadElement', '#rad-selector').new.should respond_to(:rad_element)
13
+ end
14
+ end
15
+
16
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'capybara/wheel'
1
2
  require 'rspec'
2
3
  require 'pry'
3
4
 
metadata CHANGED
@@ -1,18 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara-wheel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
- - '@gabrielrotbart'
8
+ - ! '@gabrielrotbart'
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-07-08 00:00:00.000000000 Z
12
+ date: 2013-07-17 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: bundler
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - ~>
18
20
  - !ruby/object:Gem::Version
@@ -20,6 +22,7 @@ dependencies:
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
27
  - - ~>
25
28
  - !ruby/object:Gem::Version
@@ -27,34 +30,39 @@ dependencies:
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: rake
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - '>='
35
+ - - ! '>='
32
36
  - !ruby/object:Gem::Version
33
37
  version: '0'
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - '>='
43
+ - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: '0'
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: rspec
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
- - - '>='
51
+ - - ! '>='
46
52
  - !ruby/object:Gem::Version
47
53
  version: '0'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
- - - '>='
59
+ - - ! '>='
53
60
  - !ruby/object:Gem::Version
54
61
  version: '0'
55
62
  - !ruby/object:Gem::Dependency
56
63
  name: selenium-webdriver
57
64
  requirement: !ruby/object:Gem::Requirement
65
+ none: false
58
66
  requirements:
59
67
  - - ~>
60
68
  - !ruby/object:Gem::Version
@@ -62,6 +70,7 @@ dependencies:
62
70
  type: :development
63
71
  prerelease: false
64
72
  version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
65
74
  requirements:
66
75
  - - ~>
67
76
  - !ruby/object:Gem::Version
@@ -69,6 +78,7 @@ dependencies:
69
78
  - !ruby/object:Gem::Dependency
70
79
  name: sinatra
71
80
  requirement: !ruby/object:Gem::Requirement
81
+ none: false
72
82
  requirements:
73
83
  - - ~>
74
84
  - !ruby/object:Gem::Version
@@ -76,6 +86,7 @@ dependencies:
76
86
  type: :development
77
87
  prerelease: false
78
88
  version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
79
90
  requirements:
80
91
  - - ~>
81
92
  - !ruby/object:Gem::Version
@@ -83,20 +94,23 @@ dependencies:
83
94
  - !ruby/object:Gem::Dependency
84
95
  name: pry
85
96
  requirement: !ruby/object:Gem::Requirement
97
+ none: false
86
98
  requirements:
87
- - - '>='
99
+ - - ! '>='
88
100
  - !ruby/object:Gem::Version
89
101
  version: '0'
90
102
  type: :development
91
103
  prerelease: false
92
104
  version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
93
106
  requirements:
94
- - - '>='
107
+ - - ! '>='
95
108
  - !ruby/object:Gem::Version
96
109
  version: '0'
97
110
  - !ruby/object:Gem::Dependency
98
111
  name: capybara
99
112
  requirement: !ruby/object:Gem::Requirement
113
+ none: false
100
114
  requirements:
101
115
  - - ~>
102
116
  - !ruby/object:Gem::Version
@@ -104,6 +118,7 @@ dependencies:
104
118
  type: :runtime
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
107
122
  requirements:
108
123
  - - ~>
109
124
  - !ruby/object:Gem::Version
@@ -111,15 +126,17 @@ dependencies:
111
126
  - !ruby/object:Gem::Dependency
112
127
  name: rspec
113
128
  requirement: !ruby/object:Gem::Requirement
129
+ none: false
114
130
  requirements:
115
- - - '>='
131
+ - - ! '>='
116
132
  - !ruby/object:Gem::Version
117
133
  version: '0'
118
134
  type: :runtime
119
135
  prerelease: false
120
136
  version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
121
138
  requirements:
122
- - - '>='
139
+ - - ! '>='
123
140
  - !ruby/object:Gem::Version
124
141
  version: '0'
125
142
  description: Keeping the rodent on track
@@ -140,35 +157,41 @@ files:
140
157
  - lib/capybara/wheel/element_factory.rb
141
158
  - lib/capybara/wheel/includes.rb
142
159
  - lib/capybara/wheel/page.rb
143
- - lib/capybara/wheel/subelement.rb
144
160
  - lib/capybara/wheel/version.rb
161
+ - spec/element_factory_spec.rb
162
+ - spec/element_spec.rb
163
+ - spec/feature_spec.rb
164
+ - spec/page_spec.rb
145
165
  - spec/spec_helper.rb
146
- - spec/wheel_spec.rb
147
166
  homepage: ''
148
167
  licenses:
149
168
  - MIT
150
- metadata: {}
151
169
  post_install_message:
152
170
  rdoc_options: []
153
171
  require_paths:
154
172
  - lib
155
173
  required_ruby_version: !ruby/object:Gem::Requirement
174
+ none: false
156
175
  requirements:
157
- - - '>='
176
+ - - ! '>='
158
177
  - !ruby/object:Gem::Version
159
178
  version: '0'
160
179
  required_rubygems_version: !ruby/object:Gem::Requirement
180
+ none: false
161
181
  requirements:
162
- - - '>='
182
+ - - ! '>='
163
183
  - !ruby/object:Gem::Version
164
184
  version: '0'
165
185
  requirements: []
166
186
  rubyforge_project:
167
- rubygems_version: 2.0.3
187
+ rubygems_version: 1.8.25
168
188
  signing_key:
169
- specification_version: 4
189
+ specification_version: 3
170
190
  summary: Creating (yet another) page model gem based around making capybara tests
171
191
  more stable with no need for waits
172
192
  test_files:
193
+ - spec/element_factory_spec.rb
194
+ - spec/element_spec.rb
195
+ - spec/feature_spec.rb
196
+ - spec/page_spec.rb
173
197
  - spec/spec_helper.rb
174
- - spec/wheel_spec.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: fd80ae9d800e4bff8293c3c6a913e0817915ee8e
4
- data.tar.gz: 83f9bafd3a783f3c5503704e7b0f16988c4073db
5
- SHA512:
6
- metadata.gz: 65aed3f76018833406c291d04acea02753f5541d672c0de57311eb1c6f1a406aa4caba3957dc2e463a70c93279f52df612fb8296e741ad77f3ff531673beba6e
7
- data.tar.gz: a793890e6f6ae8f8ffbcb361c7bd68f5acf502cd1ba9b3c098601bc18558fa98001a04db98bb96f41d9f6b493c8f4e236cc0d2093e3fb7659b6a53a0550e6f4a
@@ -1,24 +0,0 @@
1
- require 'capybara/wheel/includes'
2
-
3
- module Capybara
4
- module Wheel
5
- class SubElement < Capybara::Wheel::Element
6
- attr_reader :parent
7
-
8
- def initialize(selector, parent)
9
- @parent = parent
10
- @selector = selector
11
- end
12
-
13
- private
14
- def capybara_element
15
- parent_element.find(selector)
16
- end
17
-
18
- def parent_element
19
- parent.send(:capybara_element)
20
- end
21
-
22
- end
23
- end
24
- end
data/spec/wheel_spec.rb DELETED
@@ -1,108 +0,0 @@
1
- require 'spec_helper'
2
- require 'capybara/wheel'
3
-
4
- RSpec.configure do |config|
5
- config.before(:each, :some_hook) do
6
- @hook_passed_on = true
7
- end
8
- end
9
-
10
- feature 'runs as a wheel feature', :some_hook do
11
-
12
- it 'should pass' do
13
- end
14
-
15
- it 'should be set as a wheel feature' do
16
- example.metadata[:type].should == :wheel_feature
17
- end
18
-
19
- it 'should pass the right hook' do
20
- @hook_passed_on.should be_true
21
- end
22
- end
23
-
24
- feature 'Page' do
25
- let(:page) { Capybara::Wheel::Page }
26
-
27
- it 'has access to capybara' do
28
- page.new.methods.include?(:capybara).should be_true
29
- end
30
-
31
- context 'can create an element instance' do
32
- it 'and create a method for it' do
33
- page.element('RadElement', '#rad-selector').new.should respond_to(:rad_element)
34
- end
35
- end
36
-
37
- end
38
-
39
- feature 'Element' do
40
- let(:element) { Capybara::Wheel::Element }
41
-
42
- it 'has access to capybara' do
43
- element.new('#some-selector').methods.include?(:capybara).should be_true
44
- end
45
-
46
- context 'can create a subelement instance' do
47
- let(:subelement_name) { 'RadSubElement' }
48
- let(:subelement_selector) { '#rad-sub-selector' }
49
- let(:element_instance) { element.new.subelement(subelement_name, subelement_selector).new('#rad-selector') }
50
-
51
- it 'and create a method for it' do
52
- element_instance.should respond_to(:rad_sub_element)
53
- end
54
-
55
- it 'create a subelement with parent element context' do
56
- element_instance.send(:rad_sub_element).parent.should == element_instance
57
- end
58
- end
59
-
60
- end
61
-
62
- feature 'SubElement' do
63
- let(:parent_selector) { '#parent-selector'}
64
- let(:sub_selector) { '#sub-selector'}
65
- let!(:parent_element) { Capybara::Wheel::Element.new(parent_selector) }
66
- let!(:subelement) { class ASubElement < Capybara::Wheel::SubElement
67
- def my_element
68
- capybara_element
69
- end
70
- end }
71
-
72
- before :each do
73
- parent_element.instance_eval do
74
- def a_sub_element
75
- ASubElement.new('#sub-selector', self)
76
- end
77
- end
78
- end
79
-
80
- it 'calls parent element capybara_element' do
81
- pending
82
- end
83
-
84
- end
85
-
86
- feature 'ElementFactory' do
87
- let(:subject) { Capybara::Wheel::ElementFactory }
88
- let(:selector) { '#rad-selector'}
89
- let(:created_element_klass) { subject.create_element_klass(selector) }
90
-
91
-
92
- it 'creates an element' do
93
- created_element_klass.superclass.should == Capybara::Wheel::Element
94
- end
95
-
96
- it 'allows access to the selector' do
97
- created_element_klass.new.selector.should == selector
98
- end
99
-
100
- it 'generated instance evalutes block' do
101
- test_block = Proc.new do
102
- def evaled_method
103
- end
104
- end
105
-
106
- subject.create_element_klass(selector, test_block).new.should respond_to(:evaled_method)
107
- end
108
- end