capybara 3.23.0 → 3.35.3

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 (183) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +264 -11
  3. data/README.md +10 -6
  4. data/lib/capybara.rb +20 -8
  5. data/lib/capybara/config.rb +10 -8
  6. data/lib/capybara/cucumber.rb +1 -1
  7. data/lib/capybara/driver/base.rb +4 -0
  8. data/lib/capybara/driver/node.rb +4 -0
  9. data/lib/capybara/dsl.rb +10 -2
  10. data/lib/capybara/helpers.rb +28 -2
  11. data/lib/capybara/minitest.rb +232 -144
  12. data/lib/capybara/minitest/spec.rb +156 -97
  13. data/lib/capybara/node/actions.rb +36 -36
  14. data/lib/capybara/node/base.rb +6 -6
  15. data/lib/capybara/node/document.rb +2 -2
  16. data/lib/capybara/node/document_matchers.rb +3 -3
  17. data/lib/capybara/node/element.rb +77 -33
  18. data/lib/capybara/node/finders.rb +24 -17
  19. data/lib/capybara/node/matchers.rb +79 -64
  20. data/lib/capybara/node/simple.rb +11 -4
  21. data/lib/capybara/queries/ancestor_query.rb +6 -10
  22. data/lib/capybara/queries/base_query.rb +2 -1
  23. data/lib/capybara/queries/current_path_query.rb +14 -4
  24. data/lib/capybara/queries/selector_query.rb +259 -23
  25. data/lib/capybara/queries/sibling_query.rb +5 -11
  26. data/lib/capybara/queries/style_query.rb +1 -1
  27. data/lib/capybara/queries/text_query.rb +13 -1
  28. data/lib/capybara/rack_test/browser.rb +13 -4
  29. data/lib/capybara/rack_test/driver.rb +2 -1
  30. data/lib/capybara/rack_test/form.rb +2 -2
  31. data/lib/capybara/rack_test/node.rb +42 -6
  32. data/lib/capybara/registration_container.rb +44 -0
  33. data/lib/capybara/registrations/drivers.rb +18 -12
  34. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  35. data/lib/capybara/registrations/servers.rb +9 -2
  36. data/lib/capybara/result.rb +39 -19
  37. data/lib/capybara/rspec.rb +2 -0
  38. data/lib/capybara/rspec/matcher_proxies.rb +5 -5
  39. data/lib/capybara/rspec/matchers.rb +97 -74
  40. data/lib/capybara/rspec/matchers/base.rb +19 -6
  41. data/lib/capybara/rspec/matchers/count_sugar.rb +2 -1
  42. data/lib/capybara/rspec/matchers/have_ancestor.rb +5 -7
  43. data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
  44. data/lib/capybara/rspec/matchers/have_selector.rb +15 -10
  45. data/lib/capybara/rspec/matchers/have_sibling.rb +4 -7
  46. data/lib/capybara/rspec/matchers/have_text.rb +4 -7
  47. data/lib/capybara/rspec/matchers/have_title.rb +2 -2
  48. data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
  49. data/lib/capybara/rspec/matchers/match_style.rb +7 -2
  50. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  51. data/lib/capybara/selector.rb +46 -19
  52. data/lib/capybara/selector/builders/css_builder.rb +10 -6
  53. data/lib/capybara/selector/builders/xpath_builder.rb +4 -2
  54. data/lib/capybara/selector/css.rb +1 -1
  55. data/lib/capybara/selector/definition.rb +13 -11
  56. data/lib/capybara/selector/definition/button.rb +32 -15
  57. data/lib/capybara/selector/definition/checkbox.rb +2 -2
  58. data/lib/capybara/selector/definition/css.rb +3 -1
  59. data/lib/capybara/selector/definition/datalist_input.rb +2 -2
  60. data/lib/capybara/selector/definition/datalist_option.rb +1 -1
  61. data/lib/capybara/selector/definition/element.rb +3 -2
  62. data/lib/capybara/selector/definition/field.rb +1 -1
  63. data/lib/capybara/selector/definition/file_field.rb +1 -1
  64. data/lib/capybara/selector/definition/fillable_field.rb +2 -2
  65. data/lib/capybara/selector/definition/label.rb +5 -3
  66. data/lib/capybara/selector/definition/link.rb +8 -0
  67. data/lib/capybara/selector/definition/option.rb +1 -1
  68. data/lib/capybara/selector/definition/radio_button.rb +2 -2
  69. data/lib/capybara/selector/definition/select.rb +33 -14
  70. data/lib/capybara/selector/definition/table.rb +6 -3
  71. data/lib/capybara/selector/definition/table_row.rb +2 -2
  72. data/lib/capybara/selector/filter_set.rb +13 -11
  73. data/lib/capybara/selector/filters/base.rb +6 -1
  74. data/lib/capybara/selector/filters/locator_filter.rb +1 -1
  75. data/lib/capybara/selector/regexp_disassembler.rb +7 -0
  76. data/lib/capybara/selector/selector.rb +13 -3
  77. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -1
  78. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -1
  79. data/lib/capybara/selenium/atoms/src/getAttribute.js +1 -1
  80. data/lib/capybara/selenium/atoms/src/isDisplayed.js +10 -10
  81. data/lib/capybara/selenium/driver.rb +86 -24
  82. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +24 -21
  83. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +21 -19
  84. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +17 -1
  85. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +0 -4
  86. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  87. data/lib/capybara/selenium/extensions/find.rb +37 -26
  88. data/lib/capybara/selenium/extensions/html5_drag.rb +55 -11
  89. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  90. data/lib/capybara/selenium/extensions/scroll.rb +8 -10
  91. data/lib/capybara/selenium/logger_suppressor.rb +8 -2
  92. data/lib/capybara/selenium/node.rb +160 -40
  93. data/lib/capybara/selenium/nodes/chrome_node.rb +72 -12
  94. data/lib/capybara/selenium/nodes/edge_node.rb +32 -14
  95. data/lib/capybara/selenium/nodes/firefox_node.rb +28 -32
  96. data/lib/capybara/selenium/nodes/safari_node.rb +5 -29
  97. data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
  98. data/lib/capybara/selenium/patches/atoms.rb +4 -4
  99. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  100. data/lib/capybara/selenium/patches/logs.rb +32 -7
  101. data/lib/capybara/server.rb +19 -3
  102. data/lib/capybara/server/animation_disabler.rb +8 -3
  103. data/lib/capybara/server/checker.rb +1 -1
  104. data/lib/capybara/server/middleware.rb +22 -10
  105. data/lib/capybara/session.rb +66 -40
  106. data/lib/capybara/session/config.rb +11 -3
  107. data/lib/capybara/session/matchers.rb +11 -11
  108. data/lib/capybara/spec/public/offset.js +6 -0
  109. data/lib/capybara/spec/public/test.js +75 -7
  110. data/lib/capybara/spec/session/accept_alert_spec.rb +1 -1
  111. data/lib/capybara/spec/session/all_spec.rb +60 -5
  112. data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
  113. data/lib/capybara/spec/session/assert_text_spec.rb +9 -5
  114. data/lib/capybara/spec/session/check_spec.rb +6 -0
  115. data/lib/capybara/spec/session/click_button_spec.rb +16 -0
  116. data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
  117. data/lib/capybara/spec/session/current_url_spec.rb +11 -1
  118. data/lib/capybara/spec/session/fill_in_spec.rb +29 -0
  119. data/lib/capybara/spec/session/find_spec.rb +55 -0
  120. data/lib/capybara/spec/session/has_ancestor_spec.rb +2 -0
  121. data/lib/capybara/spec/session/has_button_spec.rb +51 -0
  122. data/lib/capybara/spec/session/has_css_spec.rb +26 -4
  123. data/lib/capybara/spec/session/has_current_path_spec.rb +15 -2
  124. data/lib/capybara/spec/session/has_field_spec.rb +34 -0
  125. data/lib/capybara/spec/session/has_select_spec.rb +32 -4
  126. data/lib/capybara/spec/session/has_selector_spec.rb +4 -4
  127. data/lib/capybara/spec/session/has_table_spec.rb +51 -5
  128. data/lib/capybara/spec/session/has_text_spec.rb +30 -0
  129. data/lib/capybara/spec/session/html_spec.rb +1 -1
  130. data/lib/capybara/spec/session/matches_style_spec.rb +2 -2
  131. data/lib/capybara/spec/session/node_spec.rb +394 -9
  132. data/lib/capybara/spec/session/refresh_spec.rb +2 -1
  133. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  134. data/lib/capybara/spec/session/save_page_spec.rb +4 -4
  135. data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -15
  136. data/lib/capybara/spec/session/selectors_spec.rb +16 -3
  137. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +1 -1
  138. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -1
  139. data/lib/capybara/spec/session/window/window_spec.rb +8 -8
  140. data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
  141. data/lib/capybara/spec/spec_helper.rb +14 -14
  142. data/lib/capybara/spec/test_app.rb +27 -21
  143. data/lib/capybara/spec/views/form.erb +47 -4
  144. data/lib/capybara/spec/views/offset.erb +32 -0
  145. data/lib/capybara/spec/views/spatial.erb +31 -0
  146. data/lib/capybara/spec/views/with_animation.erb +37 -1
  147. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  148. data/lib/capybara/spec/views/with_html.erb +24 -2
  149. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  150. data/lib/capybara/spec/views/with_js.erb +4 -1
  151. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  152. data/lib/capybara/spec/views/with_sortable_js.erb +1 -1
  153. data/lib/capybara/version.rb +1 -1
  154. data/lib/capybara/window.rb +3 -7
  155. data/spec/basic_node_spec.rb +15 -14
  156. data/spec/capybara_spec.rb +28 -28
  157. data/spec/dsl_spec.rb +16 -3
  158. data/spec/filter_set_spec.rb +5 -5
  159. data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
  160. data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
  161. data/spec/minitest_spec.rb +3 -2
  162. data/spec/minitest_spec_spec.rb +46 -46
  163. data/spec/rack_test_spec.rb +38 -15
  164. data/spec/regexp_dissassembler_spec.rb +52 -38
  165. data/spec/result_spec.rb +43 -32
  166. data/spec/rspec/features_spec.rb +4 -1
  167. data/spec/rspec/scenarios_spec.rb +4 -0
  168. data/spec/rspec/shared_spec_matchers.rb +68 -56
  169. data/spec/rspec_spec.rb +9 -5
  170. data/spec/selector_spec.rb +32 -17
  171. data/spec/selenium_spec_chrome.rb +78 -11
  172. data/spec/selenium_spec_chrome_remote.rb +23 -6
  173. data/spec/selenium_spec_edge.rb +15 -12
  174. data/spec/selenium_spec_firefox.rb +24 -19
  175. data/spec/selenium_spec_firefox_remote.rb +0 -8
  176. data/spec/selenium_spec_ie.rb +1 -6
  177. data/spec/server_spec.rb +106 -44
  178. data/spec/session_spec.rb +5 -5
  179. data/spec/shared_selenium_node.rb +56 -2
  180. data/spec/shared_selenium_session.rb +122 -15
  181. data/spec/spec_helper.rb +2 -2
  182. metadata +63 -17
  183. data/lib/capybara/spec/session/source_spec.rb +0 -0
@@ -9,6 +9,8 @@ require 'capybara/rspec/matcher_proxies'
9
9
  RSpec.configure do |config|
10
10
  config.include Capybara::DSL, type: :feature
11
11
  config.include Capybara::RSpecMatchers, type: :feature
12
+ config.include Capybara::DSL, type: :system
13
+ config.include Capybara::RSpecMatchers, type: :system
12
14
  config.include Capybara::RSpecMatchers, type: :view
13
15
 
14
16
  # The before and after blocks must run instantaneously, because Capybara
@@ -2,17 +2,17 @@
2
2
 
3
3
  module Capybara
4
4
  module RSpecMatcherProxies
5
- def all(*args, &block)
5
+ def all(*args, **kwargs, &block)
6
6
  if defined?(::RSpec::Matchers::BuiltIn::All) && args.first.respond_to?(:matches?)
7
7
  ::RSpec::Matchers::BuiltIn::All.new(*args)
8
8
  else
9
- find_all(*args, &block)
9
+ find_all(*args, **kwargs, &block)
10
10
  end
11
11
  end
12
12
 
13
- def within(*args, &block)
14
- if block_given?
15
- within_element(*args, &block)
13
+ def within(*args, **kwargs, &block)
14
+ if block
15
+ within_element(*args, **kwargs, &block)
16
16
  else
17
17
  be_within(*args)
18
18
  end
@@ -12,166 +12,189 @@ require 'capybara/rspec/matchers/become_closed'
12
12
 
13
13
  module Capybara
14
14
  module RSpecMatchers
15
- # RSpec matcher for whether the element(s) matching a given selector exist
16
- # See {Capybara::Node::Matcher#assert_selector}
17
- def have_selector(*args, &optional_filter_block)
18
- Matchers::HaveSelector.new(*args, &optional_filter_block)
15
+ # RSpec matcher for whether the element(s) matching a given selector exist.
16
+ #
17
+ # @see Capybara::Node::Matchers#assert_selector
18
+ def have_selector(*args, **kw_args, &optional_filter_block)
19
+ Matchers::HaveSelector.new(*args, **kw_args, &optional_filter_block)
19
20
  end
20
21
 
21
- # RSpec matcher for whether the element(s) matching a group of selectors exist
22
- # See {Capybara::Node::Matcher#assert_all_of_selectors}
23
- def have_all_of_selectors(*args, &optional_filter_block)
24
- Matchers::HaveAllSelectors.new(*args, &optional_filter_block)
22
+ # RSpec matcher for whether the element(s) matching a group of selectors exist.
23
+ #
24
+ # @see Capybara::Node::Matchers#assert_all_of_selectors
25
+ def have_all_of_selectors(*args, **kw_args, &optional_filter_block)
26
+ Matchers::HaveAllSelectors.new(*args, **kw_args, &optional_filter_block)
25
27
  end
26
28
 
27
- # RSpec matcher for whether no element(s) matching a group of selectors exist
28
- # See {Capybara::Node::Matcher#assert_none_of_selectors}
29
- def have_none_of_selectors(*args, &optional_filter_block)
30
- Matchers::HaveNoSelectors.new(*args, &optional_filter_block)
29
+ # RSpec matcher for whether no element(s) matching a group of selectors exist.
30
+ #
31
+ # @see Capybara::Node::Matchers#assert_none_of_selectors
32
+ def have_none_of_selectors(*args, **kw_args, &optional_filter_block)
33
+ Matchers::HaveNoSelectors.new(*args, **kw_args, &optional_filter_block)
31
34
  end
32
35
 
33
- # RSpec matcher for whether the element(s) matching any of a group of selectors exist
34
- # See {Capybara::Node::Matcher#assert_any_of_selectors}
35
- def have_any_of_selectors(*args, &optional_filter_block)
36
- Matchers::HaveAnySelectors.new(*args, &optional_filter_block)
36
+ # RSpec matcher for whether the element(s) matching any of a group of selectors exist.
37
+ #
38
+ # @see Capybara::Node::Matchers#assert_any_of_selectors
39
+ def have_any_of_selectors(*args, **kw_args, &optional_filter_block)
40
+ Matchers::HaveAnySelectors.new(*args, **kw_args, &optional_filter_block)
37
41
  end
38
42
 
39
- # RSpec matcher for whether the current element matches a given selector
40
- # See {Capybara::Node::Matchers#assert_matches_selector}
41
- def match_selector(*args, &optional_filter_block)
42
- Matchers::MatchSelector.new(*args, &optional_filter_block)
43
+ # RSpec matcher for whether the current element matches a given selector.
44
+ #
45
+ # @see Capybara::Node::Matchers#assert_matches_selector
46
+ def match_selector(*args, **kw_args, &optional_filter_block)
47
+ Matchers::MatchSelector.new(*args, **kw_args, &optional_filter_block)
43
48
  end
44
49
 
45
50
  %i[css xpath].each do |selector|
46
51
  define_method "have_#{selector}" do |expr, **options, &optional_filter_block|
47
- Matchers::HaveSelector.new(selector, expr, options, &optional_filter_block)
52
+ Matchers::HaveSelector.new(selector, expr, **options, &optional_filter_block)
48
53
  end
49
54
 
50
55
  define_method "match_#{selector}" do |expr, **options, &optional_filter_block|
51
- Matchers::MatchSelector.new(selector, expr, options, &optional_filter_block)
56
+ Matchers::MatchSelector.new(selector, expr, **options, &optional_filter_block)
52
57
  end
53
58
  end
54
59
 
55
60
  # @!method have_xpath(xpath, **options, &optional_filter_block)
56
- # RSpec matcher for whether elements(s) matching a given xpath selector exist
57
- # See {Capybara::Node::Matchers#has_xpath?}
61
+ # RSpec matcher for whether elements(s) matching a given xpath selector exist.
62
+ #
63
+ # @see Capybara::Node::Matchers#has_xpath?
58
64
 
59
65
  # @!method have_css(css, **options, &optional_filter_block)
60
66
  # RSpec matcher for whether elements(s) matching a given css selector exist
61
- # See {Capybara::Node::Matchers#has_css?}
67
+ #
68
+ # @see Capybara::Node::Matchers#has_css?
62
69
 
63
70
  # @!method match_xpath(xpath, **options, &optional_filter_block)
64
- # RSpec matcher for whether the current element matches a given xpath selector
65
- # See {Capybara::Node::Matchers#matches_xpath?}
71
+ # RSpec matcher for whether the current element matches a given xpath selector.
72
+ #
73
+ # @see Capybara::Node::Matchers#matches_xpath?
66
74
 
67
75
  # @!method match_css(css, **options, &optional_filter_block)
68
- # RSpec matcher for whether the current element matches a given css selector
69
- # See {Capybara::Node::Matchers#matches_css?}
76
+ # RSpec matcher for whether the current element matches a given css selector.
77
+ #
78
+ # @see Capybara::Node::Matchers#matches_css?
70
79
 
71
80
  %i[link button field select table].each do |selector|
72
81
  define_method "have_#{selector}" do |locator = nil, **options, &optional_filter_block|
73
- Matchers::HaveSelector.new(selector, locator, options, &optional_filter_block)
82
+ Matchers::HaveSelector.new(selector, locator, **options, &optional_filter_block)
74
83
  end
75
84
  end
76
85
 
77
86
  # @!method have_link(locator = nil, **options, &optional_filter_block)
78
- # RSpec matcher for links
79
- # See {Capybara::Node::Matchers#has_link?}
87
+ # RSpec matcher for links.
88
+ #
89
+ # @see Capybara::Node::Matchers#has_link?
80
90
 
81
91
  # @!method have_button(locator = nil, **options, &optional_filter_block)
82
- # RSpec matcher for buttons
83
- # See {Capybara::Node::Matchers#has_button?}
92
+ # RSpec matcher for buttons.
93
+ #
94
+ # @see Capybara::Node::Matchers#has_button?
84
95
 
85
96
  # @!method have_field(locator = nil, **options, &optional_filter_block)
86
- # RSpec matcher for links
87
- # See {Capybara::Node::Matchers#has_field?}
97
+ # RSpec matcher for form fields.
98
+ #
99
+ # @see Capybara::Node::Matchers#has_field?
88
100
 
89
101
  # @!method have_select(locator = nil, **options, &optional_filter_block)
90
- # RSpec matcher for select elements
91
- # See {Capybara::Node::Matchers#has_select?}
102
+ # RSpec matcher for select elements.
103
+ #
104
+ # @see Capybara::Node::Matchers#has_select?
92
105
 
93
106
  # @!method have_table(locator = nil, **options, &optional_filter_block)
94
- # RSpec matcher for table elements
95
- # See {Capybara::Node::Matchers#has_table?}
107
+ # RSpec matcher for table elements.
108
+ #
109
+ # @see Capybara::Node::Matchers#has_table?
96
110
 
97
111
  %i[checked unchecked].each do |state|
98
112
  define_method "have_#{state}_field" do |locator = nil, **options, &optional_filter_block|
99
- Matchers::HaveSelector.new(:field, locator, options.merge(state => true), &optional_filter_block)
113
+ Matchers::HaveSelector.new(:field, locator, **options.merge(state => true), &optional_filter_block)
100
114
  end
101
115
  end
102
116
 
103
117
  # @!method have_checked_field(locator = nil, **options, &optional_filter_block)
104
- # RSpec matcher for checked fields
105
- # See {Capybara::Node::Matchers#has_checked_field?}
118
+ # RSpec matcher for checked fields.
119
+ #
120
+ # @see Capybara::Node::Matchers#has_checked_field?
106
121
 
107
122
  # @!method have_unchecked_field(locator = nil, **options, &optional_filter_block)
108
- # RSpec matcher for unchecked fields
109
- # See {Capybara::Node::Matchers#has_unchecked_field?}
123
+ # RSpec matcher for unchecked fields.
124
+ #
125
+ # @see Capybara::Node::Matchers#has_unchecked_field?
110
126
 
111
- # RSpec matcher for text content
112
- # See {Capybara::Node::Matchers#assert_text}
113
- def have_text(*args)
114
- Matchers::HaveText.new(*args)
127
+ # RSpec matcher for text content.
128
+ #
129
+ # @see Capybara::Node::Matchers#assert_text
130
+ def have_text(text_or_type, *args, **options)
131
+ Matchers::HaveText.new(text_or_type, *args, **options)
115
132
  end
116
133
  alias_method :have_content, :have_text
117
134
 
118
135
  def have_title(title, **options)
119
- Matchers::HaveTitle.new(title, options)
136
+ Matchers::HaveTitle.new(title, **options)
120
137
  end
121
138
 
122
- # RSpec matcher for the current path
123
- # See {Capybara::SessionMatchers#assert_current_path}
124
- def have_current_path(path, **options)
125
- Matchers::HaveCurrentPath.new(path, options)
139
+ # RSpec matcher for the current path.
140
+ #
141
+ # @see Capybara::SessionMatchers#assert_current_path
142
+ def have_current_path(path, **options, &optional_filter_block)
143
+ Matchers::HaveCurrentPath.new(path, **options, &optional_filter_block)
126
144
  end
127
145
 
128
- # RSpec matcher for element style
129
- # See {Capybara::Node::Matchers#matches_style?}
130
- def match_style(styles, **options)
131
- Matchers::MatchStyle.new(styles, options)
146
+ # RSpec matcher for element style.
147
+ #
148
+ # @see Capybara::Node::Matchers#matches_style?
149
+ def match_style(styles = nil, **options)
150
+ styles, options = options, {} if styles.nil?
151
+ Matchers::MatchStyle.new(styles, **options)
132
152
  end
133
153
 
134
154
  ##
135
155
  # @deprecated
136
156
  #
137
- def have_style(styles, **options)
138
- warn 'DEPRECATED: have_style is deprecated, please use match_style'
157
+ def have_style(styles = nil, **options)
158
+ Capybara::Helpers.warn "DEPRECATED: have_style is deprecated, please use match_style : #{Capybara::Helpers.filter_backtrace(caller)}"
139
159
  match_style(styles, **options)
140
160
  end
141
161
 
142
162
  %w[selector css xpath text title current_path link button
143
163
  field checked_field unchecked_field select table
144
164
  sibling ancestor].each do |matcher_type|
145
- define_method "have_no_#{matcher_type}" do |*args, &optional_filter_block|
146
- Matchers::NegatedMatcher.new(send("have_#{matcher_type}", *args, &optional_filter_block))
165
+ define_method "have_no_#{matcher_type}" do |*args, **kw_args, &optional_filter_block|
166
+ Matchers::NegatedMatcher.new(send("have_#{matcher_type}", *args, **kw_args, &optional_filter_block))
147
167
  end
148
168
  end
149
169
  alias_method :have_no_content, :have_no_text
150
170
 
151
171
  %w[selector css xpath].each do |matcher_type|
152
- define_method "not_match_#{matcher_type}" do |*args, &optional_filter_block|
153
- Matchers::NegatedMatcher.new(send("match_#{matcher_type}", *args, &optional_filter_block))
172
+ define_method "not_match_#{matcher_type}" do |*args, **kw_args, &optional_filter_block|
173
+ Matchers::NegatedMatcher.new(send("match_#{matcher_type}", *args, **kw_args, &optional_filter_block))
154
174
  end
155
175
  end
156
176
 
157
- # RSpec matcher for whether sibling element(s) matching a given selector exist
158
- # See {Capybara::Node::Matcher#assert_sibling}
159
- def have_sibling(*args, &optional_filter_block)
160
- Matchers::HaveSibling.new(*args, &optional_filter_block)
177
+ # RSpec matcher for whether sibling element(s) matching a given selector exist.
178
+ #
179
+ # @see Capybara::Node::Matchers#assert_sibling
180
+ def have_sibling(*args, **kw_args, &optional_filter_block)
181
+ Matchers::HaveSibling.new(*args, **kw_args, &optional_filter_block)
161
182
  end
162
183
 
163
- # RSpec matcher for whether ancestor element(s) matching a given selector exist
164
- # See {Capybara::Node::Matcher#assert_ancestor}
165
- def have_ancestor(*args, &optional_filter_block)
166
- Matchers::HaveAncestor.new(*args, &optional_filter_block)
184
+ # RSpec matcher for whether ancestor element(s) matching a given selector exist.
185
+ #
186
+ # @see Capybara::Node::Matchers#assert_ancestor
187
+ def have_ancestor(*args, **kw_args, &optional_filter_block)
188
+ Matchers::HaveAncestor.new(*args, **kw_args, &optional_filter_block)
167
189
  end
168
190
 
169
191
  ##
170
192
  # Wait for window to become closed.
193
+ #
171
194
  # @example
172
195
  # expect(window).to become_closed(wait: 0.8)
173
- # @param options [Hash] optional param
174
- # @option options [Numeric] :wait (Capybara.default_max_wait_time) Maximum wait time
196
+ #
197
+ # @option options [Numeric] :wait Maximum wait time. Defaults to {Capybara.configure default_max_wait_time}
175
198
  def become_closed(**options)
176
199
  Matchers::BecomeClosed.new(options)
177
200
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'capybara/rspec/matchers/compound'
4
+ require 'capybara/rspec/matchers/count_sugar'
5
+ require 'capybara/rspec/matchers/spatial_sugar'
4
6
 
5
7
  module Capybara
6
8
  module RSpecMatchers
@@ -10,22 +12,28 @@ module Capybara
10
12
 
11
13
  attr_reader :failure_message, :failure_message_when_negated
12
14
 
13
- def initialize(*args, &filter_block)
15
+ def initialize(*args, **kw_args, &filter_block)
14
16
  @args = args.dup
17
+ @kw_args = kw_args || {}
15
18
  @filter_block = filter_block
16
19
  end
17
20
 
18
21
  private
19
22
 
20
23
  def session_query_args
21
- if @args.last.is_a? Hash
22
- @args.last[:session_options] = session_options
23
- else
24
- @args.push(session_options: session_options)
25
- end
24
+ # if @args.last.is_a? Hash
25
+ # @args.last[:session_options] = session_options
26
+ # else
27
+ # @args.push(session_options: session_options)
28
+ # end
26
29
  @args
27
30
  end
28
31
 
32
+ def session_query_options
33
+ @kw_args[:session_options] = session_options
34
+ @kw_args
35
+ end
36
+
29
37
  def session_options
30
38
  @context_el ||= nil
31
39
  if @context_el.respond_to? :session_options
@@ -65,6 +73,11 @@ module Capybara
65
73
  end
66
74
  end
67
75
 
76
+ class CountableWrappedElementMatcher < WrappedElementMatcher
77
+ include ::Capybara::RSpecMatchers::CountSugar
78
+ include ::Capybara::RSpecMatchers::SpatialSugar
79
+ end
80
+
68
81
  class NegatedMatcher
69
82
  include ::Capybara::RSpecMatchers::Matchers::Compound if defined?(::Capybara::RSpecMatchers::Matchers::Compound)
70
83
 
@@ -29,7 +29,8 @@ module Capybara
29
29
  private
30
30
 
31
31
  def options
32
- (@args.last.is_a?(Hash) ? @args : @args.push({})).last
32
+ # (@args.last.is_a?(Hash) ? @args : @args.push({})).last
33
+ @kw_args
33
34
  end
34
35
  end
35
36
  end
@@ -1,20 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'capybara/rspec/matchers/base'
4
- require 'capybara/rspec/matchers/count_sugar'
5
4
 
6
5
  module Capybara
7
6
  module RSpecMatchers
8
7
  module Matchers
9
- class HaveAncestor < WrappedElementMatcher
10
- include CountSugar
11
-
8
+ class HaveAncestor < CountableWrappedElementMatcher
12
9
  def element_matches?(el)
13
- el.assert_ancestor(*@args, &@filter_block)
10
+ el.assert_ancestor(*@args, **session_query_options, &@filter_block)
14
11
  end
15
12
 
16
13
  def element_does_not_match?(el)
17
- el.assert_no_ancestor(*@args, &@filter_block)
14
+ el.assert_no_ancestor(*@args, **session_query_options, &@filter_block)
18
15
  end
19
16
 
20
17
  def description
@@ -22,7 +19,8 @@ module Capybara
22
19
  end
23
20
 
24
21
  def query
25
- @query ||= Capybara::Queries::AncestorQuery.new(*session_query_args, &@filter_block)
22
+ # @query ||= Capybara::Queries::AncestorQuery.new(*session_query_args, &@filter_block)
23
+ @query ||= Capybara::Queries::AncestorQuery.new(*session_query_args, **session_query_options, &@filter_block)
26
24
  end
27
25
  end
28
26
  end
@@ -7,11 +7,11 @@ module Capybara
7
7
  module Matchers
8
8
  class HaveCurrentPath < WrappedElementMatcher
9
9
  def element_matches?(el)
10
- el.assert_current_path(*@args)
10
+ el.assert_current_path(current_path, **@kw_args, &@filter_block)
11
11
  end
12
12
 
13
13
  def element_does_not_match?(el)
14
- el.assert_no_current_path(*@args)
14
+ el.assert_no_current_path(current_path, **@kw_args, &@filter_block)
15
15
  end
16
16
 
17
17
  def description
@@ -1,20 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'capybara/rspec/matchers/base'
4
- require 'capybara/rspec/matchers/count_sugar'
5
4
 
6
5
  module Capybara
7
6
  module RSpecMatchers
8
7
  module Matchers
9
- class HaveSelector < WrappedElementMatcher
10
- include CountSugar
8
+ class HaveSelector < CountableWrappedElementMatcher
9
+ def initialize(*args, **kw_args, &filter_block)
10
+ super
11
+ if (RUBY_VERSION >= '2.7') && (@args.size < 2) && @kw_args.keys.any?(String) # rubocop:disable Style/GuardClause
12
+ @args.push(@kw_args)
13
+ @kw_args = {}
14
+ end
15
+ end
11
16
 
12
17
  def element_matches?(el)
13
- el.assert_selector(*@args, &@filter_block)
18
+ el.assert_selector(*@args, **session_query_options, &@filter_block)
14
19
  end
15
20
 
16
21
  def element_does_not_match?(el)
17
- el.assert_no_selector(*@args, &@filter_block)
22
+ el.assert_no_selector(*@args, **session_query_options, &@filter_block)
18
23
  end
19
24
 
20
25
  def description
@@ -22,13 +27,13 @@ module Capybara
22
27
  end
23
28
 
24
29
  def query
25
- @query ||= Capybara::Queries::SelectorQuery.new(*session_query_args, &@filter_block)
30
+ @query ||= Capybara::Queries::SelectorQuery.new(*session_query_args, **session_query_options, &@filter_block)
26
31
  end
27
32
  end
28
33
 
29
34
  class HaveAllSelectors < WrappedElementMatcher
30
35
  def element_matches?(el)
31
- el.assert_all_of_selectors(*@args, &@filter_block)
36
+ el.assert_all_of_selectors(*@args, **session_query_options, &@filter_block)
32
37
  end
33
38
 
34
39
  def does_not_match?(_actual)
@@ -42,7 +47,7 @@ module Capybara
42
47
 
43
48
  class HaveNoSelectors < WrappedElementMatcher
44
49
  def element_matches?(el)
45
- el.assert_none_of_selectors(*@args, &@filter_block)
50
+ el.assert_none_of_selectors(*@args, **session_query_options, &@filter_block)
46
51
  end
47
52
 
48
53
  def does_not_match?(_actual)
@@ -56,11 +61,11 @@ module Capybara
56
61
 
57
62
  class HaveAnySelectors < WrappedElementMatcher
58
63
  def element_matches?(el)
59
- el.assert_any_of_selectors(*@args, &@filter_block)
64
+ el.assert_any_of_selectors(*@args, **session_query_options, &@filter_block)
60
65
  end
61
66
 
62
67
  def does_not_match?(_actual)
63
- el.assert_none_of_selectors(*@args, &@filter_block)
68
+ el.assert_none_of_selectors(*@args, **session_query_options, &@filter_block)
64
69
  end
65
70
 
66
71
  def description