capybara 3.30.0 → 3.31.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +21 -0
- data/README.md +1 -1
- data/lib/capybara/dsl.rb +10 -2
- data/lib/capybara/minitest.rb +18 -4
- data/lib/capybara/node/element.rb +11 -8
- data/lib/capybara/node/finders.rb +5 -1
- data/lib/capybara/node/matchers.rb +24 -15
- data/lib/capybara/node/simple.rb +1 -1
- data/lib/capybara/queries/base_query.rb +2 -1
- data/lib/capybara/rack_test/node.rb +34 -9
- data/lib/capybara/result.rb +24 -4
- data/lib/capybara/rspec/matchers.rb +27 -27
- data/lib/capybara/rspec/matchers/base.rb +12 -6
- data/lib/capybara/rspec/matchers/count_sugar.rb +2 -1
- data/lib/capybara/rspec/matchers/have_ancestor.rb +4 -3
- data/lib/capybara/rspec/matchers/have_current_path.rb +2 -2
- data/lib/capybara/rspec/matchers/have_selector.rb +15 -7
- data/lib/capybara/rspec/matchers/have_sibling.rb +3 -3
- data/lib/capybara/rspec/matchers/have_text.rb +2 -2
- data/lib/capybara/rspec/matchers/have_title.rb +2 -2
- data/lib/capybara/rspec/matchers/match_selector.rb +3 -3
- data/lib/capybara/rspec/matchers/match_style.rb +2 -2
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +2 -1
- data/lib/capybara/selector.rb +2 -0
- data/lib/capybara/selector/definition/label.rb +1 -1
- data/lib/capybara/selector/definition/select.rb +31 -12
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +1 -1
- data/lib/capybara/selenium/extensions/html5_drag.rb +24 -8
- data/lib/capybara/selenium/node.rb +23 -6
- data/lib/capybara/selenium/nodes/chrome_node.rb +4 -2
- data/lib/capybara/selenium/nodes/edge_node.rb +1 -1
- data/lib/capybara/selenium/nodes/firefox_node.rb +1 -1
- data/lib/capybara/session.rb +30 -15
- data/lib/capybara/spec/public/test.js +40 -6
- data/lib/capybara/spec/session/all_spec.rb +45 -5
- data/lib/capybara/spec/session/assert_text_spec.rb +5 -5
- data/lib/capybara/spec/session/fill_in_spec.rb +20 -0
- data/lib/capybara/spec/session/has_css_spec.rb +3 -3
- data/lib/capybara/spec/session/has_select_spec.rb +28 -0
- data/lib/capybara/spec/session/has_text_spec.rb +5 -1
- data/lib/capybara/spec/session/node_spec.rb +92 -3
- data/lib/capybara/spec/views/form.erb +6 -1
- data/lib/capybara/version.rb +1 -1
- data/spec/rack_test_spec.rb +0 -1
- data/spec/result_spec.rb +4 -0
- data/spec/selenium_spec_chrome.rb +2 -1
- metadata +2 -2
@@ -95,6 +95,26 @@ Capybara::SpecHelper.spec '#fill_in' do
|
|
95
95
|
expect(extract_results(@session)['html5_color']).to eq('#112233')
|
96
96
|
end
|
97
97
|
|
98
|
+
describe 'with input[type="range"]' do
|
99
|
+
it 'should set the range slider correctly' do
|
100
|
+
@session.fill_in('form_age', with: 51)
|
101
|
+
@session.click_button('awesome')
|
102
|
+
expect(extract_results(@session)['age'].to_f).to eq 51
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should set the range slider to valid values' do
|
106
|
+
@session.fill_in('form_age', with: '37.6')
|
107
|
+
@session.click_button('awesome')
|
108
|
+
expect(extract_results(@session)['age'].to_f).to eq 37.5
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should respect the range slider limits' do
|
112
|
+
@session.fill_in('form_age', with: '3')
|
113
|
+
@session.click_button('awesome')
|
114
|
+
expect(extract_results(@session)['age'].to_f).to eq 13
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
98
118
|
it 'should fill in a field with a custom type' do
|
99
119
|
@session.fill_in('Schmooo', with: 'Schmooo is the game')
|
100
120
|
@session.click_button('awesome')
|
@@ -185,10 +185,10 @@ Capybara::SpecHelper.spec '#has_css?' do
|
|
185
185
|
end
|
186
186
|
|
187
187
|
it 'should be false when content occurs more times than given' do
|
188
|
-
expect(@session).not_to have_css('h2.head', maximum: 4) # edge case
|
189
|
-
expect(@session).not_to have_css('h2', maximum: 3)
|
188
|
+
# expect(@session).not_to have_css('h2.head', maximum: 4) # edge case
|
189
|
+
# expect(@session).not_to have_css('h2', maximum: 3)
|
190
190
|
expect(@session).not_to have_css('h2').at_most(3).times
|
191
|
-
expect(@session).not_to have_css('p', maximum: 1)
|
191
|
+
# expect(@session).not_to have_css('p', maximum: 1)
|
192
192
|
end
|
193
193
|
|
194
194
|
it 'should coerce maximum to an integer' do
|
@@ -117,6 +117,34 @@ Capybara::SpecHelper.spec '#has_select?' do
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
|
120
|
+
context 'with enabled options' do
|
121
|
+
it 'should be true if the listed options exist and are enabled' do
|
122
|
+
expect(@session).to have_select('form_title', enabled_options: %w[Mr Mrs Miss])
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should be false if the listed options do not exist' do
|
126
|
+
expect(@session).not_to have_select('form_title', enabled_options: ['Not there'])
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should be false if the listed option exists but is not enabled' do
|
130
|
+
expect(@session).not_to have_select('form_title', enabled_options: %w[Mr Mrs Miss Other])
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'with disabled options' do
|
135
|
+
it 'should be true if the listed options exist and are disabled' do
|
136
|
+
expect(@session).to have_select('form_title', disabled_options: ['Other'])
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should be false if the listed options do not exist' do
|
140
|
+
expect(@session).not_to have_select('form_title', disabled_options: ['Not there'])
|
141
|
+
end
|
142
|
+
|
143
|
+
it 'should be false if the listed option exists but is not disabled' do
|
144
|
+
expect(@session).not_to have_select('form_title', disabled_options: %w[Other Mrs])
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
120
148
|
context 'with partial options' do
|
121
149
|
it 'should be true if a field with the given partial options is on the page' do
|
122
150
|
expect(@session).to have_select('Region', with_options: %w[Norway Sweden])
|
@@ -127,7 +127,11 @@ Capybara::SpecHelper.spec '#has_text?' do
|
|
127
127
|
def to_hash; { value: 'Other hash' } end
|
128
128
|
end.new
|
129
129
|
@session.visit('/with_html')
|
130
|
-
|
130
|
+
if RUBY_VERSION >= '2.7'
|
131
|
+
expect(@session).to have_text(:visible, with_to_hash, **{})
|
132
|
+
else
|
133
|
+
expect(@session).to have_text(:visible, with_to_hash, {})
|
134
|
+
end
|
131
135
|
end
|
132
136
|
|
133
137
|
it 'should fail if passed without empty options' do
|
@@ -270,11 +270,11 @@ Capybara::SpecHelper.spec 'node' do
|
|
270
270
|
end
|
271
271
|
|
272
272
|
it 'works when details is toggled open and closed' do
|
273
|
-
@session.find(:css, '#closed_details').click
|
273
|
+
@session.find(:css, '#closed_details > summary').click
|
274
274
|
expect(@session).to have_css('#closed_details *', visible: true, count: 5)
|
275
275
|
.and(have_no_css('#closed_details *', visible: :hidden))
|
276
276
|
|
277
|
-
@session.find(:css, '#closed_details').click
|
277
|
+
@session.find(:css, '#closed_details > summary').click
|
278
278
|
descendants_css = '#closed_details > *:not(summary), #closed_details > *:not(summary) *'
|
279
279
|
expect(@session).to have_no_css(descendants_css, visible: true)
|
280
280
|
.and(have_css(descendants_css, visible: :hidden, count: 3))
|
@@ -468,6 +468,50 @@ Capybara::SpecHelper.spec 'node' do
|
|
468
468
|
end
|
469
469
|
end
|
470
470
|
|
471
|
+
it 'should simulate a single held down modifier key' do
|
472
|
+
%I[
|
473
|
+
alt
|
474
|
+
ctrl
|
475
|
+
meta
|
476
|
+
shift
|
477
|
+
].each do |modifier_key|
|
478
|
+
@session.visit('/with_js')
|
479
|
+
|
480
|
+
element = @session.find('//div[@id="drag"]')
|
481
|
+
target = @session.find('//div[@id="drop"]')
|
482
|
+
|
483
|
+
element.drag_to(target, drop_modifiers: modifier_key)
|
484
|
+
expect(@session).to have_css('div.drag_start', exact_text: 'Dragged!')
|
485
|
+
expect(@session).to have_xpath("//div[contains(., 'Dropped!-#{modifier_key}')]")
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
it 'should simulate multiple held down modifier keys' do
|
490
|
+
@session.visit('/with_js')
|
491
|
+
|
492
|
+
element = @session.find('//div[@id="drag"]')
|
493
|
+
target = @session.find('//div[@id="drop"]')
|
494
|
+
|
495
|
+
modifier_keys = %I[alt ctrl meta shift]
|
496
|
+
|
497
|
+
element.drag_to(target, drop_modifiers: modifier_keys)
|
498
|
+
expect(@session).to have_xpath("//div[contains(., 'Dropped!-#{modifier_keys.join('-')}')]")
|
499
|
+
end
|
500
|
+
|
501
|
+
it 'should support key aliases' do
|
502
|
+
{ control: :ctrl,
|
503
|
+
command: :meta,
|
504
|
+
cmd: :meta }.each do |(key_alias, key)|
|
505
|
+
@session.visit('/with_js')
|
506
|
+
|
507
|
+
element = @session.find('//div[@id="drag"]')
|
508
|
+
target = @session.find('//div[@id="drop"]')
|
509
|
+
|
510
|
+
element.drag_to(target, drop_modifiers: [key_alias])
|
511
|
+
expect(target).to have_text("Dropped!-#{key}", exact: true)
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
471
515
|
context 'HTML5', requires: %i[js html5_drag] do
|
472
516
|
it 'should HTML5 drag and drop an object' do
|
473
517
|
@session.visit('/with_js')
|
@@ -499,8 +543,13 @@ Capybara::SpecHelper.spec 'node' do
|
|
499
543
|
target = @session.find('//div[@id="drop_html5"]')
|
500
544
|
element.drag_to(target)
|
501
545
|
|
546
|
+
conditions = %w[DragLeave Drop DragEnd].map do |text|
|
547
|
+
have_css('div.log', text: text)
|
548
|
+
end
|
549
|
+
expect(@session).to(conditions.reduce { |memo, cond| memo.and(cond) })
|
550
|
+
|
502
551
|
# The first "DragOver" div is inserted by the last dragover event dispatched
|
503
|
-
drag_over_div = @session.
|
552
|
+
drag_over_div = @session.first('//div[@class="log" and starts-with(text(), "DragOver")]')
|
504
553
|
position = drag_over_div.text.sub('DragOver ', '')
|
505
554
|
|
506
555
|
expect(@session).to have_css('div.log', text: /DragLeave #{position}/, count: 1)
|
@@ -551,6 +600,46 @@ Capybara::SpecHelper.spec 'node' do
|
|
551
600
|
source.drag_to target
|
552
601
|
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
|
553
602
|
end
|
603
|
+
|
604
|
+
it 'should simulate a single held down modifier key' do
|
605
|
+
%I[alt ctrl meta shift].each do |modifier_key|
|
606
|
+
@session.visit('/with_js')
|
607
|
+
|
608
|
+
element = @session.find('//div[@id="drag_html5"]')
|
609
|
+
target = @session.find('//div[@id="drop_html5"]')
|
610
|
+
|
611
|
+
element.drag_to(target, drop_modifiers: modifier_key)
|
612
|
+
|
613
|
+
expect(@session).to have_css('div.drag_start', exact_text: 'HTML5 Dragged!')
|
614
|
+
expect(@session).to have_xpath("//div[contains(., 'HTML5 Dropped string: text/plain drag_html5-#{modifier_key}')]")
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
it 'should simulate multiple held down modifier keys' do
|
619
|
+
@session.visit('/with_js')
|
620
|
+
|
621
|
+
element = @session.find('//div[@id="drag_html5"]')
|
622
|
+
target = @session.find('//div[@id="drop_html5"]')
|
623
|
+
|
624
|
+
modifier_keys = %I[alt ctrl meta shift]
|
625
|
+
|
626
|
+
element.drag_to(target, drop_modifiers: modifier_keys)
|
627
|
+
expect(@session).to have_xpath("//div[contains(., 'HTML5 Dropped string: text/plain drag_html5-#{modifier_keys.join('-')}')]")
|
628
|
+
end
|
629
|
+
|
630
|
+
it 'should support key aliases' do
|
631
|
+
{ control: :ctrl,
|
632
|
+
command: :meta,
|
633
|
+
cmd: :meta }.each do |(key_alias, key)|
|
634
|
+
@session.visit('/with_js')
|
635
|
+
|
636
|
+
element = @session.find('//div[@id="drag_html5"]')
|
637
|
+
target = @session.find('//div[@id="drop_html5"]')
|
638
|
+
|
639
|
+
element.drag_to(target, drop_modifiers: [key_alias])
|
640
|
+
expect(target).to have_text(%r{^HTML5 Dropped string: text/plain drag_html5-#{key}$}m, exact: true)
|
641
|
+
end
|
642
|
+
end
|
554
643
|
end
|
555
644
|
end
|
556
645
|
|
@@ -11,7 +11,7 @@
|
|
11
11
|
<option>Miss</option>
|
12
12
|
<option disabled="disabled">Other</option>
|
13
13
|
</select>
|
14
|
-
|
14
|
+
</p>
|
15
15
|
|
16
16
|
<p>
|
17
17
|
<label for="customer_name">Customer Name
|
@@ -62,6 +62,11 @@
|
|
62
62
|
<input type="text" name="form[name]" value="John Smith" id="form_name"/>
|
63
63
|
</p>
|
64
64
|
|
65
|
+
<p>
|
66
|
+
<label for="form_age">Age</label>
|
67
|
+
<input type="range" name="form[age]" value="18" min="13" max="100" step="0.5" id="form_age"/>
|
68
|
+
</p>
|
69
|
+
|
65
70
|
<p>
|
66
71
|
<label for="form_schmooo">Schmooo</label>
|
67
72
|
<input type="schmooo" name="form[schmooo]" value="This is Schmooo!" id="form_schmooo"/>
|
data/lib/capybara/version.rb
CHANGED
data/spec/rack_test_spec.rb
CHANGED
@@ -82,7 +82,6 @@ RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
|
|
82
82
|
describe '#fill_in' do
|
83
83
|
it 'should warn that :fill_options are not supported' do
|
84
84
|
session.visit '/with_html'
|
85
|
-
|
86
85
|
expect { session.fill_in 'test_field', with: 'not_monkey', fill_options: { random: true } }.to \
|
87
86
|
output(/^Options passed to Node#set but the RackTest driver doesn't support any - ignoring/).to_stderr
|
88
87
|
expect(session).to have_field('test_field', with: 'not_monkey')
|
data/spec/result_spec.rb
CHANGED
@@ -78,6 +78,10 @@ RSpec.describe Capybara::Result do
|
|
78
78
|
eval <<~TEST, binding, __FILE__, __LINE__ + 1 if RUBY_VERSION.to_f > 2.5
|
79
79
|
expect(result[2..].map(&:text)).to eq %w[Gamma Delta]
|
80
80
|
TEST
|
81
|
+
eval <<~TEST, binding, __FILE__, __LINE__ + 1 if RUBY_VERSION.to_f > 2.6
|
82
|
+
expect(result[..2].map(&:text)).to eq %w[Alpha Beta Gamma]
|
83
|
+
expect(result[...2].map(&:text)).to eq %w[Alpha Beta]
|
84
|
+
TEST
|
81
85
|
end
|
82
86
|
|
83
87
|
it 'works with filter blocks' do
|
@@ -14,7 +14,8 @@ browser_options = ::Selenium::WebDriver::Chrome::Options.new
|
|
14
14
|
browser_options.headless! if ENV['HEADLESS']
|
15
15
|
browser_options.add_option(:w3c, ENV['W3C'] != 'false')
|
16
16
|
# Chromedriver 77 requires setting this for headless mode on linux
|
17
|
-
#
|
17
|
+
# Different versions of Chrome/selenium-webdriver require setting differently - jus set them all
|
18
|
+
browser_options.add_preference('download.default_directory', Capybara.save_path)
|
18
19
|
browser_options.add_preference(:download, default_directory: Capybara.save_path)
|
19
20
|
|
20
21
|
Capybara.register_driver :selenium_chrome do |app|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.31.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Walpole
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain:
|
12
12
|
- gem-public_cert.pem
|
13
|
-
date:
|
13
|
+
date: 2020-01-26 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: addressable
|