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,16 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'sinatra/base'
3
4
  require 'tilt/erb'
4
5
  require 'rack'
5
6
  require 'yaml'
6
7
 
7
8
  class TestApp < Sinatra::Base
8
- class TestAppError < StandardError; end
9
- class TestAppOtherError < StandardError
9
+ class TestAppError < Exception; end # rubocop:disable Lint/InheritException
10
+
11
+ class TestAppOtherError < Exception # rubocop:disable Lint/InheritException
10
12
  def initialize(string1, msg)
13
+ super()
11
14
  @something = string1
12
15
  @message = msg
13
16
  end
@@ -17,11 +20,10 @@ class TestApp < Sinatra::Base
17
20
  set :raise_errors, true
18
21
  set :show_exceptions, false
19
22
 
20
- @@form_post_count = 0
21
23
  # Also check lib/capybara/spec/views/*.erb for pages not listed here
22
24
 
23
25
  get '/' do
24
- response.set_cookie('capybara', { value: 'root cookie', domain: request.host, path: request.path} )
26
+ response.set_cookie('capybara', value: 'root cookie', domain: request.host, path: request.path)
25
27
  'Hello world! <a href="with_html">Relative</a>'
26
28
  end
27
29
 
@@ -33,14 +35,26 @@ class TestApp < Sinatra::Base
33
35
  redirect '/redirect_again'
34
36
  end
35
37
 
38
+ get '/redirect_with_fragment' do
39
+ redirect '/landed#with_fragment'
40
+ end
41
+
36
42
  get '/redirect_again' do
37
43
  redirect '/landed'
38
44
  end
39
45
 
46
+ post '/redirect_307' do
47
+ redirect '/landed', 307
48
+ end
49
+
50
+ post '/redirect_308' do
51
+ redirect '/landed', 308
52
+ end
53
+
40
54
  get '/referer_base' do
41
- '<a href="/get_referer">direct link</a>' +
42
- '<a href="/redirect_to_get_referer">link via redirect</a>' +
43
- '<form action="/get_referer" method="get"><input type="submit"></form>'
55
+ '<a href="/get_referer">direct link</a>' \
56
+ '<a href="/redirect_to_get_referer">link via redirect</a>' \
57
+ '<form action="/get_referer" method="get"><input type="submit"></form>'
44
58
  end
45
59
 
46
60
  get '/redirect_to_get_referer' do
@@ -48,7 +62,7 @@ class TestApp < Sinatra::Base
48
62
  end
49
63
 
50
64
  get '/get_referer' do
51
- request.referer.nil? ? "No referer" : "Got referer: #{request.referer}"
65
+ request.referer.nil? ? 'No referer' : "Got referer: #{request.referer}"
52
66
  end
53
67
 
54
68
  get '/host' do
@@ -58,26 +72,30 @@ class TestApp < Sinatra::Base
58
72
  get '/redirect/:times/times' do
59
73
  times = params[:times].to_i
60
74
  if times.zero?
61
- "redirection complete"
75
+ 'redirection complete'
62
76
  else
63
77
  redirect "/redirect/#{times - 1}/times"
64
78
  end
65
79
  end
66
80
 
67
81
  get '/landed' do
68
- "You landed"
82
+ 'You landed'
83
+ end
84
+
85
+ post '/landed' do
86
+ "You post landed: #{params.dig(:form, 'data')}"
69
87
  end
70
88
 
71
89
  get '/with-quotes' do
72
- %q{"No," he said, "you can't do that."}
90
+ %q("No," he said, "you can't do that.")
73
91
  end
74
92
 
75
93
  get '/form/get' do
76
- '<pre id="results">' + params[:form].to_yaml + '</pre>'
94
+ %(<pre id="results">#{params[:form].to_yaml}</pre>)
77
95
  end
78
96
 
79
97
  post '/relative' do
80
- '<pre id="results">' + params[:form].to_yaml + '</pre>'
98
+ %(<pre id="results">#{params[:form].to_yaml}</pre>)
81
99
  end
82
100
 
83
101
  get '/favicon.ico' do
@@ -88,12 +106,12 @@ class TestApp < Sinatra::Base
88
106
  redirect '/redirect_again'
89
107
  end
90
108
 
91
- delete "/delete" do
92
- "The requested object was deleted"
109
+ delete '/delete' do
110
+ 'The requested object was deleted'
93
111
  end
94
112
 
95
- get "/delete" do
96
- "Not deleted"
113
+ get '/delete' do
114
+ 'Not deleted'
97
115
  end
98
116
 
99
117
  get '/redirect_back' do
@@ -128,11 +146,11 @@ class TestApp < Sinatra::Base
128
146
  end
129
147
 
130
148
  get '/error' do
131
- raise TestAppError, "some error"
149
+ raise TestAppError, 'some error'
132
150
  end
133
151
 
134
152
  get '/other_error' do
135
- raise TestAppOtherError.new("something", "other error")
153
+ raise TestAppOtherError.new('something', 'other error')
136
154
  end
137
155
 
138
156
  get '/load_error' do
@@ -143,48 +161,145 @@ class TestApp < Sinatra::Base
143
161
  erb :with_html, locals: { referrer: request.referrer }
144
162
  end
145
163
 
164
+ get '/with_title' do
165
+ <<-HTML
166
+ <!DOCTYPE html>
167
+ <html lang="en">
168
+ <head>
169
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
170
+ <title>#{params[:title] || 'Test Title'}</title>
171
+ </head>
172
+
173
+ <body>
174
+ <svg><title>abcdefg</title></svg>
175
+ </body>
176
+ </html>
177
+ HTML
178
+ end
179
+
180
+ get '/with_iframe' do
181
+ <<-HTML
182
+ <!DOCTYPE html>
183
+ <html lang="en">
184
+ <head>
185
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
186
+ <title>Test with Iframe</title>
187
+ </head>
188
+
189
+ <body>
190
+ <iframe src="#{params[:url]}" id="#{params[:id]}"></iframe>
191
+ </body>
192
+ </html>
193
+ HTML
194
+ end
195
+
196
+ get '/base/with_base' do
197
+ <<-HTML
198
+ <!DOCTYPE html>
199
+ <html>
200
+ <head>
201
+ <base href="/">
202
+ <title>Origin</title>
203
+ </head>
204
+ <body>
205
+ <a href="with_title">Title page</a>
206
+ <a href="?a=3">Bare query</a>
207
+ </body>
208
+ </html>
209
+ HTML
210
+ end
211
+
212
+ get '/base/with_other_base' do
213
+ <<-HTML
214
+ <!DOCTYPE html>
215
+ <html>
216
+ <head>
217
+ <base href="/base/">
218
+ <title>Origin</title>
219
+ </head>
220
+ <body>
221
+ <a href="with_title">Title page</a>
222
+ <a href="?a=3">Bare query</a>
223
+ </body>
224
+ </html>
225
+ HTML
226
+ end
227
+
228
+ get '/csp' do
229
+ response.headers['Content-Security-Policy'] = "default-src 'none'; connect-src 'self'; base-uri 'none'; font-src 'self'; img-src 'self' data:; object-src 'none'; script-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; style-src 'self' 'nonce-jAviMuMisoTisVXjgLoWdA=='; form-action 'self';"
230
+ <<-HTML
231
+ <!DOCTYPE html>
232
+ <html lang="en">
233
+ <head>
234
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
235
+ <title>CSP</title>
236
+ </head>
237
+
238
+ <body>
239
+ <div>CSP</div>
240
+ </body>
241
+ </html>
242
+ HTML
243
+ end
244
+
245
+ get '/download.csv' do
246
+ content_type 'text/csv'
247
+ 'This, is, comma, separated' \
248
+ 'Thomas, Walpole, was , here'
249
+ end
250
+
251
+ get %r{/apple-touch-.*\.png/} do
252
+ halt(404)
253
+ end
254
+
146
255
  get '/:view' do |view|
147
- erb view.to_sym, locals: { referrer: request.referrer }
256
+ view_template = "#{__dir__}/views/#{view}.erb"
257
+ has_layout = File.exist?(view_template) && File.open(view_template) { |f| f.first.downcase.include?('doctype') }
258
+ erb view.to_sym, locals: { referrer: request.referrer }, layout: !has_layout
148
259
  end
149
260
 
150
261
  post '/form' do
151
- @@form_post_count += 1
152
- '<pre id="results">' + params[:form].merge({"post_count" => @@form_post_count}).to_yaml + '</pre>'
262
+ self.class.form_post_count += 1
263
+ %(
264
+ <pre id="content_type">#{request.content_type}</pre>
265
+ <pre id="results">#{params.fetch(:form, {}).merge('post_count' => self.class.form_post_count).to_yaml}</pre>
266
+ )
153
267
  end
154
268
 
155
269
  post '/upload_empty' do
156
270
  if params[:form][:file].nil?
157
- 'Successfully ignored empty file field.'
271
+ "Successfully ignored empty file field. Content type was #{request.content_type}"
158
272
  else
159
273
  'Something went wrong.'
160
274
  end
161
275
  end
162
276
 
163
277
  post '/upload' do
164
- begin
165
- buffer = []
166
- buffer << "Content-type: #{params[:form][:document][:type]}"
167
- buffer << "File content: #{params[:form][:document][:tempfile].read}"
168
- buffer.join(' | ')
169
- rescue
170
- 'No file uploaded'
171
- end
278
+ buffer = []
279
+ buffer << "Content-type: #{params.dig(:form, :document, :type)}"
280
+ buffer << "File content: #{params.dig(:form, :document, :tempfile).read}"
281
+ buffer.join(' | ')
282
+ rescue StandardError
283
+ 'No file uploaded'
172
284
  end
173
285
 
174
286
  post '/upload_multiple' do
175
- begin
176
- buffer = ["#{params[:form][:multiple_documents].size}"]
177
- params[:form][:multiple_documents].each do |doc|
178
- buffer << "Content-type: #{doc[:type]}"
179
- buffer << "File content: #{doc[:tempfile].read}"
180
- end
181
- buffer.join(' | ')
182
- rescue
183
- 'No files uploaded'
287
+ docs = params.dig(:form, :multiple_documents)
288
+ buffer = [docs.size.to_s]
289
+ docs.each do |doc|
290
+ buffer << "Content-type: #{doc[:type]}"
291
+ buffer << "File content: #{doc[:tempfile].read}"
184
292
  end
293
+ buffer.join(' | ')
294
+ rescue StandardError
295
+ 'No files uploaded'
296
+ end
297
+
298
+ class << self
299
+ attr_accessor :form_post_count
185
300
  end
186
- end
187
301
 
188
- if __FILE__ == $0
189
- Rack::Handler::WEBrick.run TestApp, Port: 8070
302
+ @form_post_count = 0
190
303
  end
304
+
305
+ Rack::Handler::Puma.run TestApp, Port: 8070 if $PROGRAM_NAME == __FILE__
@@ -0,0 +1,49 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
5
+ <title>with_animation</title>
6
+ <script src="/jquery.js" type="text/javascript" charset="utf-8"></script>
7
+ <script>
8
+ $(document).on('contextmenu', function(e){ e.preventDefault(); });
9
+ </script>
10
+ <style>
11
+ div {
12
+ width: 400px;
13
+ height: 400px;
14
+ position: absolute;
15
+ }
16
+ #obscured {
17
+ z-index: 1;
18
+ background-color: red;
19
+ }
20
+ #cover {
21
+ z-index: 2;
22
+ background-color: blue;
23
+ }
24
+ #offscreen {
25
+ top: 2000px;
26
+ left: 2000px;
27
+ background-color: green;
28
+ }
29
+ #offscreen_wrapper {
30
+ top: 2000px;
31
+ left: 2000px;
32
+ overflow-x: scroll;
33
+ background-color: yellow;
34
+ }
35
+ </style>
36
+ </head>
37
+
38
+ <body id="with_animation">
39
+ <div id="obscured">
40
+ <input id="obscured_input"/>
41
+ </div>
42
+ <div id="cover"></div>
43
+ <div id="offscreen_wrapper">
44
+ <div id="offscreen"></div>
45
+ </div>
46
+ </body>
47
+
48
+ <iframe id="frameOne" src="/frame_one"></iframe>
49
+ </html>