capybara 3.3.1 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (159) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +16 -0
  3. data/README.md +5 -7
  4. data/lib/capybara.rb +7 -6
  5. data/lib/capybara/config.rb +1 -1
  6. data/lib/capybara/dsl.rb +2 -2
  7. data/lib/capybara/helpers.rb +3 -3
  8. data/lib/capybara/minitest/spec.rb +3 -3
  9. data/lib/capybara/node/actions.rb +18 -18
  10. data/lib/capybara/node/base.rb +1 -1
  11. data/lib/capybara/node/element.rb +2 -2
  12. data/lib/capybara/node/finders.rb +6 -6
  13. data/lib/capybara/node/matchers.rb +5 -5
  14. data/lib/capybara/node/simple.rb +2 -2
  15. data/lib/capybara/queries/ancestor_query.rb +1 -1
  16. data/lib/capybara/queries/base_query.rb +12 -11
  17. data/lib/capybara/queries/current_path_query.rb +1 -1
  18. data/lib/capybara/queries/selector_query.rb +39 -15
  19. data/lib/capybara/queries/sibling_query.rb +1 -1
  20. data/lib/capybara/queries/text_query.rb +1 -1
  21. data/lib/capybara/rack_test/browser.rb +7 -7
  22. data/lib/capybara/rack_test/driver.rb +1 -1
  23. data/lib/capybara/rack_test/form.rb +7 -7
  24. data/lib/capybara/rack_test/node.rb +16 -16
  25. data/lib/capybara/rails.rb +1 -1
  26. data/lib/capybara/result.rb +8 -4
  27. data/lib/capybara/rspec/features.rb +4 -4
  28. data/lib/capybara/rspec/matchers.rb +6 -6
  29. data/lib/capybara/selector.rb +106 -90
  30. data/lib/capybara/selector/css.rb +4 -4
  31. data/lib/capybara/selector/filter_set.rb +52 -8
  32. data/lib/capybara/selector/selector.rb +39 -15
  33. data/lib/capybara/selenium/driver.rb +10 -10
  34. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +8 -0
  35. data/lib/capybara/selenium/node.rb +9 -10
  36. data/lib/capybara/selenium/nodes/chrome_node.rb +18 -0
  37. data/lib/capybara/selenium/nodes/marionette_node.rb +32 -7
  38. data/lib/capybara/server.rb +3 -3
  39. data/lib/capybara/server/animation_disabler.rb +1 -1
  40. data/lib/capybara/server/middleware.rb +1 -1
  41. data/lib/capybara/session.rb +23 -19
  42. data/lib/capybara/session/config.rb +18 -3
  43. data/lib/capybara/spec/public/test.js +1 -1
  44. data/lib/capybara/spec/session/accept_alert_spec.rb +10 -10
  45. data/lib/capybara/spec/session/accept_confirm_spec.rb +3 -3
  46. data/lib/capybara/spec/session/accept_prompt_spec.rb +9 -10
  47. data/lib/capybara/spec/session/all_spec.rb +33 -32
  48. data/lib/capybara/spec/session/ancestor_spec.rb +19 -19
  49. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +38 -38
  50. data/lib/capybara/spec/session/assert_current_path_spec.rb +16 -16
  51. data/lib/capybara/spec/session/assert_selector_spec.rb +53 -53
  52. data/lib/capybara/spec/session/assert_style_spec.rb +3 -3
  53. data/lib/capybara/spec/session/assert_text_spec.rb +31 -30
  54. data/lib/capybara/spec/session/assert_title_spec.rb +12 -12
  55. data/lib/capybara/spec/session/attach_file_spec.rb +51 -52
  56. data/lib/capybara/spec/session/body_spec.rb +6 -6
  57. data/lib/capybara/spec/session/check_spec.rb +52 -47
  58. data/lib/capybara/spec/session/choose_spec.rb +32 -32
  59. data/lib/capybara/spec/session/click_button_spec.rb +103 -103
  60. data/lib/capybara/spec/session/click_link_or_button_spec.rb +24 -23
  61. data/lib/capybara/spec/session/click_link_spec.rb +49 -48
  62. data/lib/capybara/spec/session/current_scope_spec.rb +7 -7
  63. data/lib/capybara/spec/session/current_url_spec.rb +26 -27
  64. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
  65. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +2 -2
  66. data/lib/capybara/spec/session/element/assert_match_selector_spec.rb +8 -8
  67. data/lib/capybara/spec/session/element/match_css_spec.rb +10 -10
  68. data/lib/capybara/spec/session/element/match_xpath_spec.rb +6 -6
  69. data/lib/capybara/spec/session/element/matches_selector_spec.rb +51 -51
  70. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +7 -7
  71. data/lib/capybara/spec/session/evaluate_script_spec.rb +15 -8
  72. data/lib/capybara/spec/session/execute_script_spec.rb +7 -7
  73. data/lib/capybara/spec/session/fill_in_spec.rb +43 -42
  74. data/lib/capybara/spec/session/find_button_spec.rb +23 -23
  75. data/lib/capybara/spec/session/find_by_id_spec.rb +7 -7
  76. data/lib/capybara/spec/session/find_field_spec.rb +32 -30
  77. data/lib/capybara/spec/session/find_link_spec.rb +21 -21
  78. data/lib/capybara/spec/session/find_spec.rb +153 -135
  79. data/lib/capybara/spec/session/first_spec.rb +41 -41
  80. data/lib/capybara/spec/session/frame/frame_title_spec.rb +5 -5
  81. data/lib/capybara/spec/session/frame/frame_url_spec.rb +5 -5
  82. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +17 -17
  83. data/lib/capybara/spec/session/frame/within_frame_spec.rb +31 -17
  84. data/lib/capybara/spec/session/go_back_spec.rb +1 -1
  85. data/lib/capybara/spec/session/go_forward_spec.rb +1 -1
  86. data/lib/capybara/spec/session/has_all_selectors_spec.rb +17 -17
  87. data/lib/capybara/spec/session/has_button_spec.rb +13 -13
  88. data/lib/capybara/spec/session/has_css_spec.rb +133 -131
  89. data/lib/capybara/spec/session/has_current_path_spec.rb +29 -29
  90. data/lib/capybara/spec/session/has_field_spec.rb +58 -58
  91. data/lib/capybara/spec/session/has_link_spec.rb +4 -4
  92. data/lib/capybara/spec/session/has_none_selectors_spec.rb +24 -24
  93. data/lib/capybara/spec/session/has_select_spec.rb +43 -43
  94. data/lib/capybara/spec/session/has_selector_spec.rb +71 -71
  95. data/lib/capybara/spec/session/has_style_spec.rb +3 -3
  96. data/lib/capybara/spec/session/has_table_spec.rb +4 -4
  97. data/lib/capybara/spec/session/has_text_spec.rb +53 -52
  98. data/lib/capybara/spec/session/has_title_spec.rb +14 -14
  99. data/lib/capybara/spec/session/has_xpath_spec.rb +39 -38
  100. data/lib/capybara/spec/session/headers_spec.rb +1 -1
  101. data/lib/capybara/spec/session/html_spec.rb +6 -6
  102. data/lib/capybara/spec/session/node_spec.rb +129 -123
  103. data/lib/capybara/spec/session/node_wrapper_spec.rb +10 -7
  104. data/lib/capybara/spec/session/refresh_spec.rb +4 -7
  105. data/lib/capybara/spec/session/reset_session_spec.rb +28 -28
  106. data/lib/capybara/spec/session/response_code_spec.rb +1 -1
  107. data/lib/capybara/spec/session/save_and_open_page_spec.rb +2 -2
  108. data/lib/capybara/spec/session/save_page_spec.rb +37 -37
  109. data/lib/capybara/spec/session/save_screenshot_spec.rb +6 -6
  110. data/lib/capybara/spec/session/screenshot_spec.rb +2 -2
  111. data/lib/capybara/spec/session/select_spec.rb +81 -81
  112. data/lib/capybara/spec/session/selectors_spec.rb +17 -17
  113. data/lib/capybara/spec/session/sibling_spec.rb +9 -9
  114. data/lib/capybara/spec/session/text_spec.rb +23 -23
  115. data/lib/capybara/spec/session/title_spec.rb +5 -5
  116. data/lib/capybara/spec/session/uncheck_spec.rb +24 -20
  117. data/lib/capybara/spec/session/unselect_spec.rb +37 -37
  118. data/lib/capybara/spec/session/visit_spec.rb +48 -49
  119. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -1
  120. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +16 -16
  121. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +2 -2
  122. data/lib/capybara/spec/session/window/window_spec.rb +4 -4
  123. data/lib/capybara/spec/session/window/within_window_spec.rb +14 -14
  124. data/lib/capybara/spec/session/within_spec.rb +41 -41
  125. data/lib/capybara/spec/spec_helper.rb +11 -9
  126. data/lib/capybara/spec/test_app.rb +18 -17
  127. data/lib/capybara/spec/views/form.erb +29 -31
  128. data/lib/capybara/spec/views/with_html.erb +2 -2
  129. data/lib/capybara/version.rb +1 -1
  130. data/spec/basic_node_spec.rb +23 -23
  131. data/spec/capybara_spec.rb +20 -20
  132. data/spec/css_splitter_spec.rb +7 -7
  133. data/spec/dsl_spec.rb +37 -32
  134. data/spec/filter_set_spec.rb +4 -4
  135. data/spec/fixtures/selenium_driver_rspec_failure.rb +1 -1
  136. data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
  137. data/spec/minitest_spec.rb +4 -4
  138. data/spec/minitest_spec_spec.rb +23 -23
  139. data/spec/per_session_config_spec.rb +5 -5
  140. data/spec/rack_test_spec.rb +44 -44
  141. data/spec/result_spec.rb +14 -14
  142. data/spec/rspec/features_spec.rb +13 -13
  143. data/spec/rspec/scenarios_spec.rb +4 -4
  144. data/spec/rspec/shared_spec_matchers.rb +282 -281
  145. data/spec/rspec/views_spec.rb +3 -3
  146. data/spec/rspec_matchers_spec.rb +10 -10
  147. data/spec/rspec_spec.rb +29 -29
  148. data/spec/selector_spec.rb +64 -64
  149. data/spec/selenium_spec_chrome.rb +14 -22
  150. data/spec/selenium_spec_chrome_remote.rb +28 -8
  151. data/spec/selenium_spec_edge.rb +9 -4
  152. data/spec/selenium_spec_firefox_remote.rb +87 -0
  153. data/spec/selenium_spec_ie.rb +9 -4
  154. data/spec/selenium_spec_marionette.rb +42 -18
  155. data/spec/server_spec.rb +29 -27
  156. data/spec/session_spec.rb +17 -17
  157. data/spec/shared_selenium_session.rb +70 -52
  158. data/spec/spec_helper.rb +1 -1
  159. metadata +4 -2
@@ -13,13 +13,7 @@ CHROME_DRIVER = ENV['HEADLESS'] ? :selenium_chrome_headless : :selenium_chrome
13
13
 
14
14
  Capybara.register_driver :selenium_chrome do |app|
15
15
  driver = Capybara::Selenium::Driver.new(app, browser: :chrome)
16
- # TODO: Fix this when selenium with `download_path =` support is released
17
- bridge = driver.browser.send(:bridge)
18
- params = { cmd: 'Page.setDownloadBehavior', params: { behavior: 'allow', downloadPath: Capybara.save_path } }
19
- command = +'/session/:session_id/chromium/send_command'
20
- command[':session_id'] = bridge.session_id
21
- bridge.http.call(:post, command, params)
22
-
16
+ driver.browser.download_path = Capybara.save_path
23
17
  driver
24
18
  end
25
19
 
@@ -28,14 +22,7 @@ Capybara.register_driver :selenium_chrome_headless do |app|
28
22
  browser_options.args << '--headless'
29
23
  browser_options.args << '--disable-gpu' if Gem.win_platform?
30
24
  driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
31
-
32
- # TODO: Fix this when selenium with `download_path =` support is released
33
- bridge = driver.browser.send(:bridge)
34
- params = { cmd: 'Page.setDownloadBehavior', params: { behavior: 'allow', downloadPath: Capybara.save_path } }
35
- command = +'/session/:session_id/chromium/send_command'
36
- command[':session_id'] = bridge.session_id
37
- bridge.http.call(:post, command, params)
38
-
25
+ driver.browser.download_path = Capybara.save_path
39
26
  driver
40
27
  end
41
28
 
@@ -58,16 +45,21 @@ skipped_tests << :windows if ENV['TRAVIS'] && (ENV['SKIP_WINDOW'] || ENV['HEADLE
58
45
 
59
46
  $stdout.puts `#{Selenium::WebDriver::Chrome.driver_path} --version` if ENV['CI']
60
47
 
61
- Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybara_skip: skipped_tests
48
+ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybara_skip: skipped_tests do |example|
49
+ case example.metadata[:description]
50
+ when /should fetch a response when sequentially visiting same destination with a target/
51
+ skip 'Chrome/chromedriver has an issue visiting URL with target after visiting same URL without target' if chrome_lt?(65.0, @session)
52
+ end
53
+ end
62
54
 
63
- RSpec.describe "Capybara::Session with chrome" do
55
+ RSpec.describe 'Capybara::Session with chrome' do
64
56
  include Capybara::SpecHelper
65
- include_examples "Capybara::Session", TestSessions::Chrome, CHROME_DRIVER
57
+ include_examples 'Capybara::Session', TestSessions::Chrome, CHROME_DRIVER
66
58
  include_examples Capybara::RSpecMatchers, TestSessions::Chrome, CHROME_DRIVER
67
59
 
68
- context "storage" do
69
- describe "#reset!" do
70
- it "does not clear either storage by default" do
60
+ context 'storage' do
61
+ describe '#reset!' do
62
+ it 'does not clear either storage by default' do
71
63
  @session = TestSessions::Chrome
72
64
  @session.visit('/with_js')
73
65
  @session.find(:css, '#set-storage').click
@@ -79,7 +71,7 @@ RSpec.describe "Capybara::Session with chrome" do
79
71
  expect(@session.evaluate_script('Object.keys(sessionStorage)')).not_to be_empty
80
72
  end
81
73
 
82
- it "clears storage when set" do
74
+ it 'clears storage when set' do
83
75
  @session = Capybara::Session.new(:selenium_chrome_clear_storage, TestApp)
84
76
  @session.visit('/with_js')
85
77
  @session.find(:css, '#set-storage').click
@@ -14,11 +14,20 @@ def selenium_port
14
14
  end
15
15
 
16
16
  def ensure_selenium_running!
17
- TCPSocket.open(selenium_host, selenium_port)
18
- rescue
19
- raise 'Selenium is not running. ' \
20
- "You can run a selenium server easily with: \n" \
21
- ' $ docker-compose up -d selenium'
17
+ timer = Capybara::Helpers.timer(expire_in: 20)
18
+ begin
19
+ TCPSocket.open(selenium_host, selenium_port)
20
+ rescue StandardError
21
+ if timer.expired?
22
+ raise 'Selenium is not running. ' \
23
+ "You can run a selenium server easily with: \n" \
24
+ ' $ docker-compose up -d selenium_chrome'
25
+ else
26
+ puts 'Waiting for Selenium docker instance...'
27
+ sleep 1
28
+ retry
29
+ end
30
+ end
22
31
  end
23
32
 
24
33
  Capybara.register_driver :selenium_chrome_remote do |app|
@@ -39,15 +48,26 @@ module TestSessions
39
48
  Chrome = Capybara::Session.new(CHROME_REMOTE_DRIVER, TestApp)
40
49
  end
41
50
 
51
+ TestSessions::Chrome.driver.browser.file_detector = lambda do |args|
52
+ # args => ["/path/to/file"]
53
+ str = args.first.to_s
54
+ str if File.exist?(str)
55
+ end
56
+
42
57
  skipped_tests = %i[response_headers status_code trigger download]
43
58
  # skip window tests when headless for now - closing a window not supported by chromedriver/chrome
44
59
  skipped_tests << :windows if ENV['TRAVIS'] && (ENV['SKIP_WINDOW'] || ENV['HEADLESS'])
45
60
 
46
- Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests
61
+ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
62
+ case example.metadata[:full_description]
63
+ when 'Capybara::Session selenium_chrome_remote #attach_file with multipart form should not break when using HTML5 multiple file input uploading multiple files'
64
+ pending "Selenium with Remote Chrome doesn't support multiple file upload"
65
+ end
66
+ end
47
67
 
48
- RSpec.describe "Capybara::Session with chrome" do
68
+ RSpec.describe 'Capybara::Session with remote Chrome' do
49
69
  include Capybara::SpecHelper
50
- include_examples "Capybara::Session", TestSessions::Chrome, CHROME_REMOTE_DRIVER
70
+ include_examples 'Capybara::Session', TestSessions::Chrome, CHROME_REMOTE_DRIVER
51
71
  include_examples Capybara::RSpecMatchers, TestSessions::Chrome, CHROME_REMOTE_DRIVER
52
72
 
53
73
  it 'is considered to be chrome' do
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require "selenium-webdriver"
4
+ require 'selenium-webdriver'
5
5
  require 'shared_selenium_session'
6
6
  require 'rspec/shared_spec_matchers'
7
7
 
@@ -18,10 +18,15 @@ skipped_tests = %i[response_headers status_code trigger modals]
18
18
 
19
19
  $stdout.puts `#{Selenium::WebDriver::Edge.driver_path} --version` if ENV['CI']
20
20
 
21
- Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, "selenium", capybara_skip: skipped_tests
21
+ Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, 'selenium', capybara_skip: skipped_tests do |example|
22
+ case example.metadata[:description]
23
+ when /#refresh it reposts$/
24
+ skip 'Edge insists on prompting without providing a way to suppress'
25
+ end
26
+ end
22
27
 
23
- RSpec.describe "Capybara::Session with Edge", capybara_skip: skipped_tests do
28
+ RSpec.describe 'Capybara::Session with Edge', capybara_skip: skipped_tests do
24
29
  include Capybara::SpecHelper
25
- include_examples "Capybara::Session", TestSessions::SeleniumEdge, :selenium_edge
30
+ include_examples 'Capybara::Session', TestSessions::SeleniumEdge, :selenium_edge
26
31
  include_examples Capybara::RSpecMatchers, TestSessions::SeleniumEdge, :selenium_edge
27
32
  end
@@ -0,0 +1,87 @@
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
+ def selenium_host
9
+ ENV.fetch('SELENIUM_HOST', '0.0.0.0')
10
+ end
11
+
12
+ def selenium_port
13
+ ENV.fetch('SELENIUM_PORT', 4445)
14
+ end
15
+
16
+ def ensure_selenium_running!
17
+ timer = Capybara::Helpers.timer(expire_in: 20)
18
+ begin
19
+ TCPSocket.open(selenium_host, selenium_port)
20
+ rescue StandardError
21
+ if timer.expired?
22
+ raise 'Selenium is not running. ' \
23
+ "You can run a selenium server easily with: \n" \
24
+ ' $ docker-compose up -d selenium_firefox'
25
+ else
26
+ puts 'Waiting for Selenium docker instance...'
27
+ sleep 1
28
+ retry
29
+ end
30
+ end
31
+ end
32
+
33
+ Capybara.register_driver :selenium_firefox_remote do |app|
34
+ ensure_selenium_running!
35
+
36
+ url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
37
+ caps = Selenium::WebDriver::Remote::Capabilities.firefox
38
+
39
+ Capybara::Selenium::Driver.new app,
40
+ browser: :remote,
41
+ desired_capabilities: caps,
42
+ url: url
43
+ end
44
+
45
+ FIREFOX_REMOTE_DRIVER = :selenium_firefox_remote
46
+
47
+ module TestSessions
48
+ RemoteFirefox = Capybara::Session.new(FIREFOX_REMOTE_DRIVER, TestApp)
49
+ end
50
+
51
+ TestSessions::RemoteFirefox.driver.browser.file_detector = lambda do |args|
52
+ # args => ["/path/to/file"]
53
+ str = args.first.to_s
54
+ str if File.exist?(str)
55
+ end
56
+
57
+ skipped_tests = %i[response_headers status_code trigger download]
58
+ # skip window tests when headless for now - closing a window not supported by chromedriver/chrome
59
+ skipped_tests << :windows if ENV['TRAVIS'] && (ENV['SKIP_WINDOW'] || ENV['HEADLESS'])
60
+
61
+ Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
62
+ case example.metadata[:full_description]
63
+ when 'Capybara::Session selenium_firefox_remote node #send_keys should generate key events',
64
+ 'Capybara::Session selenium_firefox_remote node #send_keys should allow for multiple simultaneous keys',
65
+ 'Capybara::Session selenium_firefox_remote node #send_keys should send special characters'
66
+ pending "selenium-webdriver/geckodriver doesn't support complex sets of characters"
67
+ when 'Capybara::Session selenium_firefox_remote node #click should allow multiple modifiers'
68
+ pending "Firefox doesn't generate an event for shift+control+click" if marionette_gte?(62, @session)
69
+ when /^Capybara::Session selenium node #double_click/
70
+ pending "selenium-webdriver/geckodriver doesn't generate double click event" if marionette_lt?(59, @session)
71
+ when 'Capybara::Session selenium_firefox_remote #refresh it reposts'
72
+ skip 'Firefox insists on prompting without providing a way to suppress'
73
+ when 'Capybara::Session selenium_firefox_remote #accept_prompt should accept the prompt with a blank response when there is a default'
74
+ pending "Geckodriver doesn't set a blank response currently"
75
+ end
76
+ end
77
+
78
+ RSpec.describe 'Capybara::Session with remote firefox' do
79
+ include Capybara::SpecHelper
80
+ include_examples 'Capybara::Session', TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVER
81
+ include_examples Capybara::RSpecMatchers, TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVER
82
+
83
+ it 'is considered to be firefox' do
84
+ expect(session.driver.send(:firefox?)).to be_truthy
85
+ expect(session.driver.send(:marionette?)).to be_truthy
86
+ end
87
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require "selenium-webdriver"
4
+ require 'selenium-webdriver'
5
5
  require 'shared_selenium_session'
6
6
  require 'rspec/shared_spec_matchers'
7
7
 
@@ -22,10 +22,15 @@ skipped_tests = %i[response_headers status_code trigger modals hover form_attrib
22
22
 
23
23
  $stdout.puts `#{Selenium::WebDriver::IE.driver_path} --version` if ENV['CI']
24
24
 
25
- Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, "selenium", capybara_skip: skipped_tests
25
+ Capybara::SpecHelper.run_specs TestSessions::SeleniumIE, 'selenium', capybara_skip: skipped_tests do |example|
26
+ case example.metadata[:description]
27
+ when /#refresh it reposts$/
28
+ skip 'Firefox and Edge insist on prompting without providing a way to suppress'
29
+ end
30
+ end
26
31
 
27
- RSpec.describe "Capybara::Session with Internet Explorer", capybara_skip: skipped_tests do
32
+ RSpec.describe 'Capybara::Session with Internet Explorer', capybara_skip: skipped_tests do
28
33
  include Capybara::SpecHelper
29
- include_examples "Capybara::Session", TestSessions::SeleniumIE, :selenium_ie
34
+ include_examples 'Capybara::Session', TestSessions::SeleniumIE, :selenium_ie
30
35
  include_examples Capybara::RSpecMatchers, TestSessions::SeleniumIE, :selenium_ie
31
36
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require "selenium-webdriver"
4
+ require 'selenium-webdriver'
5
5
  require 'shared_selenium_session'
6
6
  require 'rspec/shared_spec_matchers'
7
7
 
@@ -48,11 +48,26 @@ skipped_tests << :windows if ENV['TRAVIS'] && ENV['SKIP_WINDOW']
48
48
 
49
49
  $stdout.puts `#{Selenium::WebDriver::Firefox.driver_path} --version` if ENV['CI']
50
50
 
51
- Capybara::SpecHelper.run_specs TestSessions::SeleniumMarionette, "selenium", capybara_skip: skipped_tests
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 #send_keys should generate key events',
54
+ 'Capybara::Session selenium node #send_keys should allow for multiple simultaneous keys',
55
+ 'Capybara::Session selenium node #send_keys should send special characters'
56
+ pending "selenium-webdriver/geckodriver doesn't support complex sets of characters"
57
+ when 'Capybara::Session selenium node #click should allow multiple modifiers'
58
+ pending "Firefox doesn't generate an event for shift+control+click" if marionette_gte?(62, @session)
59
+ when /^Capybara::Session selenium node #double_click/
60
+ pending "selenium-webdriver/geckodriver doesn't generate double click event" if marionette_lt?(59, @session)
61
+ when 'Capybara::Session selenium #refresh it reposts'
62
+ skip 'Firefox insists on prompting without providing a way to suppress'
63
+ when 'Capybara::Session selenium #accept_prompt should accept the prompt with a blank response when there is a default'
64
+ pending "Geckodriver doesn't set a blank response currently"
65
+ end
66
+ end
52
67
 
53
- RSpec.describe "Capybara::Session with firefox" do # rubocop:disable RSpec/MultipleDescribes
68
+ RSpec.describe 'Capybara::Session with firefox' do # rubocop:disable RSpec/MultipleDescribes
54
69
  include Capybara::SpecHelper
55
- include_examples "Capybara::Session", TestSessions::SeleniumMarionette, :selenium_marionette
70
+ include_examples 'Capybara::Session', TestSessions::SeleniumMarionette, :selenium_marionette
56
71
  include_examples Capybara::RSpecMatchers, TestSessions::SeleniumMarionette, :selenium_marionette
57
72
  end
58
73
 
@@ -62,14 +77,14 @@ RSpec.describe Capybara::Selenium::Driver do
62
77
  end
63
78
 
64
79
  describe '#quit' do
65
- it "should reset browser when quit" do
80
+ it 'should reset browser when quit' do
66
81
  expect(@driver.browser).to be_truthy
67
82
  @driver.quit
68
83
  # access instance variable directly so we don't create a new browser instance
69
84
  expect(@driver.instance_variable_get(:@browser)).to be_nil
70
85
  end
71
86
 
72
- context "with errors" do
87
+ context 'with errors' do
73
88
  before do
74
89
  @original_browser = @driver.browser
75
90
  end
@@ -80,11 +95,11 @@ RSpec.describe Capybara::Selenium::Driver do
80
95
  @original_browser.quit
81
96
  end
82
97
 
83
- it "warns UnknownError returned during quit because the browser is probably already gone" do
98
+ it 'warns UnknownError returned during quit because the browser is probably already gone' do
84
99
  allow(@driver).to receive(:warn)
85
100
  allow(@driver.browser).to(
86
101
  receive(:quit)
87
- .and_raise(Selenium::WebDriver::Error::UnknownError, "random message")
102
+ .and_raise(Selenium::WebDriver::Error::UnknownError, 'random message')
88
103
  )
89
104
 
90
105
  expect { @driver.quit }.not_to raise_error
@@ -92,11 +107,11 @@ RSpec.describe Capybara::Selenium::Driver do
92
107
  expect(@driver).to have_received(:warn).with(/random message/)
93
108
  end
94
109
 
95
- it "ignores silenced UnknownError returned during quit because the browser is almost definitely already gone" do
110
+ it 'ignores silenced UnknownError returned during quit because the browser is almost definitely already gone' do
96
111
  allow(@driver).to receive(:warn)
97
112
  allow(@driver.browser).to(
98
113
  receive(:quit)
99
- .and_raise(Selenium::WebDriver::Error::UnknownError, "Error communicating with the remote browser")
114
+ .and_raise(Selenium::WebDriver::Error::UnknownError, 'Error communicating with the remote browser')
100
115
  )
101
116
 
102
117
  expect { @driver.quit }.not_to raise_error
@@ -106,9 +121,9 @@ RSpec.describe Capybara::Selenium::Driver do
106
121
  end
107
122
  end
108
123
 
109
- context "storage" do
110
- describe "#reset!" do
111
- it "does not clear either storage by default" do
124
+ context 'storage' do
125
+ describe '#reset!' do
126
+ it 'does not clear either storage by default' do
112
127
  @session = TestSessions::SeleniumMarionette
113
128
  @session.visit('/with_js')
114
129
  @session.find(:css, '#set-storage').click
@@ -118,7 +133,7 @@ RSpec.describe Capybara::Selenium::Driver do
118
133
  expect(@session.driver.browser.session_storage.keys).not_to be_empty
119
134
  end
120
135
 
121
- it "clears storage when set" do
136
+ it 'clears storage when set' do
122
137
  @session = Capybara::Session.new(:selenium_marionette_clear_storage, TestApp)
123
138
  @session.visit('/with_js')
124
139
  @session.find(:css, '#set-storage').click
@@ -130,13 +145,13 @@ RSpec.describe Capybara::Selenium::Driver do
130
145
  end
131
146
  end
132
147
 
133
- context "#refresh" do
148
+ context '#refresh' do
134
149
  def extract_results(session)
135
150
  expect(session).to have_xpath("//pre[@id='results']")
136
151
  YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
137
152
  end
138
153
 
139
- it "can repost by accepting confirm" do
154
+ it 'can repost by accepting confirm' do
140
155
  @session = TestSessions::SeleniumMarionette
141
156
  @session.visit('/form')
142
157
  @session.select('Sweden', from: 'form_region')
@@ -154,8 +169,8 @@ RSpec.describe Capybara::Selenium::Driver do
154
169
  end
155
170
 
156
171
  RSpec.describe Capybara::Selenium::Node do
157
- context "#click" do
158
- it "warns when attempting on a table row" do
172
+ context '#click' do
173
+ it 'warns when attempting on a table row' do
159
174
  session = TestSessions::SeleniumMarionette
160
175
  session.visit('/tables')
161
176
  tr = session.find(:css, '#agent_table tr:first-child')
@@ -163,5 +178,14 @@ RSpec.describe Capybara::Selenium::Node do
163
178
  tr.click
164
179
  expect(tr.base).to have_received(:warn).with(/Clicking the first cell in the row instead/)
165
180
  end
181
+
182
+ it 'should allow multiple modifiers', requires: [:js] do
183
+ session = TestSessions::SeleniumMarionette
184
+ session.visit('with_js')
185
+ # Firefox v62+ doesn't generate an event for control+shift+click
186
+ session.find(:css, '#click-test').click(:alt, :ctrl, :meta)
187
+ # it also triggers a contextmenu event when control is held so don't check click type
188
+ expect(session).to have_link('Has been alt control meta')
189
+ end
166
190
  end
167
191
  end
@@ -3,8 +3,8 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  RSpec.describe Capybara::Server do
6
- it "should spool up a rack server" do
7
- @app = proc { |_env| [200, {}, ["Hello Server!"]] }
6
+ it 'should spool up a rack server' do
7
+ @app = proc { |_env| [200, {}, ['Hello Server!']] }
8
8
  @server = Capybara::Server.new(@app).boot
9
9
 
10
10
  @res = Net::HTTP.start(@server.host, @server.port) { |http| http.get('/') }
@@ -12,14 +12,16 @@ RSpec.describe Capybara::Server do
12
12
  expect(@res.body).to include('Hello Server')
13
13
  end
14
14
 
15
- it "should do nothing when no server given" do
15
+ it 'should do nothing when no server given' do
16
16
  expect do
17
17
  @server = Capybara::Server.new(nil).boot
18
18
  end.not_to raise_error
19
19
  end
20
20
 
21
- it "should bind to the specified host" do
21
+ it 'should bind to the specified host' do
22
22
  # TODO: travis with jruby in container mode has an issue with this test
23
+ skip 'This platform has an issue with this test' if (ENV['TRAVIS'] && (RUBY_ENGINE == 'jruby')) || Gem.win_platform?
24
+
23
25
  begin
24
26
  app = proc { |_env| [200, {}, ['Hello Server!']] }
25
27
 
@@ -35,12 +37,12 @@ RSpec.describe Capybara::Server do
35
37
  ensure
36
38
  Capybara.server_host = nil
37
39
  end
38
- end unless (ENV['TRAVIS'] && (RUBY_ENGINE == 'jruby')) || Gem.win_platform?
40
+ end
39
41
 
40
- it "should use specified port" do
42
+ it 'should use specified port' do
41
43
  Capybara.server_port = 22789
42
44
 
43
- @app = proc { |_env| [200, {}, ["Hello Server!"]] }
45
+ @app = proc { |_env| [200, {}, ['Hello Server!']] }
44
46
  @server = Capybara::Server.new(@app).boot
45
47
 
46
48
  @res = Net::HTTP.start(@server.host, 22789) { |http| http.get('/') }
@@ -49,8 +51,8 @@ RSpec.describe Capybara::Server do
49
51
  Capybara.server_port = nil
50
52
  end
51
53
 
52
- it "should use given port" do
53
- @app = proc { |_env| [200, {}, ["Hello Server!"]] }
54
+ it 'should use given port' do
55
+ @app = proc { |_env| [200, {}, ['Hello Server!']] }
54
56
  @server = Capybara::Server.new(@app, port: 22790).boot
55
57
 
56
58
  @res = Net::HTTP.start(@server.host, 22790) { |http| http.get('/') }
@@ -59,9 +61,9 @@ RSpec.describe Capybara::Server do
59
61
  Capybara.server_port = nil
60
62
  end
61
63
 
62
- it "should find an available port" do
63
- @app1 = proc { |_env| [200, {}, ["Hello Server!"]] }
64
- @app2 = proc { |_env| [200, {}, ["Hello Second Server!"]] }
64
+ it 'should find an available port' do
65
+ @app1 = proc { |_env| [200, {}, ['Hello Server!']] }
66
+ @app2 = proc { |_env| [200, {}, ['Hello Second Server!']] }
65
67
 
66
68
  @server1 = Capybara::Server.new(@app1).boot
67
69
  @server2 = Capybara::Server.new(@app2).boot
@@ -73,10 +75,10 @@ RSpec.describe Capybara::Server do
73
75
  expect(@res2.body).to include('Hello Second Server')
74
76
  end
75
77
 
76
- it "should support SSL" do
78
+ it 'should support SSL' do
77
79
  begin
78
- key = File.join(Dir.pwd, "spec", "fixtures", "key.pem")
79
- cert = File.join(Dir.pwd, "spec", "fixtures", "certificate.pem")
80
+ key = File.join(Dir.pwd, 'spec', 'fixtures', 'key.pem')
81
+ cert = File.join(Dir.pwd, 'spec', 'fixtures', 'certificate.pem')
80
82
  Capybara.server = :puma, { Host: "ssl://#{Capybara.server_host}?key=#{key}&cert=#{cert}" }
81
83
  app = proc { |_env| [200, {}, ['Hello SSL Server!']] }
82
84
  server = Capybara::Server.new(app).boot
@@ -95,7 +97,7 @@ RSpec.describe Capybara::Server do
95
97
  end
96
98
  end
97
99
 
98
- context "When Capybara.reuse_server is true" do
100
+ context 'When Capybara.reuse_server is true' do
99
101
  before do
100
102
  @old_reuse_server = Capybara.reuse_server
101
103
  Capybara.reuse_server = true
@@ -105,8 +107,8 @@ RSpec.describe Capybara::Server do
105
107
  Capybara.reuse_server = @old_reuse_server
106
108
  end
107
109
 
108
- it "should use the existing server if it already running" do
109
- @app = proc { |_env| [200, {}, ["Hello Server!"]] }
110
+ it 'should use the existing server if it already running' do
111
+ @app = proc { |_env| [200, {}, ['Hello Server!']] }
110
112
 
111
113
  @server1 = Capybara::Server.new(@app).boot
112
114
  @server2 = Capybara::Server.new(@app).boot
@@ -120,14 +122,14 @@ RSpec.describe Capybara::Server do
120
122
  expect(@server1.port).to eq(@server2.port)
121
123
  end
122
124
 
123
- it "detects and waits for all reused server sessions pending requests" do
125
+ it 'detects and waits for all reused server sessions pending requests' do
124
126
  done = 0
125
127
 
126
128
  app = proc do |env|
127
129
  request = Rack::Request.new(env)
128
130
  sleep request.params['wait_time'].to_f
129
131
  done += 1
130
- [200, {}, ["Hello Server!"]]
132
+ [200, {}, ['Hello Server!']]
131
133
  end
132
134
 
133
135
  server1 = Capybara::Server.new(app).boot
@@ -142,7 +144,7 @@ RSpec.describe Capybara::Server do
142
144
  end
143
145
  end
144
146
 
145
- context "When Capybara.reuse_server is false" do
147
+ context 'When Capybara.reuse_server is false' do
146
148
  before do
147
149
  @old_reuse_server = Capybara.reuse_server
148
150
  Capybara.reuse_server = false
@@ -152,8 +154,8 @@ RSpec.describe Capybara::Server do
152
154
  Capybara.reuse_server = @old_reuse_server
153
155
  end
154
156
 
155
- it "should not reuse an already running server" do
156
- @app = proc { |_env| [200, {}, ["Hello Server!"]] }
157
+ it 'should not reuse an already running server' do
158
+ @app = proc { |_env| [200, {}, ['Hello Server!']] }
157
159
 
158
160
  @server1 = Capybara::Server.new(@app).boot
159
161
  @server2 = Capybara::Server.new(@app).boot
@@ -167,14 +169,14 @@ RSpec.describe Capybara::Server do
167
169
  expect(@server1.port).not_to eq(@server2.port)
168
170
  end
169
171
 
170
- it "detects and waits for only one sessions pending requests" do
172
+ it 'detects and waits for only one sessions pending requests' do
171
173
  done = 0
172
174
 
173
175
  app = proc do |env|
174
176
  request = Rack::Request.new(env)
175
177
  sleep request.params['wait_time'].to_f
176
178
  done += 1
177
- [200, {}, ["Hello Server!"]]
179
+ [200, {}, ['Hello Server!']]
178
180
  end
179
181
 
180
182
  server1 = Capybara::Server.new(app).boot
@@ -192,7 +194,7 @@ RSpec.describe Capybara::Server do
192
194
  end
193
195
  end
194
196
 
195
- it "should raise server errors when the server errors before the timeout" do
197
+ it 'should raise server errors when the server errors before the timeout' do
196
198
  begin
197
199
  Capybara.register_server :kaboom do
198
200
  sleep 0.1
@@ -208,7 +210,7 @@ RSpec.describe Capybara::Server do
208
210
  end
209
211
  end
210
212
 
211
- it "is not #responsive? when Net::HTTP raises a SystemCallError" do
213
+ it 'is not #responsive? when Net::HTTP raises a SystemCallError' do
212
214
  app = -> { [200, {}, ['Hello, world']] }
213
215
  server = Capybara::Server.new(app)
214
216
  allow(Net::HTTP).to receive(:start).and_raise(SystemCallError.allocate)