capybara 3.38.0 → 3.39.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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +20 -0
  3. data/lib/capybara/node/actions.rb +4 -4
  4. data/lib/capybara/node/finders.rb +2 -0
  5. data/lib/capybara/node/whitespace_normalizer.rb +81 -0
  6. data/lib/capybara/rack_test/node.rb +18 -15
  7. data/lib/capybara/registrations/drivers.rb +3 -3
  8. data/lib/capybara/registrations/servers.rb +16 -4
  9. data/lib/capybara/rspec/matcher_proxies.rb +3 -3
  10. data/lib/capybara/rspec/matchers/base.rb +8 -6
  11. data/lib/capybara/rspec/matchers/compound.rb +1 -1
  12. data/lib/capybara/selector/definition/link.rb +2 -1
  13. data/lib/capybara/selenium/driver.rb +4 -4
  14. data/lib/capybara/selenium/driver_specializations/edge_driver.rb +8 -4
  15. data/lib/capybara/selenium/extensions/html5_drag.rb +3 -0
  16. data/lib/capybara/selenium/node.rb +8 -10
  17. data/lib/capybara/selenium/nodes/chrome_node.rb +5 -1
  18. data/lib/capybara/selenium/nodes/edge_node.rb +24 -2
  19. data/lib/capybara/selenium/patches/action_pauser.rb +3 -3
  20. data/lib/capybara/selenium/patches/atoms.rb +1 -1
  21. data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -1
  22. data/lib/capybara/server/animation_disabler.rb +2 -3
  23. data/lib/capybara/spec/public/test.js +4 -0
  24. data/lib/capybara/spec/session/all_spec.rb +1 -1
  25. data/lib/capybara/spec/session/click_link_spec.rb +11 -0
  26. data/lib/capybara/spec/session/find_link_spec.rb +10 -0
  27. data/lib/capybara/spec/session/find_spec.rb +1 -1
  28. data/lib/capybara/spec/session/first_spec.rb +1 -1
  29. data/lib/capybara/spec/session/frame/within_frame_spec.rb +2 -0
  30. data/lib/capybara/spec/session/has_all_selectors_spec.rb +5 -5
  31. data/lib/capybara/spec/session/has_any_selectors_spec.rb +2 -2
  32. data/lib/capybara/spec/session/has_current_path_spec.rb +1 -1
  33. data/lib/capybara/spec/session/has_link_spec.rb +5 -1
  34. data/lib/capybara/spec/session/has_none_selectors_spec.rb +7 -7
  35. data/lib/capybara/spec/session/matches_style_spec.rb +2 -0
  36. data/lib/capybara/spec/session/node_spec.rb +16 -0
  37. data/lib/capybara/spec/session/scroll_spec.rb +3 -1
  38. data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
  39. data/lib/capybara/spec/views/form.erb +4 -0
  40. data/lib/capybara/spec/views/with_html.erb +1 -1
  41. data/lib/capybara/version.rb +1 -1
  42. data/spec/css_builder_spec.rb +1 -1
  43. data/spec/css_splitter_spec.rb +1 -1
  44. data/spec/rack_test_spec.rb +2 -2
  45. data/spec/rspec/scenarios_spec.rb +1 -1
  46. data/spec/rspec_matchers_spec.rb +25 -0
  47. data/spec/sauce_spec_chrome.rb +1 -1
  48. data/spec/selenium_spec_chrome.rb +5 -6
  49. data/spec/selenium_spec_chrome_remote.rb +5 -7
  50. data/spec/selenium_spec_edge.rb +11 -7
  51. data/spec/selenium_spec_firefox.rb +10 -4
  52. data/spec/selenium_spec_firefox_remote.rb +16 -3
  53. data/spec/selenium_spec_ie.rb +1 -1
  54. data/spec/selenium_spec_safari.rb +1 -1
  55. data/spec/server_spec.rb +2 -2
  56. data/spec/shared_selenium_session.rb +2 -1
  57. data/spec/spec_helper.rb +33 -0
  58. data/spec/whitespace_normalizer_spec.rb +54 -0
  59. data/spec/xpath_builder_spec.rb +1 -1
  60. metadata +4 -2
@@ -67,4 +67,14 @@ Capybara::SpecHelper.spec '#find_link' do
67
67
  expect { @session.find_link(download: 37) }.to raise_error ArgumentError
68
68
  end
69
69
  end
70
+
71
+ context 'with :target option' do
72
+ it 'should accept partial matches when false' do
73
+ expect(@session.find_link(target: '_self').text).to eq('labore')
74
+ end
75
+
76
+ it 'should not accept partial matches when true' do
77
+ expect { @session.find_link(target: '_blank') }.to raise_error Capybara::ElementNotFound
78
+ end
79
+ end
70
80
  end
@@ -236,7 +236,7 @@ Capybara::SpecHelper.spec '#find' do
236
236
  it 'should accept an XPath instance' do
237
237
  @session.visit('/form')
238
238
  @xpath = Capybara::Selector.new(:fillable_field, config: {}, format: :xpath).call('First Name')
239
- expect(@xpath).to be_a(::XPath::Union)
239
+ expect(@xpath).to be_a(XPath::Union)
240
240
  expect(@session.find(@xpath).value).to eq('John')
241
241
  end
242
242
 
@@ -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(::XPath::Union)
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 ::RSpec::Expectations::ExpectationNotMetError
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 ::RSpec::Expectations::ExpectationNotMetError
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 ::RSpec::Expectations::ExpectationNotMetError
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 ::RSpec::Expectations::ExpectationNotMetError
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 ::RSpec::Expectations::ExpectationNotMetError
50
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
51
51
  end
52
52
  end
53
53
 
@@ -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 ::RSpec::Expectations::ExpectationNotMetError
15
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
16
16
  end
17
17
 
18
18
  it 'should use default selector' do
@@ -20,7 +20,7 @@ Capybara::SpecHelper.spec '#have_any_of_selectors' do
20
20
  expect(@session).to have_any_of_selectors('p a#foo', 'h2#h2two', 'a#not_on_page')
21
21
  expect do
22
22
  expect(@session).to have_any_of_selectors('p a#blah', 'h2#h2three')
23
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
23
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
24
24
  end
25
25
 
26
26
  it 'should be negateable' do
@@ -75,7 +75,7 @@ Capybara::SpecHelper.spec '#has_current_path?' do
75
75
  @session.visit('/with_js?test=test')
76
76
  expect(@session).to have_current_path('/with_js?test=test')
77
77
  expect(@session).to have_current_path('/with_js', ignore_query: true)
78
- uri = ::Addressable::URI.parse(@session.current_url)
78
+ uri = Addressable::URI.parse(@session.current_url)
79
79
  uri.query = nil
80
80
  expect(@session).to have_current_path(uri.to_s, ignore_query: true)
81
81
  end
@@ -11,12 +11,14 @@ Capybara::SpecHelper.spec '#has_link?' do
11
11
  expect(@session).to have_link('A link', href: '/with_simple_html')
12
12
  expect(@session).to have_link(:'A link', href: :'/with_simple_html')
13
13
  expect(@session).to have_link('A link', href: %r{/with_simple_html})
14
+ expect(@session).to have_link('labore', target: '_self')
14
15
  end
15
16
 
16
17
  it 'should be false if the given link is not on the page' do
17
18
  expect(@session).not_to have_link('monkey')
18
19
  expect(@session).not_to have_link('A link', href: '/nonexistent-href')
19
20
  expect(@session).not_to have_link('A link', href: /nonexistent/)
21
+ expect(@session).not_to have_link('labore', target: '_blank')
20
22
  end
21
23
 
22
24
  it 'should notify if an invalid locator is specified' do
@@ -40,7 +42,7 @@ Capybara::SpecHelper.spec '#has_link?' do
40
42
  it 'should raise an error if an invalid option is passed' do
41
43
  expect do
42
44
  expect(@session).to have_link('labore', invalid: true)
43
- end.to raise_error(ArgumentError, 'Invalid option(s) :invalid, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :href, :alt, :title, :download')
45
+ end.to raise_error(ArgumentError, 'Invalid option(s) :invalid, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :href, :alt, :title, :target, :download')
44
46
  end
45
47
  end
46
48
 
@@ -53,12 +55,14 @@ Capybara::SpecHelper.spec '#has_no_link?' do
53
55
  expect(@session).not_to have_no_link('foo')
54
56
  expect(@session).not_to have_no_link('awesome title')
55
57
  expect(@session).not_to have_no_link('A link', href: '/with_simple_html')
58
+ expect(@session).not_to have_no_link('labore', target: '_self')
56
59
  end
57
60
 
58
61
  it 'should be true if the given link is not on the page' do
59
62
  expect(@session).to have_no_link('monkey')
60
63
  expect(@session).to have_no_link('A link', href: '/nonexistent-href')
61
64
  expect(@session).to have_no_link('A link', href: %r{/nonexistent-href})
65
+ expect(@session).to have_no_link('labore', target: '_blank')
62
66
  end
63
67
 
64
68
  context 'with focused:', requires: [:active_element] do
@@ -8,10 +8,10 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
8
8
  it 'should be false if any of the given locators are on the page' do
9
9
  expect do
10
10
  expect(@session).to have_none_of_selectors(:xpath, '//p', '//a')
11
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
11
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
12
12
  expect do
13
13
  expect(@session).to have_none_of_selectors(:css, 'p a#foo')
14
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
14
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
15
15
  end
16
16
 
17
17
  it 'should be true if none of the given locators are on the page' do
@@ -24,7 +24,7 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
24
24
  expect(@session).to have_none_of_selectors('p a#doesnotexist', 'abbr')
25
25
  expect do
26
26
  expect(@session).to have_none_of_selectors('abbr', 'p a#foo')
27
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
27
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
28
28
  end
29
29
 
30
30
  context 'should respect scopes' do
@@ -32,7 +32,7 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
32
32
  @session.within "//p[@id='first']" do
33
33
  expect do
34
34
  expect(@session).to have_none_of_selectors(".//a[@id='foo']")
35
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
35
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
36
36
  expect(@session).to have_none_of_selectors(".//a[@id='red']")
37
37
  end
38
38
  end
@@ -41,7 +41,7 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
41
41
  el = @session.find "//p[@id='first']"
42
42
  expect do
43
43
  expect(el).to have_none_of_selectors(".//a[@id='foo']")
44
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
44
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
45
45
  expect(el).to have_none_of_selectors(".//a[@id='red']")
46
46
  end
47
47
  end
@@ -50,14 +50,14 @@ Capybara::SpecHelper.spec '#have_none_of_selectors' do
50
50
  it 'should apply the options to all locators' do
51
51
  expect do
52
52
  expect(@session).to have_none_of_selectors('//p//a', text: 'Redirect')
53
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
53
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
54
54
  expect(@session).to have_none_of_selectors('//p', text: 'Doesnotexist')
55
55
  end
56
56
 
57
57
  it 'should discard all matches where the given regexp is matched' do
58
58
  expect do
59
59
  expect(@session).to have_none_of_selectors('//p//a', text: /re[dab]i/i, count: 1)
60
- end.to raise_error ::RSpec::Expectations::ExpectationNotMetError
60
+ end.to raise_error RSpec::Expectations::ExpectationNotMetError
61
61
  expect(@session).to have_none_of_selectors('//p//a', text: /Red$/)
62
62
  end
63
63
  end
@@ -23,6 +23,7 @@ Capybara::SpecHelper.spec '#matches_style?', requires: [:css] do
23
23
  expect(@session.find(:css, '#first').matches_style?(display: /^in/)).to be false
24
24
  end
25
25
 
26
+ # rubocop:disable Capybara/MatchStyle
26
27
  it 'deprecated has_style?' do
27
28
  expect { have_style(display: /^bl/) }.to \
28
29
  output(/have_style is deprecated/).to_stderr
@@ -32,4 +33,5 @@ Capybara::SpecHelper.spec '#matches_style?', requires: [:css] do
32
33
  el.has_style?('display' => /^bl/)
33
34
  expect(Capybara::Helpers).to have_received(:warn)
34
35
  end
36
+ # rubocop:enable Capybara/MatchStyle
35
37
  end
@@ -157,6 +157,12 @@ Capybara::SpecHelper.spec 'node' do
157
157
  expect(@session.find(:css, '#existing_content_editable_child_parent').text).to eq("Some content\nWYSIWYG")
158
158
  end
159
159
  end
160
+
161
+ it 'should submit single text input forms if ended with \n' do
162
+ @session.visit('/form')
163
+ @session.find(:css, '#single_input').set("my entry\n")
164
+ expect(extract_results(@session)['single_input']).to eq('my entry')
165
+ end
160
166
  end
161
167
 
162
168
  describe '#tag_name' do
@@ -651,6 +657,16 @@ Capybara::SpecHelper.spec 'node' do
651
657
  expect(target).to have_text(%r{^HTML5 Dropped string: text/plain drag_html5-#{key}$}m, exact: true)
652
658
  end
653
659
  end
660
+
661
+ it 'should trigger a dragenter event, before the first dragover event' do
662
+ @session.visit('/with_js')
663
+ element = @session.find('//div[@id="drag_html5"]')
664
+ target = @session.find('//div[@id="drop_html5"]')
665
+ element.drag_to(target)
666
+
667
+ # Events are listed in reverse chronological order
668
+ expect(@session).to have_text(/DragOver.*DragEnter/m)
669
+ end
654
670
  end
655
671
  end
656
672
 
@@ -36,7 +36,9 @@ Capybara::SpecHelper.spec '#scroll_to', requires: [:scroll] do
36
36
  it 'can scroll the window to the vertical bottom' do
37
37
  @session.scroll_to :bottom
38
38
  max_scroll = @session.evaluate_script('document.documentElement.scrollHeight - document.documentElement.clientHeight')
39
- expect(@session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')).to eq [0, max_scroll]
39
+ scrolled_location_x, scrolled_location_y = @session.evaluate_script('[window.scrollX || window.pageXOffset, window.scrollY || window.pageYOffset]')
40
+ expect(scrolled_location_x).to be_within(0.5).of(0)
41
+ expect(scrolled_location_y).to be_within(0.5).of(max_scroll)
40
42
  end
41
43
 
42
44
  it 'can scroll the window to the vertical center' do
@@ -29,6 +29,6 @@ Capybara::SpecHelper.spec '#windows', requires: [:windows] do
29
29
  titles = @session.windows.map do |window|
30
30
  @session.within_window(window) { @session.title }
31
31
  end
32
- expect(titles).to match_array(['With Windows', 'Title of the first popup', 'Title of popup two'])
32
+ expect(titles).to match_array(['With Windows', 'Title of the first popup', 'Title of popup two']) # rubocop:disable RSpec/MatchArray
33
33
  end
34
34
  end
@@ -695,6 +695,10 @@ New line after and before textarea tag
695
695
  </p>
696
696
  </form>
697
697
 
698
+ <form id="single_input_form" action="/form" method="post">
699
+ <input type="text" name="form[single_input]" id="single_input"/>
700
+ </form>
701
+
698
702
  <label>Confusion
699
703
  <input type="checkbox" id="confusion_checkbox" class="confusion-checkbox confusion"/>
700
704
  </label>
@@ -19,7 +19,7 @@
19
19
 
20
20
  <p class="para" id="first" data-random="abc\def" style="line-height: 25px;">
21
21
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
22
- tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple" tabindex="1">labore</a>
22
+ tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple" tabindex="1" target="_self">labore</a>
23
23
  et dolore magna aliqua. Ut enim ad minim veniam,
24
24
  quis nostrud exercitation <a href="/foo" id="foo" data-test-id="test-foo">ullamco</a> laboris nisi
25
25
  ut aliquip ex ea commodo consequat.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Capybara
4
- VERSION = '3.38.0'
4
+ VERSION = '3.39.0'
5
5
  end
@@ -5,7 +5,7 @@ require 'spec_helper'
5
5
  # rubocop:disable RSpec/InstanceVariable
6
6
  RSpec.describe Capybara::Selector::CSSBuilder do
7
7
  let :builder do
8
- ::Capybara::Selector::CSSBuilder.new(@css)
8
+ described_class.new(@css)
9
9
  end
10
10
 
11
11
  context 'add_attribute_conditions' do
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
 
5
5
  RSpec.describe Capybara::Selector::CSS::Splitter do
6
6
  let :splitter do
7
- ::Capybara::Selector::CSS::Splitter.new
7
+ described_class.new
8
8
  end
9
9
 
10
10
  context 'split not needed' do
@@ -220,7 +220,7 @@ RSpec.describe Capybara::RackTest::Driver do
220
220
  driver = described_class.new(TestApp)
221
221
 
222
222
  driver.visit('/redirect')
223
- expect(driver.response.header['Location']).to be_nil
223
+ expect(driver.response.headers['Location']).to be_nil
224
224
  expect(driver.current_url).to match %r{/landed$}
225
225
  end
226
226
 
@@ -234,7 +234,7 @@ RSpec.describe Capybara::RackTest::Driver do
234
234
  driver = described_class.new(TestApp, follow_redirects: false)
235
235
 
236
236
  driver.visit('/redirect')
237
- expect(driver.response.header['Location']).to match %r{/redirect_again$}
237
+ expect(driver.response.headers['Location']).to match %r{/redirect_again$}
238
238
  expect(driver.current_url).to match %r{/redirect$}
239
239
  end
240
240
  end
@@ -16,7 +16,7 @@ feature 'if fscenario aliases focused tag then' do
16
16
  end
17
17
 
18
18
  feature 'if xscenario aliases to pending then' do
19
- xscenario "this test should be 'temporarily disabled with xscenario'" do
19
+ xscenario "this test should be 'temporarily disabled with xscenario'" do # rubocop:disable RSpec/PendingWithoutReason
20
20
  end
21
21
  end
22
22
 
@@ -56,6 +56,31 @@ RSpec.describe 'Capybara RSpec Matchers', type: :feature do
56
56
  end
57
57
  end
58
58
 
59
+ context 'with a filter block' do
60
+ it 'applies the filter' do
61
+ visit('/with_html')
62
+ expect(page).to have_selector(:css, 'input#test_field')
63
+
64
+ expect(page).to have_selector(:css, 'input', count: 1) { |input| input.value == 'monkey' }
65
+ expect(page).to have_selector(:css, 'input', count: 1) do |input|
66
+ input.value == 'monkey'
67
+ end
68
+ expect(page).to have_no_selector(:css, 'input#test_field') { |input| input.value == 'not a monkey' }
69
+ expect(page).to have_no_selector(:css, 'input#test_field') do |input|
70
+ input.value == 'not a monkey'
71
+ end
72
+
73
+ expect(page).not_to have_selector(:css, 'input#test_field') { |input| input.value == 'not a monkey' }
74
+ expect(page).not_to have_selector(:css, 'input#test_field') do |input|
75
+ input.value == 'not a monkey'
76
+ end
77
+ expect(page).not_to have_no_selector(:css, 'input', count: 1) { |input| input.value == 'monkey' }
78
+ expect(page).not_to have_no_selector(:css, 'input#test_field', count: 1) do |input|
79
+ input.value == 'monkey'
80
+ end
81
+ end
82
+ end
83
+
59
84
  def error_msg_for(&block)
60
85
  expect(&block).to(raise_error { |e| return e.message })
61
86
  end
@@ -27,7 +27,7 @@ Capybara.register_driver :sauce_chrome do |app|
27
27
 
28
28
  Capybara::Selenium::Driver.new(app,
29
29
  browser: :remote, url: url,
30
- desired_capabilities: capabilities,
30
+ capabilities: capabilities,
31
31
  options: Selenium::WebDriver::Chrome::Options.new(args: ['']))
32
32
  end
33
33
 
@@ -10,8 +10,8 @@ CHROME_DRIVER = :selenium_chrome
10
10
 
11
11
  Selenium::WebDriver::Chrome.path = '/usr/bin/google-chrome-beta' if ENV.fetch('CI', nil) && ENV.fetch('CHROME_BETA', nil)
12
12
 
13
- browser_options = ::Selenium::WebDriver::Chrome::Options.new
14
- browser_options.headless! if ENV['HEADLESS']
13
+ browser_options = Selenium::WebDriver::Chrome::Options.new
14
+ browser_options.add_argument('--headless') if ENV['HEADLESS']
15
15
 
16
16
  # Chromedriver 77 requires setting this for headless mode on linux
17
17
  # Different versions of Chrome/selenium-webdriver require setting differently - jus set them all
@@ -87,6 +87,9 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_DRIVER.to_s, capybar
87
87
  pending "Chrome headless doesn't support maximize" if ENV['HEADLESS']
88
88
  when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
89
89
  pending "Selenium doesn't currently support getting visible text for shadow root elements"
90
+ when /Capybara::Session selenium_chrome node #shadow_root/
91
+ skip 'Not supported with this Selenium version' if selenium_lt?('4.1', @session)
92
+ skip 'Not supported with this chromedriver version' if chromedriver_lt?('96.0', @session)
90
93
  end
91
94
  end
92
95
 
@@ -201,8 +204,4 @@ RSpec.describe 'Capybara::Session with chrome' do
201
204
  end.not_to raise_error
202
205
  end
203
206
  end
204
-
205
- def chromedriver_version
206
- Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
207
- end
208
207
  end
@@ -39,11 +39,10 @@ Capybara.register_driver :selenium_chrome_remote do |app|
39
39
  ensure_selenium_running!
40
40
 
41
41
  url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
42
- browser_options = ::Selenium::WebDriver::Chrome::Options.new
42
+ browser_options = Selenium::WebDriver::Chrome::Options.new
43
43
 
44
44
  Capybara::Selenium::Driver.new app,
45
45
  browser: :remote,
46
- desired_capabilities: :chrome,
47
46
  options: browser_options,
48
47
  url: url
49
48
  end
@@ -62,8 +61,11 @@ Capybara::SpecHelper.run_specs TestSessions::Chrome, CHROME_REMOTE_DRIVER.to_s,
62
61
  'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once for each set of files uploaded',
63
62
  'Capybara::Session selenium_chrome_remote #attach_file with multipart form should fire change once when uploading multiple files from empty'
64
63
  pending "Selenium with Remote Chrome doesn't support multiple file upload" unless selenium_gte?(3.14)
65
- when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
64
+ when /Capybara::Session selenium_chrome_remote node #shadow_root should get visible text/
66
65
  pending "Selenium doesn't currently support getting visible text for shadow root elements"
66
+ when /Capybara::Session selenium_chrome_remote node #shadow_root/
67
+ skip 'Not supported with this Selenium version' if selenium_lt?('4.1', @session)
68
+ skip 'Not supported with this chromedriver version' if chromedriver_lt?('96.0', @session)
67
69
  end
68
70
  end
69
71
 
@@ -96,8 +98,4 @@ RSpec.describe 'Capybara::Session with remote Chrome' do
96
98
  end.not_to raise_error
97
99
  end
98
100
  end
99
-
100
- def chromedriver_version
101
- Gem::Version.new(session.driver.browser.capabilities['chrome']['chromedriverVersion'].split[0])
102
- end
103
101
  end
@@ -10,15 +10,17 @@ require 'rspec/shared_spec_matchers'
10
10
  # Selenium::WebDriver::Edge::Service.driver_path = '/usr/local/bin/msedgedriver'
11
11
  # end
12
12
 
13
- if ::Selenium::WebDriver::Platform.mac?
14
- Selenium::WebDriver::EdgeChrome.path = '/Applications/Microsoft Edge Dev.app/Contents/MacOS/Microsoft Edge Dev'
13
+ if Selenium::WebDriver::Platform.mac?
14
+ Selenium::WebDriver::Edge.path = '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge'
15
15
  end
16
16
 
17
17
  Capybara.register_driver :selenium_edge do |app|
18
18
  # ::Selenium::WebDriver.logger.level = "debug"
19
19
  # If we don't create an options object the path set above won't be used
20
- browser_options = ::Selenium::WebDriver::EdgeChrome::Options.new
21
- Capybara::Selenium::Driver.new(app, browser: :edge_chrome, options: browser_options).tap do |driver|
20
+ browser_options = Selenium::WebDriver::Edge::Options.new
21
+ browser_options.add_argument('--headless') if ENV['HEADLESS']
22
+
23
+ Capybara::Selenium::Driver.new(app, browser: :edge, options: browser_options).tap do |driver|
22
24
  driver.browser
23
25
  driver.download_path = Capybara.save_path
24
26
  end
@@ -30,14 +32,16 @@ end
30
32
 
31
33
  skipped_tests = %i[response_headers status_code trigger]
32
34
 
33
- Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::EdgeChrome) if ENV['CI']
35
+ Capybara::SpecHelper.log_selenium_driver_version(Selenium::WebDriver::Edge) if ENV['CI']
34
36
 
35
37
  Capybara::SpecHelper.run_specs TestSessions::SeleniumEdge, 'selenium', capybara_skip: skipped_tests do |example|
36
38
  case example.metadata[:full_description]
37
39
  when 'Capybara::Session selenium #attach_file with a block can upload by clicking the file input'
38
- pending "EdgeChrome doesn't allow clicking on file inputs"
39
- when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
40
+ pending "Edge doesn't allow clicking on file inputs"
41
+ when /Capybara::Session selenium node #shadow_root should get visible text/
40
42
  pending "Selenium doesn't currently support getting visible text for shadow root elements"
43
+ when /Capybara::Session selenium Capybara::Window#maximize/
44
+ pending "Edge headless doesn't support maximize" if ENV['HEADLESS']
41
45
  end
42
46
  end
43
47
 
@@ -6,7 +6,7 @@ require 'shared_selenium_session'
6
6
  require 'shared_selenium_node'
7
7
  require 'rspec/shared_spec_matchers'
8
8
 
9
- browser_options = ::Selenium::WebDriver::Firefox::Options.new
9
+ browser_options = Selenium::WebDriver::Firefox::Options.new
10
10
  browser_options.headless! if ENV['HEADLESS']
11
11
  # browser_options.add_option("log", {"level": "trace"})
12
12
 
@@ -62,7 +62,7 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
62
62
  when 'Capybara::Session selenium #accept_confirm should work with nested modals'
63
63
  skip 'Broken in 63 <= FF < 69 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session) && firefox_lt?(69, @session)
64
64
  skip 'Hangs in 69 <= FF < 71 - Dont know what issue for this - previous issue was closed as fixed but it is not' if firefox_gte?(69, @session) && firefox_lt?(71, @session)
65
- skip 'Broken again intermittently in FF 71 - jus skip it'
65
+ skip 'Broken again intermittently in FF 71 - jus skip it' if firefox_lt?(109, @session) # don't really know when it was fixed
66
66
  when 'Capybara::Session selenium #click_link can download a file'
67
67
  skip 'Need to figure out testing of file downloading on windows platform' if Gem.win_platform?
68
68
  when 'Capybara::Session selenium #reset_session! removes ALL cookies'
@@ -71,17 +71,23 @@ Capybara::SpecHelper.run_specs TestSessions::SeleniumFirefox, 'selenium', capyba
71
71
  pending "Firefox < 62 doesn't support a DataTransfer constructor" if firefox_lt?(62.0, @session)
72
72
  when 'Capybara::Session selenium #accept_alert should handle the alert if the page changes',
73
73
  'Capybara::Session selenium #accept_alert with an asynchronous alert should accept the alert'
74
- skip 'No clue what Firefox is doing here - works fine on MacOS locally'
74
+ skip 'No clue what Firefox is doing here - works fine on MacOS locally' if firefox_lt?(109, @session) # don't really know when it was fixed
75
75
  when 'Capybara::Session selenium node #shadow_root should find elements inside the shadow dom using CSS',
76
76
  'Capybara::Session selenium node #shadow_root should find nested shadow roots',
77
77
  'Capybara::Session selenium node #shadow_root should click on elements',
78
78
  'Capybara::Session selenium node #shadow_root should use convenience methods once moved to a descendant of the shadow root',
79
+ 'Capybara::Session selenium node #shadow_root should produce error messages when failing',
79
80
  'Capybara::Session with firefox with selenium driver #evaluate_script returns a shadow root'
80
81
  pending "Firefox doesn't yet have full W3C shadow root support"
81
82
  when 'Capybara::Session selenium #fill_in should handle carriage returns with line feeds in a textarea correctly'
82
83
  pending 'Not sure what firefox is doing here'
83
- when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
84
+ when /Capybara::Session selenium node #shadow_root should get visible text/
84
85
  pending "Selenium doesn't currently support getting visible text for shadow root elements"
86
+ when /Capybara::Session selenium node #shadow_root/
87
+ skip 'Not supported with this Selenium version' if selenium_lt?('4.1', @session)
88
+ skip 'Not supported with this geckodriver version' if geckodriver_lt?('0.31.0', @session)
89
+ when /Capybara::Session selenium node #set should submit single text input forms if ended with \\n/
90
+ pending 'Firefox/geckodriver doesn\'t submit with values ending in \n'
85
91
  end
86
92
  end
87
93
 
@@ -35,11 +35,10 @@ Capybara.register_driver :selenium_firefox_remote do |app|
35
35
  ensure_selenium_running!
36
36
 
37
37
  url = "http://#{selenium_host}:#{selenium_port}/wd/hub"
38
- browser_options = ::Selenium::WebDriver::Firefox::Options.new
38
+ browser_options = Selenium::WebDriver::Firefox::Options.new
39
39
 
40
40
  Capybara::Selenium::Driver.new app,
41
41
  browser: :remote,
42
- desired_capabilities: :firefox,
43
42
  options: browser_options,
44
43
  url: url
45
44
  end
@@ -65,8 +64,22 @@ Capybara::SpecHelper.run_specs TestSessions::RemoteFirefox, FIREFOX_REMOTE_DRIVE
65
64
  when /#accept_confirm should work with nested modals$/
66
65
  # skip because this is timing based and hence flaky when set to pending
67
66
  skip 'Broken in FF 63 - https://bugzilla.mozilla.org/show_bug.cgi?id=1487358' if firefox_gte?(63, @session)
68
- when /Capybara::Session selenium_chrome node #shadow_root should get visible text/
67
+ when 'Capybara::Session selenium_firefox_remote #fill_in should handle carriage returns with line feeds in a textarea correctly'
68
+ pending 'Not sure what firefox is doing here'
69
+ when 'Capybara::Session selenium_firefox_remote node #shadow_root should find elements inside the shadow dom using CSS',
70
+ 'Capybara::Session selenium_firefox_remote node #shadow_root should find nested shadow roots',
71
+ 'Capybara::Session selenium_firefox_remote node #shadow_root should click on elements',
72
+ 'Capybara::Session selenium_firefox_remote node #shadow_root should use convenience methods once moved to a descendant of the shadow root',
73
+ 'Capybara::Session selenium_firefox_remote node #shadow_root should produce error messages when failing',
74
+ 'Capybara::Session with firefox with selenium driver #evaluate_script returns a shadow root'
75
+ pending "Firefox doesn't yet have full W3C shadow root support"
76
+ when /Capybara::Session selenium_firefox_remote node #shadow_root should get visible text/
69
77
  pending "Selenium doesn't currently support getting visible text for shadow root elements"
78
+ when /Capybara::Session selenium_firefox_remote node #shadow_root/
79
+ skip 'Not supported with this Selenium version' if selenium_lt?('4.1', @session)
80
+ skip 'Not supported with this geckodriver version' if geckodriver_lt?('0.31.0', @session)
81
+ when /Capybara::Session selenium_firefox_remote node #set should submit single text input forms if ended with \\n/
82
+ pending 'Firefox/geckodriver doesn\'t submit with values ending in \n'
70
83
  end
71
84
  end
72
85
 
@@ -28,7 +28,7 @@ end
28
28
 
29
29
  Capybara.register_driver :selenium_ie do |app|
30
30
  # ::Selenium::WebDriver.logger.level = "debug"
31
- options = ::Selenium::WebDriver::IE::Options.new
31
+ options = Selenium::WebDriver::IE::Options.new
32
32
  # options.require_window_focus = true
33
33
  # options.add_option("log", {"level": "trace"})
34
34
 
@@ -14,7 +14,7 @@ SAFARI_DRIVER = :selenium_safari
14
14
  # ::Selenium::WebDriver::Safari
15
15
  # end.driver_path = '/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
16
16
 
17
- browser_options = ::Selenium::WebDriver::Safari::Options.new
17
+ browser_options = Selenium::WebDriver::Safari::Options.new
18
18
  # browser_options.headless! if ENV['HEADLESS']
19
19
 
20
20
  Capybara.register_driver :selenium_safari do |app|
data/spec/server_spec.rb CHANGED
@@ -95,7 +95,7 @@ RSpec.describe Capybara::Server do
95
95
  it 'should return its #base_url' do
96
96
  app = proc { |_env| [200, {}, ['Hello Server!']] }
97
97
  server = described_class.new(app).boot
98
- uri = ::Addressable::URI.parse(server.base_url)
98
+ uri = Addressable::URI.parse(server.base_url)
99
99
  expect(uri.to_hash).to include(scheme: 'http', host: server.host, port: server.port)
100
100
  end
101
101
 
@@ -136,7 +136,7 @@ RSpec.describe Capybara::Server do
136
136
  end
137
137
 
138
138
  expect(res.body).to include('Hello SSL Server!')
139
- uri = ::Addressable::URI.parse(server.base_url)
139
+ uri = Addressable::URI.parse(server.base_url)
140
140
  expect(uri.to_hash).to include(scheme: 'https', host: server.host, port: server.port)
141
141
  ensure
142
142
  Capybara.server = :default