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.
- checksums.yaml +4 -4
- data/History.md +39 -0
- data/README.md +3 -3
- data/lib/capybara/config.rb +1 -2
- data/lib/capybara/helpers.rb +1 -1
- data/lib/capybara/node/actions.rb +6 -6
- data/lib/capybara/node/base.rb +5 -5
- data/lib/capybara/node/element.rb +5 -5
- data/lib/capybara/node/finders.rb +7 -5
- data/lib/capybara/node/simple.rb +3 -2
- data/lib/capybara/queries/base_query.rb +1 -1
- data/lib/capybara/queries/selector_query.rb +7 -7
- data/lib/capybara/queries/style_query.rb +1 -1
- data/lib/capybara/rack_test/form.rb +1 -1
- data/lib/capybara/registrations/drivers.rb +36 -0
- data/lib/capybara/registrations/servers.rb +38 -0
- data/lib/capybara/result.rb +2 -2
- data/lib/capybara/rspec/matcher_proxies.rb +2 -2
- data/lib/capybara/rspec/matchers/base.rb +2 -2
- data/lib/capybara/rspec/matchers.rb +1 -1
- data/lib/capybara/selector/css.rb +3 -3
- data/lib/capybara/selector/filters/base.rb +1 -1
- data/lib/capybara/selector/selector.rb +1 -0
- data/lib/capybara/selector/xpath_extensions.rb +8 -0
- data/lib/capybara/selector.rb +117 -102
- data/lib/capybara/selenium/driver.rb +97 -48
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +16 -4
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +23 -0
- data/lib/capybara/selenium/driver_specializations/internet_explorer_driver.rb +5 -0
- data/lib/capybara/selenium/driver_specializations/safari_driver.rb +13 -0
- data/lib/capybara/selenium/extensions/find.rb +48 -37
- data/lib/capybara/selenium/extensions/html5_drag.rb +3 -1
- data/lib/capybara/selenium/logger_suppressor.rb +29 -0
- data/lib/capybara/selenium/node.rb +22 -8
- data/lib/capybara/selenium/nodes/chrome_node.rb +8 -4
- data/lib/capybara/selenium/patches/persistent_client.rb +20 -0
- data/lib/capybara/server/animation_disabler.rb +1 -1
- data/lib/capybara/server/checker.rb +1 -1
- data/lib/capybara/server/middleware.rb +3 -3
- data/lib/capybara/session/config.rb +2 -8
- data/lib/capybara/session.rb +9 -5
- data/lib/capybara/spec/session/attach_file_spec.rb +1 -1
- data/lib/capybara/spec/session/check_spec.rb +4 -4
- data/lib/capybara/spec/session/choose_spec.rb +2 -2
- data/lib/capybara/spec/session/click_button_spec.rb +28 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +2 -2
- data/lib/capybara/spec/session/find_spec.rb +1 -1
- data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +14 -1
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +12 -1
- data/lib/capybara/spec/session/has_css_spec.rb +9 -2
- data/lib/capybara/spec/session/has_table_spec.rb +4 -4
- data/lib/capybara/spec/session/node_spec.rb +18 -6
- data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
- data/lib/capybara/spec/session/unselect_spec.rb +1 -1
- data/lib/capybara/spec/spec_helper.rb +1 -1
- data/lib/capybara/spec/views/frame_child.erb +2 -1
- data/lib/capybara/spec/views/react.erb +45 -0
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +1 -1
- data/lib/capybara.rb +2 -70
- data/spec/minitest_spec_spec.rb +1 -1
- data/spec/result_spec.rb +10 -6
- data/spec/rspec/shared_spec_matchers.rb +8 -4
- data/spec/sauce_spec_chrome.rb +42 -0
- data/spec/selector_spec.rb +4 -0
- data/spec/selenium_spec_safari.rb +2 -3
- data/spec/session_spec.rb +7 -0
- data/spec/shared_selenium_session.rb +14 -12
- data/spec/spec_helper.rb +2 -1
- 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
|
-
|
|
116
|
+
before do
|
|
117
117
|
Capybara.predicates_wait = false
|
|
118
|
-
Capybara.default_max_wait_time =
|
|
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
|
-
[
|
|
53
|
-
[
|
|
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
|
-
[
|
|
88
|
-
[
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
117
|
-
|
|
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(:
|
|
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,
|
|
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,
|
|
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 =
|
|
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']
|
|
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>
|
data/lib/capybara/version.rb
CHANGED
data/lib/capybara/window.rb
CHANGED
|
@@ -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
|
-
|
|
470
|
-
|
|
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
|
data/spec/minitest_spec_spec.rb
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
data/spec/selector_spec.rb
CHANGED
|
@@ -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
|
|
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 '
|
|
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
|
-
|
|
478
|
-
session.
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
session.
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
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
|
-
|
|
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)
|