capybara 3.29.0 → 3.33.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +91 -1
  3. data/README.md +10 -3
  4. data/lib/capybara.rb +17 -7
  5. data/lib/capybara/config.rb +7 -3
  6. data/lib/capybara/cucumber.rb +1 -1
  7. data/lib/capybara/dsl.rb +10 -2
  8. data/lib/capybara/helpers.rb +3 -1
  9. data/lib/capybara/minitest.rb +232 -144
  10. data/lib/capybara/minitest/spec.rb +153 -97
  11. data/lib/capybara/node/actions.rb +35 -35
  12. data/lib/capybara/node/document.rb +2 -2
  13. data/lib/capybara/node/document_matchers.rb +3 -3
  14. data/lib/capybara/node/element.rb +23 -16
  15. data/lib/capybara/node/finders.rb +17 -11
  16. data/lib/capybara/node/matchers.rb +64 -51
  17. data/lib/capybara/node/simple.rb +4 -2
  18. data/lib/capybara/queries/ancestor_query.rb +1 -1
  19. data/lib/capybara/queries/base_query.rb +2 -1
  20. data/lib/capybara/queries/selector_query.rb +25 -5
  21. data/lib/capybara/queries/sibling_query.rb +1 -1
  22. data/lib/capybara/queries/style_query.rb +1 -1
  23. data/lib/capybara/queries/text_query.rb +6 -0
  24. data/lib/capybara/rack_test/browser.rb +7 -2
  25. data/lib/capybara/rack_test/driver.rb +1 -1
  26. data/lib/capybara/rack_test/form.rb +1 -1
  27. data/lib/capybara/rack_test/node.rb +34 -9
  28. data/lib/capybara/registration_container.rb +44 -0
  29. data/lib/capybara/registrations/servers.rb +1 -1
  30. data/lib/capybara/result.rb +29 -5
  31. data/lib/capybara/rspec/matcher_proxies.rb +4 -4
  32. data/lib/capybara/rspec/matchers.rb +27 -27
  33. data/lib/capybara/rspec/matchers/base.rb +12 -6
  34. data/lib/capybara/rspec/matchers/count_sugar.rb +2 -1
  35. data/lib/capybara/rspec/matchers/have_ancestor.rb +4 -3
  36. data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
  37. data/lib/capybara/rspec/matchers/have_selector.rb +15 -7
  38. data/lib/capybara/rspec/matchers/have_sibling.rb +3 -3
  39. data/lib/capybara/rspec/matchers/have_text.rb +3 -3
  40. data/lib/capybara/rspec/matchers/have_title.rb +2 -2
  41. data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
  42. data/lib/capybara/rspec/matchers/match_style.rb +2 -2
  43. data/lib/capybara/rspec/matchers/spatial_sugar.rb +2 -1
  44. data/lib/capybara/selector.rb +34 -17
  45. data/lib/capybara/selector/css.rb +1 -1
  46. data/lib/capybara/selector/definition.rb +7 -6
  47. data/lib/capybara/selector/definition/button.rb +8 -2
  48. data/lib/capybara/selector/definition/checkbox.rb +2 -2
  49. data/lib/capybara/selector/definition/css.rb +3 -1
  50. data/lib/capybara/selector/definition/datalist_input.rb +1 -1
  51. data/lib/capybara/selector/definition/datalist_option.rb +1 -1
  52. data/lib/capybara/selector/definition/element.rb +1 -1
  53. data/lib/capybara/selector/definition/field.rb +1 -1
  54. data/lib/capybara/selector/definition/file_field.rb +1 -1
  55. data/lib/capybara/selector/definition/fillable_field.rb +2 -2
  56. data/lib/capybara/selector/definition/label.rb +4 -2
  57. data/lib/capybara/selector/definition/link.rb +8 -0
  58. data/lib/capybara/selector/definition/radio_button.rb +2 -2
  59. data/lib/capybara/selector/definition/select.rb +32 -13
  60. data/lib/capybara/selector/definition/table.rb +6 -3
  61. data/lib/capybara/selector/filter_set.rb +11 -9
  62. data/lib/capybara/selector/filters/base.rb +6 -1
  63. data/lib/capybara/selector/filters/locator_filter.rb +1 -1
  64. data/lib/capybara/selector/selector.rb +8 -2
  65. data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -1
  66. data/lib/capybara/selenium/atoms/src/getAttribute.js +1 -1
  67. data/lib/capybara/selenium/driver.rb +22 -11
  68. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +8 -10
  69. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +7 -9
  70. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +2 -2
  71. data/lib/capybara/selenium/extensions/html5_drag.rb +30 -13
  72. data/lib/capybara/selenium/node.rb +97 -18
  73. data/lib/capybara/selenium/nodes/chrome_node.rb +11 -14
  74. data/lib/capybara/selenium/nodes/edge_node.rb +4 -2
  75. data/lib/capybara/selenium/nodes/firefox_node.rb +4 -4
  76. data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
  77. data/lib/capybara/selenium/patches/logs.rb +3 -5
  78. data/lib/capybara/server.rb +15 -3
  79. data/lib/capybara/server/checker.rb +1 -1
  80. data/lib/capybara/server/middleware.rb +20 -10
  81. data/lib/capybara/session.rb +43 -26
  82. data/lib/capybara/session/config.rb +9 -3
  83. data/lib/capybara/session/matchers.rb +6 -6
  84. data/lib/capybara/spec/public/test.js +69 -6
  85. data/lib/capybara/spec/session/all_spec.rb +60 -5
  86. data/lib/capybara/spec/session/ancestor_spec.rb +5 -0
  87. data/lib/capybara/spec/session/assert_text_spec.rb +9 -5
  88. data/lib/capybara/spec/session/click_button_spec.rb +16 -0
  89. data/lib/capybara/spec/session/fill_in_spec.rb +29 -0
  90. data/lib/capybara/spec/session/find_spec.rb +31 -8
  91. data/lib/capybara/spec/session/has_button_spec.rb +16 -0
  92. data/lib/capybara/spec/session/has_css_spec.rb +12 -9
  93. data/lib/capybara/spec/session/has_current_path_spec.rb +2 -2
  94. data/lib/capybara/spec/session/has_field_spec.rb +16 -0
  95. data/lib/capybara/spec/session/has_select_spec.rb +32 -4
  96. data/lib/capybara/spec/session/has_selector_spec.rb +4 -4
  97. data/lib/capybara/spec/session/has_table_spec.rb +51 -5
  98. data/lib/capybara/spec/session/has_text_spec.rb +35 -0
  99. data/lib/capybara/spec/session/node_spec.rb +160 -29
  100. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +2 -2
  101. data/lib/capybara/spec/session/save_screenshot_spec.rb +4 -4
  102. data/lib/capybara/spec/session/selectors_spec.rb +15 -2
  103. data/lib/capybara/spec/session/window/window_spec.rb +7 -7
  104. data/lib/capybara/spec/spec_helper.rb +2 -2
  105. data/lib/capybara/spec/test_app.rb +14 -18
  106. data/lib/capybara/spec/views/form.erb +18 -2
  107. data/lib/capybara/spec/views/with_dragula.erb +3 -1
  108. data/lib/capybara/spec/views/with_html.erb +2 -2
  109. data/lib/capybara/spec/views/with_js.erb +1 -0
  110. data/lib/capybara/version.rb +1 -1
  111. data/spec/capybara_spec.rb +1 -1
  112. data/spec/dsl_spec.rb +16 -3
  113. data/spec/minitest_spec.rb +1 -1
  114. data/spec/minitest_spec_spec.rb +46 -46
  115. data/spec/rack_test_spec.rb +13 -1
  116. data/spec/regexp_dissassembler_spec.rb +40 -36
  117. data/spec/result_spec.rb +43 -32
  118. data/spec/rspec/features_spec.rb +1 -0
  119. data/spec/rspec/shared_spec_matchers.rb +68 -56
  120. data/spec/rspec_spec.rb +4 -4
  121. data/spec/selector_spec.rb +1 -1
  122. data/spec/selenium_spec_chrome.rb +9 -6
  123. data/spec/selenium_spec_chrome_remote.rb +2 -0
  124. data/spec/selenium_spec_firefox.rb +7 -2
  125. data/spec/server_spec.rb +65 -31
  126. data/spec/session_spec.rb +1 -1
  127. data/spec/shared_selenium_node.rb +21 -3
  128. data/spec/shared_selenium_session.rb +33 -14
  129. data/spec/spec_helper.rb +1 -1
  130. metadata +6 -4
@@ -43,7 +43,7 @@ RSpec.describe 'capybara/rspec' do
43
43
  expect(Capybara.current_driver).to eq(:culerity)
44
44
  end
45
45
 
46
- context '#all' do
46
+ describe '#all' do
47
47
  it 'allows access to the Capybara finder' do
48
48
  visit('/with_html')
49
49
  found = all(:css, 'h2') { |element| element[:class] == 'head' }
@@ -57,7 +57,7 @@ RSpec.describe 'capybara/rspec' do
57
57
  end
58
58
  end
59
59
 
60
- context '#within' do
60
+ describe '#within' do
61
61
  it 'allows access to the Capybara scoper' do
62
62
  visit('/with_html')
63
63
  expect do
@@ -82,7 +82,7 @@ RSpec.describe 'capybara/rspec' do
82
82
  end.new
83
83
  end
84
84
 
85
- context '#all' do
85
+ describe '#all' do
86
86
  it 'allows access to the Capybara finder' do
87
87
  test_class_instance.visit('/with_html')
88
88
  expect(test_class_instance.all(:css, 'h2.head').size).to eq(5)
@@ -95,7 +95,7 @@ RSpec.describe 'capybara/rspec' do
95
95
  end
96
96
  end
97
97
 
98
- context '#within' do
98
+ describe '#within' do
99
99
  it 'allows access to the Capybara scoper' do
100
100
  test_class_instance.visit('/with_html')
101
101
  expect do
@@ -476,7 +476,7 @@ RSpec.describe Capybara do
476
476
  end
477
477
 
478
478
  describe ':link_or_button selector' do
479
- around(:all) do |example|
479
+ around do |example|
480
480
  described_class.modify_selector(:link_or_button) do
481
481
  expression_filter(:random) { |xpath, _| xpath } # do nothing filter
482
482
  end
@@ -14,7 +14,8 @@ browser_options = ::Selenium::WebDriver::Chrome::Options.new
14
14
  browser_options.headless! if ENV['HEADLESS']
15
15
  browser_options.add_option(:w3c, ENV['W3C'] != 'false')
16
16
  # Chromedriver 77 requires setting this for headless mode on linux
17
- # browser_options.add_preference('download.default_directory', Capybara.save_path)
17
+ # Different versions of Chrome/selenium-webdriver require setting differently - jus set them all
18
+ browser_options.add_preference('download.default_directory', Capybara.save_path)
18
19
  browser_options.add_preference(:download, default_directory: Capybara.save_path)
19
20
 
20
21
  Capybara.register_driver :selenium_chrome do |app|
@@ -29,7 +30,7 @@ Capybara.register_driver :selenium_chrome_not_clear_storage do |app|
29
30
  browser: :chrome,
30
31
  options: browser_options
31
32
  }
32
- Capybara::Selenium::Driver.new(app, chrome_options.merge(clear_local_storage: false, clear_session_storage: false))
33
+ Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_local_storage: false, clear_session_storage: false))
33
34
  end
34
35
 
35
36
  Capybara.register_driver :selenium_chrome_not_clear_session_storage do |app|
@@ -37,7 +38,7 @@ Capybara.register_driver :selenium_chrome_not_clear_session_storage do |app|
37
38
  browser: :chrome,
38
39
  options: browser_options
39
40
  }
40
- Capybara::Selenium::Driver.new(app, chrome_options.merge(clear_session_storage: false))
41
+ Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_session_storage: false))
41
42
  end
42
43
 
43
44
  Capybara.register_driver :selenium_chrome_not_clear_local_storage do |app|
@@ -45,7 +46,7 @@ Capybara.register_driver :selenium_chrome_not_clear_local_storage do |app|
45
46
  browser: :chrome,
46
47
  options: browser_options
47
48
  }
48
- Capybara::Selenium::Driver.new(app, chrome_options.merge(clear_local_storage: false))
49
+ Capybara::Selenium::Driver.new(app, **chrome_options.merge(clear_local_storage: false))
49
50
  end
50
51
 
51
52
  Capybara.register_driver :selenium_driver_subclass_with_chrome do |app|
@@ -67,8 +68,10 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybar
67
68
  skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
68
69
  when /Capybara::Session selenium_chrome Capybara::Window#maximize/
69
70
  pending "Chrome headless doesn't support maximize" if ENV['HEADLESS']
70
- when /details non-summary descendants should be non-visible/
71
- pending 'Chromedriver built-in is_displayed is currently broken' if ENV['W3C'] == 'false'
71
+ when /Capybara::Window#fullscreen should be able to fullscreen the window/
72
+ skip 'Chromedriver hangs on attempts to fullscreen in headless mode' if ENV['HEADLESS']
73
+ when /node #right_click delay should delay the mouse up/
74
+ skip "Legacy selenium doesn't support separate right button down/up" if ENV['W3C'] == 'false'
72
75
  end
73
76
  end
74
77
 
@@ -62,6 +62,8 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s,
62
62
  'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once for each set of files uploaded',
63
63
  'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once when uploading multiple files from empty'
64
64
  pending "Selenium with Remote Chrome doesn't support multiple file upload" unless selenium_gte?(3.14)
65
+ when /node #right_click delay should delay the mouse up/
66
+ skip "Legacy selenium doesn't support separate right button down/up" if ENV['W3C'] == 'false'
65
67
  end
66
68
  end
67
69
 
@@ -49,7 +49,7 @@ Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::Firefox) i
49
49
  Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capybara_skip: skipped_tests do |example|
50
50
  case example.metadata[:full_description]
51
51
  when 'Capybara::Session selenium node #click should allow multiple modifiers'
52
- pending "Firefox doesn't generate an event for shift+control+click" if firefox_gte?(62, @session) && !Gem.win_platform?
52
+ pending "Firefox on OSX doesn't generate an event for shift+control+click" if firefox_gte?(62, @session) && Selenium::WebDriver::Platform.mac?
53
53
  when /^Capybara::Session selenium node #double_click/
54
54
  pending "selenium-webdriver/geckodriver doesn't generate double click event" if firefox_lt?(59, @session)
55
55
  when 'Capybara::Session selenium #accept_prompt should accept the prompt with a blank response when there is a default'
@@ -58,12 +58,17 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
58
58
  pending "FF < 62 doesn't support setting all files at once" if firefox_lt?(62, @session)
59
59
  when 'Capybara::Session selenium #accept_confirm should work with nested modals'
60
60
  skip 'Broken in 63 <= FF < 69 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session) && firefox_lt?(69, @session)
61
+ skip 'Hangs in 69 <= FF < 71 - Dont know what issue for this - previous issue was closed as fixed but it is not' if firefox_gte?(69, @session) && firefox_lt?(71, @session)
62
+ skip 'Broken again intermittently in FF 71 - jus skip it'
61
63
  when 'Capybara::Session selenium #click_link can download a file'
62
64
  skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
63
65
  when 'Capybara::Session selenium #reset_session! removes ALL cookies'
64
66
  pending "Geckodriver doesn't provide a way to remove cookies outside the current domain"
65
67
  when /drag_to.*HTML5/
66
68
  pending "Firefox < 62 doesn't support a DataTransfer constuctor" if firefox_lt?(62.0, @session)
69
+ when 'Capybara::Session selenium #accept_alert should handle the alert if the page changes',
70
+ 'Capybara::Session selenium #accept_alert with an asynchronous alert should accept the alert'
71
+ skip 'No clue what Firefox is doing here - works fine on MacOS locally'
67
72
  end
68
73
  end
69
74
 
@@ -181,7 +186,7 @@ RSpec.describe Capybara::Selenium::Driver do
181
186
  end
182
187
 
183
188
  RSpec.describe Capybara::Selenium::Node do
184
- context '#click' do
189
+ describe '#click' do
185
190
  it 'warns when attempting on a table row' do
186
191
  session = TestSessions::SeleniumFirefox
187
192
  session.visit('/tables')
@@ -74,6 +74,24 @@ RSpec.describe Capybara::Server do
74
74
  end
75
75
  end
76
76
 
77
+ it 'should handle that getting available ports fails randomly' do
78
+ # Use a port to force a EADDRINUSE error to be generated
79
+ server = TCPServer.new('0.0.0.0', 0)
80
+ server_port = server.addr[1]
81
+ d_server = instance_double('TCPServer', addr: [nil, server_port, nil, nil], close: nil)
82
+ call_count = 0
83
+ allow(TCPServer).to receive(:new).and_wrap_original do |m, *args|
84
+ call_count.zero? ? d_server : m.call(*args)
85
+ ensure
86
+ call_count += 1
87
+ end
88
+
89
+ port = described_class.new(Object.new, host: '0.0.0.0').port
90
+ expect(port).not_to eq(server_port)
91
+ ensure
92
+ server&.close
93
+ end
94
+
77
95
  it 'should return its #base_url' do
78
96
  app = proc { |_env| [200, {}, ['Hello Server!']] }
79
97
  server = described_class.new(app).boot
@@ -82,29 +100,27 @@ RSpec.describe Capybara::Server do
82
100
  end
83
101
 
84
102
  it 'should support SSL' do
85
- begin
86
- key = File.join(Dir.pwd, 'spec', 'fixtures', 'key.pem')
87
- cert = File.join(Dir.pwd, 'spec', 'fixtures', 'certificate.pem')
88
- Capybara.server = :puma, { Host: "ssl://#{Capybara.server_host}?key=#{key}&cert=#{cert}" }
89
- app = proc { |_env| [200, {}, ['Hello SSL Server!']] }
90
- server = described_class.new(app).boot
91
-
92
- expect do
93
- Net::HTTP.start(server.host, server.port, max_retries: 0) { |http| http.get('/__identify__') }
94
- end.to(raise_error do |e|
95
- expect(e.is_a?(EOFError) || e.is_a?(Net::ReadTimeout)).to be true
96
- end)
103
+ key = File.join(Dir.pwd, 'spec', 'fixtures', 'key.pem')
104
+ cert = File.join(Dir.pwd, 'spec', 'fixtures', 'certificate.pem')
105
+ Capybara.server = :puma, { Host: "ssl://#{Capybara.server_host}?key=#{key}&cert=#{cert}" }
106
+ app = proc { |_env| [200, {}, ['Hello SSL Server!']] }
107
+ server = described_class.new(app).boot
97
108
 
98
- res = Net::HTTP.start(server.host, server.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |https|
99
- https.get('/')
100
- end
109
+ expect do
110
+ Net::HTTP.start(server.host, server.port, max_retries: 0) { |http| http.get('/__identify__') }
111
+ end.to(raise_error do |e|
112
+ expect(e.is_a?(EOFError) || e.is_a?(Net::ReadTimeout)).to be true
113
+ end)
101
114
 
102
- expect(res.body).to include('Hello SSL Server!')
103
- uri = ::Addressable::URI.parse(server.base_url)
104
- expect(uri.to_hash).to include(scheme: 'https', host: server.host, port: server.port)
105
- ensure
106
- Capybara.server = :default
115
+ res = Net::HTTP.start(server.host, server.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_NONE) do |https|
116
+ https.get('/')
107
117
  end
118
+
119
+ expect(res.body).to include('Hello SSL Server!')
120
+ uri = ::Addressable::URI.parse(server.base_url)
121
+ expect(uri.to_hash).to include(scheme: 'https', host: server.host, port: server.port)
122
+ ensure
123
+ Capybara.server = :default
108
124
  end
109
125
 
110
126
  context 'When Capybara.reuse_server is true' do
@@ -202,19 +218,37 @@ RSpec.describe Capybara::Server do
202
218
  end
203
219
 
204
220
  it 'should raise server errors when the server errors before the timeout' do
205
- begin
206
- Capybara.register_server :kaboom do
207
- sleep 0.1
208
- raise 'kaboom'
209
- end
210
- Capybara.server = :kaboom
221
+ Capybara.register_server :kaboom do
222
+ sleep 0.1
223
+ raise 'kaboom'
224
+ end
225
+ Capybara.server = :kaboom
211
226
 
212
- expect do
213
- described_class.new(proc { |e| }).boot
214
- end.to raise_error(RuntimeError, 'kaboom')
215
- ensure
216
- Capybara.server = :default
227
+ expect do
228
+ described_class.new(proc { |e| }).boot
229
+ end.to raise_error(RuntimeError, 'kaboom')
230
+ ensure
231
+ Capybara.server = :default
232
+ end
233
+
234
+ it 'should raise an error when there are pending requests' do
235
+ app = proc do |env|
236
+ request = Rack::Request.new(env)
237
+ sleep request.params['wait_time'].to_f
238
+ [200, {}, ['Hello Server!']]
217
239
  end
240
+
241
+ server = described_class.new(app).boot
242
+
243
+ expect do
244
+ start_request(server, 59.0)
245
+ server.wait_for_pending_requests
246
+ end.not_to raise_error
247
+
248
+ expect do
249
+ start_request(server, 61.0)
250
+ server.wait_for_pending_requests
251
+ end.to raise_error('Requests did not finish in 60 seconds: ["/?wait_time=61.0"]')
218
252
  end
219
253
 
220
254
  it 'is not #responsive? when Net::HTTP raises a SystemCallError' do
@@ -3,7 +3,7 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Capybara::Session do
6
- context '#new' do
6
+ describe '#new' do
7
7
  it 'should raise an error if passed non-existent driver' do
8
8
  expect do
9
9
  described_class.new(:quox, TestApp).driver
@@ -6,7 +6,7 @@ require 'selenium-webdriver'
6
6
  RSpec.shared_examples 'Capybara::Node' do |session, _mode|
7
7
  let(:session) { session }
8
8
 
9
- context '#content_editable?' do
9
+ describe '#content_editable?' do
10
10
  it 'returns true when the element is content editable' do
11
11
  session.visit('/with_js')
12
12
  expect(session.find(:css, '#existing_content_editable').base.content_editable?).to be true
@@ -19,7 +19,7 @@ RSpec.shared_examples 'Capybara::Node' do |session, _mode|
19
19
  end
20
20
  end
21
21
 
22
- context '#send_keys' do
22
+ describe '#send_keys' do
23
23
  it 'should process space' do
24
24
  session.visit('/form')
25
25
  session.find(:css, '#address1_city').send_keys('ocean', [:shift, :space, 'side'])
@@ -27,7 +27,25 @@ RSpec.shared_examples 'Capybara::Node' do |session, _mode|
27
27
  end
28
28
  end
29
29
 
30
- context '#visible?' do
30
+ describe '#[]' do
31
+ it 'should work for spellcheck' do
32
+ session.visit('/with_html')
33
+ expect(session.find('//input[@spellcheck="TRUE"]')[:spellcheck]).to eq('true')
34
+ expect(session.find('//input[@spellcheck="FALSE"]')[:spellcheck]).to eq('false')
35
+ end
36
+ end
37
+
38
+ describe '#set' do
39
+ it 'respects maxlength when using rapid set' do
40
+ session.visit('/form')
41
+ inp = session.find(:css, '#long_length')
42
+ value = (0...50).map { |i| ((i % 26) + 65).chr }.join
43
+ inp.set(value, rapid: true)
44
+ expect(inp.value).to eq value[0...35]
45
+ end
46
+ end
47
+
48
+ describe '#visible?' do
31
49
  let(:bridge) do
32
50
  session.driver.browser.send(:bridge)
33
51
  end
@@ -72,7 +72,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
72
72
  end
73
73
  end
74
74
 
75
- context '#fill_in_with empty string and no options' do
75
+ describe '#fill_in_with empty string and no options' do
76
76
  it 'should trigger change when clearing a field' do
77
77
  pending "safaridriver doesn't trigger change for clear" if safari?(session)
78
78
  session.visit('/with_js')
@@ -83,7 +83,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
83
83
  end
84
84
  end
85
85
 
86
- context '#fill_in with { :clear => :backspace } fill_option', requires: [:js] do
86
+ describe '#fill_in with { :clear => :backspace } fill_option', requires: [:js] do
87
87
  before do
88
88
  # Firefox has an issue with change events if the main window doesn't think it's focused
89
89
  session.execute_script('window.focus()')
@@ -150,7 +150,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
150
150
  end
151
151
  end
152
152
 
153
- context '#fill_in with { clear: :none } fill_options' do
153
+ describe '#fill_in with { clear: :none } fill_options' do
154
154
  it 'should append to content in a field' do
155
155
  pending 'Safari overwrites by default - need to figure out a workaround' if safari?(session)
156
156
 
@@ -160,9 +160,18 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
160
160
  fill_options: { clear: :none })
161
161
  expect(session.find(:fillable_field, 'form_first_name').value).to eq('JohnHarry')
162
162
  end
163
+
164
+ it 'works with rapid fill' do
165
+ pending 'Safari overwrites by default - need to figure out a workaround' if safari?(session)
166
+
167
+ long_string = (0...60).map { |i| ((i % 26) + 65).chr }.join
168
+ session.visit('/form')
169
+ session.fill_in('form_first_name', with: long_string, fill_options: { clear: :none })
170
+ expect(session.find(:fillable_field, 'form_first_name').value).to eq('John' + long_string)
171
+ end
163
172
  end
164
173
 
165
- context '#fill_in with Date' do
174
+ describe '#fill_in with Date' do
166
175
  before do
167
176
  session.visit('/form')
168
177
  session.find(:css, '#form_date').execute_script <<-JS
@@ -194,7 +203,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
194
203
  end
195
204
  end
196
205
 
197
- context '#fill_in with { clear: Array } fill_options' do
206
+ describe '#fill_in with { clear: Array } fill_options' do
198
207
  it 'should pass the array through to the element' do
199
208
  # this is mainly for use with [[:control, 'a'], :backspace] - however since that is platform dependant I'm testing with something less useful
200
209
  session.visit('/form')
@@ -299,8 +308,9 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
299
308
  describe 'Element#click' do
300
309
  it 'should handle fixed headers/footers' do
301
310
  session.visit('/with_fixed_header_footer')
302
- # session.click_link('Go to root')
303
- session.find(:link, 'Go to root').click
311
+ session.using_wait_time(2) do
312
+ session.find(:link, 'Go to root').click
313
+ end
304
314
  expect(session).to have_current_path('/')
305
315
  end
306
316
  end
@@ -424,7 +434,7 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
424
434
  it 'can find html5 svg elements' do
425
435
  session.visit('with_html5_svg')
426
436
  expect(session).to have_selector(:element, :svg)
427
- expect(session).to have_selector(:element, :rect, visible: true)
437
+ expect(session).to have_selector(:element, :rect, visible: :visible)
428
438
  expect(session).to have_selector(:element, :circle)
429
439
  expect(session).to have_selector(:element, :linearGradient, visible: :all)
430
440
  end
@@ -440,21 +450,30 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
440
450
  context 'controlled components' do
441
451
  it 'can set and clear a text field' do
442
452
  skip "This test doesn't support older browsers" if ie?(session)
443
- # session.visit 'https://reactjs.org/docs/forms.html'
444
- # session.all(:css, 'h2#controlled-components ~ p a', text: 'Try it on CodePen')[0].click
445
- # copied into local view
453
+
446
454
  session.visit 'react'
447
- # Not necessary when accessed locally
448
- # session.within_frame(:css, 'iframe.result-iframe:not([src=""])', wait: 10) do
455
+
449
456
  session.fill_in('Name:', with: 'abc')
450
457
  session.accept_prompt 'A name was submitted: abc' do
451
458
  session.click_button('Submit')
452
459
  end
460
+
453
461
  session.fill_in('Name:', with: '')
454
462
  session.accept_prompt(/A name was submitted: $/) do
455
463
  session.click_button('Submit')
456
464
  end
457
- # end
465
+ end
466
+
467
+ it 'works with rapid fill' do
468
+ skip "This test doesn't support older browsers" if ie?(session)
469
+
470
+ session.visit 'react'
471
+ long_string = (0...60).map { |i| ((i % 26) + 65).chr }.join
472
+
473
+ session.fill_in('Name:', with: long_string)
474
+ session.accept_prompt "A name was submitted: #{long_string}" do
475
+ session.click_button('Submit')
476
+ end
458
477
  end
459
478
  end
460
479
  end
@@ -46,7 +46,7 @@ module Capybara
46
46
  end
47
47
 
48
48
  def edge?(session)
49
- browser_name(session).match?(/^edge/)
49
+ browser_name(session).to_s.start_with?('edge')
50
50
  end
51
51
 
52
52
  def legacy_edge?(session)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.29.0
4
+ version: 3.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Walpole
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
12
  - gem-public_cert.pem
13
- date: 2019-09-02 00:00:00.000000000 Z
13
+ date: 2020-06-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: addressable
@@ -450,6 +450,7 @@ files:
450
450
  - lib/capybara/rack_test/form.rb
451
451
  - lib/capybara/rack_test/node.rb
452
452
  - lib/capybara/rails.rb
453
+ - lib/capybara/registration_container.rb
453
454
  - lib/capybara/registrations/drivers.rb
454
455
  - lib/capybara/registrations/patches/puma_ssl.rb
455
456
  - lib/capybara/registrations/servers.rb
@@ -528,6 +529,7 @@ files:
528
529
  - lib/capybara/selenium/nodes/firefox_node.rb
529
530
  - lib/capybara/selenium/nodes/ie_node.rb
530
531
  - lib/capybara/selenium/nodes/safari_node.rb
532
+ - lib/capybara/selenium/patches/action_pauser.rb
531
533
  - lib/capybara/selenium/patches/atoms.rb
532
534
  - lib/capybara/selenium/patches/is_displayed.rb
533
535
  - lib/capybara/selenium/patches/logs.rb
@@ -737,14 +739,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
737
739
  requirements:
738
740
  - - ">="
739
741
  - !ruby/object:Gem::Version
740
- version: 2.4.0
742
+ version: 2.5.0
741
743
  required_rubygems_version: !ruby/object:Gem::Requirement
742
744
  requirements:
743
745
  - - ">="
744
746
  - !ruby/object:Gem::Version
745
747
  version: '0'
746
748
  requirements: []
747
- rubygems_version: 3.0.6
749
+ rubygems_version: 3.1.2
748
750
  signing_key:
749
751
  specification_version: 4
750
752
  summary: Capybara aims to simplify the process of integration testing Rack applications,