capybara 2.0.3 → 2.1.0.beta1

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 (81) hide show
  1. data.tar.gz.sig +0 -0
  2. data/History.md +73 -0
  3. data/README.md +52 -5
  4. data/lib/capybara.rb +44 -62
  5. data/lib/capybara/cucumber.rb +4 -1
  6. data/lib/capybara/driver/base.rb +13 -9
  7. data/lib/capybara/driver/node.rb +18 -6
  8. data/lib/capybara/helpers.rb +111 -22
  9. data/lib/capybara/node/actions.rb +24 -19
  10. data/lib/capybara/node/base.rb +25 -32
  11. data/lib/capybara/node/document.rb +6 -2
  12. data/lib/capybara/node/element.rb +45 -7
  13. data/lib/capybara/node/finders.rb +48 -21
  14. data/lib/capybara/node/matchers.rb +38 -21
  15. data/lib/capybara/node/simple.rb +29 -7
  16. data/lib/capybara/query.rb +72 -26
  17. data/lib/capybara/rack_test/browser.rb +11 -3
  18. data/lib/capybara/rack_test/css_handlers.rb +8 -0
  19. data/lib/capybara/rack_test/driver.rb +11 -3
  20. data/lib/capybara/rack_test/form.rb +8 -1
  21. data/lib/capybara/rack_test/node.rb +92 -36
  22. data/lib/capybara/rails.rb +1 -2
  23. data/lib/capybara/result.rb +21 -37
  24. data/lib/capybara/rspec/matchers.rb +60 -31
  25. data/lib/capybara/selector.rb +46 -13
  26. data/lib/capybara/selenium/driver.rb +42 -6
  27. data/lib/capybara/selenium/node.rb +23 -5
  28. data/lib/capybara/session.rb +46 -11
  29. data/lib/capybara/spec/public/test.js +12 -0
  30. data/lib/capybara/spec/session/all_spec.rb +9 -8
  31. data/lib/capybara/spec/session/attach_file_spec.rb +14 -0
  32. data/lib/capybara/spec/session/check_spec.rb +14 -0
  33. data/lib/capybara/spec/session/choose_spec.rb +14 -0
  34. data/lib/capybara/spec/session/click_button_spec.rb +77 -1
  35. data/lib/capybara/spec/session/click_link_or_button_spec.rb +65 -0
  36. data/lib/capybara/spec/session/click_link_spec.rb +24 -0
  37. data/lib/capybara/spec/session/current_scope_spec.rb +29 -0
  38. data/lib/capybara/spec/session/fill_in_spec.rb +14 -0
  39. data/lib/capybara/spec/session/find_button_spec.rb +12 -0
  40. data/lib/capybara/spec/session/find_by_id_spec.rb +12 -1
  41. data/lib/capybara/spec/session/find_field_spec.rb +30 -0
  42. data/lib/capybara/spec/session/find_link_spec.rb +12 -0
  43. data/lib/capybara/spec/session/find_spec.rb +258 -16
  44. data/lib/capybara/spec/session/first_spec.rb +25 -8
  45. data/lib/capybara/spec/session/has_css_spec.rb +2 -2
  46. data/lib/capybara/spec/session/has_field_spec.rb +10 -2
  47. data/lib/capybara/spec/session/has_selector_spec.rb +9 -0
  48. data/lib/capybara/spec/session/has_text_spec.rb +96 -0
  49. data/lib/capybara/spec/session/has_title_spec.rb +47 -0
  50. data/lib/capybara/spec/session/node_spec.rb +43 -0
  51. data/lib/capybara/spec/session/reset_session_spec.rb +10 -2
  52. data/lib/capybara/spec/session/save_page_spec.rb +30 -0
  53. data/lib/capybara/spec/session/select_spec.rb +65 -0
  54. data/lib/capybara/spec/session/text_spec.rb +31 -0
  55. data/lib/capybara/spec/session/title_spec.rb +16 -0
  56. data/lib/capybara/spec/session/uncheck_spec.rb +14 -0
  57. data/lib/capybara/spec/session/unselect_spec.rb +42 -0
  58. data/lib/capybara/spec/session/visit_spec.rb +3 -3
  59. data/lib/capybara/spec/session/within_frame_spec.rb +14 -0
  60. data/lib/capybara/spec/session/within_spec.rb +3 -3
  61. data/lib/capybara/spec/spec_helper.rb +6 -1
  62. data/lib/capybara/spec/views/form.erb +39 -2
  63. data/lib/capybara/spec/views/frame_child.erb +9 -0
  64. data/lib/capybara/spec/views/frame_parent.erb +8 -0
  65. data/lib/capybara/spec/views/with_base_tag.erb +10 -0
  66. data/lib/capybara/spec/views/with_count.erb +7 -0
  67. data/lib/capybara/spec/views/with_hover.erb +17 -0
  68. data/lib/capybara/spec/views/with_html.erb +21 -2
  69. data/lib/capybara/spec/views/with_js.erb +5 -0
  70. data/lib/capybara/spec/views/with_scope.erb +6 -1
  71. data/lib/capybara/spec/views/with_title.erb +1 -0
  72. data/lib/capybara/spec/views/within_frames.erb +1 -0
  73. data/lib/capybara/version.rb +1 -1
  74. data/spec/basic_node_spec.rb +75 -24
  75. data/spec/dsl_spec.rb +2 -1
  76. data/spec/rack_test_spec.rb +4 -3
  77. data/spec/rspec/matchers_spec.rb +105 -17
  78. data/spec/server_spec.rb +8 -8
  79. data/spec/spec_helper.rb +2 -1
  80. metadata +83 -23
  81. metadata.gz.sig +0 -0
@@ -4,6 +4,37 @@ Capybara::SpecHelper.spec '#text' do
4
4
  @session.text.should == 'Bar'
5
5
  end
6
6
 
7
+ it "ignores invisible text by default" do
8
+ @session.visit('/with_html')
9
+ @session.find(:id, "hidden-text").text.should == 'Some of this text is'
10
+ end
11
+
12
+ it "shows invisible text if `:all` given" do
13
+ @session.visit('/with_html')
14
+ @session.find(:id, "hidden-text").text(:all).should == 'Some of this text is hidden!'
15
+ end
16
+
17
+ it "ignores invisible text if `:visible` given" do
18
+ Capybara.ignore_hidden_elements = false
19
+ @session.visit('/with_html')
20
+ @session.find(:id, "hidden-text").text(:visible).should == 'Some of this text is'
21
+ end
22
+
23
+ it "ignores invisible text if `Capybara.ignore_hidden_elements = true`" do
24
+ @session.visit('/with_html')
25
+ @session.find(:id, "hidden-text").text.should == 'Some of this text is'
26
+ Capybara.ignore_hidden_elements = false
27
+ @session.find(:id, "hidden-text").text.should == 'Some of this text is hidden!'
28
+ end
29
+
30
+ it "ignores invisible text if `Capybara.visible_text_only = true`" do
31
+ @session.visit('/with_html')
32
+ Capybara.visible_text_only = true
33
+ @session.find(:id, "hidden-text").text.should == 'Some of this text is'
34
+ Capybara.ignore_hidden_elements = false
35
+ @session.find(:id, "hidden-text").text.should == 'Some of this text is'
36
+ end
37
+
7
38
  context "with css as default selector" do
8
39
  before { Capybara.default_selector = :css }
9
40
  it "should print the text of the page" do
@@ -0,0 +1,16 @@
1
+ Capybara::SpecHelper.spec '#title' do
2
+
3
+ it "should print the title of the page" do
4
+ @session.visit('/with_title')
5
+ @session.title.should == 'Test Title'
6
+ end
7
+
8
+ context "with css as default selector" do
9
+ before { Capybara.default_selector = :css }
10
+ it "should print the title of the page" do
11
+ @session.visit('/with_title')
12
+ @session.title.should == 'Test Title'
13
+ end
14
+ after { Capybara.default_selector = :xpath }
15
+ end
16
+ end
@@ -23,4 +23,18 @@ Capybara::SpecHelper.spec "#uncheck" do
23
23
  extract_results(@session)['pets'].should include('dog')
24
24
  extract_results(@session)['pets'].should_not include('hamster')
25
25
  end
26
+
27
+ context "with :exact option" do
28
+ it "should accept partial matches when false" do
29
+ @session.uncheck('Ham', :exact => false)
30
+ @session.click_button('awesome')
31
+ extract_results(@session)['pets'].should_not include('hamster')
32
+ end
33
+
34
+ it "should not accept partial matches when true" do
35
+ expect do
36
+ @session.uncheck('Ham', :exact => true)
37
+ end.to raise_error(Capybara::ElementNotFound)
38
+ end
39
+ end
26
40
  end
@@ -69,4 +69,46 @@ Capybara::SpecHelper.spec "#unselect" do
69
69
  end.to raise_error(Capybara::ElementNotFound, msg)
70
70
  end
71
71
  end
72
+
73
+ context "with :exact option" do
74
+ context "when `false`" do
75
+ it "can match select box approximately" do
76
+ @session.unselect("Boxerbriefs", :from => "Under", :exact => false)
77
+ @session.click_button("awesome")
78
+ extract_results(@session)["underwear"].should_not include("Boxerbriefs")
79
+ end
80
+
81
+ it "can match option approximately" do
82
+ @session.unselect("Boxerbr", :from => "Underwear", :exact => false)
83
+ @session.click_button("awesome")
84
+ extract_results(@session)["underwear"].should_not include("Boxerbriefs")
85
+ end
86
+
87
+ it "can match option approximately when :from not given" do
88
+ @session.unselect("Boxerbr", :exact => false)
89
+ @session.click_button("awesome")
90
+ extract_results(@session)["underwear"].should_not include("Boxerbriefs")
91
+ end
92
+ end
93
+
94
+ context "when `true`" do
95
+ it "can match select box approximately" do
96
+ expect do
97
+ @session.unselect("Boxerbriefs", :from => "Under", :exact => true)
98
+ end.to raise_error(Capybara::ElementNotFound)
99
+ end
100
+
101
+ it "can match option approximately" do
102
+ expect do
103
+ @session.unselect("Boxerbr", :from => "Underwear", :exact => true)
104
+ end.to raise_error(Capybara::ElementNotFound)
105
+ end
106
+
107
+ it "can match option approximately when :from not given" do
108
+ expect do
109
+ @session.unselect("Boxerbr", :exact => true)
110
+ end.to raise_error(Capybara::ElementNotFound)
111
+ end
112
+ end
113
+ end
72
114
  end
@@ -72,18 +72,18 @@ Capybara::SpecHelper.spec '#visit' do
72
72
  it "should send a referer when following a link" do
73
73
  @session.visit '/referer_base'
74
74
  @session.find('//a[@href="/get_referer"]').click
75
- @session.body.should match %r{http://.*/referer_base}
75
+ @session.should have_content %r{http://.*/referer_base}
76
76
  end
77
77
 
78
78
  it "should preserve the original referer URL when following a redirect" do
79
79
  @session.visit('/referer_base')
80
80
  @session.find('//a[@href="/redirect_to_get_referer"]').click
81
- @session.body.should match %r{http://.*/referer_base}
81
+ @session.should have_content %r{http://.*/referer_base}
82
82
  end
83
83
 
84
84
  it "should send a referer when submitting a form" do
85
85
  @session.visit '/referer_base'
86
86
  @session.find('//input').click
87
- @session.body.should match %r{http://.*/referer_base}
87
+ @session.should have_content %r{http://.*/referer_base}
88
88
  end
89
89
  end
@@ -28,4 +28,18 @@ Capybara::SpecHelper.spec '#within_frame', :requires => [:frames] do
28
28
  it "should return the result of executing the block" do
29
29
  @session.within_frame("frameOne") { "return value" }.should eql "return value"
30
30
  end
31
+ it "should find the div given Element" do
32
+ element = @session.find(:id, 'frameOne')
33
+ @session.within_frame element do
34
+ @session.find("//*[@id='divInFrameOne']").text.should eql 'This is the text of divInFrameOne'
35
+ end
36
+ end
37
+ it "should find multiple nested frames" do
38
+ @session.within_frame 'parentFrame' do
39
+ @session.within_frame 'childFrame' do
40
+ @session.within_frame 'grandchildFrame1' do end
41
+ @session.within_frame 'grandchildFrame2' do end
42
+ end
43
+ end
44
+ end
31
45
  end
@@ -5,7 +5,7 @@ Capybara::SpecHelper.spec '#within' do
5
5
 
6
6
  context "with CSS selector" do
7
7
  it "should click links in the given scope" do
8
- @session.within(:css, "#for_bar li[contains('With Simple HTML')]") do
8
+ @session.within(:css, "#for_bar li", text: 'With Simple HTML') do
9
9
  @session.click_link('Go')
10
10
  end
11
11
  @session.should have_content('Bar')
@@ -46,7 +46,7 @@ Capybara::SpecHelper.spec '#within' do
46
46
 
47
47
  context "with Node rather than selector" do
48
48
  it "should click links in the given scope" do
49
- node_of_interest = @session.find(:css, "#for_bar li[contains('With Simple HTML')]")
49
+ node_of_interest = @session.find(:css, "#for_bar li", text: 'With Simple HTML')
50
50
 
51
51
  @session.within(node_of_interest) do
52
52
  @session.click_link('Go')
@@ -58,7 +58,7 @@ Capybara::SpecHelper.spec '#within' do
58
58
  context "with the default selector set to CSS" do
59
59
  before { Capybara.default_selector = :css }
60
60
  it "should use CSS" do
61
- @session.within("#for_bar li[contains('With Simple HTML')]") do
61
+ @session.within("#for_bar li", text: 'With Simple HTML') do
62
62
  @session.click_link('Go')
63
63
  end
64
64
  @session.should have_content('Bar')
@@ -2,7 +2,6 @@ require "rspec"
2
2
  require "capybara"
3
3
  require "capybara/rspec" # Required here instead of in rspec_spec to avoid RSpec deprecation warning
4
4
  require "capybara/spec/test_app"
5
- require "capybara/spec/spec_helper"
6
5
  require "nokogiri"
7
6
 
8
7
  module Capybara
@@ -19,6 +18,12 @@ module Capybara
19
18
  Capybara.app_host = nil
20
19
  Capybara.default_selector = :xpath
21
20
  Capybara.default_wait_time = 1
21
+ Capybara.ignore_hidden_elements = true
22
+ Capybara.exact = false
23
+ Capybara.exact_options = false
24
+ Capybara.raise_server_errors = true
25
+ Capybara.visible_text_only = false
26
+ Capybara.match = :smart
22
27
  end
23
28
 
24
29
  def filter(requires, metadata)
@@ -8,9 +8,21 @@
8
8
  <option>Mrs</option>
9
9
  <option>Mr</option>
10
10
  <option>Miss</option>
11
+ <option disabled="disabled">Other</option>
11
12
  </select>
13
+ </p>
14
+
15
+ <p>
16
+ <label for="customer_name">Customer Name
17
+ <input type="text" name="form[customer_name]" value="Blah" id="customer_name" disabled="disabled"/>
18
+ </label>
12
19
  </p>
13
20
 
21
+ <p>
22
+ <label for="customer_email">Customer Email
23
+ <input type="text" name="form[customer_email]" value="ben@ben.com" id="customer_email"/>
24
+ </label>
25
+ </p>
14
26
 
15
27
  <p>
16
28
  <label for="form_other_title">Other title</label>
@@ -253,10 +265,35 @@
253
265
  <button type="submit" id="click_me_123" title="Click Title button" value="click_me">Click me!</button>
254
266
  <button type="submit" name="form[no_value]">No Value!</button>
255
267
  <button id="no_type">No Type!</button>
256
- <input type="button" disabled value="Disabled button"/>
268
+ <input type="button" disabled="disabled" value="Disabled button"/>
257
269
  </p>
258
270
  </form>
259
271
 
272
+ <input type="text" name="form[outside_input]" value="outside_input" form="form1"/>
273
+
274
+ <form id="form1" action="/form" method="post">
275
+ <input type="text" name="form[which_form]" value="form1" id="form_which_form"/>
276
+ <input type="text" name="form[for_form2]" value="for_form2" form="form2"/>
277
+ <input type="submit" name="form[submit_form1]" value="submit_form1" id="submit_form1"/>
278
+ </form>
279
+
280
+ <form id="form2" action="/form" method="post">
281
+ <input type="text" name="form[which_form]" value="form2" id="form_which_form"/>
282
+ <input type="submit" name="form[unused]" value="unused"/>
283
+ <button type="submit" name="form[other_form_button]" value="other_form_button" form="form1">Form1</button>
284
+ </form>
285
+
286
+ <textarea name="form[outside_textarea]" form="form1">Some text here</textarea>
287
+ <select name="form[outside_select]" form="form1">
288
+ <option>Lisp</option>
289
+ <option selected="selected">Ruby</option>
290
+ <option>Php</option>
291
+ </select>
292
+
293
+ <input type="submit" name="form[outside_submit]" value="outside_submit" form="form1"/>
294
+ <button type="submit" name="form[outside_button]" value="outside_button" form="form2">Outside!</button>
295
+
296
+
260
297
  <form id="get-form" action="/form/get?foo=bar" method="get">
261
298
  <p>
262
299
  <label for="form_middle_name">Middle Name</label>
@@ -304,7 +341,7 @@
304
341
 
305
342
  <p>
306
343
  <label for="form_multiple_documents">Multiple Documents</label>
307
- <input type="file" name="form[multiple_documents][]" id="form_multiple_documents" multiple />
344
+ <input type="file" name="form[multiple_documents][]" id="form_multiple_documents" multiple="multiple" />
308
345
  </p>
309
346
 
310
347
  <p>
@@ -0,0 +1,9 @@
1
+ <html>
2
+ <head>
3
+ <title>This is the child frame title</title>
4
+ </head>
5
+ <body>
6
+ <iframe src="/frame_one" id="grandchildFrame1"></iframe>
7
+ <iframe src="/frame_two" id="grandchildFrame2"></iframe>
8
+ </body>
9
+ </html>
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <title>This is the parent frame title</title>
4
+ </head>
5
+ <body>
6
+ <iframe src='/frame_child' id='childFrame'></iframe>
7
+ </body>
8
+ </html>
@@ -0,0 +1,10 @@
1
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
2
+ <head>
3
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
4
+ <base href="http://example2.com" />
5
+ <title>with_external_source</title>
6
+ </head>
7
+ <body id="with_js">
8
+ <h1>FooBar</h1>
9
+ </body>
10
+ </html
@@ -0,0 +1,7 @@
1
+ <h1>This page is used for testing number options of has_text?</h1>
2
+
3
+ <p>count1</p>
4
+ <div>
5
+ <p>2 count</p>
6
+ <p>Count</p>
7
+ </div>
@@ -0,0 +1,17 @@
1
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en">
2
+ <head>
3
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
4
+ <title>with_hover</title>
5
+ </head>
6
+
7
+ <body id="with_hover">
8
+ <style type="text/css">
9
+ .hidden_until_hover {display: none;}
10
+ .wrapper:hover .hidden_until_hover { display: block }
11
+ </style>
12
+ <div class="wrapper">
13
+ Some text here so the wrapper has size
14
+ <div class="hidden_until_hover">Here I am</div>
15
+ </div>
16
+ </body>
17
+ </html>
@@ -28,11 +28,13 @@
28
28
 
29
29
  <p>
30
30
  <input type="text" id="test_field" value="monkey"/>
31
+ <input type="text" readonly="readonly" value="should not change" />
31
32
  <textarea id="normal">
32
33
  banana</textarea>
33
34
  <textarea id="additional_newline">
34
35
 
35
36
  banana</textarea>
37
+ <textarea readonly="readonly">textarea should not change</textarea>
36
38
  <a href="/redirect_back">BackToMyself</a>
37
39
  <a title="twas a fine link" href="/redirect">A link came first</a>
38
40
  <a title="a fine link" href="/with_simple_html">A link</a>
@@ -49,6 +51,7 @@ banana</textarea>
49
51
  <input type="text" checked="checked" id="checked_field">
50
52
  <a href="/redirect"><img width="20" height="20" alt="very fine image" /></a>
51
53
  <a href="/with_simple_html"><img width="20" height="20" alt="fine image" /></a>
54
+ <a href="/with_simple_html" disabled="disabled">Disabled link</a>
52
55
 
53
56
  <a href="?query_string=true">Naked Query String</a>
54
57
  <% if params[:query_string] %>
@@ -61,6 +64,10 @@ banana</textarea>
61
64
  <a href="/with_simple_html" title="hidden link" class="simple">hidden link</a>
62
65
  </div>
63
66
 
67
+ <div id="hidden-text">
68
+ Some of this text is <em style="display:none">hidden!</em>
69
+ </div>
70
+
64
71
  <div style="display: none;">
65
72
  <a id="first_invisble" class="hidden">first hidden link</a>
66
73
  </div>
@@ -78,6 +85,18 @@ banana</textarea>
78
85
  </div>
79
86
 
80
87
  <ul>
81
- <li id="john_monkey">Monkey John</li>
82
- <li id="paul_monkey">Monkey Paul</li>
88
+ <li class="beatle guitarist" id="john">John</li>
89
+ <li class="beatle bassist drummer" id="paul">Paul</li>
90
+ <li class="beatle guitarist" id="george">George</li>
91
+ <li class="beatle drummer" id="ringo">Ringo</li>
83
92
  </ul>
93
+
94
+ <div>
95
+ <div class="singular">singular</div>
96
+ <div class="multiple">multiple one</div>
97
+ <div class="multiple">multiple two</div>
98
+ <div class="almost_singular but_not_quite">almost singular but not quite</div>
99
+ <div class="almost_singular">almost singular</div>
100
+ </div>
101
+
102
+ <input type="text" disabled="disabled" name="disabled_text" value="This is disabled"/>
@@ -19,6 +19,7 @@
19
19
  </div>
20
20
 
21
21
  <p><a href="#" id="clickable">Click me</a></p>
22
+ <p><a href="#" id="slow-click">Slowly</a></p>
22
23
 
23
24
  <p>
24
25
  <select id="waiter">
@@ -57,6 +58,10 @@
57
58
  </ul>
58
59
  </p>
59
60
 
61
+ <p>
62
+ <a href="#" id="change-title">Change title</a>
63
+ </p>
64
+
60
65
  <script type="text/javascript">
61
66
  // a javascript comment
62
67
  var aVar = 123;
@@ -4,6 +4,7 @@
4
4
  Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
5
5
  incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia.
6
6
  <a href="/redirect">Go</a>
7
+ <input name="disabled" disabled="disabled"/>
7
8
  </p>
8
9
 
9
10
  <div id="for_bar">
@@ -23,6 +24,10 @@
23
24
  <label for="bar_first_name">First Name</label>
24
25
  <input type="text" name="form[first_name]" value="Peter" id="bar_first_name"/>
25
26
  </p>
27
+ <p>
28
+ <label for="bar_other_name">Other Name</label>
29
+ <input type="text" name="form[other_name]" value="James" id="bar_other_name" disabled="disabled"/>
30
+ </p>
26
31
  <p><input type="submit" value="Go"/></p>
27
32
  </form>
28
33
  </li>
@@ -33,4 +38,4 @@
33
38
  <ul>
34
39
  <li>With Simple HTML: <a href="/">Go</a>
35
40
  </ul>
36
- </div>
41
+ </div>
@@ -0,0 +1 @@
1
+ <title>Test Title</title>
@@ -6,5 +6,6 @@
6
6
  <div id="divInMainWindow">This is the text for divInMainWindow</div>
7
7
  <iframe src="/frame_one" id="frameOne"></iframe>
8
8
  <iframe src="/frame_two" id="frameTwo"></iframe>
9
+ <iframe src="/frame_parent" id="parentFrame"></iframe>
9
10
  </body>
10
11
  </html>