capybara-extensions 0.2.0 → 0.3.0

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