capybara 3.8.1 → 3.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/History.md +465 -0
  4. data/License.txt +1 -1
  5. data/README.md +58 -57
  6. data/lib/capybara/config.rb +10 -4
  7. data/lib/capybara/cucumber.rb +1 -1
  8. data/lib/capybara/driver/base.rb +2 -2
  9. data/lib/capybara/driver/node.rb +26 -5
  10. data/lib/capybara/dsl.rb +12 -4
  11. data/lib/capybara/helpers.rb +8 -4
  12. data/lib/capybara/minitest/spec.rb +162 -85
  13. data/lib/capybara/minitest.rb +248 -148
  14. data/lib/capybara/node/actions.rb +149 -96
  15. data/lib/capybara/node/base.rb +27 -10
  16. data/lib/capybara/node/document.rb +12 -0
  17. data/lib/capybara/node/document_matchers.rb +9 -5
  18. data/lib/capybara/node/element.rb +254 -109
  19. data/lib/capybara/node/finders.rb +83 -76
  20. data/lib/capybara/node/matchers.rb +279 -141
  21. data/lib/capybara/node/simple.rb +25 -6
  22. data/lib/capybara/queries/ancestor_query.rb +5 -7
  23. data/lib/capybara/queries/base_query.rb +11 -5
  24. data/lib/capybara/queries/current_path_query.rb +3 -3
  25. data/lib/capybara/queries/match_query.rb +1 -0
  26. data/lib/capybara/queries/selector_query.rb +467 -103
  27. data/lib/capybara/queries/sibling_query.rb +5 -4
  28. data/lib/capybara/queries/style_query.rb +6 -2
  29. data/lib/capybara/queries/text_query.rb +17 -3
  30. data/lib/capybara/queries/title_query.rb +2 -2
  31. data/lib/capybara/rack_test/browser.rb +22 -15
  32. data/lib/capybara/rack_test/driver.rb +10 -1
  33. data/lib/capybara/rack_test/errors.rb +6 -0
  34. data/lib/capybara/rack_test/form.rb +33 -28
  35. data/lib/capybara/rack_test/node.rb +74 -6
  36. data/lib/capybara/registration_container.rb +44 -0
  37. data/lib/capybara/registrations/drivers.rb +36 -0
  38. data/lib/capybara/registrations/patches/puma_ssl.rb +27 -0
  39. data/lib/capybara/registrations/servers.rb +44 -0
  40. data/lib/capybara/result.rb +55 -23
  41. data/lib/capybara/rspec/features.rb +4 -4
  42. data/lib/capybara/rspec/matcher_proxies.rb +36 -15
  43. data/lib/capybara/rspec/matchers/base.rb +111 -0
  44. data/lib/capybara/rspec/matchers/become_closed.rb +33 -0
  45. data/lib/capybara/rspec/matchers/compound.rb +88 -0
  46. data/lib/capybara/rspec/matchers/count_sugar.rb +37 -0
  47. data/lib/capybara/rspec/matchers/have_ancestor.rb +28 -0
  48. data/lib/capybara/rspec/matchers/have_current_path.rb +29 -0
  49. data/lib/capybara/rspec/matchers/have_selector.rb +77 -0
  50. data/lib/capybara/rspec/matchers/have_sibling.rb +27 -0
  51. data/lib/capybara/rspec/matchers/have_text.rb +33 -0
  52. data/lib/capybara/rspec/matchers/have_title.rb +29 -0
  53. data/lib/capybara/rspec/matchers/match_selector.rb +27 -0
  54. data/lib/capybara/rspec/matchers/match_style.rb +38 -0
  55. data/lib/capybara/rspec/matchers/spatial_sugar.rb +39 -0
  56. data/lib/capybara/rspec/matchers.rb +117 -311
  57. data/lib/capybara/selector/builders/css_builder.rb +84 -0
  58. data/lib/capybara/selector/builders/xpath_builder.rb +69 -0
  59. data/lib/capybara/selector/css.rb +17 -15
  60. data/lib/capybara/selector/definition/button.rb +52 -0
  61. data/lib/capybara/selector/definition/checkbox.rb +26 -0
  62. data/lib/capybara/selector/definition/css.rb +10 -0
  63. data/lib/capybara/selector/definition/datalist_input.rb +35 -0
  64. data/lib/capybara/selector/definition/datalist_option.rb +25 -0
  65. data/lib/capybara/selector/definition/element.rb +27 -0
  66. data/lib/capybara/selector/definition/field.rb +40 -0
  67. data/lib/capybara/selector/definition/fieldset.rb +14 -0
  68. data/lib/capybara/selector/definition/file_field.rb +13 -0
  69. data/lib/capybara/selector/definition/fillable_field.rb +33 -0
  70. data/lib/capybara/selector/definition/frame.rb +17 -0
  71. data/lib/capybara/selector/definition/id.rb +6 -0
  72. data/lib/capybara/selector/definition/label.rb +62 -0
  73. data/lib/capybara/selector/definition/link.rb +54 -0
  74. data/lib/capybara/selector/definition/link_or_button.rb +16 -0
  75. data/lib/capybara/selector/definition/option.rb +27 -0
  76. data/lib/capybara/selector/definition/radio_button.rb +27 -0
  77. data/lib/capybara/selector/definition/select.rb +81 -0
  78. data/lib/capybara/selector/definition/table.rb +109 -0
  79. data/lib/capybara/selector/definition/table_row.rb +21 -0
  80. data/lib/capybara/selector/definition/xpath.rb +5 -0
  81. data/lib/capybara/selector/definition.rb +277 -0
  82. data/lib/capybara/selector/filter.rb +1 -0
  83. data/lib/capybara/selector/filter_set.rb +26 -19
  84. data/lib/capybara/selector/filters/base.rb +24 -5
  85. data/lib/capybara/selector/filters/expression_filter.rb +3 -3
  86. data/lib/capybara/selector/filters/locator_filter.rb +29 -0
  87. data/lib/capybara/selector/filters/node_filter.rb +16 -2
  88. data/lib/capybara/selector/regexp_disassembler.rb +214 -0
  89. data/lib/capybara/selector/selector.rb +73 -367
  90. data/lib/capybara/selector/xpath_extensions.rb +17 -0
  91. data/lib/capybara/selector.rb +221 -480
  92. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -0
  93. data/lib/capybara/selenium/atoms/isDisplayed.min.js +1 -0
  94. data/lib/capybara/selenium/atoms/src/getAttribute.js +161 -0
  95. data/lib/capybara/selenium/atoms/src/isDisplayed.js +454 -0
  96. data/lib/capybara/selenium/driver.rb +203 -86
  97. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +88 -14
  98. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +124 -0
  99. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +89 -0
  100. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +26 -0
  101. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +24 -0
  102. data/lib/capybara/selenium/extensions/file_input_click_emulation.rb +34 -0
  103. data/lib/capybara/selenium/extensions/find.rb +110 -0
  104. data/lib/capybara/selenium/extensions/html5_drag.rb +191 -22
  105. data/lib/capybara/selenium/extensions/modifier_keys_stack.rb +28 -0
  106. data/lib/capybara/selenium/extensions/scroll.rb +78 -0
  107. data/lib/capybara/selenium/logger_suppressor.rb +34 -0
  108. data/lib/capybara/selenium/node.rb +298 -93
  109. data/lib/capybara/selenium/nodes/chrome_node.rb +100 -8
  110. data/lib/capybara/selenium/nodes/edge_node.rb +104 -0
  111. data/lib/capybara/selenium/nodes/firefox_node.rb +131 -0
  112. data/lib/capybara/selenium/nodes/ie_node.rb +22 -0
  113. data/lib/capybara/selenium/nodes/safari_node.rb +118 -0
  114. data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
  115. data/lib/capybara/selenium/patches/atoms.rb +18 -0
  116. data/lib/capybara/selenium/patches/is_displayed.rb +16 -0
  117. data/lib/capybara/selenium/patches/logs.rb +45 -0
  118. data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -3
  119. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  120. data/lib/capybara/server/animation_disabler.rb +4 -3
  121. data/lib/capybara/server/checker.rb +6 -2
  122. data/lib/capybara/server/middleware.rb +23 -13
  123. data/lib/capybara/server.rb +30 -7
  124. data/lib/capybara/session/config.rb +14 -10
  125. data/lib/capybara/session/matchers.rb +11 -7
  126. data/lib/capybara/session.rb +152 -111
  127. data/lib/capybara/spec/public/offset.js +6 -0
  128. data/lib/capybara/spec/public/test.js +101 -10
  129. data/lib/capybara/spec/session/all_spec.rb +96 -6
  130. data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
  131. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +29 -0
  132. data/lib/capybara/spec/session/assert_current_path_spec.rb +5 -2
  133. data/lib/capybara/spec/session/assert_selector_spec.rb +0 -10
  134. data/lib/capybara/spec/session/assert_style_spec.rb +4 -4
  135. data/lib/capybara/spec/session/assert_text_spec.rb +9 -5
  136. data/lib/capybara/spec/session/attach_file_spec.rb +63 -36
  137. data/lib/capybara/spec/session/check_spec.rb +10 -4
  138. data/lib/capybara/spec/session/choose_spec.rb +8 -2
  139. data/lib/capybara/spec/session/click_button_spec.rb +117 -61
  140. data/lib/capybara/spec/session/click_link_or_button_spec.rb +16 -0
  141. data/lib/capybara/spec/session/click_link_spec.rb +17 -6
  142. data/lib/capybara/spec/session/element/matches_selector_spec.rb +40 -39
  143. data/lib/capybara/spec/session/evaluate_script_spec.rb +13 -0
  144. data/lib/capybara/spec/session/execute_script_spec.rb +1 -0
  145. data/lib/capybara/spec/session/fill_in_spec.rb +47 -6
  146. data/lib/capybara/spec/session/find_field_spec.rb +1 -1
  147. data/lib/capybara/spec/session/find_spec.rb +74 -4
  148. data/lib/capybara/spec/session/first_spec.rb +1 -1
  149. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +13 -1
  150. data/lib/capybara/spec/session/frame/within_frame_spec.rb +12 -1
  151. data/lib/capybara/spec/session/has_all_selectors_spec.rb +1 -1
  152. data/lib/capybara/spec/session/has_ancestor_spec.rb +46 -0
  153. data/lib/capybara/spec/session/has_any_selectors_spec.rb +25 -0
  154. data/lib/capybara/spec/session/has_button_spec.rb +16 -0
  155. data/lib/capybara/spec/session/has_css_spec.rb +122 -12
  156. data/lib/capybara/spec/session/has_current_path_spec.rb +6 -4
  157. data/lib/capybara/spec/session/has_field_spec.rb +55 -0
  158. data/lib/capybara/spec/session/has_select_spec.rb +34 -6
  159. data/lib/capybara/spec/session/has_selector_spec.rb +11 -4
  160. data/lib/capybara/spec/session/has_sibling_spec.rb +50 -0
  161. data/lib/capybara/spec/session/has_table_spec.rb +166 -0
  162. data/lib/capybara/spec/session/has_text_spec.rb +48 -1
  163. data/lib/capybara/spec/session/has_xpath_spec.rb +17 -0
  164. data/lib/capybara/spec/session/html_spec.rb +7 -0
  165. data/lib/capybara/spec/session/matches_style_spec.rb +35 -0
  166. data/lib/capybara/spec/session/node_spec.rb +643 -18
  167. data/lib/capybara/spec/session/node_wrapper_spec.rb +1 -1
  168. data/lib/capybara/spec/session/refresh_spec.rb +4 -0
  169. data/lib/capybara/spec/session/reset_session_spec.rb +23 -8
  170. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  171. data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
  172. data/lib/capybara/spec/session/scroll_spec.rb +117 -0
  173. data/lib/capybara/spec/session/select_spec.rb +10 -10
  174. data/lib/capybara/spec/session/selectors_spec.rb +36 -5
  175. data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
  176. data/lib/capybara/spec/session/unselect_spec.rb +1 -1
  177. data/lib/capybara/spec/session/window/become_closed_spec.rb +20 -17
  178. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +4 -0
  179. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +4 -0
  180. data/lib/capybara/spec/session/window/window_spec.rb +59 -58
  181. data/lib/capybara/spec/session/window/windows_spec.rb +4 -0
  182. data/lib/capybara/spec/session/within_spec.rb +23 -0
  183. data/lib/capybara/spec/spec_helper.rb +16 -6
  184. data/lib/capybara/spec/test_app.rb +28 -23
  185. data/lib/capybara/spec/views/animated.erb +49 -0
  186. data/lib/capybara/spec/views/form.erb +48 -7
  187. data/lib/capybara/spec/views/frame_child.erb +3 -2
  188. data/lib/capybara/spec/views/frame_one.erb +1 -0
  189. data/lib/capybara/spec/views/obscured.erb +47 -0
  190. data/lib/capybara/spec/views/offset.erb +32 -0
  191. data/lib/capybara/spec/views/react.erb +45 -0
  192. data/lib/capybara/spec/views/scroll.erb +20 -0
  193. data/lib/capybara/spec/views/spatial.erb +31 -0
  194. data/lib/capybara/spec/views/tables.erb +67 -0
  195. data/lib/capybara/spec/views/with_animation.erb +29 -1
  196. data/lib/capybara/spec/views/with_dragula.erb +24 -0
  197. data/lib/capybara/spec/views/with_hover.erb +1 -0
  198. data/lib/capybara/spec/views/with_hover1.erb +10 -0
  199. data/lib/capybara/spec/views/with_html.erb +32 -6
  200. data/lib/capybara/spec/views/with_js.erb +3 -1
  201. data/lib/capybara/spec/views/with_jstree.erb +26 -0
  202. data/lib/capybara/spec/views/with_scope_other.erb +6 -0
  203. data/lib/capybara/spec/views/with_sortable_js.erb +21 -0
  204. data/lib/capybara/version.rb +1 -1
  205. data/lib/capybara/window.rb +11 -11
  206. data/lib/capybara.rb +118 -111
  207. data/spec/basic_node_spec.rb +14 -3
  208. data/spec/capybara_spec.rb +29 -29
  209. data/spec/css_builder_spec.rb +101 -0
  210. data/spec/dsl_spec.rb +46 -21
  211. data/spec/filter_set_spec.rb +5 -5
  212. data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
  213. data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
  214. data/spec/minitest_spec.rb +18 -4
  215. data/spec/minitest_spec_spec.rb +59 -44
  216. data/spec/rack_test_spec.rb +117 -89
  217. data/spec/regexp_dissassembler_spec.rb +250 -0
  218. data/spec/result_spec.rb +51 -49
  219. data/spec/rspec/features_spec.rb +3 -0
  220. data/spec/rspec/shared_spec_matchers.rb +112 -97
  221. data/spec/rspec_spec.rb +35 -17
  222. data/spec/sauce_spec_chrome.rb +43 -0
  223. data/spec/selector_spec.rb +244 -28
  224. data/spec/selenium_spec_chrome.rb +125 -54
  225. data/spec/selenium_spec_chrome_remote.rb +26 -12
  226. data/spec/selenium_spec_edge.rb +23 -8
  227. data/spec/selenium_spec_firefox.rb +208 -0
  228. data/spec/selenium_spec_firefox_remote.rb +15 -18
  229. data/spec/selenium_spec_ie.rb +82 -13
  230. data/spec/selenium_spec_safari.rb +148 -0
  231. data/spec/server_spec.rb +118 -77
  232. data/spec/session_spec.rb +19 -3
  233. data/spec/shared_selenium_node.rb +83 -0
  234. data/spec/shared_selenium_session.rb +110 -65
  235. data/spec/spec_helper.rb +57 -9
  236. data/spec/xpath_builder_spec.rb +93 -0
  237. metadata +257 -17
  238. data/lib/capybara/rspec/compound.rb +0 -94
  239. data/lib/capybara/selenium/driver_specializations/marionette_driver.rb +0 -49
  240. data/lib/capybara/selenium/nodes/marionette_node.rb +0 -121
  241. data/lib/capybara/spec/session/has_style_spec.rb +0 -25
  242. data/spec/selenium_spec_marionette.rb +0 -172
@@ -1,121 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'capybara/selenium/extensions/html5_drag'
4
-
5
- class Capybara::Selenium::MarionetteNode < Capybara::Selenium::Node
6
- include Html5Drag
7
-
8
- def click(keys = [], **options)
9
- super
10
- rescue ::Selenium::WebDriver::Error::ElementNotInteractableError
11
- if tag_name == 'tr'
12
- warn 'You are attempting to click a table row which has issues in geckodriver/marionette - see https://github.com/mozilla/geckodriver/issues/1228. ' \
13
- 'Your test should probably be clicking on a table cell like a user would. Clicking the first cell in the row instead.'
14
- return find_css('th:first-child,td:first-child')[0].click(keys, options)
15
- end
16
- raise
17
- end
18
-
19
- def disabled?
20
- # Not sure exactly what version of FF fixed the below issue, but it is definitely fixed in 61+
21
- return super unless browser_version < 61.0
22
-
23
- return true if super
24
- # workaround for selenium-webdriver/geckodriver reporting elements as enabled when they are nested in disabling elements
25
- if %w[option optgroup].include? tag_name
26
- find_xpath('parent::*[self::optgroup or self::select]')[0].disabled?
27
- else
28
- !find_xpath('parent::fieldset[@disabled] | ancestor::*[not(self::legend) or preceding-sibling::legend][parent::fieldset[@disabled]]').empty?
29
- end
30
- end
31
-
32
- def set_file(value) # rubocop:disable Naming/AccessorMethodName
33
- # By default files are appended so we have to clear here if its multiple and already set
34
- native.clear if multiple? && driver.evaluate_script('arguments[0].files', self).any?
35
- return super if browser_version >= 62.0
36
-
37
- # Workaround lack of support for multiple upload by uploading one at a time
38
- path_names = value.to_s.empty? ? [] : value
39
- Array(path_names).each do |path|
40
- unless driver.browser.respond_to?(:upload)
41
- if (fd = bridge.file_detector)
42
- local_file = fd.call([path])
43
- path = upload(local_file) if local_file
44
- end
45
- end
46
- native.send_keys(path)
47
- end
48
- end
49
-
50
- def send_keys(*args)
51
- # https://github.com/mozilla/geckodriver/issues/846
52
- return super(*args.map { |arg| arg == :space ? ' ' : arg }) if args.none? { |arg| arg.is_a? Array }
53
-
54
- native.click
55
- args.each_with_object(browser_action) do |keys, actions|
56
- _send_keys(keys, actions)
57
- end.perform
58
- end
59
-
60
- def drag_to(element)
61
- return super unless (browser_version >= 62.0) && html5_draggable?
62
- html5_drag_to(element)
63
- end
64
-
65
- private
66
-
67
- def click_with_options(click_options)
68
- # Firefox/marionette has an issue clicking with offset near viewport edge
69
- # scroll element to middle just in case
70
- scroll_to_center if click_options.coords?
71
- super
72
- end
73
-
74
- def _send_keys(keys, actions, down_keys = nil)
75
- case keys
76
- when String
77
- keys = keys.upcase if down_keys&.include?(:shift) # https://bugzilla.mozilla.org/show_bug.cgi?id=1405370
78
- actions.send_keys(keys)
79
- when :space
80
- actions.send_keys(' ') # https://github.com/mozilla/geckodriver/issues/846
81
- when :control, :left_control, :right_control,
82
- :alt, :left_alt, :right_alt,
83
- :shift, :left_shift, :right_shift,
84
- :meta, :left_meta, :right_meta,
85
- :command
86
- if down_keys.nil?
87
- actions.send_keys(keys)
88
- else
89
- down_keys << keys
90
- actions.key_down(keys)
91
- end
92
- when Symbol
93
- actions.send_keys(keys)
94
- when Array
95
- local_down_keys = []
96
- keys.each do |sub_keys|
97
- _send_keys(sub_keys, actions, local_down_keys)
98
- end
99
- local_down_keys.each { |key| actions.key_up(key) }
100
- else
101
- raise ArgumentError, 'Unknown keys type'
102
- end
103
- end
104
-
105
- def bridge
106
- driver.browser.send(:bridge)
107
- end
108
-
109
- def upload(local_file)
110
- unless File.file?(local_file)
111
- raise ArgumentError, "You may only upload files: #{local_file.inspect}"
112
- end
113
-
114
- result = bridge.http.call(:post, "session/#{bridge.session_id}/file", file: Selenium::WebDriver::Zipper.zip_file(local_file))
115
- result['value']
116
- end
117
-
118
- def browser_version
119
- driver.browser.capabilities[:browser_version].to_f
120
- end
121
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Capybara::SpecHelper.spec '#has_style?', requires: [:css] do
4
- before do
5
- @session.visit('/with_html')
6
- end
7
-
8
- it 'should be true if the element has the given style' do
9
- expect(@session.find(:css, '#first')).to have_style(display: 'block')
10
- expect(@session.find(:css, '#first').has_style?(display: 'block')).to be true
11
- expect(@session.find(:css, '#second')).to have_style('display' => 'inline')
12
- expect(@session.find(:css, '#second').has_style?('display' => 'inline')).to be true
13
- end
14
-
15
- it 'should be false if the element does not have the given style' do
16
- expect(@session.find(:css, '#first').has_style?('display' => 'inline')).to be false
17
- expect(@session.find(:css, '#second').has_style?(display: 'block')).to be false
18
- end
19
-
20
- it 'allows Regexp for value matching' do
21
- expect(@session.find(:css, '#first')).to have_style(display: /^bl/)
22
- expect(@session.find(:css, '#first').has_style?('display' => /^bl/)).to be true
23
- expect(@session.find(:css, '#first').has_style?(display: /^in/)).to be false
24
- end
25
- end
@@ -1,172 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
- require 'selenium-webdriver'
5
- require 'shared_selenium_session'
6
- require 'rspec/shared_spec_matchers'
7
-
8
- browser_options = ::Selenium::WebDriver::Firefox::Options.new
9
- browser_options.args << '--headless' if ENV['HEADLESS']
10
- browser_options.add_preference 'dom.file.createInChild', true
11
- # browser_options.add_option("log", {"level": "trace"})
12
-
13
- browser_options.profile = Selenium::WebDriver::Firefox::Profile.new.tap do |profile|
14
- profile['browser.download.dir'] = Capybara.save_path
15
- profile['browser.download.folderList'] = 2
16
- profile['browser.helperApps.neverAsk.saveToDisk'] = 'text/csv'
17
- end
18
-
19
- Capybara.register_driver :selenium_marionette do |app|
20
- # ::Selenium::WebDriver.logger.level = "debug"
21
- Capybara::Selenium::Driver.new(
22
- app,
23
- browser: :firefox,
24
- desired_capabilities: { marionette: true, 'moz:webdriverClick': true },
25
- options: browser_options,
26
- # Get a trace level log from geckodriver
27
- # :driver_opts => { args: ['-vv'] }
28
- )
29
- end
30
-
31
- Capybara.register_driver :selenium_marionette_clear_storage do |app|
32
- Capybara::Selenium::Driver.new(
33
- app,
34
- browser: :firefox,
35
- desired_capabilities: { marionette: true },
36
- clear_local_storage: true,
37
- clear_session_storage: true,
38
- options: browser_options
39
- )
40
- end
41
-
42
- module TestSessions
43
- SeleniumMarionette = Capybara::Session.new(:selenium_marionette, TestApp)
44
- end
45
-
46
- skipped_tests = %i[response_headers status_code trigger]
47
- skipped_tests << :windows if ENV['TRAVIS'] && ENV['SKIP_WINDOW']
48
-
49
- $stdout.puts `#{Selenium::WebDriver::Firefox.driver_path} --version` if ENV['CI']
50
-
51
- Capybara::SpecHelper.run_specs TestSessions::SeleniumMarionette, 'selenium', capybara_skip: skipped_tests do |example|
52
- case example.metadata[:full_description]
53
- when 'Capybara::Session selenium node #click should allow multiple modifiers'
54
- pending "Firefox doesn't generate an event for shift+control+click" if marionette_gte?(62, @session) && !Gem.win_platform?
55
- when /^Capybara::Session selenium node #double_click/
56
- pending "selenium-webdriver/geckodriver doesn't generate double click event" if marionette_lt?(59, @session)
57
- when 'Capybara::Session selenium #accept_prompt should accept the prompt with a blank response when there is a default'
58
- pending "Geckodriver doesn't set a blank response in FF < 63 - https://bugzilla.mozilla.org/show_bug.cgi?id=1486485" if marionette_lt?(63, @session)
59
- when 'Capybara::Session selenium #attach_file with multipart form should fire change once for each set of files uploaded'
60
- pending 'Gekcodriver appends files so we have to first call clear for multiple files which creates an extra change ' \
61
- 'if files are already set'
62
- when 'Capybara::Session selenium #attach_file with multipart form should fire change once when uploading multiple files from empty'
63
- pending "FF < 62 doesn't support setting all files at once" if marionette_lt?(62, @session)
64
- when 'Capybara::Session selenium #accept_confirm should work with nested modals'
65
- skip 'Broken in FF 63 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if marionette_gte?(63, @session)
66
- when 'Capybara::Session selenium #click_link can download a file'
67
- skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
68
- end
69
- end
70
-
71
- RSpec.describe 'Capybara::Session with firefox' do # rubocop:disable RSpec/MultipleDescribes
72
- include Capybara::SpecHelper
73
- include_examples 'Capybara::Session', TestSessions::SeleniumMarionette, :selenium_marionette
74
- include_examples Capybara::RSpecMatchers, TestSessions::SeleniumMarionette, :selenium_marionette
75
- end
76
-
77
- RSpec.describe Capybara::Selenium::Driver do
78
- before do
79
- @driver = Capybara::Selenium::Driver.new(TestApp, browser: :firefox, options: browser_options)
80
- end
81
-
82
- describe '#quit' do
83
- it 'should reset browser when quit' do
84
- expect(@driver.browser).to be_truthy
85
- @driver.quit
86
- # access instance variable directly so we don't create a new browser instance
87
- expect(@driver.instance_variable_get(:@browser)).to be_nil
88
- end
89
-
90
- context 'with errors' do
91
- before do
92
- @original_browser = @driver.browser
93
- end
94
-
95
- after do
96
- # Ensure browser is actually quit so we don't leave hanging processe
97
- RSpec::Mocks.space.proxy_for(@original_browser).reset
98
- @original_browser.quit
99
- end
100
-
101
- it 'warns UnknownError returned during quit because the browser is probably already gone' do
102
- allow(@driver).to receive(:warn)
103
- allow(@driver.browser).to(
104
- receive(:quit)
105
- .and_raise(Selenium::WebDriver::Error::UnknownError, 'random message')
106
- )
107
-
108
- expect { @driver.quit }.not_to raise_error
109
- expect(@driver.instance_variable_get(:@browser)).to be_nil
110
- expect(@driver).to have_received(:warn).with(/random message/)
111
- end
112
-
113
- it 'ignores silenced UnknownError returned during quit because the browser is almost definitely already gone' do
114
- allow(@driver).to receive(:warn)
115
- allow(@driver.browser).to(
116
- receive(:quit)
117
- .and_raise(Selenium::WebDriver::Error::UnknownError, 'Error communicating with the remote browser')
118
- )
119
-
120
- expect { @driver.quit }.not_to raise_error
121
- expect(@driver.instance_variable_get(:@browser)).to be_nil
122
- expect(@driver).not_to have_received(:warn)
123
- end
124
- end
125
- end
126
-
127
- context 'storage' do
128
- describe '#reset!' do
129
- it 'does not clear either storage by default' do
130
- @session = TestSessions::SeleniumMarionette
131
- @session.visit('/with_js')
132
- @session.find(:css, '#set-storage').click
133
- @session.reset!
134
- @session.visit('/with_js')
135
- expect(@session.driver.browser.local_storage.keys).not_to be_empty
136
- expect(@session.driver.browser.session_storage.keys).not_to be_empty
137
- end
138
-
139
- it 'clears storage when set' do
140
- @session = Capybara::Session.new(:selenium_marionette_clear_storage, TestApp)
141
- @session.visit('/with_js')
142
- @session.find(:css, '#set-storage').click
143
- @session.reset!
144
- @session.visit('/with_js')
145
- expect(@session.driver.browser.local_storage.keys).to be_empty
146
- expect(@session.driver.browser.session_storage.keys).to be_empty
147
- end
148
- end
149
- end
150
- end
151
-
152
- RSpec.describe Capybara::Selenium::Node do
153
- context '#click' do
154
- it 'warns when attempting on a table row' do
155
- session = TestSessions::SeleniumMarionette
156
- session.visit('/tables')
157
- tr = session.find(:css, '#agent_table tr:first-child')
158
- allow(tr.base).to receive(:warn)
159
- tr.click
160
- expect(tr.base).to have_received(:warn).with(/Clicking the first cell in the row instead/)
161
- end
162
-
163
- it 'should allow multiple modifiers', requires: [:js] do
164
- session = TestSessions::SeleniumMarionette
165
- session.visit('with_js')
166
- # Firefox v62+ doesn't generate an event for control+shift+click
167
- session.find(:css, '#click-test').click(:alt, :ctrl, :meta)
168
- # it also triggers a contextmenu event when control is held so don't check click type
169
- expect(session).to have_link('Has been alt control meta')
170
- end
171
- end
172
- end