capybara 3.21.0 → 3.22.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/History.md +14 -0
  4. data/README.md +13 -8
  5. data/lib/capybara.rb +38 -32
  6. data/lib/capybara/driver/node.rb +2 -2
  7. data/lib/capybara/minitest.rb +14 -1
  8. data/lib/capybara/minitest/spec.rb +20 -7
  9. data/lib/capybara/node/finders.rb +41 -47
  10. data/lib/capybara/node/matchers.rb +161 -72
  11. data/lib/capybara/queries/ancestor_query.rb +9 -7
  12. data/lib/capybara/queries/sibling_query.rb +11 -4
  13. data/lib/capybara/result.rb +2 -0
  14. data/lib/capybara/rspec/matchers.rb +16 -1
  15. data/lib/capybara/rspec/matchers/have_ancestor.rb +30 -0
  16. data/lib/capybara/rspec/matchers/have_sibling.rb +30 -0
  17. data/lib/capybara/selector.rb +153 -171
  18. data/lib/capybara/selector/definition/checkbox.rb +8 -5
  19. data/lib/capybara/selector/definition/radio_button.rb +8 -5
  20. data/lib/capybara/selector/filter_set.rb +4 -2
  21. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +35 -1
  22. data/lib/capybara/session.rb +74 -71
  23. data/lib/capybara/session/config.rb +1 -1
  24. data/lib/capybara/spec/session/check_spec.rb +6 -0
  25. data/lib/capybara/spec/session/choose_spec.rb +6 -0
  26. data/lib/capybara/spec/session/has_ancestor_spec.rb +44 -0
  27. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  28. data/lib/capybara/spec/session/select_spec.rb +5 -5
  29. data/lib/capybara/spec/views/form.erb +1 -1
  30. data/lib/capybara/version.rb +1 -1
  31. data/lib/capybara/window.rb +10 -10
  32. data/spec/minitest_spec.rb +11 -1
  33. data/spec/minitest_spec_spec.rb +11 -1
  34. data/spec/regexp_dissassembler_spec.rb +1 -1
  35. metadata +7 -2
@@ -19,21 +19,20 @@ module Capybara
19
19
  # This will check if the expression occurs exactly 4 times.
20
20
  #
21
21
  # It also accepts all options that {Capybara::Node::Finders#all} accepts,
22
- # such as :text and :visible.
22
+ # such as `:text` and `:visible`.
23
23
  #
24
24
  # page.has_selector?('li', text: 'Horse', visible: true)
25
25
  #
26
- # has_selector? can also accept XPath expressions generated by the
26
+ # {#has_selector?} can also accept XPath expressions generated by the
27
27
  # XPath gem:
28
28
  #
29
29
  # page.has_selector?(:xpath, XPath.descendant(:p))
30
30
  #
31
31
  # @param (see Capybara::Node::Finders#all)
32
- # @param args
33
- # @option args [Integer] :count (nil) Number of times the text should occur
34
- # @option args [Integer] :minimum (nil) Minimum number of times the text should occur
35
- # @option args [Integer] :maximum (nil) Maximum number of times the text should occur
36
- # @option args [Range] :between (nil) Range of times that should contain number of times text occurs
32
+ # @option options [Integer] :count (nil) Number of matching elements that should exist
33
+ # @option options [Integer] :minimum (nil) Minimum number of matching elements that should exist
34
+ # @option options [Integer] :maximum (nil) Maximum number of matching elements that should exist
35
+ # @option options [Range] :between (nil) Range of number of matching elements that should exist
37
36
  # @return [Boolean] If the expression exists
38
37
  #
39
38
  def has_selector?(*args, **options, &optional_filter_block)
@@ -43,9 +42,9 @@ module Capybara
43
42
  ##
44
43
  #
45
44
  # Checks if a given selector is not on the page or a descendant of the current node.
46
- # Usage is identical to Capybara::Node::Matchers#has_selector?
45
+ # Usage is identical to {#has_selector?}.
47
46
  #
48
- # @param (see Capybara::Node::Finders#has_selector?)
47
+ # @param (see #has_selector?)
49
48
  # @return [Boolean]
50
49
  #
51
50
  def has_no_selector?(*args, **options, &optional_filter_block)
@@ -54,7 +53,7 @@ module Capybara
54
53
 
55
54
  ##
56
55
  #
57
- # Checks if a an element has the specified CSS styles
56
+ # Checks if a an element has the specified CSS styles.
58
57
  #
59
58
  # element.matches_style?( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
60
59
  #
@@ -66,7 +65,7 @@ module Capybara
66
65
  end
67
66
 
68
67
  ##
69
- # @deprecated
68
+ # @deprecated Use {#matches_style?} instead.
70
69
  #
71
70
  def has_style?(styles, **options)
72
71
  warn 'DEPRECATED: has_style? is deprecated, please use matches_style?'
@@ -89,15 +88,15 @@ module Capybara
89
88
  # This will check if the expression occurs exactly 4 times. See
90
89
  # {Capybara::Node::Finders#all} for other available result size options.
91
90
  #
92
- # If a :count of 0 is specified, it will behave like {#assert_no_selector};
91
+ # If a `:count` of 0 is specified, it will behave like {#assert_no_selector};
93
92
  # however, use of that method is preferred over this one.
94
93
  #
95
94
  # It also accepts all options that {Capybara::Node::Finders#all} accepts,
96
- # such as :text and :visible.
95
+ # such as `:text` and `:visible`.
97
96
  #
98
97
  # page.assert_selector('li', text: 'Horse', visible: true)
99
98
  #
100
- # `assert_selector` can also accept XPath expressions generated by the
99
+ # {#assert_selector} can also accept XPath expressions generated by the
101
100
  # XPath gem:
102
101
  #
103
102
  # page.assert_selector(:xpath, XPath.descendant(:p))
@@ -114,7 +113,7 @@ module Capybara
114
113
 
115
114
  ##
116
115
  #
117
- # Asserts that an element has the specified CSS styles
116
+ # Asserts that an element has the specified CSS styles.
118
117
  #
119
118
  # element.assert_matches_style( 'color' => 'rgb(0,0,255)', 'font-size' => /px/ )
120
119
  #
@@ -131,7 +130,8 @@ module Capybara
131
130
  end
132
131
 
133
132
  ##
134
- # @deprecated
133
+ # @deprecated Use {#assert_matches_style} instead.
134
+ #
135
135
  def assert_style(styles, **options)
136
136
  warn 'assert_style is deprecated, please use assert_matches_style instead'
137
137
  assert_matches_style(styles, **options)
@@ -139,16 +139,16 @@ module Capybara
139
139
 
140
140
  # Asserts that all of the provided selectors are present on the given page
141
141
  # or descendants of the current node. If options are provided, the assertion
142
- # will check that each locator is present with those options as well (other than :wait).
142
+ # will check that each locator is present with those options as well (other than `:wait`).
143
143
  #
144
144
  # page.assert_all_of_selectors(:custom, 'Tom', 'Joe', visible: all)
145
145
  # page.assert_all_of_selectors(:css, '#my_div', 'a.not_clicked')
146
146
  #
147
147
  # It accepts all options that {Capybara::Node::Finders#all} accepts,
148
- # such as :text and :visible.
148
+ # such as `:text` and `:visible`.
149
149
  #
150
- # The :wait option applies to all of the selectors as a group, so all of the locators must be present
151
- # within :wait (Defaults to Capybara.default_max_wait_time) seconds.
150
+ # The `:wait` option applies to all of the selectors as a group, so all of the locators must be present
151
+ # within `:wait` (defaults to {Capybara.configure default_max_wait_time}) seconds.
152
152
  #
153
153
  # @overload assert_all_of_selectors([kind = Capybara.default_selector], *locators, **options)
154
154
  #
@@ -160,16 +160,16 @@ module Capybara
160
160
 
161
161
  # Asserts that none of the provided selectors are present on the given page
162
162
  # or descendants of the current node. If options are provided, the assertion
163
- # will check that each locator is present with those options as well (other than :wait).
163
+ # will check that each locator is not present with those options as well (other than `:wait`).
164
164
  #
165
165
  # page.assert_none_of_selectors(:custom, 'Tom', 'Joe', visible: all)
166
166
  # page.assert_none_of_selectors(:css, '#my_div', 'a.not_clicked')
167
167
  #
168
168
  # It accepts all options that {Capybara::Node::Finders#all} accepts,
169
- # such as :text and :visible.
169
+ # such as `:text` and `:visible`.
170
170
  #
171
- # The :wait option applies to all of the selectors as a group, so none of the locators must be present
172
- # within :wait (Defaults to Capybara.default_max_wait_time) seconds.
171
+ # The `:wait` option applies to all of the selectors as a group, so none of the locators must be present
172
+ # within `:wait` (defaults to {Capybara.configure default_max_wait_time}) seconds.
173
173
  #
174
174
  # @overload assert_none_of_selectors([kind = Capybara.default_selector], *locators, **options)
175
175
  #
@@ -180,17 +180,17 @@ module Capybara
180
180
  end
181
181
 
182
182
  # Asserts that any of the provided selectors are present on the given page
183
- # or descendants of the current node. If options are provided, the assertion
184
- # will check that each locator is present with those options as well (other than :wait).
183
+ # or descendants of the current node. If options are provided, the assertion
184
+ # will check that each locator is present with those options as well (other than `:wait`).
185
185
  #
186
186
  # page.assert_any_of_selectors(:custom, 'Tom', 'Joe', visible: all)
187
187
  # page.assert_any_of_selectors(:css, '#my_div', 'a.not_clicked')
188
188
  #
189
189
  # It accepts all options that {Capybara::Node::Finders#all} accepts,
190
- # such as :text and :visible.
190
+ # such as `:text` and `:visible`.
191
191
  #
192
- # The :wait option applies to all of the selectors as a group, so any of the locators must be present
193
- # within :wait (Defaults to Capybara.default_max_wait_time) seconds.
192
+ # The `:wait` option applies to all of the selectors as a group, so any of the locators must be present
193
+ # within `:wait` (defaults to {Capybara.configure default_max_wait_time}) seconds.
194
194
  #
195
195
  # @overload assert_any_of_selectors([kind = Capybara.default_selector], *locators, **options)
196
196
  #
@@ -215,17 +215,17 @@ module Capybara
215
215
  ##
216
216
  #
217
217
  # Asserts that a given selector is not on the page or a descendant of the current node.
218
- # Usage is identical to Capybara::Node::Matchers#assert_selector
218
+ # Usage is identical to {#assert_selector}.
219
219
  #
220
- # Query options such as :count, :minimum, :maximum, and :between are
220
+ # Query options such as `:count`, `:minimum`, `:maximum`, and `:between` are
221
221
  # considered to be an integral part of the selector. This will return
222
- # true, for example, if a page contains 4 anchors but the query expects 5:
222
+ # `true`, for example, if a page contains 4 anchors but the query expects 5:
223
223
  #
224
224
  # page.assert_no_selector('a', minimum: 1) # Found, raises Capybara::ExpectationNotMet
225
225
  # page.assert_no_selector('a', count: 4) # Found, raises Capybara::ExpectationNotMet
226
226
  # page.assert_no_selector('a', count: 5) # Not Found, returns true
227
227
  #
228
- # @param (see Capybara::Node::Finders#assert_selector)
228
+ # @param (see #assert_selector)
229
229
  # @raise [Capybara::ExpectationNotMet] If the selector exists
230
230
  #
231
231
  def assert_no_selector(*args, &optional_filter_block)
@@ -250,11 +250,11 @@ module Capybara
250
250
  # This will check if the expression occurs exactly 4 times.
251
251
  #
252
252
  # It also accepts all options that {Capybara::Node::Finders#all} accepts,
253
- # such as :text and :visible.
253
+ # such as `:text` and `:visible`.
254
254
  #
255
255
  # page.has_xpath?('.//li', text: 'Horse', visible: true)
256
256
  #
257
- # has_xpath? can also accept XPath expressions generate by the
257
+ # {#has_xpath?} can also accept XPath expressions generated by the
258
258
  # XPath gem:
259
259
  #
260
260
  # xpath = XPath.generate { |x| x.descendant(:p) }
@@ -272,9 +272,9 @@ module Capybara
272
272
  ##
273
273
  #
274
274
  # Checks if a given XPath expression is not on the page or a descendant of the current node.
275
- # Usage is identical to Capybara::Node::Matchers#has_xpath?
275
+ # Usage is identical to {#has_xpath?}.
276
276
  #
277
- # @param (see Capybara::Node::Finders#has_xpath?)
277
+ # @param (see #has_xpath?)
278
278
  # @return [Boolean]
279
279
  #
280
280
  def has_no_xpath?(path, **options, &optional_filter_block)
@@ -295,7 +295,7 @@ module Capybara
295
295
  # This will check if the selector occurs exactly 4 times.
296
296
  #
297
297
  # It also accepts all options that {Capybara::Node::Finders#all} accepts,
298
- # such as :text and :visible.
298
+ # such as `:text` and `:visible`.
299
299
  #
300
300
  # page.has_css?('li', text: 'Horse', visible: true)
301
301
  #
@@ -311,9 +311,9 @@ module Capybara
311
311
  ##
312
312
  #
313
313
  # Checks if a given CSS selector is not on the page or a descendant of the current node.
314
- # Usage is identical to Capybara::Node::Matchers#has_css?
314
+ # Usage is identical to {#has_css?}.
315
315
  #
316
- # @param (see Capybara::Node::Finders#has_css?)
316
+ # @param (see #has_css?)
317
317
  # @return [Boolean]
318
318
  #
319
319
  def has_no_css?(path, **options, &optional_filter_block)
@@ -326,7 +326,6 @@ module Capybara
326
326
  # text or id.
327
327
  #
328
328
  # @param [String] locator The text or id of a link to check for
329
- # @param options
330
329
  # @option options [String, Regexp] :href The value the href attribute must be
331
330
  # @return [Boolean] Whether it exists
332
331
  #
@@ -339,7 +338,7 @@ module Capybara
339
338
  # Checks if the page or current node has no link with the given
340
339
  # text or id.
341
340
  #
342
- # @param (see Capybara::Node::Finders#has_link?)
341
+ # @param (see #has_link?)
343
342
  # @return [Boolean] Whether it doesn't exist
344
343
  #
345
344
  def has_no_link?(locator = nil, **options, &optional_filter_block)
@@ -376,7 +375,7 @@ module Capybara
376
375
  # label, name or id.
377
376
  #
378
377
  # For text fields and other textual fields, such as textareas and
379
- # HTML5 email/url/etc. fields, it's possible to specify a :with
378
+ # HTML5 email/url/etc. fields, it's possible to specify a `:with`
380
379
  # option to specify the text the field should contain:
381
380
  #
382
381
  # page.has_field?('Name', with: 'Jonas')
@@ -399,7 +398,7 @@ module Capybara
399
398
  ##
400
399
  #
401
400
  # Checks if the page or current node has no form field with the given
402
- # label, name or id. See {Capybara::Node::Matchers#has_field?}.
401
+ # label, name or id. See {#has_field?}.
403
402
  #
404
403
  # @param [String] locator The label, name or id of a field to check for
405
404
  # @option options [String, Regexp] :with The text content of the field or a Regexp to match
@@ -413,7 +412,7 @@ module Capybara
413
412
  ##
414
413
  #
415
414
  # Checks if the page or current node has a radio button or
416
- # checkbox with the given label, value, id, or Capybara.test_id attribute that is currently
415
+ # checkbox with the given label, value, id, or {Capybara.configure test_id} attribute that is currently
417
416
  # checked.
418
417
  #
419
418
  # @param [String] locator The label, name or id of a checked field
@@ -426,7 +425,7 @@ module Capybara
426
425
  ##
427
426
  #
428
427
  # Checks if the page or current node has no radio button or
429
- # checkbox with the given label, value or id, or Capybara.test_id attribute that is currently
428
+ # checkbox with the given label, value or id, or {Capybara.configure test_id} attribute that is currently
430
429
  # checked.
431
430
  #
432
431
  # @param [String] locator The label, name or id of a checked field
@@ -439,7 +438,7 @@ module Capybara
439
438
  ##
440
439
  #
441
440
  # Checks if the page or current node has a radio button or
442
- # checkbox with the given label, value or id, or Capybara.test_id attribute that is currently
441
+ # checkbox with the given label, value or id, or {Capybara.configure test_id} attribute that is currently
443
442
  # unchecked.
444
443
  #
445
444
  # @param [String] locator The label, name or id of an unchecked field
@@ -452,7 +451,7 @@ module Capybara
452
451
  ##
453
452
  #
454
453
  # Checks if the page or current node has no radio button or
455
- # checkbox with the given label, value or id, or Capybara.test_id attribute that is currently
454
+ # checkbox with the given label, value or id, or {Capybara.configure test_id} attribute that is currently
456
455
  # unchecked.
457
456
  #
458
457
  # @param [String] locator The label, name or id of an unchecked field
@@ -498,9 +497,9 @@ module Capybara
498
497
  ##
499
498
  #
500
499
  # Checks if the page or current node has no select field with the
501
- # given label, name or id. See {Capybara::Node::Matchers#has_select?}.
500
+ # given label, name or id. See {#has_select?}.
502
501
  #
503
- # @param (see Capybara::Node::Matchers#has_select?)
502
+ # @param (see #has_select?)
504
503
  # @return [Boolean] Whether it doesn't exist
505
504
  #
506
505
  def has_no_select?(locator = nil, **options, &optional_filter_block)
@@ -532,9 +531,9 @@ module Capybara
532
531
  ##
533
532
  #
534
533
  # Checks if the page or current node has no table with the given id
535
- # or caption. See {Capybara::Node::Matchers#has_table?}.
534
+ # or caption. See {#has_table?}.
536
535
  #
537
- # @param (see Capybara::Node::Matchers#has_table?)
536
+ # @param (see #has_table?)
538
537
  # @return [Boolean] Whether it doesn't exist
539
538
  #
540
539
  def has_no_table?(locator = nil, **options, &optional_filter_block)
@@ -543,14 +542,14 @@ module Capybara
543
542
 
544
543
  ##
545
544
  #
546
- # Asserts that the current_node matches a given selector
545
+ # Asserts that the current node matches a given selector.
547
546
  #
548
547
  # node.assert_matches_selector('p#foo')
549
548
  # node.assert_matches_selector(:xpath, '//p[@id="foo"]')
550
549
  # node.assert_matches_selector(:foo)
551
550
  #
552
551
  # It also accepts all options that {Capybara::Node::Finders#all} accepts,
553
- # such as :text and :visible.
552
+ # such as `:text` and `:visible`.
554
553
  #
555
554
  # node.assert_matches_selector('li', text: 'Horse', visible: true)
556
555
  #
@@ -563,6 +562,14 @@ module Capybara
563
562
  end
564
563
  end
565
564
 
565
+ ##
566
+ #
567
+ # Asserts that the current node does not match a given selector.
568
+ # Usage is identical to {#assert_matches_selector}.
569
+ #
570
+ # @param (see #assert_matches_selector)
571
+ # @raise [Capybara::ExpectationNotMet] If the selector matches
572
+ #
566
573
  def assert_not_matches_selector(*args, &optional_filter_block)
567
574
  _verify_match_result(args, optional_filter_block) do |result|
568
575
  raise Capybara::ExpectationNotMet, 'Item matched the provided selector' if result.include? self
@@ -571,9 +578,9 @@ module Capybara
571
578
 
572
579
  ##
573
580
  #
574
- # Checks if the current node matches given selector
581
+ # Checks if the current node matches given selector.
575
582
  #
576
- # @param (see Capybara::Node::Finders#has_selector?)
583
+ # @param (see #has_selector?)
577
584
  # @return [Boolean]
578
585
  #
579
586
  def matches_selector?(*args, **options, &optional_filter_block)
@@ -582,7 +589,7 @@ module Capybara
582
589
 
583
590
  ##
584
591
  #
585
- # Checks if the current node matches given XPath expression
592
+ # Checks if the current node matches given XPath expression.
586
593
  #
587
594
  # @param [String, XPath::Expression] xpath The XPath expression to match against the current code
588
595
  # @return [Boolean]
@@ -593,7 +600,7 @@ module Capybara
593
600
 
594
601
  ##
595
602
  #
596
- # Checks if the current node matches given CSS selector
603
+ # Checks if the current node matches given CSS selector.
597
604
  #
598
605
  # @param [String] css The CSS selector to match against the current code
599
606
  # @return [Boolean]
@@ -604,10 +611,10 @@ module Capybara
604
611
 
605
612
  ##
606
613
  #
607
- # Checks if the current node does not match given selector
608
- # Usage is identical to Capybara::Node::Matchers#has_selector?
614
+ # Checks if the current node does not match given selector.
615
+ # Usage is identical to {#has_selector?}.
609
616
  #
610
- # @param (see Capybara::Node::Finders#has_selector?)
617
+ # @param (see #has_selector?)
611
618
  # @return [Boolean]
612
619
  #
613
620
  def not_matches_selector?(*args, **options, &optional_filter_block)
@@ -616,7 +623,7 @@ module Capybara
616
623
 
617
624
  ##
618
625
  #
619
- # Checks if the current node does not match given XPath expression
626
+ # Checks if the current node does not match given XPath expression.
620
627
  #
621
628
  # @param [String, XPath::Expression] xpath The XPath expression to match against the current code
622
629
  # @return [Boolean]
@@ -627,7 +634,7 @@ module Capybara
627
634
 
628
635
  ##
629
636
  #
630
- # Checks if the current node does not match given CSS selector
637
+ # Checks if the current node does not match given CSS selector.
631
638
  #
632
639
  # @param [String] css The CSS selector to match against the current code
633
640
  # @return [Boolean]
@@ -642,24 +649,24 @@ module Capybara
642
649
  #
643
650
  # @!macro text_query_params
644
651
  # @overload $0(type, text, **options)
645
- # @param [:all, :visible] type Whether to check for only visible or all text. If this parameter is missing or nil then we use the value of `Capybara.ignore_hidden_elements`, which defaults to `true`, corresponding to `:visible`.
652
+ # @param [:all, :visible] type Whether to check for only visible or all text. If this parameter is missing or nil then we use the value of {Capybara.configure ignore_hidden_elements}, which defaults to `true`, corresponding to `:visible`.
646
653
  # @param [String, Regexp] text The string/regexp to check for. If it's a string, text is expected to include it. If it's a regexp, text is expected to match it.
647
654
  # @option options [Integer] :count (nil) Number of times the text is expected to occur
648
655
  # @option options [Integer] :minimum (nil) Minimum number of times the text is expected to occur
649
656
  # @option options [Integer] :maximum (nil) Maximum number of times the text is expected to occur
650
657
  # @option options [Range] :between (nil) Range of times that is expected to contain number of times text occurs
651
- # @option options [Numeric] :wait (Capybara.default_max_wait_time) Maximum time that Capybara will wait for text to eq/match given string/regexp argument
652
- # @option options [Boolean] :exact (Capybara.exact_text) Whether text must be an exact match or just substring
653
- # @option options [Boolean] :normalize_ws (false) When true replace all whitespace with standard spaces and collapse consecutive whitespace to a single space
658
+ # @option options [Numeric] :wait Maximum time that Capybara will wait for text to eq/match given string/regexp argument. Defaults to {Capybara.configure default_max_wait_time}.
659
+ # @option options [Boolean] :exact Whether text must be an exact match or just substring. Defaults to {Capybara.configure exact_text}.
660
+ # @option options [Boolean] :normalize_ws (false) When `true` replace all whitespace with standard spaces and collapse consecutive whitespace to a single space
654
661
  # @overload $0(text, **options)
655
662
  # @param [String, Regexp] text The string/regexp to check for. If it's a string, text is expected to include it. If it's a regexp, text is expected to match it.
656
663
  # @option options [Integer] :count (nil) Number of times the text is expected to occur
657
664
  # @option options [Integer] :minimum (nil) Minimum number of times the text is expected to occur
658
665
  # @option options [Integer] :maximum (nil) Maximum number of times the text is expected to occur
659
666
  # @option options [Range] :between (nil) Range of times that is expected to contain number of times text occurs
660
- # @option options [Numeric] :wait (Capybara.default_max_wait_time) Maximum time that Capybara will wait for text to eq/match given string/regexp argument
661
- # @option options [Boolean] :exact (Capybara.exact_text) Whether text must be an exact match or just substring
662
- # @option options [Boolean] :normalize_ws (false) When true replace all whitespace with standard spaces and collapse consecutive whitespace to a single space
667
+ # @option options [Numeric] :wait Maximum time that Capybara will wait for text to eq/match given string/regexp argument. Defaults to {Capybara.configure default_max_wait_time}.
668
+ # @option options [Boolean] :exact Whether text must be an exact match or just substring. Defaults to {Capybara.configure exact_text}.
669
+ # @option options [Boolean] :normalize_ws (false) When `true` replace all whitespace with standard spaces and collapse consecutive whitespace to a single space
663
670
  # @raise [Capybara::ExpectationNotMet] if the assertion hasn't succeeded during wait time
664
671
  # @return [true]
665
672
  #
@@ -718,6 +725,88 @@ module Capybara
718
725
  end
719
726
  alias_method :has_no_content?, :has_no_text?
720
727
 
728
+ ##
729
+ #
730
+ # Asserts that a given selector matches an ancestor of the current node.
731
+ #
732
+ # element.assert_ancestor('p#foo')
733
+ #
734
+ # Accepts the same options as {#assert_selector}
735
+ #
736
+ # @param (see Capybara::Node::Finders#find)
737
+ # @raise [Capybara::ExpectationNotMet] If the selector does not exist
738
+ #
739
+ def assert_ancestor(*args, &optional_filter_block)
740
+ _verify_selector_result(args, optional_filter_block, Capybara::Queries::AncestorQuery) do |result, query|
741
+ raise Capybara::ExpectationNotMet, result.failure_message unless result.matches_count? && (result.any? || query.expects_none?)
742
+ end
743
+ end
744
+
745
+ def assert_no_ancestor(*args, &optional_filter_block)
746
+ _verify_selector_result(args, optional_filter_block, Capybara::Queries::SiblingQuery) do |result, query|
747
+ if result.matches_count? && (!result.empty? || query.expects_none?)
748
+ raise Capybara::ExpectationNotMet, result.negative_failure_message
749
+ end
750
+ end
751
+ end
752
+
753
+ ##
754
+ #
755
+ # Predicate version of {#assert_ancestor}
756
+ #
757
+ def has_ancestor?(*args, **options, &optional_filter_block)
758
+ make_predicate(options) { assert_ancestor(*args, options, &optional_filter_block) }
759
+ end
760
+
761
+ ##
762
+ #
763
+ # Predicate version of {#assert_no_ancestor}
764
+ #
765
+ def has_no_ancestor?(*args, **options, &optional_filter_block)
766
+ make_predicate(options) { assert_no_ancestor(*args, options, &optional_filter_block) }
767
+ end
768
+
769
+ ##
770
+ #
771
+ # Asserts that a given selector matches a sibling of the current node.
772
+ #
773
+ # element.assert_sibling('p#foo')
774
+ #
775
+ # Accepts the same options as {#assert_selector}
776
+ #
777
+ # @param (see Capybara::Node::Finders#find)
778
+ # @raise [Capybara::ExpectationNotMet] If the selector does not exist
779
+ #
780
+ def assert_sibling(*args, &optional_filter_block)
781
+ _verify_selector_result(args, optional_filter_block, Capybara::Queries::SiblingQuery) do |result, query|
782
+ raise Capybara::ExpectationNotMet, result.failure_message unless result.matches_count? && (result.any? || query.expects_none?)
783
+ end
784
+ end
785
+
786
+ def assert_no_sibling(*args, &optional_filter_block)
787
+ _verify_selector_result(args, optional_filter_block, Capybara::Queries::SiblingQuery) do |result, query|
788
+ if result.matches_count? && (!result.empty? || query.expects_none?)
789
+ raise Capybara::ExpectationNotMet, result.negative_failure_message
790
+ end
791
+ end
792
+ end
793
+
794
+ ##
795
+ #
796
+ # Predicate version of {#assert_sibling}
797
+ #
798
+ def has_sibling?(*args, **options, &optional_filter_block)
799
+ make_predicate(options) { assert_sibling(*args, options, &optional_filter_block) }
800
+ end
801
+
802
+ ##
803
+ #
804
+ # Predicate version of {#assert_no_sibling}
805
+ #
806
+ def has_no_sibling?(*args, **options, &optional_filter_block)
807
+ make_predicate(options) { assert_no_sibling(*args, options, &optional_filter_block) }
808
+ end
809
+
721
810
  def ==(other)
722
811
  eql?(other) || (other.respond_to?(:base) && base == other.base)
723
812
  end
@@ -736,9 +825,9 @@ module Capybara
736
825
  end
737
826
  end
738
827
 
739
- def _verify_selector_result(query_args, optional_filter_block)
828
+ def _verify_selector_result(query_args, optional_filter_block, query_type = Capybara::Queries::SelectorQuery)
740
829
  query_args = _set_query_session_options(*query_args)
741
- query = Capybara::Queries::SelectorQuery.new(*query_args, &optional_filter_block)
830
+ query = query_type.new(*query_args, &optional_filter_block)
742
831
  synchronize(query.wait) do
743
832
  yield query.resolve_for(self), query
744
833
  end