capybara 3.15.0 → 3.17.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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +39 -0
  3. data/README.md +3 -3
  4. data/lib/capybara/config.rb +1 -2
  5. data/lib/capybara/helpers.rb +1 -1
  6. data/lib/capybara/node/actions.rb +6 -6
  7. data/lib/capybara/node/base.rb +5 -5
  8. data/lib/capybara/node/element.rb +5 -5
  9. data/lib/capybara/node/finders.rb +7 -5
  10. data/lib/capybara/node/simple.rb +3 -2
  11. data/lib/capybara/queries/base_query.rb +1 -1
  12. data/lib/capybara/queries/selector_query.rb +7 -7
  13. data/lib/capybara/queries/style_query.rb +1 -1
  14. data/lib/capybara/rack_test/form.rb +1 -1
  15. data/lib/capybara/registrations/drivers.rb +36 -0
  16. data/lib/capybara/registrations/servers.rb +38 -0
  17. data/lib/capybara/result.rb +2 -2
  18. data/lib/capybara/rspec/matcher_proxies.rb +2 -2
  19. data/lib/capybara/rspec/matchers/base.rb +2 -2
  20. data/lib/capybara/rspec/matchers.rb +1 -1
  21. data/lib/capybara/selector/css.rb +3 -3
  22. data/lib/capybara/selector/filters/base.rb +1 -1
  23. data/lib/capybara/selector/selector.rb +1 -0
  24. data/lib/capybara/selector/xpath_extensions.rb +8 -0
  25. data/lib/capybara/selector.rb +117 -102
  26. data/lib/capybara/selenium/driver.rb +97 -48
  27. data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +16 -4
  28. data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +23 -0
  29. data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +5 -0
  30. data/lib/capybara/selenium/driver_specializations/safari_driver.rb +13 -0
  31. data/lib/capybara/selenium/extensions/find.rb +48 -37
  32. data/lib/capybara/selenium/extensions/html5_drag.rb +3 -1
  33. data/lib/capybara/selenium/logger_suppressor.rb +29 -0
  34. data/lib/capybara/selenium/node.rb +22 -8
  35. data/lib/capybara/selenium/nodes/chrome_node.rb +8 -4
  36. data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
  37. data/lib/capybara/server/animation_disabler.rb +1 -1
  38. data/lib/capybara/server/checker.rb +1 -1
  39. data/lib/capybara/server/middleware.rb +3 -3
  40. data/lib/capybara/session/config.rb +2 -8
  41. data/lib/capybara/session.rb +9 -5
  42. data/lib/capybara/spec/session/attach_file_spec.rb +1 -1
  43. data/lib/capybara/spec/session/check_spec.rb +4 -4
  44. data/lib/capybara/spec/session/choose_spec.rb +2 -2
  45. data/lib/capybara/spec/session/click_button_spec.rb +28 -1
  46. data/lib/capybara/spec/session/fill_in_spec.rb +2 -2
  47. data/lib/capybara/spec/session/find_spec.rb +1 -1
  48. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +14 -1
  49. data/lib/capybara/spec/session/frame/within_frame_spec.rb +12 -1
  50. data/lib/capybara/spec/session/has_css_spec.rb +9 -2
  51. data/lib/capybara/spec/session/has_table_spec.rb +4 -4
  52. data/lib/capybara/spec/session/node_spec.rb +18 -6
  53. data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
  54. data/lib/capybara/spec/session/unselect_spec.rb +1 -1
  55. data/lib/capybara/spec/spec_helper.rb +1 -1
  56. data/lib/capybara/spec/views/frame_child.erb +2 -1
  57. data/lib/capybara/spec/views/react.erb +45 -0
  58. data/lib/capybara/version.rb +1 -1
  59. data/lib/capybara/window.rb +1 -1
  60. data/lib/capybara.rb +2 -70
  61. data/spec/minitest_spec_spec.rb +1 -1
  62. data/spec/result_spec.rb +10 -6
  63. data/spec/rspec/shared_spec_matchers.rb +8 -4
  64. data/spec/sauce_spec_chrome.rb +42 -0
  65. data/spec/selector_spec.rb +4 -0
  66. data/spec/selenium_spec_safari.rb +2 -3
  67. data/spec/session_spec.rb +7 -0
  68. data/spec/shared_selenium_session.rb +14 -12
  69. data/spec/spec_helper.rb +2 -1
  70. metadata +37 -17
@@ -92,7 +92,18 @@ Capybara::SpecHelper.spec '#within_frame', requires: [:frames] do
92
92
  it 'works if the frame is closed', requires: %i[frames js] do
93
93
  @session.within_frame 'parentFrame' do
94
94
  @session.within_frame 'childFrame' do
95
- @session.click_link 'Close Window'
95
+ @session.click_link 'Close Window Now'
96
+ end
97
+ expect(@session).to have_selector(:css, 'body#parentBody')
98
+ expect(@session).not_to have_selector(:css, '#childFrame')
99
+ end
100
+ end
101
+
102
+ it 'works if the frame is closed with a slight delay', requires: %i[frames js] do
103
+ @session.within_frame 'parentFrame' do
104
+ @session.within_frame 'childFrame' do
105
+ @session.click_link 'Close Window Soon'
106
+ sleep 1
96
107
  end
97
108
  expect(@session).to have_selector(:css, 'body#parentBody')
98
109
  expect(@session).not_to have_selector(:css, '#childFrame')
@@ -113,13 +113,20 @@ Capybara::SpecHelper.spec '#has_css?' do
113
113
  end
114
114
 
115
115
  context 'with predicates_wait == false' do
116
- it 'should not wait for content to appear', requires: [:js] do
116
+ before do
117
117
  Capybara.predicates_wait = false
118
- Capybara.default_max_wait_time = 2
118
+ Capybara.default_max_wait_time = 5
119
119
  @session.visit('/with_js')
120
120
  @session.click_link('Click me')
121
+ end
122
+
123
+ it 'should not wait for content to appear', requires: [:js] do
121
124
  expect(@session.has_css?("input[type='submit'][value='New Here']")).to be false
122
125
  end
126
+
127
+ it 'should should the default wait time if true is passed for :wait', requires: [:js] do
128
+ expect(@session.has_css?("input[type='submit'][value='New Here']", wait: true)).to be true
129
+ end
123
130
  end
124
131
 
125
132
  context 'with between' do
@@ -49,8 +49,8 @@ Capybara::SpecHelper.spec '#has_table?' do
49
49
  %w[Thomas Walpole Oceanside],
50
50
  %w[Danilo Wilkinson Johnsonville],
51
51
  %w[Vern Konopelski Everette],
52
- ["Ratke", "Lawrence", "East Sorayashire"],
53
- ["Palmer", "Sawayn", "West Trinidad"]
52
+ ['Ratke', 'Lawrence', 'East Sorayashire'],
53
+ ['Palmer', 'Sawayn', 'West Trinidad']
54
54
  ])
55
55
  end
56
56
 
@@ -84,8 +84,8 @@ Capybara::SpecHelper.spec '#has_table?' do
84
84
  %w[Thomas Walpole Oceanside],
85
85
  %w[Danilo Wilkinson Johnsonville],
86
86
  %w[Vern Konopelski Everette],
87
- ["Ratke", "Lawrence", "East Sorayashire"],
88
- ["Palmer", "Sawayn", "West Trinidad"]
87
+ ['Ratke', 'Lawrence', 'East Sorayashire'],
88
+ ['Palmer', 'Sawayn', 'West Trinidad']
89
89
  ])
90
90
  end
91
91
 
@@ -109,12 +109,24 @@ Capybara::SpecHelper.spec 'node' do
109
109
  expect(@session.first('//input').value).to eq('')
110
110
  end
111
111
 
112
- it 'should raise if the text field is readonly' do
113
- expect { @session.first('//input[@readonly]').set('changed') }.to raise_error(Capybara::ReadOnlyElementError)
114
- end
112
+ if ENV['CAPYBARA_THOROUGH']
113
+ it 'should raise if the text field is readonly' do
114
+ expect { @session.first('//input[@readonly]').set('changed') }.to raise_error(Capybara::ReadOnlyElementError)
115
+ end
116
+
117
+ it 'should raise if the textarea is readonly' do
118
+ expect { @session.first('//textarea[@readonly]').set('changed') }.to raise_error(Capybara::ReadOnlyElementError)
119
+ end
120
+ else
121
+ it 'should not change if the text field is readonly' do
122
+ @session.first('//input[@readonly]').set('changed')
123
+ expect(@session.first('//input[@readonly]').value).to eq 'should not change'
124
+ end
115
125
 
116
- it 'should raise if the textarea is readonly' do
117
- expect { @session.first('//textarea[@readonly]').set('changed') }.to raise_error(Capybara::ReadOnlyElementError)
126
+ it 'should not change if the textarea is readonly' do
127
+ @session.first('//textarea[@readonly]').set('changed')
128
+ expect(@session.first('//textarea[@readonly]').value).to eq 'textarea should not change'
129
+ end
118
130
  end
119
131
 
120
132
  it 'should use global default options' do
@@ -183,7 +195,7 @@ Capybara::SpecHelper.spec 'node' do
183
195
 
184
196
  it 'should see a disabled fieldset as disabled' do
185
197
  @session.visit('/form')
186
- expect(@session.find(:css, '#form_disabled_fieldset')).to be_disabled
198
+ expect(@session.find(:xpath, './/fieldset[@id="form_disabled_fieldset"]')).to be_disabled
187
199
  end
188
200
 
189
201
  context 'in a disabled fieldset' do
@@ -85,11 +85,11 @@ Capybara::SpecHelper.spec '#uncheck' do
85
85
  end
86
86
 
87
87
  it 'should raise original error when no label available' do
88
- expect { @session.uncheck('form_cars_porsche') }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_porsche"')
88
+ expect { @session.uncheck('form_cars_porsche') }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_porsche"/)
89
89
  end
90
90
 
91
91
  it 'should raise error if not allowed to click label' do
92
- expect { @session.uncheck('form_cars_jaguar', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_jaguar"')
92
+ expect { @session.uncheck('form_cars_jaguar', allow_label_click: false) }.to raise_error(Capybara::ElementNotFound, /Unable to find visible checkbox "form_cars_jaguar"/)
93
93
  end
94
94
 
95
95
  it 'should include node filter description in error if necessary' do
@@ -56,7 +56,7 @@ Capybara::SpecHelper.spec '#unselect' do
56
56
 
57
57
  context "with a locator that doesn't exist" do
58
58
  it 'should raise an error' do
59
- msg = 'Unable to find select box "does not exist"'
59
+ msg = /Unable to find select box "does not exist"/
60
60
  expect do
61
61
  @session.unselect('foo', from: 'does not exist')
62
62
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -100,7 +100,7 @@ module Capybara
100
100
 
101
101
  def silence_stream(stream)
102
102
  old_stream = stream.dup
103
- stream.reopen(RbConfig::CONFIG['host_os'] =~ /rmswin|mingw/ ? 'NUL:' : '/dev/null')
103
+ stream.reopen(RbConfig::CONFIG['host_os'].match?(/rmswin|mingw/) ? 'NUL:' : '/dev/null')
104
104
  stream.sync = true
105
105
  yield
106
106
  ensure
@@ -10,7 +10,8 @@
10
10
  </script>
11
11
  </head>
12
12
  <body id="childBody">
13
- <a href="javascript:void(0)" onClick="closeWin()">Close Window</a>
13
+ <a href="javascript:void(0)" onClick="closeWin()">Close Window Now</a>
14
+ <a href="javascript:void(0)" onClick="setTimeout(function(){closeWin()}, 10)">Close Window Soon</a>
14
15
  <iframe src="/frame_one" id="grandchildFrame1"></iframe>
15
16
  <iframe src="/frame_two" id="grandchildFrame2"></iframe>
16
17
  </body>
@@ -0,0 +1,45 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head>
4
+ <script src="https://unpkg.com/react/umd/react.development.js"></script>
5
+ <script src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
6
+ </head>
7
+ <body>
8
+ <div id="root"></div>
9
+ <script>
10
+ // https://codepen.io/gaearon/pen/VmmPgp?editors=0010
11
+ class NameForm extends React.Component {
12
+ constructor(props) {
13
+ super(props);
14
+ this.state = { value: '' };
15
+
16
+ this.handleChange = this.handleChange.bind(this);
17
+ this.handleSubmit = this.handleSubmit.bind(this);
18
+ }
19
+
20
+ handleChange(event) {
21
+ this.setState({ value: event.target.value });
22
+ }
23
+
24
+ handleSubmit(event) {
25
+ alert('A name was submitted: ' + this.state.value);
26
+ event.preventDefault();
27
+ }
28
+
29
+ render() {
30
+ return (
31
+ React.createElement("form", { onSubmit: this.handleSubmit },
32
+ React.createElement("label", null, "Name:",
33
+
34
+ React.createElement("input", { type: "text", value: this.state.value, onChange: this.handleChange })),
35
+
36
+ React.createElement("input", { type: "submit", value: "Submit" })));
37
+ }}
38
+
39
+
40
+ ReactDOM.render(
41
+ React.createElement(NameForm, null),
42
+ document.getElementById('root'));
43
+ </script>
44
+ </body>
45
+ </html>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.15.0'
4
+ VERSION = '3.17.0'
5
5
  end
@@ -49,7 +49,7 @@ module Capybara
49
49
  # @return [Boolean] whether this window is the window in which commands are being executed
50
50
  def current?
51
51
  @driver.current_window_handle == @handle
52
- rescue @driver.no_such_window_error
52
+ rescue @driver.no_such_window_error # rubocop:disable Naming/RescuedExceptionsVariableName
53
53
  false
54
54
  end
55
55
 
data/lib/capybara.rb CHANGED
@@ -466,42 +466,8 @@ module Capybara
466
466
  require 'capybara/selenium/driver'
467
467
  end
468
468
 
469
- Capybara.register_server :default do |app, port, _host|
470
- Capybara.run_default_server(app, port)
471
- end
472
-
473
- Capybara.register_server :webrick do |app, port, host, **options|
474
- require 'rack/handler/webrick'
475
- options = { Host: host, Port: port, AccessLog: [], Logger: WEBrick::Log.new(nil, 0) }.merge(options)
476
- Rack::Handler::WEBrick.run(app, options)
477
- end
478
-
479
- Capybara.register_server :puma do |app, port, host, **options|
480
- begin
481
- require 'rack/handler/puma'
482
- rescue LoadError
483
- raise LoadError, 'Capybara is unable to load `puma` for its server, please add `puma` to your project or specify a different server via something like `Capybara.server = :webrick`.'
484
- else
485
- unless Rack::Handler::Puma.respond_to?(:config)
486
- raise LoadError, 'Capybara requires `puma` version 3.8.0 or higher, please upgrade `puma` or register and specify your own server block'
487
- end
488
- end
489
- # If we just run the Puma Rack handler it installs signal handlers which prevent us from being able to interrupt tests.
490
- # Therefore construct and run the Server instance ourselves.
491
- # Rack::Handler::Puma.run(app, { Host: host, Port: port, Threads: "0:4", workers: 0, daemon: false }.merge(options))
492
- options = { Host: host, Port: port, Threads: '0:4', workers: 0, daemon: false }.merge(options)
493
- conf = Rack::Handler::Puma.config(app, options)
494
- events = conf.options[:Silent] ? ::Puma::Events.strings : ::Puma::Events.stdio
495
-
496
- events.log 'Capybara starting Puma...'
497
- events.log "* Version #{Puma::Const::PUMA_VERSION} , codename: #{Puma::Const::CODE_NAME}"
498
- events.log "* Min threads: #{conf.options[:min_threads]}, max threads: #{conf.options[:max_threads]}"
499
-
500
- Puma::Server.new(conf.app, events, conf.options).tap do |s|
501
- s.binder.parse conf.options[:binds], s.events
502
- s.min_threads, s.max_threads = conf.options[:min_threads], conf.options[:max_threads]
503
- end.run.join
504
- end
469
+ require 'capybara/registrations/servers'
470
+ require 'capybara/registrations/drivers'
505
471
 
506
472
  Capybara.configure do |config|
507
473
  config.always_include_port = false
@@ -527,37 +493,3 @@ Capybara.configure do |config|
527
493
  config.default_normalize_ws = false
528
494
  config.allow_gumbo = false
529
495
  end
530
-
531
- Capybara.register_driver :rack_test do |app|
532
- Capybara::RackTest::Driver.new(app)
533
- end
534
-
535
- Capybara.register_driver :selenium do |app|
536
- Capybara::Selenium::Driver.new(app)
537
- end
538
-
539
- Capybara.register_driver :selenium_headless do |app|
540
- Capybara::Selenium::Driver.load_selenium
541
- browser_options = ::Selenium::WebDriver::Firefox::Options.new
542
- browser_options.args << '-headless'
543
- Capybara::Selenium::Driver.new(app, browser: :firefox, options: browser_options)
544
- end
545
-
546
- Capybara.register_driver :selenium_chrome do |app|
547
- browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
548
- # Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
549
- opts.args << '--disable-site-isolation-trials'
550
- end
551
- Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
552
- end
553
-
554
- Capybara.register_driver :selenium_chrome_headless do |app|
555
- Capybara::Selenium::Driver.load_selenium
556
- browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
557
- opts.args << '--headless'
558
- opts.args << '--disable-gpu' if Gem.win_platform?
559
- # Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
560
- opts.args << '--disable-site-isolation-trials'
561
- end
562
- Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
563
- end
@@ -146,6 +146,6 @@ RSpec.describe 'capybara/minitest/spec' do
146
146
  reporter.report
147
147
  expect(output.string).to include('20 runs, 42 assertions, 1 failures, 0 errors, 1 skips')
148
148
  # Make sure error messages are displayed
149
- expect(output.string).to include('expected to find select box "non_existing_form_title" but there were no matches')
149
+ expect(output.string).to match(/expected to find select box "non_existing_form_title" .*but there were no matches/)
150
150
  end
151
151
  end
data/spec/result_spec.rb CHANGED
@@ -106,7 +106,7 @@ RSpec.describe Capybara::Result do
106
106
 
107
107
  # Not a great test but it indirectly tests what is needed
108
108
  it 'should evaluate filters lazily for idx' do
109
- skip 'JRuby has an issue with lazy enumerator evaluation' if RUBY_PLATFORM == 'java'
109
+ skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
110
110
  # Not processed until accessed
111
111
  expect(result.instance_variable_get('@result_cache').size).to be 0
112
112
 
@@ -127,7 +127,7 @@ RSpec.describe Capybara::Result do
127
127
  end
128
128
 
129
129
  it 'should evaluate filters lazily for range' do
130
- skip 'JRuby has an issue with lazy enumerator evaluation' if RUBY_PLATFORM == 'java'
130
+ skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
131
131
  result[0..1]
132
132
  expect(result.instance_variable_get('@result_cache').size).to be 2
133
133
 
@@ -136,7 +136,7 @@ RSpec.describe Capybara::Result do
136
136
  end
137
137
 
138
138
  it 'should evaluate filters lazily for idx and length' do
139
- skip 'JRuby has an issue with lazy enumerator evaluation' if RUBY_PLATFORM == 'java'
139
+ skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
140
140
  result[1, 2]
141
141
  expect(result.instance_variable_get('@result_cache').size).to be 3
142
142
 
@@ -145,7 +145,7 @@ RSpec.describe Capybara::Result do
145
145
  end
146
146
 
147
147
  it 'should only need to evaluate one result for any?' do
148
- skip 'JRuby has an issue with lazy enumerator evaluation' if RUBY_PLATFORM == 'java'
148
+ skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
149
149
  result.any?
150
150
  expect(result.instance_variable_get('@result_cache').size).to be 1
151
151
  end
@@ -158,7 +158,7 @@ RSpec.describe Capybara::Result do
158
158
 
159
159
  context '#each' do
160
160
  it 'lazily evaluates' do
161
- skip 'JRuby has an issue with lazy enumerator evaluation' if RUBY_PLATFORM == 'java'
161
+ skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
162
162
  results = []
163
163
  result.each do |el|
164
164
  results << el
@@ -174,7 +174,7 @@ RSpec.describe Capybara::Result do
174
174
  end
175
175
 
176
176
  it 'lazily evaluates' do
177
- skip 'JRuby has an issue with lazy enumerator evaluation' if RUBY_PLATFORM == 'java'
177
+ skip 'JRuby has an issue with lazy enumerator evaluation' if jruby_lazy_enumerator_workaround?
178
178
  result.each.with_index do |_el, idx|
179
179
  expect(result.instance_variable_get('@result_cache').size).to eq(idx + 1) # 0 indexing
180
180
  end
@@ -197,4 +197,8 @@ RSpec.describe Capybara::Result do
197
197
  expect(eval_count).to eq 1
198
198
  end
199
199
  end
200
+
201
+ def jruby_lazy_enumerator_workaround?
202
+ (RUBY_PLATFORM == 'java') && (Gem::Version.new(JRUBY_VERSION) < Gem::Version.new('9.2.8.0'))
203
+ end
200
204
  end
@@ -627,8 +627,12 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
627
627
  describe 'have_button matcher' do
628
628
  let(:html) { '<button>A button</button><input type="submit" value="Another button"/>' }
629
629
 
630
- it 'gives proper description' do
631
- expect(have_button('A button').description).to eq('have visible button "A button"')
630
+ it 'gives proper description with no options' do
631
+ expect(have_button('A button').description).to eq('have visible button "A button" that is not disabled')
632
+ end
633
+
634
+ it 'gives proper description with disabled :any option' do
635
+ expect(have_button('A button', disabled: :all).description).to eq('have visible button "A button"')
632
636
  end
633
637
 
634
638
  it 'passes if there is such a button' do
@@ -698,7 +702,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
698
702
  end
699
703
 
700
704
  it 'gives proper description' do
701
- expect(have_checked_field('it is checked').description).to eq('have visible field "it is checked" that is checked and not disabled')
705
+ expect(have_checked_field('it is checked').description).to eq('have visible field "it is checked" that is not disabled that is checked')
702
706
  end
703
707
 
704
708
  context 'with should' do
@@ -747,7 +751,7 @@ RSpec.shared_examples Capybara::RSpecMatchers do |session, _mode|
747
751
  end
748
752
 
749
753
  it 'gives proper description' do
750
- expect(have_unchecked_field('unchecked field').description).to eq('have visible field "unchecked field" that is not checked and not disabled')
754
+ expect(have_unchecked_field('unchecked field').description).to eq('have visible field "unchecked field" that is not disabled that is not checked')
751
755
  end
752
756
 
753
757
  context 'with should' do
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'selenium-webdriver'
5
+
6
+ require 'sauce_whisk'
7
+ # require 'shared_selenium_session'
8
+ # require 'rspec/shared_spec_matchers'
9
+
10
+ Capybara.register_driver :sauce_chrome do |app|
11
+ options = {
12
+ selenium_version: '3.141.59',
13
+ platform: 'macOS 10.12',
14
+ browser_name: 'chrome',
15
+ version: '65.0',
16
+ name: 'Capybara test',
17
+ build: ENV['TRAVIS_REPO_SLUG'] || "Ruby-RSpec-Selenium: Local-#{Time.now.to_i}",
18
+ username: ENV['SAUCE_USERNAME'],
19
+ access_key: ENV['SAUCE_ACCESS_KEY']
20
+ }
21
+
22
+ options.delete(:browser_name)
23
+
24
+ capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(options)
25
+ url = 'https://ondemand.saucelabs.com:443/wd/hub'
26
+
27
+ Capybara::Selenium::Driver.new(app,
28
+ browser: :remote, url: url,
29
+ desired_capabilities: capabilities,
30
+ options: Selenium::WebDriver::Chrome::Options.new(args: ['']))
31
+ end
32
+
33
+ CHROME_REMOTE_DRIVER = :sauce_chrome
34
+
35
+ module TestSessions
36
+ Chrome = Capybara::Session.new(CHROME_REMOTE_DRIVER, TestApp)
37
+ end
38
+
39
+ skipped_tests = %i[response_headers status_code trigger download]
40
+
41
+ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s, capybara_skip: skipped_tests do |example|
42
+ end
@@ -478,6 +478,10 @@ RSpec.describe Capybara do
478
478
  Capybara::Selector[:link_or_button].expression_filters.delete(:random)
479
479
  end
480
480
 
481
+ it 'should not find links when disabled == true' do
482
+ expect(string.all(:link_or_button, disabled: true).size).to eq 0
483
+ end
484
+
481
485
  context 'when modified' do
482
486
  it 'should still work' do
483
487
  filter = Capybara::Selector[:link_or_button].expression_filters[:random]
@@ -57,10 +57,9 @@ Capybara::SpecHelper.run_specs TestSessions::Safari, SAFARI_DRIVER.to_s, capybar
57
57
  'Capybara::Session selenium_safari node #click should allow to retry longer',
58
58
  'Capybara::Session selenium_safari node #click should retry clicking'
59
59
  pending "safaridriver doesn't return a specific enough error to deal with this"
60
- when /Capybara::Session selenium_safari #within_frame should find multiple nested frames/,
61
- /Capybara::Session selenium_safari #within_frame works if the frame is closed/,
60
+ when /Capybara::Session selenium_safari #within_frame works if the frame is closed/,
62
61
  /Capybara::Session selenium_safari #switch_to_frame works if the frame is closed/
63
- skip 'switch_to_frame(:parent) appears to go to the root in Safari rather than parent'
62
+ skip 'Safari has a race condition when clicking an element that causes the frame to close. It will sometimes raise a NoSuchFrameError'
64
63
  when /Capybara::Session selenium_safari #reset_session! removes ALL cookies/
65
64
  skip 'Safari webdriver can only remove cookies for the current domain'
66
65
  when /Capybara::Session selenium_safari #refresh it reposts/
data/spec/session_spec.rb CHANGED
@@ -80,5 +80,12 @@ RSpec.describe Capybara::Session do
80
80
  session.quit
81
81
  expect(session.driver).not_to eql driver
82
82
  end
83
+
84
+ it 'resets the document' do
85
+ session = Capybara::Session.new(:rack_test, TestApp)
86
+ document = session.document
87
+ session.quit
88
+ expect(session.document.base).not_to eql document.base
89
+ end
83
90
  end
84
91
  end
@@ -472,19 +472,21 @@ RSpec.shared_examples 'Capybara::Session' do |session, mode|
472
472
  describe 'with react' do
473
473
  context 'controlled components' do
474
474
  it 'can set and clear a text field' do
475
- session.visit 'https://reactjs.org/docs/forms.html'
476
- session.all(:css, 'h2#controlled-components ~ p a', text: 'Try it on CodePen')[0].click
477
- sleep 2 # give codepen a chance to stabilize result frame
478
- session.within_frame(:css, 'iframe.result-iframe') do
479
- session.fill_in('Name:', with: 'abc')
480
- session.accept_prompt 'A name was submitted: abc' do
481
- session.click_button('Submit')
482
- end
483
- session.fill_in('Name:', with: '')
484
- session.accept_prompt(/A name was submitted: $/) do
485
- session.click_button('Submit')
486
- end
475
+ # session.visit 'https://reactjs.org/docs/forms.html'
476
+ # session.all(:css, 'h2#controlled-components ~ p a', text: 'Try it on CodePen')[0].click
477
+ # copied into local view
478
+ session.visit 'react'
479
+ # Not necessary when accessed locally
480
+ # session.within_frame(:css, 'iframe.result-iframe:not([src=""])', wait: 10) do
481
+ session.fill_in('Name:', with: 'abc')
482
+ session.accept_prompt 'A name was submitted: abc' do
483
+ session.click_button('Submit')
484
+ end
485
+ session.fill_in('Name:', with: '')
486
+ session.accept_prompt(/A name was submitted: $/) do
487
+ session.click_button('Submit')
487
488
  end
489
+ # end
488
490
  end
489
491
  end
490
492
  end
data/spec/spec_helper.rb CHANGED
@@ -9,7 +9,8 @@ module Capybara
9
9
  module SpecHelper
10
10
  def firefox?(session)
11
11
  browser_name(session) == :firefox &&
12
- session.driver.browser.capabilities.is_a?(::Selenium::WebDriver::Remote::W3C::Capabilities)
12
+ ((defined?(::Selenium::WebDriver::VERSION) && (::Selenium::WebDriver::VERSION.to_f >= 4)) ||
13
+ session.driver.browser.capabilities.is_a?(::Selenium::WebDriver::Remote::W3C::Capabilities))
13
14
  end
14
15
 
15
16
  def firefox_lt?(version, session)