capybara 3.31.0 → 3.32.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 click_with_options(click_options)
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
- @center = @session.find(:css, 'div.center')
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: @center).text).to eq('2')
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: @center).text).to eq('8')
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: @center).text).to eq('4')
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: @center).text).to eq('6')
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: @center, above: @center).text).to eq('1')
475
- expect(@session.find(:css, 'div', right_of: @center, below: @center).text).to eq('9')
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: @center).text).to eq('2')
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
- @center = @session.find(:css, '.center')
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: @center).thrice
242
- expect(@session).to have_css('div', above: @center, right_of: @center).once
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(@center).thrice
247
- expect(@session).to have_css('div').below(@center).right_of(@center).once
248
- expect(@session).to have_css('div').near(@center).exactly(8).times
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
- @clicker = @session.find(:id, 'clicker')
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
- @clicker.click(x: 10, y: 5)
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
- @clicker.click(x: -15, y: -10)
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
- @clicker.click
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
- @clicker.click(x: 10, y: 5)
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
- @clicker.click(x: -65, y: -60)
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
- @clicker.click
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
- @clicker = @session.find(:id, 'clicker')
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
- @clicker.double_click(x: 10, y: 5)
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
- @clicker.double_click(x: -15, y: -10)
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
- @clicker.double_click
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
- @clicker.double_click(x: 10, y: 5)
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
- @clicker.double_click(x: -65, y: -60)
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
- @clicker.double_click
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
- @clicker = @session.find(:id, 'clicker')
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
- @clicker.right_click(x: 10, y: 5)
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
- @clicker.right_click(x: -15, y: -10)
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
- @clicker.right_click
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
- @clicker.right_click(x: 10, y: 5)
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
- @clicker.right_click(x: -65, y: -60)
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
- @clicker.right_click
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
- before do
145
- @initial_size = @session.current_window.size
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(*@initial_size)
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(@initial_size)
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
- before do
189
- @initial_size = @session.current_window.size
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(*@initial_size)
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
- # rubocop:disable RSpec/ScatteredSetup
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">
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.31.0'
4
+ VERSION = '3.32.0'
5
5
  end
@@ -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