capybara 3.31.0 → 3.32.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 +14 -0
- data/README.md +1 -1
- data/lib/capybara/minitest.rb +213 -138
- data/lib/capybara/minitest/spec.rb +153 -97
- data/lib/capybara/node/element.rb +2 -0
- data/lib/capybara/rack_test/browser.rb +3 -1
- data/lib/capybara/result.rb +1 -0
- data/lib/capybara/rspec/matcher_proxies.rb +4 -4
- data/lib/capybara/selenium/atoms/getAttribute.min.js +1 -1
- data/lib/capybara/selenium/atoms/src/getAttribute.js +1 -1
- data/lib/capybara/selenium/driver.rb +1 -0
- data/lib/capybara/selenium/node.rb +54 -8
- data/lib/capybara/selenium/nodes/chrome_node.rb +0 -9
- data/lib/capybara/selenium/nodes/firefox_node.rb +1 -1
- data/lib/capybara/selenium/patches/action_pauser.rb +23 -0
- data/lib/capybara/spec/public/test.js +11 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +9 -0
- data/lib/capybara/spec/session/find_spec.rb +11 -8
- data/lib/capybara/spec/session/has_css_spec.rb +9 -6
- data/lib/capybara/spec/session/node_spec.rb +48 -21
- data/lib/capybara/spec/session/window/window_spec.rb +7 -7
- data/lib/capybara/spec/spec_helper.rb +1 -2
- data/lib/capybara/spec/views/form.erb +1 -0
- data/lib/capybara/spec/views/with_html.erb +2 -2
- data/lib/capybara/version.rb +1 -1
- data/spec/rack_test_spec.rb +12 -0
- data/spec/regexp_dissassembler_spec.rb +0 -4
- data/spec/result_spec.rb +37 -14
- data/spec/selenium_spec_chrome.rb +4 -0
- data/spec/selenium_spec_chrome_remote.rb +2 -0
- data/spec/shared_selenium_node.rb +8 -0
- metadata +3 -2
@@ -92,11 +92,6 @@ private
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
def w3c?
|
96
|
-
(defined?(Selenium::WebDriver::VERSION) && (Selenium::WebDriver::VERSION.to_f >= 4)) ||
|
97
|
-
capabilities.is_a?(::Selenium::WebDriver::Remote::W3C::Capabilities)
|
98
|
-
end
|
99
|
-
|
100
95
|
def browser_version(to_float = true)
|
101
96
|
caps = capabilities
|
102
97
|
ver = (caps[:browser_version] || caps[:version])
|
@@ -116,10 +111,6 @@ private
|
|
116
111
|
capabilities['chrome']['chromedriverVersion'].split(' ')[0]
|
117
112
|
end
|
118
113
|
|
119
|
-
def capabilities
|
120
|
-
driver.browser.capabilities
|
121
|
-
end
|
122
|
-
|
123
114
|
def native_displayed?
|
124
115
|
(driver.options[:native_displayed] != false) &&
|
125
116
|
(w3c? && chromedriver_supports_displayed_endpoint?) &&
|
@@ -85,7 +85,7 @@ private
|
|
85
85
|
(driver.options[:native_displayed] != false) && !ENV['DISABLE_CAPYBARA_SELENIUM_OPTIMIZATIONS']
|
86
86
|
end
|
87
87
|
|
88
|
-
def
|
88
|
+
def perform_with_options(click_options)
|
89
89
|
# Firefox/marionette has an issue clicking with offset near viewport edge
|
90
90
|
# scroll element to middle just in case
|
91
91
|
scroll_to_center if click_options.coords?
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionPauser
|
4
|
+
def initialize(mouse, keyboard)
|
5
|
+
super
|
6
|
+
@devices[:pauser] = Pauser.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def pause(duration)
|
10
|
+
@actions << [:pauser, :pause, [duration]]
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
class Pauser
|
15
|
+
def pause(duration)
|
16
|
+
sleep duration
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private_constant :Pauser
|
21
|
+
end
|
22
|
+
|
23
|
+
::Selenium::WebDriver::ActionBuilder.prepend ActionPauser if defined? ::Selenium::WebDriver::ActionBuilder
|
@@ -153,6 +153,7 @@ $(function() {
|
|
153
153
|
});
|
154
154
|
$('#click-test').on({
|
155
155
|
click: function(e) {
|
156
|
+
window.click_delay = ((new Date().getTime()) - window.mouse_down_time)/1000.0;
|
156
157
|
var desc = "";
|
157
158
|
if (e.altKey) desc += 'alt ';
|
158
159
|
if (e.ctrlKey) desc += 'control ';
|
@@ -179,6 +180,16 @@ $(function() {
|
|
179
180
|
if (e.shiftKey) desc += 'shift ';
|
180
181
|
var pos = this.getBoundingClientRect();
|
181
182
|
$(this).after('<a id="has-been-right-clicked" href="#">Has been ' + desc + 'right clicked at ' + (e.clientX - pos.left) + ',' + (e.clientY - pos.top) + '</a>');
|
183
|
+
},
|
184
|
+
mousedown: function(e) {
|
185
|
+
window.click_delay = undefined;
|
186
|
+
window.right_click_delay = undefined;
|
187
|
+
window.mouse_down_time = new Date().getTime();
|
188
|
+
},
|
189
|
+
mouseup: function(e) {
|
190
|
+
if (e.button == 2){
|
191
|
+
window.right_click_delay = ((new Date().getTime()) - window.mouse_down_time)/1000.0;
|
192
|
+
}
|
182
193
|
}
|
183
194
|
});
|
184
195
|
$('#open-alert').click(function() {
|
@@ -47,6 +47,15 @@ Capybara::SpecHelper.spec '#fill_in' do
|
|
47
47
|
expect(extract_results(@session)['description']).to eq('Texty text')
|
48
48
|
end
|
49
49
|
|
50
|
+
it 'should fill in a textarea in a reasonable time by default' do
|
51
|
+
textarea = @session.find(:fillable_field, 'form[description]')
|
52
|
+
value = 'a' * 4000
|
53
|
+
start = Time.now
|
54
|
+
textarea.fill_in(with: value)
|
55
|
+
expect(Time.now.to_f).to be_within(0.25).of start.to_f
|
56
|
+
expect(textarea.value).to eq value
|
57
|
+
end
|
58
|
+
|
50
59
|
it 'should fill in a password field by id' do
|
51
60
|
@session.fill_in('form_password', with: 'supasikrit')
|
52
61
|
@session.click_button('awesome')
|
@@ -451,32 +451,35 @@ Capybara::SpecHelper.spec '#find' do
|
|
451
451
|
context 'with spatial filters', requires: [:spatial] do
|
452
452
|
before do
|
453
453
|
@session.visit('/spatial')
|
454
|
-
|
454
|
+
end
|
455
|
+
|
456
|
+
let :center do
|
457
|
+
@session.find(:css, 'div.center')
|
455
458
|
end
|
456
459
|
|
457
460
|
it 'should find an element above another element' do
|
458
|
-
expect(@session.find(:css, 'div:not(.corner)', above:
|
461
|
+
expect(@session.find(:css, 'div:not(.corner)', above: center).text).to eq('2')
|
459
462
|
end
|
460
463
|
|
461
464
|
it 'should find an element below another element' do
|
462
|
-
expect(@session.find(:css, 'div:not(.corner):not(.footer)', below:
|
465
|
+
expect(@session.find(:css, 'div:not(.corner):not(.footer)', below: center).text).to eq('8')
|
463
466
|
end
|
464
467
|
|
465
468
|
it 'should find an element left of another element' do
|
466
|
-
expect(@session.find(:css, 'div:not(.corner)', left_of:
|
469
|
+
expect(@session.find(:css, 'div:not(.corner)', left_of: center).text).to eq('4')
|
467
470
|
end
|
468
471
|
|
469
472
|
it 'should find an element right of another element' do
|
470
|
-
expect(@session.find(:css, 'div:not(.corner)', right_of:
|
473
|
+
expect(@session.find(:css, 'div:not(.corner)', right_of: center).text).to eq('6')
|
471
474
|
end
|
472
475
|
|
473
476
|
it 'should combine spatial filters' do
|
474
|
-
expect(@session.find(:css, 'div', left_of:
|
475
|
-
expect(@session.find(:css, 'div', right_of:
|
477
|
+
expect(@session.find(:css, 'div', left_of: center, above: center).text).to eq('1')
|
478
|
+
expect(@session.find(:css, 'div', right_of: center, below: center).text).to eq('9')
|
476
479
|
end
|
477
480
|
|
478
481
|
it 'should find an element "near" another element' do
|
479
|
-
expect(@session.find(:css, 'div.distance', near:
|
482
|
+
expect(@session.find(:css, 'div.distance', near: center).text).to eq('2')
|
480
483
|
end
|
481
484
|
end
|
482
485
|
|
@@ -234,18 +234,21 @@ Capybara::SpecHelper.spec '#has_css?' do
|
|
234
234
|
context 'with spatial requirements', requires: [:spatial] do
|
235
235
|
before do
|
236
236
|
@session.visit('/spatial')
|
237
|
-
|
237
|
+
end
|
238
|
+
|
239
|
+
let :center do
|
240
|
+
@session.find(:css, '.center')
|
238
241
|
end
|
239
242
|
|
240
243
|
it 'accepts spatial options' do
|
241
|
-
expect(@session).to have_css('div', above:
|
242
|
-
expect(@session).to have_css('div', above:
|
244
|
+
expect(@session).to have_css('div', above: center).thrice
|
245
|
+
expect(@session).to have_css('div', above: center, right_of: center).once
|
243
246
|
end
|
244
247
|
|
245
248
|
it 'supports spatial sugar' do
|
246
|
-
expect(@session).to have_css('div').left_of(
|
247
|
-
expect(@session).to have_css('div').below(
|
248
|
-
expect(@session).to have_css('div').near(
|
249
|
+
expect(@session).to have_css('div').left_of(center).thrice
|
250
|
+
expect(@session).to have_css('div').below(center).right_of(center).once
|
251
|
+
expect(@session).to have_css('div').near(center).exactly(8).times
|
249
252
|
end
|
250
253
|
end
|
251
254
|
|
@@ -808,7 +808,10 @@ Capybara::SpecHelper.spec 'node' do
|
|
808
808
|
context 'offset', requires: [:js] do
|
809
809
|
before do
|
810
810
|
@session.visit('/offset')
|
811
|
-
|
811
|
+
end
|
812
|
+
|
813
|
+
let :clicker do
|
814
|
+
@session.find(:id, 'clicker')
|
812
815
|
end
|
813
816
|
|
814
817
|
context 'when w3c_click_offset is false' do
|
@@ -817,17 +820,17 @@ Capybara::SpecHelper.spec 'node' do
|
|
817
820
|
end
|
818
821
|
|
819
822
|
it 'should offset from top left of element' do
|
820
|
-
|
823
|
+
clicker.click(x: 10, y: 5)
|
821
824
|
expect(@session).to have_text(/clicked at 110,105/)
|
822
825
|
end
|
823
826
|
|
824
827
|
it 'should offset outside the element' do
|
825
|
-
|
828
|
+
clicker.click(x: -15, y: -10)
|
826
829
|
expect(@session).to have_text(/clicked at 85,90/)
|
827
830
|
end
|
828
831
|
|
829
832
|
it 'should default to click the middle' do
|
830
|
-
|
833
|
+
clicker.click
|
831
834
|
expect(@session).to have_text(/clicked at 150,150/)
|
832
835
|
end
|
833
836
|
end
|
@@ -838,21 +841,30 @@ Capybara::SpecHelper.spec 'node' do
|
|
838
841
|
end
|
839
842
|
|
840
843
|
it 'should offset from center of element' do
|
841
|
-
|
844
|
+
clicker.click(x: 10, y: 5)
|
842
845
|
expect(@session).to have_text(/clicked at 160,155/)
|
843
846
|
end
|
844
847
|
|
845
848
|
it 'should offset outside from center of element' do
|
846
|
-
|
849
|
+
clicker.click(x: -65, y: -60)
|
847
850
|
expect(@session).to have_text(/clicked at 85,90/)
|
848
851
|
end
|
849
852
|
|
850
853
|
it 'should default to click the middle' do
|
851
|
-
|
854
|
+
clicker.click
|
852
855
|
expect(@session).to have_text(/clicked at 150,150/)
|
853
856
|
end
|
854
857
|
end
|
855
858
|
end
|
859
|
+
|
860
|
+
context 'delay', requires: [:js] do
|
861
|
+
it 'should delay the mouse up' do
|
862
|
+
@session.visit('with_js')
|
863
|
+
@session.find(:css, '#click-test').click(delay: 2)
|
864
|
+
delay = @session.evaluate_script('window.click_delay')
|
865
|
+
expect(delay).to be >= 2
|
866
|
+
end
|
867
|
+
end
|
856
868
|
end
|
857
869
|
|
858
870
|
describe '#double_click', requires: [:js] do
|
@@ -891,7 +903,10 @@ Capybara::SpecHelper.spec 'node' do
|
|
891
903
|
context 'offset', requires: [:js] do
|
892
904
|
before do
|
893
905
|
@session.visit('/offset')
|
894
|
-
|
906
|
+
end
|
907
|
+
|
908
|
+
let :clicker do
|
909
|
+
@session.find(:id, 'clicker')
|
895
910
|
end
|
896
911
|
|
897
912
|
context 'when w3c_click_offset is false' do
|
@@ -900,17 +915,17 @@ Capybara::SpecHelper.spec 'node' do
|
|
900
915
|
end
|
901
916
|
|
902
917
|
it 'should offset from top left of element' do
|
903
|
-
|
918
|
+
clicker.double_click(x: 10, y: 5)
|
904
919
|
expect(@session).to have_text(/clicked at 110,105/)
|
905
920
|
end
|
906
921
|
|
907
922
|
it 'should offset outside the element' do
|
908
|
-
|
923
|
+
clicker.double_click(x: -15, y: -10)
|
909
924
|
expect(@session).to have_text(/clicked at 85,90/)
|
910
925
|
end
|
911
926
|
|
912
927
|
it 'should default to click the middle' do
|
913
|
-
|
928
|
+
clicker.double_click
|
914
929
|
expect(@session).to have_text(/clicked at 150,150/)
|
915
930
|
end
|
916
931
|
end
|
@@ -921,17 +936,17 @@ Capybara::SpecHelper.spec 'node' do
|
|
921
936
|
end
|
922
937
|
|
923
938
|
it 'should offset from center of element' do
|
924
|
-
|
939
|
+
clicker.double_click(x: 10, y: 5)
|
925
940
|
expect(@session).to have_text(/clicked at 160,155/)
|
926
941
|
end
|
927
942
|
|
928
943
|
it 'should offset outside from center of element' do
|
929
|
-
|
944
|
+
clicker.double_click(x: -65, y: -60)
|
930
945
|
expect(@session).to have_text(/clicked at 85,90/)
|
931
946
|
end
|
932
947
|
|
933
948
|
it 'should default to click the middle' do
|
934
|
-
|
949
|
+
clicker.double_click
|
935
950
|
expect(@session).to have_text(/clicked at 150,150/)
|
936
951
|
end
|
937
952
|
end
|
@@ -974,7 +989,10 @@ Capybara::SpecHelper.spec 'node' do
|
|
974
989
|
context 'offset', requires: [:js] do
|
975
990
|
before do
|
976
991
|
@session.visit('/offset')
|
977
|
-
|
992
|
+
end
|
993
|
+
|
994
|
+
let :clicker do
|
995
|
+
@session.find(:id, 'clicker')
|
978
996
|
end
|
979
997
|
|
980
998
|
context 'when w3c_click_offset is false' do
|
@@ -983,17 +1001,17 @@ Capybara::SpecHelper.spec 'node' do
|
|
983
1001
|
end
|
984
1002
|
|
985
1003
|
it 'should offset from top left of element' do
|
986
|
-
|
1004
|
+
clicker.right_click(x: 10, y: 5)
|
987
1005
|
expect(@session).to have_text(/clicked at 110,105/)
|
988
1006
|
end
|
989
1007
|
|
990
1008
|
it 'should offset outside the element' do
|
991
|
-
|
1009
|
+
clicker.right_click(x: -15, y: -10)
|
992
1010
|
expect(@session).to have_text(/clicked at 85,90/)
|
993
1011
|
end
|
994
1012
|
|
995
1013
|
it 'should default to click the middle' do
|
996
|
-
|
1014
|
+
clicker.right_click
|
997
1015
|
expect(@session).to have_text(/clicked at 150,150/)
|
998
1016
|
end
|
999
1017
|
end
|
@@ -1004,21 +1022,30 @@ Capybara::SpecHelper.spec 'node' do
|
|
1004
1022
|
end
|
1005
1023
|
|
1006
1024
|
it 'should offset from center of element' do
|
1007
|
-
|
1025
|
+
clicker.right_click(x: 10, y: 5)
|
1008
1026
|
expect(@session).to have_text(/clicked at 160,155/)
|
1009
1027
|
end
|
1010
1028
|
|
1011
1029
|
it 'should offset outside from center of element' do
|
1012
|
-
|
1030
|
+
clicker.right_click(x: -65, y: -60)
|
1013
1031
|
expect(@session).to have_text(/clicked at 85,90/)
|
1014
1032
|
end
|
1015
1033
|
|
1016
1034
|
it 'should default to click the middle' do
|
1017
|
-
|
1035
|
+
clicker.right_click
|
1018
1036
|
expect(@session).to have_text(/clicked at 150,150/)
|
1019
1037
|
end
|
1020
1038
|
end
|
1021
1039
|
end
|
1040
|
+
|
1041
|
+
context 'delay', requires: [:js] do
|
1042
|
+
it 'should delay the mouse up' do
|
1043
|
+
@session.visit('with_js')
|
1044
|
+
@session.find(:css, '#click-test').right_click(delay: 2)
|
1045
|
+
delay = @session.evaluate_script('window.right_click_delay')
|
1046
|
+
expect(delay).to be >= 2
|
1047
|
+
end
|
1048
|
+
end
|
1022
1049
|
end
|
1023
1050
|
|
1024
1051
|
describe '#send_keys', requires: [:send_keys] do
|
@@ -141,12 +141,12 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
|
|
141
141
|
end
|
142
142
|
|
143
143
|
describe '#maximize' do
|
144
|
-
|
145
|
-
@
|
144
|
+
let! :initial_size do
|
145
|
+
@session.current_window.size
|
146
146
|
end
|
147
147
|
|
148
148
|
after do
|
149
|
-
@session.current_window.resize_to(
|
149
|
+
@session.current_window.resize_to(*initial_size)
|
150
150
|
sleep 0.5
|
151
151
|
end
|
152
152
|
|
@@ -176,7 +176,7 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
|
|
176
176
|
|
177
177
|
expect(@session.current_window).to eq(orig_window)
|
178
178
|
# Maximizing the browser affects all tabs so this may not be valid in real browsers
|
179
|
-
# expect(@session.current_window.size).to eq(
|
179
|
+
# expect(@session.current_window.size).to eq(initial_size)
|
180
180
|
|
181
181
|
ow_width, ow_height = other_window.size
|
182
182
|
expect(ow_width).to be > 400
|
@@ -185,12 +185,12 @@ Capybara::SpecHelper.spec Capybara::Window, requires: [:windows] do
|
|
185
185
|
end
|
186
186
|
|
187
187
|
describe '#fullscreen' do
|
188
|
-
|
189
|
-
@
|
188
|
+
let! :initial_size do
|
189
|
+
@session.current_window.size
|
190
190
|
end
|
191
191
|
|
192
192
|
after do
|
193
|
-
@session.current_window.resize_to(
|
193
|
+
@session.current_window.resize_to(*initial_size)
|
194
194
|
sleep 1
|
195
195
|
end
|
196
196
|
|
@@ -60,7 +60,7 @@ module Capybara
|
|
60
60
|
RSpec.describe Capybara::Session, name, options do # rubocop:disable RSpec/EmptyExampleGroup
|
61
61
|
include Capybara::SpecHelper
|
62
62
|
include Capybara::RSpecMatchers
|
63
|
-
|
63
|
+
|
64
64
|
before do |example|
|
65
65
|
@session = session
|
66
66
|
instance_exec(example, &filter_block) if filter_block
|
@@ -81,7 +81,6 @@ module Capybara
|
|
81
81
|
before :each, :exact_false do
|
82
82
|
Capybara.exact = false
|
83
83
|
end
|
84
|
-
# rubocop:enable RSpec/ScatteredSetup
|
85
84
|
|
86
85
|
specs.each do |spec_name, spec_options, block|
|
87
86
|
describe spec_name, *spec_options do # rubocop:disable RSpec/EmptyExampleGroup
|
@@ -517,6 +517,7 @@ New line after and before textarea tag
|
|
517
517
|
|
518
518
|
<p>
|
519
519
|
<input type="submit" name="form[mediocre]" id="mediocre" value="med" aria-label="Mediocre Button"/>
|
520
|
+
<input type="submit" formaction="/form/get?bar=foo" id="mediocre2" value="med2"/>
|
520
521
|
<p>
|
521
522
|
</form>
|
522
523
|
|
@@ -36,8 +36,8 @@
|
|
36
36
|
</p>
|
37
37
|
|
38
38
|
<p>
|
39
|
-
<input type="text" id="test_field" data-test-id="test_id" value="monkey"/>
|
40
|
-
<input type="text" readonly="readonly" value="should not change" />
|
39
|
+
<input type="text" id="test_field" spellcheck="TRUE" data-test-id="test_id" value="monkey"/>
|
40
|
+
<input type="text" readonly="readonly" spellcheck="FALSE" value="should not change" />
|
41
41
|
<textarea id="normal" data-other-test-id="test_id">
|
42
42
|
banana</textarea>
|
43
43
|
<textarea id="additional_newline">
|
data/lib/capybara/version.rb
CHANGED
data/spec/rack_test_spec.rb
CHANGED
@@ -127,6 +127,18 @@ RSpec.describe Capybara::Session do # rubocop:disable RSpec/MultipleDescribes
|
|
127
127
|
session.find(:label, 'Female').click
|
128
128
|
expect(session).to have_unchecked_field('gender_male')
|
129
129
|
end
|
130
|
+
|
131
|
+
it 'should rewrite the forms action query for get submission' do
|
132
|
+
session.visit('/form')
|
133
|
+
session.click_button('mediocre')
|
134
|
+
expect(session).not_to have_current_path(/foo|bar/)
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should rewrite the submit buttons formaction query for get submission' do
|
138
|
+
session.visit('/form')
|
139
|
+
session.click_button('mediocre2')
|
140
|
+
expect(session).not_to have_current_path(/foo|bar/)
|
141
|
+
end
|
130
142
|
end
|
131
143
|
end
|
132
144
|
|