capybara 2.7.0 → 3.35.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (318) hide show
  1. checksums.yaml +5 -5
  2. data/.yardopts +1 -0
  3. data/History.md +1147 -11
  4. data/License.txt +1 -1
  5. data/README.md +252 -131
  6. data/lib/capybara/config.rb +92 -0
  7. data/lib/capybara/cucumber.rb +3 -3
  8. data/lib/capybara/driver/base.rb +52 -21
  9. data/lib/capybara/driver/node.rb +48 -14
  10. data/lib/capybara/dsl.rb +16 -9
  11. data/lib/capybara/helpers.rb +72 -81
  12. data/lib/capybara/minitest/spec.rb +267 -0
  13. data/lib/capybara/minitest.rb +385 -0
  14. data/lib/capybara/node/actions.rb +337 -89
  15. data/lib/capybara/node/base.rb +50 -32
  16. data/lib/capybara/node/document.rb +19 -3
  17. data/lib/capybara/node/document_matchers.rb +22 -24
  18. data/lib/capybara/node/element.rb +388 -125
  19. data/lib/capybara/node/finders.rb +231 -121
  20. data/lib/capybara/node/matchers.rb +503 -217
  21. data/lib/capybara/node/simple.rb +64 -27
  22. data/lib/capybara/queries/ancestor_query.rb +27 -0
  23. data/lib/capybara/queries/base_query.rb +87 -11
  24. data/lib/capybara/queries/current_path_query.rb +24 -24
  25. data/lib/capybara/queries/match_query.rb +15 -10
  26. data/lib/capybara/queries/selector_query.rb +675 -81
  27. data/lib/capybara/queries/sibling_query.rb +26 -0
  28. data/lib/capybara/queries/style_query.rb +45 -0
  29. data/lib/capybara/queries/text_query.rb +88 -20
  30. data/lib/capybara/queries/title_query.rb +9 -11
  31. data/lib/capybara/rack_test/browser.rb +63 -39
  32. data/lib/capybara/rack_test/css_handlers.rb +6 -4
  33. data/lib/capybara/rack_test/driver.rb +26 -16
  34. data/lib/capybara/rack_test/errors.rb +6 -0
  35. data/lib/capybara/rack_test/form.rb +73 -58
  36. data/lib/capybara/rack_test/node.rb +187 -67
  37. data/lib/capybara/rails.rb +4 -8
  38. data/lib/capybara/registration_container.rb +44 -0
  39. data/lib/capybara/registrations/drivers.rb +42 -0
  40. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  41. data/lib/capybara/registrations/servers.rb +45 -0
  42. data/lib/capybara/result.rb +142 -14
  43. data/lib/capybara/rspec/features.rb +17 -42
  44. data/lib/capybara/rspec/matcher_proxies.rb +82 -0
  45. data/lib/capybara/rspec/matchers/base.rb +111 -0
  46. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  47. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  48. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  49. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  50. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  51. data/lib/capybara/rspec/matchers/have_selector.rb +77 -0
  52. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  53. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  54. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  55. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  56. data/lib/capybara/rspec/matchers/match_style.rb +43 -0
  57. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  58. data/lib/capybara/rspec/matchers.rb +143 -244
  59. data/lib/capybara/rspec.rb +10 -12
  60. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  61. data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
  62. data/lib/capybara/selector/css.rb +102 -0
  63. data/lib/capybara/selector/definition/button.rb +63 -0
  64. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  65. data/lib/capybara/selector/definition/css.rb +10 -0
  66. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  67. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  68. data/lib/capybara/selector/definition/element.rb +28 -0
  69. data/lib/capybara/selector/definition/field.rb +40 -0
  70. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  71. data/lib/capybara/selector/definition/file_field.rb +13 -0
  72. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  73. data/lib/capybara/selector/definition/frame.rb +17 -0
  74. data/lib/capybara/selector/definition/id.rb +6 -0
  75. data/lib/capybara/selector/definition/label.rb +62 -0
  76. data/lib/capybara/selector/definition/link.rb +54 -0
  77. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  78. data/lib/capybara/selector/definition/option.rb +27 -0
  79. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  80. data/lib/capybara/selector/definition/select.rb +81 -0
  81. data/lib/capybara/selector/definition/table.rb +109 -0
  82. data/lib/capybara/selector/definition/table_row.rb +21 -0
  83. data/lib/capybara/selector/definition/xpath.rb +5 -0
  84. data/lib/capybara/selector/definition.rb +278 -0
  85. data/lib/capybara/selector/filter.rb +3 -46
  86. data/lib/capybara/selector/filter_set.rb +124 -0
  87. data/lib/capybara/selector/filters/base.rb +77 -0
  88. data/lib/capybara/selector/filters/expression_filter.rb +22 -0
  89. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  90. data/lib/capybara/selector/filters/node_filter.rb +31 -0
  91. data/lib/capybara/selector/regexp_disassembler.rb +214 -0
  92. data/lib/capybara/selector/selector.rb +155 -0
  93. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  94. data/lib/capybara/selector.rb +232 -369
  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 +380 -142
  100. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
  101. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -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 +76 -0
  110. data/lib/capybara/selenium/logger_suppressor.rb +40 -0
  111. data/lib/capybara/selenium/node.rb +528 -97
  112. data/lib/capybara/selenium/nodes/chrome_node.rb +137 -0
  113. data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
  114. data/lib/capybara/selenium/nodes/firefox_node.rb +136 -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 +45 -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/animation_disabler.rb +63 -0
  124. data/lib/capybara/server/checker.rb +44 -0
  125. data/lib/capybara/server/middleware.rb +71 -0
  126. data/lib/capybara/server.rb +74 -71
  127. data/lib/capybara/session/config.rb +126 -0
  128. data/lib/capybara/session/matchers.rb +44 -27
  129. data/lib/capybara/session.rb +500 -297
  130. data/lib/capybara/spec/fixtures/no_extension +1 -0
  131. data/lib/capybara/spec/public/jquery.js +5 -5
  132. data/lib/capybara/spec/public/offset.js +6 -0
  133. data/lib/capybara/spec/public/test.js +168 -14
  134. data/lib/capybara/spec/session/accept_alert_spec.rb +37 -14
  135. data/lib/capybara/spec/session/accept_confirm_spec.rb +7 -6
  136. data/lib/capybara/spec/session/accept_prompt_spec.rb +38 -10
  137. data/lib/capybara/spec/session/all_spec.rb +179 -59
  138. data/lib/capybara/spec/session/ancestor_spec.rb +88 -0
  139. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +140 -0
  140. data/lib/capybara/spec/session/assert_current_path_spec.rb +75 -0
  141. data/lib/capybara/spec/session/assert_selector_spec.rb +143 -0
  142. data/lib/capybara/spec/session/assert_style_spec.rb +26 -0
  143. data/lib/capybara/spec/session/assert_text_spec.rb +258 -0
  144. data/lib/capybara/spec/session/assert_title_spec.rb +93 -0
  145. data/lib/capybara/spec/session/attach_file_spec.rb +154 -48
  146. data/lib/capybara/spec/session/body_spec.rb +12 -13
  147. data/lib/capybara/spec/session/check_spec.rb +168 -41
  148. data/lib/capybara/spec/session/choose_spec.rb +75 -23
  149. data/lib/capybara/spec/session/click_button_spec.rb +243 -175
  150. data/lib/capybara/spec/session/click_link_or_button_spec.rb +57 -32
  151. data/lib/capybara/spec/session/click_link_spec.rb +100 -53
  152. data/lib/capybara/spec/session/current_scope_spec.rb +11 -10
  153. data/lib/capybara/spec/session/current_url_spec.rb +61 -35
  154. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +7 -7
  155. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +5 -4
  156. data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +13 -6
  157. data/lib/capybara/spec/session/element/match_css_spec.rb +21 -7
  158. data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
  159. data/lib/capybara/spec/session/element/matches_selector_spec.rb +91 -34
  160. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
  161. data/lib/capybara/spec/session/evaluate_script_spec.rb +45 -3
  162. data/lib/capybara/spec/session/execute_script_spec.rb +24 -4
  163. data/lib/capybara/spec/session/fill_in_spec.rb +166 -64
  164. data/lib/capybara/spec/session/find_button_spec.rb +37 -18
  165. data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
  166. data/lib/capybara/spec/session/find_field_spec.rb +57 -34
  167. data/lib/capybara/spec/session/find_link_spec.rb +47 -10
  168. data/lib/capybara/spec/session/find_spec.rb +290 -144
  169. data/lib/capybara/spec/session/first_spec.rb +91 -48
  170. data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
  171. data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
  172. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +116 -0
  173. data/lib/capybara/spec/session/frame/within_frame_spec.rb +112 -0
  174. data/lib/capybara/spec/session/go_back_spec.rb +3 -2
  175. data/lib/capybara/spec/session/go_forward_spec.rb +3 -2
  176. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  177. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  178. data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
  179. data/lib/capybara/spec/session/has_button_spec.rb +76 -19
  180. data/lib/capybara/spec/session/has_css_spec.rb +277 -131
  181. data/lib/capybara/spec/session/has_current_path_spec.rb +98 -26
  182. data/lib/capybara/spec/session/has_field_spec.rb +177 -107
  183. data/lib/capybara/spec/session/has_link_spec.rb +13 -12
  184. data/lib/capybara/spec/session/has_none_selectors_spec.rb +78 -0
  185. data/lib/capybara/spec/session/has_select_spec.rb +191 -95
  186. data/lib/capybara/spec/session/has_selector_spec.rb +128 -64
  187. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  188. data/lib/capybara/spec/session/has_table_spec.rb +172 -5
  189. data/lib/capybara/spec/session/has_text_spec.rb +126 -60
  190. data/lib/capybara/spec/session/has_title_spec.rb +35 -12
  191. data/lib/capybara/spec/session/has_xpath_spec.rb +74 -53
  192. data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
  193. data/lib/capybara/spec/session/html_spec.rb +14 -6
  194. data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
  195. data/lib/capybara/spec/session/node_spec.rb +1028 -131
  196. data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
  197. data/lib/capybara/spec/session/refresh_spec.rb +34 -0
  198. data/lib/capybara/spec/session/reset_session_spec.rb +75 -34
  199. data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
  200. data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
  201. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +11 -15
  202. data/lib/capybara/spec/session/save_page_spec.rb +42 -55
  203. data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
  204. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  205. data/lib/capybara/spec/session/scroll_spec.rb +117 -0
  206. data/lib/capybara/spec/session/select_spec.rb +112 -85
  207. data/lib/capybara/spec/session/selectors_spec.rb +71 -8
  208. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  209. data/lib/capybara/spec/session/text_spec.rb +38 -23
  210. data/lib/capybara/spec/session/title_spec.rb +17 -5
  211. data/lib/capybara/spec/session/uncheck_spec.rb +71 -12
  212. data/lib/capybara/spec/session/unselect_spec.rb +44 -43
  213. data/lib/capybara/spec/session/visit_spec.rb +99 -32
  214. data/lib/capybara/spec/session/window/become_closed_spec.rb +33 -29
  215. data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
  216. data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
  217. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +39 -30
  218. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +17 -10
  219. data/lib/capybara/spec/session/window/window_spec.rb +121 -73
  220. data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
  221. data/lib/capybara/spec/session/window/within_window_spec.rb +52 -82
  222. data/lib/capybara/spec/session/within_spec.rb +76 -43
  223. data/lib/capybara/spec/spec_helper.rb +67 -33
  224. data/lib/capybara/spec/test_app.rb +85 -36
  225. data/lib/capybara/spec/views/animated.erb +49 -0
  226. data/lib/capybara/spec/views/buttons.erb +1 -1
  227. data/lib/capybara/spec/views/fieldsets.erb +1 -1
  228. data/lib/capybara/spec/views/form.erb +227 -20
  229. data/lib/capybara/spec/views/frame_child.erb +10 -2
  230. data/lib/capybara/spec/views/frame_one.erb +2 -1
  231. data/lib/capybara/spec/views/frame_parent.erb +2 -2
  232. data/lib/capybara/spec/views/frame_two.erb +1 -1
  233. data/lib/capybara/spec/views/header_links.erb +1 -1
  234. data/lib/capybara/spec/views/host_links.erb +1 -1
  235. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  236. data/lib/capybara/spec/views/obscured.erb +47 -0
  237. data/lib/capybara/spec/views/offset.erb +32 -0
  238. data/lib/capybara/spec/views/path.erb +1 -1
  239. data/lib/capybara/spec/views/popup_one.erb +1 -1
  240. data/lib/capybara/spec/views/popup_two.erb +1 -1
  241. data/lib/capybara/spec/views/postback.erb +1 -1
  242. data/lib/capybara/spec/views/react.erb +45 -0
  243. data/lib/capybara/spec/views/scroll.erb +20 -0
  244. data/lib/capybara/spec/views/spatial.erb +31 -0
  245. data/lib/capybara/spec/views/tables.erb +69 -2
  246. data/lib/capybara/spec/views/with_animation.erb +82 -0
  247. data/lib/capybara/spec/views/with_base_tag.erb +1 -1
  248. data/lib/capybara/spec/views/with_count.erb +1 -1
  249. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  250. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  251. data/lib/capybara/spec/views/with_hover.erb +7 -1
  252. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  253. data/lib/capybara/spec/views/with_html.erb +100 -10
  254. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  255. data/lib/capybara/spec/views/with_html_entities.erb +1 -1
  256. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  257. data/lib/capybara/spec/views/with_js.erb +49 -3
  258. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  259. data/lib/capybara/spec/views/with_namespace.erb +20 -0
  260. data/lib/capybara/spec/views/with_scope.erb +1 -1
  261. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  262. data/lib/capybara/spec/views/with_simple_html.erb +1 -1
  263. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  264. data/lib/capybara/spec/views/with_title.erb +1 -1
  265. data/lib/capybara/spec/views/with_unload_alert.erb +3 -1
  266. data/lib/capybara/spec/views/with_windows.erb +7 -1
  267. data/lib/capybara/spec/views/within_frames.erb +6 -3
  268. data/lib/capybara/version.rb +2 -1
  269. data/lib/capybara/window.rb +39 -21
  270. data/lib/capybara.rb +208 -186
  271. data/spec/basic_node_spec.rb +52 -39
  272. data/spec/capybara_spec.rb +72 -50
  273. data/spec/css_builder_spec.rb +101 -0
  274. data/spec/css_splitter_spec.rb +38 -0
  275. data/spec/dsl_spec.rb +81 -61
  276. data/spec/filter_set_spec.rb +46 -0
  277. data/spec/fixtures/capybara.csv +1 -0
  278. data/spec/fixtures/certificate.pem +25 -0
  279. data/spec/fixtures/key.pem +27 -0
  280. data/spec/fixtures/selenium_driver_rspec_failure.rb +7 -3
  281. data/spec/fixtures/selenium_driver_rspec_success.rb +7 -3
  282. data/spec/minitest_spec.rb +164 -0
  283. data/spec/minitest_spec_spec.rb +162 -0
  284. data/spec/per_session_config_spec.rb +68 -0
  285. data/spec/rack_test_spec.rb +189 -96
  286. data/spec/regexp_dissassembler_spec.rb +250 -0
  287. data/spec/result_spec.rb +143 -13
  288. data/spec/rspec/features_spec.rb +38 -32
  289. data/spec/rspec/scenarios_spec.rb +9 -7
  290. data/spec/rspec/shared_spec_matchers.rb +959 -0
  291. data/spec/rspec/views_spec.rb +9 -3
  292. data/spec/rspec_matchers_spec.rb +62 -0
  293. data/spec/rspec_spec.rb +127 -30
  294. data/spec/sauce_spec_chrome.rb +43 -0
  295. data/spec/selector_spec.rb +458 -37
  296. data/spec/selenium_spec_chrome.rb +196 -9
  297. data/spec/selenium_spec_chrome_remote.rb +100 -0
  298. data/spec/selenium_spec_edge.rb +47 -0
  299. data/spec/selenium_spec_firefox.rb +210 -0
  300. data/spec/selenium_spec_firefox_remote.rb +80 -0
  301. data/spec/selenium_spec_ie.rb +150 -0
  302. data/spec/selenium_spec_safari.rb +148 -0
  303. data/spec/server_spec.rb +200 -101
  304. data/spec/session_spec.rb +91 -0
  305. data/spec/shared_selenium_node.rb +83 -0
  306. data/spec/shared_selenium_session.rb +558 -0
  307. data/spec/spec_helper.rb +94 -2
  308. data/spec/xpath_builder_spec.rb +93 -0
  309. metadata +420 -60
  310. data/lib/capybara/query.rb +0 -7
  311. data/lib/capybara/spec/session/assert_current_path.rb +0 -60
  312. data/lib/capybara/spec/session/assert_selector.rb +0 -148
  313. data/lib/capybara/spec/session/assert_text.rb +0 -196
  314. data/lib/capybara/spec/session/assert_title.rb +0 -70
  315. data/lib/capybara/spec/session/source_spec.rb +0 -0
  316. data/lib/capybara/spec/session/within_frame_spec.rb +0 -53
  317. data/spec/rspec/matchers_spec.rb +0 -827
  318. data/spec/selenium_spec.rb +0 -151
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module XPath
4
+ class Renderer
5
+ def join(*expressions)
6
+ expressions.join('/')
7
+ end
8
+ end
9
+ end
10
+
11
+ module XPath
12
+ module DSL
13
+ def join(*expressions)
14
+ XPath::Expression.new(:join, *[self, expressions].flatten)
15
+ end
16
+ end
17
+ end
@@ -1,379 +1,242 @@
1
1
  # frozen_string_literal: true
2
- require 'capybara/selector/filter'
3
2
 
4
- module Capybara
5
- class Selector
6
-
7
- attr_reader :name, :custom_filters, :format
8
-
9
- class << self
10
- def all
11
- @selectors ||= {}
12
- end
13
-
14
- def add(name, &block)
15
- all[name.to_sym] = Capybara::Selector.new(name.to_sym, &block)
16
- end
17
-
18
- def update(name, &block)
19
- all[name.to_sym].instance_eval(&block)
20
- end
21
-
22
- def remove(name)
23
- all.delete(name.to_sym)
24
- end
25
- end
26
-
27
- def initialize(name, &block)
28
- @name = name
29
- @custom_filters = {}
30
- @match = nil
31
- @label = nil
32
- @failure_message = nil
33
- @description = nil
34
- @format = nil
35
- @expression = nil
36
- instance_eval(&block)
37
- end
38
-
39
- def xpath(&block)
40
- @format, @expression = :xpath, block if block
41
- format == :xpath ? @expression : nil
42
- end
43
-
44
- def css(&block)
45
- @format, @expression = :css, block if block
46
- format == :css ? @expression : nil
47
- end
48
-
49
- def match(&block)
50
- @match = block if block
51
- @match
52
- end
53
-
54
- def label(label=nil)
55
- @label = label if label
56
- @label
57
- end
58
-
59
- def description(options={})
60
- (@description && @description.call(options)).to_s
61
- end
62
-
63
- def call(locator)
64
- if format
65
- @expression.call(locator)
66
- else
67
- warn "Selector has no format"
68
- end
69
- end
70
-
71
- def match?(locator)
72
- @match and @match.call(locator)
73
- end
74
-
75
- def filter(name, options={}, &block)
76
- @custom_filters[name] = Filter.new(name, block, options)
77
- end
78
-
79
- def describe &block
80
- @description = block
81
- end
82
-
83
- private
84
-
85
- def locate_field(xpath, locator)
86
- locate_field = xpath[XPath.attr(:id).equals(locator) |
87
- XPath.attr(:name).equals(locator) |
88
- XPath.attr(:placeholder).equals(locator) |
89
- XPath.attr(:id).equals(XPath.anywhere(:label)[XPath.string.n.is(locator)].attr(:for))]
90
- locate_field += XPath.descendant(:label)[XPath.string.n.is(locator)].descendant(xpath)
91
- locate_field
92
- end
93
- end
94
- end
95
-
96
- Capybara.add_selector(:xpath) do
97
- xpath { |xpath| xpath }
98
- end
99
-
100
- Capybara.add_selector(:css) do
101
- css { |css| css }
102
- end
103
-
104
- Capybara.add_selector(:id) do
105
- xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
106
- end
107
-
108
- Capybara.add_selector(:field) do
109
- xpath do |locator|
110
- xpath = XPath.descendant(:input, :textarea, :select)[~XPath.attr(:type).one_of('submit', 'image', 'hidden')]
111
- xpath = locate_field(xpath, locator.to_s) unless locator.nil?
112
- xpath
113
- end
114
- filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) }
115
- filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) }
116
- filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
117
- filter(:readonly, boolean: true) { |node, value| not(value ^ node[:readonly]) }
118
- filter(:with) { |node, with| node.value == with.to_s }
119
- filter(:type) do |node, type|
120
- if ['textarea', 'select'].include?(type)
121
- node.tag_name == type
122
- else
123
- node[:type] == type
124
- end
125
- end
126
- filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
127
- describe do |options|
128
- desc, states = String.new, []
129
- desc << " of type #{options[:type].inspect}" if options[:type]
130
- desc << " with value #{options[:with].to_s.inspect}" if options.has_key?(:with)
131
- states << 'checked' if options[:checked] || (options.has_key?(:unchecked) && !options[:unchecked])
132
- states << 'not checked' if options[:unchecked] || (options.has_key?(:checked) && !options[:checked])
133
- states << 'disabled' if options[:disabled] == true
134
- desc << " that is #{states.join(' and ')}" unless states.empty?
135
- desc << " with the multiple attribute" if options[:multiple] == true
136
- desc << " without the multiple attribute" if options[:multiple] === false
3
+ require 'capybara/selector/xpath_extensions'
4
+ require 'capybara/selector/selector'
5
+ require 'capybara/selector/definition'
6
+
7
+ #
8
+ # All Selectors below support the listed selector specific filters in addition to the following system-wide filters
9
+ # * :id (String, Regexp, XPath::Expression) - Matches the id attribute
10
+ # * :class (String, Array<String | Regexp>, Regexp, XPath::Expression) - Matches the class(es) provided
11
+ # * :style (String, Regexp, Hash<String, String>) - Match on elements style
12
+ # * :above (Element) - Match elements above the passed element on the page
13
+ # * :below (Element) - Match elements below the passed element on the page
14
+ # * :left_of (Element) - Match elements left of the passed element on the page
15
+ # * :right_of (Element) - Match elements right of the passed element on the page
16
+ # * :near (Element) - Match elements near (within 50px) the passed element on the page
17
+ #
18
+ # ### Built-in Selectors
19
+ #
20
+ # * **:xpath** - Select elements by XPath expression
21
+ # * Locator: An XPath expression
22
+ #
23
+ # * **:css** - Select elements by CSS selector
24
+ # * Locator: A CSS selector
25
+ #
26
+ # * **:id** - Select element by id
27
+ # * Locator: (String, Regexp, XPath::Expression) The id of the element to match
28
+ #
29
+ # * **:field** - Select field elements (input [not of type submit, image, or hidden], textarea, select)
30
+ # * Locator: Matches against the id, {Capybara.configure test_id} attribute, name, placeholder, or
31
+ # associated label text
32
+ # * Filters:
33
+ # * :name (String, Regexp) - Matches the name attribute
34
+ # * :placeholder (String, Regexp) - Matches the placeholder attribute
35
+ # * :type (String) - Matches the type attribute of the field or element type for 'textarea' and 'select'
36
+ # * :readonly (Boolean) - Match on the element being readonly
37
+ # * :with (String, Regexp) - Matches the current value of the field
38
+ # * :checked (Boolean) - Match checked fields?
39
+ # * :unchecked (Boolean) - Match unchecked fields?
40
+ # * :disabled (Boolean, :all) - Match disabled field? (Default: false)
41
+ # * :multiple (Boolean) - Match fields that accept multiple values
42
+ # * :valid (Boolean) - Match fields that are valid/invalid according to HTML5 form validation
43
+ # * :validation_message (String, Regexp) - Matches the elements current validationMessage
44
+ #
45
+ # * **:fieldset** - Select fieldset elements
46
+ # * Locator: Matches id, {Capybara.configure test_id}, or contents of wrapped legend
47
+ # * Filters:
48
+ # * :legend (String) - Matches contents of wrapped legend
49
+ # * :disabled (Boolean) - Match disabled fieldset?
50
+ #
51
+ # * **:link** - Find links (`<a>` elements with an href attribute)
52
+ # * Locator: Matches the id, {Capybara.configure test_id}, or title attributes, or the string content of the link,
53
+ # or the alt attribute of a contained img element. By default this selector requires a link to have an href attribute.
54
+ # * Filters:
55
+ # * :title (String) - Matches the title attribute
56
+ # * :alt (String) - Matches the alt attribute of a contained img element
57
+ # * :href (String, Regexp, nil, false) - Matches the normalized href of the link, if nil will find `<a>` elements with no href attribute, if false ignores href presence
58
+ #
59
+ # * **:button** - Find buttons ( input [of type submit, reset, image, button] or button elements )
60
+ # * Locator: Matches the id, {Capybara.configure test_id} attribute, name, value, or title attributes, string content of a button, or the alt attribute of an image type button or of a descendant image of a button
61
+ # * Filters:
62
+ # * :name (String, Regexp) - Matches the name attribute
63
+ # * :title (String) - Matches the title attribute
64
+ # * :value (String) - Matches the value of an input button
65
+ # * :type (String) - Matches the type attribute
66
+ # * :disabled (Boolean, :all) - Match disabled buttons (Default: false)
67
+ #
68
+ # * **:link_or_button** - Find links or buttons
69
+ # * Locator: See :link and :button selectors
70
+ # * Filters:
71
+ # * :disabled (Boolean, :all) - Match disabled buttons? (Default: false)
72
+ #
73
+ # * **:fillable_field** - Find text fillable fields ( textarea, input [not of type submit, image, radio, checkbox, hidden, file] )
74
+ # * Locator: Matches against the id, {Capybara.configure test_id} attribute, name, placeholder, or associated label text
75
+ # * Filters:
76
+ # * :name (String, Regexp) - Matches the name attribute
77
+ # * :placeholder (String, Regexp) - Matches the placeholder attribute
78
+ # * :with (String, Regexp) - Matches the current value of the field
79
+ # * :type (String) - Matches the type attribute of the field or element type for 'textarea'
80
+ # * :disabled (Boolean, :all) - Match disabled field? (Default: false)
81
+ # * :multiple (Boolean) - Match fields that accept multiple values
82
+ # * :valid (Boolean) - Match fields that are valid/invalid according to HTML5 form validation
83
+ # * :validation_message (String, Regexp) - Matches the elements current validationMessage
84
+ #
85
+ # * **:radio_button** - Find radio buttons
86
+ # * Locator: Match id, {Capybara.configure test_id} attribute, name, or associated label text
87
+ # * Filters:
88
+ # * :name (String, Regexp) - Matches the name attribute
89
+ # * :checked (Boolean) - Match checked fields?
90
+ # * :unchecked (Boolean) - Match unchecked fields?
91
+ # * :disabled (Boolean, :all) - Match disabled field? (Default: false)
92
+ # * :option (String, Regexp) - Match the current value
93
+ # * :with - Alias of :option
94
+ #
95
+ # * **:checkbox** - Find checkboxes
96
+ # * Locator: Match id, {Capybara.configure test_id} attribute, name, or associated label text
97
+ # * Filters:
98
+ # * :name (String, Regexp) - Matches the name attribute
99
+ # * :checked (Boolean) - Match checked fields?
100
+ # * :unchecked (Boolean) - Match unchecked fields?
101
+ # * :disabled (Boolean, :all) - Match disabled field? (Default: false)
102
+ # * :with (String, Regexp) - Match the current value
103
+ # * :option - Alias of :with
104
+ #
105
+ # * **:select** - Find select elements
106
+ # * Locator: Match id, {Capybara.configure test_id} attribute, name, placeholder, or associated label text
107
+ # * Filters:
108
+ # * :name (String, Regexp) - Matches the name attribute
109
+ # * :placeholder (String, Placeholder) - Matches the placeholder attribute
110
+ # * :disabled (Boolean, :all) - Match disabled field? (Default: false)
111
+ # * :multiple (Boolean) - Match fields that accept multiple values
112
+ # * :options (Array<String>) - Exact match options
113
+ # * :enabled_options (Array<String>) - Exact match enabled options
114
+ # * :disabled_options (Array<String>) - Exact match disabled options
115
+ # * :with_options (Array<String>) - Partial match options
116
+ # * :selected (String, Array<String>) - Match the selection(s)
117
+ # * :with_selected (String, Array<String>) - Partial match the selection(s)
118
+ #
119
+ # * **:option** - Find option elements
120
+ # * Locator: Match text of option
121
+ # * Filters:
122
+ # * :disabled (Boolean) - Match disabled option
123
+ # * :selected (Boolean) - Match selected option
124
+ #
125
+ # * **:datalist_input** - Find input field with datalist completion
126
+ # * Locator: Matches against the id, {Capybara.configure test_id} attribute, name,
127
+ # placeholder, or associated label text
128
+ # * Filters:
129
+ # * :name (String, Regexp) - Matches the name attribute
130
+ # * :placeholder (String, Regexp) - Matches the placeholder attribute
131
+ # * :disabled (Boolean, :all) - Match disabled field? (Default: false)
132
+ # * :options (Array<String>) - Exact match options
133
+ # * :with_options (Array<String>) - Partial match options
134
+ #
135
+ # * **:datalist_option** - Find datalist option
136
+ # * Locator: Match text or value of option
137
+ # * Filters:
138
+ # * :disabled (Boolean) - Match disabled option
139
+ #
140
+ # * **:file_field** - Find file input elements
141
+ # * Locator: Match id, {Capybara.configure test_id} attribute, name, or associated label text
142
+ # * Filters:
143
+ # * :name (String, Regexp) - Matches the name attribute
144
+ # * :disabled (Boolean, :all) - Match disabled field? (Default: false)
145
+ # * :multiple (Boolean) - Match field that accepts multiple values
146
+ #
147
+ # * **:label** - Find label elements
148
+ # * Locator: Match id, {Capybara.configure test_id}, or text contents
149
+ # * Filters:
150
+ # * :for (Element, String, Regexp) - The element or id of the element associated with the label
151
+ #
152
+ # * **:table** - Find table elements
153
+ # * Locator: id, {Capybara.configure test_id}, or caption text of table
154
+ # * Filters:
155
+ # * :caption (String) - Match text of associated caption
156
+ # * :with_rows (Array<Array<String>>, Array<Hash<String, String>>) - Partial match `<td>` data - visibility of `<td>` elements is not considered
157
+ # * :rows (Array<Array<String>>) - Match all `<td>`s - visibility of `<td>` elements is not considered
158
+ # * :with_cols (Array<Array<String>>, Array<Hash<String, String>>) - Partial match `<td>` data - visibility of `<td>` elements is not considered
159
+ # * :cols (Array<Array<String>>) - Match all `<td>`s - visibility of `<td>` elements is not considered
160
+ #
161
+ # * **:table_row** - Find table row
162
+ # * Locator: Array<String>, Hash<String, String> table row `<td>` contents - visibility of `<td>` elements is not considered
163
+ #
164
+ # * **:frame** - Find frame/iframe elements
165
+ # * Locator: Match id, {Capybara.configure test_id} attribute, or name
166
+ # * Filters:
167
+ # * :name (String) - Match name attribute
168
+ #
169
+ # * **:element**
170
+ # * Locator: Type of element ('div', 'a', etc) - if not specified defaults to '*'
171
+ # * Filters:
172
+ # * :\<any> (String, Regexp) - Match on any specified element attribute
173
+ #
174
+ class Capybara::Selector; end # rubocop:disable Lint/EmptyClass
175
+
176
+ Capybara::Selector::FilterSet.add(:_field) do
177
+ node_filter(:checked, :boolean) { |node, value| !(value ^ node.checked?) }
178
+ node_filter(:unchecked, :boolean) { |node, value| (value ^ node.checked?) }
179
+ node_filter(:disabled, :boolean, default: false, skip_if: :all) { |node, value| !(value ^ node.disabled?) }
180
+ node_filter(:valid, :boolean) { |node, value| node.evaluate_script('this.validity.valid') == value }
181
+ node_filter(:name) { |node, value| !value.is_a?(Regexp) || value.match?(node[:name]) }
182
+ node_filter(:placeholder) { |node, value| !value.is_a?(Regexp) || value.match?(node[:placeholder]) }
183
+ node_filter(:validation_message) do |node, msg|
184
+ vm = node[:validationMessage]
185
+ (msg.is_a?(Regexp) ? msg.match?(vm) : vm == msg.to_s).tap do |res|
186
+ add_error("Expected validation message to be #{msg.inspect} but was #{vm}") unless res
187
+ end
188
+ end
189
+
190
+ expression_filter(:name) do |xpath, val|
191
+ builder(xpath).add_attribute_conditions(name: val)
192
+ end
193
+ expression_filter(:placeholder) do |xpath, val|
194
+ builder(xpath).add_attribute_conditions(placeholder: val)
195
+ end
196
+ expression_filter(:disabled) { |xpath, val| val ? xpath : xpath[~XPath.attr(:disabled)] }
197
+ expression_filter(:multiple) { |xpath, val| xpath[val ? XPath.attr(:multiple) : ~XPath.attr(:multiple)] }
198
+
199
+ describe(:expression_filters) do |name: nil, placeholder: nil, disabled: nil, multiple: nil, **|
200
+ desc = +''
201
+ desc << ' that is not disabled' if disabled == false
202
+ desc << " with name #{name}" if name
203
+ desc << " with placeholder #{placeholder}" if placeholder
204
+ desc << ' with the multiple attribute' if multiple == true
205
+ desc << ' without the multiple attribute' if multiple == false
137
206
  desc
138
207
  end
139
- end
140
-
141
- Capybara.add_selector(:fieldset) do
142
- xpath do |locator|
143
- xpath = XPath.descendant(:fieldset)
144
- xpath = xpath[XPath.attr(:id).equals(locator.to_s) | XPath.child(:legend)[XPath.string.n.is(locator.to_s)]] unless locator.nil?
145
- xpath
146
- end
147
- end
148
-
149
- Capybara.add_selector(:link) do
150
- xpath do |locator|
151
- xpath = XPath.descendant(:a)[XPath.attr(:href)]
152
- unless locator.nil?
153
- locator = locator.to_s
154
- xpath = xpath[XPath.attr(:id).equals(locator) |
155
- XPath.string.n.is(locator) |
156
- XPath.attr(:title).is(locator) |
157
- XPath.descendant(:img)[XPath.attr(:alt).is(locator)]]
158
- end
159
- xpath
160
- end
161
-
162
- filter(:href) do |node, href|
163
- if href.is_a? Regexp
164
- node[:href].match href
165
- else
166
- node.first(:xpath, XPath.axis(:self)[XPath.attr(:href).equals(href.to_s)], minimum: 0)
167
- end
168
- end
169
-
170
- describe { |options| " with href #{options[:href].inspect}" if options[:href] }
171
- end
172
-
173
- Capybara.add_selector(:button) do
174
- xpath do |locator|
175
- input_btn_xpath = XPath.descendant(:input)[XPath.attr(:type).one_of('submit', 'reset', 'image', 'button')]
176
- btn_xpath = XPath.descendant(:button)
177
- image_btn_xpath = XPath.descendant(:input)[XPath.attr(:type).equals('image')]
178
-
179
- unless locator.nil?
180
- locator = locator.to_s
181
- input_btn_xpath = input_btn_xpath[XPath.attr(:id).equals(locator) | XPath.attr(:value).is(locator) | XPath.attr(:title).is(locator)]
182
- btn_xpath = btn_xpath[XPath.attr(:id).equals(locator) | XPath.attr(:value).is(locator) | XPath.string.n.is(locator) | XPath.attr(:title).is(locator)]
183
- image_btn_xpath = image_btn_xpath[XPath.attr(:alt).is(locator)]
184
- end
185
-
186
- input_btn_xpath + btn_xpath + image_btn_xpath
187
- end
188
-
189
- filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
190
208
 
191
- describe { |options| " that is disabled" if options[:disabled] == true }
192
- end
193
-
194
- Capybara.add_selector(:link_or_button) do
195
- label "link or button"
196
- xpath do |locator|
197
- self.class.all.values_at(:link, :button).map {|selector| selector.xpath.call(locator)}.reduce(:+)
198
- end
199
-
200
- filter(:disabled, default: false, boolean: true) { |node, value| node.tag_name == "a" or not(value ^ node.disabled?) }
201
-
202
- describe { |options| " that is disabled" if options[:disabled] }
203
- end
204
-
205
- Capybara.add_selector(:fillable_field) do
206
- label "field"
207
- xpath do |locator|
208
- xpath = XPath.descendant(:input, :textarea)[~XPath.attr(:type).one_of('submit', 'image', 'radio', 'checkbox', 'hidden', 'file')]
209
- xpath = locate_field(xpath, locator.to_s) unless locator.nil?
210
- xpath
211
- end
212
-
213
- filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
214
- filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
215
-
216
- describe do |options|
217
- desc = String.new
218
- desc << " that is disabled" if options[:disabled] == true
219
- desc << " with the multiple attribute" if options[:multiple] == true
220
- desc << " without the multiple attribute" if options[:multiple] === false
221
- desc
222
- end
223
- end
224
-
225
- Capybara.add_selector(:radio_button) do
226
- label "radio button"
227
- xpath do |locator|
228
- xpath = XPath.descendant(:input)[XPath.attr(:type).equals('radio')]
229
- xpath = locate_field(xpath, locator.to_s) unless locator.nil?
230
- xpath
231
- end
232
-
233
- filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) }
234
- filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) }
235
- filter(:option) { |node, value| node.value == value.to_s }
236
- filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
237
-
238
- describe do |options|
239
- desc, states = String.new, []
240
- desc << " with value #{options[:option].inspect}" if options[:option]
241
- states << 'checked' if options[:checked] || (options.has_key?(:unchecked) && !options[:unchecked])
242
- states << 'not checked' if options[:unchecked] || (options.has_key?(:checked) && !options[:checked])
243
- states << 'disabled' if options[:disabled] == true
209
+ describe(:node_filters) do |checked: nil, unchecked: nil, disabled: nil, valid: nil, validation_message: nil, **|
210
+ desc, states = +'', []
211
+ states << 'checked' if checked || (unchecked == false)
212
+ states << 'not checked' if unchecked || (checked == false)
213
+ states << 'disabled' if disabled == true
244
214
  desc << " that is #{states.join(' and ')}" unless states.empty?
215
+ desc << ' that is valid' if valid == true
216
+ desc << ' that is invalid' if valid == false
217
+ desc << " with validation message #{validation_message.to_s.inspect}" if validation_message
245
218
  desc
246
219
  end
247
220
  end
248
221
 
249
- Capybara.add_selector(:checkbox) do
250
- xpath do |locator|
251
- xpath = XPath.descendant(:input)[XPath.attr(:type).equals('checkbox')]
252
- xpath = locate_field(xpath, locator.to_s) unless locator.nil?
253
- xpath
254
- end
255
-
256
- filter(:checked, boolean: true) { |node, value| not(value ^ node.checked?) }
257
- filter(:unchecked, boolean: true) { |node, value| (value ^ node.checked?) }
258
- filter(:option) { |node, value| node.value == value.to_s }
259
- filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
260
-
261
- describe do |options|
262
- desc, states = String.new, []
263
- desc << " with value #{options[:option].inspect}" if options[:option]
264
- states << 'checked' if options[:checked] || (options.has_key?(:unchecked) && !options[:unchecked])
265
- states << 'not checked' if options[:unchecked] || (options.has_key?(:checked) && !options[:checked])
266
- states << 'disabled' if options[:disabled] == true
267
- desc << " that is #{states.join(' and ')}" unless states.empty?
268
- desc
269
- end
270
- end
271
-
272
- Capybara.add_selector(:select) do
273
- label "select box"
274
- xpath do |locator|
275
- xpath = XPath.descendant(:select)
276
- xpath = locate_field(xpath, locator.to_s) unless locator.nil?
277
- xpath
278
- end
279
-
280
- filter(:options) do |node, options|
281
- if node.visible?
282
- actual = node.all(:xpath, './/option').map { |option| option.text }
283
- else
284
- actual = node.all(:xpath, './/option', visible: false).map { |option| option.text(:all) }
285
- end
286
- options.sort == actual.sort
287
- end
288
- filter(:with_options) do |node, options|
289
- finder_settings = { minimum: 0 }
290
- if !node.visible?
291
- finder_settings[:visible] = false
292
- end
293
- options.all? { |option| node.first(:option, option, finder_settings) }
294
- end
295
- filter(:selected) do |node, selected|
296
- actual = node.all(:xpath, './/option', visible: false).select { |option| option.selected? }.map { |option| option.text(:all) }
297
- [selected].flatten.sort == actual.sort
298
- end
299
- filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
300
- filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
301
-
302
- describe do |options|
303
- desc = String.new
304
- desc << " with options #{options[:options].inspect}" if options[:options]
305
- desc << " with at least options #{options[:with_options].inspect}" if options[:with_options]
306
- desc << " with #{options[:selected].inspect} selected" if options[:selected]
307
- desc << " that is disabled" if options[:disabled] == true
308
- desc << " that allows multiple selection" if options[:multiple] == true
309
- desc << " that only allows single selection" if options[:multiple] === false
310
- desc
311
- end
312
- end
313
-
314
- Capybara.add_selector(:option) do
315
- xpath do |locator|
316
- xpath = XPath.descendant(:option)
317
- xpath = xpath[XPath.string.n.is(locator.to_s)] unless locator.nil?
318
- xpath
319
- end
320
-
321
- filter(:disabled, boolean: true) { |node, value| not(value ^ node.disabled?) }
322
- filter(:selected, boolean: true) { |node, value| not(value ^ node.selected?) }
323
-
324
- describe do |options|
325
- desc = String.new
326
- desc << " that is#{' not' unless options[:disabled]} disabled" if options.has_key?(:disabled)
327
- desc << " that is#{' not' unless options[:selected]} selected" if options.has_key?(:selected)
328
- desc
329
- end
330
- end
331
-
332
- Capybara.add_selector(:file_field) do
333
- label "file field"
334
- xpath do |locator|
335
- xpath = XPath.descendant(:input)[XPath.attr(:type).equals('file')]
336
- xpath = locate_field(xpath, locator.to_s) unless locator.nil?
337
- xpath
338
- end
339
-
340
- filter(:disabled, default: false, boolean: true, skip_if: :all) { |node, value| not(value ^ node.disabled?) }
341
- filter(:multiple, boolean: true) { |node, value| !(value ^ node[:multiple]) }
342
-
343
- describe do |options|
344
- desc = String.new
345
- desc << " that is disabled" if options[:disabled] == true
346
- desc << " that allows multiple files" if options[:multiple] == true
347
- desc << " that only allows a single file" if options[:multiple] === false
348
- desc
349
- end
350
- end
351
-
352
- Capybara.add_selector(:label) do
353
- label "label"
354
- xpath do |locator|
355
- xpath = XPath.descendant(:label)
356
- xpath = xpath[XPath.string.n.is(locator.to_s) | XPath.attr(:id).equals(locator.to_s)] unless locator.nil?
357
- xpath
358
- end
359
-
360
- filter(:for) do |node, field_or_value|
361
- if field_or_value.is_a? Capybara::Node::Element
362
- if field_or_value[:id] && (field_or_value[:id] == node[:for])
363
- true
364
- else
365
- field_or_value.find_xpath('./ancestor::label[1]').include? node.base
366
- end
367
- else
368
- node[:for] == field_or_value.to_s
369
- end
370
- end
371
- end
372
-
373
- Capybara.add_selector(:table) do
374
- xpath do |locator|
375
- xpath = XPath.descendant(:table)
376
- xpath = xpath[XPath.attr(:id).equals(locator.to_s) | XPath.descendant(:caption).is(locator.to_s)] unless locator.nil?
377
- xpath
378
- end
379
- end
222
+ require 'capybara/selector/definition/xpath'
223
+ require 'capybara/selector/definition/css'
224
+ require 'capybara/selector/definition/id'
225
+ require 'capybara/selector/definition/field'
226
+ require 'capybara/selector/definition/fieldset'
227
+ require 'capybara/selector/definition/link'
228
+ require 'capybara/selector/definition/button'
229
+ require 'capybara/selector/definition/link_or_button'
230
+ require 'capybara/selector/definition/fillable_field'
231
+ require 'capybara/selector/definition/radio_button'
232
+ require 'capybara/selector/definition/checkbox'
233
+ require 'capybara/selector/definition/select'
234
+ require 'capybara/selector/definition/datalist_input'
235
+ require 'capybara/selector/definition/option'
236
+ require 'capybara/selector/definition/datalist_option'
237
+ require 'capybara/selector/definition/file_field'
238
+ require 'capybara/selector/definition/label'
239
+ require 'capybara/selector/definition/table'
240
+ require 'capybara/selector/definition/table_row'
241
+ require 'capybara/selector/definition/frame'
242
+ require 'capybara/selector/definition/element'