capybara 2.1.0 → 2.2.0.rc1

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 (57) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/History.md +48 -1
  5. data/README.md +22 -18
  6. data/lib/capybara.rb +28 -3
  7. data/lib/capybara/cucumber.rb +0 -2
  8. data/lib/capybara/driver/base.rb +9 -1
  9. data/lib/capybara/empty.html +4 -0
  10. data/lib/capybara/node/actions.rb +1 -1
  11. data/lib/capybara/node/finders.rb +3 -3
  12. data/lib/capybara/node/matchers.rb +22 -18
  13. data/lib/capybara/node/simple.rb +5 -3
  14. data/lib/capybara/query.rb +1 -0
  15. data/lib/capybara/rack_test/browser.rb +5 -4
  16. data/lib/capybara/rack_test/form.rb +5 -2
  17. data/lib/capybara/rack_test/node.rb +2 -1
  18. data/lib/capybara/result.rb +2 -1
  19. data/lib/capybara/rspec.rb +7 -0
  20. data/lib/capybara/rspec/features.rb +2 -0
  21. data/lib/capybara/rspec/matchers.rb +6 -6
  22. data/lib/capybara/selector.rb +3 -1
  23. data/lib/capybara/selenium/driver.rb +14 -2
  24. data/lib/capybara/selenium/node.rb +18 -5
  25. data/lib/capybara/server.rb +3 -7
  26. data/lib/capybara/session.rb +59 -17
  27. data/lib/capybara/spec/public/test.js +1 -1
  28. data/lib/capybara/spec/session/assert_selector.rb +18 -0
  29. data/lib/capybara/spec/session/attach_file_spec.rb +5 -0
  30. data/lib/capybara/spec/session/check_spec.rb +14 -0
  31. data/lib/capybara/spec/session/choose_spec.rb +14 -0
  32. data/lib/capybara/spec/session/click_button_spec.rb +20 -1
  33. data/lib/capybara/spec/session/fill_in_spec.rb +18 -2
  34. data/lib/capybara/spec/session/go_back_spec.rb +10 -0
  35. data/lib/capybara/spec/session/go_forward_spec.rb +12 -0
  36. data/lib/capybara/spec/session/has_button_spec.rb +24 -0
  37. data/lib/capybara/spec/session/has_field_spec.rb +48 -0
  38. data/lib/capybara/spec/session/has_text_spec.rb +18 -0
  39. data/lib/capybara/spec/session/node_spec.rb +36 -1
  40. data/lib/capybara/spec/session/reset_session_spec.rb +17 -2
  41. data/lib/capybara/spec/session/save_page_spec.rb +10 -4
  42. data/lib/capybara/spec/session/visit_spec.rb +16 -0
  43. data/lib/capybara/spec/session/within_frame_spec.rb +7 -0
  44. data/lib/capybara/spec/session/within_window_spec.rb +7 -0
  45. data/lib/capybara/spec/test_app.rb +1 -0
  46. data/lib/capybara/spec/views/form.erb +40 -0
  47. data/lib/capybara/spec/views/with_html.erb +5 -0
  48. data/lib/capybara/spec/views/with_js.erb +8 -0
  49. data/lib/capybara/version.rb +1 -1
  50. data/spec/capybara_spec.rb +1 -1
  51. data/spec/result_spec.rb +14 -0
  52. data/spec/rspec/features_spec.rb +15 -0
  53. data/spec/rspec/matchers_spec.rb +24 -1
  54. data/spec/selenium_spec.rb +8 -1
  55. data/spec/server_spec.rb +13 -5
  56. metadata +78 -98
  57. metadata.gz.sig +0 -0
@@ -58,6 +58,16 @@ Capybara::SpecHelper.spec '#assert_selector' do
58
58
  expect { @session.assert_selector("//p//a", :text => /Red$/) }.to raise_error(Capybara::ElementNotFound)
59
59
  end
60
60
  end
61
+
62
+ context "with wait", :requires => [:js] do
63
+ it "should find element if it appears before given wait duration" do
64
+ Capybara.using_wait_time(0.1) do
65
+ @session.visit('/with_js')
66
+ @session.click_link('Click me')
67
+ @session.assert_selector(:css, "a#has-been-clicked", :text => "Has been clicked", :wait => 0.9)
68
+ end
69
+ end
70
+ end
61
71
  end
62
72
 
63
73
  Capybara::SpecHelper.spec '#assert_no_selector' do
@@ -120,4 +130,12 @@ Capybara::SpecHelper.spec '#assert_no_selector' do
120
130
  @session.assert_no_selector("//p//a", :text => /Red$/)
121
131
  end
122
132
  end
133
+
134
+ context "with wait", :requires => [:js] do
135
+ it "should not find element if it appears after given wait duration" do
136
+ @session.visit('/with_js')
137
+ @session.click_link('Click me')
138
+ @session.assert_no_selector(:css, "a#has-been-clicked", :text => "Has been clicked", :wait => 0.1)
139
+ end
140
+ end
123
141
  end
@@ -71,6 +71,11 @@ Capybara::SpecHelper.spec "#attach_file" do
71
71
  @session.body.should include(File.read(@test_file_path))
72
72
  @session.body.should include(File.read(@another_test_file_path))
73
73
  end
74
+
75
+ it "should not send anything when attaching no files to a multiple upload field" do
76
+ @session.click_button('Upload Empty Multiple')
77
+ @session.body.should include("Successfully ignored empty file field")
78
+ end
74
79
  end
75
80
 
76
81
  context "with a locator that doesn't exist" do
@@ -96,4 +96,18 @@ Capybara::SpecHelper.spec "#check" do
96
96
  end.to raise_error(Capybara::ElementNotFound)
97
97
  end
98
98
  end
99
+
100
+ context "with `option` option" do
101
+ it "can check boxes by their value" do
102
+ @session.check('form[pets][]', :option => "cat")
103
+ @session.click_button('awesome')
104
+ extract_results(@session)['pets'].should include('cat')
105
+ end
106
+
107
+ it "should raise an error if option not found" do
108
+ expect do
109
+ @session.check('form[pets][]', :option => "elephant")
110
+ end.to raise_error(Capybara::ElementNotFound)
111
+ end
112
+ end
99
113
  end
@@ -51,4 +51,18 @@ Capybara::SpecHelper.spec "#choose" do
51
51
  end.to raise_error(Capybara::ElementNotFound)
52
52
  end
53
53
  end
54
+
55
+ context "with `option` option" do
56
+ it "can check radio buttons by their value" do
57
+ @session.choose('form[gender]', :option => "male")
58
+ @session.click_button('awesome')
59
+ extract_results(@session)['gender'].should == "male"
60
+ end
61
+
62
+ it "should raise an error if option not found" do
63
+ expect do
64
+ @session.choose('form[gender]', :option => "hermaphrodite")
65
+ end.to raise_error(Capybara::ElementNotFound)
66
+ end
67
+ end
54
68
  end
@@ -102,10 +102,18 @@ Capybara::SpecHelper.spec '#click_button' do
102
102
  @results['gender'].should == 'female'
103
103
  end
104
104
 
105
+ it "should default radio value to 'on' if none specified" do
106
+ @results['valueless_radio'].should == 'on'
107
+ end
108
+
105
109
  it "should serialize check boxes" do
106
110
  @results['pets'].should include('dog', 'hamster')
107
111
  @results['pets'].should_not include('cat')
108
112
  end
113
+
114
+ it "should default checkbox value to 'on' if none specififed" do
115
+ @results['valueless_checkbox'].should == 'on'
116
+ end
109
117
 
110
118
  it "should serialize text areas" do
111
119
  @results['description'].should == 'Descriptive text goes here'
@@ -126,7 +134,11 @@ Capybara::SpecHelper.spec '#click_button' do
126
134
  it "should not serialize a select tag without options" do
127
135
  @results['tendency'].should be_nil
128
136
  end
129
-
137
+
138
+ it "should convert lf to cr/lf in submitted textareas" do
139
+ @results['newline'].should == "\r\nNew line after and before textarea tag\r\n"
140
+ end
141
+
130
142
  it "should not submit disabled fields" do
131
143
  @results['disabled_text_field'].should be_nil
132
144
  @results['disabled_textarea'].should be_nil
@@ -225,6 +237,12 @@ Capybara::SpecHelper.spec '#click_button' do
225
237
  end
226
238
  end
227
239
 
240
+ context "with submit button not associated with any form" do
241
+ it "should not error when clicked" do
242
+ lambda { @session.click_button('no_form_button') }.should_not raise_error
243
+ end
244
+ end
245
+
228
246
  context "with alt given on an image button" do
229
247
  it "should submit the associated form" do
230
248
  @session.click_button('oh hai thar')
@@ -236,6 +254,7 @@ Capybara::SpecHelper.spec '#click_button' do
236
254
  extract_results(@session)['first_name'].should == 'John'
237
255
  end
238
256
  end
257
+
239
258
 
240
259
  context "with value given on an image button" do
241
260
  it "should submit the associated form" do
@@ -57,6 +57,12 @@ Capybara::SpecHelper.spec "#fill_in" do
57
57
  extract_results(@session)['description'].should == 'is <strong>very</strong> secret!'
58
58
  end
59
59
 
60
+ it "should handle newlines in a textarea", tw: true do
61
+ @session.fill_in('form_description', :with => "\nSome text\n")
62
+ @session.click_button('awesome')
63
+ extract_results(@session)['description'].should == "\r\nSome text\r\n"
64
+ end
65
+
60
66
  it "should fill in a field with a custom type" do
61
67
  @session.fill_in('Schmooo', :with => 'Schmooo is the game')
62
68
  @session.click_button('awesome')
@@ -109,7 +115,7 @@ Capybara::SpecHelper.spec "#fill_in" do
109
115
  extract_results(@session)['first_name'].should == 'Harry'
110
116
  end
111
117
 
112
- it "casts to string if field has maxlength", :focus => true do
118
+ it "casts to string if field has maxlength" do
113
119
  @session.fill_in(:'form_zipcode', :with => 1234567)
114
120
  @session.click_button('awesome')
115
121
  extract_results(@session)['zipcode'].should == '12345'
@@ -119,7 +125,17 @@ Capybara::SpecHelper.spec "#fill_in" do
119
125
  it 'should only trigger onchange once' do
120
126
  @session.visit('/with_js')
121
127
  @session.fill_in('with_change_event', :with => 'some value')
122
- @session.find(:css, '#with_change_event').value.should == 'some value'
128
+ # click outside the field to trigger the change event
129
+ @session.find(:css, 'body').click
130
+ @session.find(:css, '.change_event_triggered', :match => :one).should have_text 'some value'
131
+ end
132
+
133
+ it 'should trigger change when clearing field' do
134
+ @session.visit('/with_js')
135
+ @session.fill_in('with_change_event', :with => '')
136
+ # click outside the field to trigger the change event
137
+ @session.find(:css, 'body').click
138
+ @session.should have_selector(:css, '.change_event_triggered', :match => :one)
123
139
  end
124
140
  end
125
141
 
@@ -0,0 +1,10 @@
1
+ Capybara::SpecHelper.spec '#go_back', :requires => [:js] do
2
+ it "should fetch a response from the driver from the previous page" do
3
+ @session.visit('/')
4
+ @session.should have_content('Hello world!')
5
+ @session.visit('/foo')
6
+ @session.should have_content('Another World')
7
+ @session.go_back
8
+ @session.should have_content('Hello world!')
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ Capybara::SpecHelper.spec '#go_forward', :requires => [:js] do
2
+ it "should fetch a response from the driver from the previous page" do
3
+ @session.visit('/')
4
+ @session.should have_content('Hello world!')
5
+ @session.visit('/foo')
6
+ @session.should have_content('Another World')
7
+ @session.go_back
8
+ @session.should have_content('Hello world!')
9
+ @session.go_forward
10
+ @session.should have_content('Another World')
11
+ end
12
+ end
@@ -9,9 +9,21 @@ Capybara::SpecHelper.spec '#has_button?' do
9
9
  @session.should have_button(:'crap321')
10
10
  end
11
11
 
12
+ it "should be true for disabled buttons if :disabled => true" do
13
+ @session.should have_button('Disabled button', :disabled => true)
14
+ end
15
+
12
16
  it "should be false if the given button is not on the page" do
13
17
  @session.should_not have_button('monkey')
14
18
  end
19
+
20
+ it "should be false for disabled buttons by default" do
21
+ @session.should_not have_button('Disabled button')
22
+ end
23
+
24
+ it "should be false for disabled buttons if :disabled => false" do
25
+ @session.should_not have_button('Disabled button', :disabled => false)
26
+ end
15
27
  end
16
28
 
17
29
  Capybara::SpecHelper.spec '#has_no_button?' do
@@ -24,7 +36,19 @@ Capybara::SpecHelper.spec '#has_no_button?' do
24
36
  @session.should_not have_no_button('crap321')
25
37
  end
26
38
 
39
+ it "should be true for disabled buttons if :disabled => true" do
40
+ @session.should_not have_no_button('Disabled button', :disabled => true)
41
+ end
42
+
27
43
  it "should be false if the given button is not on the page" do
28
44
  @session.should have_no_button('monkey')
29
45
  end
46
+
47
+ it "should be false for disabled buttons by default" do
48
+ @session.should have_no_button('Disabled button')
49
+ end
50
+
51
+ it "should be false for disabled buttons if :disabled => false" do
52
+ @session.should have_no_button('Disabled button', :disabled => false)
53
+ end
30
54
  end
@@ -121,6 +121,10 @@ Capybara::SpecHelper.spec '#has_checked_field?' do
121
121
  @session.should have_checked_field('Hamster')
122
122
  end
123
123
 
124
+ it "should be true for disabled checkboxes if :disabled => true" do
125
+ @session.should have_checked_field('Disabled Checkbox', :disabled => true)
126
+ end
127
+
124
128
  it "should be false if an unchecked field is on the page" do
125
129
  @session.should_not have_checked_field('form_pets_cat')
126
130
  @session.should_not have_checked_field('Male')
@@ -130,6 +134,14 @@ Capybara::SpecHelper.spec '#has_checked_field?' do
130
134
  @session.should_not have_checked_field('Does Not Exist')
131
135
  end
132
136
 
137
+ it "should be false for disabled checkboxes by default" do
138
+ @session.should_not have_checked_field('Disabled Checkbox')
139
+ end
140
+
141
+ it "should be false for disabled checkboxes if :disabled => false" do
142
+ @session.should_not have_checked_field('Disabled Checkbox', :disabled => false)
143
+ end
144
+
133
145
  it "should be true after an unchecked checkbox is checked" do
134
146
  @session.check('form_pets_cat')
135
147
  @session.should have_checked_field('form_pets_cat')
@@ -159,6 +171,10 @@ Capybara::SpecHelper.spec '#has_no_checked_field?' do
159
171
  @session.should_not have_no_checked_field('Hamster')
160
172
  end
161
173
 
174
+ it "should be false for disabled checkboxes if :disabled => true" do
175
+ @session.should_not have_no_checked_field('Disabled Checkbox', :disabled => true)
176
+ end
177
+
162
178
  it "should be true if an unchecked field is on the page" do
163
179
  @session.should have_no_checked_field('form_pets_cat')
164
180
  @session.should have_no_checked_field('Male')
@@ -167,6 +183,14 @@ Capybara::SpecHelper.spec '#has_no_checked_field?' do
167
183
  it "should be true if no field is on the page" do
168
184
  @session.should have_no_checked_field('Does Not Exist')
169
185
  end
186
+
187
+ it "should be true for disabled checkboxes by default" do
188
+ @session.should have_no_checked_field('Disabled Checkbox')
189
+ end
190
+
191
+ it "should be true for disabled checkboxes if :disabled => false" do
192
+ @session.should have_no_checked_field('Disabled Checkbox', :disabled => false)
193
+ end
170
194
  end
171
195
 
172
196
  Capybara::SpecHelper.spec '#has_unchecked_field?' do
@@ -182,10 +206,22 @@ Capybara::SpecHelper.spec '#has_unchecked_field?' do
182
206
  @session.should have_unchecked_field('Male')
183
207
  end
184
208
 
209
+ it "should be true for disabled unchecked fields if :disabled => true" do
210
+ @session.should have_unchecked_field('Disabled Unchecked Checkbox', :disabled => true)
211
+ end
212
+
185
213
  it "should be false if no field is on the page" do
186
214
  @session.should_not have_unchecked_field('Does Not Exist')
187
215
  end
188
216
 
217
+ it "should be false for disabled unchecked fields by default" do
218
+ @session.should_not have_unchecked_field('Disabled Unchecked Checkbox')
219
+ end
220
+
221
+ it "should be false for disabled unchecked fields if :disabled => false" do
222
+ @session.should_not have_unchecked_field('Disabled Unchecked Checkbox', :disabled => false)
223
+ end
224
+
189
225
  it "should be false after an unchecked checkbox is checked" do
190
226
  @session.check('form_pets_cat')
191
227
  @session.should_not have_unchecked_field('form_pets_cat')
@@ -220,7 +256,19 @@ Capybara::SpecHelper.spec '#has_no_unchecked_field?' do
220
256
  @session.should_not have_no_unchecked_field('Male')
221
257
  end
222
258
 
259
+ it "should be false for disabled unchecked fields if :disabled => true" do
260
+ @session.should_not have_no_unchecked_field('Disabled Unchecked Checkbox', :disabled => true)
261
+ end
262
+
223
263
  it "should be true if no field is on the page" do
224
264
  @session.should have_no_unchecked_field('Does Not Exist')
225
265
  end
266
+
267
+ it "should be true for disabled unchecked fields by default" do
268
+ @session.should have_no_unchecked_field('Disabled Unchecked Checkbox')
269
+ end
270
+
271
+ it "should be true for disabled unchecked fields if :disabled => false" do
272
+ @session.should have_no_unchecked_field('Disabled Unchecked Checkbox', :disabled => false)
273
+ end
226
274
  end
@@ -190,6 +190,16 @@ Capybara::SpecHelper.spec '#has_text?' do
190
190
  @session.should_not have_text('count', minimum: '3')
191
191
  end
192
192
  end
193
+
194
+ context "with wait", :requires => [:js] do
195
+ it "should find element if it appears before given wait duration" do
196
+ Capybara.using_wait_time(0.1) do
197
+ @session.visit('/with_js')
198
+ @session.click_link('Click me')
199
+ @session.should have_text('Has been clicked', :wait => 0.9)
200
+ end
201
+ end
202
+ end
193
203
  end
194
204
 
195
205
  Capybara::SpecHelper.spec '#has_no_text?' do
@@ -288,4 +298,12 @@ Capybara::SpecHelper.spec '#has_no_text?' do
288
298
  @session.click_link('Click me')
289
299
  @session.should have_no_text("I changed it")
290
300
  end
301
+
302
+ context "with wait", :requires => [:js] do
303
+ it "should not find element if it appears after given wait duration" do
304
+ @session.visit('/with_js')
305
+ @session.click_link('Click me')
306
+ @session.should have_no_text('Has been clicked', :wait => 0.1)
307
+ end
308
+ end
291
309
  end
@@ -58,10 +58,25 @@ Capybara::SpecHelper.spec "node" do
58
58
  @session.find('//textarea[@id="additional_newline"]').value.should == "\nbanana"
59
59
  end
60
60
 
61
+ it "should not swallow leading newlines for set content in textarea" do
62
+ @session.find('//textarea[@id="normal"]').set("\nbanana")
63
+ @session.find('//textarea[@id="normal"]').value.should == "\nbanana"
64
+ end
65
+
61
66
  it "return any HTML content in textarea" do
62
67
  @session.find('//textarea[1]').set("some <em>html</em> here")
63
68
  @session.find('//textarea[1]').value.should == "some <em>html</em> here"
64
69
  end
70
+
71
+ it "defaults to 'on' for checkbox" do
72
+ @session.visit('/form')
73
+ @session.find('//input[@id="valueless_checkbox"]').value.should == 'on'
74
+ end
75
+
76
+ it "defaults to 'on' for radio buttons" do
77
+ @session.visit('/form')
78
+ @session.find('//input[@id="valueless_radio"]').value.should == 'on'
79
+ end
65
80
  end
66
81
 
67
82
  describe "#set" do
@@ -88,6 +103,25 @@ Capybara::SpecHelper.spec "node" do
88
103
  @session.first('//textarea[@readonly]').set('changed')
89
104
  @session.first('//textarea[@readonly]').value.should == 'textarea should not change'
90
105
  end
106
+
107
+ it 'should allow me to change the contents of a contenteditable element', :requires => [:js] do
108
+ @session.visit('/with_js')
109
+ @session.find(:css,'#existing_content_editable').set('WYSIWYG')
110
+ @session.find(:css,'#existing_content_editable').text.should == 'WYSIWYG'
111
+ end
112
+
113
+ it 'should allow me to set the contents of a contenteditable element', :requires => [:js] do
114
+ @session.visit('/with_js')
115
+ @session.find(:css,'#blank_content_editable').set('WYSIWYG')
116
+ @session.find(:css,'#blank_content_editable').text.should == 'WYSIWYG'
117
+ end
118
+
119
+ it 'should allow me to change the contents of a contenteditable elements child', :requires => [:js] do
120
+ pending "Selenium doesn't like editing nested contents"
121
+ @session.visit('/with_js')
122
+ @session.find(:css,'#existing_content_editable_child').set('WYSIWYG')
123
+ @session.find(:css,'#existing_content_editable_child').text.should == 'WYSIWYG'
124
+ end
91
125
  end
92
126
 
93
127
  describe "#tag_name" do
@@ -125,6 +159,8 @@ Capybara::SpecHelper.spec "node" do
125
159
 
126
160
  @session.find('//div[@id="hidden"]').should_not be_visible
127
161
  @session.find('//div[@id="hidden_via_ancestor"]').should_not be_visible
162
+ @session.find('//div[@id="hidden_attr"]').should_not be_visible
163
+ @session.find('//a[@id="hidden_attr_via_ancestor"]').should_not be_visible
128
164
  end
129
165
  end
130
166
 
@@ -178,7 +214,6 @@ Capybara::SpecHelper.spec "node" do
178
214
 
179
215
  describe '#hover', :requires => [:hover] do
180
216
  it "should allow hovering on an element" do
181
- pending "Selenium with firefox doesn't currently work with this (selenium with chrome does)" if @session.respond_to?(:mode) && @session.mode == :selenium && @session.driver.browser.browser == :firefox
182
217
  @session.visit('/with_hover')
183
218
  @session.find(:css,'.hidden_until_hover', :visible => false).should_not be_visible
184
219
  @session.find(:css,'.wrapper').hover
@@ -16,9 +16,18 @@ Capybara::SpecHelper.spec '#reset_session!' do
16
16
  @session.current_path.should == '/foo'
17
17
 
18
18
  @session.reset_session!
19
- [nil, '', 'about:blank'].should include @session.current_url
19
+ [
20
+ ->(v) { v == nil },
21
+ ->(v) { v == '' },
22
+ ->(v) { v == 'about:blank' },
23
+ ->(v) { v.end_with? Capybara::EMPTY_HTML_FILE_PATH } # allow file:// protocol
24
+ ].any? { |p| p.(@session.current_url) }.should be_true
25
+ [
26
+ ->(v) { v == '' },
27
+ ->(v) { v == nil },
28
+ ->(v) { v == Capybara::EMPTY_HTML_FILE_PATH }
29
+ ].any? { |p| p.(@session.current_path) }.should be_true
20
30
  @session.current_host.should be_nil
21
- @session.current_path.should be_nil
22
31
  end
23
32
 
24
33
  it "resets page body" do
@@ -31,6 +40,12 @@ Capybara::SpecHelper.spec '#reset_session!' do
31
40
  @session.should have_no_selector('.//h1')
32
41
  end
33
42
 
43
+ it "is synchronous" do
44
+ @session.visit("/with_html")
45
+ @session.reset_session!
46
+ @session.should have_no_selector :xpath, "/html/body/*", wait: false
47
+ end
48
+
34
49
  it "raises any errors caught inside the server", :requires => [:server] do
35
50
  quietly { @session.visit("/error") }
36
51
  expect do