capybara 3.30.0 → 3.35.3
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 +153 -13
- data/README.md +9 -4
- data/lib/capybara.rb +18 -8
- data/lib/capybara/config.rb +4 -6
- data/lib/capybara/cucumber.rb +1 -1
- data/lib/capybara/driver/base.rb +4 -0
- data/lib/capybara/dsl.rb +10 -2
- data/lib/capybara/helpers.rb +25 -1
- data/lib/capybara/minitest.rb +232 -144
- data/lib/capybara/minitest/spec.rb +156 -97
- data/lib/capybara/node/actions.rb +16 -21
- data/lib/capybara/node/base.rb +6 -6
- data/lib/capybara/node/element.rb +14 -13
- data/lib/capybara/node/finders.rb +12 -7
- data/lib/capybara/node/matchers.rb +36 -27
- data/lib/capybara/node/simple.rb +6 -2
- data/lib/capybara/queries/ancestor_query.rb +1 -1
- data/lib/capybara/queries/base_query.rb +2 -1
- data/lib/capybara/queries/current_path_query.rb +14 -4
- data/lib/capybara/queries/selector_query.rb +40 -18
- data/lib/capybara/queries/sibling_query.rb +1 -1
- data/lib/capybara/queries/style_query.rb +1 -1
- data/lib/capybara/queries/text_query.rb +7 -1
- data/lib/capybara/rack_test/browser.rb +9 -3
- data/lib/capybara/rack_test/driver.rb +1 -0
- data/lib/capybara/rack_test/form.rb +1 -1
- data/lib/capybara/rack_test/node.rb +35 -10
- data/lib/capybara/registration_container.rb +44 -0
- data/lib/capybara/registrations/drivers.rb +18 -12
- data/lib/capybara/registrations/patches/puma_ssl.rb +3 -1
- data/lib/capybara/registrations/servers.rb +3 -2
- data/lib/capybara/result.rb +35 -15
- data/lib/capybara/rspec.rb +2 -0
- data/lib/capybara/rspec/matcher_proxies.rb +5 -5
- data/lib/capybara/rspec/matchers.rb +33 -32
- 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 +3 -3
- 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 +7 -2
- data/lib/capybara/rspec/matchers/spatial_sugar.rb +2 -1
- data/lib/capybara/selector.rb +14 -3
- data/lib/capybara/selector/builders/css_builder.rb +1 -1
- data/lib/capybara/selector/builders/xpath_builder.rb +3 -1
- data/lib/capybara/selector/definition.rb +11 -9
- data/lib/capybara/selector/definition/button.rb +26 -14
- data/lib/capybara/selector/definition/css.rb +1 -1
- data/lib/capybara/selector/definition/datalist_input.rb +1 -1
- data/lib/capybara/selector/definition/element.rb +2 -1
- data/lib/capybara/selector/definition/fillable_field.rb +1 -1
- data/lib/capybara/selector/definition/label.rb +2 -2
- data/lib/capybara/selector/definition/link.rb +8 -0
- data/lib/capybara/selector/definition/select.rb +32 -13
- data/lib/capybara/selector/definition/table.rb +1 -1
- data/lib/capybara/selector/definition/table_row.rb +2 -2
- data/lib/capybara/selector/filter_set.rb +2 -2
- data/lib/capybara/selector/selector.rb +9 -1
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -1
- data/lib/capybara/selenium/atoms/src/getAttribute.js +1 -1
- data/lib/capybara/selenium/atoms/src/isDisplayed.js +1 -1
- data/lib/capybara/selenium/driver.rb +52 -7
- data/lib/capybara/selenium/driver_specializations/chrome_driver.rb +10 -12
- data/lib/capybara/selenium/driver_specializations/edge_driver.rb +9 -11
- data/lib/capybara/selenium/driver_specializations/firefox_driver.rb +3 -3
- data/lib/capybara/selenium/extensions/find.rb +4 -4
- data/lib/capybara/selenium/extensions/html5_drag.rb +24 -8
- data/lib/capybara/selenium/extensions/scroll.rb +8 -10
- data/lib/capybara/selenium/logger_suppressor.rb +8 -2
- data/lib/capybara/selenium/node.rb +96 -16
- data/lib/capybara/selenium/nodes/chrome_node.rb +27 -16
- data/lib/capybara/selenium/nodes/edge_node.rb +1 -1
- data/lib/capybara/selenium/nodes/firefox_node.rb +9 -4
- data/lib/capybara/selenium/nodes/safari_node.rb +1 -1
- data/lib/capybara/selenium/patches/action_pauser.rb +26 -0
- data/lib/capybara/selenium/patches/atoms.rb +4 -4
- data/lib/capybara/selenium/patches/logs.rb +7 -9
- data/lib/capybara/server/animation_disabler.rb +8 -3
- data/lib/capybara/server/middleware.rb +4 -2
- data/lib/capybara/session.rb +53 -29
- data/lib/capybara/session/config.rb +3 -1
- data/lib/capybara/session/matchers.rb +11 -11
- data/lib/capybara/spec/public/test.js +64 -7
- data/lib/capybara/spec/session/accept_alert_spec.rb +1 -1
- 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/check_spec.rb +6 -0
- data/lib/capybara/spec/session/click_button_spec.rb +11 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +9 -0
- data/lib/capybara/spec/session/current_url_spec.rb +11 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +29 -0
- data/lib/capybara/spec/session/find_spec.rb +11 -8
- data/lib/capybara/spec/session/has_button_spec.rb +51 -0
- data/lib/capybara/spec/session/has_css_spec.rb +14 -10
- data/lib/capybara/spec/session/has_current_path_spec.rb +15 -2
- data/lib/capybara/spec/session/has_field_spec.rb +16 -0
- data/lib/capybara/spec/session/has_select_spec.rb +32 -4
- data/lib/capybara/spec/session/has_selector_spec.rb +4 -4
- data/lib/capybara/spec/session/has_text_spec.rb +5 -12
- data/lib/capybara/spec/session/html_spec.rb +1 -1
- data/lib/capybara/spec/session/matches_style_spec.rb +2 -2
- data/lib/capybara/spec/session/node_spec.rb +169 -33
- data/lib/capybara/spec/session/refresh_spec.rb +2 -1
- data/lib/capybara/spec/session/save_page_spec.rb +4 -4
- data/lib/capybara/spec/session/window/switch_to_window_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_opened_by_spec.rb +1 -1
- data/lib/capybara/spec/session/window/window_spec.rb +8 -8
- data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
- data/lib/capybara/spec/spec_helper.rb +13 -14
- data/lib/capybara/spec/test_app.rb +23 -21
- data/lib/capybara/spec/views/form.erb +36 -3
- data/lib/capybara/spec/views/with_animation.erb +8 -0
- data/lib/capybara/spec/views/with_dragula.erb +3 -1
- data/lib/capybara/spec/views/with_html.erb +2 -2
- data/lib/capybara/spec/views/with_jquery_animation.erb +24 -0
- data/lib/capybara/spec/views/with_js.erb +3 -0
- data/lib/capybara/spec/views/with_sortable_js.erb +1 -1
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara/window.rb +3 -7
- data/spec/basic_node_spec.rb +9 -8
- data/spec/capybara_spec.rb +1 -1
- data/spec/dsl_spec.rb +14 -1
- data/spec/fixtures/selenium_driver_rspec_success.rb +1 -1
- data/spec/minitest_spec.rb +3 -2
- data/spec/rack_test_spec.rb +28 -6
- data/spec/regexp_dissassembler_spec.rb +0 -4
- data/spec/result_spec.rb +40 -29
- data/spec/rspec/features_spec.rb +3 -1
- data/spec/rspec/scenarios_spec.rb +4 -0
- data/spec/rspec/shared_spec_matchers.rb +63 -51
- data/spec/rspec_spec.rb +4 -0
- data/spec/selector_spec.rb +17 -2
- data/spec/selenium_spec_chrome.rb +45 -21
- data/spec/selenium_spec_chrome_remote.rb +7 -1
- data/spec/selenium_spec_firefox.rb +15 -13
- data/spec/server_spec.rb +60 -49
- data/spec/shared_selenium_node.rb +18 -0
- data/spec/shared_selenium_session.rb +98 -7
- data/spec/spec_helper.rb +1 -1
- metadata +50 -14
- data/lib/capybara/spec/session/source_spec.rb +0 -0
|
@@ -60,6 +60,22 @@ Capybara::SpecHelper.spec '#has_field' do
|
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
+
context 'with validation message', requires: [:html_validation] do
|
|
64
|
+
it 'should accept a regexp' do
|
|
65
|
+
@session.fill_in('form_zipcode', with: '1234')
|
|
66
|
+
expect(@session).to have_field('form_zipcode', validation_message: /match the requested format/)
|
|
67
|
+
expect(@session).not_to have_field('form_zipcode', validation_message: /random/)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'should accept a string' do
|
|
71
|
+
@session.fill_in('form_zipcode', with: '1234')
|
|
72
|
+
expect(@session).to have_field('form_zipcode', validation_message: 'Please match the requested format.')
|
|
73
|
+
expect(@session).not_to have_field('form_zipcode', validation_message: 'match the requested format.')
|
|
74
|
+
@session.fill_in('form_zipcode', with: '12345')
|
|
75
|
+
expect(@session).to have_field('form_zipcode', validation_message: '')
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
63
79
|
context 'with type' do
|
|
64
80
|
it 'should be true if a field with the given type is on the page' do
|
|
65
81
|
expect(@session).to have_field('First Name', type: 'text')
|
|
@@ -63,7 +63,7 @@ Capybara::SpecHelper.spec '#has_select?' do
|
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
it "should be true even when the selected option invisible, regardless of the select's visibility" do
|
|
66
|
-
expect(@session).to have_select('Icecream', visible:
|
|
66
|
+
expect(@session).to have_select('Icecream', visible: :hidden, selected: 'Chocolate')
|
|
67
67
|
expect(@session).to have_select('Sorbet', selected: 'Vanilla')
|
|
68
68
|
end
|
|
69
69
|
end
|
|
@@ -88,7 +88,7 @@ Capybara::SpecHelper.spec '#has_select?' do
|
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
it "should be true even when the selected values are invisible, regardless of the select's visibility" do
|
|
91
|
-
expect(@session).to have_select('Dessert', visible:
|
|
91
|
+
expect(@session).to have_select('Dessert', visible: :hidden, with_options: %w[Pudding Tiramisu])
|
|
92
92
|
expect(@session).to have_select('Cake', with_selected: ['Chocolate Cake', 'Sponge Cake'])
|
|
93
93
|
end
|
|
94
94
|
|
|
@@ -113,7 +113,35 @@ Capybara::SpecHelper.spec '#has_select?' do
|
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
it 'should be true even when the options are invisible, if the select itself is invisible' do
|
|
116
|
-
expect(@session).to have_select('Icecream', visible:
|
|
116
|
+
expect(@session).to have_select('Icecream', visible: :hidden, options: %w[Chocolate Vanilla Strawberry])
|
|
117
|
+
end
|
|
118
|
+
end
|
|
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])
|
|
117
145
|
end
|
|
118
146
|
end
|
|
119
147
|
|
|
@@ -130,7 +158,7 @@ Capybara::SpecHelper.spec '#has_select?' do
|
|
|
130
158
|
end
|
|
131
159
|
|
|
132
160
|
it 'should be true even when the options are invisible, if the select itself is invisible' do
|
|
133
|
-
expect(@session).to have_select('Icecream', visible:
|
|
161
|
+
expect(@session).to have_select('Icecream', visible: :hidden, with_options: %w[Vanilla Strawberry])
|
|
134
162
|
end
|
|
135
163
|
end
|
|
136
164
|
|
|
@@ -61,12 +61,12 @@ Capybara::SpecHelper.spec '#has_selector?' do
|
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
it 'should respect visibility setting' do
|
|
64
|
-
expect(@session).to have_selector(:id, 'hidden-text', text: 'Some of this text is hidden!', visible:
|
|
65
|
-
expect(@session).not_to have_selector(:id, 'hidden-text', text: 'Some of this text is hidden!', visible:
|
|
64
|
+
expect(@session).to have_selector(:id, 'hidden-text', text: 'Some of this text is hidden!', visible: :all)
|
|
65
|
+
expect(@session).not_to have_selector(:id, 'hidden-text', text: 'Some of this text is hidden!', visible: :visible)
|
|
66
66
|
Capybara.ignore_hidden_elements = false
|
|
67
|
-
expect(@session).to have_selector(:id, 'hidden-text', text: 'Some of this text is hidden!', visible:
|
|
67
|
+
expect(@session).to have_selector(:id, 'hidden-text', text: 'Some of this text is hidden!', visible: :all)
|
|
68
68
|
Capybara.visible_text_only = true
|
|
69
|
-
expect(@session).not_to have_selector(:id, 'hidden-text', text: 'Some of this text is hidden!', visible:
|
|
69
|
+
expect(@session).not_to have_selector(:id, 'hidden-text', text: 'Some of this text is hidden!', visible: :visible)
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
it 'should discard all matches where the given regexp is not matched' do
|
|
@@ -127,18 +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
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def to_s; '42' end
|
|
136
|
-
def to_hash; { blah: 'Other hash' } end
|
|
137
|
-
end.new
|
|
138
|
-
@session.visit('/with_html')
|
|
139
|
-
expect do
|
|
140
|
-
expect(@session).to have_text(:visible, with_to_hash)
|
|
141
|
-
end.to raise_error(ArgumentError)
|
|
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
|
|
142
135
|
end
|
|
143
136
|
end
|
|
144
137
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# NOTE: This file uses `sleep` to sync up parts of the tests. This is only implemented like this
|
|
4
4
|
# because of the methods being tested. In tests using Capybara this type of behavior should be implemented
|
|
5
5
|
# using Capybara provided assertions with builtin waiting behavior.
|
|
6
6
|
|
|
@@ -28,8 +28,8 @@ Capybara::SpecHelper.spec '#matches_style?', requires: [:css] do
|
|
|
28
28
|
output(/have_style is deprecated/).to_stderr
|
|
29
29
|
|
|
30
30
|
el = @session.find(:css, '#first')
|
|
31
|
-
allow(
|
|
31
|
+
allow(Capybara::Helpers).to receive(:warn).and_return(nil)
|
|
32
32
|
el.has_style?('display' => /^bl/)
|
|
33
|
-
expect(
|
|
33
|
+
expect(Capybara::Helpers).to have_received(:warn)
|
|
34
34
|
end
|
|
35
35
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# NOTE: This file uses `sleep` to sync up parts of the tests. This is only implemented like this
|
|
4
4
|
# because of the methods being tested. In tests using Capybara this type of behavior should be implemented
|
|
5
5
|
# using Capybara provided assertions with builtin waiting behavior.
|
|
6
6
|
|
|
@@ -270,13 +270,13 @@ 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
|
|
274
|
-
expect(@session).to have_css('#closed_details *', visible:
|
|
273
|
+
@session.find(:css, '#closed_details > summary').click
|
|
274
|
+
expect(@session).to have_css('#closed_details *', visible: :visible, 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
|
-
expect(@session).to have_no_css(descendants_css, visible:
|
|
279
|
+
expect(@session).to have_no_css(descendants_css, visible: :visible)
|
|
280
280
|
.and(have_css(descendants_css, visible: :hidden, count: 3))
|
|
281
281
|
end
|
|
282
282
|
end
|
|
@@ -388,8 +388,8 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
388
388
|
|
|
389
389
|
describe '#==' do
|
|
390
390
|
it 'preserve object identity' do
|
|
391
|
-
expect(@session.find('//h1') == @session.find('//h1')).to be true # rubocop:disable Lint/
|
|
392
|
-
expect(@session.find('//h1') === @session.find('//h1')).to be true # rubocop:disable Style/CaseEquality, Lint/
|
|
391
|
+
expect(@session.find('//h1') == @session.find('//h1')).to be true # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
|
|
392
|
+
expect(@session.find('//h1') === @session.find('//h1')).to be true # rubocop:disable Style/CaseEquality, Lint/BinaryOperatorWithIdenticalOperands
|
|
393
393
|
expect(@session.find('//h1').eql?(@session.find('//h1'))).to be false
|
|
394
394
|
end
|
|
395
395
|
|
|
@@ -409,6 +409,17 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
409
409
|
element = @session.find(:link, 'Second Link')
|
|
410
410
|
expect(@session.find(:xpath, element.path)).to eq(element)
|
|
411
411
|
end
|
|
412
|
+
|
|
413
|
+
it 'reports when element in shadow dom', requires: [:shadow_dom] do
|
|
414
|
+
@session.visit('/with_js')
|
|
415
|
+
shadow = @session.find(:css, '#shadow')
|
|
416
|
+
element = @session.evaluate_script(<<~JS, shadow)
|
|
417
|
+
(function(root){
|
|
418
|
+
return root.shadowRoot.querySelector('span');
|
|
419
|
+
})(arguments[0])
|
|
420
|
+
JS
|
|
421
|
+
expect(element.path).to eq '(: Shadow DOM element - no XPath :)'
|
|
422
|
+
end
|
|
412
423
|
end
|
|
413
424
|
|
|
414
425
|
describe '#trigger', requires: %i[js trigger] do
|
|
@@ -446,7 +457,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
446
457
|
|
|
447
458
|
it 'should work with Dragula' do
|
|
448
459
|
@session.visit('/with_dragula')
|
|
449
|
-
@session.within(:css, '#sortable') do
|
|
460
|
+
@session.within(:css, '#sortable.ready') do
|
|
450
461
|
src = @session.find('div', text: 'Item 1')
|
|
451
462
|
target = @session.find('div', text: 'Item 3')
|
|
452
463
|
src.drag_to target
|
|
@@ -468,6 +479,50 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
468
479
|
end
|
|
469
480
|
end
|
|
470
481
|
|
|
482
|
+
it 'should simulate a single held down modifier key' do
|
|
483
|
+
%I[
|
|
484
|
+
alt
|
|
485
|
+
ctrl
|
|
486
|
+
meta
|
|
487
|
+
shift
|
|
488
|
+
].each do |modifier_key|
|
|
489
|
+
@session.visit('/with_js')
|
|
490
|
+
|
|
491
|
+
element = @session.find('//div[@id="drag"]')
|
|
492
|
+
target = @session.find('//div[@id="drop"]')
|
|
493
|
+
|
|
494
|
+
element.drag_to(target, drop_modifiers: modifier_key)
|
|
495
|
+
expect(@session).to have_css('div.drag_start', exact_text: 'Dragged!')
|
|
496
|
+
expect(@session).to have_xpath("//div[contains(., 'Dropped!-#{modifier_key}')]")
|
|
497
|
+
end
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
it 'should simulate multiple held down modifier keys' do
|
|
501
|
+
@session.visit('/with_js')
|
|
502
|
+
|
|
503
|
+
element = @session.find('//div[@id="drag"]')
|
|
504
|
+
target = @session.find('//div[@id="drop"]')
|
|
505
|
+
|
|
506
|
+
modifier_keys = %I[alt ctrl meta shift]
|
|
507
|
+
|
|
508
|
+
element.drag_to(target, drop_modifiers: modifier_keys)
|
|
509
|
+
expect(@session).to have_xpath("//div[contains(., 'Dropped!-#{modifier_keys.join('-')}')]")
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
it 'should support key aliases' do
|
|
513
|
+
{ control: :ctrl,
|
|
514
|
+
command: :meta,
|
|
515
|
+
cmd: :meta }.each do |(key_alias, key)|
|
|
516
|
+
@session.visit('/with_js')
|
|
517
|
+
|
|
518
|
+
element = @session.find('//div[@id="drag"]')
|
|
519
|
+
target = @session.find('//div[@id="drop"]')
|
|
520
|
+
|
|
521
|
+
element.drag_to(target, drop_modifiers: [key_alias])
|
|
522
|
+
expect(target).to have_text("Dropped!-#{key}", exact: true)
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
|
|
471
526
|
context 'HTML5', requires: %i[js html5_drag] do
|
|
472
527
|
it 'should HTML5 drag and drop an object' do
|
|
473
528
|
@session.visit('/with_js')
|
|
@@ -499,8 +554,13 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
499
554
|
target = @session.find('//div[@id="drop_html5"]')
|
|
500
555
|
element.drag_to(target)
|
|
501
556
|
|
|
557
|
+
conditions = %w[DragLeave Drop DragEnd].map do |text|
|
|
558
|
+
have_css('div.log', text: text)
|
|
559
|
+
end
|
|
560
|
+
expect(@session).to(conditions.reduce { |memo, cond| memo.and(cond) })
|
|
561
|
+
|
|
502
562
|
# The first "DragOver" div is inserted by the last dragover event dispatched
|
|
503
|
-
drag_over_div = @session.
|
|
563
|
+
drag_over_div = @session.first('//div[@class="log" and starts-with(text(), "DragOver")]')
|
|
504
564
|
position = drag_over_div.text.sub('DragOver ', '')
|
|
505
565
|
|
|
506
566
|
expect(@session).to have_css('div.log', text: /DragLeave #{position}/, count: 1)
|
|
@@ -551,6 +611,46 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
551
611
|
source.drag_to target
|
|
552
612
|
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped")]')
|
|
553
613
|
end
|
|
614
|
+
|
|
615
|
+
it 'should simulate a single held down modifier key' do
|
|
616
|
+
%I[alt ctrl meta shift].each do |modifier_key|
|
|
617
|
+
@session.visit('/with_js')
|
|
618
|
+
|
|
619
|
+
element = @session.find('//div[@id="drag_html5"]')
|
|
620
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
621
|
+
|
|
622
|
+
element.drag_to(target, drop_modifiers: modifier_key)
|
|
623
|
+
|
|
624
|
+
expect(@session).to have_css('div.drag_start', exact_text: 'HTML5 Dragged!')
|
|
625
|
+
expect(@session).to have_xpath("//div[contains(., 'HTML5 Dropped string: text/plain drag_html5-#{modifier_key}')]")
|
|
626
|
+
end
|
|
627
|
+
end
|
|
628
|
+
|
|
629
|
+
it 'should simulate multiple held down modifier keys' do
|
|
630
|
+
@session.visit('/with_js')
|
|
631
|
+
|
|
632
|
+
element = @session.find('//div[@id="drag_html5"]')
|
|
633
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
634
|
+
|
|
635
|
+
modifier_keys = %I[alt ctrl meta shift]
|
|
636
|
+
|
|
637
|
+
element.drag_to(target, drop_modifiers: modifier_keys)
|
|
638
|
+
expect(@session).to have_xpath("//div[contains(., 'HTML5 Dropped string: text/plain drag_html5-#{modifier_keys.join('-')}')]")
|
|
639
|
+
end
|
|
640
|
+
|
|
641
|
+
it 'should support key aliases' do
|
|
642
|
+
{ control: :ctrl,
|
|
643
|
+
command: :meta,
|
|
644
|
+
cmd: :meta }.each do |(key_alias, key)|
|
|
645
|
+
@session.visit('/with_js')
|
|
646
|
+
|
|
647
|
+
element = @session.find('//div[@id="drag_html5"]')
|
|
648
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
649
|
+
|
|
650
|
+
element.drag_to(target, drop_modifiers: [key_alias])
|
|
651
|
+
expect(target).to have_text(%r{^HTML5 Dropped string: text/plain drag_html5-#{key}$}m, exact: true)
|
|
652
|
+
end
|
|
653
|
+
end
|
|
554
654
|
end
|
|
555
655
|
end
|
|
556
656
|
|
|
@@ -582,6 +682,15 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
582
682
|
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped string: text/plain Some dropped text")]')
|
|
583
683
|
end
|
|
584
684
|
|
|
685
|
+
it 'can drop a pathname' do
|
|
686
|
+
@session.visit('/with_js')
|
|
687
|
+
target = @session.find('//div[@id="drop_html5"]')
|
|
688
|
+
target.drop(
|
|
689
|
+
Pathname.new(with_os_path_separators(File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__))))
|
|
690
|
+
)
|
|
691
|
+
expect(@session).to have_xpath('//div[contains(., "HTML5 Dropped file: capybara.jpg")]')
|
|
692
|
+
end
|
|
693
|
+
|
|
585
694
|
it 'can drop multiple strings' do
|
|
586
695
|
@session.visit('/with_js')
|
|
587
696
|
target = @session.find('//div[@id="drop_html5"]')
|
|
@@ -669,7 +778,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
669
778
|
@session.visit('with_js')
|
|
670
779
|
@session.find(:css, '#click-test').click(x: 5, y: 5)
|
|
671
780
|
link = @session.find(:link, 'has-been-clicked')
|
|
672
|
-
locations = link.text.match(/^Has been clicked at (?<x>[\d
|
|
781
|
+
locations = link.text.match(/^Has been clicked at (?<x>[\d.-]+),(?<y>[\d.-]+)$/)
|
|
673
782
|
# Resulting click location should be very close to 0, 0 relative to top left corner of the element, but may not be exact due to
|
|
674
783
|
# integer/float conversions and rounding.
|
|
675
784
|
expect(locations[:x].to_f).to be_within(1).of(5)
|
|
@@ -719,7 +828,10 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
719
828
|
context 'offset', requires: [:js] do
|
|
720
829
|
before do
|
|
721
830
|
@session.visit('/offset')
|
|
722
|
-
|
|
831
|
+
end
|
|
832
|
+
|
|
833
|
+
let :clicker do
|
|
834
|
+
@session.find(:id, 'clicker')
|
|
723
835
|
end
|
|
724
836
|
|
|
725
837
|
context 'when w3c_click_offset is false' do
|
|
@@ -728,17 +840,17 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
728
840
|
end
|
|
729
841
|
|
|
730
842
|
it 'should offset from top left of element' do
|
|
731
|
-
|
|
843
|
+
clicker.click(x: 10, y: 5)
|
|
732
844
|
expect(@session).to have_text(/clicked at 110,105/)
|
|
733
845
|
end
|
|
734
846
|
|
|
735
847
|
it 'should offset outside the element' do
|
|
736
|
-
|
|
848
|
+
clicker.click(x: -15, y: -10)
|
|
737
849
|
expect(@session).to have_text(/clicked at 85,90/)
|
|
738
850
|
end
|
|
739
851
|
|
|
740
852
|
it 'should default to click the middle' do
|
|
741
|
-
|
|
853
|
+
clicker.click
|
|
742
854
|
expect(@session).to have_text(/clicked at 150,150/)
|
|
743
855
|
end
|
|
744
856
|
end
|
|
@@ -749,21 +861,30 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
749
861
|
end
|
|
750
862
|
|
|
751
863
|
it 'should offset from center of element' do
|
|
752
|
-
|
|
864
|
+
clicker.click(x: 10, y: 5)
|
|
753
865
|
expect(@session).to have_text(/clicked at 160,155/)
|
|
754
866
|
end
|
|
755
867
|
|
|
756
868
|
it 'should offset outside from center of element' do
|
|
757
|
-
|
|
869
|
+
clicker.click(x: -65, y: -60)
|
|
758
870
|
expect(@session).to have_text(/clicked at 85,90/)
|
|
759
871
|
end
|
|
760
872
|
|
|
761
873
|
it 'should default to click the middle' do
|
|
762
|
-
|
|
874
|
+
clicker.click
|
|
763
875
|
expect(@session).to have_text(/clicked at 150,150/)
|
|
764
876
|
end
|
|
765
877
|
end
|
|
766
878
|
end
|
|
879
|
+
|
|
880
|
+
context 'delay', requires: [:js] do
|
|
881
|
+
it 'should delay the mouse up' do
|
|
882
|
+
@session.visit('with_js')
|
|
883
|
+
@session.find(:css, '#click-test').click(delay: 2)
|
|
884
|
+
delay = @session.evaluate_script('window.click_delay')
|
|
885
|
+
expect(delay).to be >= 2
|
|
886
|
+
end
|
|
887
|
+
end
|
|
767
888
|
end
|
|
768
889
|
|
|
769
890
|
describe '#double_click', requires: [:js] do
|
|
@@ -783,7 +904,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
783
904
|
@session.visit('with_js')
|
|
784
905
|
@session.find(:css, '#click-test').double_click(x: 10, y: 5)
|
|
785
906
|
link = @session.find(:link, 'has-been-double-clicked')
|
|
786
|
-
locations = link.text.match(/^Has been double clicked at (?<x>[\d
|
|
907
|
+
locations = link.text.match(/^Has been double clicked at (?<x>[\d.-]+),(?<y>[\d.-]+)$/)
|
|
787
908
|
# Resulting click location should be very close to 10, 5 relative to top left corner of the element, but may not be exact due
|
|
788
909
|
# to integer/float conversions and rounding.
|
|
789
910
|
expect(locations[:x].to_f).to be_within(1).of(10)
|
|
@@ -802,7 +923,10 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
802
923
|
context 'offset', requires: [:js] do
|
|
803
924
|
before do
|
|
804
925
|
@session.visit('/offset')
|
|
805
|
-
|
|
926
|
+
end
|
|
927
|
+
|
|
928
|
+
let :clicker do
|
|
929
|
+
@session.find(:id, 'clicker')
|
|
806
930
|
end
|
|
807
931
|
|
|
808
932
|
context 'when w3c_click_offset is false' do
|
|
@@ -811,17 +935,17 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
811
935
|
end
|
|
812
936
|
|
|
813
937
|
it 'should offset from top left of element' do
|
|
814
|
-
|
|
938
|
+
clicker.double_click(x: 10, y: 5)
|
|
815
939
|
expect(@session).to have_text(/clicked at 110,105/)
|
|
816
940
|
end
|
|
817
941
|
|
|
818
942
|
it 'should offset outside the element' do
|
|
819
|
-
|
|
943
|
+
clicker.double_click(x: -15, y: -10)
|
|
820
944
|
expect(@session).to have_text(/clicked at 85,90/)
|
|
821
945
|
end
|
|
822
946
|
|
|
823
947
|
it 'should default to click the middle' do
|
|
824
|
-
|
|
948
|
+
clicker.double_click
|
|
825
949
|
expect(@session).to have_text(/clicked at 150,150/)
|
|
826
950
|
end
|
|
827
951
|
end
|
|
@@ -832,17 +956,17 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
832
956
|
end
|
|
833
957
|
|
|
834
958
|
it 'should offset from center of element' do
|
|
835
|
-
|
|
959
|
+
clicker.double_click(x: 10, y: 5)
|
|
836
960
|
expect(@session).to have_text(/clicked at 160,155/)
|
|
837
961
|
end
|
|
838
962
|
|
|
839
963
|
it 'should offset outside from center of element' do
|
|
840
|
-
|
|
964
|
+
clicker.double_click(x: -65, y: -60)
|
|
841
965
|
expect(@session).to have_text(/clicked at 85,90/)
|
|
842
966
|
end
|
|
843
967
|
|
|
844
968
|
it 'should default to click the middle' do
|
|
845
|
-
|
|
969
|
+
clicker.double_click
|
|
846
970
|
expect(@session).to have_text(/clicked at 150,150/)
|
|
847
971
|
end
|
|
848
972
|
end
|
|
@@ -866,7 +990,7 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
866
990
|
@session.visit('with_js')
|
|
867
991
|
@session.find(:css, '#click-test').right_click(x: 10, y: 10)
|
|
868
992
|
link = @session.find(:link, 'has-been-right-clicked')
|
|
869
|
-
locations = link.text.match(/^Has been right clicked at (?<x>[\d
|
|
993
|
+
locations = link.text.match(/^Has been right clicked at (?<x>[\d.-]+),(?<y>[\d.-]+)$/)
|
|
870
994
|
# Resulting click location should be very close to 10, 10 relative to top left corner of the element, but may not be exact due
|
|
871
995
|
# to integer/float conversions and rounding
|
|
872
996
|
expect(locations[:x].to_f).to be_within(1).of(10)
|
|
@@ -885,7 +1009,10 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
885
1009
|
context 'offset', requires: [:js] do
|
|
886
1010
|
before do
|
|
887
1011
|
@session.visit('/offset')
|
|
888
|
-
|
|
1012
|
+
end
|
|
1013
|
+
|
|
1014
|
+
let :clicker do
|
|
1015
|
+
@session.find(:id, 'clicker')
|
|
889
1016
|
end
|
|
890
1017
|
|
|
891
1018
|
context 'when w3c_click_offset is false' do
|
|
@@ -894,17 +1021,17 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
894
1021
|
end
|
|
895
1022
|
|
|
896
1023
|
it 'should offset from top left of element' do
|
|
897
|
-
|
|
1024
|
+
clicker.right_click(x: 10, y: 5)
|
|
898
1025
|
expect(@session).to have_text(/clicked at 110,105/)
|
|
899
1026
|
end
|
|
900
1027
|
|
|
901
1028
|
it 'should offset outside the element' do
|
|
902
|
-
|
|
1029
|
+
clicker.right_click(x: -15, y: -10)
|
|
903
1030
|
expect(@session).to have_text(/clicked at 85,90/)
|
|
904
1031
|
end
|
|
905
1032
|
|
|
906
1033
|
it 'should default to click the middle' do
|
|
907
|
-
|
|
1034
|
+
clicker.right_click
|
|
908
1035
|
expect(@session).to have_text(/clicked at 150,150/)
|
|
909
1036
|
end
|
|
910
1037
|
end
|
|
@@ -915,21 +1042,30 @@ Capybara::SpecHelper.spec 'node' do
|
|
|
915
1042
|
end
|
|
916
1043
|
|
|
917
1044
|
it 'should offset from center of element' do
|
|
918
|
-
|
|
1045
|
+
clicker.right_click(x: 10, y: 5)
|
|
919
1046
|
expect(@session).to have_text(/clicked at 160,155/)
|
|
920
1047
|
end
|
|
921
1048
|
|
|
922
1049
|
it 'should offset outside from center of element' do
|
|
923
|
-
|
|
1050
|
+
clicker.right_click(x: -65, y: -60)
|
|
924
1051
|
expect(@session).to have_text(/clicked at 85,90/)
|
|
925
1052
|
end
|
|
926
1053
|
|
|
927
1054
|
it 'should default to click the middle' do
|
|
928
|
-
|
|
1055
|
+
clicker.right_click
|
|
929
1056
|
expect(@session).to have_text(/clicked at 150,150/)
|
|
930
1057
|
end
|
|
931
1058
|
end
|
|
932
1059
|
end
|
|
1060
|
+
|
|
1061
|
+
context 'delay', requires: [:js] do
|
|
1062
|
+
it 'should delay the mouse up' do
|
|
1063
|
+
@session.visit('with_js')
|
|
1064
|
+
@session.find(:css, '#click-test').right_click(delay: 2)
|
|
1065
|
+
delay = @session.evaluate_script('window.right_click_delay')
|
|
1066
|
+
expect(delay).to be >= 2
|
|
1067
|
+
end
|
|
1068
|
+
end
|
|
933
1069
|
end
|
|
934
1070
|
|
|
935
1071
|
describe '#send_keys', requires: [:send_keys] do
|