capybara 2.1.0 → 2.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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