capybara 3.36.0 → 3.39.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.md +94 -4
- data/README.md +24 -12
- data/lib/capybara/driver/node.rb +4 -0
- data/lib/capybara/dsl.rb +4 -10
- data/lib/capybara/helpers.rb +6 -2
- data/lib/capybara/minitest/spec.rb +2 -2
- data/lib/capybara/node/actions.rb +4 -4
- data/lib/capybara/node/base.rb +2 -1
- data/lib/capybara/node/element.rb +12 -1
- data/lib/capybara/node/finders.rb +10 -1
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/base_query.rb +2 -2
- data/lib/capybara/queries/selector_query.rb +24 -9
- data/lib/capybara/queries/text_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +63 -8
- data/lib/capybara/rack_test/driver.rb +4 -4
- data/lib/capybara/rack_test/form.rb +29 -7
- data/lib/capybara/rack_test/node.rb +19 -16
- data/lib/capybara/registration_container.rb +0 -3
- data/lib/capybara/registrations/drivers.rb +3 -3
- data/lib/capybara/registrations/servers.rb +30 -10
- data/lib/capybara/rspec/matcher_proxies.rb +3 -3
- data/lib/capybara/rspec/matchers/base.rb +8 -6
- data/lib/capybara/rspec/matchers/compound.rb +1 -1
- data/lib/capybara/rspec/matchers/have_selector.rb +4 -4
- data/lib/capybara/rspec/matchers.rb +14 -14
- data/lib/capybara/selector/definition/link.rb +2 -1
- data/lib/capybara/selector/definition.rb +3 -2
- data/lib/capybara/selector/filter_set.rb +4 -5
- data/lib/capybara/selector/regexp_disassembler.rb +2 -5
- data/lib/capybara/selector/selector.rb +5 -1
- data/lib/capybara/selenium/driver.rb +11 -4
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +8 -4
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +1 -1
- data/lib/capybara/selenium/extensions/html5_drag.rb +5 -4
- data/lib/capybara/selenium/logger_suppressor.rb +6 -2
- data/lib/capybara/selenium/node.rb +72 -25
- data/lib/capybara/selenium/nodes/chrome_node.rb +5 -1
- data/lib/capybara/selenium/nodes/edge_node.rb +24 -2
- data/lib/capybara/selenium/nodes/firefox_node.rb +2 -2
- data/lib/capybara/selenium/nodes/safari_node.rb +2 -2
- data/lib/capybara/selenium/patches/action_pauser.rb +3 -3
- data/lib/capybara/selenium/patches/atoms.rb +1 -1
- data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -1
- data/lib/capybara/server/animation_disabler.rb +36 -25
- data/lib/capybara/server/middleware.rb +1 -1
- data/lib/capybara/session/config.rb +4 -2
- data/lib/capybara/session.rb +19 -30
- data/lib/capybara/spec/public/test.js +4 -0
- data/lib/capybara/spec/session/all_spec.rb +6 -8
- data/lib/capybara/spec/session/assert_text_spec.rb +17 -17
- data/lib/capybara/spec/session/attach_file_spec.rb +6 -0
- data/lib/capybara/spec/session/check_spec.rb +1 -0
- data/lib/capybara/spec/session/click_link_spec.rb +11 -0
- data/lib/capybara/spec/session/current_scope_spec.rb +1 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +6 -0
- data/lib/capybara/spec/session/find_link_spec.rb +10 -0
- data/lib/capybara/spec/session/find_spec.rb +7 -1
- data/lib/capybara/spec/session/first_spec.rb +1 -1
- data/lib/capybara/spec/session/frame/within_frame_spec.rb +2 -0
- data/lib/capybara/spec/session/has_all_selectors_spec.rb +5 -5
- data/lib/capybara/spec/session/has_ancestor_spec.rb +2 -2
- data/lib/capybara/spec/session/has_any_selectors_spec.rb +2 -2
- data/lib/capybara/spec/session/has_button_spec.rb +6 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +3 -3
- data/lib/capybara/spec/session/has_field_spec.rb +1 -1
- data/lib/capybara/spec/session/has_link_spec.rb +16 -0
- data/lib/capybara/spec/session/has_none_selectors_spec.rb +7 -7
- data/lib/capybara/spec/session/has_select_spec.rb +10 -4
- data/lib/capybara/spec/session/has_selector_spec.rb +15 -0
- data/lib/capybara/spec/session/has_text_spec.rb +5 -13
- data/lib/capybara/spec/session/matches_style_spec.rb +2 -0
- data/lib/capybara/spec/session/node_spec.rb +81 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +13 -0
- data/lib/capybara/spec/session/scroll_spec.rb +3 -1
- data/lib/capybara/spec/session/visit_spec.rb +20 -0
- data/lib/capybara/spec/session/window/window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
- data/lib/capybara/spec/session/within_spec.rb +13 -0
- data/lib/capybara/spec/spec_helper.rb +8 -2
- data/lib/capybara/spec/test_app.rb +74 -6
- data/lib/capybara/spec/views/form.erb +17 -0
- data/lib/capybara/spec/views/with_html.erb +3 -3
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +1 -1
- data/lib/capybara.rb +5 -2
- data/spec/capybara_spec.rb +12 -0
- data/spec/counter_spec.rb +35 -0
- data/spec/css_builder_spec.rb +1 -1
- data/spec/css_splitter_spec.rb +1 -1
- data/spec/dsl_spec.rb +4 -2
- data/spec/fixtures/selenium_driver_rspec_failure.rb +2 -2
- data/spec/fixtures/selenium_driver_rspec_success.rb +2 -2
- data/spec/minitest_spec.rb +4 -0
- data/spec/minitest_spec_spec.rb +4 -0
- data/spec/per_session_config_spec.rb +1 -1
- data/spec/rack_test_spec.rb +16 -2
- data/spec/result_spec.rb +27 -29
- data/spec/rspec/features_spec.rb +2 -2
- data/spec/rspec/scenarios_spec.rb +2 -2
- data/spec/rspec/shared_spec_matchers.rb +1 -1
- data/spec/rspec_matchers_spec.rb +25 -0
- data/spec/rspec_spec.rb +2 -2
- data/spec/sauce_spec_chrome.rb +4 -4
- data/spec/selector_spec.rb +4 -4
- data/spec/selenium_spec_chrome.rb +8 -7
- data/spec/selenium_spec_chrome_remote.rb +9 -9
- data/spec/selenium_spec_edge.rb +12 -6
- data/spec/selenium_spec_firefox.rb +21 -5
- data/spec/selenium_spec_firefox_remote.rb +19 -4
- data/spec/selenium_spec_ie.rb +4 -2
- data/spec/selenium_spec_safari.rb +8 -2
- data/spec/server_spec.rb +7 -7
- data/spec/shared_selenium_session.rb +13 -6
- data/spec/spec_helper.rb +35 -2
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +1 -1
- metadata +9 -4
data/lib/capybara/session.rb
CHANGED
@@ -40,6 +40,7 @@ module Capybara
|
|
40
40
|
|
41
41
|
NODE_METHODS = %i[
|
42
42
|
all first attach_file text check choose scroll_to scroll_by
|
43
|
+
click double_click right_click
|
43
44
|
click_link_or_button click_button click_link
|
44
45
|
fill_in find find_all find_button find_by_id find_field find_link
|
45
46
|
has_content? has_text? has_css? has_no_content? has_no_text?
|
@@ -58,7 +59,7 @@ module Capybara
|
|
58
59
|
].freeze
|
59
60
|
SESSION_METHODS = %i[
|
60
61
|
body html source current_url current_host current_path
|
61
|
-
execute_script evaluate_script visit refresh go_back go_forward send_keys
|
62
|
+
execute_script evaluate_script evaluate_async_script visit refresh go_back go_forward send_keys
|
62
63
|
within within_element within_fieldset within_table within_frame switch_to_frame
|
63
64
|
current_window windows open_new_window switch_to_window within_window window_opened_by
|
64
65
|
save_page save_and_open_page save_screenshot
|
@@ -129,6 +130,8 @@ module Capybara
|
|
129
130
|
if @touched
|
130
131
|
driver.reset!
|
131
132
|
@touched = false
|
133
|
+
switch_to_frame(:top) rescue nil # rubocop:disable Style/RescueModifier
|
134
|
+
@scopes = [nil]
|
132
135
|
end
|
133
136
|
@server&.wait_for_pending_requests
|
134
137
|
raise_server_error!
|
@@ -159,9 +162,8 @@ module Capybara
|
|
159
162
|
if config.raise_server_errors
|
160
163
|
raise CapybaraError, 'Your application server raised an error - It has been raised in your test code because Capybara.raise_server_errors == true'
|
161
164
|
end
|
162
|
-
rescue CapybaraError
|
163
|
-
|
164
|
-
raise @server.error, @server.error.message, @server.error.backtrace
|
165
|
+
rescue CapybaraError => capy_error # rubocop:disable Naming/RescuedExceptionsVariableName
|
166
|
+
raise @server.error, cause: capy_error
|
165
167
|
ensure
|
166
168
|
@server.reset_error!
|
167
169
|
end
|
@@ -360,7 +362,7 @@ module Capybara
|
|
360
362
|
new_scope = args.first.respond_to?(:to_capybara_node) ? args.first.to_capybara_node : find(*args, **kw_args)
|
361
363
|
begin
|
362
364
|
scopes.push(new_scope)
|
363
|
-
yield if block_given?
|
365
|
+
yield new_scope if block_given?
|
364
366
|
ensure
|
365
367
|
scopes.pop
|
366
368
|
end
|
@@ -409,7 +411,7 @@ module Capybara
|
|
409
411
|
scopes.push(:frame)
|
410
412
|
when :parent
|
411
413
|
if scopes.last != :frame
|
412
|
-
raise Capybara::ScopeError, "`switch_to_frame(:parent)` cannot be called from inside a descendant frame's "\
|
414
|
+
raise Capybara::ScopeError, "`switch_to_frame(:parent)` cannot be called from inside a descendant frame's " \
|
413
415
|
'`within` block.'
|
414
416
|
end
|
415
417
|
scopes.pop
|
@@ -419,7 +421,7 @@ module Capybara
|
|
419
421
|
top_level_scopes = [:frame, nil]
|
420
422
|
if idx
|
421
423
|
if scopes.slice(idx..).any? { |scope| !top_level_scopes.include?(scope) }
|
422
|
-
raise Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's "\
|
424
|
+
raise Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's " \
|
423
425
|
'`within` block.'
|
424
426
|
end
|
425
427
|
scopes.slice!(idx..)
|
@@ -511,7 +513,7 @@ module Capybara
|
|
511
513
|
raise ArgumentError, '`switch_to_window`: either window or block should be provided' if !window && !window_locator
|
512
514
|
|
513
515
|
unless scopes.last.nil?
|
514
|
-
raise Capybara::ScopeError, '`switch_to_window` is not supposed to be invoked from '\
|
516
|
+
raise Capybara::ScopeError, '`switch_to_window` is not supposed to be invoked from ' \
|
515
517
|
'`within` or `within_frame` blocks.'
|
516
518
|
end
|
517
519
|
|
@@ -582,7 +584,7 @@ module Capybara
|
|
582
584
|
synchronize_windows(options) do
|
583
585
|
opened_handles = (driver.window_handles - old_handles)
|
584
586
|
if opened_handles.size != 1
|
585
|
-
raise Capybara::WindowError, 'block passed to #window_opened_by '\
|
587
|
+
raise Capybara::WindowError, 'block passed to #window_opened_by ' \
|
586
588
|
"opened #{opened_handles.size} windows instead of 1"
|
587
589
|
end
|
588
590
|
Window.new(self, opened_handles.first)
|
@@ -765,33 +767,20 @@ module Capybara
|
|
765
767
|
end
|
766
768
|
|
767
769
|
NODE_METHODS.each do |method|
|
768
|
-
|
769
|
-
|
770
|
-
def #{method}(...)
|
771
|
-
@touched = true
|
772
|
-
current_scope.#{method}(...)
|
773
|
-
end
|
774
|
-
METHOD
|
775
|
-
else
|
776
|
-
define_method method do |*args, &block|
|
770
|
+
class_eval <<~METHOD, __FILE__, __LINE__ + 1
|
771
|
+
def #{method}(...)
|
777
772
|
@touched = true
|
778
|
-
current_scope
|
773
|
+
current_scope.#{method}(...)
|
779
774
|
end
|
780
|
-
|
775
|
+
METHOD
|
781
776
|
end
|
782
777
|
|
783
778
|
DOCUMENT_METHODS.each do |method|
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
document.#{method}(...)
|
788
|
-
end
|
789
|
-
METHOD
|
790
|
-
else
|
791
|
-
define_method method do |*args, &block|
|
792
|
-
document.send(method, *args, &block)
|
779
|
+
class_eval <<~METHOD, __FILE__, __LINE__ + 1
|
780
|
+
def #{method}(...)
|
781
|
+
document.#{method}(...)
|
793
782
|
end
|
794
|
-
|
783
|
+
METHOD
|
795
784
|
end
|
796
785
|
|
797
786
|
def inspect
|
@@ -44,6 +44,10 @@ $(function() {
|
|
44
44
|
$(this).after('<div class="log">DragOver with client position: ' + ev.clientX + ',' + ev.clientY)
|
45
45
|
if ($(this).hasClass('drop')) { ev.preventDefault(); }
|
46
46
|
});
|
47
|
+
$('#drop_html5, #drop_html5_scroll').on('dragenter', function(ev){
|
48
|
+
$(this).after('<div class="log">DragEnter')
|
49
|
+
if ($(this).hasClass('drop')) { ev.preventDefault(); }
|
50
|
+
});
|
47
51
|
$('#drop_html5, #drop_html5_scroll').on('dragleave', function(ev){
|
48
52
|
$(this).after('<div class="log">DragLeave with client position: ' + ev.clientX + ',' + ev.clientY)
|
49
53
|
if ($(this).hasClass('drop')) { ev.preventDefault(); }
|
@@ -31,7 +31,7 @@ Capybara::SpecHelper.spec '#all' do
|
|
31
31
|
it 'should accept an XPath instance', :exact_false do
|
32
32
|
@session.visit('/form')
|
33
33
|
@xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('Name')
|
34
|
-
expect(@xpath).to be_a(
|
34
|
+
expect(@xpath).to be_a(XPath::Union)
|
35
35
|
@result = @session.all(@xpath).map(&:value)
|
36
36
|
expect(@result).to include('Smith', 'John', 'John Smith')
|
37
37
|
end
|
@@ -132,7 +132,7 @@ Capybara::SpecHelper.spec '#all' do
|
|
132
132
|
it 'should use the sessions ignore_hidden_elements', psc: true do
|
133
133
|
Capybara.ignore_hidden_elements = true
|
134
134
|
@session.config.ignore_hidden_elements = false
|
135
|
-
expect(Capybara.ignore_hidden_elements).to
|
135
|
+
expect(Capybara.ignore_hidden_elements).to be(true)
|
136
136
|
expect(@session.all(:css, 'a.simple').size).to eq(2)
|
137
137
|
@session.config.ignore_hidden_elements = true
|
138
138
|
expect(@session.all(:css, 'a.simple').size).to eq(1)
|
@@ -208,12 +208,10 @@ Capybara::SpecHelper.spec '#all' do
|
|
208
208
|
expect { @session.all(:css, 'h1, p', between: 5..) }.to raise_error(Capybara::ExpectationNotMet)
|
209
209
|
end
|
210
210
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
end
|
216
|
-
TEST
|
211
|
+
it 'treats a beginless range as maximum' do
|
212
|
+
expect { @session.all(:css, 'h1, p', between: ..7) }.not_to raise_error
|
213
|
+
expect { @session.all(:css, 'h1, p', between: ..3) }.to raise_error(Capybara::ExpectationNotMet)
|
214
|
+
end
|
217
215
|
end
|
218
216
|
|
219
217
|
context 'with multiple count filters' do
|
@@ -3,16 +3,16 @@
|
|
3
3
|
Capybara::SpecHelper.spec '#assert_text' do
|
4
4
|
it 'should be true if the given text is on the page' do
|
5
5
|
@session.visit('/with_html')
|
6
|
-
expect(@session.assert_text('est')).to
|
7
|
-
expect(@session.assert_text('Lorem')).to
|
8
|
-
expect(@session.assert_text('Redirect')).to
|
9
|
-
expect(@session.assert_text(:Redirect)).to
|
10
|
-
expect(@session.assert_text('text with whitespace')).to
|
6
|
+
expect(@session.assert_text('est')).to be(true)
|
7
|
+
expect(@session.assert_text('Lorem')).to be(true)
|
8
|
+
expect(@session.assert_text('Redirect')).to be(true)
|
9
|
+
expect(@session.assert_text(:Redirect)).to be(true)
|
10
|
+
expect(@session.assert_text('text with whitespace')).to be(true)
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'should support collapsing whitespace' do
|
14
14
|
@session.visit('/with_html')
|
15
|
-
expect(@session.assert_text('text with whitespace', normalize_ws: true)).to
|
15
|
+
expect(@session.assert_text('text with whitespace', normalize_ws: true)).to be(true)
|
16
16
|
end
|
17
17
|
|
18
18
|
context 'with enabled default collapsing whitespace' do
|
@@ -20,19 +20,19 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
20
20
|
|
21
21
|
it 'should be true if the given unnormalized text is on the page' do
|
22
22
|
@session.visit('/with_html')
|
23
|
-
expect(@session.assert_text('text with whitespace', normalize_ws: false)).to
|
23
|
+
expect(@session.assert_text('text with whitespace', normalize_ws: false)).to be(true)
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should support collapsing whitespace' do
|
27
27
|
@session.visit('/with_html')
|
28
|
-
expect(@session.assert_text('text with whitespace')).to
|
28
|
+
expect(@session.assert_text('text with whitespace')).to be(true)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'should take scopes into account' do
|
33
33
|
@session.visit('/with_html')
|
34
34
|
@session.within("//a[@title='awesome title']") do
|
35
|
-
expect(@session.assert_text('labore')).to
|
35
|
+
expect(@session.assert_text('labore')).to be(true)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -47,13 +47,13 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
47
47
|
|
48
48
|
it 'should be true if :all given and text is invisible.' do
|
49
49
|
@session.visit('/with_html')
|
50
|
-
expect(@session.assert_text(:all, 'Some of this text is hidden!')).to
|
50
|
+
expect(@session.assert_text(:all, 'Some of this text is hidden!')).to be(true)
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'should be true if `Capybara.ignore_hidden_elements = true` and text is invisible.' do
|
54
54
|
Capybara.ignore_hidden_elements = false
|
55
55
|
@session.visit('/with_html')
|
56
|
-
expect(@session.assert_text('Some of this text is hidden!')).to
|
56
|
+
expect(@session.assert_text('Some of this text is hidden!')).to be(true)
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'should raise error with a helpful message if the requested text is present but invisible' do
|
@@ -88,7 +88,7 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
88
88
|
|
89
89
|
it 'should be true if the text in the page matches given regexp' do
|
90
90
|
@session.visit('/with_html')
|
91
|
-
expect(@session.assert_text(/Lorem/)).to
|
91
|
+
expect(@session.assert_text(/Lorem/)).to be(true)
|
92
92
|
end
|
93
93
|
|
94
94
|
it "should raise error if the text in the page doesn't match given regexp" do
|
@@ -109,13 +109,13 @@ Capybara::SpecHelper.spec '#assert_text' do
|
|
109
109
|
Capybara.default_max_wait_time = 2
|
110
110
|
@session.visit('/with_js')
|
111
111
|
@session.click_link('Click me')
|
112
|
-
expect(@session.assert_text('Has been clicked')).to
|
112
|
+
expect(@session.assert_text('Has been clicked')).to be(true)
|
113
113
|
end
|
114
114
|
|
115
115
|
context 'with between' do
|
116
116
|
it 'should be true if the text occurs within the range given' do
|
117
117
|
@session.visit('/with_count')
|
118
|
-
expect(@session.assert_text('count', between: 1..3)).to
|
118
|
+
expect(@session.assert_text('count', between: 1..3)).to be(true)
|
119
119
|
end
|
120
120
|
|
121
121
|
it 'should be false if the text occurs more or fewer times than range' do
|
@@ -203,13 +203,13 @@ Capybara::SpecHelper.spec '#assert_no_text' do
|
|
203
203
|
it 'should be true if scoped to an element which does not have the text' do
|
204
204
|
@session.visit('/with_html')
|
205
205
|
@session.within("//a[@title='awesome title']") do
|
206
|
-
expect(@session.assert_no_text('monkey')).to
|
206
|
+
expect(@session.assert_no_text('monkey')).to be(true)
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
210
|
it 'should be true if the given text is on the page but not visible' do
|
211
211
|
@session.visit('/with_html')
|
212
|
-
expect(@session.assert_no_text('Inside element with hidden ancestor')).to
|
212
|
+
expect(@session.assert_no_text('Inside element with hidden ancestor')).to be(true)
|
213
213
|
end
|
214
214
|
|
215
215
|
it 'should raise error if :all given and text is invisible.' do
|
@@ -236,7 +236,7 @@ Capybara::SpecHelper.spec '#assert_no_text' do
|
|
236
236
|
context 'with count' do
|
237
237
|
it 'should be true if the text occurs within the range given' do
|
238
238
|
@session.visit('/with_count')
|
239
|
-
expect(@session.assert_text('count', count: 2)).to
|
239
|
+
expect(@session.assert_text('count', count: 2)).to be(true)
|
240
240
|
end
|
241
241
|
|
242
242
|
it 'should be false if the text occurs more or fewer times than range' do
|
@@ -55,6 +55,12 @@ Capybara::SpecHelper.spec '#attach_file' do
|
|
55
55
|
expect(@session).to have_content('No file uploaded')
|
56
56
|
end
|
57
57
|
|
58
|
+
it 'should send prior hidden field if no file submitted' do
|
59
|
+
@session.click_button('Upload Empty With Hidden')
|
60
|
+
expect(extract_results(@session)['document2']).to eq('hidden_field')
|
61
|
+
expect(extract_content_type(@session)).to start_with('multipart/form-data;')
|
62
|
+
end
|
63
|
+
|
58
64
|
it 'should send content type text/plain when uploading a text file' do
|
59
65
|
@session.attach_file 'Single Document', with_os_path_separators(test_file_path)
|
60
66
|
@session.click_button 'Upload Single'
|
@@ -239,6 +239,7 @@ Capybara::SpecHelper.spec '#check' do
|
|
239
239
|
|
240
240
|
context 'with allow_label_click options', requires: [:js] do
|
241
241
|
it 'should allow offsets to click location on label' do
|
242
|
+
Capybara.w3c_click_offset = false
|
242
243
|
expect(@session.find(:checkbox, 'form_cars_lotus', unchecked: true, visible: :hidden)).to be_truthy
|
243
244
|
@session.check('form_cars_lotus', allow_label_click: { x: 90, y: 10 })
|
244
245
|
@session.click_button('awesome')
|
@@ -131,6 +131,17 @@ Capybara::SpecHelper.spec '#click_link' do
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
+
context 'with :target option given' do
|
135
|
+
it 'should find links with valid target' do
|
136
|
+
@session.click_link('labore', target: '_self')
|
137
|
+
expect(@session).to have_content('Bar')
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should raise error if link wasn't found" do
|
141
|
+
expect { @session.click_link('labore', target: '_blank') }.to raise_error(Capybara::ElementNotFound, /Unable to find link "labore"/)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
134
145
|
it 'should follow relative links' do
|
135
146
|
@session.visit('/')
|
136
147
|
@session.click_link('Relative')
|
@@ -7,7 +7,7 @@ Capybara::SpecHelper.spec '#current_scope' do
|
|
7
7
|
|
8
8
|
context 'when not in a #within block' do
|
9
9
|
it 'should return the document' do
|
10
|
-
expect(@session.current_scope).to
|
10
|
+
expect(@session.current_scope).to be_a Capybara::Node::Document
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -98,6 +98,12 @@ Capybara::SpecHelper.spec '#fill_in' do
|
|
98
98
|
expect(extract_results(@session)['description']).to eq("\r\nSome text\r\n")
|
99
99
|
end
|
100
100
|
|
101
|
+
it 'should handle carriage returns with line feeds in a textarea correctly' do
|
102
|
+
@session.fill_in('form_description', with: "\r\nSome text\r\n")
|
103
|
+
@session.click_button('awesome')
|
104
|
+
expect(extract_results(@session)['description']).to eq("\r\nSome text\r\n")
|
105
|
+
end
|
106
|
+
|
101
107
|
it 'should fill in a color field' do
|
102
108
|
@session.fill_in('Html5 Color', with: '#112233')
|
103
109
|
@session.click_button('html5_submit')
|
@@ -67,4 +67,14 @@ Capybara::SpecHelper.spec '#find_link' do
|
|
67
67
|
expect { @session.find_link(download: 37) }.to raise_error ArgumentError
|
68
68
|
end
|
69
69
|
end
|
70
|
+
|
71
|
+
context 'with :target option' do
|
72
|
+
it 'should accept partial matches when false' do
|
73
|
+
expect(@session.find_link(target: '_self').text).to eq('labore')
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should not accept partial matches when true' do
|
77
|
+
expect { @session.find_link(target: '_blank') }.to raise_error Capybara::ElementNotFound
|
78
|
+
end
|
79
|
+
end
|
70
80
|
end
|
@@ -236,7 +236,7 @@ Capybara::SpecHelper.spec '#find' do
|
|
236
236
|
it 'should accept an XPath instance' do
|
237
237
|
@session.visit('/form')
|
238
238
|
@xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('First Name')
|
239
|
-
expect(@xpath).to be_a(
|
239
|
+
expect(@xpath).to be_a(XPath::Union)
|
240
240
|
expect(@session.find(@xpath).value).to eq('John')
|
241
241
|
end
|
242
242
|
|
@@ -528,4 +528,10 @@ Capybara::SpecHelper.spec '#find' do
|
|
528
528
|
expect(@session.find(:link, 'test-foo')[:id]).to eq 'foo'
|
529
529
|
end
|
530
530
|
end
|
531
|
+
|
532
|
+
it 'should warn if passed count options' do
|
533
|
+
allow(Capybara::Helpers).to receive(:warn)
|
534
|
+
@session.find('//h1', count: 44)
|
535
|
+
expect(Capybara::Helpers).to have_received(:warn).with(/'find' does not support count options/)
|
536
|
+
end
|
531
537
|
end
|
@@ -25,7 +25,7 @@ Capybara::SpecHelper.spec '#first' do
|
|
25
25
|
it 'should accept an XPath instance' do
|
26
26
|
@session.visit('/form')
|
27
27
|
@xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('First Name')
|
28
|
-
expect(@xpath).to be_a(
|
28
|
+
expect(@xpath).to be_a(XPath::Union)
|
29
29
|
expect(@session.first(@xpath).value).to eq('John')
|
30
30
|
end
|
31
31
|
|
@@ -64,7 +64,9 @@ Capybara::SpecHelper.spec '#within_frame', requires: [:frames] do
|
|
64
64
|
end
|
65
65
|
expect do
|
66
66
|
# Multiple frames in scope here
|
67
|
+
# rubocop:disable Style/Semicolon
|
67
68
|
@session.within_frame { ; }
|
69
|
+
# rubocop:enable Style/Semicolon
|
68
70
|
end.to raise_error Capybara::Ambiguous
|
69
71
|
end
|
70
72
|
|
@@ -12,7 +12,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
|
|
12
12
|
it 'should be false if any of the given selectors are not on the page' do
|
13
13
|
expect do
|
14
14
|
expect(@session).to have_all_of_selectors(:css, 'p a#foo', 'h2#h2three', 'h2#h2one')
|
15
|
-
end.to raise_error
|
15
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'should use default selector' do
|
@@ -20,7 +20,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
|
|
20
20
|
expect(@session).to have_all_of_selectors('p a#foo', 'h2#h2two', 'h2#h2one')
|
21
21
|
expect do
|
22
22
|
expect(@session).to have_all_of_selectors('p a#foo', 'h2#h2three', 'h2#h2one')
|
23
|
-
end.to raise_error
|
23
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
24
24
|
end
|
25
25
|
|
26
26
|
context 'should respect scopes' do
|
@@ -29,7 +29,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
|
|
29
29
|
expect(@session).to have_all_of_selectors(".//a[@id='foo']")
|
30
30
|
expect do
|
31
31
|
expect(@session).to have_all_of_selectors(".//a[@id='red']")
|
32
|
-
end.to raise_error
|
32
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -38,7 +38,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
|
|
38
38
|
expect(el).to have_all_of_selectors(".//a[@id='foo']")
|
39
39
|
expect do
|
40
40
|
expect(el).to have_all_of_selectors(".//a[@id='red']")
|
41
|
-
end.to raise_error
|
41
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -47,7 +47,7 @@ Capybara::SpecHelper.spec '#have_all_of_selectors' do
|
|
47
47
|
expect(@session).to have_all_of_selectors(:field, 'normal', 'additional_newline', type: :textarea)
|
48
48
|
expect do
|
49
49
|
expect(@session).to have_all_of_selectors(:field, 'normal', 'test_field', 'additional_newline', type: :textarea)
|
50
|
-
end.to raise_error
|
50
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
@@ -39,8 +39,8 @@ Capybara::SpecHelper.spec '#have_no_ancestor' do
|
|
39
39
|
it 'should assert no matching ancestor' do
|
40
40
|
el = @session.find(:css, '#ancestor1')
|
41
41
|
expect(el).to have_no_ancestor(:css, '#child')
|
42
|
-
expect(el).to have_no_ancestor(:css, '#
|
42
|
+
expect(el).to have_no_ancestor(:css, '#ancestor1_sibling')
|
43
43
|
expect(el).not_to have_ancestor(:css, '#child')
|
44
|
-
expect(el).not_to have_ancestor(:css, '#
|
44
|
+
expect(el).not_to have_ancestor(:css, '#ancestor1_sibling')
|
45
45
|
end
|
46
46
|
end
|
@@ -12,7 +12,7 @@ Capybara::SpecHelper.spec '#have_any_of_selectors' do
|
|
12
12
|
it 'should be false if none of the given selectors are not on the page' do
|
13
13
|
expect do
|
14
14
|
expect(@session).to have_any_of_selectors(:css, 'span a#foo', 'h2#h2nope', 'h2#h2one_no')
|
15
|
-
end.to raise_error
|
15
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'should use default selector' do
|
@@ -20,7 +20,7 @@ Capybara::SpecHelper.spec '#have_any_of_selectors' do
|
|
20
20
|
expect(@session).to have_any_of_selectors('p a#foo', 'h2#h2two', 'a#not_on_page')
|
21
21
|
expect do
|
22
22
|
expect(@session).to have_any_of_selectors('p a#blah', 'h2#h2three')
|
23
|
-
end.to raise_error
|
23
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'should be negateable' do
|
@@ -77,6 +77,12 @@ Capybara::SpecHelper.spec '#has_button?' do
|
|
77
77
|
expect(@session).to have_button('A Button', focused: false)
|
78
78
|
end
|
79
79
|
end
|
80
|
+
|
81
|
+
it 'should raise an error if an invalid option is passed' do
|
82
|
+
expect do
|
83
|
+
expect(@session).to have_button('A Button', invalid: true)
|
84
|
+
end.to raise_error(ArgumentError, 'Invalid option(s) :invalid, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :disabled, :name, :value, :title, :type')
|
85
|
+
end
|
80
86
|
end
|
81
87
|
|
82
88
|
Capybara::SpecHelper.spec '#has_no_button?' do
|
@@ -16,8 +16,8 @@ Capybara::SpecHelper.spec '#has_current_path?' do
|
|
16
16
|
|
17
17
|
it 'should not raise an error when non-http' do
|
18
18
|
@session.reset_session!
|
19
|
-
expect(@session.has_current_path?(/monkey/)).to
|
20
|
-
expect(@session.has_current_path?('/with_js')).to
|
19
|
+
expect(@session.has_current_path?(/monkey/)).to be false
|
20
|
+
expect(@session.has_current_path?('/with_js')).to be false
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'should handle non-escaped query options' do
|
@@ -75,7 +75,7 @@ Capybara::SpecHelper.spec '#has_current_path?' do
|
|
75
75
|
@session.visit('/with_js?test=test')
|
76
76
|
expect(@session).to have_current_path('/with_js?test=test')
|
77
77
|
expect(@session).to have_current_path('/with_js', ignore_query: true)
|
78
|
-
uri =
|
78
|
+
uri = Addressable::URI.parse(@session.current_url)
|
79
79
|
uri.query = nil
|
80
80
|
expect(@session).to have_current_path(uri.to_s, ignore_query: true)
|
81
81
|
end
|
@@ -383,7 +383,7 @@ Capybara::SpecHelper.spec '#has_no_unchecked_field?' do
|
|
383
383
|
end
|
384
384
|
|
385
385
|
it 'should support locator-less usage' do
|
386
|
-
expect(@session.has_no_unchecked_field?(disabled: false, id: 'form_disabled_unchecked_checkbox')).to
|
386
|
+
expect(@session.has_no_unchecked_field?(disabled: false, id: 'form_disabled_unchecked_checkbox')).to be true
|
387
387
|
expect(@session).to have_no_unchecked_field(disabled: false, id: 'form_disabled_unchecked_checkbox')
|
388
388
|
end
|
389
389
|
end
|
@@ -11,12 +11,20 @@ Capybara::SpecHelper.spec '#has_link?' do
|
|
11
11
|
expect(@session).to have_link('A link', href: '/with_simple_html')
|
12
12
|
expect(@session).to have_link(:'A link', href: :'/with_simple_html')
|
13
13
|
expect(@session).to have_link('A link', href: %r{/with_simple_html})
|
14
|
+
expect(@session).to have_link('labore', target: '_self')
|
14
15
|
end
|
15
16
|
|
16
17
|
it 'should be false if the given link is not on the page' do
|
17
18
|
expect(@session).not_to have_link('monkey')
|
18
19
|
expect(@session).not_to have_link('A link', href: '/nonexistent-href')
|
19
20
|
expect(@session).not_to have_link('A link', href: /nonexistent/)
|
21
|
+
expect(@session).not_to have_link('labore', target: '_blank')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should notify if an invalid locator is specified' do
|
25
|
+
allow(Capybara::Helpers).to receive(:warn).and_return(nil)
|
26
|
+
@session.has_link?(@session)
|
27
|
+
expect(Capybara::Helpers).to have_received(:warn).with(/Called from: .+/)
|
20
28
|
end
|
21
29
|
|
22
30
|
context 'with focused:', requires: [:active_element] do
|
@@ -30,6 +38,12 @@ Capybara::SpecHelper.spec '#has_link?' do
|
|
30
38
|
expect(@session).to have_link('labore', focused: false)
|
31
39
|
end
|
32
40
|
end
|
41
|
+
|
42
|
+
it 'should raise an error if an invalid option is passed' do
|
43
|
+
expect do
|
44
|
+
expect(@session).to have_link('labore', invalid: true)
|
45
|
+
end.to raise_error(ArgumentError, 'Invalid option(s) :invalid, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :href, :alt, :title, :target, :download')
|
46
|
+
end
|
33
47
|
end
|
34
48
|
|
35
49
|
Capybara::SpecHelper.spec '#has_no_link?' do
|
@@ -41,12 +55,14 @@ Capybara::SpecHelper.spec '#has_no_link?' do
|
|
41
55
|
expect(@session).not_to have_no_link('foo')
|
42
56
|
expect(@session).not_to have_no_link('awesome title')
|
43
57
|
expect(@session).not_to have_no_link('A link', href: '/with_simple_html')
|
58
|
+
expect(@session).not_to have_no_link('labore', target: '_self')
|
44
59
|
end
|
45
60
|
|
46
61
|
it 'should be true if the given link is not on the page' do
|
47
62
|
expect(@session).to have_no_link('monkey')
|
48
63
|
expect(@session).to have_no_link('A link', href: '/nonexistent-href')
|
49
64
|
expect(@session).to have_no_link('A link', href: %r{/nonexistent-href})
|
65
|
+
expect(@session).to have_no_link('labore', target: '_blank')
|
50
66
|
end
|
51
67
|
|
52
68
|
context 'with focused:', requires: [:active_element] do
|
@@ -8,10 +8,10 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
|
|
8
8
|
it 'should be false if any of the given locators are on the page' do
|
9
9
|
expect do
|
10
10
|
expect(@session).to have_none_of_selectors(:xpath, '//p', '//a')
|
11
|
-
end.to raise_error
|
11
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
12
12
|
expect do
|
13
13
|
expect(@session).to have_none_of_selectors(:css, 'p a#foo')
|
14
|
-
end.to raise_error
|
14
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'should be true if none of the given locators are on the page' do
|
@@ -24,7 +24,7 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
|
|
24
24
|
expect(@session).to have_none_of_selectors('p a#doesnotexist', 'abbr')
|
25
25
|
expect do
|
26
26
|
expect(@session).to have_none_of_selectors('abbr', 'p a#foo')
|
27
|
-
end.to raise_error
|
27
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
28
28
|
end
|
29
29
|
|
30
30
|
context 'should respect scopes' do
|
@@ -32,7 +32,7 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
|
|
32
32
|
@session.within "//p[@id='first']" do
|
33
33
|
expect do
|
34
34
|
expect(@session).to have_none_of_selectors(".//a[@id='foo']")
|
35
|
-
end.to raise_error
|
35
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
36
36
|
expect(@session).to have_none_of_selectors(".//a[@id='red']")
|
37
37
|
end
|
38
38
|
end
|
@@ -41,7 +41,7 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
|
|
41
41
|
el = @session.find "//p[@id='first']"
|
42
42
|
expect do
|
43
43
|
expect(el).to have_none_of_selectors(".//a[@id='foo']")
|
44
|
-
end.to raise_error
|
44
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
45
45
|
expect(el).to have_none_of_selectors(".//a[@id='red']")
|
46
46
|
end
|
47
47
|
end
|
@@ -50,14 +50,14 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
|
|
50
50
|
it 'should apply the options to all locators' do
|
51
51
|
expect do
|
52
52
|
expect(@session).to have_none_of_selectors('//p//a', text: 'Redirect')
|
53
|
-
end.to raise_error
|
53
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
54
54
|
expect(@session).to have_none_of_selectors('//p', text: 'Doesnotexist')
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'should discard all matches where the given regexp is matched' do
|
58
58
|
expect do
|
59
59
|
expect(@session).to have_none_of_selectors('//p//a', text: /re[dab]i/i, count: 1)
|
60
|
-
end.to raise_error
|
60
|
+
end.to raise_error RSpec::Expectations::ExpectationNotMetError
|
61
61
|
expect(@session).to have_none_of_selectors('//p//a', text: /Red$/)
|
62
62
|
end
|
63
63
|
end
|