capybara 0.4.1.2 → 1.0.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 (69) hide show
  1. data/History.txt +46 -0
  2. data/README.rdoc +211 -64
  3. data/lib/capybara.rb +31 -15
  4. data/lib/capybara/cucumber.rb +12 -16
  5. data/lib/capybara/dsl.rb +65 -28
  6. data/lib/capybara/node/actions.rb +7 -5
  7. data/lib/capybara/node/document.rb +8 -0
  8. data/lib/capybara/node/finders.rb +11 -7
  9. data/lib/capybara/node/matchers.rb +32 -6
  10. data/lib/capybara/node/simple.rb +20 -0
  11. data/lib/capybara/rack_test/browser.rb +115 -0
  12. data/lib/capybara/rack_test/driver.rb +77 -0
  13. data/lib/capybara/rack_test/form.rb +80 -0
  14. data/lib/capybara/rack_test/node.rb +101 -0
  15. data/lib/capybara/rspec.rb +11 -3
  16. data/lib/capybara/rspec/features.rb +22 -0
  17. data/lib/capybara/rspec/matchers.rb +146 -0
  18. data/lib/capybara/selector.rb +27 -8
  19. data/lib/capybara/selenium/driver.rb +148 -0
  20. data/lib/capybara/selenium/node.rb +91 -0
  21. data/lib/capybara/session.rb +42 -15
  22. data/lib/capybara/spec/driver.rb +55 -1
  23. data/lib/capybara/spec/fixtures/capybara.jpg +0 -0
  24. data/lib/capybara/spec/public/test.js +7 -2
  25. data/lib/capybara/spec/session.rb +51 -7
  26. data/lib/capybara/spec/session/attach_file_spec.rb +9 -6
  27. data/lib/capybara/spec/session/click_button_spec.rb +35 -0
  28. data/lib/capybara/spec/session/current_host_spec.rb +62 -0
  29. data/lib/capybara/spec/session/fill_in_spec.rb +6 -0
  30. data/lib/capybara/spec/session/find_spec.rb +23 -1
  31. data/lib/capybara/spec/session/first_spec.rb +39 -6
  32. data/lib/capybara/spec/session/has_css_spec.rb +30 -0
  33. data/lib/capybara/spec/session/has_field_spec.rb +47 -11
  34. data/lib/capybara/spec/session/javascript.rb +0 -1
  35. data/lib/capybara/spec/session/text_spec.rb +19 -0
  36. data/lib/capybara/spec/test_app.rb +9 -0
  37. data/lib/capybara/spec/views/form.erb +8 -3
  38. data/lib/capybara/spec/views/header_links.erb +7 -0
  39. data/lib/capybara/spec/views/host_links.erb +12 -0
  40. data/lib/capybara/spec/views/with_html.erb +6 -2
  41. data/lib/capybara/spec/views/with_html_entities.erb +1 -0
  42. data/lib/capybara/spec/views/with_js.erb +4 -0
  43. data/lib/capybara/util/save_and_open_page.rb +7 -3
  44. data/lib/capybara/util/timeout.rb +2 -2
  45. data/lib/capybara/version.rb +1 -1
  46. data/spec/capybara_spec.rb +1 -1
  47. data/spec/driver/rack_test_driver_spec.rb +24 -2
  48. data/spec/driver/selenium_driver_spec.rb +2 -1
  49. data/spec/dsl_spec.rb +56 -4
  50. data/spec/rspec/features_spec.rb +45 -0
  51. data/spec/rspec/matchers_spec.rb +451 -0
  52. data/spec/rspec_spec.rb +9 -2
  53. data/spec/save_and_open_page_spec.rb +9 -13
  54. data/spec/server_spec.rb +4 -0
  55. data/spec/session/rack_test_session_spec.rb +2 -2
  56. data/spec/session/selenium_session_spec.rb +1 -1
  57. data/spec/spec_helper.rb +0 -14
  58. data/spec/string_spec.rb +1 -1
  59. metadata +60 -69
  60. data/lib/capybara/driver/celerity_driver.rb +0 -164
  61. data/lib/capybara/driver/culerity_driver.rb +0 -26
  62. data/lib/capybara/driver/rack_test_driver.rb +0 -303
  63. data/lib/capybara/driver/selenium_driver.rb +0 -161
  64. data/spec/driver/celerity_driver_spec.rb +0 -13
  65. data/spec/driver/culerity_driver_spec.rb +0 -14
  66. data/spec/driver/remote_culerity_driver_spec.rb +0 -22
  67. data/spec/driver/remote_selenium_driver_spec.rb +0 -16
  68. data/spec/session/celerity_session_spec.rb +0 -24
  69. data/spec/session/culerity_session_spec.rb +0 -26
@@ -25,9 +25,14 @@ $(function() {
25
25
  }, 500);
26
26
  });
27
27
  $('#with_focus_event').focus(function() {
28
- $('body').append('<p id="focus_event_triggered">Focus Event triggered</p>')
28
+ $('body').append('<p id="focus_event_triggered">Focus Event triggered</p>');
29
29
  });
30
30
  $('#checkbox_with_event').click(function() {
31
- $('body').append('<p id="checkbox_event_triggered">Checkbox event triggered</p>')
31
+ $('body').append('<p id="checkbox_event_triggered">Checkbox event triggered</p>');
32
+ });
33
+ $('#fire_ajax_request').click(function() {
34
+ $.ajax({url: "/slow_response", context: document.body, success: function() {
35
+ $('body').append('<p id="ajax_request_done">Ajax request done</p>');
36
+ }});
32
37
  });
33
38
  });
@@ -9,13 +9,7 @@ shared_examples_for "session" do
9
9
  end
10
10
 
11
11
  after do
12
- @session.reset!
13
- end
14
-
15
- describe '#app' do
16
- it "should remember the application" do
17
- @session.app.should == TestApp
18
- end
12
+ @session.reset_session!
19
13
  end
20
14
 
21
15
  describe '#visit' do
@@ -34,6 +28,16 @@ shared_examples_for "session" do
34
28
  end
35
29
  end
36
30
 
31
+ describe '#html' do
32
+ it "should return the unmodified page body" do
33
+ # html and body should be aliased, but we can't just check for
34
+ # method(:html) == method(:body) because these shared examples get run
35
+ # against the DSL, which uses forwarding methods. So we test behavior.
36
+ @session.visit('/')
37
+ @session.body.should include('Hello world!')
38
+ end
39
+ end
40
+
37
41
  describe '#source' do
38
42
  it "should return the unmodified page source" do
39
43
  @session.visit('/')
@@ -41,6 +45,44 @@ shared_examples_for "session" do
41
45
  end
42
46
  end
43
47
 
48
+ describe '#reset_session!' do
49
+ it "removes cookies" do
50
+ @session.visit('/set_cookie')
51
+ @session.visit('/get_cookie')
52
+ @session.body.should include('test_cookie')
53
+
54
+ @session.reset_session!
55
+ @session.visit('/get_cookie')
56
+ @session.body.should_not include('test_cookie')
57
+ end
58
+
59
+ it "resets current host" do
60
+ @session.visit('http://capybara-testapp.heroku.com')
61
+ @session.current_host.should == 'http://capybara-testapp.heroku.com'
62
+
63
+ @session.reset_session!
64
+ @session.current_host.should be_nil
65
+ end
66
+
67
+ it "resets current path" do
68
+ @session.visit('/with_html')
69
+ @session.current_path.should == '/with_html'
70
+
71
+ @session.reset_session!
72
+ @session.current_path.should be_nil
73
+ end
74
+
75
+ it "resets page body" do
76
+ @session.visit('/with_html')
77
+ @session.body.should include('This is a test')
78
+ @session.find('.//h1').text.should include('This is a test')
79
+
80
+ @session.reset_session!
81
+ @session.body.should_not include('This is a test')
82
+ @session.should have_no_selector('.//h1')
83
+ end
84
+ end
85
+
44
86
  it_should_behave_like "all"
45
87
  it_should_behave_like "first"
46
88
  it_should_behave_like "attach_file"
@@ -66,10 +108,12 @@ shared_examples_for "session" do
66
108
  it_should_behave_like "has_select"
67
109
  it_should_behave_like "has_table"
68
110
  it_should_behave_like "select"
111
+ it_should_behave_like "text"
69
112
  it_should_behave_like "uncheck"
70
113
  it_should_behave_like "unselect"
71
114
  it_should_behave_like "within"
72
115
  it_should_behave_like "current_url"
116
+ it_should_behave_like "current_host"
73
117
 
74
118
  it "should encode complex field names, like array[][value]" do
75
119
  @session.visit('/form')
@@ -2,6 +2,8 @@ shared_examples_for "attach_file" do
2
2
 
3
3
  describe "#attach_file" do
4
4
  before do
5
+ @test_file_path = File.expand_path('../fixtures/test_file.txt', File.dirname(__FILE__))
6
+ @test_jpg_file_path = File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__))
5
7
  @session.visit('/form')
6
8
  end
7
9
 
@@ -20,11 +22,6 @@ shared_examples_for "attach_file" do
20
22
  end
21
23
 
22
24
  context "with multipart form" do
23
- before do
24
- @test_file_path = File.expand_path('../fixtures/test_file.txt', File.dirname(__FILE__))
25
- @test_jpg_file_path = File.expand_path('../fixtures/capybara.jpg', File.dirname(__FILE__))
26
- end
27
-
28
25
  it "should set a file path by id" do
29
26
  @session.attach_file "form_document", @test_file_path
30
27
  @session.click_button('Upload')
@@ -63,7 +60,13 @@ shared_examples_for "attach_file" do
63
60
 
64
61
  context "with a locator that doesn't exist" do
65
62
  it "should raise an error" do
66
- running { @session.attach_file('does not exist', 'foo.txt') }.should raise_error(Capybara::ElementNotFound)
63
+ running { @session.attach_file('does not exist', @test_file_path) }.should raise_error(Capybara::ElementNotFound)
64
+ end
65
+ end
66
+
67
+ context "with a path that doesn't exist" do
68
+ it "should raise an error" do
69
+ running { @session.attach_file('Image', '/no_such_file.png') }.should raise_error(Capybara::FileNotFound)
67
70
  end
68
71
  end
69
72
  end
@@ -123,6 +123,18 @@ shared_examples_for "click_button" do
123
123
  end
124
124
  end
125
125
 
126
+ context "with title given on a submit button" do
127
+ it "should submit the associated form" do
128
+ @session.click_button('What an Awesome Button')
129
+ extract_results(@session)['first_name'].should == 'John'
130
+ end
131
+
132
+ it "should work with partial matches" do
133
+ @session.click_button('What an Awesome')
134
+ extract_results(@session)['first_name'].should == 'John'
135
+ end
136
+ end
137
+
126
138
  context "with alt given on an image button" do
127
139
  it "should submit the associated form" do
128
140
  @session.click_button('oh hai thar')
@@ -154,6 +166,18 @@ shared_examples_for "click_button" do
154
166
  end
155
167
  end
156
168
 
169
+ context "with title given on an image button" do
170
+ it "should submit the associated form" do
171
+ @session.click_button('Okay 556 Image')
172
+ extract_results(@session)['first_name'].should == 'John'
173
+ end
174
+
175
+ it "should work with partial matches" do
176
+ @session.click_button('Okay 556')
177
+ extract_results(@session)['first_name'].should == 'John'
178
+ end
179
+ end
180
+
157
181
  context "with text given on a button defined by <button> tag" do
158
182
  it "should submit the associated form" do
159
183
  @session.click_button('Click me')
@@ -203,6 +227,17 @@ shared_examples_for "click_button" do
203
227
  end
204
228
  end
205
229
 
230
+ context "with title given on a button defined by <button> tag" do
231
+ it "should submit the associated form" do
232
+ @session.click_button('Click Title button')
233
+ extract_results(@session)['first_name'].should == 'John'
234
+ end
235
+
236
+ it "should work with partial matches" do
237
+ @session.click_button('Click Title')
238
+ extract_results(@session)['first_name'].should == 'John'
239
+ end
240
+ end
206
241
  context "with a locator that doesn't exist" do
207
242
  it "should raise an error" do
208
243
  running do
@@ -0,0 +1,62 @@
1
+ shared_examples_for "current_host" do
2
+ after do
3
+ Capybara.app_host = nil
4
+ end
5
+
6
+ describe '#current_host' do
7
+ it "is affected by visiting a page directly" do
8
+ @session.visit('http://capybara-testapp.heroku.com/host')
9
+ @session.body.should include('Current host is http://capybara-testapp.heroku.com')
10
+ @session.current_host.should == 'http://capybara-testapp.heroku.com'
11
+ end
12
+
13
+ it "returns to the app host when visiting a relative url" do
14
+ Capybara.app_host = "http://capybara1.elabs.se"
15
+ @session.visit('http://capybara-testapp.heroku.com/host')
16
+ @session.body.should include('Current host is http://capybara-testapp.heroku.com')
17
+ @session.current_host.should == 'http://capybara-testapp.heroku.com'
18
+ @session.visit('/host')
19
+ @session.body.should include('Current host is http://capybara1.elabs.se')
20
+ @session.current_host.should == 'http://capybara1.elabs.se'
21
+ end
22
+
23
+ it "is affected by setting Capybara.app_host" do
24
+ Capybara.app_host = "http://capybara-testapp.heroku.com"
25
+ @session.visit('/host')
26
+ @session.body.should include('Current host is http://capybara-testapp.heroku.com')
27
+ @session.current_host.should == 'http://capybara-testapp.heroku.com'
28
+ Capybara.app_host = "http://capybara1.elabs.se"
29
+ @session.visit('/host')
30
+ @session.body.should include('Current host is http://capybara1.elabs.se')
31
+ @session.current_host.should == 'http://capybara1.elabs.se'
32
+ end
33
+
34
+ it "is unaffected by following a relative link" do
35
+ @session.visit('http://capybara-testapp.heroku.com/host_links')
36
+ @session.click_link('Relative Host')
37
+ @session.body.should include('Current host is http://capybara-testapp.heroku.com')
38
+ @session.current_host.should == 'http://capybara-testapp.heroku.com'
39
+ end
40
+
41
+ it "is affected by following an absolute link" do
42
+ @session.visit('http://capybara-testapp.heroku.com/host_links')
43
+ @session.click_link('Absolute Host')
44
+ @session.body.should include('Current host is http://capybara2.elabs.se')
45
+ @session.current_host.should == 'http://capybara2.elabs.se'
46
+ end
47
+
48
+ it "is unaffected by posting through a relative form" do
49
+ @session.visit('http://capybara-testapp.heroku.com/host_links')
50
+ @session.click_button('Relative Host')
51
+ @session.body.should include('Current host is http://capybara-testapp.heroku.com')
52
+ @session.current_host.should == 'http://capybara-testapp.heroku.com'
53
+ end
54
+
55
+ it "is affected by posting through an absolute form" do
56
+ @session.visit('http://capybara-testapp.heroku.com/host_links')
57
+ @session.click_button('Absolute Host')
58
+ @session.body.should include('Current host is http://capybara2.elabs.se')
59
+ @session.current_host.should == 'http://capybara2.elabs.se'
60
+ end
61
+ end
62
+ end
@@ -70,6 +70,12 @@ shared_examples_for "fill_in" do
70
70
  extract_results(@session)['phone'].should == '+1 555 7022'
71
71
  end
72
72
 
73
+ it "should fill in a text field respecting its maxlength attribute" do
74
+ @session.fill_in('Zipcode', :with => '52071350')
75
+ @session.click_button('awesome')
76
+ extract_results(@session)['zipcode'].should == '52071'
77
+ end
78
+
73
79
  it "should fill in a password field by name" do
74
80
  @session.fill_in('form[password]', :with => 'supasikrit')
75
81
  @session.click_button('awesome')
@@ -79,6 +79,28 @@ shared_examples_for "find" do
79
79
  end
80
80
  end
81
81
 
82
+ context "with custom selector with failure_message option" do
83
+ it "should raise an error with the failure message if the element is not found" do
84
+ Capybara.add_selector(:monkey) do
85
+ xpath { |num| ".//*[contains(@id, 'monkey')][#{num}]" }
86
+ failure_message { |node, selector| node.all(".//*[contains(@id, 'monkey')]").map { |node| node.text }.sort.join(', ') }
87
+ end
88
+ running do
89
+ @session.find(:monkey, '14').text.should == 'Monkey Paul'
90
+ end.should raise_error(Capybara::ElementNotFound, "Monkey John, Monkey Paul")
91
+ end
92
+
93
+ it "should pass the selector as the second argument" do
94
+ Capybara.add_selector(:monkey) do
95
+ xpath { |num| ".//*[contains(@id, 'monkey')][#{num}]" }
96
+ failure_message { |node, selector| selector.name.to_s + ': ' + selector.locator + ' - ' + node.all(".//*[contains(@id, 'monkey')]").map { |node| node.text }.sort.join(', ') }
97
+ end
98
+ running do
99
+ @session.find(:monkey, '14').text.should == 'Monkey Paul'
100
+ end.should raise_error(Capybara::ElementNotFound, "monkey: 14 - Monkey John, Monkey Paul")
101
+ end
102
+ end
103
+
82
104
  context "with css as default selector" do
83
105
  before { Capybara.default_selector = :css }
84
106
  it "should find the first element using the given locator" do
@@ -97,7 +119,7 @@ shared_examples_for "find" do
97
119
  it "should raise ElementNotFound with a useful default message if nothing was found" do
98
120
  running do
99
121
  @session.find(:xpath, '//div[@id="nosuchthing"]').should be_nil
100
- end.should raise_error(Capybara::ElementNotFound, "Unable to find '//div[@id=\"nosuchthing\"]'")
122
+ end.should raise_error(Capybara::ElementNotFound, "Unable to find xpath \"//div[@id=\\\"nosuchthing\\\"]\"")
101
123
  end
102
124
 
103
125
  it "should accept an XPath instance and respect the order of paths" do
@@ -44,19 +44,52 @@ shared_examples_for "first" do
44
44
 
45
45
  context "with visible filter" do
46
46
  after { Capybara.ignore_hidden_elements = false }
47
- it "should only find visible nodes" do
48
- @session.first(:css, "a.visibility").should_not be_visible
49
- @session.first(:css, "a.visibility", :visible => true).should be_visible
47
+ it "should only find visible nodes if true given" do
48
+ @session.first(:css, "a#invisible").should_not be_nil
49
+ @session.first(:css, "a#invisible", :visible => true).should be_nil
50
50
  Capybara.ignore_hidden_elements = true
51
- @session.first(:css, "a.visibility").should be_visible
51
+ @session.first(:css, "a#invisible").should be_nil
52
52
  end
53
53
 
54
- it "should only find invisible nodes" do
54
+ it "should include invisible nodes if false given" do
55
55
  Capybara.ignore_hidden_elements = true
56
- @session.first(:css, "a.visibility", :visible => false).should_not be_visible
56
+ @session.first(:css, "a#invisible", :visible => false).should_not be_nil
57
+ @session.first(:css, "a#invisible").should be_nil
57
58
  end
58
59
  end
59
60
 
61
+ context "with prefer visible elements" do
62
+ it "should find invisible elements if no visible element exists" do
63
+ @session.first(:css, 'a#invisible')[:id].should == 'invisible'
64
+ end
65
+
66
+ it "should prefer visible elements over invisible elements" do
67
+ @session.first(:css, 'a.visibility')[:id].should == 'visible'
68
+ end
69
+
70
+ it "should return the first invisible element if no visible elements exist" do
71
+ @session.first(:css, 'a.hidden')[:id].should == 'first_invisble'
72
+ end
73
+
74
+ it "find visible links normally" do
75
+ @session.first(:css, 'a#visible')[:id].should == 'visible'
76
+ end
77
+ end
78
+
79
+ context "without prefer visible elements" do
80
+ before { Capybara.prefer_visible_elements = false }
81
+
82
+ it "should find invisible elements if no visible element exists" do
83
+ @session.first(:css, 'a#invisible')[:id].should == 'invisible'
84
+ end
85
+
86
+ it "should not prefer visible elements over invisible elements" do
87
+ @session.first(:css, 'a.visibility')[:id].should == 'invisible'
88
+ end
89
+
90
+ after { Capybara.prefer_visible_elements = true }
91
+ end
92
+
60
93
  context "within a scope" do
61
94
  before do
62
95
  @session.visit('/with_scope')
@@ -54,6 +54,11 @@ shared_examples_for "has_css" do
54
54
  @session.should_not have_css("abbr", :count => 2)
55
55
  @session.should_not have_css("p a.doesnotexist", :count => 1)
56
56
  end
57
+
58
+ it "should coerce count to an integer" do
59
+ @session.should have_css("p", :count => "3")
60
+ @session.should have_css("p a#foo", :count => "1")
61
+ end
57
62
  end
58
63
 
59
64
  context "with maximum" do
@@ -72,6 +77,11 @@ shared_examples_for "has_css" do
72
77
  @session.should_not have_css("abbr", :maximum => 2)
73
78
  @session.should_not have_css("p a.doesnotexist", :maximum => 1)
74
79
  end
80
+
81
+ it "should coerce maximum to an integer" do
82
+ @session.should have_css("h2.head", :maximum => "5") # edge case
83
+ @session.should have_css("h2", :maximum => "10")
84
+ end
75
85
  end
76
86
 
77
87
  context "with minimum" do
@@ -90,6 +100,11 @@ shared_examples_for "has_css" do
90
100
  @session.should_not have_css("abbr", :minimum => 2)
91
101
  @session.should_not have_css("p a.doesnotexist", :minimum => 7)
92
102
  end
103
+
104
+ it "should coerce minimum to an integer" do
105
+ @session.should have_css("h2.head", :minimum => "5") # edge case
106
+ @session.should have_css("h2", :minimum => "3")
107
+ end
93
108
  end
94
109
 
95
110
  context "with text" do
@@ -160,6 +175,11 @@ shared_examples_for "has_css" do
160
175
  @session.should have_no_css("abbr", :count => 2)
161
176
  @session.should have_no_css("p a.doesnotexist", :count => 1)
162
177
  end
178
+
179
+ it "should coerce count to an integer" do
180
+ @session.should_not have_no_css("p", :count => "3")
181
+ @session.should_not have_no_css("p a#foo", :count => "1")
182
+ end
163
183
  end
164
184
 
165
185
  context "with maximum" do
@@ -178,6 +198,11 @@ shared_examples_for "has_css" do
178
198
  @session.should have_no_css("abbr", :maximum => 5)
179
199
  @session.should have_no_css("p a.doesnotexist", :maximum => 10)
180
200
  end
201
+
202
+ it "should coerce maximum to an integer" do
203
+ @session.should_not have_no_css("h2.head", :maximum => "5") # edge case
204
+ @session.should_not have_no_css("h2", :maximum => "10")
205
+ end
181
206
  end
182
207
 
183
208
  context "with minimum" do
@@ -196,6 +221,11 @@ shared_examples_for "has_css" do
196
221
  @session.should have_no_css("abbr", :minimum => 5)
197
222
  @session.should have_no_css("p a.doesnotexist", :minimum => 10)
198
223
  end
224
+
225
+ it "should coerce minimum to an integer" do
226
+ @session.should_not have_no_css("h2.head", :minimum => "4") # edge case
227
+ @session.should_not have_no_css("h2", :minimum => "3")
228
+ end
199
229
  end
200
230
 
201
231
  context "with text" do
@@ -1,4 +1,4 @@
1
- shared_examples_for "has_field" do
1
+ shared_examples_for "has_field" do
2
2
  describe '#has_field' do
3
3
  before { @session.visit('/form') }
4
4
 
@@ -14,15 +14,15 @@ shared_examples_for "has_field" do
14
14
 
15
15
  context 'with value' do
16
16
  it "should be true if a field with the given value is on the page" do
17
- @session.should have_field('First Name', :with => 'John')
18
- @session.should have_field('Phone', :with => '+1 555 7021')
19
- @session.should have_field('Street', :with => 'Sesame street 66')
17
+ @session.should have_field('First Name', :with => 'John')
18
+ @session.should have_field('Phone', :with => '+1 555 7021')
19
+ @session.should have_field('Street', :with => 'Sesame street 66')
20
20
  @session.should have_field('Description', :with => 'Descriptive text goes here')
21
21
  end
22
22
 
23
23
  it "should be false if the given field is not on the page" do
24
- @session.should_not have_field('First Name', :with => 'Peter')
25
- @session.should_not have_field('Wrong Name', :with => 'John')
24
+ @session.should_not have_field('First Name', :with => 'Peter')
25
+ @session.should_not have_field('Wrong Name', :with => 'John')
26
26
  @session.should_not have_field('Description', :with => 'Monkey')
27
27
  end
28
28
 
@@ -53,15 +53,15 @@ shared_examples_for "has_field" do
53
53
 
54
54
  context 'with value' do
55
55
  it "should be false if a field with the given value is on the page" do
56
- @session.should_not have_no_field('First Name', :with => 'John')
57
- @session.should_not have_no_field('Phone', :with => '+1 555 7021')
58
- @session.should_not have_no_field('Street', :with => 'Sesame street 66')
56
+ @session.should_not have_no_field('First Name', :with => 'John')
57
+ @session.should_not have_no_field('Phone', :with => '+1 555 7021')
58
+ @session.should_not have_no_field('Street', :with => 'Sesame street 66')
59
59
  @session.should_not have_no_field('Description', :with => 'Descriptive text goes here')
60
60
  end
61
61
 
62
62
  it "should be true if the given field is not on the page" do
63
- @session.should have_no_field('First Name', :with => 'Peter')
64
- @session.should have_no_field('Wrong Name', :with => 'John')
63
+ @session.should have_no_field('First Name', :with => 'Peter')
64
+ @session.should have_no_field('Wrong Name', :with => 'John')
65
65
  @session.should have_no_field('Description', :with => 'Monkey')
66
66
  end
67
67
 
@@ -115,6 +115,24 @@ shared_examples_for "has_field" do
115
115
  end
116
116
  end
117
117
 
118
+ describe '#has_no_checked_field?' do
119
+ before { @session.visit('/form') }
120
+
121
+ it "should be false if a checked field is on the page" do
122
+ @session.should_not have_no_checked_field('gender_female')
123
+ @session.should_not have_no_checked_field('Hamster')
124
+ end
125
+
126
+ it "should be true if an unchecked field is on the page" do
127
+ @session.should have_no_checked_field('form_pets_cat')
128
+ @session.should have_no_checked_field('Male')
129
+ end
130
+
131
+ it "should be true if no field is on the page" do
132
+ @session.should have_no_checked_field('Does Not Exist')
133
+ end
134
+ end
135
+
118
136
  describe '#has_unchecked_field?' do
119
137
  before { @session.visit('/form') }
120
138
 
@@ -152,5 +170,23 @@ shared_examples_for "has_field" do
152
170
  @session.should have_unchecked_field('gender_female')
153
171
  end
154
172
  end
173
+
174
+ describe '#has_no_unchecked_field?' do
175
+ before { @session.visit('/form') }
176
+
177
+ it "should be true if a checked field is on the page" do
178
+ @session.should have_no_unchecked_field('gender_female')
179
+ @session.should have_no_unchecked_field('Hamster')
180
+ end
181
+
182
+ it "should be false if an unchecked field is on the page" do
183
+ @session.should_not have_no_unchecked_field('form_pets_cat')
184
+ @session.should_not have_no_unchecked_field('Male')
185
+ end
186
+
187
+ it "should be true if no field is on the page" do
188
+ @session.should have_no_unchecked_field('Does Not Exist')
189
+ end
190
+ end
155
191
  end
156
192