capybara 3.38.0 → 3.39.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +27 -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/logger_suppressor.rb +2 -2
  17. data/lib/capybara/selenium/node.rb +8 -10
  18. data/lib/capybara/selenium/nodes/chrome_node.rb +5 -1
  19. data/lib/capybara/selenium/nodes/edge_node.rb +24 -2
  20. data/lib/capybara/selenium/patches/action_pauser.rb +3 -3
  21. data/lib/capybara/selenium/patches/atoms.rb +1 -1
  22. data/lib/capybara/selenium/patches/pause_duration_fix.rb +1 -1
  23. data/lib/capybara/server/animation_disabler.rb +2 -3
  24. data/lib/capybara/spec/public/test.js +4 -0
  25. data/lib/capybara/spec/session/all_spec.rb +1 -1
  26. data/lib/capybara/spec/session/click_link_spec.rb +11 -0
  27. data/lib/capybara/spec/session/find_link_spec.rb +10 -0
  28. data/lib/capybara/spec/session/find_spec.rb +1 -1
  29. data/lib/capybara/spec/session/first_spec.rb +1 -1
  30. data/lib/capybara/spec/session/frame/within_frame_spec.rb +2 -0
  31. data/lib/capybara/spec/session/has_all_selectors_spec.rb +5 -5
  32. data/lib/capybara/spec/session/has_any_selectors_spec.rb +2 -2
  33. data/lib/capybara/spec/session/has_current_path_spec.rb +1 -1
  34. data/lib/capybara/spec/session/has_link_spec.rb +5 -1
  35. data/lib/capybara/spec/session/has_none_selectors_spec.rb +7 -7
  36. data/lib/capybara/spec/session/matches_style_spec.rb +2 -0
  37. data/lib/capybara/spec/session/node_spec.rb +16 -0
  38. data/lib/capybara/spec/session/scroll_spec.rb +3 -1
  39. data/lib/capybara/spec/session/window/windows_spec.rb +1 -1
  40. data/lib/capybara/spec/views/form.erb +4 -0
  41. data/lib/capybara/spec/views/with_html.erb +1 -1
  42. data/lib/capybara/version.rb +1 -1
  43. data/spec/css_builder_spec.rb +1 -1
  44. data/spec/css_splitter_spec.rb +1 -1
  45. data/spec/rack_test_spec.rb +2 -2
  46. data/spec/rspec/scenarios_spec.rb +1 -1
  47. data/spec/rspec_matchers_spec.rb +25 -0
  48. data/spec/sauce_spec_chrome.rb +1 -1
  49. data/spec/selenium_spec_chrome.rb +5 -6
  50. data/spec/selenium_spec_chrome_remote.rb +5 -7
  51. data/spec/selenium_spec_edge.rb +11 -7
  52. data/spec/selenium_spec_firefox.rb +10 -4
  53. data/spec/selenium_spec_firefox_remote.rb +16 -3
  54. data/spec/selenium_spec_ie.rb +1 -1
  55. data/spec/selenium_spec_safari.rb +1 -1
  56. data/spec/server_spec.rb +2 -2
  57. data/spec/shared_selenium_session.rb +2 -1
  58. data/spec/spec_helper.rb +33 -0
  59. data/spec/whitespace_normalizer_spec.rb +54 -0
  60. data/spec/xpath_builder_spec.rb +1 -1
  61. metadata +4 -2
@@ -131,6 +131,17 @@ Capybara::SpecHelper.spec '#click_link' do
131
131
  end
132
132
  end
133
133
 
134
+ context 'with :target option given' do
135
+ it 'should find links with valid target' do
136
+ @session.click_link('labore', target: '_self')
137
+ expect(@session).to have_content('Bar')
138
+ end
139
+
140
+ it "should raise error if link wasn't found" do
141
+ expect { @session.click_link('labore', target: '_blank') }.to raise_error(Capybara::ElementNotFound, /Unable to find link "labore"/)
142
+ end
143
+ end
144
+
134
145
  it 'should follow relative links' do
135
146
  @session.visit('/')
136
147
  @session.click_link('Relative')
@@ -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.1'
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|