capybara 2.15.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (177) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +137 -2
  3. data/README.md +36 -25
  4. data/lib/capybara/config.rb +11 -57
  5. data/lib/capybara/cucumber.rb +2 -3
  6. data/lib/capybara/driver/base.rb +19 -16
  7. data/lib/capybara/driver/node.rb +5 -4
  8. data/lib/capybara/dsl.rb +1 -0
  9. data/lib/capybara/helpers.rb +19 -29
  10. data/lib/capybara/minitest/spec.rb +16 -13
  11. data/lib/capybara/minitest.rb +140 -137
  12. data/lib/capybara/node/actions.rb +68 -89
  13. data/lib/capybara/node/base.rb +11 -18
  14. data/lib/capybara/node/document.rb +2 -2
  15. data/lib/capybara/node/document_matchers.rb +8 -8
  16. data/lib/capybara/node/element.rb +32 -42
  17. data/lib/capybara/node/finders.rb +64 -71
  18. data/lib/capybara/node/matchers.rb +50 -71
  19. data/lib/capybara/node/simple.rb +11 -17
  20. data/lib/capybara/queries/ancestor_query.rb +12 -8
  21. data/lib/capybara/queries/base_query.rb +22 -18
  22. data/lib/capybara/queries/current_path_query.rb +12 -25
  23. data/lib/capybara/queries/match_query.rb +3 -7
  24. data/lib/capybara/queries/selector_query.rb +100 -96
  25. data/lib/capybara/queries/sibling_query.rb +5 -5
  26. data/lib/capybara/queries/text_query.rb +35 -35
  27. data/lib/capybara/queries/title_query.rb +8 -11
  28. data/lib/capybara/rack_test/browser.rb +15 -18
  29. data/lib/capybara/rack_test/css_handlers.rb +6 -4
  30. data/lib/capybara/rack_test/driver.rb +6 -10
  31. data/lib/capybara/rack_test/form.rb +52 -39
  32. data/lib/capybara/rack_test/node.rb +93 -63
  33. data/lib/capybara/rails.rb +2 -6
  34. data/lib/capybara/result.rb +22 -22
  35. data/lib/capybara/rspec/compound.rb +5 -10
  36. data/lib/capybara/rspec/features.rb +17 -48
  37. data/lib/capybara/rspec/matcher_proxies.rb +31 -15
  38. data/lib/capybara/rspec/matchers.rb +116 -58
  39. data/lib/capybara/rspec.rb +5 -10
  40. data/lib/capybara/selector/css.rb +6 -11
  41. data/lib/capybara/selector/filter.rb +1 -17
  42. data/lib/capybara/selector/filter_set.rb +18 -15
  43. data/lib/capybara/selector/filters/base.rb +7 -6
  44. data/lib/capybara/selector/filters/expression_filter.rb +6 -23
  45. data/lib/capybara/selector/filters/node_filter.rb +2 -12
  46. data/lib/capybara/selector/selector.rb +28 -34
  47. data/lib/capybara/selector.rb +129 -117
  48. data/lib/capybara/selenium/driver.rb +172 -163
  49. data/lib/capybara/selenium/node.rb +218 -104
  50. data/lib/capybara/server.rb +3 -2
  51. data/lib/capybara/session/config.rb +47 -59
  52. data/lib/capybara/session/matchers.rb +23 -14
  53. data/lib/capybara/session.rb +175 -229
  54. data/lib/capybara/spec/fixtures/no_extension +1 -0
  55. data/lib/capybara/spec/public/test.js +38 -6
  56. data/lib/capybara/spec/session/accept_alert_spec.rb +1 -0
  57. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -2
  58. data/lib/capybara/spec/session/accept_prompt_spec.rb +30 -1
  59. data/lib/capybara/spec/session/all_spec.rb +31 -18
  60. data/lib/capybara/spec/session/ancestor_spec.rb +6 -8
  61. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +6 -5
  62. data/lib/capybara/spec/session/assert_current_path.rb +12 -11
  63. data/lib/capybara/spec/session/assert_selector.rb +1 -0
  64. data/lib/capybara/spec/session/assert_text.rb +31 -23
  65. data/lib/capybara/spec/session/assert_title.rb +13 -3
  66. data/lib/capybara/spec/session/attach_file_spec.rb +57 -29
  67. data/lib/capybara/spec/session/body_spec.rb +1 -0
  68. data/lib/capybara/spec/session/check_spec.rb +7 -6
  69. data/lib/capybara/spec/session/choose_spec.rb +5 -4
  70. data/lib/capybara/spec/session/click_button_spec.rb +24 -32
  71. data/lib/capybara/spec/session/click_link_or_button_spec.rb +8 -7
  72. data/lib/capybara/spec/session/click_link_spec.rb +8 -7
  73. data/lib/capybara/spec/session/current_scope_spec.rb +4 -3
  74. data/lib/capybara/spec/session/current_url_spec.rb +19 -8
  75. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +1 -1
  76. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -0
  77. data/lib/capybara/spec/session/element/assert_match_selector.rb +1 -1
  78. data/lib/capybara/spec/session/element/match_xpath_spec.rb +1 -1
  79. data/lib/capybara/spec/session/element/matches_selector_spec.rb +5 -5
  80. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
  81. data/lib/capybara/spec/session/evaluate_script_spec.rb +5 -4
  82. data/lib/capybara/spec/session/execute_script_spec.rb +4 -3
  83. data/lib/capybara/spec/session/fill_in_spec.rb +30 -5
  84. data/lib/capybara/spec/session/find_button_spec.rb +4 -3
  85. data/lib/capybara/spec/session/find_by_id_spec.rb +2 -1
  86. data/lib/capybara/spec/session/find_field_spec.rb +9 -15
  87. data/lib/capybara/spec/session/find_link_spec.rb +6 -5
  88. data/lib/capybara/spec/session/find_spec.rb +37 -31
  89. data/lib/capybara/spec/session/first_spec.rb +60 -33
  90. data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
  91. data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
  92. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +2 -1
  93. data/lib/capybara/spec/session/frame/within_frame_spec.rb +9 -16
  94. data/lib/capybara/spec/session/go_back_spec.rb +1 -0
  95. data/lib/capybara/spec/session/go_forward_spec.rb +1 -0
  96. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  97. data/lib/capybara/spec/session/has_button_spec.rb +2 -1
  98. data/lib/capybara/spec/session/has_css_spec.rb +3 -2
  99. data/lib/capybara/spec/session/has_current_path_spec.rb +49 -22
  100. data/lib/capybara/spec/session/has_field_spec.rb +4 -3
  101. data/lib/capybara/spec/session/has_link_spec.rb +5 -4
  102. data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
  103. data/lib/capybara/spec/session/has_select_spec.rb +32 -31
  104. data/lib/capybara/spec/session/has_selector_spec.rb +5 -4
  105. data/lib/capybara/spec/session/has_table_spec.rb +2 -1
  106. data/lib/capybara/spec/session/has_text_spec.rb +9 -13
  107. data/lib/capybara/spec/session/has_title_spec.rb +1 -0
  108. data/lib/capybara/spec/session/has_xpath_spec.rb +1 -0
  109. data/lib/capybara/spec/session/headers.rb +2 -1
  110. data/lib/capybara/spec/session/html_spec.rb +1 -0
  111. data/lib/capybara/spec/session/node_spec.rb +107 -58
  112. data/lib/capybara/spec/session/node_wrapper_spec.rb +36 -0
  113. data/lib/capybara/spec/session/refresh_spec.rb +6 -2
  114. data/lib/capybara/spec/session/reset_session_spec.rb +19 -0
  115. data/lib/capybara/spec/session/response_code.rb +1 -0
  116. data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
  117. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -11
  118. data/lib/capybara/spec/session/save_page_spec.rb +1 -17
  119. data/lib/capybara/spec/session/save_screenshot_spec.rb +3 -3
  120. data/lib/capybara/spec/session/select_spec.rb +21 -20
  121. data/lib/capybara/spec/session/selectors_spec.rb +2 -2
  122. data/lib/capybara/spec/session/sibling_spec.rb +1 -1
  123. data/lib/capybara/spec/session/text_spec.rb +17 -3
  124. data/lib/capybara/spec/session/title_spec.rb +11 -1
  125. data/lib/capybara/spec/session/uncheck_spec.rb +4 -3
  126. data/lib/capybara/spec/session/unselect_spec.rb +7 -6
  127. data/lib/capybara/spec/session/visit_spec.rb +64 -3
  128. data/lib/capybara/spec/session/window/become_closed_spec.rb +2 -1
  129. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
  130. data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
  131. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +2 -1
  132. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +2 -1
  133. data/lib/capybara/spec/session/window/window_spec.rb +12 -12
  134. data/lib/capybara/spec/session/window/windows_spec.rb +2 -3
  135. data/lib/capybara/spec/session/window/within_window_spec.rb +15 -71
  136. data/lib/capybara/spec/session/within_spec.rb +1 -0
  137. data/lib/capybara/spec/spec_helper.rb +36 -18
  138. data/lib/capybara/spec/test_app.rb +17 -9
  139. data/lib/capybara/spec/views/form.erb +7 -0
  140. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  141. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  142. data/lib/capybara/spec/views/with_hover.erb +5 -0
  143. data/lib/capybara/spec/views/with_html.erb +27 -1
  144. data/lib/capybara/spec/views/with_js.erb +11 -0
  145. data/lib/capybara/spec/views/within_frames.erb +4 -1
  146. data/lib/capybara/version.rb +2 -1
  147. data/lib/capybara/window.rb +6 -10
  148. data/lib/capybara.rb +29 -26
  149. data/spec/basic_node_spec.rb +1 -0
  150. data/spec/capybara_spec.rb +16 -69
  151. data/spec/dsl_spec.rb +5 -13
  152. data/spec/filter_set_spec.rb +5 -4
  153. data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -1
  154. data/spec/fixtures/selenium_driver_rspec_success.rb +3 -2
  155. data/spec/minitest_spec.rb +13 -4
  156. data/spec/minitest_spec_spec.rb +12 -3
  157. data/spec/per_session_config_spec.rb +9 -8
  158. data/spec/rack_test_spec.rb +21 -20
  159. data/spec/result_spec.rb +17 -16
  160. data/spec/rspec/features_spec.rb +17 -14
  161. data/spec/rspec/scenarios_spec.rb +5 -7
  162. data/spec/rspec/shared_spec_matchers.rb +96 -99
  163. data/spec/rspec/views_spec.rb +2 -1
  164. data/spec/rspec_matchers_spec.rb +18 -2
  165. data/spec/rspec_spec.rb +11 -15
  166. data/spec/selector_spec.rb +5 -6
  167. data/spec/selenium_spec_chrome.rb +20 -11
  168. data/spec/selenium_spec_edge.rb +27 -0
  169. data/spec/selenium_spec_ie.rb +31 -0
  170. data/spec/selenium_spec_marionette.rb +38 -12
  171. data/spec/server_spec.rb +33 -33
  172. data/spec/session_spec.rb +2 -1
  173. data/spec/shared_selenium_session.rb +82 -22
  174. data/spec/spec_helper.rb +3 -6
  175. metadata +76 -81
  176. data/lib/capybara/query.rb +0 -7
  177. data/spec/selenium_spec_firefox.rb +0 -68
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#has_select?' do
3
4
  before { @session.visit('/form') }
4
5
 
@@ -6,7 +7,7 @@ Capybara::SpecHelper.spec '#has_select?' do
6
7
  expect(@session).to have_select('Locale')
7
8
  expect(@session).to have_select('form_region')
8
9
  expect(@session).to have_select('Languages')
9
- expect(@session).to have_select(:'Languages')
10
+ expect(@session).to have_select(:Languages)
10
11
  end
11
12
 
12
13
  it "should be false if the field is not on the page" do
@@ -27,13 +28,13 @@ Capybara::SpecHelper.spec '#has_select?' do
27
28
  expect(@session).not_to have_select('Does not exist', selected: 'John')
28
29
  expect(@session).not_to have_select('City', selected: 'Not there')
29
30
  expect(@session).not_to have_select('Underwear', selected: [
30
- 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns', 'Nonexistant'
31
+ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns', 'Nonexistent'
31
32
  ])
32
33
  expect(@session).not_to have_select('Underwear', selected: [
33
34
  'Boxerbriefs', 'Briefs', 'Boxers', 'Commando', "Frenchman's Pantalons", 'Long Johns'
34
35
  ])
35
36
  expect(@session).not_to have_select('Underwear', selected: [
36
- 'Boxerbriefs', 'Briefs','Commando', "Frenchman's Pantalons"
37
+ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons"
37
38
  ])
38
39
  end
39
40
 
@@ -69,25 +70,25 @@ Capybara::SpecHelper.spec '#has_select?' do
69
70
 
70
71
  context 'with partial select' do
71
72
  it "should be true if a field with the given partial values is on the page" do
72
- expect(@session).to have_select('Underwear', with_selected: ['Boxerbriefs', 'Briefs'])
73
+ expect(@session).to have_select('Underwear', with_selected: %w[Boxerbriefs Briefs])
73
74
  end
74
75
 
75
76
  it "should be false if a field with the given partial values is not on the page" do
76
- expect(@session).not_to have_select('Underwear', with_selected: ['Boxerbriefs', 'Boxers'])
77
+ expect(@session).not_to have_select('Underwear', with_selected: %w[Boxerbriefs Boxers])
77
78
  end
78
79
 
79
80
  it "should be true after the given partial value is selected" do
80
81
  @session.select('Boxers', from: 'Underwear')
81
- expect(@session).to have_select('Underwear', with_selected: ['Boxerbriefs', 'Boxers'])
82
+ expect(@session).to have_select('Underwear', with_selected: %w[Boxerbriefs Boxers])
82
83
  end
83
84
 
84
85
  it "should be false after one of the given partial values is unselected" do
85
86
  @session.unselect('Briefs', from: 'Underwear')
86
- expect(@session).not_to have_select('Underwear', with_selected: ['Boxerbriefs', 'Briefs'])
87
+ expect(@session).not_to have_select('Underwear', with_selected: %w[Boxerbriefs Briefs])
87
88
  end
88
89
 
89
90
  it "should be true even when the selected values are invisible, regardless of the select's visibility" do
90
- expect(@session).to have_select('Dessert', visible: false, with_options: ['Pudding', 'Tiramisu'])
91
+ expect(@session).to have_select('Dessert', visible: false, with_options: %w[Pudding Tiramisu])
91
92
  expect(@session).to have_select('Cake', with_selected: ['Chocolate Cake', 'Sponge Cake'])
92
93
  end
93
94
 
@@ -99,7 +100,7 @@ Capybara::SpecHelper.spec '#has_select?' do
99
100
 
100
101
  context 'with exact options' do
101
102
  it "should be true if a field with the given options is on the page" do
102
- expect(@session).to have_select('Region', options: ['Norway', 'Sweden', 'Finland'])
103
+ expect(@session).to have_select('Region', options: %w[Norway Sweden Finland])
103
104
  expect(@session).to have_select('Tendency', options: [])
104
105
  end
105
106
 
@@ -107,29 +108,29 @@ Capybara::SpecHelper.spec '#has_select?' do
107
108
  expect(@session).not_to have_select('Locale', options: ['Swedish'])
108
109
  expect(@session).not_to have_select('Does not exist', options: ['John'])
109
110
  expect(@session).not_to have_select('City', options: ['London', 'Made up city'])
110
- expect(@session).not_to have_select('Region', options: ['Norway', 'Sweden'])
111
- expect(@session).not_to have_select('Region', options: ['Norway', 'Norway', 'Norway'])
111
+ expect(@session).not_to have_select('Region', options: %w[Norway Sweden])
112
+ expect(@session).not_to have_select('Region', options: %w[Norway Norway Norway])
112
113
  end
113
114
 
114
115
  it "should be true even when the options are invisible, if the select itself is invisible" do
115
- expect(@session).to have_select("Icecream", visible: false, options: ['Chocolate', 'Vanilla', 'Strawberry'])
116
+ expect(@session).to have_select("Icecream", visible: false, options: %w[Chocolate Vanilla Strawberry])
116
117
  end
117
118
  end
118
119
 
119
120
  context 'with partial options' do
120
121
  it "should be true if a field with the given partial options is on the page" do
121
- expect(@session).to have_select('Region', with_options: ['Norway', 'Sweden'])
122
+ expect(@session).to have_select('Region', with_options: %w[Norway Sweden])
122
123
  expect(@session).to have_select('City', with_options: ['London'])
123
124
  end
124
125
 
125
126
  it "should be false if a field with the given partial options is not on the page" do
126
127
  expect(@session).not_to have_select('Locale', with_options: ['Uruguayan'])
127
128
  expect(@session).not_to have_select('Does not exist', with_options: ['John'])
128
- expect(@session).not_to have_select('Region', with_options: ['Norway', 'Sweden', 'Finland', 'Latvia'])
129
+ expect(@session).not_to have_select('Region', with_options: %w[Norway Sweden Finland Latvia])
129
130
  end
130
131
 
131
132
  it "should be true even when the options are invisible, if the select itself is invisible" do
132
- expect(@session).to have_select("Icecream", visible: false, with_options: ['Vanilla', 'Strawberry'])
133
+ expect(@session).to have_select("Icecream", visible: false, with_options: %w[Vanilla Strawberry])
133
134
  end
134
135
  end
135
136
 
@@ -151,9 +152,9 @@ Capybara::SpecHelper.spec '#has_select?' do
151
152
  end
152
153
 
153
154
  it "should support locator-less usage" do
154
- expect(@session.has_select?(with_options: ['Norway', 'Sweden'])).to eq true
155
+ expect(@session.has_select?(with_options: %w[Norway Sweden])).to eq true
155
156
  expect(@session).to have_select(with_options: ['London'])
156
- expect(@session.has_select?(with_selected: ['Commando', 'Boxerbriefs'])).to eq true
157
+ expect(@session.has_select?(with_selected: %w[Commando Boxerbriefs])).to eq true
157
158
  expect(@session).to have_select(with_selected: ['Briefs'])
158
159
  end
159
160
  end
@@ -185,13 +186,13 @@ Capybara::SpecHelper.spec '#has_no_select?' do
185
186
  expect(@session).to have_no_select('Does not exist', selected: 'John')
186
187
  expect(@session).to have_no_select('City', selected: 'Not there')
187
188
  expect(@session).to have_no_select('Underwear', selected: [
188
- 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns', 'Nonexistant'
189
+ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons", 'Long Johns', 'Nonexistent'
189
190
  ])
190
191
  expect(@session).to have_no_select('Underwear', selected: [
191
192
  'Boxerbriefs', 'Briefs', 'Boxers', 'Commando', "Frenchman's Pantalons", 'Long Johns'
192
193
  ])
193
194
  expect(@session).to have_no_select('Underwear', selected: [
194
- 'Boxerbriefs', 'Briefs','Commando', "Frenchman's Pantalons"
195
+ 'Boxerbriefs', 'Briefs', 'Commando', "Frenchman's Pantalons"
195
196
  ])
196
197
  end
197
198
 
@@ -222,21 +223,21 @@ Capybara::SpecHelper.spec '#has_no_select?' do
222
223
 
223
224
  context 'with partial select' do
224
225
  it "should be false if a field with the given partial values is on the page" do
225
- expect(@session).not_to have_no_select('Underwear', with_selected: ['Boxerbriefs', 'Briefs'])
226
+ expect(@session).not_to have_no_select('Underwear', with_selected: %w[Boxerbriefs Briefs])
226
227
  end
227
228
 
228
229
  it "should be true if a field with the given partial values is not on the page" do
229
- expect(@session).to have_no_select('Underwear', with_selected: ['Boxerbriefs', 'Boxers'])
230
+ expect(@session).to have_no_select('Underwear', with_selected: %w[Boxerbriefs Boxers])
230
231
  end
231
232
 
232
233
  it "should be false after the given partial value is selected" do
233
234
  @session.select('Boxers', from: 'Underwear')
234
- expect(@session).not_to have_no_select('Underwear', with_selected: ['Boxerbriefs', 'Boxers'])
235
+ expect(@session).not_to have_no_select('Underwear', with_selected: %w[Boxerbriefs Boxers])
235
236
  end
236
237
 
237
238
  it "should be true after one of the given partial values is unselected" do
238
239
  @session.unselect('Briefs', from: 'Underwear')
239
- expect(@session).to have_no_select('Underwear', with_selected: ['Boxerbriefs', 'Briefs'])
240
+ expect(@session).to have_no_select('Underwear', with_selected: %w[Boxerbriefs Briefs])
240
241
  end
241
242
 
242
243
  it "should support non array partial values" do
@@ -247,35 +248,35 @@ Capybara::SpecHelper.spec '#has_no_select?' do
247
248
 
248
249
  context 'with exact options' do
249
250
  it "should be false if a field with the given options is on the page" do
250
- expect(@session).not_to have_no_select('Region', options: ['Norway', 'Sweden', 'Finland'])
251
+ expect(@session).not_to have_no_select('Region', options: %w[Norway Sweden Finland])
251
252
  end
252
253
 
253
254
  it "should be true if the given field is not on the page" do
254
255
  expect(@session).to have_no_select('Locale', options: ['Swedish'])
255
256
  expect(@session).to have_no_select('Does not exist', options: ['John'])
256
257
  expect(@session).to have_no_select('City', options: ['London', 'Made up city'])
257
- expect(@session).to have_no_select('Region', options: ['Norway', 'Sweden'])
258
- expect(@session).to have_no_select('Region', options: ['Norway', 'Norway', 'Norway'])
258
+ expect(@session).to have_no_select('Region', options: %w[Norway Sweden])
259
+ expect(@session).to have_no_select('Region', options: %w[Norway Norway Norway])
259
260
  end
260
261
  end
261
262
 
262
263
  context 'with partial options' do
263
264
  it "should be false if a field with the given partial options is on the page" do
264
- expect(@session).not_to have_no_select('Region', with_options: ['Norway', 'Sweden'])
265
+ expect(@session).not_to have_no_select('Region', with_options: %w[Norway Sweden])
265
266
  expect(@session).not_to have_no_select('City', with_options: ['London'])
266
267
  end
267
268
 
268
269
  it "should be true if a field with the given partial options is not on the page" do
269
270
  expect(@session).to have_no_select('Locale', with_options: ['Uruguayan'])
270
271
  expect(@session).to have_no_select('Does not exist', with_options: ['John'])
271
- expect(@session).to have_no_select('Region', with_options: ['Norway', 'Sweden', 'Finland', 'Latvia'])
272
+ expect(@session).to have_no_select('Region', with_options: %w[Norway Sweden Finland Latvia])
272
273
  end
273
274
  end
274
275
 
275
276
  it "should support locator-less usage" do
276
- expect(@session.has_no_select?(with_options: ['Norway', 'Sweden', 'Finland', 'Latvia'])).to eq true
277
- expect(@session).to have_no_select(with_options: ['New London'] )
277
+ expect(@session.has_no_select?(with_options: %w[Norway Sweden Finland Latvia])).to eq true
278
+ expect(@session).to have_no_select(with_options: ['New London'])
278
279
  expect(@session.has_no_select?(with_selected: ['Boxers'])).to eq true
279
- expect(@session).to have_no_select(with_selected: ['Commando', 'Boxers'])
280
+ expect(@session).to have_no_select(with_selected: %w[Commando Boxers])
280
281
  end
281
282
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#has_selector?' do
3
4
  before do
4
5
  @session.visit('/with_html')
@@ -72,9 +73,10 @@ Capybara::SpecHelper.spec '#has_selector?' do
72
73
  expect(@session).not_to have_selector("//p//a", text: /Red$/)
73
74
  end
74
75
 
75
- it "should warn when extra parameters passed" do
76
- expect_any_instance_of(Kernel).to receive(:warn).with(/extra/)
77
- expect(@session).to have_selector(:css, "p a#foo", 'extra')
76
+ it "should raise when extra parameters passed" do
77
+ expect do
78
+ expect(@session).to have_selector(:css, "p a#foo", 'extra')
79
+ end.to raise_error ArgumentError, /extra/
78
80
  end
79
81
  end
80
82
 
@@ -131,7 +133,6 @@ Capybara::SpecHelper.spec '#has_no_selector?' do
131
133
  end
132
134
 
133
135
  it "should accept a filter block" do
134
- skip "RSpec < 3 doesn't pass the block along to the matcher for the Builtin::Has matcher" if rspec2?
135
136
  expect(@session).to have_no_selector(:css, "a#foo") { |el| el[:id] != "foo" }
136
137
  end
137
138
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#has_table?' do
3
4
  before do
4
5
  @session.visit('/tables')
@@ -7,7 +8,7 @@ Capybara::SpecHelper.spec '#has_table?' do
7
8
  it "should be true if the table is on the page" do
8
9
  expect(@session).to have_table('Villain')
9
10
  expect(@session).to have_table('villain_table')
10
- expect(@session).to have_table(:'villain_table')
11
+ expect(@session).to have_table(:villain_table)
11
12
  end
12
13
 
13
14
  it "should be false if the table is not on the page" do
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#has_text?' do
3
4
  it "should be true if the given text is on the page at least once" do
4
5
  @session.visit('/with_html')
5
6
  expect(@session).to have_text('est')
6
7
  expect(@session).to have_text('Lorem')
7
8
  expect(@session).to have_text('Redirect')
8
- expect(@session).to have_text(:'Redirect')
9
+ expect(@session).to have_text(:Redirect)
9
10
  end
10
11
 
11
12
  it "should be true if scoped to an element which has the text" do
@@ -28,14 +29,9 @@ Capybara::SpecHelper.spec '#has_text?' do
28
29
  expect(@session).to have_text('exercitation ullamco laboris')
29
30
  end
30
31
 
31
- it "should ignore extra whitespace and newlines" do
32
- @session.visit('/with_html')
33
- expect(@session).to have_text('text with whitespace')
34
- end
35
-
36
- it "should ignore whitespace and newlines in the search string" do
32
+ it "should search correctly normalized text" do
37
33
  @session.visit('/with_html')
38
- expect(@session).to have_text("text with \n\n whitespace")
34
+ expect(@session).to have_text('text with whitespace')
39
35
  end
40
36
 
41
37
  it "should be false if the given text is not on the page" do
@@ -51,12 +47,12 @@ Capybara::SpecHelper.spec '#has_text?' do
51
47
 
52
48
  it 'should handle double quotes in the text' do
53
49
  @session.visit('/with-quotes')
54
- expect(@session).to have_text(%q{"No," he said})
50
+ expect(@session).to have_text('"No," he said')
55
51
  end
56
52
 
57
53
  it 'should handle mixed single and double quotes in the text' do
58
54
  @session.visit('/with-quotes')
59
- expect(@session).to have_text(%q{"you can't do that."})
55
+ expect(@session).to have_text(%q("you can't do that."))
60
56
  end
61
57
 
62
58
  it 'should be false if text is in the title tag in the head' do
@@ -265,12 +261,12 @@ Capybara::SpecHelper.spec '#has_no_text?' do
265
261
 
266
262
  it 'should handle double quotes in the text' do
267
263
  @session.visit('/with-quotes')
268
- expect(@session).not_to have_no_text(%q{"No," he said})
264
+ expect(@session).not_to have_no_text('"No," he said')
269
265
  end
270
266
 
271
267
  it 'should handle mixed single and double quotes in the text' do
272
268
  @session.visit('/with-quotes')
273
- expect(@session).not_to have_no_text(%q{"you can't do that."})
269
+ expect(@session).not_to have_no_text(%q("you can't do that."))
274
270
  end
275
271
 
276
272
  it 'should be true if text is in the title tag in the head' do
@@ -325,7 +321,7 @@ Capybara::SpecHelper.spec '#has_no_text?' do
325
321
  it "should not find element if it appears after given wait duration" do
326
322
  @session.visit('/with_js')
327
323
  @session.click_link('Click me')
328
- expect(@session).to have_no_text('Has been clicked', wait: 0.1)
324
+ expect(@session).to have_no_text('Has been clicked', wait: 0.05)
329
325
  end
330
326
  end
331
327
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#has_title?' do
3
4
  before do
4
5
  @session.visit('/with_js')
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#has_xpath?' do
3
4
  before do
4
5
  @session.visit('/with_html')
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#response_headers' do
3
4
  it "should return response headers", requires: [:response_headers] do
4
5
  @session.visit('/with_simple_html')
5
- expect(@session.response_headers['Content-Type']).to match %r(text/html)
6
+ expect(@session.response_headers['Content-Type']).to match %r{text/html}
6
7
  end
7
8
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#html' do
3
4
  it "should return the unmodified page body" do
4
5
  @session.visit('/')
@@ -27,14 +27,6 @@ Capybara::SpecHelper.spec "node" do
27
27
  end
28
28
  end
29
29
 
30
- describe "#parent" do
31
- it "should be deprecated" do
32
- @node = @session.find(:css, '#first')
33
- expect(@node).to receive(:warn).with(/^DEPRECATED:/)
34
- expect(@node.parent).to eq(@node.query_scope)
35
- end
36
- end
37
-
38
30
  describe "#text" do
39
31
  it "should extract node texts" do
40
32
  expect(@session.all('//a')[0].text).to eq('labore')
@@ -102,44 +94,32 @@ Capybara::SpecHelper.spec "node" do
102
94
  expect(@session.first('//input').value).to eq('')
103
95
  end
104
96
 
105
- it "should not set if the text field is readonly" do
106
- expect(@session.first('//input[@readonly]').value).to eq('should not change')
107
- @session.first('//input[@readonly]').set('changed')
108
- expect(@session.first('//input[@readonly]').value).to eq('should not change')
109
- end
110
-
111
97
  it "should raise if the text field is readonly" do
112
- expect(@session.first('//input[@readonly]').set('changed')).to raise_error(Capybara::ReadOnlyElementError)
113
- end if Capybara::VERSION.to_f > 3.0
114
-
115
- it "should not set if the textarea is readonly" do
116
- expect(@session.first('//textarea[@readonly]').value).to eq('textarea should not change')
117
- @session.first('//textarea[@readonly]').set('changed')
118
- expect(@session.first('//textarea[@readonly]').value).to eq('textarea should not change')
98
+ expect { @session.first('//input[@readonly]').set('changed') }.to raise_error(Capybara::ReadOnlyElementError)
119
99
  end
120
100
 
121
101
  it "should raise if the text field is readonly" do
122
- expect(@session.first('//textarea[@readonly]').set('changed')).to raise_error(Capybara::ReadOnlyElementError)
123
- end if Capybara::VERSION.to_f > 3.0
102
+ expect { @session.first('//textarea[@readonly]').set('changed') }.to raise_error(Capybara::ReadOnlyElementError)
103
+ end
124
104
 
125
105
  context "with a contenteditable element", requires: [:js] do
126
106
  it 'should allow me to change the contents' do
127
107
  @session.visit('/with_js')
128
- @session.find(:css,'#existing_content_editable').set('WYSIWYG')
129
- expect(@session.find(:css,'#existing_content_editable').text).to eq('WYSIWYG')
108
+ @session.find(:css, '#existing_content_editable').set('WYSIWYG')
109
+ expect(@session.find(:css, '#existing_content_editable').text).to eq('WYSIWYG')
130
110
  end
131
111
 
132
112
  it 'should allow me to set the contents' do
133
113
  @session.visit('/with_js')
134
- @session.find(:css,'#blank_content_editable').set('WYSIWYG')
135
- expect(@session.find(:css,'#blank_content_editable').text).to eq('WYSIWYG')
114
+ @session.find(:css, '#blank_content_editable').set('WYSIWYG')
115
+ expect(@session.find(:css, '#blank_content_editable').text).to eq('WYSIWYG')
136
116
  end
137
117
 
138
118
  it 'should allow me to change the contents of a child element' do
139
119
  @session.visit('/with_js')
140
- @session.find(:css,'#existing_content_editable_child').set('WYSIWYG')
141
- expect(@session.find(:css,'#existing_content_editable_child').text).to eq('WYSIWYG')
142
- expect(@session.find(:css,'#existing_content_editable_child_parent').text).to eq('Some content WYSIWYG')
120
+ @session.find(:css, '#existing_content_editable_child').set('WYSIWYG')
121
+ expect(@session.find(:css, '#existing_content_editable_child').text).to eq('WYSIWYG')
122
+ expect(@session.find(:css, '#existing_content_editable_child_parent').text).to eq("Some content\nWYSIWYG")
143
123
  end
144
124
  end
145
125
  end
@@ -258,9 +238,9 @@ Capybara::SpecHelper.spec "node" do
258
238
 
259
239
  describe "#==" do
260
240
  it "preserve object identity" do
261
- expect(@session.find('//h1') == @session.find('//h1')).to be true
262
- expect(@session.find('//h1') === @session.find('//h1')).to be true
263
- expect(@session.find('//h1').eql? @session.find('//h1')).to be false
241
+ expect(@session.find('//h1') == @session.find('//h1')).to be true # rubocop:disable Lint/UselessComparison
242
+ expect(@session.find('//h1') === @session.find('//h1')).to be true # rubocop:disable Style/CaseEquality, Lint/UselessComparison
243
+ expect(@session.find('//h1').eql?(@session.find('//h1'))).to be false
264
244
  end
265
245
 
266
246
  it "returns false for unrelated object" do
@@ -281,7 +261,7 @@ Capybara::SpecHelper.spec "node" do
281
261
  end
282
262
  end
283
263
 
284
- describe "#trigger", requires: [:js, :trigger] do
264
+ describe "#trigger", requires: %i[js trigger] do
285
265
  it "should allow triggering of custom JS events" do
286
266
  @session.visit('/with_js')
287
267
  @session.find(:css, '#with_focus_event').trigger(:focus)
@@ -289,7 +269,7 @@ Capybara::SpecHelper.spec "node" do
289
269
  end
290
270
  end
291
271
 
292
- describe '#drag_to', requires: [:js, :drag] do
272
+ describe '#drag_to', requires: %i[js drag] do
293
273
  it "should drag and drop an object" do
294
274
  @session.visit('/with_js')
295
275
  element = @session.find('//div[@id="drag"]')
@@ -297,14 +277,29 @@ Capybara::SpecHelper.spec "node" do
297
277
  element.drag_to(target)
298
278
  expect(@session.find('//div[contains(., "Dropped!")]')).not_to be_nil
299
279
  end
280
+
281
+ it "should drag and drop if scrolling is needed" do
282
+ @session.visit('/with_js')
283
+ element = @session.find('//div[@id="drag_scroll"]')
284
+ target = @session.find('//div[@id="drop_scroll"]')
285
+ element.drag_to(target)
286
+ expect(@session.find('//div[contains(., "Dropped!")]')).not_to be_nil
287
+ end
300
288
  end
301
289
 
302
290
  describe '#hover', requires: [:hover] do
303
291
  it "should allow hovering on an element" do
304
292
  @session.visit('/with_hover')
305
- expect(@session.find(:css,'.hidden_until_hover', visible: false)).not_to be_visible
306
- @session.find(:css,'.wrapper').hover
307
- expect(@session.find(:css, '.hidden_until_hover', visible: false)).to be_visible
293
+ expect(@session.find(:css, '.wrapper:not(.scroll_needed) .hidden_until_hover', visible: false)).not_to be_visible
294
+ @session.find(:css, '.wrapper:not(.scroll_needed)').hover
295
+ expect(@session.find(:css, '.wrapper:not(.scroll_needed) .hidden_until_hover', visible: false)).to be_visible
296
+ end
297
+
298
+ it "should allow hovering on an element that needs to be scrolled into view" do
299
+ @session.visit('/with_hover')
300
+ expect(@session.find(:css, '.wrapper.scroll_needed .hidden_until_hover', visible: false)).not_to be_visible
301
+ @session.find(:css, '.wrapper.scroll_needed').hover
302
+ expect(@session.find(:css, '.wrapper.scroll_needed .hidden_until_hover', visible: false)).to be_visible
308
303
  end
309
304
  end
310
305
 
@@ -343,24 +338,84 @@ Capybara::SpecHelper.spec "node" do
343
338
  radio.click
344
339
  expect(radio).to be_checked
345
340
  end
341
+
342
+ it "should allow modifiers", requires: [:js] do
343
+ @session.visit('/with_js')
344
+ @session.find(:css, '#click-test').click(:shift)
345
+ expect(@session).to have_link('Has been shift clicked')
346
+ end
347
+
348
+ it "should allow multiple modifiers", requires: [:js] do
349
+ @session.visit('with_js')
350
+ @session.find(:css, '#click-test').click(:control, :alt, :meta, :shift)
351
+ # Selenium with Chrome on OSX ctrl-click generates a right click so just verify all keys but not click type
352
+ expect(@session).to have_link("alt control meta shift")
353
+ end
354
+
355
+ it "should allow to adjust the click offset", requires: [:js] do
356
+ @session.visit('with_js')
357
+ @session.find(:css, '#click-test').click(x: 5, y: 5)
358
+ link = @session.find(:link, 'has-been-clicked')
359
+ locations = link.text.match(/^Has been clicked at (?<x>[\d\.-]+),(?<y>[\d\.-]+)$/)
360
+ # Resulting click location should be very close to 0, 0 relative to top left corner of the element, but may not be exact due to
361
+ # integer/float conversions and rounding.
362
+ expect(locations[:x].to_f).to be_within(1).of(5)
363
+ expect(locations[:y].to_f).to be_within(1).of(5)
364
+ end
346
365
  end
347
366
 
348
367
  describe '#double_click', requires: [:js] do
368
+ before do
369
+ pending "selenium-webdriver/geckodriver doesn't generate double click event" if marionette_lt?(59, @session)
370
+ end
371
+
349
372
  it "should double click an element" do
350
- pending "selenium-webdriver/geckodriver doesn't support mouse move_to" if marionette?(@session)
351
373
  @session.visit('/with_js')
352
374
  @session.find(:css, '#click-test').double_click
353
375
  expect(@session.find(:css, '#has-been-double-clicked')).to be
354
376
  end
377
+
378
+ it "should allow modifiers", requires: [:js] do
379
+ @session.visit('/with_js')
380
+ @session.find(:css, '#click-test').double_click(:alt)
381
+ expect(@session).to have_link('Has been alt double clicked')
382
+ end
383
+
384
+ it "should allow to adjust the offset", requires: [:js] do
385
+ @session.visit('with_js')
386
+ @session.find(:css, '#click-test').double_click(x: 10, y: 5)
387
+ link = @session.find(:link, 'has-been-double-clicked')
388
+ locations = link.text.match(/^Has been double clicked at (?<x>[\d\.-]+),(?<y>[\d\.-]+)$/)
389
+ # Resulting click location should be very close to 10, 5 relative to top left corner of the element, but may not be exact due
390
+ # to integer/float conversions and rounding.
391
+ expect(locations[:x].to_f).to be_within(1).of(10)
392
+ expect(locations[:y].to_f).to be_within(1).of(5)
393
+ end
355
394
  end
356
395
 
357
396
  describe '#right_click', requires: [:js] do
358
397
  it "should right click an element" do
359
- pending "selenium-webdriver/geckodriver doesn't support mouse move_to" if marionette?(@session)
360
398
  @session.visit('/with_js')
361
399
  @session.find(:css, '#click-test').right_click
362
400
  expect(@session.find(:css, '#has-been-right-clicked')).to be
363
401
  end
402
+
403
+ it "should allow modifiers", requires: [:js] do
404
+ @session.visit('/with_js')
405
+ @session.find(:css, '#click-test').right_click(:meta)
406
+ expect(@session).to have_link('Has been meta right clicked')
407
+ end
408
+
409
+ it "should allow to adjust the offset", requires: [:js] do
410
+ @session.visit('with_js')
411
+ @session.find(:css, '#click-test').right_click(x: 10, y: 10)
412
+ link = @session.find(:link, 'has-been-right-clicked')
413
+ locations = link.text.match(/^Has been right clicked at (?<x>[\d\.-]+),(?<y>[\d\.-]+)$/)
414
+ # Resulting click location should be very close to 10, 10 relative to top left corner of the element, but may not be exact due
415
+ # to integer/float conversions and rounding
416
+ expect(locations[:x].to_f).to be_within(1).of(10)
417
+ expect(locations[:y].to_f).to be_within(1).of(10)
418
+ end
364
419
  end
365
420
 
366
421
  describe '#send_keys', requires: [:send_keys] do
@@ -384,10 +439,10 @@ Capybara::SpecHelper.spec "node" do
384
439
  expect(@session.find(:css, '#address1_city').value).to eq 'Oceanside'
385
440
  end
386
441
 
387
- it "should generate key events", requires: [:send_keys, :js] do
442
+ it "should generate key events", requires: %i[send_keys js] do
388
443
  pending "selenium-webdriver/geckodriver doesn't support complex sets of characters" if marionette?(@session)
389
444
  @session.visit('/with_js')
390
- @session.find(:css, '#with-key-events').send_keys([:shift,'t'], [:shift,'w'])
445
+ @session.find(:css, '#with-key-events').send_keys([:shift, 't'], [:shift, 'w'])
391
446
  expect(@session.find(:css, '#key-events-output')).to have_text('keydown:16 keydown:84 keydown:16 keydown:87')
392
447
  end
393
448
  end
@@ -420,9 +475,9 @@ Capybara::SpecHelper.spec "node" do
420
475
  sleep(0.3)
421
476
  expect do
422
477
  expect(node).to have_text('has been reloaded')
423
- end.to raise_error do |error|
478
+ end.to(raise_error do |error|
424
479
  expect(error).to be_an_invalid_element_error(@session)
425
- end
480
+ end)
426
481
  end
427
482
  after { Capybara.automatic_reload = true }
428
483
  end
@@ -464,14 +519,10 @@ Capybara::SpecHelper.spec "node" do
464
519
 
465
520
  expect do
466
521
  expect(node).to have_text('Foo')
467
- end.to raise_error { |error|
468
- expect(error).to be_an_invalid_element_error(@session)
469
- }
522
+ end.to(raise_error { |error| expect(error).to be_an_invalid_element_error(@session) })
470
523
  expect do
471
524
  expect(node).to have_text('Bar')
472
- end.to raise_error { |error|
473
- expect(error).to be_an_invalid_element_error(@session)
474
- }
525
+ end.to(raise_error { |error| expect(error).to be_an_invalid_element_error(@session) })
475
526
  end
476
527
 
477
528
  it "should reload nodes with options" do
@@ -485,26 +536,24 @@ Capybara::SpecHelper.spec "node" do
485
536
  end
486
537
 
487
538
  context "when #synchronize raises server errors" do
488
- it "sets an explanatory exception as the cause of server exceptions", requires: [:server, :js] do
489
- skip "This version of ruby doesn't support exception causes" unless Exception.instance_methods.include? :cause
539
+ it "sets an explanatory exception as the cause of server exceptions", requires: %i[server js] do
490
540
  quietly { @session.visit("/error") }
491
541
  expect do
492
542
  @session.find(:css, 'span')
493
- end.to raise_error(TestApp::TestAppError) do |e|
543
+ end.to(raise_error(TestApp::TestAppError) do |e|
494
544
  expect(e.cause).to be_a Capybara::CapybaraError
495
545
  expect(e.cause.message).to match(/Your application server raised an error/)
496
- end
546
+ end)
497
547
  end
498
548
 
499
- it "sets an explanatory exception as the cause of server exceptions with errors with initializers", requires: [:server, :js] do
500
- skip "This version of ruby doesn't support exception causes" unless Exception.instance_methods.include? :cause
549
+ it "sets an explanatory exception as the cause of server exceptions with errors with initializers", requires: %i[server js] do
501
550
  quietly { @session.visit("/other_error") }
502
551
  expect do
503
552
  @session.find(:css, 'span')
504
- end.to raise_error(TestApp::TestAppOtherError) do |e|
553
+ end.to(raise_error(TestApp::TestAppOtherError) do |e|
505
554
  expect(e.cause).to be_a Capybara::CapybaraError
506
555
  expect(e.cause.message).to match(/Your application server raised an error/)
507
- end
556
+ end)
508
557
  end
509
558
  end
510
559