napybara 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 53a5710df7b6badb61d443588bec50cd7d179618
4
- data.tar.gz: 61e611ff8fa988a70190860db4e0b8800cb010ce
3
+ metadata.gz: c7b2cbbf480b100b3a1adc606cfa57b05868f860
4
+ data.tar.gz: 2a4ec7daa20873ffb807f49eba6302d4aa9171d1
5
5
  SHA512:
6
- metadata.gz: 7e25b434912b12dc7175089a32433d62a24ec4b1d8a533e80e4a86c46c98d6e04b157528aa37a7462dbaf930f51cd7e2f6725297db3366fc9ef0901f47f37503
7
- data.tar.gz: 81beacfbd669927f9798c7c4ecec8333f88bbb16fe285aee98d0836f6ba7c6d3f87b5fa62ee744a8e44719bd9c41c055ae0a1879e48f509c44e24d523af92a22
6
+ metadata.gz: b5661e2643515c2fa34eacef4702e1aa577f17f84ee4f02a9d0cf7d7929f544613ad183cc6c1ecf1ef6b78a584958376d634997d415819aa3b85a89794901e5f
7
+ data.tar.gz: 7eff003cfac47e53c8f476679e123630913f7eb289dc59bf71fbe48063bee022b049b0ddfa805ac35eeaaa05b2ec7d3f72b56735a512eddec629dce7842ca2f6
@@ -3,5 +3,4 @@ rvm:
3
3
  - 1.9.3
4
4
  - 2.0.0
5
5
  - 2.1.0
6
- - rbx
7
6
  cache: bundler
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## master
4
+
5
+ Rename `#get` as #node. `#get` may become deprecated soon.
6
+
7
+ Add `#selector`.
8
+
3
9
  ## 0.4.1
4
10
 
5
11
  Update README.
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Napybara
2
2
 
3
+ [![Build Status](https://api.travis-ci.org/gsmendoza/napybara.svg)](https://travis-ci.org/gsmendoza/napybara)
4
+
3
5
  So you're writing an integration test for the following page:
4
6
 
5
7
  ```html
@@ -19,12 +21,13 @@ So you're writing an integration test for the following page:
19
21
  </html>
20
22
  ```
21
23
 
22
- Wouldn't it be nice if your test helpers followed the page's structure?
24
+ Wouldn't it be nice if you can write test helpers that followed the page's
25
+ structure?
23
26
 
24
27
  ```ruby
25
28
  messages_page.visit!
26
29
 
27
- messages_page.form.message_row.text_field.get.set 'Hello World!'
30
+ messages_page.form.message_row.text_field.node.set 'Hello World!'
28
31
  messages_page.form.submit!
29
32
 
30
33
  expect(messages_page.message(Message.find(1))).to have_content('Hello world!')
@@ -36,7 +39,7 @@ expect(messages_page.messages[1]).to have_content('Kamusta mundo!')
36
39
 
37
40
  With Napybara, now you can!
38
41
 
39
- ## Napybara::Element.new and #get
42
+ ## Napybara::Element.new and #node
40
43
 
41
44
  First off, let's wrap the Capybara session in a Napybara element:
42
45
 
@@ -49,10 +52,10 @@ end
49
52
  In Rails integration tests which use Capybara, `self` is usually the Capybara session.
50
53
 
51
54
  You can get the Capybara element wrapped by the Napybara element with
52
- `Napybara::Element#get`:
55
+ `Napybara::Element#node`:
53
56
 
54
57
  ```ruby
55
- expect(messages_page.get).to eq(self)
58
+ expect(messages_page.node).to eq(self)
56
59
  ```
57
60
 
58
61
  ## Finding by selector
@@ -68,7 +71,7 @@ end
68
71
 
69
72
  # ...
70
73
 
71
- expect(messages_page.form.get['class']).to eq('new-message')
74
+ expect(messages_page.form.node['class']).to eq('new-message')
72
75
  ```
73
76
 
74
77
  ## Finding by object
@@ -89,7 +92,7 @@ end
89
92
 
90
93
  # ...
91
94
 
92
- expect(messages_page.message(some_message).get['id'])
95
+ expect(messages_page.message(some_message).node['id'])
93
96
  .to eq("message-#{some_message.id}")
94
97
 
95
98
  ```
@@ -106,7 +109,7 @@ If the ruby object is identified by a method other than the object's id, you can
106
109
  `Napybara::Element#finder` also adds `has_` and `has_no_` methods to the element.
107
110
  With the Napybara elements above, you can call:
108
111
 
109
- ```
112
+ ```ruby
110
113
  expect(messages_page.has_form?).to be_true
111
114
  expect(messages_page).to have_form
112
115
 
@@ -136,8 +139,8 @@ end
136
139
 
137
140
  # ...
138
141
 
139
- expect(messages_page.messages[0].get.text).to eq("Hello world!")
140
- expect(messages_page.messages[1].get.text).to eq("Kamusta mundo!")
142
+ expect(messages_page.messages[0].node.text).to eq("Hello world!")
143
+ expect(messages_page.messages[1].node.text).to eq("Kamusta mundo!")
141
144
  ```
142
145
 
143
146
  Napybara uses ActiveSupport to get the plural version of the finder name.
@@ -150,7 +153,7 @@ You can add new methods to a Napybara element with plain Ruby:
150
153
  let(:messages_page) do
151
154
  Napybara::Element.new(self) do |page|
152
155
  def page.visit!
153
- get.visit get.messages_path
156
+ node.visit node.messages_path
154
157
  end
155
158
  end
156
159
  end
@@ -167,7 +170,7 @@ Adding the same methods to multiple Napybara elements? You can share the methods
167
170
  ```ruby
168
171
  module PageExtensions
169
172
  def visit!
170
- get.visit get.messages_path
173
+ node.visit node.messages_path
171
174
  @visited = true
172
175
  end
173
176
 
@@ -192,10 +195,10 @@ expect(messages_page).to be_visited
192
195
 
193
196
  And what if you want to share a module with finders? Again, with plain Ruby:
194
197
 
195
- ```
198
+ ```ruby
196
199
  module IsAForm
197
200
  def submit!
198
- submit_button.get.click
201
+ submit_button.node.click
199
202
  end
200
203
 
201
204
  def self.add_to(form)
@@ -222,7 +225,7 @@ helpers at the start of this README:
222
225
 
223
226
  module PageExtensions
224
227
  def visit!
225
- get.visit get.messages_path
228
+ node.visit node.messages_path
226
229
  @visited = true
227
230
  end
228
231
 
@@ -233,7 +236,7 @@ end
233
236
 
234
237
  module IsAForm
235
238
  def submit!
236
- submit_button.get.click
239
+ submit_button.node.click
237
240
  end
238
241
 
239
242
  def self.add_to(form)
@@ -243,7 +246,7 @@ module IsAForm
243
246
  end
244
247
 
245
248
  let(:messages_page) do
246
- Napybara::Element.new(capybara_page) do |page|
249
+ Napybara::Element.new(self) do |page|
247
250
  page.extend PageExtensions
248
251
 
249
252
  page.finder :form, 'form.new-message' do |form|
@@ -259,6 +262,27 @@ let(:messages_page) do
259
262
  end
260
263
  ```
261
264
 
265
+ ## And a few more things: getting the selector of a finder
266
+
267
+ `Napybara::Element#selector` returns a selector that can be used to find the element:
268
+
269
+ ```ruby
270
+ expect(messages_page.form.message_row.text_field.selector)
271
+ .to eq('form.new-message .message-row input[type=text]')
272
+
273
+ expect(messages_page.message(Message.find(2)).selector)
274
+ .to eq('#message-2')
275
+
276
+ expect(messages_page.messages.selector)
277
+ .to eq('.message-list .message')
278
+
279
+ expect(messages_page.messages[1].selector)
280
+ .to eq('.message-list .message')
281
+
282
+ ```
283
+
284
+ Take note that with `messages_page.messages[1]`, it's currently not possible to get the ith match of a selector. We'll have to wait until [`nth-match`](http://www.w3.org/TR/selectors4/#nth-match-pseudo) becomes mainstream.
285
+
262
286
  ## Installation
263
287
 
264
288
  ```
@@ -4,4 +4,6 @@ module Napybara
4
4
  end
5
5
 
6
6
  require "napybara/element"
7
+ require "napybara/element_array"
8
+ require "napybara/selector"
7
9
  require "napybara/version"
@@ -2,18 +2,24 @@ require 'napybara'
2
2
 
3
3
  module Napybara
4
4
  class Element
5
- attr_reader :capybara_element
6
- alias_method :get, :capybara_element
5
+ attr_reader :node, :parent, :selector_string
6
+
7
+ alias_method :get, :node
8
+
9
+ def initialize(node, parent = nil, selector_string = nil, &block)
10
+ @node = node
11
+ @parent = parent
12
+ @selector_string = selector_string
7
13
 
8
- def initialize(capybara_element, &block)
9
- @capybara_element = capybara_element
10
14
  block.call(self) if block_given?
11
15
  end
12
16
 
13
17
  def finder(child_element_name, child_element_selector, record_selector = nil, &block)
14
18
  self.define_singleton_method(child_element_name) do |record = nil|
15
19
  selector = Selector.new(child_element_selector, record_selector, record)
16
- self.class.new(self.get.find(selector.to_s), &block)
20
+ selector_string = selector.to_s
21
+
22
+ self.class.new(self.get.find(selector_string), self, selector_string, &block)
17
23
  end
18
24
 
19
25
  self.define_singleton_method("has_#{child_element_name}?") do |record = nil|
@@ -27,29 +33,19 @@ module Napybara
27
33
  end
28
34
 
29
35
  self.define_singleton_method(child_element_name.to_s.pluralize) do
30
- self.get.all(child_element_selector).map do |child_element|
31
- self.class.new(child_element, &block)
32
- end
33
- end
34
- end
36
+ elements = self.get.all(child_element_selector)
37
+ .map.with_index do |child_element, i|
35
38
 
36
- class Selector < Struct.new(:child_element_selector, :record_selector, :record)
37
- METHOD_NAME_REGEX = /\{(\w+)\}/
38
- def method_name
39
- record_selector.match(METHOD_NAME_REGEX)[1]
40
- end
39
+ self.class.new(child_element, self, child_element_selector, &block)
40
+ end
41
41
 
42
- def record_id
43
- record && record.public_send(method_name)
42
+ ElementArray.new(elements, self, child_element_selector)
44
43
  end
44
+ end
45
45
 
46
- def to_s
47
- if record
48
- record_selector.gsub(METHOD_NAME_REGEX, record_id.to_s)
49
- else
50
- child_element_selector
51
- end
52
- end
46
+ def selector
47
+ parent_selector = parent.try(:selector)
48
+ parent_selector ? "#{parent_selector} #{selector_string}" : selector_string
53
49
  end
54
50
  end
55
51
  end
@@ -0,0 +1,14 @@
1
+ module Napybara
2
+ class ElementArray < Array
3
+ def initialize(elements, parent, selector_string = '')
4
+ @parent = parent
5
+ @selector_string = selector_string
6
+ super(elements)
7
+ end
8
+
9
+ def selector
10
+ parent_selector = @parent.try(:selector)
11
+ parent_selector ? "#{@parent.selector} #{@selector_string}" : @selector_string
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+ module Napybara
2
+ class Selector < Struct.new(:child_element_selector, :record_selector, :record)
3
+ METHOD_NAME_REGEX = /\{(\w+)\}/
4
+ def method_name
5
+ record_selector.match(METHOD_NAME_REGEX)[1]
6
+ end
7
+
8
+ def record_id
9
+ record && record.public_send(method_name)
10
+ end
11
+
12
+ def to_s
13
+ if record
14
+ record_selector.gsub(METHOD_NAME_REGEX, record_id.to_s)
15
+ else
16
+ child_element_selector
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module Napybara
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -11,7 +11,7 @@ describe 'Readme example:' do
11
11
  <li class="message" id="message-2">Kamusta mundo!</li>
12
12
  </ul>
13
13
  <form class='new-message'>
14
- <div class="message-row" />
14
+ <div class="message-row">
15
15
  <label for='message'>Message</label>
16
16
  <input id='message' type='text' name='message'>
17
17
  </div>
@@ -30,8 +30,8 @@ describe 'Readme example:' do
30
30
  @messages_page = Napybara::Element.new(capybara_page)
31
31
  end
32
32
 
33
- And "I call #get on the Napybara page" do
34
- @get_result = @messages_page.get
33
+ And "I call #node on the Napybara page" do
34
+ @get_result = @messages_page.node
35
35
  end
36
36
 
37
37
  Then "I should get the capybara page" do
@@ -52,7 +52,7 @@ describe 'Readme example:' do
52
52
 
53
53
  Then "the finder should be able to find the element matching the selector" do
54
54
 
55
- expect(@messages_page.form.get['class']).to eq('new-message')
55
+ expect(@messages_page.form.node['class']).to eq('new-message')
56
56
  end
57
57
  end
58
58
 
@@ -70,7 +70,7 @@ describe 'Readme example:' do
70
70
  Then "the finder should be able to find the element matching a given object" do
71
71
  id = 1
72
72
  message = OpenStruct.new(id: id)
73
- expect(@messages_page.message(message).get['id']).to eq("message-#{id}")
73
+ expect(@messages_page.message(message).node['id']).to eq("message-#{id}")
74
74
  end
75
75
  end
76
76
 
@@ -114,8 +114,8 @@ describe 'Readme example:' do
114
114
  Then "I should be able to find all the elements matching the selector with
115
115
  a plural version of the finder name" do
116
116
 
117
- expect(@messages_page.message_items[0].get.text).to eq("Hello world!")
118
- expect(@messages_page.message_items[1].get.text).to eq("Kamusta mundo!")
117
+ expect(@messages_page.message_items[0].node.text).to eq("Hello world!")
118
+ expect(@messages_page.message_items[1].node.text).to eq("Kamusta mundo!")
119
119
  end
120
120
  end
121
121
 
@@ -169,4 +169,37 @@ describe 'Readme example:' do
169
169
  expect(@messages_page).to be_visited
170
170
  end
171
171
  end
172
+
173
+ Steps "Getting the selector of a finder" do
174
+ Given "I have a a capybara page" do
175
+ capybara_page
176
+ end
177
+
178
+ When "I wrap the page in a Napybara element" do
179
+ @messages_page = Napybara::Element.new(capybara_page) do |page|
180
+ page.finder :form, 'form.new-message' do |form|
181
+
182
+ form.finder :message_row, '.message-row' do |row|
183
+ row.finder :text_field, 'input[type=text]'
184
+ end
185
+ end
186
+
187
+ page.finder :message, '.messages-list .message', '#message-{id}'
188
+ end
189
+ end
190
+
191
+ Then "I can get the selectors of the Napybara finder results" do
192
+ expect(@messages_page.form.message_row.text_field.selector)
193
+ .to eq('form.new-message .message-row input[type=text]')
194
+
195
+ expect(@messages_page.message(OpenStruct.new(id: 2)).selector)
196
+ .to eq('#message-2')
197
+
198
+ expect(@messages_page.messages.selector)
199
+ .to eq('.messages-list .message')
200
+
201
+ expect(@messages_page.messages[1].selector)
202
+ .to eq('.messages-list .message')
203
+ end
204
+ end
172
205
  end
@@ -104,4 +104,80 @@ describe Napybara::Element do
104
104
  expect(page.has_no_form?(object)).to be_false
105
105
  end
106
106
  end
107
+
108
+ describe "#selector" do
109
+ it "can return the selector for a single element" do
110
+ napybara_page = described_class.new(capybara_page) do |page|
111
+ page.finder :form, '.some-form'
112
+ end
113
+
114
+ expect(napybara_page.form.selector).to eq('.some-form')
115
+ end
116
+
117
+ it "can return the selector for an element nested one layer" do
118
+ napybara_page = described_class.new(capybara_page) do |page|
119
+ page.finder :form, '.some-form' do |form|
120
+ form.finder :some_button, '.some-button'
121
+ end
122
+ end
123
+
124
+ expect(napybara_page.form.some_button.selector).to eq('.some-form .some-button')
125
+ end
126
+
127
+ it "can return the selector for an element nested more than one layer" do
128
+ napybara_page = described_class.new(capybara_page) do |page|
129
+ page.finder :form, '.some-form' do |form|
130
+ form.finder :some_button, '.some-button' do |button|
131
+ button.finder :img, 'img'
132
+ end
133
+ end
134
+ end
135
+
136
+ expect(napybara_page.form.some_button.img.selector)
137
+ .to eq('.some-form .some-button img')
138
+ end
139
+
140
+ it "can return the selector for an element array" do
141
+ napybara_page = described_class.new(capybara_page) do |page|
142
+ page.finder :button, 'button'
143
+ end
144
+
145
+ expect(napybara_page.buttons.selector).to eq('button')
146
+ end
147
+
148
+ context "where the items of the element array are not adjacent" do
149
+ let(:capybara_page) do
150
+ Capybara.string <<-HTML
151
+ <form class='some-form', id='form-1'>
152
+ <button class='recognized-button some-button' />
153
+ <button class='ignored-button' />
154
+ <button class='recognized-button another-button' />
155
+ </form>
156
+ HTML
157
+ end
158
+
159
+ it "can return the selector of the ith item of an element array" do
160
+ napybara_page = described_class.new(capybara_page) do |page|
161
+ page.finder :button, '.recognized-button'
162
+ end
163
+
164
+ first_button = napybara_page.buttons[1]
165
+
166
+ expect(first_button.selector).to eq('.recognized-button')
167
+
168
+ expect(napybara_page.node.all(first_button.selector)[1]['class'])
169
+ .to eq('recognized-button another-button')
170
+ end
171
+ end
172
+
173
+ it "can return the selector of an child of an element array item" do
174
+ napybara_page = described_class.new(capybara_page) do |page|
175
+ page.finder :button, 'button' do |button|
176
+ button.finder :image, 'img'
177
+ end
178
+ end
179
+
180
+ expect(napybara_page.buttons[0].image.selector).to eq('button img')
181
+ end
182
+ end
107
183
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: napybara
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - George Mendoza
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-18 00:00:00.000000000 Z
11
+ date: 2014-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -198,6 +198,8 @@ files:
198
198
  - Rakefile
199
199
  - lib/napybara.rb
200
200
  - lib/napybara/element.rb
201
+ - lib/napybara/element_array.rb
202
+ - lib/napybara/selector.rb
201
203
  - lib/napybara/version.rb
202
204
  - napybara.gemspec
203
205
  - spec/dummy_app/config.ru