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
@@ -5,192 +5,251 @@ require 'minitest/spec'
5
5
  module Capybara
6
6
  module Minitest
7
7
  module Expectations
8
- %w[text content title current_path].each do |assertion|
9
- infect_an_assertion "assert_#{assertion}", "must_have_#{assertion}", :reverse
10
- infect_an_assertion "refute_#{assertion}", "wont_have_#{assertion}", :reverse
11
- end
8
+ ##
9
+ # Expectation that there is an ancestor
10
+ #
11
+ # @!method must_have_ancestor
12
+ # See {Capybara::Node::Matchers#has_ancestor?}
12
13
 
13
- # rubocop:disable Style/MultilineBlockChain
14
- (%w[selector xpath css link button field select table checked_field unchecked_field
15
- ancestor sibling].flat_map do |assertion|
16
- [%W[assert_#{assertion} must_have_#{assertion}],
17
- %W[refute_#{assertion} wont_have_#{assertion}]]
18
- end + [%w[assert_all_of_selectors must_have_all_of_selectors],
19
- %w[assert_none_of_selectors must_have_none_of_selectors],
20
- %w[assert_any_of_selectors must_have_any_of_selectors],
21
- %w[assert_matches_style must_match_style]] +
22
- %w[selector xpath css].flat_map do |assertion|
23
- [%W[assert_matches_#{assertion} must_match_#{assertion}],
24
- %W[refute_matches_#{assertion} wont_match_#{assertion}]]
25
- end).each do |(meth, new_name)|
26
- class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
27
- def #{new_name} *args, &block
28
- ::Minitest::Expectation.new(self, ::Minitest::Spec.current).#{new_name}(*args, &block)
29
- end
30
- ASSERTION
14
+ ##
15
+ # Expectation that there is button
16
+ #
17
+ # @!method must_have_button
18
+ # See {Capybara::Node::Matchers#has_button?}
31
19
 
32
- ::Minitest::Expectation.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
33
- def #{new_name} *args, &block
34
- ctx.#{meth}(target, *args, &block)
35
- end
36
- ASSERTION
37
- end
38
- # rubocop:enable Style/MultilineBlockChain
20
+ ##
21
+ # Expectation that there is no button
22
+ #
23
+ # @!method wont_have_button
24
+ # See {Capybara::Node::Matchers#has_no_button?}
39
25
 
40
26
  ##
41
- # @deprecated
42
- def must_have_style(*args, &block)
43
- warn 'must_have_style is deprecated, please use must_match_style'
44
- must_match_style(*args, &block)
45
- end
27
+ # Expectation that there is checked_field
28
+ #
29
+ # @!method must_have_checked_field
30
+ # See {Capybara::Node::Matchers#has_checked_field?}
46
31
 
47
32
  ##
48
- # Expectation that there is xpath
33
+ # Expectation that there is no checked_field
49
34
  #
50
- # @!method must_have_xpath
51
- # see Capybara::Node::Matchers#has_xpath?
35
+ # @!method wont_have_checked_field
36
+ # See {Capybara::Node::Matchers#has_no_checked_field?}
52
37
 
53
38
  ##
54
- # Expectation that there is no xpath
39
+ # Expectation that there is unchecked_field
55
40
  #
56
- # @!method wont_have_xpath
57
- # see Capybara::Node::Matchers#has_no_xpath?
41
+ # @!method must_have_unchecked_field
42
+ # See {Capybara::Node::Matchers#has_unchecked_field?}
58
43
 
59
44
  ##
60
- # Expectation that there is css
45
+ # Expectation that there is no unchecked_field
61
46
  #
62
- # @!method must_have_css
63
- # see Capybara::Node::Matchers#has_css?
47
+ # @!method wont_have_unchecked_field
48
+ # See {Capybara::Node::Matchers#has_no_unchecked_field?}
64
49
 
65
50
  ##
66
- # Expectation that there is no css
51
+ # Expectation that page content does match
67
52
  #
68
- # @!method wont_have_css
69
- # see Capybara::Node::Matchers#has_no_css?
53
+ # @!method must_have_content
54
+ # See {Capybara::Node::Matchers#has_content?}
70
55
 
71
56
  ##
72
- # Expectation that there is link
57
+ # Expectation that page content does not match
73
58
  #
74
- # @!method must_have_link
75
- # see {Capybara::Node::Matchers#has_link?}
59
+ # @!method wont_have_content
60
+ # See {Capybara::Node::Matchers#has_no_content?}
76
61
 
77
62
  ##
78
- # Expectation that there is no link
63
+ # Expectation that there is css
79
64
  #
80
- # @!method wont_have_link
81
- # see {Capybara::Node::Matchers#has_no_link?}
65
+ # @!method must_have_css
66
+ # See {Capybara::Node::Matchers#has_css?}
82
67
 
83
68
  ##
84
- # Expectation that there is button
69
+ # Expectation that there is no css
85
70
  #
86
- # @!method must_have_button
87
- # see {Capybara::Node::Matchers#has_button?}
71
+ # @!method wont_have_css
72
+ # See {Capybara::Node::Matchers#has_no_css?}
88
73
 
89
74
  ##
90
- # Expectation that there is no button
75
+ # Expectation that current path matches
91
76
  #
92
- # @!method wont_have_button
93
- # see {Capybara::Node::Matchers#has_no_button?}
77
+ # @!method must_have_current_path
78
+ # See {Capybara::SessionMatchers#has_current_path?}
79
+
80
+ ##
81
+ # Expectation that current page does not match
82
+ #
83
+ # @!method wont_have_current_path
84
+ # See {Capybara::SessionMatchers#has_no_current_path?}
94
85
 
95
86
  ##
96
87
  # Expectation that there is field
97
88
  #
98
89
  # @!method must_have_field
99
- # see {Capybara::Node::Matchers#has_field?}
90
+ # See {Capybara::Node::Matchers#has_field?}
100
91
 
101
92
  ##
102
93
  # Expectation that there is no field
103
94
  #
104
95
  # @!method wont_have_field
105
- # see {Capybara::Node::Matchers#has_no_field?}
96
+ # See {Capybara::Node::Matchers#has_no_field?}
106
97
 
107
98
  ##
108
- # Expectation that there is checked_field
99
+ # Expectation that there is link
109
100
  #
110
- # @!method must_have_checked_field
111
- # see {Capybara::Node::Matchers#has_checked_field?}
101
+ # @!method must_have_link
102
+ # See {Capybara::Node::Matchers#has_link?}
112
103
 
113
104
  ##
114
- # Expectation that there is no checked_field
105
+ # Expectation that there is no link
115
106
  #
116
- # @!method wont_have_chceked_field
107
+ # @!method wont_have_link
108
+ # See {Capybara::Node::Matchers#has_no_link?}
117
109
 
118
110
  ##
119
- # Expectation that there is unchecked_field
111
+ # Expectation that page text does match
120
112
  #
121
- # @!method must_have_unchecked_field
122
- # see {Capybara::Node::Matchers#has_unchecked_field?}
113
+ # @!method must_have_text
114
+ # See {Capybara::Node::Matchers#has_text?}
123
115
 
124
116
  ##
125
- # Expectation that there is no unchecked_field
117
+ # Expectation that page text does not match
126
118
  #
127
- # @!method wont_have_unchceked_field
119
+ # @!method wont_have_text
120
+ # See {Capybara::Node::Matchers#has_no_text?}
121
+
122
+ ##
123
+ # Expectation that page title does match
124
+ #
125
+ # @!method must_have_title
126
+ # See {Capybara::Node::DocumentMatchers#has_title?}
127
+
128
+ ##
129
+ # Expectation that page title does not match
130
+ #
131
+ # @!method wont_have_title
132
+ # See {Capybara::Node::DocumentMatchers#has_no_title?}
128
133
 
129
134
  ##
130
135
  # Expectation that there is select
131
136
  #
132
137
  # @!method must_have_select
133
- # see {Capybara::Node::Matchers#has_select?}
138
+ # See {Capybara::Node::Matchers#has_select?}
134
139
 
135
140
  ##
136
141
  # Expectation that there is no select
137
142
  #
138
143
  # @!method wont_have_select
139
- # see {Capybara::Node::Matchers#has_no_select?}
144
+ # See {Capybara::Node::Matchers#has_no_select?}
140
145
 
141
146
  ##
142
- # Expectation that there is table
147
+ # Expectation that there is a selector
143
148
  #
144
- # @!method must_have_table
145
- # see {Capybara::Node::Matchers#has_table?}
149
+ # @!method must_have_selector
150
+ # See {Capybara::Node::Matchers#has_selector?}
146
151
 
147
152
  ##
148
- # Expectation that there is no table
153
+ # Expectation that there is no selector
149
154
  #
150
- # @!method wont_have_table
151
- # see {Capybara::Node::Matchers#has_no_table?}
155
+ # @!method wont_have_selector
156
+ # See {Capybara::Node::Matchers#has_no_selector?}
152
157
 
153
158
  ##
154
- # Expectation that page title does match
159
+ # Expectation that all of the provided selectors are present
155
160
  #
156
- # @!method must_have_title
157
- # see {Capybara::Node::DocumentMatchers#assert_title}
161
+ # @!method must_have_all_of_selectors
162
+ # See {Capybara::Node::Matchers#assert_all_of_selectors}
158
163
 
159
164
  ##
160
- # Expectation that page title does not match
165
+ # Expectation that none of the provided selectors are present
161
166
  #
162
- # @!method wont_have_title
163
- # see {Capybara::Node::DocumentMatchers#assert_no_title}
167
+ # @!method must_have_none_of_selectors
168
+ # See {Capybara::Node::Matchers#assert_none_of_selectors}
164
169
 
165
170
  ##
166
- # Expectation that current path matches
171
+ # Expectation that any of the provided selectors are present
167
172
  #
168
- # @!method must_have_current_path
169
- # see {Capybara::SessionMatchers#assert_current_path}
173
+ # @!method must_have_any_of_selectors
174
+ # See {Capybara::Node::Matchers#assert_any_of_selectors}
170
175
 
171
176
  ##
172
- # Expectation that current page does not match
177
+ # Expectation that there is a sibling
173
178
  #
174
- # @!method wont_have_current_path
175
- # see {Capybara::SessionMatchers#assert_no_current_path}
179
+ # @!method must_have_sibling
180
+ # See {Capybara::Node::Matchers#has_sibling?}
176
181
 
177
182
  ##
178
183
  # Expectation that element has style
179
184
  #
180
185
  # @!method must_match_style
181
- # see {Capybara::Node::Matchers#assert_matches_style}
186
+ # See {Capybara::Node::Matchers#matches_style?}
182
187
 
183
188
  ##
184
- # Expectation that there is an ancestor
189
+ # Expectation that there is table
185
190
  #
186
- # @!method must_have_ancestor
187
- # see Capybara::Node::Matchers#has_ancestor?
191
+ # @!method must_have_table
192
+ # See {Capybara::Node::Matchers#has_table?}
188
193
 
189
194
  ##
190
- # Expectation that there is a sibling
195
+ # Expectation that there is no table
191
196
  #
192
- # @!method must_have_sibling
193
- # see Capybara::Node::Matchers#has_sibling?
197
+ # @!method wont_have_table
198
+ # See {Capybara::Node::Matchers#has_no_table?}
199
+
200
+ ##
201
+ # Expectation that there is xpath
202
+ #
203
+ # @!method must_have_xpath
204
+ # See {Capybara::Node::Matchers#has_xpath?}
205
+
206
+ ##
207
+ # Expectation that there is no xpath
208
+ #
209
+ # @!method wont_have_xpath
210
+ # See {Capybara::Node::Matchers#has_no_xpath?}
211
+
212
+ # This currently doesn't work for Ruby 2.8 due to Minitest not forwarding keyword args separately
213
+ # %w[text content title current_path].each do |assertion|
214
+ # infect_an_assertion "assert_#{assertion}", "must_have_#{assertion}", :reverse
215
+ # infect_an_assertion "refute_#{assertion}", "wont_have_#{assertion}", :reverse
216
+ # end
217
+
218
+ # rubocop:disable Style/MultilineBlockChain
219
+ (%w[text content title current_path
220
+ selector xpath css link button field select table checked_field unchecked_field
221
+ ancestor sibling].flat_map do |assertion|
222
+ [%W[assert_#{assertion} must_have_#{assertion}],
223
+ %W[refute_#{assertion} wont_have_#{assertion}]]
224
+ end + [%w[assert_all_of_selectors must_have_all_of_selectors],
225
+ %w[assert_none_of_selectors must_have_none_of_selectors],
226
+ %w[assert_any_of_selectors must_have_any_of_selectors],
227
+ %w[assert_matches_style must_match_style]] +
228
+ %w[selector xpath css].flat_map do |assertion|
229
+ [%W[assert_matches_#{assertion} must_match_#{assertion}],
230
+ %W[refute_matches_#{assertion} wont_match_#{assertion}]]
231
+ end).each do |(meth, new_name)|
232
+ class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
233
+ def #{new_name} *args, **kw_args, &block
234
+ ::Minitest::Expectation.new(self, ::Minitest::Spec.current).#{new_name}(*args, **kw_args, &block)
235
+ end
236
+ ASSERTION
237
+
238
+ ::Minitest::Expectation.class_eval <<-ASSERTION, __FILE__, __LINE__ + 1
239
+ def #{new_name} *args, **kw_args, &block
240
+ raise "Calling ##{new_name} outside of test." unless ctx
241
+ ctx.#{meth}(target, *args, **kw_args, &block)
242
+ end
243
+ ASSERTION
244
+ end
245
+ # rubocop:enable Style/MultilineBlockChain
246
+
247
+ ##
248
+ # @deprecated
249
+ def must_have_style(*args, **kw_args, &block)
250
+ warn 'must_have_style is deprecated, please use must_match_style'
251
+ must_match_style(*args, **kw_args, &block)
252
+ end
194
253
  end
195
254
  end
196
255
  end
@@ -23,7 +23,7 @@ module Capybara
23
23
  # @return [Capybara::Node::Element] The element clicked
24
24
  #
25
25
  def click_link_or_button(locator = nil, **options)
26
- find(:link_or_button, locator, options).click
26
+ find(:link_or_button, locator, **options).click
27
27
  end
28
28
  alias_method :click_on, :click_link_or_button
29
29
 
@@ -39,7 +39,7 @@ module Capybara
39
39
  #
40
40
  # @return [Capybara::Node::Element] The element clicked
41
41
  def click_link(locator = nil, **options)
42
- find(:link, locator, options).click
42
+ find(:link, locator, **options).click
43
43
  end
44
44
 
45
45
  ##
@@ -55,7 +55,7 @@ module Capybara
55
55
  # @param [Hash] options See {Capybara::Node::Finders#find_button}
56
56
  # @return [Capybara::Node::Element] The element clicked
57
57
  def click_button(locator = nil, **options)
58
- find(:button, locator, options).click
58
+ find(:button, locator, **options).click
59
59
  end
60
60
 
61
61
  ##
@@ -88,7 +88,7 @@ module Capybara
88
88
  def fill_in(locator = nil, with:, currently_with: nil, fill_options: {}, **find_options)
89
89
  find_options[:with] = currently_with if currently_with
90
90
  find_options[:allow_self] = true if locator.nil?
91
- find(:fillable_field, locator, find_options).set(with, fill_options)
91
+ find(:fillable_field, locator, **find_options).set(with, **fill_options)
92
92
  end
93
93
 
94
94
  # @!macro label_click
@@ -119,7 +119,7 @@ module Capybara
119
119
  #
120
120
  # @return [Capybara::Node::Element] The element chosen or the label clicked
121
121
  def choose(locator = nil, **options)
122
- _check_with_label(:radio_button, true, locator, options)
122
+ _check_with_label(:radio_button, true, locator, **options)
123
123
  end
124
124
 
125
125
  ##
@@ -147,7 +147,7 @@ module Capybara
147
147
  #
148
148
  # @return [Capybara::Node::Element] The element checked or the label clicked
149
149
  def check(locator = nil, **options)
150
- _check_with_label(:checkbox, true, locator, options)
150
+ _check_with_label(:checkbox, true, locator, **options)
151
151
  end
152
152
 
153
153
  ##
@@ -175,7 +175,7 @@ module Capybara
175
175
  #
176
176
  # @return [Capybara::Node::Element] The element unchecked or the label clicked
177
177
  def uncheck(locator = nil, **options)
178
- _check_with_label(:checkbox, false, locator, options)
178
+ _check_with_label(:checkbox, false, locator, **options)
179
179
  end
180
180
 
181
181
  ##
@@ -205,7 +205,7 @@ module Capybara
205
205
  if el.respond_to?(:tag_name) && (el.tag_name == 'input')
206
206
  select_datalist_option(el, value)
207
207
  else
208
- el.find(:option, value, options).select_option
208
+ el.find(:option, value, **options).select_option
209
209
  end
210
210
  end
211
211
 
@@ -229,8 +229,8 @@ module Capybara
229
229
  def unselect(value = nil, from: nil, **options)
230
230
  raise ArgumentError, 'The :from option does not take an element' if from.is_a? Capybara::Node::Element
231
231
 
232
- scope = from ? find(:select, from, options) : self
233
- scope.find(:option, value, options).unselect_option
232
+ scope = from ? find(:select, from, **options) : self
233
+ scope.find(:option, value, **options).unselect_option
234
234
  end
235
235
 
236
236
  ##
@@ -276,7 +276,9 @@ module Capybara
276
276
  # @yield Block whose actions will trigger the system file chooser to be shown
277
277
  # @return [Capybara::Node::Element] The file field element
278
278
  def attach_file(locator = nil, paths, make_visible: nil, **options) # rubocop:disable Style/OptionalArguments
279
- raise ArgumentError, '``#attach_file` does not support passing both a locator and a block' if locator && block_given?
279
+ if locator && block_given?
280
+ raise ArgumentError, '``#attach_file` does not support passing both a locator and a block'
281
+ end
280
282
 
281
283
  Array(paths).each do |path|
282
284
  raise Capybara::FileNotFound, "cannot attach file, #{path} does not exist" unless File.exist?(path.to_s)
@@ -288,16 +290,17 @@ module Capybara
288
290
  execute_script CAPTURE_FILE_ELEMENT_SCRIPT
289
291
  yield
290
292
  file_field = evaluate_script 'window._capybara_clicked_file_input'
293
+ raise ArgumentError, "Capybara was unable to determine the file input you're attaching to" unless file_field
291
294
  rescue ::Capybara::NotSupportedByDriverError
292
295
  warn 'Block mode of `#attach_file` is not supported by the current driver - ignoring.'
293
296
  end
294
297
  end
295
298
  # Allow user to update the CSS style of the file input since they are so often hidden on a page
296
299
  if make_visible
297
- ff = file_field || find(:file_field, locator, options.merge(visible: :all))
300
+ ff = file_field || find(:file_field, locator, **options.merge(visible: :all))
298
301
  while_visible(ff, make_visible) { |el| el.set(paths) }
299
302
  else
300
- (file_field || find(:file_field, locator, options)).set(paths)
303
+ (file_field || find(:file_field, locator, **options)).set(paths)
301
304
  end
302
305
  end
303
306
 
@@ -305,16 +308,14 @@ module Capybara
305
308
 
306
309
  def find_select_or_datalist_input(from, options)
307
310
  synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
311
+ find(:select, from, **options)
312
+ rescue Capybara::ElementNotFound => select_error # rubocop:disable Naming/RescuedExceptionsVariableName
313
+ raise if %i[selected with_selected multiple].any? { |option| options.key?(option) }
314
+
308
315
  begin
309
- find(:select, from, options)
310
- rescue Capybara::ElementNotFound => select_error
311
- raise if %i[selected with_selected multiple].any? { |option| options.key?(option) }
312
-
313
- begin
314
- find(:datalist_input, from, options)
315
- rescue Capybara::ElementNotFound => dlinput_error
316
- raise Capybara::ElementNotFound, "#{select_error.message} and #{dlinput_error.message}"
317
- end
316
+ find(:datalist_input, from, **options)
317
+ rescue Capybara::ElementNotFound => dlinput_error # rubocop:disable Naming/RescuedExceptionsVariableName
318
+ raise Capybara::ElementNotFound, "#{select_error.message} and #{dlinput_error.message}"
318
319
  end
319
320
  end
320
321
  end
@@ -337,7 +338,9 @@ module Capybara
337
338
  visible_css = { opacity: 1, display: 'block', visibility: 'visible', width: 'auto', height: 'auto' }
338
339
  end
339
340
  _update_style(element, visible_css)
340
- raise ExpectationNotMet, 'The style changes in :make_visible did not make the file input visible' unless element.visible?
341
+ unless element.visible?
342
+ raise ExpectationNotMet, 'The style changes in :make_visible did not make the file input visible'
343
+ end
341
344
 
342
345
  begin
343
346
  yield element
@@ -354,26 +357,23 @@ module Capybara
354
357
 
355
358
  def _reset_style(element)
356
359
  element.execute_script(RESET_STYLE_SCRIPT)
357
- rescue StandardError # rubocop:disable Lint/HandleExceptions swallow extra errors
360
+ rescue StandardError # rubocop:disable Lint/SuppressedException swallow extra errors
358
361
  end
359
362
 
360
363
  def _check_with_label(selector, checked, locator,
361
364
  allow_label_click: session_options.automatic_label_click, **options)
362
365
  options[:allow_self] = true if locator.nil?
363
-
364
366
  synchronize(Capybara::Queries::BaseQuery.wait(options, session_options.default_max_wait_time)) do
367
+ el = find(selector, locator, **options)
368
+ el.set(checked)
369
+ rescue StandardError => e
370
+ raise unless allow_label_click && catch_error?(e)
371
+
365
372
  begin
366
- el = find(selector, locator, options)
367
- el.set(checked)
368
- rescue StandardError => e
369
- raise unless allow_label_click && catch_error?(e)
370
-
371
- begin
372
- el ||= find(selector, locator, options.merge(visible: :all))
373
- el.session.find(:label, for: el, visible: true).click unless el.checked? == checked
374
- rescue StandardError # swallow extra errors - raise original
375
- raise e
376
- end
373
+ el ||= find(selector, locator, **options.merge(visible: :all))
374
+ el.session.find(:label, for: el, visible: true, match: :first).click unless el.checked? == checked
375
+ rescue StandardError # swallow extra errors - raise original
376
+ raise e
377
377
  end
378
378
  end
379
379
  end