capybara 3.32.2

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 (313) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -0
  3. data/History.md +1813 -0
  4. data/License.txt +22 -0
  5. data/README.md +1099 -0
  6. data/lib/capybara.rb +511 -0
  7. data/lib/capybara/config.rb +94 -0
  8. data/lib/capybara/cucumber.rb +27 -0
  9. data/lib/capybara/driver/base.rb +170 -0
  10. data/lib/capybara/driver/node.rb +139 -0
  11. data/lib/capybara/dsl.rb +65 -0
  12. data/lib/capybara/helpers.rb +108 -0
  13. data/lib/capybara/minitest.rb +386 -0
  14. data/lib/capybara/minitest/spec.rb +264 -0
  15. data/lib/capybara/node/actions.rb +420 -0
  16. data/lib/capybara/node/base.rb +143 -0
  17. data/lib/capybara/node/document.rb +48 -0
  18. data/lib/capybara/node/document_matchers.rb +67 -0
  19. data/lib/capybara/node/element.rb +606 -0
  20. data/lib/capybara/node/finders.rb +325 -0
  21. data/lib/capybara/node/matchers.rb +883 -0
  22. data/lib/capybara/node/simple.rb +208 -0
  23. data/lib/capybara/queries/ancestor_query.rb +27 -0
  24. data/lib/capybara/queries/base_query.rb +106 -0
  25. data/lib/capybara/queries/current_path_query.rb +51 -0
  26. data/lib/capybara/queries/match_query.rb +26 -0
  27. data/lib/capybara/queries/selector_query.rb +710 -0
  28. data/lib/capybara/queries/sibling_query.rb +26 -0
  29. data/lib/capybara/queries/style_query.rb +45 -0
  30. data/lib/capybara/queries/text_query.rb +110 -0
  31. data/lib/capybara/queries/title_query.rb +39 -0
  32. data/lib/capybara/rack_test/browser.rb +140 -0
  33. data/lib/capybara/rack_test/css_handlers.rb +13 -0
  34. data/lib/capybara/rack_test/driver.rb +109 -0
  35. data/lib/capybara/rack_test/errors.rb +6 -0
  36. data/lib/capybara/rack_test/form.rb +127 -0
  37. data/lib/capybara/rack_test/node.rb +325 -0
  38. data/lib/capybara/rails.rb +16 -0
  39. data/lib/capybara/registrations/drivers.rb +36 -0
  40. data/lib/capybara/registrations/patches/puma_ssl.rb +27 -0
  41. data/lib/capybara/registrations/servers.rb +44 -0
  42. data/lib/capybara/result.rb +190 -0
  43. data/lib/capybara/rspec.rb +29 -0
  44. data/lib/capybara/rspec/features.rb +23 -0
  45. data/lib/capybara/rspec/matcher_proxies.rb +82 -0
  46. data/lib/capybara/rspec/matchers.rb +201 -0
  47. data/lib/capybara/rspec/matchers/base.rb +111 -0
  48. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  49. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  50. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  51. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  52. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  53. data/lib/capybara/rspec/matchers/have_selector.rb +77 -0
  54. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  55. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  56. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  57. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  58. data/lib/capybara/rspec/matchers/match_style.rb +38 -0
  59. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  60. data/lib/capybara/selector.rb +233 -0
  61. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  62. data/lib/capybara/selector/builders/xpath_builder.rb +69 -0
  63. data/lib/capybara/selector/css.rb +102 -0
  64. data/lib/capybara/selector/definition.rb +276 -0
  65. data/lib/capybara/selector/definition/button.rb +51 -0
  66. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  67. data/lib/capybara/selector/definition/css.rb +10 -0
  68. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  69. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  70. data/lib/capybara/selector/definition/element.rb +27 -0
  71. data/lib/capybara/selector/definition/field.rb +40 -0
  72. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  73. data/lib/capybara/selector/definition/file_field.rb +13 -0
  74. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  75. data/lib/capybara/selector/definition/frame.rb +17 -0
  76. data/lib/capybara/selector/definition/id.rb +6 -0
  77. data/lib/capybara/selector/definition/label.rb +62 -0
  78. data/lib/capybara/selector/definition/link.rb +46 -0
  79. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  80. data/lib/capybara/selector/definition/option.rb +27 -0
  81. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  82. data/lib/capybara/selector/definition/select.rb +81 -0
  83. data/lib/capybara/selector/definition/table.rb +109 -0
  84. data/lib/capybara/selector/definition/table_row.rb +21 -0
  85. data/lib/capybara/selector/definition/xpath.rb +5 -0
  86. data/lib/capybara/selector/filter.rb +5 -0
  87. data/lib/capybara/selector/filter_set.rb +124 -0
  88. data/lib/capybara/selector/filters/base.rb +77 -0
  89. data/lib/capybara/selector/filters/expression_filter.rb +22 -0
  90. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  91. data/lib/capybara/selector/filters/node_filter.rb +31 -0
  92. data/lib/capybara/selector/regexp_disassembler.rb +214 -0
  93. data/lib/capybara/selector/selector.rb +147 -0
  94. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  95. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  96. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  97. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  98. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  99. data/lib/capybara/selenium/driver.rb +496 -0
  100. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +119 -0
  101. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +126 -0
  102. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +89 -0
  103. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  104. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  105. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  106. data/lib/capybara/selenium/extensions/find.rb +110 -0
  107. data/lib/capybara/selenium/extensions/html5_drag.rb +228 -0
  108. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  109. data/lib/capybara/selenium/extensions/scroll.rb +78 -0
  110. data/lib/capybara/selenium/logger_suppressor.rb +34 -0
  111. data/lib/capybara/selenium/node.rb +610 -0
  112. data/lib/capybara/selenium/nodes/chrome_node.rb +119 -0
  113. data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
  114. data/lib/capybara/selenium/nodes/firefox_node.rb +131 -0
  115. data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
  116. data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
  117. data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
  118. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  119. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  120. data/lib/capybara/selenium/patches/logs.rb +47 -0
  121. data/lib/capybara/selenium/patches/pause_duration_fix.rb +9 -0
  122. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  123. data/lib/capybara/server.rb +126 -0
  124. data/lib/capybara/server/animation_disabler.rb +58 -0
  125. data/lib/capybara/server/checker.rb +44 -0
  126. data/lib/capybara/server/middleware.rb +69 -0
  127. data/lib/capybara/session.rb +942 -0
  128. data/lib/capybara/session/config.rb +124 -0
  129. data/lib/capybara/session/matchers.rb +87 -0
  130. data/lib/capybara/spec/fixtures/another_test_file.txt +1 -0
  131. data/lib/capybara/spec/fixtures/capybara.jpg +3 -0
  132. data/lib/capybara/spec/fixtures/no_extension +1 -0
  133. data/lib/capybara/spec/fixtures/test_file.txt +1 -0
  134. data/lib/capybara/spec/public/jquery-ui.js +13 -0
  135. data/lib/capybara/spec/public/jquery.js +5 -0
  136. data/lib/capybara/spec/public/offset.js +6 -0
  137. data/lib/capybara/spec/public/test.js +268 -0
  138. data/lib/capybara/spec/session/accept_alert_spec.rb +81 -0
  139. data/lib/capybara/spec/session/accept_confirm_spec.rb +32 -0
  140. data/lib/capybara/spec/session/accept_prompt_spec.rb +78 -0
  141. data/lib/capybara/spec/session/all_spec.rb +278 -0
  142. data/lib/capybara/spec/session/ancestor_spec.rb +88 -0
  143. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +140 -0
  144. data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
  145. data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
  146. data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
  147. data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
  148. data/lib/capybara/spec/session/assert_title_spec.rb +93 -0
  149. data/lib/capybara/spec/session/attach_file_spec.rb +216 -0
  150. data/lib/capybara/spec/session/body_spec.rb +23 -0
  151. data/lib/capybara/spec/session/check_spec.rb +235 -0
  152. data/lib/capybara/spec/session/choose_spec.rb +121 -0
  153. data/lib/capybara/spec/session/click_button_spec.rb +506 -0
  154. data/lib/capybara/spec/session/click_link_or_button_spec.rb +129 -0
  155. data/lib/capybara/spec/session/click_link_spec.rb +229 -0
  156. data/lib/capybara/spec/session/current_scope_spec.rb +31 -0
  157. data/lib/capybara/spec/session/current_url_spec.rb +115 -0
  158. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +36 -0
  159. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +21 -0
  160. data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +38 -0
  161. data/lib/capybara/spec/session/element/match_css_spec.rb +31 -0
  162. data/lib/capybara/spec/session/element/match_xpath_spec.rb +25 -0
  163. data/lib/capybara/spec/session/element/matches_selector_spec.rb +120 -0
  164. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
  165. data/lib/capybara/spec/session/evaluate_script_spec.rb +49 -0
  166. data/lib/capybara/spec/session/execute_script_spec.rb +28 -0
  167. data/lib/capybara/spec/session/fill_in_spec.rb +286 -0
  168. data/lib/capybara/spec/session/find_button_spec.rb +74 -0
  169. data/lib/capybara/spec/session/find_by_id_spec.rb +33 -0
  170. data/lib/capybara/spec/session/find_field_spec.rb +113 -0
  171. data/lib/capybara/spec/session/find_link_spec.rb +70 -0
  172. data/lib/capybara/spec/session/find_spec.rb +531 -0
  173. data/lib/capybara/spec/session/first_spec.rb +156 -0
  174. data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
  175. data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
  176. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +116 -0
  177. data/lib/capybara/spec/session/frame/within_frame_spec.rb +112 -0
  178. data/lib/capybara/spec/session/go_back_spec.rb +12 -0
  179. data/lib/capybara/spec/session/go_forward_spec.rb +14 -0
  180. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  181. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  182. data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
  183. data/lib/capybara/spec/session/has_button_spec.rb +69 -0
  184. data/lib/capybara/spec/session/has_css_spec.rb +374 -0
  185. data/lib/capybara/spec/session/has_current_path_spec.rb +138 -0
  186. data/lib/capybara/spec/session/has_field_spec.rb +349 -0
  187. data/lib/capybara/spec/session/has_link_spec.rb +39 -0
  188. data/lib/capybara/spec/session/has_none_selectors_spec.rb +78 -0
  189. data/lib/capybara/spec/session/has_select_spec.rb +310 -0
  190. data/lib/capybara/spec/session/has_selector_spec.rb +202 -0
  191. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  192. data/lib/capybara/spec/session/has_table_spec.rb +198 -0
  193. data/lib/capybara/spec/session/has_text_spec.rb +394 -0
  194. data/lib/capybara/spec/session/has_title_spec.rb +71 -0
  195. data/lib/capybara/spec/session/has_xpath_spec.rb +149 -0
  196. data/lib/capybara/spec/session/headers_spec.rb +8 -0
  197. data/lib/capybara/spec/session/html_spec.rb +47 -0
  198. data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
  199. data/lib/capybara/spec/session/node_spec.rb +1292 -0
  200. data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
  201. data/lib/capybara/spec/session/refresh_spec.rb +33 -0
  202. data/lib/capybara/spec/session/reset_session_spec.rb +148 -0
  203. data/lib/capybara/spec/session/response_code_spec.rb +8 -0
  204. data/lib/capybara/spec/session/save_and_open_page_spec.rb +21 -0
  205. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +43 -0
  206. data/lib/capybara/spec/session/save_page_spec.rb +110 -0
  207. data/lib/capybara/spec/session/save_screenshot_spec.rb +55 -0
  208. data/lib/capybara/spec/session/screenshot_spec.rb +18 -0
  209. data/lib/capybara/spec/session/scroll_spec.rb +117 -0
  210. data/lib/capybara/spec/session/select_spec.rb +229 -0
  211. data/lib/capybara/spec/session/selectors_spec.rb +98 -0
  212. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  213. data/lib/capybara/spec/session/source_spec.rb +0 -0
  214. data/lib/capybara/spec/session/text_spec.rb +74 -0
  215. data/lib/capybara/spec/session/title_spec.rb +29 -0
  216. data/lib/capybara/spec/session/uncheck_spec.rb +100 -0
  217. data/lib/capybara/spec/session/unselect_spec.rb +116 -0
  218. data/lib/capybara/spec/session/visit_spec.rb +204 -0
  219. data/lib/capybara/spec/session/window/become_closed_spec.rb +89 -0
  220. data/lib/capybara/spec/session/window/current_window_spec.rb +28 -0
  221. data/lib/capybara/spec/session/window/open_new_window_spec.rb +31 -0
  222. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +132 -0
  223. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +99 -0
  224. data/lib/capybara/spec/session/window/window_spec.rb +203 -0
  225. data/lib/capybara/spec/session/window/windows_spec.rb +34 -0
  226. data/lib/capybara/spec/session/window/within_window_spec.rb +157 -0
  227. data/lib/capybara/spec/session/within_spec.rb +199 -0
  228. data/lib/capybara/spec/spec_helper.rb +134 -0
  229. data/lib/capybara/spec/test_app.rb +226 -0
  230. data/lib/capybara/spec/views/animated.erb +49 -0
  231. data/lib/capybara/spec/views/buttons.erb +5 -0
  232. data/lib/capybara/spec/views/fieldsets.erb +30 -0
  233. data/lib/capybara/spec/views/form.erb +685 -0
  234. data/lib/capybara/spec/views/frame_child.erb +18 -0
  235. data/lib/capybara/spec/views/frame_one.erb +10 -0
  236. data/lib/capybara/spec/views/frame_parent.erb +9 -0
  237. data/lib/capybara/spec/views/frame_two.erb +9 -0
  238. data/lib/capybara/spec/views/header_links.erb +8 -0
  239. data/lib/capybara/spec/views/host_links.erb +13 -0
  240. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  241. data/lib/capybara/spec/views/obscured.erb +47 -0
  242. data/lib/capybara/spec/views/offset.erb +32 -0
  243. data/lib/capybara/spec/views/path.erb +13 -0
  244. data/lib/capybara/spec/views/popup_one.erb +9 -0
  245. data/lib/capybara/spec/views/popup_two.erb +9 -0
  246. data/lib/capybara/spec/views/postback.erb +14 -0
  247. data/lib/capybara/spec/views/react.erb +45 -0
  248. data/lib/capybara/spec/views/scroll.erb +20 -0
  249. data/lib/capybara/spec/views/spatial.erb +31 -0
  250. data/lib/capybara/spec/views/tables.erb +130 -0
  251. data/lib/capybara/spec/views/with_animation.erb +74 -0
  252. data/lib/capybara/spec/views/with_base_tag.erb +11 -0
  253. data/lib/capybara/spec/views/with_count.erb +8 -0
  254. data/lib/capybara/spec/views/with_dragula.erb +22 -0
  255. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  256. data/lib/capybara/spec/views/with_hover.erb +24 -0
  257. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  258. data/lib/capybara/spec/views/with_html.erb +208 -0
  259. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  260. data/lib/capybara/spec/views/with_html_entities.erb +2 -0
  261. data/lib/capybara/spec/views/with_js.erb +160 -0
  262. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  263. data/lib/capybara/spec/views/with_namespace.erb +20 -0
  264. data/lib/capybara/spec/views/with_scope.erb +42 -0
  265. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  266. data/lib/capybara/spec/views/with_simple_html.erb +2 -0
  267. data/lib/capybara/spec/views/with_slow_unload.erb +17 -0
  268. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  269. data/lib/capybara/spec/views/with_title.erb +5 -0
  270. data/lib/capybara/spec/views/with_unload_alert.erb +14 -0
  271. data/lib/capybara/spec/views/with_windows.erb +54 -0
  272. data/lib/capybara/spec/views/within_frames.erb +15 -0
  273. data/lib/capybara/version.rb +5 -0
  274. data/lib/capybara/window.rb +146 -0
  275. data/spec/basic_node_spec.rb +154 -0
  276. data/spec/capybara_spec.rb +112 -0
  277. data/spec/css_builder_spec.rb +101 -0
  278. data/spec/css_splitter_spec.rb +38 -0
  279. data/spec/dsl_spec.rb +276 -0
  280. data/spec/filter_set_spec.rb +46 -0
  281. data/spec/fixtures/capybara.csv +1 -0
  282. data/spec/fixtures/certificate.pem +25 -0
  283. data/spec/fixtures/key.pem +27 -0
  284. data/spec/fixtures/selenium_driver_rspec_failure.rb +13 -0
  285. data/spec/fixtures/selenium_driver_rspec_success.rb +13 -0
  286. data/spec/minitest_spec.rb +163 -0
  287. data/spec/minitest_spec_spec.rb +162 -0
  288. data/spec/per_session_config_spec.rb +68 -0
  289. data/spec/rack_test_spec.rb +268 -0
  290. data/spec/regexp_dissassembler_spec.rb +250 -0
  291. data/spec/result_spec.rb +196 -0
  292. data/spec/rspec/features_spec.rb +99 -0
  293. data/spec/rspec/scenarios_spec.rb +19 -0
  294. data/spec/rspec/shared_spec_matchers.rb +947 -0
  295. data/spec/rspec/views_spec.rb +14 -0
  296. data/spec/rspec_matchers_spec.rb +62 -0
  297. data/spec/rspec_spec.rb +145 -0
  298. data/spec/sauce_spec_chrome.rb +43 -0
  299. data/spec/selector_spec.rb +513 -0
  300. data/spec/selenium_spec_chrome.rb +188 -0
  301. data/spec/selenium_spec_chrome_remote.rb +96 -0
  302. data/spec/selenium_spec_edge.rb +47 -0
  303. data/spec/selenium_spec_firefox.rb +208 -0
  304. data/spec/selenium_spec_firefox_remote.rb +80 -0
  305. data/spec/selenium_spec_ie.rb +150 -0
  306. data/spec/selenium_spec_safari.rb +148 -0
  307. data/spec/server_spec.rb +292 -0
  308. data/spec/session_spec.rb +91 -0
  309. data/spec/shared_selenium_node.rb +83 -0
  310. data/spec/shared_selenium_session.rb +476 -0
  311. data/spec/spec_helper.rb +100 -0
  312. data/spec/xpath_builder_spec.rb +93 -0
  313. metadata +753 -0
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#dismiss_confirm', requires: [:modals] do
4
+ before do
5
+ @session.visit('/with_js')
6
+ end
7
+
8
+ it 'should dismiss the confirm' do
9
+ @session.dismiss_confirm do
10
+ @session.click_link('Open confirm')
11
+ end
12
+ expect(@session).to have_xpath("//a[@id='open-confirm' and @confirmed='false']")
13
+ end
14
+
15
+ it 'should dismiss the confirm if the message matches' do
16
+ @session.dismiss_confirm 'Confirm opened' do
17
+ @session.click_link('Open confirm')
18
+ end
19
+ expect(@session).to have_xpath("//a[@id='open-confirm' and @confirmed='false']")
20
+ end
21
+
22
+ it "should not dismiss the confirm if the message doesn't match" do
23
+ expect do
24
+ @session.dismiss_confirm 'Incorrect Text' do
25
+ @session.click_link('Open confirm')
26
+ end
27
+ end.to raise_error(Capybara::ModalNotFound)
28
+ end
29
+
30
+ it 'should return the message presented' do
31
+ message = @session.dismiss_confirm do
32
+ @session.click_link('Open confirm')
33
+ end
34
+ expect(message).to eq('Confirm opened')
35
+ end
36
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#dismiss_prompt', requires: [:modals] do
4
+ before do
5
+ @session.visit('/with_js')
6
+ end
7
+
8
+ it 'should dismiss the prompt' do
9
+ @session.dismiss_prompt do
10
+ @session.click_link('Open prompt')
11
+ end
12
+ expect(@session).to have_xpath("//a[@id='open-prompt' and @response='dismissed']")
13
+ end
14
+
15
+ it 'should return the message presented' do
16
+ message = @session.dismiss_prompt do
17
+ @session.click_link('Open prompt')
18
+ end
19
+ expect(message).to eq('Prompt opened')
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#assert_matches_selector' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ @element = @session.find(:css, 'span', text: '42')
7
+ end
8
+
9
+ it 'should be true if the given selector matches the element' do
10
+ expect(@element.assert_matches_selector(:css, '.number')).to be true
11
+ end
12
+
13
+ it 'should be false if the given selector does not match the element' do
14
+ expect { @element.assert_matches_selector(:css, '.not_number') }.to raise_error(Capybara::ElementNotFound)
15
+ end
16
+
17
+ it 'should not be callable on the session' do
18
+ expect { @session.assert_matches_selector(:css, '.number') }.to raise_error(NoMethodError)
19
+ end
20
+
21
+ it 'should wait for match to occur', requires: [:js] do
22
+ @session.visit('/with_js')
23
+ input = @session.find(:css, '#disable-on-click')
24
+
25
+ expect(input.assert_matches_selector(:css, 'input:enabled')).to be true
26
+ input.click
27
+ expect(input.assert_matches_selector(:css, 'input:disabled')).to be true
28
+ end
29
+
30
+ it 'should not accept count options' do
31
+ expect { @element.assert_matches_selector(:css, '.number', count: 1) }.to raise_error(ArgumentError, /count/)
32
+ end
33
+
34
+ it 'should accept a filter block' do
35
+ @element.assert_matches_selector(:css, 'span') { |el| el[:class] == 'number' }
36
+ @element.assert_not_matches_selector(:css, 'span') { |el| el[:class] == 'not_number' }
37
+ end
38
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#match_css?' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ @element = @session.find(:css, 'span', text: '42')
7
+ end
8
+
9
+ it 'should be true if the given selector matches the element' do
10
+ expect(@element).to match_css('span')
11
+ expect(@element).to match_css('span.number')
12
+ end
13
+
14
+ it 'should be false if the given selector does not match' do
15
+ expect(@element).not_to match_css('div')
16
+ expect(@element).not_to match_css('p a#doesnotexist')
17
+ expect(@element).not_to match_css('p.nosuchclass')
18
+ end
19
+
20
+ it 'should accept an optional filter block' do
21
+ # This would be better done with
22
+ expect(@element).to match_css('span') { |el| el[:class] == 'number' }
23
+ expect(@element).not_to match_css('span') { |el| el[:class] == 'not_number' }
24
+ end
25
+
26
+ it 'should work with root element found via ancestor' do
27
+ el = @session.find(:css, 'body').find(:xpath, '..')
28
+ expect(el).to match_css('html')
29
+ expect { expect(el).to not_match_css('html') }.to raise_exception(RSpec::Expectations::ExpectationNotMetError)
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#match_xpath?' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ @element = @session.find(:css, 'span.number')
7
+ end
8
+
9
+ it 'should be true if the given selector is on the page' do
10
+ expect(@element).to match_xpath('//span')
11
+ expect(@element).to match_xpath("//span[@class='number']")
12
+ end
13
+
14
+ it 'should be false if the given selector is not on the page' do
15
+ expect(@element).not_to match_xpath('//abbr')
16
+ expect(@element).not_to match_xpath('//div')
17
+ expect(@element).not_to match_xpath("//span[@class='not_a_number']")
18
+ end
19
+
20
+ it 'should use xpath even if default selector is CSS' do
21
+ Capybara.default_selector = :css
22
+ expect(@element).not_to have_xpath("//span[@class='not_a_number']")
23
+ expect(@element).not_to have_xpath("//div[@class='number']")
24
+ end
25
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#match_selector?' do
4
+ let(:element) { @session.find(:xpath, '//span', text: '42') }
5
+
6
+ before do
7
+ @session.visit('/with_html')
8
+ end
9
+
10
+ it 'should be true if the element matches the given selector' do
11
+ expect(element).to match_selector(:xpath, '//span')
12
+ expect(element).to match_selector(:css, 'span.number')
13
+ expect(element.matches_selector?(:css, 'span.number')).to be true
14
+ end
15
+
16
+ it 'should be false if the element does not match the given selector' do
17
+ expect(element).not_to match_selector(:xpath, '//div')
18
+ expect(element).not_to match_selector(:css, 'span.not_a_number')
19
+ expect(element.matches_selector?(:css, 'span.not_a_number')).to be false
20
+ end
21
+
22
+ it 'should use default selector' do
23
+ Capybara.default_selector = :css
24
+ expect(element).not_to match_selector('span.not_a_number')
25
+ expect(element).to match_selector('span.number')
26
+ end
27
+
28
+ it 'should work with elements located via a sibling selector' do
29
+ sibling = element.sibling(:css, 'span', text: 'Other span')
30
+ expect(sibling).to match_selector(:xpath, '//span')
31
+ expect(sibling).to match_selector(:css, 'span')
32
+ end
33
+
34
+ it 'should work with the html element' do
35
+ html = @session.find('/html')
36
+ expect(html).to match_selector(:css, 'html')
37
+ end
38
+
39
+ context 'with text' do
40
+ it 'should discard all matches where the given string is not contained' do
41
+ expect(element).to match_selector('//span', text: '42')
42
+ expect(element).not_to match_selector('//span', text: 'Doesnotexist')
43
+ end
44
+ end
45
+
46
+ it 'should have css sugar' do
47
+ expect(element.matches_css?('span.number')).to be true
48
+ expect(element.matches_css?('span.not_a_number')).to be false
49
+ expect(element.matches_css?('span.number', text: '42')).to be true
50
+ expect(element.matches_css?('span.number', text: 'Nope')).to be false
51
+ end
52
+
53
+ it 'should have xpath sugar' do
54
+ expect(element.matches_xpath?('//span')).to be true
55
+ expect(element.matches_xpath?('//div')).to be false
56
+ expect(element.matches_xpath?('//span', text: '42')).to be true
57
+ expect(element.matches_xpath?('//span', text: 'Nope')).to be false
58
+ end
59
+
60
+ it 'should accept selector filters' do
61
+ @session.visit('/form')
62
+ cbox = @session.find(:css, '#form_pets_dog')
63
+ expect(cbox.matches_selector?(:checkbox, id: 'form_pets_dog', option: 'dog', name: 'form[pets][]', checked: true)).to be true
64
+ end
65
+
66
+ it 'should accept a custom filter block' do
67
+ @session.visit('/form')
68
+ cbox = @session.find(:css, '#form_pets_dog')
69
+ expect(cbox).to match_selector(:checkbox) { |node| node[:id] == 'form_pets_dog' }
70
+ expect(cbox).not_to match_selector(:checkbox) { |node| node[:id] != 'form_pets_dog' }
71
+ expect(cbox.matches_selector?(:checkbox) { |node| node[:id] == 'form_pets_dog' }).to be true
72
+ expect(cbox.matches_selector?(:checkbox) { |node| node[:id] != 'form_pets_dog' }).to be false
73
+ end
74
+ end
75
+
76
+ Capybara::SpecHelper.spec '#not_matches_selector?' do
77
+ let(:element) { @session.find(:css, 'span', text: 42) }
78
+ before do
79
+ @session.visit('/with_html')
80
+ end
81
+
82
+ it 'should be false if the given selector matches the element' do
83
+ expect(element).not_to not_match_selector(:xpath, '//span')
84
+ expect(element).not_to not_match_selector(:css, 'span.number')
85
+ expect(element.not_matches_selector?(:css, 'span.number')).to be false
86
+ end
87
+
88
+ it 'should be true if the given selector does not match the element' do
89
+ expect(element).to not_match_selector(:xpath, '//abbr')
90
+ expect(element).to not_match_selector(:css, 'p a#doesnotexist')
91
+ expect(element.not_matches_selector?(:css, 'p a#doesnotexist')).to be true
92
+ end
93
+
94
+ it 'should use default selector' do
95
+ Capybara.default_selector = :css
96
+ expect(element).to not_match_selector('p a#doesnotexist')
97
+ expect(element).not_to not_match_selector('span.number')
98
+ end
99
+
100
+ context 'with text' do
101
+ it 'should discard all matches where the given string is contained' do
102
+ expect(element).not_to not_match_selector(:css, 'span.number', text: '42')
103
+ expect(element).to not_match_selector(:css, 'span.number', text: 'Doesnotexist')
104
+ end
105
+ end
106
+
107
+ it 'should have CSS sugar' do
108
+ expect(element.not_matches_css?('span.number')).to be false
109
+ expect(element.not_matches_css?('p a#doesnotexist')).to be true
110
+ expect(element.not_matches_css?('span.number', text: '42')).to be false
111
+ expect(element.not_matches_css?('span.number', text: 'Doesnotexist')).to be true
112
+ end
113
+
114
+ it 'should have xpath sugar' do
115
+ expect(element.not_matches_xpath?('//span')).to be false
116
+ expect(element.not_matches_xpath?('//div')).to be true
117
+ expect(element.not_matches_xpath?('//span', text: '42')).to be false
118
+ expect(element.not_matches_xpath?('//span', text: 'Doesnotexist')).to be true
119
+ end
120
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#evaluate_async_script', requires: [:js] do
4
+ it 'should evaluate the given script and return whatever it produces' do
5
+ @session.visit('/with_js')
6
+ expect(@session.evaluate_async_script('arguments[0](4)')).to eq(4)
7
+ end
8
+
9
+ it 'should support passing elements as arguments to the script', requires: %i[js es_args] do
10
+ @session.visit('/with_js')
11
+ el = @session.find(:css, '#drag p')
12
+ result = @session.evaluate_async_script('arguments[2]([arguments[0].innerText, arguments[1]])', el, 'Doodle Funk')
13
+ expect(result).to eq ['This is a draggable element.', 'Doodle Funk']
14
+ end
15
+
16
+ it 'should support returning elements after asynchronous operation', requires: %i[js es_args] do
17
+ @session.visit('/with_js')
18
+ @session.find(:css, '#change') # ensure page has loaded and element is available
19
+ el = @session.evaluate_async_script("var cb = arguments[0]; setTimeout(function(){ cb(document.getElementById('change')) }, 100)")
20
+ expect(el).to be_instance_of(Capybara::Node::Element)
21
+ expect(el).to eq(@session.find(:css, '#change'))
22
+ end
23
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#evaluate_script', requires: [:js] do
4
+ it 'should evaluate the given script and return whatever it produces' do
5
+ @session.visit('/with_js')
6
+ expect(@session.evaluate_script('1+3')).to eq(4)
7
+ end
8
+
9
+ it 'should ignore leading whitespace' do
10
+ @session.visit('/with_js')
11
+ expect(@session.evaluate_script('
12
+ 1 + 3
13
+ ')).to eq(4)
14
+ end
15
+
16
+ it 'should pass arguments to the script', requires: %i[js es_args] do
17
+ @session.visit('/with_js')
18
+ expect(@session).to have_css('#change')
19
+ @session.evaluate_script("document.getElementById('change').textContent = arguments[0]", 'Doodle Funk')
20
+ expect(@session).to have_css('#change', text: 'Doodle Funk')
21
+ end
22
+
23
+ it 'should support passing elements as arguments to the script', requires: %i[js es_args] do
24
+ @session.visit('/with_js')
25
+ el = @session.find(:css, '#change')
26
+ @session.evaluate_script('arguments[0].textContent = arguments[1]', el, 'Doodle Funk')
27
+ expect(@session).to have_css('#change', text: 'Doodle Funk')
28
+ end
29
+
30
+ it 'should support returning elements', requires: %i[js es_args] do
31
+ @session.visit('/with_js')
32
+ @session.find(:css, '#change') # ensure page has loaded and element is available
33
+ el = @session.evaluate_script("document.getElementById('change')")
34
+ expect(el).to be_instance_of(Capybara::Node::Element)
35
+ expect(el).to eq(@session.find(:css, '#change'))
36
+ end
37
+
38
+ it 'should support multi statement via IIFE' do
39
+ @session.visit('/with_js')
40
+ @session.find(:css, '#change')
41
+ el = @session.evaluate_script(<<~JS)
42
+ (function(){
43
+ var el = document.getElementById('change');
44
+ return el;
45
+ })()
46
+ JS
47
+ expect(el).to eq(@session.find(:css, '#change'))
48
+ end
49
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#execute_script', requires: [:js] do
4
+ it 'should execute the given script and return nothing' do
5
+ @session.visit('/with_js')
6
+ expect(@session.execute_script("document.getElementById('change').textContent = 'Funky Doodle'")).to be_nil
7
+ expect(@session).to have_css('#change', text: 'Funky Doodle')
8
+ end
9
+
10
+ it 'should be able to call functions defined in the page' do
11
+ @session.visit('/with_js')
12
+ expect { @session.execute_script("$('#change').text('Funky Doodle')") }.not_to raise_error
13
+ end
14
+
15
+ it 'should pass arguments to the script', requires: %i[js es_args] do
16
+ @session.visit('/with_js')
17
+ expect(@session).to have_css('#change')
18
+ @session.execute_script("document.getElementById('change').textContent = arguments[0]", 'Doodle Funk')
19
+ expect(@session).to have_css('#change', text: 'Doodle Funk')
20
+ end
21
+
22
+ it 'should support passing elements as arguments to the script', requires: %i[js es_args] do
23
+ @session.visit('/with_js')
24
+ el = @session.find(:css, '#change')
25
+ @session.execute_script('arguments[1].textContent = arguments[0]', 'Doodle Funk', el)
26
+ expect(@session).to have_css('#change', text: 'Doodle Funk')
27
+ end
28
+ end
@@ -0,0 +1,286 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#fill_in' do
4
+ before do
5
+ @session.visit('/form')
6
+ end
7
+
8
+ it 'should fill in a text field by id' do
9
+ @session.fill_in('form_first_name', with: 'Harry')
10
+ @session.click_button('awesome')
11
+ expect(extract_results(@session)['first_name']).to eq('Harry')
12
+ end
13
+
14
+ it 'should fill in a text field by name' do
15
+ @session.fill_in('form[last_name]', with: 'Green')
16
+ @session.click_button('awesome')
17
+ expect(extract_results(@session)['last_name']).to eq('Green')
18
+ end
19
+
20
+ it 'should fill in a text field by label without for' do
21
+ @session.fill_in('First Name', with: 'Harry')
22
+ @session.click_button('awesome')
23
+ expect(extract_results(@session)['first_name']).to eq('Harry')
24
+ end
25
+
26
+ it 'should fill in a url field by label without for' do
27
+ @session.fill_in('Html5 Url', with: 'http://www.avenueq.com')
28
+ @session.click_button('html5_submit')
29
+ expect(extract_results(@session)['html5_url']).to eq('http://www.avenueq.com')
30
+ end
31
+
32
+ it 'should fill in a textarea by id' do
33
+ @session.fill_in('form_description', with: 'Texty text')
34
+ @session.click_button('awesome')
35
+ expect(extract_results(@session)['description']).to eq('Texty text')
36
+ end
37
+
38
+ it 'should fill in a textarea by label' do
39
+ @session.fill_in('Description', with: 'Texty text')
40
+ @session.click_button('awesome')
41
+ expect(extract_results(@session)['description']).to eq('Texty text')
42
+ end
43
+
44
+ it 'should fill in a textarea by name' do
45
+ @session.fill_in('form[description]', with: 'Texty text')
46
+ @session.click_button('awesome')
47
+ expect(extract_results(@session)['description']).to eq('Texty text')
48
+ end
49
+
50
+ it 'should fill in a textarea in a reasonable time by default' do
51
+ textarea = @session.find(:fillable_field, 'form[description]')
52
+ value = 'a' * 4000
53
+ start = Time.now
54
+ textarea.fill_in(with: value)
55
+ expect(Time.now.to_f).to be_within(0.25).of start.to_f
56
+ expect(textarea.value).to eq value
57
+ end
58
+
59
+ it 'should fill in a password field by id' do
60
+ @session.fill_in('form_password', with: 'supasikrit')
61
+ @session.click_button('awesome')
62
+ expect(extract_results(@session)['password']).to eq('supasikrit')
63
+ end
64
+
65
+ context 'Date/Time' do
66
+ it 'should fill in a date input' do
67
+ date = Date.today
68
+ @session.fill_in('form_date', with: date)
69
+ @session.click_button('awesome')
70
+ expect(Date.parse(extract_results(@session)['date'])).to eq date
71
+ end
72
+
73
+ it 'should fill in a time input' do
74
+ time = Time.new(2018, 3, 9, 15, 26)
75
+ @session.fill_in('form_time', with: time)
76
+ @session.click_button('awesome')
77
+ results = extract_results(@session)['time']
78
+ expect(Time.parse(results).strftime('%r')).to eq time.strftime('%r')
79
+ end
80
+
81
+ it 'should fill in a datetime input' do
82
+ dt = Time.new(2018, 3, 13, 9, 53)
83
+ @session.fill_in('form_datetime', with: dt)
84
+ @session.click_button('awesome')
85
+ expect(Time.parse(extract_results(@session)['datetime'])).to eq dt
86
+ end
87
+ end
88
+
89
+ it 'should handle HTML in a textarea' do
90
+ @session.fill_in('form_description', with: 'is <strong>very</strong> secret!')
91
+ @session.click_button('awesome')
92
+ expect(extract_results(@session)['description']).to eq('is <strong>very</strong> secret!')
93
+ end
94
+
95
+ it 'should handle newlines in a textarea' do
96
+ @session.fill_in('form_description', with: "\nSome text\n")
97
+ @session.click_button('awesome')
98
+ expect(extract_results(@session)['description']).to eq("\r\nSome text\r\n")
99
+ end
100
+
101
+ it 'should fill in a color field' do
102
+ @session.fill_in('Html5 Color', with: '#112233')
103
+ @session.click_button('html5_submit')
104
+ expect(extract_results(@session)['html5_color']).to eq('#112233')
105
+ end
106
+
107
+ describe 'with input[type="range"]' do
108
+ it 'should set the range slider correctly' do
109
+ @session.fill_in('form_age', with: 51)
110
+ @session.click_button('awesome')
111
+ expect(extract_results(@session)['age'].to_f).to eq 51
112
+ end
113
+
114
+ it 'should set the range slider to valid values' do
115
+ @session.fill_in('form_age', with: '37.6')
116
+ @session.click_button('awesome')
117
+ expect(extract_results(@session)['age'].to_f).to eq 37.5
118
+ end
119
+
120
+ it 'should respect the range slider limits' do
121
+ @session.fill_in('form_age', with: '3')
122
+ @session.click_button('awesome')
123
+ expect(extract_results(@session)['age'].to_f).to eq 13
124
+ end
125
+ end
126
+
127
+ it 'should fill in a field with a custom type' do
128
+ @session.fill_in('Schmooo', with: 'Schmooo is the game')
129
+ @session.click_button('awesome')
130
+ expect(extract_results(@session)['schmooo']).to eq('Schmooo is the game')
131
+ end
132
+
133
+ it 'should fill in a field without a type' do
134
+ @session.fill_in('Phone', with: '+1 555 7022')
135
+ @session.click_button('awesome')
136
+ expect(extract_results(@session)['phone']).to eq('+1 555 7022')
137
+ end
138
+
139
+ it 'should fill in a text field respecting its maxlength attribute' do
140
+ @session.fill_in('Zipcode', with: '52071350')
141
+ @session.click_button('awesome')
142
+ expect(extract_results(@session)['zipcode']).to eq('52071')
143
+ end
144
+
145
+ it 'should fill in a password field by name' do
146
+ @session.fill_in('form[password]', with: 'supasikrit')
147
+ @session.click_button('awesome')
148
+ expect(extract_results(@session)['password']).to eq('supasikrit')
149
+ end
150
+
151
+ it 'should fill in a password field by label' do
152
+ @session.fill_in('Password', with: 'supasikrit')
153
+ @session.click_button('awesome')
154
+ expect(extract_results(@session)['password']).to eq('supasikrit')
155
+ end
156
+
157
+ it 'should fill in a password field by name' do
158
+ @session.fill_in('form[password]', with: 'supasikrit')
159
+ @session.click_button('awesome')
160
+ expect(extract_results(@session)['password']).to eq('supasikrit')
161
+ end
162
+
163
+ it 'should fill in a field based on current value' do
164
+ @session.fill_in(id: /form.*name/, currently_with: 'John', with: 'Thomas')
165
+ @session.click_button('awesome')
166
+ expect(extract_results(@session)['first_name']).to eq('Thomas')
167
+ end
168
+
169
+ it 'should fill in a field based on type' do
170
+ @session.fill_in(type: 'schmooo', with: 'Schmooo for all')
171
+ @session.click_button('awesome')
172
+ expect(extract_results(@session)['schmooo']).to eq('Schmooo for all')
173
+ end
174
+
175
+ it 'should be able to fill in element called on when no locator passed' do
176
+ field = @session.find(:fillable_field, 'form[password]')
177
+ field.fill_in(with: 'supasikrit')
178
+ @session.click_button('awesome')
179
+ expect(extract_results(@session)['password']).to eq('supasikrit')
180
+ end
181
+
182
+ it "should throw an exception if a hash containing 'with' is not provided" do
183
+ expect { @session.fill_in 'Name' }.to raise_error(ArgumentError, /with/)
184
+ end
185
+
186
+ it 'should wait for asynchronous load', requires: [:js] do
187
+ Capybara.default_max_wait_time = 2
188
+ @session.visit('/with_js')
189
+ @session.click_link('Click me')
190
+ @session.fill_in('new_field', with: 'Testing...')
191
+ end
192
+
193
+ it 'casts to string' do
194
+ @session.fill_in(:form_first_name, with: :Harry)
195
+ @session.click_button('awesome')
196
+ expect(extract_results(@session)['first_name']).to eq('Harry')
197
+ end
198
+
199
+ it 'casts to string if field has maxlength' do
200
+ @session.fill_in(:form_zipcode, with: 1234567)
201
+ @session.click_button('awesome')
202
+ expect(extract_results(@session)['zipcode']).to eq('12345')
203
+ end
204
+
205
+ it 'fills in a field if default_set_options is nil' do
206
+ Capybara.default_set_options = nil
207
+ @session.fill_in(:form_first_name, with: 'Thomas')
208
+ @session.click_button('awesome')
209
+ expect(extract_results(@session)['first_name']).to eq('Thomas')
210
+ end
211
+
212
+ context 'on a pre-populated textfield with a reformatting onchange', requires: [:js] do
213
+ it 'should only trigger onchange once' do
214
+ @session.visit('/with_js')
215
+ # Click somewhere on the page to ensure focus is acquired. Without this FF won't generate change events for some reason???
216
+ @session.find(:css, 'h1', text: 'FooBar').click
217
+ @session.fill_in('with_change_event', with: 'some value')
218
+ # click outside the field to trigger the change event
219
+ @session.find(:css, 'h1', text: 'FooBar').click
220
+ expect(@session.find(:css, '.change_event_triggered', match: :one)).to have_text 'some value'
221
+ end
222
+
223
+ it 'should trigger change when clearing field' do
224
+ @session.visit('/with_js')
225
+ @session.fill_in('with_change_event', with: '')
226
+ # click outside the field to trigger the change event
227
+ @session.find(:css, 'h1', text: 'FooBar').click
228
+ expect(@session).to have_selector(:css, '.change_event_triggered', match: :one)
229
+ end
230
+ end
231
+
232
+ context 'with ignore_hidden_fields' do
233
+ before { Capybara.ignore_hidden_elements = true }
234
+
235
+ after { Capybara.ignore_hidden_elements = false }
236
+
237
+ it 'should not find a hidden field' do
238
+ msg = /Unable to find visible field "Super Secret"/
239
+ expect do
240
+ @session.fill_in('Super Secret', with: '777')
241
+ end.to raise_error(Capybara::ElementNotFound, msg)
242
+ end
243
+ end
244
+
245
+ context "with a locator that doesn't exist" do
246
+ it 'should raise an error' do
247
+ msg = /Unable to find field "does not exist"/
248
+ expect do
249
+ @session.fill_in('does not exist', with: 'Blah blah')
250
+ end.to raise_error(Capybara::ElementNotFound, msg)
251
+ end
252
+ end
253
+
254
+ context 'on a disabled field' do
255
+ it 'should raise an error' do
256
+ expect do
257
+ @session.fill_in('Disabled Text Field', with: 'Blah blah')
258
+ end.to raise_error(Capybara::ElementNotFound)
259
+ end
260
+ end
261
+
262
+ context 'with :exact option' do
263
+ it 'should accept partial matches when false' do
264
+ @session.fill_in('Explanation', with: 'Dude', exact: false)
265
+ @session.click_button('awesome')
266
+ expect(extract_results(@session)['name_explanation']).to eq('Dude')
267
+ end
268
+
269
+ it 'should not accept partial matches when true' do
270
+ expect do
271
+ @session.fill_in('Explanation', with: 'Dude', exact: true)
272
+ end.to raise_error(Capybara::ElementNotFound)
273
+ end
274
+ end
275
+
276
+ it 'should return the element filled in' do
277
+ el = @session.find(:fillable_field, 'form_first_name')
278
+ expect(@session.fill_in('form_first_name', with: 'Harry')).to eq el
279
+ end
280
+
281
+ it 'should warn if passed what looks like a CSS id selector' do
282
+ expect do
283
+ @session.fill_in('#form_first_name', with: 'Harry')
284
+ end.to raise_error(/you may be passing a CSS selector or XPath expression rather than a locator/)
285
+ end
286
+ end