capybara-extensions 0.2.0 → 0.3.0

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.
@@ -0,0 +1,74 @@
1
+ require_relative 'locators'
2
+
3
+ module CapybaraExtensions::Matchers
4
+ include CapybaraExtensions::Locators
5
+ CapybaraExtensions::ExtensionMethods.concat [:has_field_value?, :has_no_field_value?, :has_image?, :has_no_image?, :has_meta_tag?, :has_no_meta_tag?]
6
+
7
+ # Checks that the current node has an image with the given src or alt.
8
+ #
9
+ # @param options [Hash] must pass a hash containing src and/or alt to match against.
10
+ # @return [Boolean] true if the image matches.
11
+ #
12
+ def has_image?(options = {})
13
+ raise "Must pass a hash containing 'src' or 'alt'" unless options.is_a?(Hash) && (options.has_key?(:src) || options.has_key?(:alt))
14
+ has_selector?(:xpath, "//img#{image_locator(options)}")
15
+ end
16
+
17
+ # Checks that the current node does not have an image with the given src or alt.
18
+ #
19
+ # @param options [Hash] must pass a hash containing src and/or alt to match against.
20
+ # @return [Boolean] true if the image does not match.
21
+ #
22
+ def has_no_image?(options = {})
23
+ raise "Must pass a hash with 'alt' or 'src'" unless options.is_a?(Hash) and (options.has_key?(:alt) or options.has_key?(:src))
24
+ has_no_selector?(:xpath, "//img#{image_locator(options)}")
25
+ end
26
+
27
+ # Checks that the value of a field matches a given value. Typically, you'll want to scope this to a form.
28
+ #
29
+ # @param locator [String] the label, name, or id of the field.
30
+ # @param text [String] the text to match against the field value.
31
+ # @return [Boolean] true if the field value matches.
32
+ #
33
+ def has_field_value?(locator, text)
34
+ if find_field(locator).value == text
35
+ true
36
+ else
37
+ raise Capybara::ExpectationNotMet, "expected to find field #{locator} with a value of #{text}."
38
+ end
39
+ end
40
+
41
+ # Checks that the value of a field does not match a given value. Typically, you'll want to scope this to a form.
42
+ #
43
+ # @param locator [String] the label, name, or id of the field.
44
+ # @param text [String] the text to match against the field value.
45
+ # @return [Boolean] true if the field value does not match.
46
+ #
47
+ def has_no_field_value?(locator, text)
48
+ if find_field(locator).value != text
49
+ true
50
+ else
51
+ raise Capybara::ExpectationNotMet, "expected to not find field #{locator} with a value of #{text}."
52
+ end
53
+ end
54
+
55
+ # Checks the that the content of a meta tag matches a given value.
56
+ #
57
+ # @param name [String] the name attribute of the meta tag.
58
+ # @param content [String] the value of the content attribute to match against.
59
+ # @return [Boolean] true if the meta tag content matches the name.
60
+ #
61
+ def has_meta_tag?(name, content)
62
+ has_selector?(:xpath, "/html/head/meta#{meta_tag_locator(name, content)}", visible: false)
63
+ end
64
+
65
+ # Checks the that the content of a meta tag does not match a given value.
66
+ #
67
+ # @param name [String] the name attribute of the meta tag.
68
+ # @param content [String] the value of the content attribute to match against.
69
+ # @return [Boolean] true if the meta tag content does not match the name.
70
+ #
71
+ def has_no_meta_tag?(name, content)
72
+ has_no_selector?(:xpath, "/html/head/meta#{meta_tag_locator(name, content)}", visible: false)
73
+ end
74
+ end
@@ -0,0 +1,3 @@
1
+ module CapybaraExtensions
2
+ VERSION = "0.3.0"
3
+ end
@@ -1,12 +1,30 @@
1
- require 'rubygems'
2
1
  require 'capybara'
2
+ require 'capybara_minitest_spec'
3
3
 
4
- module Capybara
5
- module Node
6
- module Finders
7
- def parent
8
- find(:xpath, '..')
9
- end
4
+ module CapybaraExtensions
5
+ ExtensionMethods = []
6
+ end
7
+
8
+ require 'capybara-extensions/finders'
9
+ require 'capybara-extensions/matchers'
10
+
11
+ module Capybara::DSL
12
+ CapybaraExtensions::ExtensionMethods.each do |method|
13
+ define_method method do |*args, &block|
14
+ page.send method, *args, &block
15
+ end
16
+ end
17
+ end
18
+
19
+ class Capybara::Session
20
+ CapybaraExtensions::ExtensionMethods.each do |method|
21
+ define_method method do |*args, &block|
22
+ current_scope.send method, *args, &block
10
23
  end
11
24
  end
12
25
  end
26
+
27
+ Capybara::Node::Base.send(:include, CapybaraExtensions::Finders)
28
+ Capybara::Node::Base.send(:include, CapybaraExtensions::Matchers)
29
+ Capybara::Node::Simple.send(:include, CapybaraExtensions::Matchers)
30
+ Capybara::Node::Simple.send(:include, CapybaraExtensions::Finders)
@@ -0,0 +1,353 @@
1
+ require 'test_helper'
2
+
3
+ describe '.string' do
4
+ let(:post) { Post.new(3) }
5
+ let(:string) { Capybara.string TestString }
6
+ let(:unique) { 'John Doe' }
7
+ let(:multiple) { 'Jane Doe' }
8
+
9
+ # Finders
10
+ # article
11
+ #
12
+ describe '#find_article' do
13
+ it 'finds the article when passed a unique string' do
14
+ string.find_article(unique).text.must_have_content unique
15
+ string.find_article(unique).text.wont_have_content multiple
16
+ string.article(unique).text.must_have_content unique
17
+ string.article(unique).text.wont_have_content multiple
18
+ end
19
+
20
+ it 'finds the article when passed an instance' do
21
+ string.find_article(post).text.must_have_content unique
22
+ string.find_article(post).text.wont_have_content multiple
23
+ string.article(post).text.must_have_content unique
24
+ string.article(post).text.wont_have_content multiple
25
+ end
26
+ end
27
+
28
+ describe '#first_article' do
29
+ it 'finds the first article when passed a non-unique string' do
30
+ string.first_article(multiple).text.must_have_content multiple
31
+ string.first_article(multiple).text.wont_have_content unique
32
+ end
33
+ end
34
+
35
+
36
+ # li
37
+ #
38
+ describe '#find_list_item' do
39
+ it 'finds the list item when passed a unique string' do
40
+ string.find_list_item('foo').text.must_have_content 'foo'
41
+ string.find_list_item('foo').text.wont_have_content 'bar'
42
+ string.list_item('foo').text.must_have_content 'foo'
43
+ string.list_item('foo').text.wont_have_content 'bar'
44
+ end
45
+
46
+ it 'finds the list item when passed an instance' do
47
+ string.find_list_item(post).text.must_have_content 'foo'
48
+ string.find_list_item(post).text.wont_have_content 'bar'
49
+ string.list_item(post).text.must_have_content 'foo'
50
+ string.list_item(post).text.wont_have_content 'bar'
51
+ end
52
+ end
53
+
54
+ describe '#list_item_number' do
55
+ it 'return the list item of the number passed in to an ol' do
56
+ string.find_unordered_list('foo').list_item_number(2).must_have_content 'bar'
57
+ string.find_unordered_list('foo').list_item_number(2).wont_have_content 'foo'
58
+ end
59
+ end
60
+
61
+ # ol
62
+ #
63
+ describe '#find_ordered_list' do
64
+ it 'finds the ordered list when passed a unique string' do
65
+ string.find_ordered_list(unique).text.must_have_content unique
66
+ string.find_ordered_list(unique).text.wont_have_content multiple
67
+ string.ordered_list(unique).text.must_have_content unique
68
+ string.ordered_list(unique).text.wont_have_content multiple
69
+ end
70
+
71
+ it 'finds the ordered list when passed an instance' do
72
+ string.find_ordered_list(post).text.must_have_content unique
73
+ string.find_ordered_list(post).text.wont_have_content multiple
74
+ string.ordered_list(post).text.must_have_content unique
75
+ string.ordered_list(post).text.wont_have_content multiple
76
+ end
77
+ end
78
+
79
+ describe '#first_ordered_list' do
80
+ it 'finds the first ordered list when passed a non-unique string' do
81
+ string.first_ordered_list(multiple).text.must_have_content multiple
82
+ string.first_ordered_list(multiple).text.wont_have_content unique
83
+ end
84
+ end
85
+
86
+ # ul
87
+ #
88
+ describe '#find_unordered_list' do
89
+ it 'finds the unordered list when passed a unique string' do
90
+ string.find_unordered_list(unique).text.must_have_content unique
91
+ string.find_unordered_list(unique).text.wont_have_content multiple
92
+ string.unordered_list(unique).text.must_have_content unique
93
+ string.unordered_list(unique).text.wont_have_content multiple
94
+ end
95
+
96
+ it 'finds the unordered list when passed an instance' do
97
+ string.find_unordered_list(post).text.must_have_content unique
98
+ string.find_unordered_list(post).text.wont_have_content multiple
99
+ string.unordered_list(post).text.must_have_content unique
100
+ string.unordered_list(post).text.wont_have_content multiple
101
+ end
102
+ end
103
+
104
+ describe '#first_unordered_list' do
105
+ it 'finds the first unordered list when passed a non-unique string' do
106
+ string.first_unordered_list(multiple).text.must_have_content multiple
107
+ string.first_unordered_list(multiple).text.wont_have_content unique
108
+ end
109
+ end
110
+
111
+ # tr
112
+ #
113
+ describe '#find_row' do
114
+ it 'finds the row when passed a unique string' do
115
+ string.find_row(unique).text.must_have_content unique
116
+ string.find_row(unique).text.wont_have_content multiple
117
+ string.row(unique).text.must_have_content unique
118
+ string.row(unique).text.wont_have_content multiple
119
+ end
120
+
121
+ it 'finds the row when passed an instance' do
122
+ string.find_row(post).text.must_have_content unique
123
+ string.find_row(post).text.wont_have_content multiple
124
+ string.row(post).text.must_have_content unique
125
+ string.row(post).text.wont_have_content multiple
126
+ end
127
+ end
128
+
129
+ describe '#first_row' do
130
+ it 'finds the first nav when passed a non-unique string' do
131
+ string.first_row(multiple).text.must_have_content multiple
132
+ string.first_row(multiple).text.wont_have_content unique
133
+ end
134
+ end
135
+
136
+ describe '#row_number' do
137
+ it 'returns the row of the number passed in when scoped to a table' do
138
+ string.find_table('Jane Doe').row_number(1).text.must_have_content 'The first post title'
139
+ string.find_table('Jane Doe').row_number(1).text.wont_have_content 'The second post title'
140
+ string.find_table('Jane Doe').row_number(2).text.must_have_content 'The second post title'
141
+ string.find_table('Jane Doe').row_number(2).text.wont_have_content 'The first post title'
142
+ end
143
+ end
144
+
145
+ # paragraph
146
+ #
147
+ describe '#find_paragraph' do
148
+ it 'finds the paragraph when passed a unique string' do
149
+ string.find_paragraph(unique).text.must_have_content unique
150
+ string.find_paragraph(unique).text.wont_have_content multiple
151
+ string.paragraph(unique).text.must_have_content unique
152
+ string.paragraph(unique).text.wont_have_content multiple
153
+ end
154
+
155
+ it 'finds the paragraph when passed an instance' do
156
+ string.find_paragraph(post).text.must_have_content unique
157
+ string.find_paragraph(post).text.wont_have_content multiple
158
+ string.paragraph(post).text.must_have_content unique
159
+ string.paragraph(post).text.wont_have_content multiple
160
+ end
161
+ end
162
+
163
+ describe '#first_paragraph' do
164
+ it 'finds the first paragraph containing a string' do
165
+ string.first_paragraph(multiple).text.must_have_content multiple
166
+ string.first_paragraph(multiple).text.wont_have_content unique
167
+ end
168
+ end
169
+
170
+ # table
171
+ #
172
+ describe '#find_table' do
173
+ it 'finds the table when passed a unique string' do
174
+ string.find_table(unique).text.must_have_content unique
175
+ string.find_table(unique).text.wont_have_content multiple
176
+ string.table(unique).text.must_have_content unique
177
+ string.table(unique).text.wont_have_content multiple
178
+ end
179
+
180
+ it 'finds the table when passed a non-unique string' do
181
+ string.find_table(multiple).text.must_have_content multiple
182
+ string.find_table(multiple).text.wont_have_content unique
183
+ end
184
+
185
+ it 'finds the table when passed an instance object' do
186
+ string.find_table(post).text.must_have_content unique
187
+ string.find_table(post).text.wont_have_content multiple
188
+ end
189
+ end
190
+
191
+ describe '#first_table' do
192
+ it 'finds the first table when passed a non-unique string' do
193
+ string.first_table(multiple).text.must_have_content multiple
194
+ string.first_table(multiple).text.wont_have_content unique
195
+ end
196
+ end
197
+
198
+
199
+ # navigation
200
+ #
201
+ describe '#navigation' do
202
+ it 'finds the navigation when passed a unique string' do
203
+ string.find_navigation(unique).text.must_have_content unique
204
+ string.find_navigation(unique).text.wont_have_content multiple
205
+ string.navigation(unique).text.must_have_content unique
206
+ string.navigation(unique).text.wont_have_content multiple
207
+ end
208
+
209
+ it 'finds the nav when passed an instance' do
210
+ string.find_navigation(post).text.must_have_content multiple
211
+ string.find_navigation(post).text.wont_have_content unique
212
+ string.navigation(post).text.must_have_content multiple
213
+ string.find_navigation(post).text.wont_have_content unique
214
+ end
215
+ end
216
+
217
+ describe '#first_navigation' do
218
+ it 'finds the first navigation when passed a non-unique string' do
219
+ string.first_navigation(multiple).text.must_have_content multiple
220
+ string.first_navigation(multiple).text.wont_have_content unique
221
+ end
222
+ end
223
+
224
+ # section
225
+ #
226
+ describe '#section' do
227
+ it 'finds a section when passed a unique string' do
228
+ string.find_section(unique).text.must_have_content unique
229
+ string.find_section(unique).text.wont_have_content multiple
230
+ string.section(unique).text.must_have_content unique
231
+ string.section(unique).text.wont_have_content multiple
232
+ end
233
+
234
+ it 'finds a section when passed an instance' do
235
+ string.find_section(post).text.must_have_content unique
236
+ string.find_section(post).text.wont_have_content multiple
237
+ string.section(post).text.must_have_content unique
238
+ string.section(post).text.wont_have_content multiple
239
+ end
240
+ end
241
+
242
+ # header
243
+ #
244
+ describe '#header' do
245
+ it 'finds the header when passed a unique string' do
246
+ string.find_header(unique).text.must_have_content unique
247
+ string.find_header(unique).text.wont_have_content multiple
248
+ string.header(unique).text.must_have_content unique
249
+ string.header(unique).text.wont_have_content multiple
250
+ end
251
+
252
+ it 'finds the header when passed an instance' do
253
+ string.find_header(post).text.must_have_content multiple
254
+ string.find_header(post).text.wont_have_content unique
255
+ string.header(post).text.must_have_content multiple
256
+ string.find_header(post).text.wont_have_content unique
257
+ end
258
+ end
259
+
260
+ describe '#first_header' do
261
+ it 'finds the first header when passed a non-unique string' do
262
+ string.first_header(multiple).text.must_have_content multiple
263
+ string.first_header(multiple).text.wont_have_content unique
264
+ end
265
+ end
266
+
267
+ # footer
268
+ #
269
+ describe '#footer' do
270
+ it 'finds the footer when passed a unique string' do
271
+ string.find_footer(unique).text.must_have_content unique
272
+ string.find_footer(unique).text.wont_have_content multiple
273
+ string.footer(unique).text.must_have_content unique
274
+ string.footer(unique).text.wont_have_content multiple
275
+ end
276
+
277
+ it 'finds the footer when passed an instance' do
278
+ string.find_footer(post).text.must_have_content multiple
279
+ string.find_footer(post).text.wont_have_content unique
280
+ string.footer(post).text.must_have_content multiple
281
+ string.find_footer(post).text.wont_have_content unique
282
+ end
283
+ end
284
+
285
+ describe '#first_footer' do
286
+ it 'finds the first footer when passed a non-unique string' do
287
+ string.first_footer(multiple).text.must_have_content multiple
288
+ string.first_footer(multiple).text.wont_have_content unique
289
+ end
290
+ end
291
+
292
+ # aside
293
+ #
294
+ describe '#aside' do
295
+ it 'finds the aside when passed a unique string' do
296
+ string.find_aside(unique).text.must_have_content unique
297
+ string.find_aside(unique).text.wont_have_content multiple
298
+ string.aside(unique).text.must_have_content unique
299
+ string.aside(unique).text.wont_have_content multiple
300
+ end
301
+
302
+ it 'finds the aside when passed an instance' do
303
+ string.find_aside(post).text.must_have_content multiple
304
+ string.find_aside(post).text.wont_have_content unique
305
+ string.aside(post).text.must_have_content multiple
306
+ string.find_aside(post).text.wont_have_content unique
307
+ end
308
+ end
309
+
310
+ describe '#first_aside' do
311
+ it 'finds the first aside when passed a non-unique string' do
312
+ string.first_aside(multiple).text.must_have_content multiple
313
+ string.first_aside(multiple).text.wont_have_content unique
314
+ end
315
+ end
316
+
317
+ # form
318
+ #
319
+ describe '#form' do
320
+ it 'finds the form when passed a unique string' do
321
+ string.find_form(unique).text.must_have_content unique
322
+ string.find_form(unique).text.wont_have_content multiple
323
+ string.form(unique).text.must_have_content unique
324
+ string.form(unique).text.wont_have_content multiple
325
+ end
326
+
327
+ it 'finds the form when passed an instance' do
328
+ string.find_form(post).text.must_have_content multiple
329
+ string.find_form(post).text.wont_have_content unique
330
+ string.form(post).text.must_have_content multiple
331
+ string.find_form(post).text.wont_have_content unique
332
+ end
333
+ end
334
+
335
+ describe '#first_form' do
336
+ it 'finds the first form when passed a non-unique string' do
337
+ string.first_form(multiple).text.must_have_content multiple
338
+ string.first_form(multiple).text.wont_have_content unique
339
+ end
340
+ end
341
+
342
+ # image
343
+ #
344
+ describe '#find_image' do
345
+ let(:image) { 'http://example.com/johndoe' }
346
+
347
+ it 'finds an image when passed src and alt' do
348
+ string.find_image(src: 'http://example.com/johndoe', alt: 'John Doe').native.attributes['src'].value.must_equal image
349
+ string.find_image(src: 'http://example.com/johndoe').native.attributes['src'].value.must_equal image
350
+ string.find_image(alt: 'John Doe').native.attributes['src'].value.must_equal image
351
+ end
352
+ end
353
+ end
@@ -0,0 +1,115 @@
1
+ require 'test_helper'
2
+
3
+ describe '.string' do
4
+ let(:post) { Post.new(3) }
5
+ let(:string) { Capybara.string TestString }
6
+ let(:unique) { 'John Doe' }
7
+ let(:multiple) { 'Jane Doe' }
8
+
9
+ # images
10
+ describe '#has_image?' do
11
+ it 'returns true if the image has an alt with the argument' do
12
+ string.has_image?(alt: unique).must_equal true
13
+ end
14
+
15
+ it 'returns false if the image does not have an alt with the argument' do
16
+ string.has_image?(alt: multiple).must_equal false
17
+ end
18
+
19
+ it 'returns true if the image has an src with the argument' do
20
+ string.has_image?(src: 'http://example.com/johndoe').must_equal true
21
+ end
22
+
23
+ it 'returns false if the image does not have an src with the argument' do
24
+ string.has_image?(src: 'http://example.com/johndoh').must_equal false
25
+ end
26
+
27
+ it 'returns true if the image has an alt and an src with the arguments' do
28
+ string.has_image?(alt: unique, src: 'http://example.com/johndoe').must_equal true
29
+ end
30
+
31
+ it 'returns false if the image does not have an alt and an src with the arguments' do
32
+ string.has_image?(alt: unique, src: 'http://example.com/johndoh').must_equal false
33
+ end
34
+ end
35
+
36
+ describe '#has_no_image?' do
37
+ it 'returns true if there is no image with the alt' do
38
+ string.has_no_image?(alt: multiple).must_equal true
39
+ end
40
+
41
+ it 'returns false if there is an image with the alt' do
42
+ string.has_no_image?(alt: unique).must_equal false
43
+ end
44
+
45
+ it 'returns true if there is no image with the src' do
46
+ string.has_no_image?(src: 'http://example.com/johndoh').must_equal true
47
+ end
48
+
49
+ it 'returns false if there is an image with the src' do
50
+ string.has_no_image?(src: 'http://example.com/johndoe').must_equal false
51
+ end
52
+
53
+ it 'returns true if there is no image with an alt and a src with the arguments' do
54
+ string.has_no_image?(alt: unique, src: 'http://example.com/johndoh').must_equal true
55
+ end
56
+ end
57
+
58
+ # field_values
59
+ describe '#has_field_value?' do
60
+ it 'returns true when the field has the passed in value' do
61
+ string.find_form(unique).has_field_value?('name', unique).must_equal true
62
+ end
63
+
64
+ it 'fails if has_field_value? returns false' do
65
+ assert_raises(Capybara::ExpectationNotMet) do
66
+ string.find_form(unique).has_field_value?(:name, multiple)
67
+ end.must_have_content 'expected to find field name with a value of Jane Doe.'
68
+ end
69
+ end
70
+
71
+ describe '#has_no_field_value?' do
72
+ it 'returns true if the field does not have the passed in value' do
73
+ string.find_form(unique).has_no_field_value?('name', 'John Doh').must_equal true
74
+ end
75
+
76
+ it 'fails if has_no_field_value? returns false' do
77
+ assert_raises(Capybara::ExpectationNotMet) do
78
+ string.find_form(unique).has_no_field_value?('name', unique)
79
+ end.must_have_content 'expected to not find field name with a value of John Doe.'
80
+ end
81
+ end
82
+
83
+ # meta tags
84
+ describe '#has_meta_tag?' do
85
+ it 'returns true when the meta tag name and content are present' do
86
+ string.has_meta_tag?('title', 'CapybaraExtensions!').must_equal true
87
+ end
88
+
89
+ it 'returns false when the meta tag name is not present' do
90
+ string.has_meta_tag?('nonexistent_name', 'CapybaraExtensions!').must_equal false
91
+ end
92
+
93
+ it 'returns false when the meta tag content is not present' do
94
+ string.has_meta_tag?('title', 'Nonexistent content').must_equal false
95
+ end
96
+ end
97
+
98
+ describe '#has_no_meta_tag?' do
99
+ it 'returns true when the meta tag name and content are not present' do
100
+ string.has_no_meta_tag?('title', 'foo').must_equal true
101
+ end
102
+
103
+ it 'returns true when the meta tag name is not present' do
104
+ string.has_no_meta_tag?('nonexistent_name', 'CapybaraExtensions!').must_equal true
105
+ end
106
+
107
+ it 'returns true when the meta tag content is not present' do
108
+ string.has_no_meta_tag?('title', 'Nonexistent content').must_equal true
109
+ end
110
+
111
+ it 'returns false when the meta tag name and content are present' do
112
+ string.has_no_meta_tag?('title', 'CapybaraExtensions!').must_equal false
113
+ end
114
+ end
115
+ end