capybara 2.15.0 → 3.0.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 (177) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +137 -2
  3. data/README.md +36 -25
  4. data/lib/capybara/config.rb +11 -57
  5. data/lib/capybara/cucumber.rb +2 -3
  6. data/lib/capybara/driver/base.rb +19 -16
  7. data/lib/capybara/driver/node.rb +5 -4
  8. data/lib/capybara/dsl.rb +1 -0
  9. data/lib/capybara/helpers.rb +19 -29
  10. data/lib/capybara/minitest/spec.rb +16 -13
  11. data/lib/capybara/minitest.rb +140 -137
  12. data/lib/capybara/node/actions.rb +68 -89
  13. data/lib/capybara/node/base.rb +11 -18
  14. data/lib/capybara/node/document.rb +2 -2
  15. data/lib/capybara/node/document_matchers.rb +8 -8
  16. data/lib/capybara/node/element.rb +32 -42
  17. data/lib/capybara/node/finders.rb +64 -71
  18. data/lib/capybara/node/matchers.rb +50 -71
  19. data/lib/capybara/node/simple.rb +11 -17
  20. data/lib/capybara/queries/ancestor_query.rb +12 -8
  21. data/lib/capybara/queries/base_query.rb +22 -18
  22. data/lib/capybara/queries/current_path_query.rb +12 -25
  23. data/lib/capybara/queries/match_query.rb +3 -7
  24. data/lib/capybara/queries/selector_query.rb +100 -96
  25. data/lib/capybara/queries/sibling_query.rb +5 -5
  26. data/lib/capybara/queries/text_query.rb +35 -35
  27. data/lib/capybara/queries/title_query.rb +8 -11
  28. data/lib/capybara/rack_test/browser.rb +15 -18
  29. data/lib/capybara/rack_test/css_handlers.rb +6 -4
  30. data/lib/capybara/rack_test/driver.rb +6 -10
  31. data/lib/capybara/rack_test/form.rb +52 -39
  32. data/lib/capybara/rack_test/node.rb +93 -63
  33. data/lib/capybara/rails.rb +2 -6
  34. data/lib/capybara/result.rb +22 -22
  35. data/lib/capybara/rspec/compound.rb +5 -10
  36. data/lib/capybara/rspec/features.rb +17 -48
  37. data/lib/capybara/rspec/matcher_proxies.rb +31 -15
  38. data/lib/capybara/rspec/matchers.rb +116 -58
  39. data/lib/capybara/rspec.rb +5 -10
  40. data/lib/capybara/selector/css.rb +6 -11
  41. data/lib/capybara/selector/filter.rb +1 -17
  42. data/lib/capybara/selector/filter_set.rb +18 -15
  43. data/lib/capybara/selector/filters/base.rb +7 -6
  44. data/lib/capybara/selector/filters/expression_filter.rb +6 -23
  45. data/lib/capybara/selector/filters/node_filter.rb +2 -12
  46. data/lib/capybara/selector/selector.rb +28 -34
  47. data/lib/capybara/selector.rb +129 -117
  48. data/lib/capybara/selenium/driver.rb +172 -163
  49. data/lib/capybara/selenium/node.rb +218 -104
  50. data/lib/capybara/server.rb +3 -2
  51. data/lib/capybara/session/config.rb +47 -59
  52. data/lib/capybara/session/matchers.rb +23 -14
  53. data/lib/capybara/session.rb +175 -229
  54. data/lib/capybara/spec/fixtures/no_extension +1 -0
  55. data/lib/capybara/spec/public/test.js +38 -6
  56. data/lib/capybara/spec/session/accept_alert_spec.rb +1 -0
  57. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -2
  58. data/lib/capybara/spec/session/accept_prompt_spec.rb +30 -1
  59. data/lib/capybara/spec/session/all_spec.rb +31 -18
  60. data/lib/capybara/spec/session/ancestor_spec.rb +6 -8
  61. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +6 -5
  62. data/lib/capybara/spec/session/assert_current_path.rb +12 -11
  63. data/lib/capybara/spec/session/assert_selector.rb +1 -0
  64. data/lib/capybara/spec/session/assert_text.rb +31 -23
  65. data/lib/capybara/spec/session/assert_title.rb +13 -3
  66. data/lib/capybara/spec/session/attach_file_spec.rb +57 -29
  67. data/lib/capybara/spec/session/body_spec.rb +1 -0
  68. data/lib/capybara/spec/session/check_spec.rb +7 -6
  69. data/lib/capybara/spec/session/choose_spec.rb +5 -4
  70. data/lib/capybara/spec/session/click_button_spec.rb +24 -32
  71. data/lib/capybara/spec/session/click_link_or_button_spec.rb +8 -7
  72. data/lib/capybara/spec/session/click_link_spec.rb +8 -7
  73. data/lib/capybara/spec/session/current_scope_spec.rb +4 -3
  74. data/lib/capybara/spec/session/current_url_spec.rb +19 -8
  75. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +1 -1
  76. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -0
  77. data/lib/capybara/spec/session/element/assert_match_selector.rb +1 -1
  78. data/lib/capybara/spec/session/element/match_xpath_spec.rb +1 -1
  79. data/lib/capybara/spec/session/element/matches_selector_spec.rb +5 -5
  80. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +23 -0
  81. data/lib/capybara/spec/session/evaluate_script_spec.rb +5 -4
  82. data/lib/capybara/spec/session/execute_script_spec.rb +4 -3
  83. data/lib/capybara/spec/session/fill_in_spec.rb +30 -5
  84. data/lib/capybara/spec/session/find_button_spec.rb +4 -3
  85. data/lib/capybara/spec/session/find_by_id_spec.rb +2 -1
  86. data/lib/capybara/spec/session/find_field_spec.rb +9 -15
  87. data/lib/capybara/spec/session/find_link_spec.rb +6 -5
  88. data/lib/capybara/spec/session/find_spec.rb +37 -31
  89. data/lib/capybara/spec/session/first_spec.rb +60 -33
  90. data/lib/capybara/spec/session/frame/frame_title_spec.rb +23 -0
  91. data/lib/capybara/spec/session/frame/frame_url_spec.rb +23 -0
  92. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +2 -1
  93. data/lib/capybara/spec/session/frame/within_frame_spec.rb +9 -16
  94. data/lib/capybara/spec/session/go_back_spec.rb +1 -0
  95. data/lib/capybara/spec/session/go_forward_spec.rb +1 -0
  96. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  97. data/lib/capybara/spec/session/has_button_spec.rb +2 -1
  98. data/lib/capybara/spec/session/has_css_spec.rb +3 -2
  99. data/lib/capybara/spec/session/has_current_path_spec.rb +49 -22
  100. data/lib/capybara/spec/session/has_field_spec.rb +4 -3
  101. data/lib/capybara/spec/session/has_link_spec.rb +5 -4
  102. data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
  103. data/lib/capybara/spec/session/has_select_spec.rb +32 -31
  104. data/lib/capybara/spec/session/has_selector_spec.rb +5 -4
  105. data/lib/capybara/spec/session/has_table_spec.rb +2 -1
  106. data/lib/capybara/spec/session/has_text_spec.rb +9 -13
  107. data/lib/capybara/spec/session/has_title_spec.rb +1 -0
  108. data/lib/capybara/spec/session/has_xpath_spec.rb +1 -0
  109. data/lib/capybara/spec/session/headers.rb +2 -1
  110. data/lib/capybara/spec/session/html_spec.rb +1 -0
  111. data/lib/capybara/spec/session/node_spec.rb +107 -58
  112. data/lib/capybara/spec/session/node_wrapper_spec.rb +36 -0
  113. data/lib/capybara/spec/session/refresh_spec.rb +6 -2
  114. data/lib/capybara/spec/session/reset_session_spec.rb +19 -0
  115. data/lib/capybara/spec/session/response_code.rb +1 -0
  116. data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
  117. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -11
  118. data/lib/capybara/spec/session/save_page_spec.rb +1 -17
  119. data/lib/capybara/spec/session/save_screenshot_spec.rb +3 -3
  120. data/lib/capybara/spec/session/select_spec.rb +21 -20
  121. data/lib/capybara/spec/session/selectors_spec.rb +2 -2
  122. data/lib/capybara/spec/session/sibling_spec.rb +1 -1
  123. data/lib/capybara/spec/session/text_spec.rb +17 -3
  124. data/lib/capybara/spec/session/title_spec.rb +11 -1
  125. data/lib/capybara/spec/session/uncheck_spec.rb +4 -3
  126. data/lib/capybara/spec/session/unselect_spec.rb +7 -6
  127. data/lib/capybara/spec/session/visit_spec.rb +64 -3
  128. data/lib/capybara/spec/session/window/become_closed_spec.rb +2 -1
  129. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
  130. data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
  131. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +2 -1
  132. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +2 -1
  133. data/lib/capybara/spec/session/window/window_spec.rb +12 -12
  134. data/lib/capybara/spec/session/window/windows_spec.rb +2 -3
  135. data/lib/capybara/spec/session/window/within_window_spec.rb +15 -71
  136. data/lib/capybara/spec/session/within_spec.rb +1 -0
  137. data/lib/capybara/spec/spec_helper.rb +36 -18
  138. data/lib/capybara/spec/test_app.rb +17 -9
  139. data/lib/capybara/spec/views/form.erb +7 -0
  140. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  141. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  142. data/lib/capybara/spec/views/with_hover.erb +5 -0
  143. data/lib/capybara/spec/views/with_html.erb +27 -1
  144. data/lib/capybara/spec/views/with_js.erb +11 -0
  145. data/lib/capybara/spec/views/within_frames.erb +4 -1
  146. data/lib/capybara/version.rb +2 -1
  147. data/lib/capybara/window.rb +6 -10
  148. data/lib/capybara.rb +29 -26
  149. data/spec/basic_node_spec.rb +1 -0
  150. data/spec/capybara_spec.rb +16 -69
  151. data/spec/dsl_spec.rb +5 -13
  152. data/spec/filter_set_spec.rb +5 -4
  153. data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -1
  154. data/spec/fixtures/selenium_driver_rspec_success.rb +3 -2
  155. data/spec/minitest_spec.rb +13 -4
  156. data/spec/minitest_spec_spec.rb +12 -3
  157. data/spec/per_session_config_spec.rb +9 -8
  158. data/spec/rack_test_spec.rb +21 -20
  159. data/spec/result_spec.rb +17 -16
  160. data/spec/rspec/features_spec.rb +17 -14
  161. data/spec/rspec/scenarios_spec.rb +5 -7
  162. data/spec/rspec/shared_spec_matchers.rb +96 -99
  163. data/spec/rspec/views_spec.rb +2 -1
  164. data/spec/rspec_matchers_spec.rb +18 -2
  165. data/spec/rspec_spec.rb +11 -15
  166. data/spec/selector_spec.rb +5 -6
  167. data/spec/selenium_spec_chrome.rb +20 -11
  168. data/spec/selenium_spec_edge.rb +27 -0
  169. data/spec/selenium_spec_ie.rb +31 -0
  170. data/spec/selenium_spec_marionette.rb +38 -12
  171. data/spec/server_spec.rb +33 -33
  172. data/spec/session_spec.rb +2 -1
  173. data/spec/shared_selenium_session.rb +82 -22
  174. data/spec/spec_helper.rb +3 -6
  175. metadata +76 -81
  176. data/lib/capybara/query.rb +0 -7
  177. data/spec/selenium_spec_firefox.rb +0 -68
@@ -1,22 +1,23 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Capybara
3
4
  # @api private
4
5
  module Queries
5
6
  class TextQuery < BaseQuery
6
- def initialize(*args)
7
- @type = (args.first.is_a?(Symbol) || args.first.nil?) ? args.shift : nil
8
- # @type = (Capybara.ignore_hidden_elements or Capybara.visible_text_only) ? :visible : :all if @type.nil?
9
- @options = if args.last.is_a?(Hash) then args.pop.dup else {} end
7
+ def initialize(type = nil, expected_text, session_options:, **options) # rubocop:disable Style/OptionalArguments
8
+ @type = if type.nil?
9
+ Capybara.ignore_hidden_elements || Capybara.visible_text_only ? :visible : :all
10
+ else
11
+ type
12
+ end
13
+
14
+ @expected_text = expected_text.is_a?(Regexp) ? expected_text : expected_text.to_s
15
+ @options = options
10
16
  super(@options)
17
+ self.session_options = session_options
11
18
 
12
- @type = (session_options.ignore_hidden_elements or session_options.visible_text_only) ? :visible : :all if @type.nil?
19
+ @search_regexp = Capybara::Helpers.to_regexp(@expected_text, exact: exact?)
13
20
 
14
- @expected_text = args.shift
15
- unless @expected_text.is_a?(Regexp)
16
- @expected_text = Capybara::Helpers.normalize_whitespace(@expected_text)
17
- end
18
- @search_regexp = Capybara::Helpers.to_regexp(@expected_text, nil, exact?)
19
- warn "Unused parameters passed to #{self.class.name} : #{args.to_s}" unless args.empty?
20
21
  assert_valid_keys
21
22
  end
22
23
 
@@ -42,48 +43,47 @@ module Capybara
42
43
  end
43
44
  end
44
45
 
45
- private
46
+ private
46
47
 
47
48
  def exact?
48
49
  options.fetch(:exact, session_options.exact_text)
49
50
  end
50
51
 
51
52
  def build_message(report_on_invisible)
52
- message = String.new()
53
+ message = "".dup
53
54
  unless (COUNT_KEYS & @options.keys).empty?
54
55
  message << " but found #{@count} #{Capybara::Helpers.declension('time', 'times', @count)}"
55
56
  end
56
57
  message << " in #{@actual_text.inspect}"
57
58
 
58
59
  details_message = []
60
+ details_message << case_insensitive_message if @node and !@expected_text.is_a? Regexp
61
+ details_message << invisible_message if @node and check_visible_text? and report_on_invisible
62
+ details_message.compact!
59
63
 
60
- if @node and !@expected_text.is_a? Regexp
61
- insensitive_regexp = Capybara::Helpers.to_regexp(@expected_text, Regexp::IGNORECASE)
62
- insensitive_count = @actual_text.scan(insensitive_regexp).size
63
- if insensitive_count != @count
64
- details_message << "it was found #{insensitive_count} #{Capybara::Helpers.declension("time", "times", insensitive_count)} using a case insensitive search"
65
- end
66
- end
64
+ message << ". (However, #{details_message.join(' and ')}.)" unless details_message.empty?
65
+ message
66
+ end
67
67
 
68
- if @node and check_visible_text? and report_on_invisible
69
- begin
70
- invisible_text = text(@node, :all)
71
- invisible_count = invisible_text.scan(@search_regexp).size
72
- if invisible_count != @count
73
- details_message << ". it was found #{invisible_count} #{Capybara::Helpers.declension("time", "times", invisible_count)} including non-visible text"
74
- end
75
- rescue
76
- # An error getting the non-visible text (if element goes out of scope) should not affect the response
77
- end
68
+ def case_insensitive_message
69
+ insensitive_regexp = Capybara::Helpers.to_regexp(@expected_text, options: Regexp::IGNORECASE)
70
+ insensitive_count = @actual_text.scan(insensitive_regexp).size
71
+ if insensitive_count != @count
72
+ "it was found #{insensitive_count} #{Capybara::Helpers.declension("time", "times", insensitive_count)} using a case insensitive search"
78
73
  end
74
+ end
79
75
 
80
- message << ". (However, #{details_message.join(' and ')}.)" unless details_message.empty?
81
-
82
- message
76
+ def invisible_message
77
+ invisible_text = text(@node, :all)
78
+ invisible_count = invisible_text.scan(@search_regexp).size
79
+ if invisible_count != @count
80
+ "it was found #{invisible_count} #{Capybara::Helpers.declension("time", "times", invisible_count)} including non-visible text"
81
+ end
82
+ rescue # An error getting the non-visible text (if element goes out of scope) should not affect the response
83
83
  end
84
84
 
85
85
  def valid_keys
86
- COUNT_KEYS + [:wait, :exact]
86
+ COUNT_KEYS + %i[wait exact]
87
87
  end
88
88
 
89
89
  def check_visible_text?
@@ -91,7 +91,7 @@ module Capybara
91
91
  end
92
92
 
93
93
  def text(node, query_type)
94
- Capybara::Helpers.normalize_whitespace(node.text(query_type))
94
+ node.text(query_type)
95
95
  end
96
96
  end
97
97
  end
@@ -1,22 +1,19 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Capybara
3
4
  # @api private
4
5
  module Queries
5
6
  class TitleQuery < BaseQuery
6
- def initialize(expected_title, options = {})
7
- @expected_title = expected_title
7
+ def initialize(expected_title, **options)
8
+ @expected_title = expected_title.is_a?(Regexp) ? expected_title : expected_title.to_s
8
9
  @options = options
9
10
  super(@options)
10
- unless @expected_title.is_a?(Regexp)
11
- @expected_title = Capybara::Helpers.normalize_whitespace(@expected_title)
12
- end
13
- @search_regexp = Capybara::Helpers.to_regexp(@expected_title, nil, options.fetch(:exact, false))
11
+ @search_regexp = Capybara::Helpers.to_regexp(@expected_title, all_whitespace: true, exact: options.fetch(:exact, false))
14
12
  assert_valid_keys
15
13
  end
16
14
 
17
15
  def resolves_for?(node)
18
- @actual_title = node.title
19
- @actual_title.match(@search_regexp)
16
+ (@actual_title = node.title).match(@search_regexp)
20
17
  end
21
18
 
22
19
  def failure_message
@@ -27,15 +24,15 @@ module Capybara
27
24
  failure_message_helper(' not')
28
25
  end
29
26
 
30
- private
27
+ private
31
28
 
32
29
  def failure_message_helper(negated = '')
33
- verb = (@expected_title.is_a?(Regexp))? 'match' : 'include'
30
+ verb = @expected_title.is_a?(Regexp) ? 'match' : 'include'
34
31
  "expected #{@actual_title.inspect}#{negated} to #{verb} #{@expected_title.inspect}"
35
32
  end
36
33
 
37
34
  def valid_keys
38
- [:wait, :exact]
35
+ %i[wait exact]
39
36
  end
40
37
  end
41
38
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Capybara::RackTest::Browser
3
4
  include ::Rack::Test::Methods
4
5
 
@@ -17,7 +18,7 @@ class Capybara::RackTest::Browser
17
18
  driver.options
18
19
  end
19
20
 
20
- def visit(path, attributes = {})
21
+ def visit(path, **attributes)
21
22
  reset_host!
22
23
  process_and_follow_redirects(:get, path, attributes)
23
24
  end
@@ -28,23 +29,24 @@ class Capybara::RackTest::Browser
28
29
  end
29
30
 
30
31
  def submit(method, path, attributes)
31
- path = request_path if not path or path.empty?
32
- process_and_follow_redirects(method, path, attributes, {'HTTP_REFERER' => current_url})
32
+ path = request_path if path.nil? || path.empty?
33
+ process_and_follow_redirects(method, path, attributes, 'HTTP_REFERER' => current_url)
33
34
  end
34
35
 
35
- def follow(method, path, attributes = {})
36
+ def follow(method, path, **attributes)
36
37
  return if path.gsub(/^#{Regexp.escape(request_path)}/, '').start_with?('#') || path.downcase.start_with?('javascript:')
37
- process_and_follow_redirects(method, path, attributes, {'HTTP_REFERER' => current_url})
38
+ process_and_follow_redirects(method, path, attributes, 'HTTP_REFERER' => current_url)
38
39
  end
39
40
 
40
41
  def process_and_follow_redirects(method, path, attributes = {}, env = {})
41
42
  process(method, path, attributes, env)
42
- if driver.follow_redirects?
43
- driver.redirect_limit.times do
44
- process(:get, last_response["Location"], {}, env) if last_response.redirect?
45
- end
46
- raise Capybara::InfiniteRedirectError, "redirected more than #{driver.redirect_limit} times, check for infinite redirects." if last_response.redirect?
43
+
44
+ return unless driver.follow_redirects?
45
+
46
+ driver.redirect_limit.times do
47
+ process(:get, last_response["Location"], {}, env) if last_response.redirect?
47
48
  end
49
+ raise Capybara::InfiniteRedirectError, "redirected more than #{driver.redirect_limit} times, check for infinite redirects." if last_response.redirect?
48
50
  end
49
51
 
50
52
  def process(method, path, attributes = {}, env = {})
@@ -55,7 +57,7 @@ class Capybara::RackTest::Browser
55
57
  else
56
58
  new_uri.path = request_path if path.start_with?("?")
57
59
  new_uri.path = "/" if new_uri.path.empty?
58
- new_uri.path = request_path.sub(%r(/[^/]*$), '/') + new_uri.path unless new_uri.path.start_with?('/')
60
+ new_uri.path = request_path.sub(%r{/[^/]*$}, '/') + new_uri.path unless new_uri.path.start_with?('/')
59
61
  end
60
62
  new_uri.scheme ||= @current_scheme
61
63
  new_uri.host ||= @current_host
@@ -91,7 +93,7 @@ class Capybara::RackTest::Browser
91
93
  end
92
94
 
93
95
  def find(format, selector)
94
- if format==:css
96
+ if format == :css
95
97
  dom.css(selector, Capybara::RackTest::CSSHandlers.new)
96
98
  else
97
99
  dom.xpath(selector)
@@ -105,12 +107,7 @@ class Capybara::RackTest::Browser
105
107
  end
106
108
 
107
109
  def title
108
- if dom.respond_to? :title
109
- dom.title
110
- else
111
- #old versions of nokogiri don't have #title - remove in 3.0
112
- dom.xpath('/html/head/title | /html/title').first.text
113
- end
110
+ dom.title
114
111
  end
115
112
 
116
113
  protected
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Capybara::RackTest::CSSHandlers < BasicObject
3
4
  include ::Kernel
4
-
5
- def disabled list
5
+
6
+ def disabled(list)
6
7
  list.find_all { |node| node.has_attribute? 'disabled' }
7
- end
8
- def enabled list
8
+ end
9
+
10
+ def enabled(list)
9
11
  list.find_all { |node| !node.has_attribute? 'disabled' }
10
12
  end
11
13
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'rack/test'
3
4
  require 'rack/utils'
4
5
  require 'mini_mime'
@@ -10,10 +11,10 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
10
11
  respect_data_method: false,
11
12
  follow_redirects: true,
12
13
  redirect_limit: 5
13
- }
14
+ }.freeze
14
15
  attr_reader :app, :options
15
16
 
16
- def initialize(app, options={})
17
+ def initialize(app, **options)
17
18
  raise ArgumentError, "rack-test requires a rack application, but none was given" unless app
18
19
  @session = nil
19
20
  @app = app
@@ -40,7 +41,7 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
40
41
  browser.last_request
41
42
  end
42
43
 
43
- def visit(path, attributes = {})
44
+ def visit(path, **attributes)
44
45
  browser.visit(path, attributes)
45
46
  end
46
47
 
@@ -52,7 +53,7 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
52
53
  browser.submit(method, path, attributes)
53
54
  end
54
55
 
55
- def follow(method, path, attributes = {})
56
+ def follow(method, path, **attributes)
56
57
  browser.follow(method, path, attributes)
57
58
  end
58
59
 
@@ -73,7 +74,7 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
73
74
  end
74
75
 
75
76
  def find_css(selector)
76
- browser.find(:css,selector)
77
+ browser.find(:css, selector)
77
78
  end
78
79
 
79
80
  def html
@@ -92,11 +93,6 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
92
93
  @browser = nil
93
94
  end
94
95
 
95
- # @deprecated This method is being removed
96
- def browser_initialized?
97
- super && !@browser.nil?
98
- end
99
-
100
96
  def get(*args, &block); browser.get(*args, &block); end
101
97
  def post(*args, &block); browser.post(*args, &block); end
102
98
  def put(*args, &block); browser.put(*args, &block); end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  class Capybara::RackTest::Form < Capybara::RackTest::Node
3
4
  # This only needs to inherit from Rack::Test::UploadedFile because Rack::Test checks for
4
5
  # the class specifically when determining whether to construct the request as multipart.
@@ -13,57 +14,28 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
13
14
  def original_filename; ""; end
14
15
  def content_type; "application/octet-stream"; end
15
16
  def path; @empty_file.path; end
17
+ def size; 0; end
18
+ def read; ""; end
16
19
  end
17
20
 
18
21
  def params(button)
19
22
  params = make_params
20
23
 
21
- form_element_types=[:input, :select, :textarea]
22
- form_elements_xpath=XPath.generate do |x|
23
- xpath=x.descendant(*form_element_types).where(~x.attr(:form))
24
- xpath=xpath.union(x.anywhere(*form_element_types).where(x.attr(:form) == native[:id])) if native[:id]
25
- xpath.where(~x.attr(:disabled))
24
+ form_element_types = %i[input select textarea]
25
+ form_elements_xpath = XPath.generate do |x|
26
+ xpath = x.descendant(*form_element_types).where(!x.attr(:form))
27
+ xpath += x.anywhere(*form_element_types).where(x.attr(:form) == native[:id]) if native[:id]
28
+ xpath.where(!x.attr(:disabled))
26
29
  end.to_s
27
30
 
28
31
  native.xpath(form_elements_xpath).map do |field|
29
32
  case field.name
30
33
  when 'input'
31
- if %w(radio checkbox).include? field['type']
32
- if field['checked']
33
- node=Capybara::RackTest::Node.new(self.driver, field)
34
- merge_param!(params, field['name'].to_s, node.value.to_s)
35
- end
36
- elsif %w(submit image).include? field['type']
37
- # TO DO identify the click button here (in document order, rather
38
- # than leaving until the end of the params)
39
- elsif field['type'] =='file'
40
- if multipart?
41
- file = \
42
- if (value = field['value']).to_s.empty?
43
- NilUploadedFile.new
44
- else
45
- Rack::Test::UploadedFile.new(value, MiniMime.lookup_by_filename(value).content_type)
46
- end
47
- merge_param!(params, field['name'].to_s, file)
48
- else
49
- merge_param!(params, field['name'].to_s, File.basename(field['value'].to_s))
50
- end
51
- else
52
- merge_param!(params, field['name'].to_s, field['value'].to_s)
53
- end
34
+ add_input_param(field, params)
54
35
  when 'select'
55
- if field['multiple'] == 'multiple'
56
- options = field.xpath(".//option[@selected]")
57
- options.each do |option|
58
- merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s)
59
- end
60
- else
61
- option = field.xpath(".//option[@selected]").first
62
- option ||= field.xpath('.//option').first
63
- merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s) if option
64
- end
36
+ add_select_param(field, params)
65
37
  when 'textarea'
66
- merge_param!(params, field['name'].to_s, field['_capybara_raw_value'].to_s.gsub(/\n/, "\r\n"))
38
+ add_textarea_param(field, params)
67
39
  end
68
40
  end
69
41
  merge_param!(params, button[:name], button[:value] || "") if button[:name]
@@ -108,4 +80,45 @@ private
108
80
  ParamsHash.new
109
81
  end
110
82
  end
83
+
84
+ def add_input_param(field, params)
85
+ if %w[radio checkbox].include? field['type']
86
+ if field['checked']
87
+ node = Capybara::RackTest::Node.new(driver, field)
88
+ merge_param!(params, field['name'].to_s, node.value.to_s)
89
+ end
90
+ elsif %w[submit image].include? field['type']
91
+ # TODO: identify the click button here (in document order, rather
92
+ # than leaving until the end of the params)
93
+ elsif field['type'] == 'file'
94
+ if multipart?
95
+ file = if (value = field['value']).to_s.empty?
96
+ NilUploadedFile.new
97
+ else
98
+ mime_info = MiniMime.lookup_by_filename(value)
99
+ Rack::Test::UploadedFile.new(value, (mime_info && mime_info.content_type).to_s)
100
+ end
101
+ merge_param!(params, field['name'].to_s, file)
102
+ else
103
+ merge_param!(params, field['name'].to_s, File.basename(field['value'].to_s))
104
+ end
105
+ else
106
+ merge_param!(params, field['name'].to_s, field['value'].to_s)
107
+ end
108
+ end
109
+
110
+ def add_select_param(field, params)
111
+ if field['multiple'] == 'multiple'
112
+ field.xpath(".//option[@selected]").each do |option|
113
+ merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s)
114
+ end
115
+ else
116
+ option = field.xpath('.//option[@selected]').first || field.xpath('.//option').first
117
+ merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s) if option
118
+ end
119
+ end
120
+
121
+ def add_textarea_param(field, params)
122
+ merge_param!(params, field['name'].to_s, field['_capybara_raw_value'].to_s.gsub(/\n/, "\r\n"))
123
+ end
111
124
  end