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,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#become_closed', requires: %i[windows js] do
4
+ let!(:window) { @session.current_window }
5
+ let(:other_window) do
6
+ @session.window_opened_by do
7
+ @session.find(:css, '#openWindow').click
8
+ end
9
+ end
10
+
11
+ before do
12
+ @session.visit('/with_windows')
13
+ end
14
+
15
+ after do
16
+ @session.document.synchronize(5, errors: [Capybara::CapybaraError]) do
17
+ raise Capybara::CapybaraError if @session.windows.size != 1
18
+ end
19
+ @session.switch_to_window(window)
20
+ end
21
+
22
+ context 'with :wait option' do
23
+ it 'should wait if value of :wait is more than timeout' do
24
+ @session.within_window other_window do
25
+ @session.execute_script('setTimeout(function(){ window.close(); }, 500);')
26
+ end
27
+ Capybara.using_wait_time 0.1 do
28
+ expect(other_window).to become_closed(wait: 5)
29
+ end
30
+ end
31
+
32
+ it 'should raise error if value of :wait is less than timeout' do
33
+ @session.within_window other_window do
34
+ @session.execute_script('setTimeout(function(){ window.close(); }, 1000);')
35
+ end
36
+ Capybara.using_wait_time 2 do
37
+ expect do
38
+ expect(other_window).to become_closed(wait: 0.2)
39
+ end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\Aexpected #<Window @handle=".+"> to become closed after 0.2 seconds\Z/)
40
+ end
41
+ end
42
+ end
43
+
44
+ context 'without :wait option' do
45
+ it 'should wait if value of default_max_wait_time is more than timeout' do
46
+ @session.within_window other_window do
47
+ @session.execute_script('setTimeout(function(){ window.close(); }, 500);')
48
+ end
49
+ Capybara.using_wait_time 5 do
50
+ expect(other_window).to become_closed
51
+ end
52
+ end
53
+
54
+ it 'should raise error if value of default_max_wait_time is less than timeout' do
55
+ @session.within_window other_window do
56
+ @session.execute_script('setTimeout(function(){ window.close(); }, 900);')
57
+ end
58
+ Capybara.using_wait_time 0.4 do
59
+ expect do
60
+ expect(other_window).to become_closed
61
+ end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\Aexpected #<Window @handle=".+"> to become closed after 0.4 seconds\Z/)
62
+ end
63
+ end
64
+ end
65
+
66
+ context 'with not_to' do
67
+ it "should not raise error if window doesn't close before default_max_wait_time" do
68
+ @session.within_window other_window do
69
+ @session.execute_script('setTimeout(function(){ window.close(); }, 1000);')
70
+ end
71
+ Capybara.using_wait_time 0.3 do
72
+ expect do
73
+ expect(other_window).not_to become_closed
74
+ end.not_to raise_error
75
+ end
76
+ end
77
+
78
+ it 'should raise error if window closes before default_max_wait_time' do
79
+ @session.within_window other_window do
80
+ @session.execute_script('setTimeout(function(){ window.close(); }, 700);')
81
+ end
82
+ Capybara.using_wait_time 3.1 do
83
+ expect do
84
+ expect(other_window).not_to become_closed
85
+ end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\Aexpected #<Window @handle=".+"> not to become closed after 3.1 seconds\Z/)
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#current_window', requires: [:windows] do
4
+ before do
5
+ @window = @session.current_window
6
+ @session.visit('/with_windows')
7
+ end
8
+
9
+ after do
10
+ (@session.windows - [@window]).each do |w|
11
+ @session.switch_to_window w
12
+ w.close
13
+ end
14
+ @session.switch_to_window(@window)
15
+ end
16
+
17
+ it 'should return window' do
18
+ expect(@session.current_window).to be_instance_of(Capybara::Window)
19
+ end
20
+
21
+ it 'should be modified by switching to another window' do
22
+ window = @session.window_opened_by { @session.find(:css, '#openWindow').click }
23
+
24
+ expect do
25
+ @session.switch_to_window(window)
26
+ end.to change { @session.current_window }.from(@window).to(window)
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ Capybara::SpecHelper.spec '#open_new_window', requires: [:windows] do
4
+ before do
5
+ @window = @session.current_window
6
+ @session.visit('/with_windows')
7
+ end
8
+
9
+ after do
10
+ (@session.windows - [@window]).each do |w|
11
+ @session.switch_to_window w
12
+ w.close
13
+ end
14
+ @session.switch_to_window(@window)
15
+ end
16
+
17
+ it 'should open new window with blank url and title' do
18
+ window = @session.open_new_window
19
+ @session.switch_to_window(window)
20
+ expect(@session.title).to satisfy('be a blank title') { |title| ['', 'about:blank'].include? title }
21
+ expect(@session.current_url).to eq('about:blank')
22
+ end
23
+
24
+ it 'should open window with changeable content' do
25
+ window = @session.open_new_window
26
+ @session.within_window window do
27
+ @session.visit '/with_html'
28
+ expect(@session).to have_css('#first')
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Note: This file uses `sleep` to sync up parts of the tests. This is only implemented like this
4
+ # because of the methods being tested. In tests using Capybara this type of behavior should be implemented
5
+ # using Capybara provided assertions with builtin waiting behavior.
6
+
7
+ Capybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do
8
+ before do
9
+ @window = @session.current_window
10
+ @session.visit('/with_windows')
11
+ @session.assert_selector(:css, 'body.loaded')
12
+ end
13
+
14
+ after do
15
+ (@session.windows - [@window]).each do |w|
16
+ @session.switch_to_window w
17
+ w.close
18
+ end
19
+ @session.switch_to_window(@window)
20
+ end
21
+
22
+ it 'should raise error when invoked without args' do
23
+ expect do
24
+ @session.switch_to_window
25
+ end.to raise_error(ArgumentError, '`switch_to_window`: either window or block should be provided')
26
+ end
27
+
28
+ it 'should raise error when invoked with window and block' do
29
+ expect do
30
+ @session.switch_to_window(@window) { @session.title == 'Title of the first popup' }
31
+ end.to raise_error(ArgumentError, '`switch_to_window` can take either a block or a window, not both')
32
+ end
33
+
34
+ context 'with an instance of Capybara::Window' do
35
+ it 'should be able to switch to window' do
36
+ window = @session.open_new_window
37
+ expect(@session.title).to eq('With Windows')
38
+ @session.switch_to_window(window)
39
+ expect(@session.title).to satisfy('be a blank title') { |title| ['', 'about:blank'].include? title }
40
+ end
41
+
42
+ it 'should raise error when closed window is passed' do
43
+ original_window = @session.current_window
44
+ new_window = @session.open_new_window
45
+ @session.switch_to_window(new_window)
46
+ new_window.close
47
+ @session.switch_to_window(original_window)
48
+ expect do
49
+ @session.switch_to_window(new_window)
50
+ end.to raise_error(@session.driver.no_such_window_error)
51
+ end
52
+ end
53
+
54
+ context 'with block' do
55
+ before do
56
+ @session.find(:css, '#openTwoWindows').click
57
+ sleep(1) # wait for the windows to open
58
+ end
59
+
60
+ it 'should be able to switch to current window' do
61
+ @session.switch_to_window { @session.title == 'With Windows' }
62
+ expect(@session).to have_css('#openTwoWindows')
63
+ end
64
+
65
+ it 'should find the div in another window' do
66
+ @session.switch_to_window { @session.title == 'Title of popup two' }
67
+ expect(@session).to have_css('#divInPopupTwo')
68
+ end
69
+
70
+ it 'should be able to switch multiple times' do
71
+ @session.switch_to_window { @session.title == 'Title of the first popup' }
72
+ expect(@session).to have_css('#divInPopupOne')
73
+ @session.switch_to_window { @session.title == 'Title of popup two' }
74
+ expect(@session).to have_css('#divInPopupTwo')
75
+ end
76
+
77
+ it 'should return window' do
78
+ window = @session.switch_to_window { @session.title == 'Title of popup two' }
79
+ expect((@session.windows - [@window])).to include(window)
80
+ end
81
+
82
+ it "should raise error when invoked inside `within` as it's nonsense" do
83
+ expect do
84
+ @session.within(:css, '#doesNotOpenWindows') do
85
+ @session.switch_to_window { @session.title == 'With Windows' }
86
+ end
87
+ end.to raise_error(Capybara::ScopeError, /`switch_to_window` is not supposed to be invoked/)
88
+ end
89
+
90
+ it "should raise error when invoked inside `within_frame` as it's nonsense" do
91
+ expect do
92
+ @session.within_frame('frameOne') do
93
+ @session.switch_to_window { @session.title == 'With Windows' }
94
+ end
95
+ end.to raise_error(Capybara::ScopeError, /`switch_to_window` is not supposed to be invoked from/)
96
+ end
97
+
98
+ it 'should allow to be called inside within_window and within_window will still return to original' do
99
+ other_windows = (@session.windows - [@window])
100
+ expect(@session.current_window).to eq(@window)
101
+ @session.within_window other_windows[0] do
102
+ expect(@session.current_window).to eq(other_windows[0])
103
+ @session.switch_to_window other_windows[1]
104
+ expect(@session.current_window).to eq(other_windows[1])
105
+ end
106
+ expect(@session.current_window).to eq(@window)
107
+ end
108
+
109
+ it "should raise error if window matching block wasn't found" do
110
+ original = @session.current_window
111
+ expect do
112
+ @session.switch_to_window { @session.title == 'A title' }
113
+ end.to raise_error(Capybara::WindowError, 'Could not find a window matching block/lambda')
114
+ expect(@session.current_window).to eq(original)
115
+ end
116
+
117
+ it 'should switch to original window if error is raised inside block' do
118
+ original = @session.switch_to_window(@session.windows[1])
119
+ expect do
120
+ @session.switch_to_window { raise 'error' }
121
+ end.to raise_error(StandardError, 'error')
122
+ expect(@session.current_window).to eq(original)
123
+ end
124
+ end
125
+
126
+ it 'should wait for window to appear' do
127
+ @session.find(:css, '#openWindowWithTimeout').click
128
+ expect do
129
+ @session.switch_to_window(wait: 5) { @session.title == 'Title of the first popup' }
130
+ end.not_to raise_error
131
+ end
132
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Note: This file uses `sleep` to sync up parts of the tests. This is only implemented like this
4
+ # because of the methods being tested. In tests using Capybara this type of behavior should be implemented
5
+ # using Capybara provided assertions with builtin waiting behavior.
6
+
7
+ Capybara::SpecHelper.spec '#window_opened_by', requires: [:windows] do
8
+ before do
9
+ @window = @session.current_window
10
+ @session.visit('/with_windows')
11
+ @session.assert_selector(:css, 'body.loaded')
12
+ end
13
+
14
+ after do
15
+ (@session.windows - [@window]).each do |w|
16
+ @session.switch_to_window w
17
+ w.close
18
+ end
19
+ @session.switch_to_window(@window)
20
+ end
21
+
22
+ let(:zero_windows_message) { 'block passed to #window_opened_by opened 0 windows instead of 1' }
23
+ let(:two_windows_message) { 'block passed to #window_opened_by opened 2 windows instead of 1' }
24
+
25
+ context 'with :wait option' do
26
+ it 'should raise error if value of :wait is less than timeout' do
27
+ # So large value is used as `driver.window_handles` takes up to 800 ms on Travis
28
+ Capybara.using_wait_time 2 do
29
+ button = @session.find(:css, '#openWindowWithLongerTimeout')
30
+ expect do
31
+ @session.window_opened_by(wait: 0.3) do
32
+ button.click
33
+ end
34
+ end.to raise_error(Capybara::WindowError, zero_windows_message)
35
+ end
36
+ @session.document.synchronize(5, errors: [Capybara::CapybaraError]) do
37
+ raise Capybara::CapybaraError if @session.windows.size != 2
38
+ end
39
+ end
40
+
41
+ it 'should find window if value of :wait is more than timeout' do
42
+ button = @session.find(:css, '#openWindowWithTimeout')
43
+ Capybara.using_wait_time 0.1 do
44
+ window = @session.window_opened_by(wait: 1.5) do
45
+ button.click
46
+ end
47
+ expect(window).to be_instance_of(Capybara::Window)
48
+ end
49
+ end
50
+ end
51
+
52
+ context 'without :wait option' do
53
+ it 'should raise error if default_max_wait_time is less than timeout' do
54
+ button = @session.find(:css, '#openWindowWithTimeout')
55
+ Capybara.using_wait_time 0.1 do
56
+ expect do
57
+ @session.window_opened_by do
58
+ button.click
59
+ end
60
+ end.to raise_error(Capybara::WindowError, zero_windows_message)
61
+ end
62
+ @session.document.synchronize(2, errors: [Capybara::CapybaraError]) do
63
+ raise Capybara::CapybaraError if @session.windows.size != 2
64
+ end
65
+ end
66
+
67
+ it 'should find window if default_max_wait_time is more than timeout' do
68
+ button = @session.find(:css, '#openWindowWithTimeout')
69
+ Capybara.using_wait_time 5 do
70
+ window = @session.window_opened_by do
71
+ button.click
72
+ end
73
+ expect(window).to be_instance_of(Capybara::Window)
74
+ end
75
+ end
76
+ end
77
+
78
+ it 'should raise error when two windows have been opened by block' do
79
+ button = @session.find(:css, '#openTwoWindows')
80
+ expect do
81
+ @session.window_opened_by do
82
+ button.click
83
+ sleep 1 # It's possible for window_opened_by to be fullfilled before the second window opens
84
+ end
85
+ end.to raise_error(Capybara::WindowError, two_windows_message)
86
+ @session.document.synchronize(2, errors: [Capybara::CapybaraError]) do
87
+ raise Capybara::CapybaraError if @session.windows.size != 3
88
+ end
89
+ end
90
+
91
+ it 'should raise error when no windows were opened by block' do
92
+ button = @session.find(:css, '#doesNotOpenWindows')
93
+ expect do
94
+ @session.window_opened_by do
95
+ button.click
96
+ end
97
+ end.to raise_error(Capybara::WindowError, zero_windows_message)
98
+ end
99
+ end
@@ -0,0 +1,203 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Note: This file uses `sleep` to sync up parts of the tests. This is only implemented like this
4
+ # because of the methods being tested. In tests using Capybara this type of behavior should be implemented
5
+ # using Capybara provided assertions with builtin waiting behavior.
6
+
7
+ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
8
+ let!(:orig_window) { @session.current_window }
9
+ before do
10
+ @session.visit('/with_windows')
11
+ end
12
+
13
+ after do
14
+ (@session.windows - [orig_window]).each do |w|
15
+ @session.switch_to_window w
16
+ w.close
17
+ end
18
+ @session.switch_to_window(orig_window)
19
+ end
20
+
21
+ describe '#exists?' do
22
+ it 'should become false after window was closed' do
23
+ other_window = @session.window_opened_by do
24
+ @session.find(:css, '#openWindow').click
25
+ end
26
+
27
+ expect do
28
+ @session.switch_to_window other_window
29
+ other_window.close
30
+ end.to change(other_window, :exists?).from(true).to(false)
31
+ end
32
+ end
33
+
34
+ describe '#closed?' do
35
+ it 'should become true after window was closed' do
36
+ other_window = @session.window_opened_by do
37
+ @session.find(:css, '#openWindow').click
38
+ end
39
+ expect do
40
+ @session.switch_to_window other_window
41
+ other_window.close
42
+ end.to change { other_window.closed? }.from(false).to(true)
43
+ end
44
+ end
45
+
46
+ describe '#current?' do
47
+ let(:other_window) do
48
+ @session.window_opened_by do
49
+ @session.find(:css, '#openWindow').click
50
+ end
51
+ end
52
+
53
+ it 'should become true after switching to window' do
54
+ expect do
55
+ @session.switch_to_window(other_window)
56
+ end.to change(other_window, :current?).from(false).to(true)
57
+ end
58
+
59
+ it 'should return false if window is closed' do
60
+ @session.switch_to_window(other_window)
61
+ other_window.close
62
+ expect(other_window.current?).to eq(false)
63
+ end
64
+ end
65
+
66
+ describe '#close' do
67
+ let!(:other_window) do
68
+ @session.window_opened_by do
69
+ @session.find(:css, '#openWindow').click
70
+ end
71
+ end
72
+
73
+ it 'should switch to original window if invoked not for current window' do
74
+ expect(@session.windows.size).to eq(2)
75
+ expect(@session.current_window).to eq(orig_window)
76
+ other_window.close
77
+ expect(@session.windows.size).to eq(1)
78
+ expect(@session.current_window).to eq(orig_window)
79
+ end
80
+
81
+ it 'should make subsequent invocations of other methods raise no_such_window_error if invoked for current window' do
82
+ @session.switch_to_window(other_window)
83
+ expect(@session.current_window).to eq(other_window)
84
+ other_window.close
85
+ expect do
86
+ @session.find(:css, '#some_id')
87
+ end.to raise_error(@session.driver.no_such_window_error)
88
+ @session.switch_to_window(orig_window)
89
+ end
90
+ end
91
+
92
+ describe '#size' do
93
+ def win_size
94
+ @session.evaluate_script('[window.outerWidth || window.innerWidth, window.outerHeight || window.innerHeight]')
95
+ end
96
+
97
+ it 'should return size of whole window', requires: %i[windows js] do
98
+ expect(@session.current_window.size).to eq win_size
99
+ end
100
+
101
+ it 'should switch to original window if invoked not for current window' do
102
+ other_window = @session.window_opened_by do
103
+ @session.find(:css, '#openWindow').click
104
+ end
105
+ sleep 1
106
+ size = @session.within_window(other_window) do
107
+ win_size
108
+ end
109
+ expect(other_window.size).to eq(size)
110
+ expect(@session.current_window).to eq(orig_window)
111
+ end
112
+ end
113
+
114
+ describe '#resize_to' do
115
+ let!(:initial_size) { @session.current_window.size }
116
+
117
+ after do
118
+ @session.current_window.resize_to(*initial_size)
119
+ sleep 1
120
+ end
121
+
122
+ it 'should be able to resize window', requires: %i[windows js] do
123
+ width, height = initial_size
124
+ @session.current_window.resize_to(width - 100, height - 100)
125
+ sleep 1
126
+ expect(@session.current_window.size).to eq([width - 100, height - 100])
127
+ end
128
+
129
+ it 'should stay on current window if invoked not for current window', requires: %i[windows js] do
130
+ other_window = @session.window_opened_by do
131
+ @session.find(:css, '#openWindow').click
132
+ end
133
+
134
+ other_window.resize_to(600, 400)
135
+ expect(@session.current_window).to eq(orig_window)
136
+
137
+ @session.within_window(other_window) do
138
+ expect(@session.current_window.size).to eq([600, 400])
139
+ end
140
+ end
141
+ end
142
+
143
+ describe '#maximize' do
144
+ let! :initial_size do
145
+ @session.current_window.size
146
+ end
147
+
148
+ after do
149
+ @session.current_window.resize_to(*initial_size)
150
+ sleep 0.5
151
+ end
152
+
153
+ it 'should be able to maximize window', requires: %i[windows js] do
154
+ start_width, start_height = 400, 300
155
+ @session.current_window.resize_to(start_width, start_height)
156
+ sleep 0.5
157
+
158
+ @session.current_window.maximize
159
+ sleep 0.5 # The timing on maximize is finicky on Travis -- wait a bit for maximize to occur
160
+
161
+ max_width, max_height = @session.current_window.size
162
+
163
+ # maximize behavior is window manage dependant, so just make sure it increases in size
164
+ expect(max_width).to be > start_width
165
+ expect(max_height).to be > start_height
166
+ end
167
+
168
+ it 'should stay on current window if invoked not for current window', requires: %i[windows js] do
169
+ other_window = @session.window_opened_by do
170
+ @session.find(:css, '#openWindow').click
171
+ end
172
+ other_window.resize_to(400, 300)
173
+ sleep 0.5
174
+ other_window.maximize
175
+ sleep 0.5 # The timing on maximize is finicky on Travis -- wait a bit for maximize to occur
176
+
177
+ expect(@session.current_window).to eq(orig_window)
178
+ # Maximizing the browser affects all tabs so this may not be valid in real browsers
179
+ # expect(@session.current_window.size).to eq(initial_size)
180
+
181
+ ow_width, ow_height = other_window.size
182
+ expect(ow_width).to be > 400
183
+ expect(ow_height).to be > 300
184
+ end
185
+ end
186
+
187
+ describe '#fullscreen' do
188
+ let! :initial_size do
189
+ @session.current_window.size
190
+ end
191
+
192
+ after do
193
+ @session.current_window.resize_to(*initial_size)
194
+ sleep 1
195
+ end
196
+
197
+ it 'should be able to fullscreen the window' do
198
+ expect do
199
+ @session.current_window.fullscreen
200
+ end.not_to raise_error
201
+ end
202
+ end
203
+ end