capybara 2.14.4 → 2.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +17 -0
  3. data/README.md +14 -22
  4. data/lib/capybara.rb +16 -4
  5. data/lib/capybara/config.rb +12 -2
  6. data/lib/capybara/driver/base.rb +4 -0
  7. data/lib/capybara/node/finders.rb +79 -16
  8. data/lib/capybara/queries/ancestor_query.rb +25 -0
  9. data/lib/capybara/queries/selector_query.rb +4 -1
  10. data/lib/capybara/queries/sibling_query.rb +25 -0
  11. data/lib/capybara/rack_test/browser.rb +5 -0
  12. data/lib/capybara/rack_test/driver.rb +5 -1
  13. data/lib/capybara/rack_test/form.rb +1 -3
  14. data/lib/capybara/rack_test/node.rb +1 -1
  15. data/lib/capybara/rspec/compound.rb +95 -0
  16. data/lib/capybara/rspec/matchers.rb +4 -1
  17. data/lib/capybara/selector.rb +1 -0
  18. data/lib/capybara/selector/filter.rb +13 -41
  19. data/lib/capybara/selector/filter_set.rb +12 -5
  20. data/lib/capybara/selector/filters/base.rb +33 -0
  21. data/lib/capybara/selector/filters/expression_filter.rb +40 -0
  22. data/lib/capybara/selector/filters/node_filter.rb +27 -0
  23. data/lib/capybara/selector/selector.rb +4 -4
  24. data/lib/capybara/selenium/driver.rb +12 -2
  25. data/lib/capybara/selenium/node.rb +70 -55
  26. data/lib/capybara/session.rb +65 -41
  27. data/lib/capybara/spec/session/ancestor_spec.rb +85 -0
  28. data/lib/capybara/spec/session/attach_file_spec.rb +1 -1
  29. data/lib/capybara/spec/session/check_spec.rb +4 -4
  30. data/lib/capybara/spec/session/choose_spec.rb +2 -2
  31. data/lib/capybara/spec/session/click_button_spec.rb +1 -1
  32. data/lib/capybara/spec/session/click_link_or_button_spec.rb +3 -3
  33. data/lib/capybara/spec/session/click_link_spec.rb +1 -1
  34. data/lib/capybara/spec/session/fill_in_spec.rb +2 -2
  35. data/lib/capybara/spec/session/find_spec.rb +1 -1
  36. data/lib/capybara/spec/session/refresh_spec.rb +28 -0
  37. data/lib/capybara/spec/session/select_spec.rb +2 -2
  38. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  39. data/lib/capybara/spec/session/uncheck_spec.rb +2 -2
  40. data/lib/capybara/spec/session/unselect_spec.rb +2 -2
  41. data/lib/capybara/spec/session/window/become_closed_spec.rb +3 -3
  42. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +11 -9
  43. data/lib/capybara/spec/session/window/within_window_spec.rb +27 -2
  44. data/lib/capybara/spec/test_app.rb +3 -1
  45. data/lib/capybara/spec/views/with_html.erb +27 -1
  46. data/lib/capybara/spec/views/with_windows.erb +4 -0
  47. data/lib/capybara/version.rb +1 -1
  48. data/spec/capybara_spec.rb +9 -1
  49. data/spec/minitest_spec_spec.rb +1 -1
  50. data/spec/rspec/shared_spec_matchers.rb +146 -42
  51. data/spec/selenium_spec_chrome.rb +12 -16
  52. data/spec/selenium_spec_marionette.rb +2 -0
  53. data/spec/shared_selenium_session.rb +2 -0
  54. metadata +14 -6
  55. data/lib/capybara/selector/expression_filter.rb +0 -40
@@ -58,7 +58,7 @@ module Capybara
58
58
  ]
59
59
  SESSION_METHODS = [
60
60
  :body, :html, :source, :current_url, :current_host, :current_path,
61
- :execute_script, :evaluate_script, :visit, :go_back, :go_forward,
61
+ :execute_script, :evaluate_script, :visit, :refresh, :go_back, :go_forward,
62
62
  :within, :within_element, :within_fieldset, :within_table, :within_frame, :switch_to_frame,
63
63
  :current_window, :windows, :open_new_window, :switch_to_window, :within_window, :window_opened_by,
64
64
  :save_page, :save_and_open_page, :save_screenshot,
@@ -269,6 +269,15 @@ module Capybara
269
269
  driver.visit(visit_uri.to_s)
270
270
  end
271
271
 
272
+ ##
273
+ #
274
+ # Refresh the page
275
+ #
276
+ def refresh
277
+ raise_server_error!
278
+ driver.refresh
279
+ end
280
+
272
281
  ##
273
282
  #
274
283
  # Move back a single entry in the browser's history.
@@ -472,14 +481,14 @@ module Capybara
472
481
  # @raise [Capybara::WindowError] if no window matches given block
473
482
  # @overload switch_to_window(window)
474
483
  # @param window [Capybara::Window] window that should be switched to
475
- # @raise [Capybara::Driver::Base#no_such_window_error] if unexistent (e.g. closed) window was passed
484
+ # @raise [Capybara::Driver::Base#no_such_window_error] if non-existent (e.g. closed) window was passed
476
485
  #
477
486
  # @return [Capybara::Window] window that has been switched to
478
- # @raise [Capybara::ScopeError] if this method is invoked inside `within`,
479
- # `within_frame` or `within_window` methods
487
+ # @raise [Capybara::ScopeError] if this method is invoked inside `within` or
488
+ # `within_frame` methods
480
489
  # @raise [ArgumentError] if both or neither arguments were provided
481
490
  #
482
- def switch_to_window(window = nil, options= {})
491
+ def switch_to_window(window = nil, options= {}, &window_locator)
483
492
  options, window = window, nil if window.is_a? Hash
484
493
 
485
494
  block_given = block_given?
@@ -487,34 +496,12 @@ module Capybara
487
496
  raise ArgumentError, "`switch_to_window` can take either a block or a window, not both"
488
497
  elsif !window && !block_given
489
498
  raise ArgumentError, "`switch_to_window`: either window or block should be provided"
490
- elsif scopes.size > 1
499
+ elsif !scopes.last.nil?
491
500
  raise Capybara::ScopeError, "`switch_to_window` is not supposed to be invoked from "\
492
- "`within`'s, `within_frame`'s' or `within_window`'s' block."
501
+ "`within` or `within_frame` blocks."
493
502
  end
494
503
 
495
- if window
496
- driver.switch_to_window(window.handle)
497
- window
498
- else
499
- wait_time = Capybara::Queries::BaseQuery.wait(options, config.default_max_wait_time)
500
- document.synchronize(wait_time, errors: [Capybara::WindowError]) do
501
- original_window_handle = driver.current_window_handle
502
- begin
503
- driver.window_handles.each do |handle|
504
- driver.switch_to_window handle
505
- if yield
506
- return Window.new(self, handle)
507
- end
508
- end
509
- rescue => e
510
- driver.switch_to_window(original_window_handle)
511
- raise e
512
- else
513
- driver.switch_to_window(original_window_handle)
514
- raise Capybara::WindowError, "Could not find a window matching block/lambda"
515
- end
516
- end
517
- end
504
+ _switch_to_window(window, options, &window_locator)
518
505
  end
519
506
 
520
507
  ##
@@ -538,30 +525,35 @@ module Capybara
538
525
  # @deprecated Pass window or lambda instead
539
526
  # @param [String] handle, name, url or title of the window
540
527
  #
541
- # @raise [Capybara::ScopeError] if this method is invoked inside `within`,
542
- # `within_frame` or `within_window` methods
528
+ # @raise [Capybara::ScopeError] if this method is invoked inside `within_frame` method
543
529
  # @return value returned by the block
544
530
  #
545
531
  def within_window(window_or_handle)
546
532
  if window_or_handle.instance_of?(Capybara::Window)
547
533
  original = current_window
548
- switch_to_window(window_or_handle) unless original == window_or_handle
549
534
  scopes << nil
550
535
  begin
551
- yield
536
+ _switch_to_window(window_or_handle) unless original == window_or_handle
537
+ begin
538
+ yield
539
+ ensure
540
+ _switch_to_window(original) unless original == window_or_handle
541
+ end
552
542
  ensure
553
- @scopes.pop
554
- switch_to_window(original) unless original == window_or_handle
543
+ scopes.pop
555
544
  end
556
545
  elsif window_or_handle.is_a?(Proc)
557
546
  original = current_window
558
- switch_to_window { window_or_handle.call }
559
547
  scopes << nil
560
548
  begin
561
- yield
549
+ _switch_to_window { window_or_handle.call }
550
+ begin
551
+ yield
552
+ ensure
553
+ _switch_to_window(original)
554
+ end
562
555
  ensure
563
- @scopes.pop
564
- switch_to_window(original)
556
+ scopes.pop
565
557
  end
566
558
  else
567
559
  offending_line = caller.first
@@ -572,7 +564,7 @@ module Capybara
572
564
  scopes << nil
573
565
  driver.within_window(window_or_handle) { yield }
574
566
  ensure
575
- @scopes.pop
567
+ scopes.pop
576
568
  end
577
569
  end
578
570
  end
@@ -919,5 +911,37 @@ module Capybara
919
911
  end
920
912
  end
921
913
  end
914
+
915
+ def _switch_to_window(window = nil, options= {})
916
+ options, window = window, nil if window.is_a? Hash
917
+
918
+ raise Capybara::ScopeError, "Window cannot be switched inside a `within_frame` block" if scopes.include?(:frame)
919
+ raise Capybara::ScopeError, "Window cannot be switch inside a `within` block" unless scopes.last.nil?
920
+
921
+ if window
922
+ driver.switch_to_window(window.handle)
923
+ window
924
+ else
925
+ wait_time = Capybara::Queries::BaseQuery.wait(options, config.default_max_wait_time)
926
+ document.synchronize(wait_time, errors: [Capybara::WindowError]) do
927
+ original_window_handle = driver.current_window_handle
928
+ begin
929
+ driver.window_handles.each do |handle|
930
+ driver.switch_to_window handle
931
+ if yield
932
+ return Window.new(self, handle)
933
+ end
934
+ end
935
+ rescue => e
936
+ driver.switch_to_window(original_window_handle)
937
+ raise e
938
+ else
939
+ driver.switch_to_window(original_window_handle)
940
+ raise Capybara::WindowError, "Could not find a window matching block/lambda"
941
+ end
942
+ end
943
+ end
944
+ end
945
+
922
946
  end
923
947
  end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+ Capybara::SpecHelper.spec '#ancestor' do
3
+ before do
4
+ @session.visit('/with_html')
5
+ end
6
+
7
+ after do
8
+ Capybara::Selector.remove(:monkey)
9
+ end
10
+
11
+ it "should find the ancestor element using the given locator" do
12
+ el = @session.find(:css, '#first_image')
13
+ expect(el.ancestor('//p')).to have_text('Lorem ipsum dolor')
14
+ expect(el.ancestor("//a")[:'aria-label']).to eq('Go to simple')
15
+ end
16
+
17
+ it "should find the ancestor element using the given locator and options" do
18
+ el = @session.find(:css, '#child')
19
+ expect(el.ancestor('//div', text: 'Ancestor Ancestor Ancestor')[:id]).to eq('ancestor3')
20
+ end
21
+
22
+ it "should raise an error if there are multiple matches" do
23
+ el = @session.find(:css, '#child')
24
+ expect { el.ancestor('//div') }.to raise_error(Capybara::Ambiguous)
25
+ expect { el.ancestor('//div', text: 'Ancestor') }.to raise_error(Capybara::Ambiguous)
26
+ end
27
+
28
+ context "with css selectors" do
29
+ it "should find the first element using the given locator" do
30
+ el = @session.find(:css, '#first_image')
31
+ expect(el.ancestor(:css, 'p')).to have_text('Lorem ipsum dolor')
32
+ expect(el.ancestor(:css, 'a')[:'aria-label']).to eq('Go to simple')
33
+ end
34
+
35
+ it "should support pseudo selectors" do
36
+ el = @session.find(:css, '#button_img')
37
+ expect(el.ancestor(:css, 'button:disabled')[:id]).to eq('ancestor_button')
38
+ end
39
+ end
40
+
41
+ context "with xpath selectors" do
42
+ it "should find the first element using the given locator" do
43
+ el = @session.find(:css, '#first_image')
44
+ expect(el.ancestor(:xpath, '//p')).to have_text('Lorem ipsum dolor')
45
+ expect(el.ancestor(:xpath, "//a")[:'aria-label']).to eq('Go to simple')
46
+ end
47
+ end
48
+
49
+ context "with custom selector" do
50
+ it "should use the custom selector" do
51
+ Capybara.add_selector(:level) do
52
+ xpath { |num| ".//*[@id='ancestor#{num}']" }
53
+ end
54
+ el = @session.find(:css, '#child')
55
+ expect(el.ancestor(:level, 1).text).to eq('Ancestor Child')
56
+ expect(el.ancestor(:level, 3).text).to eq('Ancestor Ancestor Ancestor Child')
57
+ end
58
+ end
59
+
60
+
61
+ it "should raise ElementNotFound with a useful default message if nothing was found" do
62
+ el = @session.find(:css, '#child')
63
+ expect do
64
+ el.ancestor(:xpath, '//div[@id="nosuchthing"]')
65
+ end.to raise_error(Capybara::ElementNotFound, "Unable to find xpath \"//div[@id=\\\"nosuchthing\\\"]\" that is an ancestor of visible css \"#child\"")
66
+ end
67
+
68
+
69
+
70
+ context "within a scope" do
71
+ it "should limit the ancestors to inside the scope" do
72
+ @session.within(:css, '#ancestor2') do
73
+ el = @session.find(:css, '#child')
74
+ expect(el.ancestor(:css,'div', text: 'Ancestor')[:id]).to eq('ancestor1')
75
+ end
76
+ end
77
+ end
78
+
79
+ it "should raise if selector type is unknown" do
80
+ el = @session.find(:css, '#child')
81
+ expect do
82
+ el.ancestor(:unknown, '//h1')
83
+ end.to raise_error(ArgumentError)
84
+ end
85
+ end
@@ -81,7 +81,7 @@ Capybara::SpecHelper.spec "#attach_file" do
81
81
 
82
82
  context "with a locator that doesn't exist" do
83
83
  it "should raise an error" do
84
- msg = "Unable to find file field \"does not exist\""
84
+ msg = "Unable to find visible file field \"does not exist\" that is not disabled"
85
85
  expect do
86
86
  @session.attach_file('does not exist', @test_file_path)
87
87
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -69,7 +69,7 @@ Capybara::SpecHelper.spec "#check" do
69
69
 
70
70
  context "with a locator that doesn't exist" do
71
71
  it "should raise an error" do
72
- msg = "Unable to find checkbox \"does not exist\""
72
+ msg = "Unable to find visible checkbox \"does not exist\" that is not disabled"
73
73
  expect do
74
74
  @session.check('does not exist')
75
75
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -142,11 +142,11 @@ Capybara::SpecHelper.spec "#check" do
142
142
  end
143
143
 
144
144
  it "should raise original error when no label available" do
145
- expect { @session.check('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound, 'Unable to find checkbox "form_cars_ariel"')
145
+ expect { @session.check('form_cars_ariel') }.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_ariel" that is not disabled')
146
146
  end
147
147
 
148
148
  it "should raise error if not allowed to click label" do
149
- expect{@session.check('form_cars_mclaren', allow_label_click: false)}.to raise_error(Capybara::ElementNotFound, 'Unable to find checkbox "form_cars_mclaren"')
149
+ expect{@session.check('form_cars_mclaren', allow_label_click: false)}.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_mclaren" that is not disabled')
150
150
  end
151
151
  end
152
152
 
@@ -158,7 +158,7 @@ Capybara::SpecHelper.spec "#check" do
158
158
  end
159
159
 
160
160
  it "should raise error if checkbox not visible" do
161
- expect{@session.check('form_cars_mclaren')}.to raise_error(Capybara::ElementNotFound, 'Unable to find checkbox "form_cars_mclaren"')
161
+ expect{@session.check('form_cars_mclaren')}.to raise_error(Capybara::ElementNotFound, 'Unable to find visible checkbox "form_cars_mclaren" that is not disabled')
162
162
  end
163
163
 
164
164
  context "with allow_label_click == true" do
@@ -24,7 +24,7 @@ Capybara::SpecHelper.spec "#choose" do
24
24
 
25
25
  context "with a locator that doesn't exist" do
26
26
  it "should raise an error" do
27
- msg = "Unable to find radio button \"does not exist\""
27
+ msg = "Unable to find visible radio button \"does not exist\" that is not disabled"
28
28
  expect do
29
29
  @session.choose('does not exist')
30
30
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -82,7 +82,7 @@ Capybara::SpecHelper.spec "#choose" do
82
82
  end
83
83
 
84
84
  it "should raise error if not allowed to click label" do
85
- expect{@session.choose("party_democrat", allow_label_click: false)}.to raise_error(Capybara::ElementNotFound, 'Unable to find radio button "party_democrat"')
85
+ expect{@session.choose("party_democrat", allow_label_click: false)}.to raise_error(Capybara::ElementNotFound, 'Unable to find visible radio button "party_democrat" that is not disabled')
86
86
  end
87
87
  end
88
88
  end
@@ -353,7 +353,7 @@ Capybara::SpecHelper.spec '#click_button' do
353
353
 
354
354
  context "with a locator that doesn't exist" do
355
355
  it "should raise an error" do
356
- msg = "Unable to find button \"does not exist\""
356
+ msg = "Unable to find visible button \"does not exist\""
357
357
  expect do
358
358
  @session.click_button('does not exist')
359
359
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -54,7 +54,7 @@ Capybara::SpecHelper.spec '#click_link_or_button' do
54
54
  context "when `false`" do
55
55
  it "does not click on link which matches approximately" do
56
56
  @session.visit('/with_html')
57
- msg = "Unable to find link or button \"abore\""
57
+ msg = "Unable to find visible link or button \"abore\""
58
58
  expect do
59
59
  @session.click_link_or_button('abore', exact: true)
60
60
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -62,7 +62,7 @@ Capybara::SpecHelper.spec '#click_link_or_button' do
62
62
 
63
63
  it "does not click on approximately matching button" do
64
64
  @session.visit('/form')
65
- msg = "Unable to find link or button \"awe\""
65
+ msg = "Unable to find visible link or button \"awe\""
66
66
 
67
67
  expect do
68
68
  @session.click_link_or_button('awe', exact: true)
@@ -74,7 +74,7 @@ Capybara::SpecHelper.spec '#click_link_or_button' do
74
74
  context "with a locator that doesn't exist" do
75
75
  it "should raise an error" do
76
76
  @session.visit('/with_html')
77
- msg = "Unable to find link or button \"does not exist\""
77
+ msg = "Unable to find visible link or button \"does not exist\""
78
78
  expect do
79
79
  @session.click_link_or_button('does not exist')
80
80
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -67,7 +67,7 @@ Capybara::SpecHelper.spec '#click_link' do
67
67
 
68
68
  context "with a locator that doesn't exist" do
69
69
  it "should raise an error" do
70
- msg = "Unable to find link \"does not exist\""
70
+ msg = "Unable to find visible link \"does not exist\""
71
71
  expect do
72
72
  @session.click_link('does not exist')
73
73
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -156,7 +156,7 @@ Capybara::SpecHelper.spec "#fill_in" do
156
156
  before { Capybara.ignore_hidden_elements = true }
157
157
  after { Capybara.ignore_hidden_elements = false }
158
158
  it "should not find a hidden field" do
159
- msg = "Unable to find field \"Super Secret\""
159
+ msg = "Unable to find visible field \"Super Secret\" that is not disabled"
160
160
  expect do
161
161
  @session.fill_in('Super Secret', with: '777')
162
162
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -165,7 +165,7 @@ Capybara::SpecHelper.spec "#fill_in" do
165
165
 
166
166
  context "with a locator that doesn't exist" do
167
167
  it "should raise an error" do
168
- msg = "Unable to find field \"does not exist\""
168
+ msg = "Unable to find visible field \"does not exist\" that is not disabled"
169
169
  expect do
170
170
  @session.fill_in('does not exist', with: 'Blah blah')
171
171
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -205,7 +205,7 @@ Capybara::SpecHelper.spec '#find' do
205
205
  it "should raise ElementNotFound with a useful default message if nothing was found" do
206
206
  expect do
207
207
  @session.find(:xpath, '//div[@id="nosuchthing"]').to be_nil
208
- end.to raise_error(Capybara::ElementNotFound, "Unable to find xpath \"//div[@id=\\\"nosuchthing\\\"]\"")
208
+ end.to raise_error(Capybara::ElementNotFound, "Unable to find visible xpath \"//div[@id=\\\"nosuchthing\\\"]\"")
209
209
  end
210
210
 
211
211
  it "should accept an XPath instance" do
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+ Capybara::SpecHelper.spec '#refresh' do
3
+ it "reload the page" do
4
+ @session.visit('/form')
5
+ expect(@session).to have_select('form_locale', selected: 'English')
6
+ @session.select('Swedish', from: 'form_locale')
7
+ expect(@session).to have_select('form_locale', selected: 'Swedish')
8
+ @session.refresh
9
+ expect(@session).to have_select('form_locale', selected: 'English')
10
+ end
11
+
12
+ it "raises any errors caught inside the server", requires: [:server] do
13
+ quietly { @session.visit("/error") }
14
+ expect do
15
+ @session.refresh
16
+ end.to raise_error(TestApp::TestAppError)
17
+ end
18
+
19
+ it "it reposts" do
20
+ @session.visit('/form')
21
+ @session.select('Sweden', from: 'form_region')
22
+ @session.click_button('awesome')
23
+ expect {
24
+ @session.refresh
25
+ sleep 2
26
+ }.to change{ extract_results(@session)['post_count'] }.by(1)
27
+ end
28
+ end
@@ -85,7 +85,7 @@ Capybara::SpecHelper.spec "#select" do
85
85
 
86
86
  context "with a locator that doesn't exist" do
87
87
  it "should raise an error" do
88
- msg = "Unable to find select box \"does not exist\""
88
+ msg = "Unable to find visible select box \"does not exist\" that is not disabled"
89
89
  expect do
90
90
  @session.select('foo', from: 'does not exist')
91
91
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -94,7 +94,7 @@ Capybara::SpecHelper.spec "#select" do
94
94
 
95
95
  context "with an option that doesn't exist" do
96
96
  it "should raise an error" do
97
- msg = "Unable to find option \"Does not Exist\""
97
+ msg = "Unable to find visible option \"Does not Exist\""
98
98
  expect do
99
99
  @session.select('Does not Exist', from: 'form_locale')
100
100
  end.to raise_error(Capybara::ElementNotFound, msg)
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+ Capybara::SpecHelper.spec '#sibling' do
3
+ before do
4
+ @session.visit('/with_html')
5
+ end
6
+
7
+ after do
8
+ Capybara::Selector.remove(:monkey)
9
+ end
10
+
11
+ it "should find a prior sibling element using the given locator" do
12
+ el = @session.find(:css, '#mid_sibling')
13
+ expect(el.sibling('//div[@data-pre]')[:id]).to eq('pre_sibling')
14
+ end
15
+
16
+ it "should find a following sibling element using the given locator" do
17
+ el = @session.find(:css, '#mid_sibling')
18
+ expect(el.sibling('//div[@data-post]')[:id]).to eq('post_sibling')
19
+ end
20
+
21
+ it "should raise an error if there are multiple matches" do
22
+ el = @session.find(:css, '#mid_sibling')
23
+ expect { el.sibling('//div') }.to raise_error(Capybara::Ambiguous)
24
+ end
25
+
26
+ context "with css selectors" do
27
+ it "should find the first element using the given locator" do
28
+ el = @session.find(:css, '#mid_sibling')
29
+ expect(el.sibling(:css, '#pre_sibling')).to have_text('Pre Sibling')
30
+ expect(el.sibling(:css, '#post_sibling')).to have_text('Post Sibling')
31
+ end
32
+ end
33
+
34
+ context "with custom selector" do
35
+ it "should use the custom selector" do
36
+ Capybara.add_selector(:data_attribute) do
37
+ xpath { |attr| ".//*[@data-#{attr}]" }
38
+ end
39
+ el = @session.find(:css, '#mid_sibling')
40
+ expect(el.sibling(:data_attribute, 'pre').text).to eq('Pre Sibling')
41
+ expect(el.sibling(:data_attribute, 'post').text).to eq('Post Sibling')
42
+ end
43
+ end
44
+
45
+
46
+ it "should raise ElementNotFound with a useful default message if nothing was found" do
47
+ el = @session.find(:css, '#child')
48
+ expect do
49
+ el.sibling(:xpath, '//div[@id="nosuchthing"]')
50
+ end.to raise_error(Capybara::ElementNotFound, "Unable to find xpath \"//div[@id=\\\"nosuchthing\\\"]\" that is a sibling of visible css \"#child\"")
51
+ end
52
+ end