capybara 3.35.0 → 3.40.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 +168 -5
- data/README.md +199 -39
- data/lib/capybara/config.rb +16 -4
- data/lib/capybara/driver/base.rb +4 -0
- data/lib/capybara/driver/node.rb +5 -1
- data/lib/capybara/dsl.rb +4 -10
- data/lib/capybara/helpers.rb +9 -14
- data/lib/capybara/minitest/spec.rb +18 -6
- data/lib/capybara/minitest.rb +14 -1
- data/lib/capybara/node/actions.rb +14 -9
- data/lib/capybara/node/base.rb +2 -1
- data/lib/capybara/node/document.rb +2 -2
- data/lib/capybara/node/element.rb +13 -2
- data/lib/capybara/node/finders.rb +11 -2
- data/lib/capybara/node/matchers.rb +25 -0
- data/lib/capybara/node/simple.rb +5 -1
- data/lib/capybara/node/whitespace_normalizer.rb +81 -0
- data/lib/capybara/queries/active_element_query.rb +18 -0
- data/lib/capybara/queries/ancestor_query.rb +2 -1
- data/lib/capybara/queries/base_query.rb +2 -2
- data/lib/capybara/queries/current_path_query.rb +1 -1
- data/lib/capybara/queries/selector_query.rb +40 -11
- data/lib/capybara/queries/sibling_query.rb +2 -1
- data/lib/capybara/queries/text_query.rb +1 -1
- data/lib/capybara/rack_test/browser.rb +64 -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 +32 -33
- data/lib/capybara/registration_container.rb +2 -5
- data/lib/capybara/registrations/drivers.rb +7 -7
- data/lib/capybara/registrations/servers.rb +37 -16
- data/lib/capybara/result.rb +2 -2
- data/lib/capybara/rspec/matcher_proxies.rb +6 -6
- 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 +9 -17
- data/lib/capybara/rspec/matchers.rb +21 -16
- data/lib/capybara/selector/builders/css_builder.rb +1 -1
- data/lib/capybara/selector/builders/xpath_builder.rb +1 -1
- data/lib/capybara/selector/css.rb +6 -6
- data/lib/capybara/selector/definition/button.rb +10 -5
- data/lib/capybara/selector/definition/checkbox.rb +1 -1
- data/lib/capybara/selector/definition/file_field.rb +1 -1
- data/lib/capybara/selector/definition/fillable_field.rb +1 -1
- data/lib/capybara/selector/definition/link.rb +2 -1
- data/lib/capybara/selector/definition/radio_button.rb +1 -1
- data/lib/capybara/selector/definition/table.rb +1 -1
- data/lib/capybara/selector/definition/table_row.rb +2 -2
- data/lib/capybara/selector/definition.rb +4 -2
- data/lib/capybara/selector/filter_set.rb +4 -7
- data/lib/capybara/selector/regexp_disassembler.rb +2 -5
- data/lib/capybara/selector/selector.rb +5 -1
- data/lib/capybara/selector.rb +252 -0
- data/lib/capybara/selenium/driver.rb +31 -54
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +1 -1
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +9 -5
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +2 -7
- data/lib/capybara/selenium/extensions/html5_drag.rb +5 -4
- data/lib/capybara/selenium/node.rb +60 -38
- data/lib/capybara/selenium/nodes/chrome_node.rb +4 -16
- data/lib/capybara/selenium/nodes/edge_node.rb +19 -13
- data/lib/capybara/selenium/nodes/firefox_node.rb +3 -3
- data/lib/capybara/selenium/nodes/safari_node.rb +4 -4
- 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 +40 -23
- data/lib/capybara/server/middleware.rb +1 -1
- data/lib/capybara/server.rb +1 -1
- data/lib/capybara/session/config.rb +4 -2
- data/lib/capybara/session.rb +34 -34
- data/lib/capybara/spec/public/test.js +4 -0
- data/lib/capybara/spec/session/active_element_spec.rb +31 -0
- data/lib/capybara/spec/session/all_spec.rb +11 -15
- 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 +10 -0
- data/lib/capybara/spec/session/choose_spec.rb +6 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
- data/lib/capybara/spec/session/click_link_spec.rb +12 -1
- 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 +15 -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 +6 -2
- data/lib/capybara/spec/session/has_button_spec.rb +30 -0
- data/lib/capybara/spec/session/has_current_path_spec.rb +3 -3
- data/lib/capybara/spec/session/has_element_spec.rb +47 -0
- data/lib/capybara/spec/session/has_field_spec.rb +25 -1
- data/lib/capybara/spec/session/has_link_spec.rb +40 -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_table_spec.rb +13 -2
- data/lib/capybara/spec/session/has_text_spec.rb +6 -14
- data/lib/capybara/spec/session/matches_style_spec.rb +2 -0
- data/lib/capybara/spec/session/node_spec.rb +88 -1
- data/lib/capybara/spec/session/node_wrapper_spec.rb +1 -1
- data/lib/capybara/spec/session/reset_session_spec.rb +13 -0
- data/lib/capybara/spec/session/scroll_spec.rb +7 -5
- data/lib/capybara/spec/session/uncheck_spec.rb +1 -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 +12 -5
- data/lib/capybara/spec/test_app.rb +91 -14
- data/lib/capybara/spec/views/animated.erb +1 -1
- data/lib/capybara/spec/views/form.erb +34 -4
- data/lib/capybara/spec/views/frame_child.erb +1 -1
- data/lib/capybara/spec/views/frame_one.erb +1 -1
- data/lib/capybara/spec/views/frame_parent.erb +1 -1
- data/lib/capybara/spec/views/frame_two.erb +1 -1
- data/lib/capybara/spec/views/initial_alert.erb +2 -1
- data/lib/capybara/spec/views/layout.erb +10 -0
- data/lib/capybara/spec/views/obscured.erb +1 -1
- data/lib/capybara/spec/views/offset.erb +2 -1
- data/lib/capybara/spec/views/path.erb +2 -2
- data/lib/capybara/spec/views/popup_one.erb +1 -1
- data/lib/capybara/spec/views/popup_two.erb +1 -1
- data/lib/capybara/spec/views/react.erb +2 -2
- data/lib/capybara/spec/views/scroll.erb +2 -1
- data/lib/capybara/spec/views/spatial.erb +1 -1
- data/lib/capybara/spec/views/with_animation.erb +2 -3
- data/lib/capybara/spec/views/with_base_tag.erb +2 -2
- data/lib/capybara/spec/views/with_dragula.erb +2 -2
- data/lib/capybara/spec/views/with_fixed_header_footer.erb +2 -1
- data/lib/capybara/spec/views/with_hover.erb +2 -2
- data/lib/capybara/spec/views/with_html.erb +5 -3
- data/lib/capybara/spec/views/with_jquery_animation.erb +1 -1
- data/lib/capybara/spec/views/with_js.erb +2 -3
- data/lib/capybara/spec/views/with_jstree.erb +1 -1
- data/lib/capybara/spec/views/with_namespace.erb +1 -0
- data/lib/capybara/spec/views/with_scope.erb +2 -2
- data/lib/capybara/spec/views/with_shadow.erb +31 -0
- data/lib/capybara/spec/views/with_slow_unload.erb +2 -1
- data/lib/capybara/spec/views/with_sortable_js.erb +2 -2
- data/lib/capybara/spec/views/with_unload_alert.erb +1 -0
- data/lib/capybara/spec/views/with_windows.erb +1 -1
- data/lib/capybara/spec/views/within_frames.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +1 -1
- data/lib/capybara.rb +30 -30
- data/spec/basic_node_spec.rb +16 -3
- 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 +5 -3
- 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 +12 -1
- data/spec/minitest_spec_spec.rb +4 -0
- data/spec/per_session_config_spec.rb +1 -1
- data/spec/rack_test_spec.rb +30 -12
- data/spec/result_spec.rb +41 -35
- data/spec/rspec/features_spec.rb +3 -3
- data/spec/rspec/scenarios_spec.rb +2 -2
- data/spec/rspec/shared_spec_matchers.rb +27 -3
- data/spec/rspec_matchers_spec.rb +25 -0
- data/spec/rspec_spec.rb +3 -3
- data/spec/sauce_spec_chrome.rb +5 -5
- data/spec/selector_spec.rb +4 -4
- data/spec/selenium_spec_chrome.rb +20 -18
- data/spec/selenium_spec_chrome_remote.rb +15 -19
- data/spec/selenium_spec_edge.rb +19 -6
- data/spec/selenium_spec_firefox.rb +26 -8
- data/spec/selenium_spec_firefox_remote.rb +18 -4
- data/spec/selenium_spec_ie.rb +7 -8
- data/spec/selenium_spec_safari.rb +34 -20
- data/spec/server_spec.rb +19 -7
- data/spec/shared_selenium_node.rb +0 -4
- data/spec/shared_selenium_session.rb +22 -14
- data/spec/spec_helper.rb +36 -3
- data/spec/whitespace_normalizer_spec.rb +54 -0
- data/spec/xpath_builder_spec.rb +1 -1
- metadata +49 -30
- data/lib/capybara/selenium/logger_suppressor.rb +0 -34
- data/lib/capybara/selenium/patches/action_pauser.rb +0 -26
- data/lib/capybara/spec/views/with_title.erb +0 -5
data/lib/capybara/session.rb
CHANGED
@@ -40,10 +40,12 @@ 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?
|
46
47
|
has_no_css? has_no_xpath? has_xpath? select uncheck
|
48
|
+
has_element? has_no_element?
|
47
49
|
has_link? has_no_link? has_button? has_no_button? has_field?
|
48
50
|
has_no_field? has_checked_field? has_unchecked_field?
|
49
51
|
has_no_table? has_table? unselect has_select? has_no_select?
|
@@ -58,7 +60,7 @@ module Capybara
|
|
58
60
|
].freeze
|
59
61
|
SESSION_METHODS = %i[
|
60
62
|
body html source current_url current_host current_path
|
61
|
-
execute_script evaluate_script visit refresh go_back go_forward send_keys
|
63
|
+
execute_script evaluate_script evaluate_async_script visit refresh go_back go_forward send_keys
|
62
64
|
within within_element within_fieldset within_table within_frame switch_to_frame
|
63
65
|
current_window windows open_new_window switch_to_window within_window window_opened_by
|
64
66
|
save_page save_and_open_page save_screenshot
|
@@ -129,6 +131,8 @@ module Capybara
|
|
129
131
|
if @touched
|
130
132
|
driver.reset!
|
131
133
|
@touched = false
|
134
|
+
switch_to_frame(:top) rescue nil # rubocop:disable Style/RescueModifier
|
135
|
+
@scopes = [nil]
|
132
136
|
end
|
133
137
|
@server&.wait_for_pending_requests
|
134
138
|
raise_server_error!
|
@@ -159,9 +163,8 @@ module Capybara
|
|
159
163
|
if config.raise_server_errors
|
160
164
|
raise CapybaraError, 'Your application server raised an error - It has been raised in your test code because Capybara.raise_server_errors == true'
|
161
165
|
end
|
162
|
-
rescue CapybaraError
|
163
|
-
|
164
|
-
raise @server.error, @server.error.message, @server.error.backtrace
|
166
|
+
rescue CapybaraError => capy_error # rubocop:disable Naming/RescuedExceptionsVariableName
|
167
|
+
raise @server.error, cause: capy_error
|
165
168
|
ensure
|
166
169
|
@server.reset_error!
|
167
170
|
end
|
@@ -307,8 +310,18 @@ module Capybara
|
|
307
310
|
# @!method send_keys
|
308
311
|
# @see Capybara::Node::Element#send_keys
|
309
312
|
#
|
310
|
-
def send_keys(
|
311
|
-
driver.send_keys(
|
313
|
+
def send_keys(...)
|
314
|
+
driver.send_keys(...)
|
315
|
+
end
|
316
|
+
|
317
|
+
##
|
318
|
+
#
|
319
|
+
# Returns the element with focus.
|
320
|
+
#
|
321
|
+
# Not supported by Rack Test
|
322
|
+
#
|
323
|
+
def active_element
|
324
|
+
Capybara::Queries::ActiveElementQuery.new.resolve_for(self)[0].tap(&:allow_reload!)
|
312
325
|
end
|
313
326
|
|
314
327
|
##
|
@@ -350,7 +363,7 @@ module Capybara
|
|
350
363
|
new_scope = args.first.respond_to?(:to_capybara_node) ? args.first.to_capybara_node : find(*args, **kw_args)
|
351
364
|
begin
|
352
365
|
scopes.push(new_scope)
|
353
|
-
yield if block_given?
|
366
|
+
yield new_scope if block_given?
|
354
367
|
ensure
|
355
368
|
scopes.pop
|
356
369
|
end
|
@@ -399,7 +412,7 @@ module Capybara
|
|
399
412
|
scopes.push(:frame)
|
400
413
|
when :parent
|
401
414
|
if scopes.last != :frame
|
402
|
-
raise Capybara::ScopeError, "`switch_to_frame(:parent)` cannot be called from inside a descendant frame's "\
|
415
|
+
raise Capybara::ScopeError, "`switch_to_frame(:parent)` cannot be called from inside a descendant frame's " \
|
403
416
|
'`within` block.'
|
404
417
|
end
|
405
418
|
scopes.pop
|
@@ -408,11 +421,11 @@ module Capybara
|
|
408
421
|
idx = scopes.index(:frame)
|
409
422
|
top_level_scopes = [:frame, nil]
|
410
423
|
if idx
|
411
|
-
if scopes.slice(idx
|
412
|
-
raise Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's "\
|
424
|
+
if scopes.slice(idx..).any? { |scope| !top_level_scopes.include?(scope) }
|
425
|
+
raise Capybara::ScopeError, "`switch_to_frame(:top)` cannot be called from inside a descendant frame's " \
|
413
426
|
'`within` block.'
|
414
427
|
end
|
415
|
-
scopes.slice!(idx
|
428
|
+
scopes.slice!(idx..)
|
416
429
|
driver.switch_to_frame(:top)
|
417
430
|
end
|
418
431
|
else
|
@@ -501,7 +514,7 @@ module Capybara
|
|
501
514
|
raise ArgumentError, '`switch_to_window`: either window or block should be provided' if !window && !window_locator
|
502
515
|
|
503
516
|
unless scopes.last.nil?
|
504
|
-
raise Capybara::ScopeError, '`switch_to_window` is not supposed to be invoked from '\
|
517
|
+
raise Capybara::ScopeError, '`switch_to_window` is not supposed to be invoked from ' \
|
505
518
|
'`within` or `within_frame` blocks.'
|
506
519
|
end
|
507
520
|
|
@@ -572,7 +585,7 @@ module Capybara
|
|
572
585
|
synchronize_windows(options) do
|
573
586
|
opened_handles = (driver.window_handles - old_handles)
|
574
587
|
if opened_handles.size != 1
|
575
|
-
raise Capybara::WindowError, 'block passed to #window_opened_by '\
|
588
|
+
raise Capybara::WindowError, 'block passed to #window_opened_by ' \
|
576
589
|
"opened #{opened_handles.size} windows instead of 1"
|
577
590
|
end
|
578
591
|
Window.new(self, opened_handles.first)
|
@@ -755,33 +768,20 @@ module Capybara
|
|
755
768
|
end
|
756
769
|
|
757
770
|
NODE_METHODS.each do |method|
|
758
|
-
|
759
|
-
|
760
|
-
def #{method}(...)
|
761
|
-
@touched = true
|
762
|
-
current_scope.#{method}(...)
|
763
|
-
end
|
764
|
-
METHOD
|
765
|
-
else
|
766
|
-
define_method method do |*args, &block|
|
771
|
+
class_eval <<~METHOD, __FILE__, __LINE__ + 1
|
772
|
+
def #{method}(...)
|
767
773
|
@touched = true
|
768
|
-
current_scope
|
774
|
+
current_scope.#{method}(...)
|
769
775
|
end
|
770
|
-
|
776
|
+
METHOD
|
771
777
|
end
|
772
778
|
|
773
779
|
DOCUMENT_METHODS.each do |method|
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
document.#{method}(...)
|
778
|
-
end
|
779
|
-
METHOD
|
780
|
-
else
|
781
|
-
define_method method do |*args, &block|
|
782
|
-
document.send(method, *args, &block)
|
780
|
+
class_eval <<~METHOD, __FILE__, __LINE__ + 1
|
781
|
+
def #{method}(...)
|
782
|
+
document.#{method}(...)
|
783
783
|
end
|
784
|
-
|
784
|
+
METHOD
|
785
785
|
end
|
786
786
|
|
787
787
|
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(); }
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Capybara::SpecHelper.spec '#active_element', requires: [:active_element] do
|
4
|
+
it 'should return the active element' do
|
5
|
+
@session.visit('/form')
|
6
|
+
@session.send_keys(:tab)
|
7
|
+
|
8
|
+
expect(@session.active_element).to match_selector(:css, '[tabindex="1"]')
|
9
|
+
|
10
|
+
@session.send_keys(:tab)
|
11
|
+
|
12
|
+
expect(@session.active_element).to match_selector(:css, '[tabindex="2"]')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should support reloading' do
|
16
|
+
@session.visit('/form')
|
17
|
+
expect(@session.active_element).to match_selector(:css, 'body')
|
18
|
+
@session.execute_script <<-JS
|
19
|
+
window.setTimeout(() => {
|
20
|
+
document.querySelector('#form_title').focus();
|
21
|
+
}, 1000)
|
22
|
+
JS
|
23
|
+
expect(@session.active_element).to match_selector(:css, 'body', wait: false)
|
24
|
+
expect(@session.active_element).to match_selector(:css, '#form_title', wait: 2)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should return a Capybara::Element' do
|
28
|
+
@session.visit('/form')
|
29
|
+
expect(@session.active_element).to be_a Capybara::Node::Element
|
30
|
+
end
|
31
|
+
end
|
@@ -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
|
@@ -129,10 +129,10 @@ Capybara::SpecHelper.spec '#all' do
|
|
129
129
|
end
|
130
130
|
|
131
131
|
context 'with per session config', requires: [:psc] do
|
132
|
-
it 'should use the sessions ignore_hidden_elements', psc
|
132
|
+
it 'should use the sessions ignore_hidden_elements', :psc 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)
|
@@ -203,19 +203,15 @@ Capybara::SpecHelper.spec '#all' do
|
|
203
203
|
expect { @session.all(:css, 'h1, p', between: 0..3) }.to raise_error(Capybara::ExpectationNotMet)
|
204
204
|
end
|
205
205
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
end
|
211
|
-
TEST
|
206
|
+
it 'treats an endless range as minimum' do
|
207
|
+
expect { @session.all(:css, 'h1, p', between: 2..) }.not_to raise_error
|
208
|
+
expect { @session.all(:css, 'h1, p', between: 5..) }.to raise_error(Capybara::ExpectationNotMet)
|
209
|
+
end
|
212
210
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
end
|
218
|
-
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
|
219
215
|
end
|
220
216
|
|
221
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'
|
@@ -236,6 +236,16 @@ Capybara::SpecHelper.spec '#check' do
|
|
236
236
|
expect(@session).to have_field('multi_label_checkbox', checked: true, visible: :hidden)
|
237
237
|
end
|
238
238
|
end
|
239
|
+
|
240
|
+
context 'with allow_label_click options', requires: [:js] do
|
241
|
+
it 'should allow offsets to click location on label' do
|
242
|
+
Capybara.w3c_click_offset = false
|
243
|
+
expect(@session.find(:checkbox, 'form_cars_lotus', unchecked: true, visible: :hidden)).to be_truthy
|
244
|
+
@session.check('form_cars_lotus', allow_label_click: { x: 90, y: 10 })
|
245
|
+
@session.click_button('awesome')
|
246
|
+
expect(extract_results(@session)['cars']).to include('lotus')
|
247
|
+
end
|
248
|
+
end
|
239
249
|
end
|
240
250
|
end
|
241
251
|
end
|
@@ -11,6 +11,12 @@ Capybara::SpecHelper.spec '#choose' do
|
|
11
11
|
expect(extract_results(@session)['gender']).to eq('male')
|
12
12
|
end
|
13
13
|
|
14
|
+
it 'ignores readonly attribute on radio buttons' do
|
15
|
+
@session.choose('gender_both')
|
16
|
+
@session.click_button('awesome')
|
17
|
+
expect(extract_results(@session)['gender']).to eq('both')
|
18
|
+
end
|
19
|
+
|
14
20
|
it 'should choose a radio button by label' do
|
15
21
|
@session.choose('Both')
|
16
22
|
@session.click_button('awesome')
|
@@ -38,6 +38,15 @@ Capybara::SpecHelper.spec '#click_link_or_button' do
|
|
38
38
|
expect(extract_results(@session)['first_name']).to eq('John')
|
39
39
|
end
|
40
40
|
|
41
|
+
context 'with test_id' do
|
42
|
+
it 'should click on a button' do
|
43
|
+
Capybara.test_id = 'data-test-id'
|
44
|
+
@session.visit('/form')
|
45
|
+
@session.click_link_or_button('test_id_button')
|
46
|
+
expect(extract_results(@session)['first_name']).to eq('John')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
41
50
|
context 'with :exact option' do
|
42
51
|
context 'when `false`' do
|
43
52
|
it 'clicks on approximately matching link' do
|
@@ -105,7 +105,7 @@ Capybara::SpecHelper.spec '#click_link' do
|
|
105
105
|
|
106
106
|
it "should raise an error if no link's href matched the pattern" do
|
107
107
|
expect { @session.click_link('labore', href: /invalid_pattern/) }.to raise_error(Capybara::ElementNotFound, %r{with href matching /invalid_pattern/})
|
108
|
-
expect { @session.click_link('labore', href: /.+d+/) }.to raise_error(Capybara::ElementNotFound, /#{Regexp.quote
|
108
|
+
expect { @session.click_link('labore', href: /.+d+/) }.to raise_error(Capybara::ElementNotFound, /#{Regexp.quote 'with href matching /.+d+/'}/)
|
109
109
|
end
|
110
110
|
|
111
111
|
context 'href: nil' do
|
@@ -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
|
@@ -233,10 +233,18 @@ Capybara::SpecHelper.spec '#find' do
|
|
233
233
|
end.to raise_error(Capybara::ElementNotFound, 'Unable to find xpath "//div[@id=\\"nosuchthing\\"]"')
|
234
234
|
end
|
235
235
|
|
236
|
+
context 'without locator' do
|
237
|
+
it 'should not output `nil` in the ElementNotFound message if nothing was found' do
|
238
|
+
expect do
|
239
|
+
@session.find(:label, text: 'no such thing').to be_nil
|
240
|
+
end.to raise_error(Capybara::ElementNotFound, 'Unable to find label')
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
236
244
|
it 'should accept an XPath instance' do
|
237
245
|
@session.visit('/form')
|
238
246
|
@xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('First Name')
|
239
|
-
expect(@xpath).to be_a(
|
247
|
+
expect(@xpath).to be_a(XPath::Union)
|
240
248
|
expect(@session.find(@xpath).value).to eq('John')
|
241
249
|
end
|
242
250
|
|
@@ -528,4 +536,10 @@ Capybara::SpecHelper.spec '#find' do
|
|
528
536
|
expect(@session.find(:link, 'test-foo')[:id]).to eq 'foo'
|
529
537
|
end
|
530
538
|
end
|
539
|
+
|
540
|
+
it 'should warn if passed count options' do
|
541
|
+
allow(Capybara::Helpers).to receive(:warn)
|
542
|
+
@session.find('//h1', count: 44)
|
543
|
+
expect(Capybara::Helpers).to have_received(:warn).with(/'find' does not support count options/)
|
544
|
+
end
|
531
545
|
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,6 +20,10 @@ 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
|
+
end
|
25
|
+
|
26
|
+
it 'should be negateable' do
|
27
|
+
expect(@session).not_to have_any_of_selectors(:css, 'span a#foo', 'h2#h2nope', 'h2#h2one_no')
|
24
28
|
end
|
25
29
|
end
|