capybara 3.30.0 → 3.31.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 +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
|