capybara 2.18.0 → 3.40.0

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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -1
  3. data/History.md +945 -12
  4. data/License.txt +1 -1
  5. data/README.md +264 -90
  6. data/lib/capybara/config.rb +29 -57
  7. data/lib/capybara/cucumber.rb +2 -3
  8. data/lib/capybara/driver/base.rb +35 -18
  9. data/lib/capybara/driver/node.rb +40 -10
  10. data/lib/capybara/dsl.rb +10 -7
  11. data/lib/capybara/helpers.rb +70 -31
  12. data/lib/capybara/minitest/spec.rb +185 -83
  13. data/lib/capybara/minitest.rb +232 -112
  14. data/lib/capybara/node/actions.rb +274 -171
  15. data/lib/capybara/node/base.rb +42 -34
  16. data/lib/capybara/node/document.rb +15 -3
  17. data/lib/capybara/node/document_matchers.rb +19 -21
  18. data/lib/capybara/node/element.rb +362 -135
  19. data/lib/capybara/node/finders.rb +151 -137
  20. data/lib/capybara/node/matchers.rb +394 -209
  21. data/lib/capybara/node/simple.rb +59 -26
  22. data/lib/capybara/node/whitespace_normalizer.rb +81 -0
  23. data/lib/capybara/queries/active_element_query.rb +18 -0
  24. data/lib/capybara/queries/ancestor_query.rb +12 -9
  25. data/lib/capybara/queries/base_query.rb +39 -28
  26. data/lib/capybara/queries/current_path_query.rb +21 -27
  27. data/lib/capybara/queries/match_query.rb +14 -7
  28. data/lib/capybara/queries/selector_query.rb +659 -149
  29. data/lib/capybara/queries/sibling_query.rb +11 -9
  30. data/lib/capybara/queries/style_query.rb +45 -0
  31. data/lib/capybara/queries/text_query.rb +56 -38
  32. data/lib/capybara/queries/title_query.rb +8 -11
  33. data/lib/capybara/rack_test/browser.rb +114 -42
  34. data/lib/capybara/rack_test/css_handlers.rb +6 -4
  35. data/lib/capybara/rack_test/driver.rb +22 -17
  36. data/lib/capybara/rack_test/errors.rb +6 -0
  37. data/lib/capybara/rack_test/form.rb +93 -58
  38. data/lib/capybara/rack_test/node.rb +184 -81
  39. data/lib/capybara/rails.rb +3 -7
  40. data/lib/capybara/registration_container.rb +41 -0
  41. data/lib/capybara/registrations/drivers.rb +42 -0
  42. data/lib/capybara/registrations/patches/puma_ssl.rb +29 -0
  43. data/lib/capybara/registrations/servers.rb +66 -0
  44. data/lib/capybara/result.rb +97 -63
  45. data/lib/capybara/rspec/features.rb +17 -50
  46. data/lib/capybara/rspec/matcher_proxies.rb +52 -15
  47. data/lib/capybara/rspec/matchers/base.rb +113 -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 +69 -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 +43 -0
  59. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  60. data/lib/capybara/rspec/matchers.rb +146 -310
  61. data/lib/capybara/rspec.rb +7 -11
  62. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  63. data/lib/capybara/selector/builders/xpath_builder.rb +71 -0
  64. data/lib/capybara/selector/css.rb +85 -13
  65. data/lib/capybara/selector/definition/button.rb +68 -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 +28 -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 +55 -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/definition.rb +280 -0
  87. data/lib/capybara/selector/filter.rb +2 -17
  88. data/lib/capybara/selector/filter_set.rb +80 -33
  89. data/lib/capybara/selector/filters/base.rb +50 -6
  90. data/lib/capybara/selector/filters/expression_filter.rb +8 -26
  91. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  92. data/lib/capybara/selector/filters/node_filter.rb +16 -12
  93. data/lib/capybara/selector/regexp_disassembler.rb +211 -0
  94. data/lib/capybara/selector/selector.rb +93 -210
  95. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  96. data/lib/capybara/selector.rb +475 -523
  97. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  98. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  99. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  100. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  101. data/lib/capybara/selenium/driver.rb +298 -267
  102. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +117 -0
  103. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +128 -0
  104. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +84 -0
  105. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  106. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  107. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  108. data/lib/capybara/selenium/extensions/find.rb +110 -0
  109. data/lib/capybara/selenium/extensions/html5_drag.rb +229 -0
  110. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  111. data/lib/capybara/selenium/extensions/scroll.rb +76 -0
  112. data/lib/capybara/selenium/node.rb +517 -145
  113. data/lib/capybara/selenium/nodes/chrome_node.rb +125 -0
  114. data/lib/capybara/selenium/nodes/edge_node.rb +110 -0
  115. data/lib/capybara/selenium/nodes/firefox_node.rb +136 -0
  116. data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
  117. data/lib/capybara/selenium/nodes/safari_node.rb +118 -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 +80 -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 +59 -67
  127. data/lib/capybara/session/config.rb +81 -67
  128. data/lib/capybara/session/matchers.rb +28 -20
  129. data/lib/capybara/session.rb +337 -365
  130. data/lib/capybara/spec/public/jquery.js +5 -5
  131. data/lib/capybara/spec/public/offset.js +6 -0
  132. data/lib/capybara/spec/public/test.js +151 -12
  133. data/lib/capybara/spec/session/accept_alert_spec.rb +12 -11
  134. data/lib/capybara/spec/session/accept_confirm_spec.rb +6 -5
  135. data/lib/capybara/spec/session/accept_prompt_spec.rb +10 -10
  136. data/lib/capybara/spec/session/active_element_spec.rb +31 -0
  137. data/lib/capybara/spec/session/all_spec.rb +161 -57
  138. data/lib/capybara/spec/session/ancestor_spec.rb +27 -24
  139. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +68 -38
  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.rb → assert_title_spec.rb} +22 -12
  145. data/lib/capybara/spec/session/attach_file_spec.rb +144 -69
  146. data/lib/capybara/spec/session/body_spec.rb +12 -13
  147. data/lib/capybara/spec/session/check_spec.rb +117 -55
  148. data/lib/capybara/spec/session/choose_spec.rb +64 -31
  149. data/lib/capybara/spec/session/click_button_spec.rb +231 -173
  150. data/lib/capybara/spec/session/click_link_or_button_spec.rb +55 -35
  151. data/lib/capybara/spec/session/click_link_spec.rb +93 -58
  152. data/lib/capybara/spec/session/current_scope_spec.rb +12 -11
  153. data/lib/capybara/spec/session/current_url_spec.rb +57 -39
  154. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +4 -4
  155. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +3 -2
  156. data/lib/capybara/spec/session/element/{assert_match_selector.rb → assert_match_selector_spec.rb} +11 -9
  157. data/lib/capybara/spec/session/element/match_css_spec.rb +18 -10
  158. data/lib/capybara/spec/session/element/match_xpath_spec.rb +9 -7
  159. data/lib/capybara/spec/session/element/matches_selector_spec.rb +71 -57
  160. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +8 -7
  161. data/lib/capybara/spec/session/evaluate_script_spec.rb +29 -8
  162. data/lib/capybara/spec/session/execute_script_spec.rb +10 -8
  163. data/lib/capybara/spec/session/fill_in_spec.rb +134 -43
  164. data/lib/capybara/spec/session/find_button_spec.rb +25 -24
  165. data/lib/capybara/spec/session/find_by_id_spec.rb +10 -9
  166. data/lib/capybara/spec/session/find_field_spec.rb +37 -41
  167. data/lib/capybara/spec/session/find_link_spec.rb +46 -17
  168. data/lib/capybara/spec/session/find_spec.rb +260 -145
  169. data/lib/capybara/spec/session/first_spec.rb +80 -52
  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 +33 -20
  173. data/lib/capybara/spec/session/frame/within_frame_spec.rb +52 -32
  174. data/lib/capybara/spec/session/go_back_spec.rb +2 -1
  175. data/lib/capybara/spec/session/go_forward_spec.rb +2 -1
  176. data/lib/capybara/spec/session/has_all_selectors_spec.rb +31 -31
  177. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  178. data/lib/capybara/spec/session/has_any_selectors_spec.rb +29 -0
  179. data/lib/capybara/spec/session/has_button_spec.rb +100 -13
  180. data/lib/capybara/spec/session/has_css_spec.rb +272 -137
  181. data/lib/capybara/spec/session/has_current_path_spec.rb +60 -61
  182. data/lib/capybara/spec/session/has_element_spec.rb +47 -0
  183. data/lib/capybara/spec/session/has_field_spec.rb +139 -59
  184. data/lib/capybara/spec/session/has_link_spec.rb +47 -6
  185. data/lib/capybara/spec/session/has_none_selectors_spec.rb +42 -40
  186. data/lib/capybara/spec/session/has_select_spec.rb +107 -72
  187. data/lib/capybara/spec/session/has_selector_spec.rb +120 -71
  188. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  189. data/lib/capybara/spec/session/has_table_spec.rb +183 -5
  190. data/lib/capybara/spec/session/has_text_spec.rb +106 -62
  191. data/lib/capybara/spec/session/has_title_spec.rb +20 -14
  192. data/lib/capybara/spec/session/has_xpath_spec.rb +57 -38
  193. data/lib/capybara/spec/session/{headers.rb → headers_spec.rb} +3 -2
  194. data/lib/capybara/spec/session/html_spec.rb +14 -6
  195. data/lib/capybara/spec/session/matches_style_spec.rb +37 -0
  196. data/lib/capybara/spec/session/node_spec.rb +1024 -153
  197. data/lib/capybara/spec/session/node_wrapper_spec.rb +39 -0
  198. data/lib/capybara/spec/session/refresh_spec.rb +12 -6
  199. data/lib/capybara/spec/session/reset_session_spec.rb +82 -35
  200. data/lib/capybara/spec/session/{response_code.rb → response_code_spec.rb} +2 -1
  201. data/lib/capybara/spec/session/save_and_open_page_spec.rb +3 -2
  202. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +8 -12
  203. data/lib/capybara/spec/session/save_page_spec.rb +42 -55
  204. data/lib/capybara/spec/session/save_screenshot_spec.rb +16 -14
  205. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  206. data/lib/capybara/spec/session/scroll_spec.rb +119 -0
  207. data/lib/capybara/spec/session/select_spec.rb +107 -81
  208. data/lib/capybara/spec/session/selectors_spec.rb +52 -19
  209. data/lib/capybara/spec/session/sibling_spec.rb +10 -10
  210. data/lib/capybara/spec/session/text_spec.rb +37 -21
  211. data/lib/capybara/spec/session/title_spec.rb +17 -5
  212. data/lib/capybara/spec/session/uncheck_spec.rb +43 -23
  213. data/lib/capybara/spec/session/unselect_spec.rb +39 -38
  214. data/lib/capybara/spec/session/visit_spec.rb +85 -53
  215. data/lib/capybara/spec/session/window/become_closed_spec.rb +24 -20
  216. data/lib/capybara/spec/session/window/current_window_spec.rb +5 -3
  217. data/lib/capybara/spec/session/window/open_new_window_spec.rb +5 -3
  218. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +27 -22
  219. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +12 -6
  220. data/lib/capybara/spec/session/window/window_spec.rb +97 -63
  221. data/lib/capybara/spec/session/window/windows_spec.rb +12 -10
  222. data/lib/capybara/spec/session/window/within_window_spec.rb +31 -86
  223. data/lib/capybara/spec/session/within_spec.rb +83 -44
  224. data/lib/capybara/spec/spec_helper.rb +54 -44
  225. data/lib/capybara/spec/test_app.rb +158 -43
  226. data/lib/capybara/spec/views/animated.erb +49 -0
  227. data/lib/capybara/spec/views/form.erb +163 -42
  228. data/lib/capybara/spec/views/frame_child.erb +4 -3
  229. data/lib/capybara/spec/views/frame_one.erb +2 -1
  230. data/lib/capybara/spec/views/frame_parent.erb +1 -1
  231. data/lib/capybara/spec/views/frame_two.erb +1 -1
  232. data/lib/capybara/spec/views/initial_alert.erb +2 -1
  233. data/lib/capybara/spec/views/layout.erb +10 -0
  234. data/lib/capybara/spec/views/obscured.erb +47 -0
  235. data/lib/capybara/spec/views/offset.erb +33 -0
  236. data/lib/capybara/spec/views/path.erb +2 -2
  237. data/lib/capybara/spec/views/popup_one.erb +1 -1
  238. data/lib/capybara/spec/views/popup_two.erb +1 -1
  239. data/lib/capybara/spec/views/react.erb +45 -0
  240. data/lib/capybara/spec/views/scroll.erb +21 -0
  241. data/lib/capybara/spec/views/spatial.erb +31 -0
  242. data/lib/capybara/spec/views/tables.erb +68 -1
  243. data/lib/capybara/spec/views/with_animation.erb +81 -0
  244. data/lib/capybara/spec/views/with_base_tag.erb +2 -2
  245. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  246. data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
  247. data/lib/capybara/spec/views/with_hover.erb +3 -2
  248. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  249. data/lib/capybara/spec/views/with_html.erb +69 -12
  250. data/lib/capybara/spec/views/with_html5_svg.erb +20 -0
  251. data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
  252. data/lib/capybara/spec/views/with_js.erb +30 -5
  253. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  254. data/lib/capybara/spec/views/with_namespace.erb +21 -0
  255. data/lib/capybara/spec/views/with_scope.erb +2 -2
  256. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  257. data/lib/capybara/spec/views/with_shadow.erb +31 -0
  258. data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
  259. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  260. data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
  261. data/lib/capybara/spec/views/with_windows.erb +1 -1
  262. data/lib/capybara/spec/views/within_frames.erb +5 -2
  263. data/lib/capybara/version.rb +2 -1
  264. data/lib/capybara/window.rb +36 -34
  265. data/lib/capybara.rb +134 -107
  266. data/spec/basic_node_spec.rb +60 -34
  267. data/spec/capybara_spec.rb +63 -88
  268. data/spec/counter_spec.rb +35 -0
  269. data/spec/css_builder_spec.rb +101 -0
  270. data/spec/css_splitter_spec.rb +38 -0
  271. data/spec/dsl_spec.rb +85 -64
  272. data/spec/filter_set_spec.rb +27 -9
  273. data/spec/fixtures/certificate.pem +25 -0
  274. data/spec/fixtures/key.pem +27 -0
  275. data/spec/fixtures/selenium_driver_rspec_failure.rb +6 -5
  276. data/spec/fixtures/selenium_driver_rspec_success.rb +6 -5
  277. data/spec/minitest_spec.rb +52 -7
  278. data/spec/minitest_spec_spec.rb +94 -63
  279. data/spec/per_session_config_spec.rb +14 -13
  280. data/spec/rack_test_spec.rb +194 -125
  281. data/spec/regexp_dissassembler_spec.rb +250 -0
  282. data/spec/result_spec.rb +111 -50
  283. data/spec/rspec/features_spec.rb +37 -31
  284. data/spec/rspec/scenarios_spec.rb +10 -8
  285. data/spec/rspec/shared_spec_matchers.rb +473 -422
  286. data/spec/rspec/views_spec.rb +5 -3
  287. data/spec/rspec_matchers_spec.rb +52 -11
  288. data/spec/rspec_spec.rb +109 -89
  289. data/spec/sauce_spec_chrome.rb +43 -0
  290. data/spec/selector_spec.rb +397 -68
  291. data/spec/selenium_spec_chrome.rb +187 -40
  292. data/spec/selenium_spec_chrome_remote.rb +96 -0
  293. data/spec/selenium_spec_edge.rb +60 -0
  294. data/spec/selenium_spec_firefox.rb +201 -41
  295. data/spec/selenium_spec_firefox_remote.rb +94 -0
  296. data/spec/selenium_spec_ie.rb +149 -0
  297. data/spec/selenium_spec_safari.rb +162 -0
  298. data/spec/server_spec.rb +213 -102
  299. data/spec/session_spec.rb +53 -16
  300. data/spec/shared_selenium_node.rb +79 -0
  301. data/spec/shared_selenium_session.rb +473 -122
  302. data/spec/spec_helper.rb +126 -7
  303. data/spec/whitespace_normalizer_spec.rb +54 -0
  304. data/spec/xpath_builder_spec.rb +93 -0
  305. metadata +355 -73
  306. data/.yard/templates_custom/default/class/html/selectors.erb +0 -38
  307. data/.yard/templates_custom/default/class/html/setup.rb +0 -17
  308. data/.yard/yard_extensions.rb +0 -78
  309. data/lib/capybara/query.rb +0 -7
  310. data/lib/capybara/rspec/compound.rb +0 -95
  311. data/lib/capybara/spec/session/assert_current_path.rb +0 -72
  312. data/lib/capybara/spec/session/assert_selector.rb +0 -148
  313. data/lib/capybara/spec/session/assert_text.rb +0 -234
  314. data/lib/capybara/spec/session/source_spec.rb +0 -0
  315. data/lib/capybara/spec/views/with_title.erb +0 -5
  316. data/spec/selenium_spec_marionette.rb +0 -127
@@ -1,13 +1,14 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#visit' do
3
- it "should fetch a response from the driver with a relative url" do
4
+ it 'should fetch a response from the driver with a relative url' do
4
5
  @session.visit('/')
5
6
  expect(@session).to have_content('Hello world!')
6
7
  @session.visit('/foo')
7
8
  expect(@session).to have_content('Another World')
8
9
  end
9
10
 
10
- it "should fetch a response from the driver with an absolute url with a port" do
11
+ it 'should fetch a response from the driver with an absolute url with a port' do
11
12
  # Preparation
12
13
  @session.visit('/')
13
14
  root_uri = URI.parse(@session.current_url)
@@ -27,34 +28,40 @@ Capybara::SpecHelper.spec '#visit' do
27
28
  expect(@session).to have_content('Hello world!')
28
29
  end
29
30
 
30
- it "raises any errors caught inside the server", requires: [:server] do
31
- quietly { @session.visit("/error") }
31
+ it 'should fetch a response when sequentially visiting same destination with a target' do
32
+ @session.visit('/form')
33
+ expect(@session).to have_css('#form_title')
34
+ @session.visit('/form#form_title')
35
+ expect(@session).to have_css('#form_title')
36
+ end
37
+
38
+ it 'raises any errors caught inside the server', requires: [:server] do
39
+ quietly { @session.visit('/error') }
32
40
  expect do
33
- @session.visit("/")
41
+ @session.visit('/')
34
42
  end.to raise_error(TestApp::TestAppError)
35
43
  end
36
44
 
37
- it "should be able to open non-http url", requires: [:about_scheme] do
38
- @session.visit("about:blank")
39
- @session.assert_no_selector :xpath, "/html/body/*"
45
+ it 'should be able to open non-http url', requires: [:about_scheme] do
46
+ @session.visit('about:blank')
47
+ @session.assert_no_selector :xpath, '/html/body/*'
40
48
  end
41
49
 
42
- context "when Capybara.always_include_port is true" do
43
-
50
+ context 'when Capybara.always_include_port is true' do
44
51
  let(:root_uri) do
45
52
  @session.visit('/')
46
53
  URI.parse(@session.current_url)
47
54
  end
48
55
 
49
- before(:each) do
56
+ before do
50
57
  Capybara.always_include_port = true
51
58
  end
52
59
 
53
- after(:each) do
60
+ after do
54
61
  Capybara.always_include_port = false
55
62
  end
56
63
 
57
- it "should fetch a response from the driver with an absolute url without a port" do
64
+ it 'should fetch a response from the driver with an absolute url without a port' do
58
65
  @session.visit("http://#{root_uri.host}/")
59
66
  expect(URI.parse(@session.current_url).port).to eq(root_uri.port)
60
67
  expect(@session).to have_content('Hello world!')
@@ -64,129 +71,154 @@ Capybara::SpecHelper.spec '#visit' do
64
71
  expect(@session).to have_content('Another World')
65
72
  end
66
73
 
67
- it "should add the server port to a visited url if no port specified", requires: [:server] do
68
- expect(@session.driver).to receive(:visit).with("http://www.example.com:#{@session.server.port}")
69
- @session.visit("http://www.example.com")
74
+ it 'should add the server port to a visited url if no port specified', requires: [:server] do
75
+ allow(@session.driver).to receive(:visit)
76
+ @session.visit('http://www.example.com')
77
+ expect(@session.driver).to have_received(:visit).with("http://www.example.com:#{@session.server.port}")
70
78
  end
71
79
 
72
- it "should not override the visit specified port even if default for scheme", requires: [:server] do
73
- expect(@session.driver).to receive(:visit).with("http://www.example.com:80")
80
+ it 'should not override the visit specified port even if default for scheme', requires: [:server] do
81
+ allow(@session.driver).to receive(:visit)
74
82
  @session.visit('http://www.example.com:80')
83
+ expect(@session.driver).to have_received(:visit).with('http://www.example.com:80')
75
84
  end
76
85
 
77
- it "should give preference to app_host port if specified", requires: [:server] do
78
- Capybara.app_host = "http://www.example.com:6666"
79
- expect(@session.driver).to receive(:visit).with("http://www.example.com:6666/random")
86
+ it 'should give preference to app_host port if specified', requires: [:server] do
87
+ allow(@session.driver).to receive(:visit)
88
+ Capybara.app_host = 'http://www.example.com:6666'
80
89
  @session.visit('/random')
90
+ expect(@session.driver).to have_received(:visit).with('http://www.example.com:6666/random')
81
91
  end
82
92
 
83
93
  it "shouldn't override port if no server", requires: [:server] do
84
94
  session = Capybara::Session.new(@session.mode, nil)
85
- expect(session.driver).to receive(:visit).with("http://www.google.com")
86
- session.visit("http://www.google.com")
95
+ allow(session.driver).to receive(:visit)
96
+ session.visit('http://www.google.com')
97
+ expect(session.driver).to have_received(:visit).with('http://www.google.com')
87
98
  end
88
99
 
89
100
  it "shouldn't override port if no server but app_host is set", requires: [:server] do
90
101
  session = Capybara::Session.new(@session.mode, nil)
91
- Capybara.app_host = "http://www.example.com:6666"
92
- expect(session.driver).to receive(:visit).with("http://www.google.com")
93
- session.visit("http://www.google.com")
102
+ Capybara.app_host = 'http://www.example.com:6666'
103
+ allow(session.driver).to receive(:visit)
104
+ session.visit('http://www.google.com')
105
+ expect(session.driver).to have_received(:visit).with('http://www.google.com')
94
106
  end
95
107
  end
96
108
 
97
- context "when Capybara.always_include_port is false" do
98
- before(:each) do
109
+ context 'when Capybara.always_include_port is false' do
110
+ before do
99
111
  Capybara.always_include_port = false
100
112
  end
101
113
 
102
114
  it "shouldn't overwrite port if app_host is set", requires: [:server] do
103
115
  session = Capybara::Session.new(@session.mode, nil)
104
- Capybara.app_host = "http://www.example.com:6666"
105
- expect(session.driver).to receive(:visit).with("http://www.google.com")
106
- session.visit("http://www.google.com")
116
+ Capybara.app_host = 'http://www.example.com:6666'
117
+ allow(session.driver).to receive(:visit)
118
+ session.visit('http://www.google.com')
119
+ expect(session.driver).to have_received(:visit).with('http://www.google.com')
107
120
  end
108
121
 
109
122
  it "shouldn't overwrite port if port specfified", requires: [:server] do
110
123
  session = Capybara::Session.new(@session.mode, nil)
111
- Capybara.app_host = "http://www.example.com:6666"
112
- expect(session.driver).to receive(:visit).with("http://www.google.com:99")
113
- session.visit("http://www.google.com:99")
124
+ Capybara.app_host = 'http://www.example.com:6666'
125
+ allow(session.driver).to receive(:visit)
126
+ session.visit('http://www.google.com:99')
127
+ expect(session.driver).to have_received(:visit).with('http://www.google.com:99')
114
128
  end
115
129
  end
116
130
 
117
-
118
- context "without a server", requires: [:server] do
119
- it "should respect `app_host`" do
131
+ context 'without a server', requires: [:server] do
132
+ it 'should respect `app_host`' do
120
133
  serverless_session = Capybara::Session.new(@session.mode, nil)
121
134
  Capybara.app_host = "http://#{@session.server.host}:#{@session.server.port}"
122
- serverless_session.visit("/foo")
123
- expect(serverless_session).to have_content("Another World")
135
+ serverless_session.visit('/foo')
136
+ expect(serverless_session).to have_content('Another World')
124
137
  end
125
138
 
126
- it "should visit a fully qualified URL" do
139
+ it 'should visit a fully qualified URL' do
127
140
  serverless_session = Capybara::Session.new(@session.mode, nil)
128
141
  serverless_session.visit("http://#{@session.server.host}:#{@session.server.port}/foo")
129
- expect(serverless_session).to have_content("Another World")
142
+ expect(serverless_session).to have_content('Another World')
130
143
  end
131
144
  end
132
145
 
133
- context "with Capybara.app_host set" do
134
- it "should override server", requires: [:server] do
146
+ context 'with Capybara.app_host set' do
147
+ it 'should override server', requires: [:server] do
135
148
  another_session = Capybara::Session.new(@session.mode, @session.app.dup)
136
149
  Capybara.app_host = "http://#{@session.server.host}:#{@session.server.port}"
137
150
  another_session.visit('/foo')
138
- expect(another_session).to have_content("Another World")
151
+ expect(another_session).to have_content('Another World')
139
152
  expect(another_session.current_url).to start_with(Capybara.app_host)
140
153
  expect(URI.parse(another_session.current_url).port).not_to eq another_session.server.port
141
154
  expect(URI.parse(another_session.current_url).port).to eq @session.server.port
142
155
  end
143
156
 
144
- it "should append relative path", requires: [:server] do
157
+ it 'should append relative path', requires: [:server] do
145
158
  Capybara.app_host = "http://#{@session.server.host}:#{@session.server.port}/redirect/0"
146
159
  @session.visit('/times')
147
160
  expect(@session).to have_content('redirection complete')
148
161
  end
149
162
 
150
- it "should work if `app_host` has a trailing /", requires: [:server] do
163
+ it 'should work if `app_host` has a trailing /', requires: [:server] do
151
164
  Capybara.app_host = "http://#{@session.server.host}:#{@session.server.port}/"
152
165
  @session.visit('/')
153
166
  expect(@session).to have_content('Hello world!')
154
167
  end
155
168
  end
156
169
 
157
- it "should send no referer when visiting a page" do
170
+ it 'should send no referer when visiting a page' do
158
171
  @session.visit '/get_referer'
159
172
  expect(@session).to have_content 'No referer'
160
173
  end
161
174
 
162
- it "should send no referer when visiting a second page" do
175
+ it 'should send no referer when visiting a second page' do
163
176
  @session.visit '/get_referer'
164
177
  @session.visit '/get_referer'
165
178
  expect(@session).to have_content 'No referer'
166
179
  end
167
180
 
168
- it "should send a referer when following a link" do
181
+ it 'should send a referer when following a link' do
169
182
  @session.visit '/referer_base'
170
183
  @session.find('//a[@href="/get_referer"]').click
171
184
  expect(@session).to have_content %r{http://.*/referer_base}
172
185
  end
173
186
 
174
- it "should preserve the original referer URL when following a redirect" do
187
+ it 'should preserve the original referer URL when following a redirect' do
175
188
  @session.visit('/referer_base')
176
189
  @session.find('//a[@href="/redirect_to_get_referer"]').click
177
190
  expect(@session).to have_content %r{http://.*/referer_base}
178
191
  end
179
192
 
180
- it "should send a referer when submitting a form" do
193
+ it 'should send a referer when submitting a form' do
181
194
  @session.visit '/referer_base'
182
195
  @session.find('//input').click
183
196
  expect(@session).to have_content %r{http://.*/referer_base}
184
197
  end
185
198
 
186
- it "can set cookie if a blank path is specified" do
187
- @session.visit("")
199
+ it 'can set cookie if a blank path is specified' do
200
+ @session.visit('')
188
201
  @session.visit('/get_cookie')
189
202
  expect(@session).to have_content('root cookie')
190
203
  end
191
204
 
205
+ context 'with base element' do
206
+ it 'should use base href with relative links' do
207
+ @session.visit('/base/with_base')
208
+ @session.click_link('Title page')
209
+ expect(@session).to have_current_path('/with_title')
210
+ end
211
+
212
+ it 'should use base href with bare queries' do
213
+ @session.visit('/base/with_base')
214
+ @session.click_link('Bare query')
215
+ expect(@session).to have_current_path('/?a=3')
216
+ end
217
+
218
+ it 'should not use the base href with a new visit call' do
219
+ @session.visit('/base/with_other_base')
220
+ @session.visit('with_html')
221
+ expect(@session).to have_current_path('/with_html')
222
+ end
223
+ end
192
224
  end
@@ -1,37 +1,41 @@
1
1
  # frozen_string_literal: true
2
- Capybara::SpecHelper.spec '#become_closed', requires: [:windows, :js] do
3
- before(:each) do
4
- @window = @session.current_window
5
- @session.visit('/with_windows')
6
- @other_window = @session.window_opened_by do
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
7
  @session.find(:css, '#openWindow').click
8
8
  end
9
9
  end
10
10
 
11
- after(:each) do
11
+ before do
12
+ @session.visit('/with_windows')
13
+ end
14
+
15
+ after do
12
16
  @session.document.synchronize(5, errors: [Capybara::CapybaraError]) do
13
17
  raise Capybara::CapybaraError if @session.windows.size != 1
14
18
  end
15
- @session.switch_to_window(@window)
19
+ @session.switch_to_window(window)
16
20
  end
17
21
 
18
22
  context 'with :wait option' do
19
23
  it 'should wait if value of :wait is more than timeout' do
20
- @session.within_window @other_window do
24
+ @session.within_window other_window do
21
25
  @session.execute_script('setTimeout(function(){ window.close(); }, 500);')
22
26
  end
23
27
  Capybara.using_wait_time 0.1 do
24
- expect(@other_window).to become_closed(wait: 5)
28
+ expect(other_window).to become_closed(wait: 5)
25
29
  end
26
30
  end
27
31
 
28
32
  it 'should raise error if value of :wait is less than timeout' do
29
- @session.within_window @other_window do
33
+ @session.within_window other_window do
30
34
  @session.execute_script('setTimeout(function(){ window.close(); }, 1000);')
31
35
  end
32
36
  Capybara.using_wait_time 2 do
33
37
  expect do
34
- expect(@other_window).to become_closed(wait: 0.2)
38
+ expect(other_window).to become_closed(wait: 0.2)
35
39
  end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\Aexpected #<Window @handle=".+"> to become closed after 0.2 seconds\Z/)
36
40
  end
37
41
  end
@@ -39,21 +43,21 @@ Capybara::SpecHelper.spec '#become_closed', requires: [:windows, :js] do
39
43
 
40
44
  context 'without :wait option' do
41
45
  it 'should wait if value of default_max_wait_time is more than timeout' do
42
- @session.within_window @other_window do
46
+ @session.within_window other_window do
43
47
  @session.execute_script('setTimeout(function(){ window.close(); }, 500);')
44
48
  end
45
49
  Capybara.using_wait_time 5 do
46
- expect(@other_window).to become_closed
50
+ expect(other_window).to become_closed
47
51
  end
48
52
  end
49
53
 
50
54
  it 'should raise error if value of default_max_wait_time is less than timeout' do
51
- @session.within_window @other_window do
55
+ @session.within_window other_window do
52
56
  @session.execute_script('setTimeout(function(){ window.close(); }, 900);')
53
57
  end
54
58
  Capybara.using_wait_time 0.4 do
55
59
  expect do
56
- expect(@other_window).to become_closed
60
+ expect(other_window).to become_closed
57
61
  end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\Aexpected #<Window @handle=".+"> to become closed after 0.4 seconds\Z/)
58
62
  end
59
63
  end
@@ -61,23 +65,23 @@ Capybara::SpecHelper.spec '#become_closed', requires: [:windows, :js] do
61
65
 
62
66
  context 'with not_to' do
63
67
  it "should not raise error if window doesn't close before default_max_wait_time" do
64
- @session.within_window @other_window do
68
+ @session.within_window other_window do
65
69
  @session.execute_script('setTimeout(function(){ window.close(); }, 1000);')
66
70
  end
67
71
  Capybara.using_wait_time 0.3 do
68
72
  expect do
69
- expect(@other_window).not_to become_closed
70
- end
73
+ expect(other_window).not_to become_closed
74
+ end.not_to raise_error
71
75
  end
72
76
  end
73
77
 
74
78
  it 'should raise error if window closes before default_max_wait_time' do
75
- @session.within_window @other_window do
79
+ @session.within_window other_window do
76
80
  @session.execute_script('setTimeout(function(){ window.close(); }, 700);')
77
81
  end
78
82
  Capybara.using_wait_time 3.1 do
79
83
  expect do
80
- expect(@other_window).not_to become_closed
84
+ expect(other_window).not_to become_closed
81
85
  end.to raise_error(RSpec::Expectations::ExpectationNotMetError, /\Aexpected #<Window @handle=".+"> not to become closed after 3.1 seconds\Z/)
82
86
  end
83
87
  end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#current_window', requires: [:windows] do
3
- before(:each) do
4
+ before do
4
5
  @window = @session.current_window
5
6
  @session.visit('/with_windows')
6
7
  end
7
- after(:each) do
8
+
9
+ after do
8
10
  (@session.windows - [@window]).each do |w|
9
11
  @session.switch_to_window w
10
12
  w.close
@@ -16,7 +18,7 @@ Capybara::SpecHelper.spec '#current_window', requires: [:windows] do
16
18
  expect(@session.current_window).to be_instance_of(Capybara::Window)
17
19
  end
18
20
 
19
- it "should be modified by switching to another window" do
21
+ it 'should be modified by switching to another window' do
20
22
  window = @session.window_opened_by { @session.find(:css, '#openWindow').click }
21
23
 
22
24
  expect do
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  Capybara::SpecHelper.spec '#open_new_window', requires: [:windows] do
3
- before(:each) do
4
+ before do
4
5
  @window = @session.current_window
5
6
  @session.visit('/with_windows')
6
7
  end
7
- after(:each) do
8
+
9
+ after do
8
10
  (@session.windows - [@window]).each do |w|
9
11
  @session.switch_to_window w
10
12
  w.close
@@ -15,7 +17,7 @@ Capybara::SpecHelper.spec '#open_new_window', requires: [:windows] do
15
17
  it 'should open new window with blank url and title' do
16
18
  window = @session.open_new_window
17
19
  @session.switch_to_window(window)
18
- expect(['', 'about:blank']).to include(@session.title)
20
+ expect(@session.title).to satisfy('be a blank title') { |title| ['', 'about:blank'].include? title }
19
21
  expect(@session.current_url).to eq('about:blank')
20
22
  end
21
23
 
@@ -1,12 +1,17 @@
1
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
+
2
7
  Capybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do
3
- before(:each) do
8
+ before do
4
9
  @window = @session.current_window
5
10
  @session.visit('/with_windows')
6
- expect(@session).to have_css('body.loaded')
11
+ @session.assert_selector(:css, 'body.loaded')
7
12
  end
8
13
 
9
- after(:each) do
14
+ after do
10
15
  (@session.windows - [@window]).each do |w|
11
16
  @session.switch_to_window w
12
17
  w.close
@@ -14,27 +19,27 @@ Capybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do
14
19
  @session.switch_to_window(@window)
15
20
  end
16
21
 
17
- it "should raise error when invoked without args" do
22
+ it 'should raise error when invoked without args' do
18
23
  expect do
19
24
  @session.switch_to_window
20
- end.to raise_error(ArgumentError, "`switch_to_window`: either window or block should be provided")
25
+ end.to raise_error(ArgumentError, '`switch_to_window`: either window or block should be provided')
21
26
  end
22
27
 
23
- it "should raise error when invoked with window and block" do
28
+ it 'should raise error when invoked with window and block' do
24
29
  expect do
25
30
  @session.switch_to_window(@window) { @session.title == 'Title of the first popup' }
26
- end.to raise_error(ArgumentError, "`switch_to_window` can take either a block or a window, not both")
31
+ end.to raise_error(ArgumentError, '`switch_to_window` can take either a block or a window, not both')
27
32
  end
28
33
 
29
- context "with an instance of Capybara::Window" do
30
- it "should be able to switch to window" do
34
+ context 'with an instance of Capybara::Window' do
35
+ it 'should be able to switch to window' do
31
36
  window = @session.open_new_window
32
37
  expect(@session.title).to eq('With Windows')
33
38
  @session.switch_to_window(window)
34
- expect(['', 'about:blank']).to include(@session.title)
39
+ expect(@session.title).to satisfy('be a blank title') { |title| ['', 'about:blank'].include? title }
35
40
  end
36
41
 
37
- it "should raise error when closed window is passed" do
42
+ it 'should raise error when closed window is passed' do
38
43
  original_window = @session.current_window
39
44
  new_window = @session.open_new_window
40
45
  @session.switch_to_window(new_window)
@@ -46,30 +51,30 @@ Capybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do
46
51
  end
47
52
  end
48
53
 
49
- context "with block" do
50
- before(:each) do
54
+ context 'with block' do
55
+ before do
51
56
  @session.find(:css, '#openTwoWindows').click
52
57
  sleep(1) # wait for the windows to open
53
58
  end
54
59
 
55
- it "should be able to switch to current window" do
60
+ it 'should be able to switch to current window' do
56
61
  @session.switch_to_window { @session.title == 'With Windows' }
57
62
  expect(@session).to have_css('#openTwoWindows')
58
63
  end
59
64
 
60
- it "should find the div in another window" do
65
+ it 'should find the div in another window' do
61
66
  @session.switch_to_window { @session.title == 'Title of popup two' }
62
67
  expect(@session).to have_css('#divInPopupTwo')
63
68
  end
64
69
 
65
- it "should be able to switch multiple times" do
70
+ it 'should be able to switch multiple times' do
66
71
  @session.switch_to_window { @session.title == 'Title of the first popup' }
67
72
  expect(@session).to have_css('#divInPopupOne')
68
73
  @session.switch_to_window { @session.title == 'Title of popup two' }
69
74
  expect(@session).to have_css('#divInPopupTwo')
70
75
  end
71
76
 
72
- it "should return window" do
77
+ it 'should return window' do
73
78
  window = @session.switch_to_window { @session.title == 'Title of popup two' }
74
79
  expect((@session.windows - [@window])).to include(window)
75
80
  end
@@ -90,7 +95,7 @@ Capybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do
90
95
  end.to raise_error(Capybara::ScopeError, /`switch_to_window` is not supposed to be invoked from/)
91
96
  end
92
97
 
93
- it "should allow to be called inside within_window and within_window will still return to original" do
98
+ it 'should allow to be called inside within_window and within_window will still return to original' do
94
99
  other_windows = (@session.windows - [@window])
95
100
  expect(@session.current_window).to eq(@window)
96
101
  @session.within_window other_windows[0] do
@@ -105,11 +110,11 @@ Capybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do
105
110
  original = @session.current_window
106
111
  expect do
107
112
  @session.switch_to_window { @session.title == 'A title' }
108
- end.to raise_error(Capybara::WindowError, "Could not find a window matching block/lambda")
113
+ end.to raise_error(Capybara::WindowError, 'Could not find a window matching block/lambda')
109
114
  expect(@session.current_window).to eq(original)
110
115
  end
111
116
 
112
- it "should switch to original window if error is raised inside block" do
117
+ it 'should switch to original window if error is raised inside block' do
113
118
  original = @session.switch_to_window(@session.windows[1])
114
119
  expect do
115
120
  @session.switch_to_window { raise 'error' }
@@ -118,10 +123,10 @@ Capybara::SpecHelper.spec '#switch_to_window', requires: [:windows] do
118
123
  end
119
124
  end
120
125
 
121
- it "should wait for window to appear" do
126
+ it 'should wait for window to appear' do
122
127
  @session.find(:css, '#openWindowWithTimeout').click
123
128
  expect do
124
- @session.switch_to_window(wait: 5) { @session.title == 'Title of the first popup'}
129
+ @session.switch_to_window(wait: 5) { @session.title == 'Title of the first popup' }
125
130
  end.not_to raise_error
126
131
  end
127
132
  end
@@ -1,11 +1,17 @@
1
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
+
2
7
  Capybara::SpecHelper.spec '#window_opened_by', requires: [:windows] do
3
- before(:each) do
8
+ before do
4
9
  @window = @session.current_window
5
10
  @session.visit('/with_windows')
6
- expect(@session).to have_css('body.loaded')
11
+ @session.assert_selector(:css, 'body.loaded')
7
12
  end
8
- after(:each) do
13
+
14
+ after do
9
15
  (@session.windows - [@window]).each do |w|
10
16
  @session.switch_to_window w
11
17
  w.close
@@ -13,14 +19,14 @@ Capybara::SpecHelper.spec '#window_opened_by', requires: [:windows] do
13
19
  @session.switch_to_window(@window)
14
20
  end
15
21
 
16
- let(:zero_windows_message) { "block passed to #window_opened_by opened 0 windows instead of 1" }
17
- let(:two_windows_message) { "block passed to #window_opened_by opened 2 windows instead of 1" }
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' }
18
24
 
19
25
  context 'with :wait option' do
20
26
  it 'should raise error if value of :wait is less than timeout' do
21
27
  # So large value is used as `driver.window_handles` takes up to 800 ms on Travis
22
28
  Capybara.using_wait_time 2 do
23
- button=@session.find(:css, '#openWindowWithLongerTimeout')
29
+ button = @session.find(:css, '#openWindowWithLongerTimeout')
24
30
  expect do
25
31
  @session.window_opened_by(wait: 0.3) do
26
32
  button.click