capybara 3.3.1 → 3.4.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 (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)