capybara 3.21.0 → 3.22.0

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