capybara 2.13.0 → 2.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +5 -5
  2. data/History.md +218 -18
  3. data/README.md +54 -23
  4. data/lib/capybara/config.rb +132 -0
  5. data/lib/capybara/cucumber.rb +1 -0
  6. data/lib/capybara/driver/base.rb +14 -0
  7. data/lib/capybara/dsl.rb +1 -3
  8. data/lib/capybara/helpers.rb +3 -3
  9. data/lib/capybara/minitest/spec.rb +14 -37
  10. data/lib/capybara/minitest.rb +95 -114
  11. data/lib/capybara/node/actions.rb +10 -10
  12. data/lib/capybara/node/base.rb +7 -2
  13. data/lib/capybara/node/element.rb +9 -3
  14. data/lib/capybara/node/finders.rb +92 -18
  15. data/lib/capybara/node/matchers.rb +21 -9
  16. data/lib/capybara/node/simple.rb +5 -0
  17. data/lib/capybara/queries/ancestor_query.rb +25 -0
  18. data/lib/capybara/queries/base_query.rb +12 -3
  19. data/lib/capybara/queries/current_path_query.rb +13 -9
  20. data/lib/capybara/queries/selector_query.rb +62 -23
  21. data/lib/capybara/queries/sibling_query.rb +25 -0
  22. data/lib/capybara/queries/text_query.rb +10 -5
  23. data/lib/capybara/queries/title_query.rb +1 -0
  24. data/lib/capybara/rack_test/browser.rb +13 -5
  25. data/lib/capybara/rack_test/driver.rb +6 -1
  26. data/lib/capybara/rack_test/form.rb +4 -3
  27. data/lib/capybara/rack_test/node.rb +1 -1
  28. data/lib/capybara/rspec/compound.rb +95 -0
  29. data/lib/capybara/rspec/matcher_proxies.rb +45 -0
  30. data/lib/capybara/rspec/matchers.rb +108 -7
  31. data/lib/capybara/rspec.rb +3 -1
  32. data/lib/capybara/selector/filter.rb +13 -41
  33. data/lib/capybara/selector/filter_set.rb +30 -4
  34. data/lib/capybara/selector/filters/base.rb +33 -0
  35. data/lib/capybara/selector/filters/expression_filter.rb +40 -0
  36. data/lib/capybara/selector/filters/node_filter.rb +27 -0
  37. data/lib/capybara/selector/selector.rb +36 -15
  38. data/lib/capybara/selector.rb +63 -42
  39. data/lib/capybara/selenium/driver.rb +177 -33
  40. data/lib/capybara/selenium/node.rb +106 -55
  41. data/lib/capybara/server.rb +6 -5
  42. data/lib/capybara/session/config.rb +114 -0
  43. data/lib/capybara/session/matchers.rb +15 -4
  44. data/lib/capybara/session.rb +178 -65
  45. data/lib/capybara/spec/fixtures/no_extension +1 -0
  46. data/lib/capybara/spec/public/test.js +18 -3
  47. data/lib/capybara/spec/session/accept_alert_spec.rb +9 -1
  48. data/lib/capybara/spec/session/accept_prompt_spec.rb +29 -1
  49. data/lib/capybara/spec/session/all_spec.rb +13 -1
  50. data/lib/capybara/spec/session/ancestor_spec.rb +85 -0
  51. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +24 -8
  52. data/lib/capybara/spec/session/assert_selector.rb +1 -1
  53. data/lib/capybara/spec/session/assert_text.rb +8 -0
  54. data/lib/capybara/spec/session/assert_title.rb +22 -9
  55. data/lib/capybara/spec/session/attach_file_spec.rb +8 -1
  56. data/lib/capybara/spec/session/check_spec.rb +4 -4
  57. data/lib/capybara/spec/session/choose_spec.rb +2 -2
  58. data/lib/capybara/spec/session/click_button_spec.rb +1 -1
  59. data/lib/capybara/spec/session/click_link_or_button_spec.rb +3 -3
  60. data/lib/capybara/spec/session/click_link_spec.rb +1 -1
  61. data/lib/capybara/spec/session/current_url_spec.rb +3 -3
  62. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +3 -3
  63. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +1 -1
  64. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +22 -0
  65. data/lib/capybara/spec/session/evaluate_script_spec.rb +1 -1
  66. data/lib/capybara/spec/session/fill_in_spec.rb +8 -2
  67. data/lib/capybara/spec/session/find_field_spec.rb +1 -0
  68. data/lib/capybara/spec/session/find_spec.rb +8 -6
  69. data/lib/capybara/spec/session/first_spec.rb +10 -5
  70. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  71. data/lib/capybara/spec/session/has_css_spec.rb +11 -0
  72. data/lib/capybara/spec/session/has_current_path_spec.rb +52 -7
  73. data/lib/capybara/spec/session/has_link_spec.rb +4 -4
  74. data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
  75. data/lib/capybara/spec/session/has_select_spec.rb +64 -6
  76. data/lib/capybara/spec/session/has_selector_spec.rb +1 -3
  77. data/lib/capybara/spec/session/has_text_spec.rb +5 -3
  78. data/lib/capybara/spec/session/has_title_spec.rb +4 -2
  79. data/lib/capybara/spec/session/has_xpath_spec.rb +5 -3
  80. data/lib/capybara/spec/session/node_spec.rb +50 -26
  81. data/lib/capybara/spec/session/refresh_spec.rb +28 -0
  82. data/lib/capybara/spec/session/reset_session_spec.rb +3 -3
  83. data/lib/capybara/spec/session/select_spec.rb +3 -2
  84. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  85. data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
  86. data/lib/capybara/spec/session/unselect_spec.rb +2 -2
  87. data/lib/capybara/spec/session/visit_spec.rb +56 -1
  88. data/lib/capybara/spec/session/window/become_closed_spec.rb +11 -11
  89. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +11 -9
  90. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +4 -4
  91. data/lib/capybara/spec/session/window/within_window_spec.rb +27 -2
  92. data/lib/capybara/spec/spec_helper.rb +28 -4
  93. data/lib/capybara/spec/test_app.rb +3 -1
  94. data/lib/capybara/spec/views/form.erb +27 -1
  95. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  96. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  97. data/lib/capybara/spec/views/with_hover.erb +5 -0
  98. data/lib/capybara/spec/views/with_html.erb +33 -2
  99. data/lib/capybara/spec/views/with_js.erb +12 -0
  100. data/lib/capybara/spec/views/with_windows.erb +4 -0
  101. data/lib/capybara/version.rb +1 -1
  102. data/lib/capybara/window.rb +1 -1
  103. data/lib/capybara.rb +102 -124
  104. data/spec/capybara_spec.rb +43 -21
  105. data/spec/dsl_spec.rb +1 -0
  106. data/spec/filter_set_spec.rb +28 -0
  107. data/spec/minitest_spec.rb +9 -1
  108. data/spec/minitest_spec_spec.rb +19 -5
  109. data/spec/per_session_config_spec.rb +67 -0
  110. data/spec/result_spec.rb +20 -0
  111. data/spec/rspec/shared_spec_matchers.rb +148 -44
  112. data/spec/rspec/views_spec.rb +4 -0
  113. data/spec/rspec_matchers_spec.rb +46 -0
  114. data/spec/rspec_spec.rb +77 -0
  115. data/spec/selector_spec.rb +2 -1
  116. data/spec/selenium_spec_chrome.rb +25 -17
  117. data/spec/selenium_spec_firefox.rb +2 -1
  118. data/spec/selenium_spec_marionette.rb +18 -5
  119. data/spec/session_spec.rb +44 -0
  120. data/spec/shared_selenium_session.rb +72 -8
  121. data/spec/spec_helper.rb +4 -0
  122. metadata +55 -8
data/spec/rspec_spec.rb CHANGED
@@ -7,6 +7,10 @@ RSpec.describe 'capybara/rspec', :type => :feature do
7
7
  expect(page.body).to include('Another World')
8
8
  end
9
9
 
10
+ it "should include RSpec matcher proxies" do
11
+ expect(self.class.ancestors).to include Capybara::RSpecMatcherProxies
12
+ end
13
+
10
14
  context "resetting session" do
11
15
  it "sets a cookie in one example..." do
12
16
  visit('/set_cookie')
@@ -36,6 +40,79 @@ RSpec.describe 'capybara/rspec', :type => :feature do
36
40
  it "switches to the given driver when giving it as metadata", :driver => :culerity do
37
41
  expect(Capybara.current_driver).to eq(:culerity)
38
42
  end
43
+
44
+ context "#all" do
45
+ it "allows access to the Capybara finder" do
46
+ visit('/with_html')
47
+ expect(all(:css, 'h2.head').size).to eq(5)
48
+ end
49
+
50
+ it "allows access to the RSpec matcher" do
51
+ skip "RSpec < 3 doesn't have an `all` matcher" if rspec2?
52
+
53
+ visit('/with_html')
54
+ expect(["test1", "test2"]).to all(be_a(String))
55
+ end
56
+ end
57
+
58
+ context "#within" do
59
+ it "allows access to the Capybara scoper" do
60
+ visit('/with_html')
61
+ expect do
62
+ within(:css, "#does_not_exist") { click_link "Go to simple" }
63
+ end.to raise_error(Capybara::ElementNotFound)
64
+ end
65
+
66
+ it "allows access to the RSpec matcher" do
67
+ skip "RSpec version doesn't have a 'within' matcher" unless ::RSpec::Matchers.instance_methods.include?(:within)
68
+ visit('/with_html')
69
+ # This reads terribly, but must call #within
70
+ expect(find(:css, 'span.number').text.to_i).to within(1).of(41)
71
+ end
72
+ end
73
+ end
74
+
75
+ RSpec.describe 'capybara/rspec', :type => :other do
76
+ context "when RSpec::Matchers is included after Capybara::DSL" do
77
+ before do
78
+ class DSL_MatchersTest
79
+ include Capybara::DSL
80
+ include RSpec::Matchers
81
+ end
82
+
83
+ @test_class_instance = DSL_MatchersTest.new
84
+ end
85
+
86
+ context "#all" do
87
+ it "allows access to the Capybara finder" do
88
+ @test_class_instance.visit('/with_html')
89
+ expect(@test_class_instance.all(:css, 'h2.head').size).to eq(5)
90
+ end
91
+
92
+ it "allows access to the RSpec matcher" do
93
+ skip "RSpec < 3 doesn't have an `all` matcher" if rspec2?
94
+
95
+ @test_class_instance.visit('/with_html')
96
+ expect(["test1", "test2"]).to @test_class_instance.all(be_a(String))
97
+ end
98
+ end
99
+
100
+ context "#within" do
101
+ it "allows access to the Capybara scoper" do
102
+ @test_class_instance.visit('/with_html')
103
+ expect do
104
+ @test_class_instance.within(:css, "#does_not_exist") { @test_class_instance.click_link "Go to simple" }
105
+ end.to raise_error(Capybara::ElementNotFound)
106
+ end
107
+
108
+ it "allows access to the RSpec matcher" do
109
+ skip "RSpec version doesn't have a 'within' matcher" unless ::RSpec::Matchers.instance_methods.include?(:within)
110
+ @test_class_instance.visit('/with_html')
111
+ # This reads terribly, but must call #within
112
+ expect(@test_class_instance.find(:css, 'span.number').text.to_i).to @test_class_instance.within(1).of(41)
113
+ end
114
+ end
115
+ end
39
116
  end
40
117
 
41
118
  RSpec.describe 'capybara/rspec', :type => :other do
@@ -28,7 +28,7 @@ RSpec.describe Capybara do
28
28
  <input type="hidden" id="hidden_field" value="this is hidden"/>
29
29
  <a href="#">link</a>
30
30
  <fieldset></fieldset>
31
- <select>
31
+ <select id="select">
32
32
  <option value="a">A</option>
33
33
  <option value="b" disabled>B</option>
34
34
  <option value="c" selected>C</option>
@@ -177,6 +177,7 @@ RSpec.describe Capybara do
177
177
 
178
178
  it "finds by type" do
179
179
  expect(string.find(:field, type: 'file')[:id]).to eq 'file'
180
+ expect(string.find(:field, type: 'select')[:id]).to eq 'select'
180
181
  end
181
182
  end
182
183
 
@@ -3,30 +3,34 @@ require 'spec_helper'
3
3
  require 'selenium-webdriver'
4
4
  require 'shared_selenium_session'
5
5
 
6
- Capybara.register_driver :selenium_chrome do |app|
7
- args = ENV['TRAVIS'] ? ['no-sandbox' ] : []
8
- Capybara::Selenium::Driver.new(app, :browser => :chrome, :args => args)
9
- end
6
+ CHROME_DRIVER = if ENV['HEADLESS'] then :selenium_chrome_headless else :selenium_chrome end
7
+
8
+ # if ENV['HEADLESS'] && ENV['TRAVIS']
9
+ # Selenium::WebDriver::Chrome.path='/usr/bin/google-chrome-beta'
10
+ # end
10
11
 
11
12
  Capybara.register_driver :selenium_chrome_clear_storage do |app|
12
- args = ENV['TRAVIS'] ? ['no-sandbox' ] : []
13
- Capybara::Selenium::Driver.new(app, :browser => :chrome,
14
- :args => args,
15
- clear_local_storage: true,
16
- clear_session_storage: true)
13
+ chrome_options = {
14
+ browser: :chrome,
15
+ options: ::Selenium::WebDriver::Chrome::Options.new()
16
+ }
17
+ chrome_options[:options].args << 'headless' if ENV['HEADLESS']
18
+ Capybara::Selenium::Driver.new(app, chrome_options.merge(clear_local_storage: true, clear_session_storage: true))
17
19
  end
18
20
 
19
21
  module TestSessions
20
- Chrome = Capybara::Session.new(:selenium_chrome, TestApp)
22
+ Chrome = Capybara::Session.new(CHROME_DRIVER, TestApp)
21
23
  end
22
24
 
23
25
  skipped_tests = [:response_headers, :status_code, :trigger]
24
- skipped_tests << :windows if ENV['TRAVIS'] && !ENV['WINDOW_TEST']
26
+ # skip window tests when headless for now - closing a window not supported by chromedriver/chrome
27
+ skipped_tests << :windows if ENV['TRAVIS'] && (ENV['SKIP_WINDOW'] || ENV['HEADLESS'])
25
28
 
26
- Capybara::SpecHelper.run_specs TestSessions::Chrome, "selenium_chrome", capybara_skip: skipped_tests
29
+ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybara_skip: skipped_tests
27
30
 
28
31
  RSpec.describe "Capybara::Session with chrome" do
29
- include_examples "Capybara::Session", TestSessions::Chrome, :selenium_chrome
32
+ include Capybara::SpecHelper
33
+ include_examples "Capybara::Session", TestSessions::Chrome, CHROME_DRIVER
30
34
 
31
35
  context "storage" do
32
36
  describe "#reset!" do
@@ -36,8 +40,10 @@ RSpec.describe "Capybara::Session with chrome" do
36
40
  @session.find(:css, '#set-storage').click
37
41
  @session.reset!
38
42
  @session.visit('/with_js')
39
- expect(@session.driver.browser.local_storage.keys).not_to be_empty
40
- expect(@session.driver.browser.session_storage.keys).not_to be_empty
43
+ # expect(@session.driver.browser.local_storage.keys).not_to be_empty
44
+ # expect(@session.driver.browser.session_storage.keys).not_to be_empty
45
+ expect(@session.evaluate_script('Object.keys(localStorage)')).not_to be_empty
46
+ expect(@session.evaluate_script('Object.keys(sessionStorage)')).not_to be_empty
41
47
  end
42
48
 
43
49
  it "clears storage when set" do
@@ -46,8 +52,10 @@ RSpec.describe "Capybara::Session with chrome" do
46
52
  @session.find(:css, '#set-storage').click
47
53
  @session.reset!
48
54
  @session.visit('/with_js')
49
- expect(@session.driver.browser.local_storage.keys).to be_empty
50
- expect(@session.driver.browser.session_storage.keys).to be_empty
55
+ # expect(@session.driver.browser.local_storage.keys).to be_empty
56
+ # expect(@session.driver.browser.session_storage.keys).to be_empty
57
+ expect(@session.evaluate_script('Object.keys(localStorage)')).to be_empty
58
+ expect(@session.evaluate_script('Object.keys(sessionStorage)')).to be_empty
51
59
  end
52
60
  end
53
61
  end
@@ -31,11 +31,12 @@ skipped_tests = [
31
31
  :status_code,
32
32
  :trigger
33
33
  ]
34
- skipped_tests << :windows if ENV['TRAVIS'] && !ENV['WINDOW_TEST']
34
+ skipped_tests << :windows if ENV['TRAVIS'] && ENV['SKIP_WINDOW']
35
35
 
36
36
  Capybara::SpecHelper.run_specs TestSessions::Selenium, "selenium", capybara_skip: skipped_tests
37
37
 
38
38
  RSpec.describe "Capybara::Session with legacy firefox" do
39
+ include Capybara::SpecHelper
39
40
  include_examples "Capybara::Session", TestSessions::Selenium, :selenium_firefox
40
41
  include_examples Capybara::RSpecMatchers, TestSessions::Selenium, :selenium_firefox
41
42
 
@@ -4,11 +4,20 @@ require "selenium-webdriver"
4
4
  require 'shared_selenium_session'
5
5
  require 'rspec/shared_spec_matchers'
6
6
 
7
+ browser_options = ::Selenium::WebDriver::Firefox::Options.new()
8
+ browser_options.args << '--headless' if ENV['HEADLESS']
9
+ browser_options.add_preference 'dom.file.createInChild', true
10
+ # browser_options.add_option("log", {"level": "trace"})
11
+
7
12
  Capybara.register_driver :selenium_marionette do |app|
13
+ # ::Selenium::WebDriver.logger.level = "debug"
8
14
  Capybara::Selenium::Driver.new(
9
15
  app,
10
16
  browser: :firefox,
11
- desired_capabilities: Selenium::WebDriver::Remote::Capabilities.firefox(marionette: true)
17
+ desired_capabilities: {marionette: true, 'moz:webdriverClick': true},
18
+ options: browser_options
19
+ # Get a trace level log from geckodriver
20
+ # :driver_opts => { args: ['-vv'] }
12
21
  )
13
22
  end
14
23
 
@@ -16,12 +25,15 @@ Capybara.register_driver :selenium_marionette_clear_storage do |app|
16
25
  Capybara::Selenium::Driver.new(
17
26
  app,
18
27
  browser: :firefox,
19
- desired_capabilities: Selenium::WebDriver::Remote::Capabilities.firefox(marionette: true),
28
+ desired_capabilities: {marionette: true},
20
29
  clear_local_storage: true,
21
- clear_session_storage: true
30
+ clear_session_storage: true,
31
+ options: browser_options
22
32
  )
23
33
  end
24
34
 
35
+
36
+
25
37
  module TestSessions
26
38
  SeleniumMarionette = Capybara::Session.new(:selenium_marionette, TestApp)
27
39
  end
@@ -31,18 +43,19 @@ skipped_tests = [
31
43
  :status_code,
32
44
  :trigger
33
45
  ]
34
- skipped_tests << :windows if ENV['TRAVIS'] && !ENV['WINDOW_TEST']
46
+ skipped_tests << :windows if ENV['TRAVIS'] && ENV['SKIP_WINDOW']
35
47
 
36
48
  Capybara::SpecHelper.run_specs TestSessions::SeleniumMarionette, "selenium", capybara_skip: skipped_tests
37
49
 
38
50
  RSpec.describe "Capybara::Session with firefox" do
51
+ include Capybara::SpecHelper
39
52
  include_examples "Capybara::Session", TestSessions::SeleniumMarionette, :selenium_marionette
40
53
  include_examples Capybara::RSpecMatchers, TestSessions::SeleniumMarionette, :selenium_marionette
41
54
  end
42
55
 
43
56
  RSpec.describe Capybara::Selenium::Driver do
44
57
  before do
45
- @driver = Capybara::Selenium::Driver.new(TestApp, browser: :firefox)
58
+ @driver = Capybara::Selenium::Driver.new(TestApp, browser: :firefox, options: browser_options)
46
59
  end
47
60
 
48
61
  describe '#quit' do
data/spec/session_spec.rb CHANGED
@@ -7,4 +7,48 @@ RSpec.describe Capybara::Session do
7
7
  Capybara::Session.new(:unknown, { random: "hash"})
8
8
  end.to raise_error TypeError, "The second parameter to Session::new should be a rack app if passed."
9
9
  end
10
+
11
+ context "current_driver" do
12
+ it "is global when threadsafe false" do
13
+ Capybara.threadsafe = false
14
+ Capybara.current_driver = :selenium
15
+ thread = Thread.new do
16
+ Capybara.current_driver = :random
17
+ end
18
+ thread.join
19
+ expect(Capybara.current_driver).to eq :random
20
+ end
21
+
22
+ it "is thread specific threadsafe true" do
23
+ Capybara.threadsafe = true
24
+ Capybara.current_driver = :selenium
25
+ thread = Thread.new do
26
+ Capybara.current_driver = :random
27
+ end
28
+ thread.join
29
+ expect(Capybara.current_driver).to eq :selenium
30
+ end
31
+ end
32
+
33
+ context "session_name" do
34
+ it "is global when threadsafe false" do
35
+ Capybara.threadsafe = false
36
+ Capybara.session_name = "sess1"
37
+ thread = Thread.new do
38
+ Capybara.session_name = "sess2"
39
+ end
40
+ thread.join
41
+ expect(Capybara.session_name).to eq "sess2"
42
+ end
43
+
44
+ it "is thread specific when threadsafe true" do
45
+ Capybara.threadsafe = true
46
+ Capybara.session_name = "sess1"
47
+ thread = Thread.new do
48
+ Capybara.session_name = "sess2"
49
+ end
50
+ thread.join
51
+ expect(Capybara.session_name).to eq "sess1"
52
+ end
53
+ end
10
54
  end
@@ -34,6 +34,8 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
34
34
  before do
35
35
  @current_dir = Dir.getwd
36
36
  Dir.chdir(File.join(File.dirname(__FILE__), '..'))
37
+ @env = { 'SELENIUM_BROWSER' => @session.driver.options[:browser].to_s }
38
+ @env['LEGACY_FIREFOX'] = 'TRUE' if mode == :selenium_firefox
37
39
  end
38
40
 
39
41
  after do
@@ -41,16 +43,14 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
41
43
  end
42
44
 
43
45
  it "should have return code 1 when running selenium_driver_rspec_failure.rb" do
44
- env = { 'SELENIUM_BROWSER' => @session.driver.options[:browser].to_s,
45
- 'LEGACY_FIREFOX' => (mode == :selenium_firefox ? 'TRUE' : nil) }
46
- system(env, 'rspec spec/fixtures/selenium_driver_rspec_failure.rb', out: File::NULL, err: File::NULL)
46
+ skip if ENV['HEADLESS']
47
+ system(@env, 'rspec spec/fixtures/selenium_driver_rspec_failure.rb', out: File::NULL, err: File::NULL)
47
48
  expect($?.exitstatus).to eq(1)
48
49
  end
49
50
 
50
51
  it "should have return code 0 when running selenium_driver_rspec_success.rb" do
51
- env = { 'SELENIUM_BROWSER' => @session.driver.options[:browser].to_s,
52
- 'LEGACY_FIREFOX' => (mode == :selenium_firefox ? 'TRUE' : nil) }
53
- system(env, 'rspec spec/fixtures/selenium_driver_rspec_success.rb', out: File::NULL, err: File::NULL)
52
+ skip if ENV['HEADLESS']
53
+ system(@env, 'rspec spec/fixtures/selenium_driver_rspec_success.rb', out: File::NULL, err: File::NULL)
54
54
  expect($?.exitstatus).to eq(0)
55
55
  end
56
56
  end
@@ -60,7 +60,24 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
60
60
  @session.visit('/with_js')
61
61
  @session.click_link('Open alert')
62
62
  @session.accept_alert
63
- expect{@session.driver.browser.switch_to.alert}.to raise_error(Selenium::WebDriver::Error::NoAlertPresentError)
63
+ expect{@session.driver.browser.switch_to.alert}.to raise_error(@session.driver.send(:modal_error))
64
+ end
65
+
66
+ it "can be called before visiting" do
67
+ @session.accept_alert "Initial alert" do
68
+ @session.visit('/initial_alert')
69
+ end
70
+ expect(@session).to have_text('Initial alert page')
71
+ end
72
+ end
73
+
74
+ context '#fill_in_with empty string and no options' do
75
+ it 'should trigger change when clearing a field' do
76
+ @session.visit('/with_js')
77
+ @session.fill_in('with_change_event', with: '')
78
+ # click outside the field to trigger the change event
79
+ @session.find(:css, 'body').click
80
+ expect(@session).to have_selector(:css, '.change_event_triggered', match: :one)
64
81
  end
65
82
  end
66
83
 
@@ -89,6 +106,15 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
89
106
  @session.find(:css, 'body').click
90
107
  expect(@session).to have_selector(:css, '.change_event_triggered', match: :one)
91
108
  end
109
+
110
+ it 'should trigger input event field_value.length times' do
111
+ @session.visit('/with_js')
112
+ @session.fill_in('with_change_event', with: '',
113
+ fill_options: { :clear => :backspace })
114
+ # click outside the field to trigger the change event
115
+ @session.find(:css, 'body').click
116
+ expect(@session).to have_xpath('//p[@class="input_event_triggered"]', count: 13)
117
+ end
92
118
  end
93
119
 
94
120
  context "#fill_in with { clear: :none } fill_options" do
@@ -102,7 +128,7 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
102
128
 
103
129
  context "#fill_in with { clear: Array } fill_options" do
104
130
  it 'should pass the array through to the element' do
105
- pending "selenium-webdriver/geckodriver doesn't support complex sets of characters" if @session.driver.marionette?
131
+ pending "selenium-webdriver/geckodriver doesn't support complex sets of characters" if marionette?(@session)
106
132
  #this is mainly for use with [[:control, 'a'], :backspace] - however since that is platform dependant I'm testing with something less useful
107
133
  @session.visit('/form')
108
134
  @session.fill_in('form_first_name', with: 'Harry',
@@ -120,6 +146,14 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
120
146
  end
121
147
  end
122
148
 
149
+ describe "all with disappearing elements" do
150
+ it "ignores stale elements in results" do
151
+ @session.visit('/path')
152
+ elements = @session.all(:link) { |node| raise Selenium::WebDriver::Error::StaleElementReferenceError }
153
+ expect(elements.size).to eq 0
154
+ end
155
+ end
156
+
123
157
  describe "#evaluate_script" do
124
158
  it "can return an element" do
125
159
  @session.visit('/form')
@@ -146,6 +180,36 @@ RSpec.shared_examples "Capybara::Session" do |session, mode|
146
180
  }
147
181
  })
148
182
  end
183
+
184
+ describe "#evaluate_async_script" do
185
+ it "will timeout if the script takes too long" do
186
+ @session.visit('/with_js')
187
+ expect do
188
+ @session.using_wait_time(1) do
189
+ @session.evaluate_async_script("var cb = arguments[0]; setTimeout(function(){ cb(null) }, 3000)")
190
+ end
191
+ end.to raise_error Selenium::WebDriver::Error::ScriptTimeoutError
192
+ end
193
+ end
194
+ end
195
+
196
+ describe "Element#inspect" do
197
+ it "outputs obsolete elements" do
198
+ @session.visit('/form')
199
+ el = @session.find(:button, 'Click me!').click
200
+ expect(@session).to have_no_button('Click me!')
201
+ expect(el).not_to receive(:synchronize)
202
+ expect(el.inspect).to eq "Obsolete #<Capybara::Node::Element>"
203
+ end
204
+ end
205
+
206
+ describe "Element#click" do
207
+ it "should handle fixed headers/footers" do
208
+ @session.visit('/with_fixed_header_footer')
209
+ # @session.click_link('Go to root')
210
+ @session.find(:link, 'Go to root').click
211
+ expect(@session).to have_current_path('/')
212
+ end
149
213
  end
150
214
  end
151
215
  end
data/spec/spec_helper.rb CHANGED
@@ -8,3 +8,7 @@ RSpec.configure do |config|
8
8
  config.filter_run_including focus_: true unless ENV['TRAVIS']
9
9
  config.run_all_when_everything_filtered = true
10
10
  end
11
+
12
+ def rspec2?
13
+ !defined?(::RSpec::Expectations::Version) || (Gem::Version.new(RSpec::Expectations::Version::STRING) < Gem::Version.new('3.0'))
14
+ end