capybara 2.0.0.beta2 → 2.0.0.beta4

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 (93) hide show
  1. data/History.txt +30 -1
  2. data/README.md +52 -31
  3. data/lib/capybara.rb +1 -0
  4. data/lib/capybara/driver/base.rb +1 -1
  5. data/lib/capybara/driver/node.rb +1 -0
  6. data/lib/capybara/dsl.rb +12 -5
  7. data/lib/capybara/helpers.rb +33 -0
  8. data/lib/capybara/node/actions.rb +4 -2
  9. data/lib/capybara/node/base.rb +52 -1
  10. data/lib/capybara/node/element.rb +0 -12
  11. data/lib/capybara/node/finders.rb +1 -1
  12. data/lib/capybara/node/matchers.rb +57 -47
  13. data/lib/capybara/node/simple.rb +4 -0
  14. data/lib/capybara/query.rb +11 -11
  15. data/lib/capybara/rack_test/browser.rb +14 -15
  16. data/lib/capybara/rack_test/driver.rb +2 -2
  17. data/lib/capybara/rack_test/node.rb +15 -2
  18. data/lib/capybara/result.rb +7 -19
  19. data/lib/capybara/rspec.rb +7 -4
  20. data/lib/capybara/rspec/features.rb +4 -1
  21. data/lib/capybara/rspec/matchers.rb +8 -3
  22. data/lib/capybara/selector.rb +1 -2
  23. data/lib/capybara/selenium/driver.rb +2 -2
  24. data/lib/capybara/selenium/node.rb +9 -7
  25. data/lib/capybara/session.rb +47 -31
  26. data/lib/capybara/spec/fixtures/another_test_file.txt +1 -0
  27. data/lib/capybara/spec/public/test.js +1 -1
  28. data/lib/capybara/spec/session/all_spec.rb +60 -62
  29. data/lib/capybara/spec/session/assert_selector.rb +123 -0
  30. data/lib/capybara/spec/session/attach_file_spec.rb +72 -58
  31. data/lib/capybara/spec/session/body_spec.rb +21 -0
  32. data/lib/capybara/spec/session/check_spec.rb +67 -50
  33. data/lib/capybara/spec/session/choose_spec.rb +32 -21
  34. data/lib/capybara/spec/session/click_button_spec.rb +261 -221
  35. data/lib/capybara/spec/session/click_link_or_button_spec.rb +40 -30
  36. data/lib/capybara/spec/session/click_link_spec.rb +95 -81
  37. data/lib/capybara/spec/session/current_url_spec.rb +70 -60
  38. data/lib/capybara/spec/session/evaluate_script_spec.rb +6 -0
  39. data/lib/capybara/spec/session/execute_script_spec.rb +7 -0
  40. data/lib/capybara/spec/session/fill_in_spec.rb +118 -92
  41. data/lib/capybara/spec/session/find_button_spec.rb +16 -14
  42. data/lib/capybara/spec/session/find_by_id_spec.rb +16 -14
  43. data/lib/capybara/spec/session/find_field_spec.rb +23 -21
  44. data/lib/capybara/spec/session/find_link_spec.rb +15 -14
  45. data/lib/capybara/spec/session/find_spec.rb +96 -91
  46. data/lib/capybara/spec/session/first_spec.rb +53 -55
  47. data/lib/capybara/spec/session/has_button_spec.rb +22 -24
  48. data/lib/capybara/spec/session/has_css_spec.rb +190 -205
  49. data/lib/capybara/spec/session/has_field_spec.rb +167 -169
  50. data/lib/capybara/spec/session/has_link_spec.rb +26 -29
  51. data/lib/capybara/spec/session/has_select_spec.rb +175 -176
  52. data/lib/capybara/spec/session/has_selector_spec.rb +94 -100
  53. data/lib/capybara/spec/session/has_table_spec.rb +22 -26
  54. data/lib/capybara/spec/session/has_text_spec.rb +159 -132
  55. data/lib/capybara/spec/session/has_xpath_spec.rb +100 -96
  56. data/lib/capybara/spec/session/headers.rb +4 -17
  57. data/lib/capybara/spec/session/html_spec.rb +15 -0
  58. data/lib/capybara/spec/session/node_spec.rb +172 -82
  59. data/lib/capybara/spec/session/reset_session_spec.rb +42 -0
  60. data/lib/capybara/spec/session/response_code.rb +4 -17
  61. data/lib/capybara/spec/session/save_page_spec.rb +46 -0
  62. data/lib/capybara/spec/session/screenshot.rb +8 -24
  63. data/lib/capybara/spec/session/select_spec.rb +100 -89
  64. data/lib/capybara/spec/session/source_spec.rb +12 -0
  65. data/lib/capybara/spec/session/text_spec.rb +15 -17
  66. data/lib/capybara/spec/session/uncheck_spec.rb +22 -17
  67. data/lib/capybara/spec/session/unselect_spec.rb +57 -52
  68. data/lib/capybara/spec/session/visit_spec.rb +58 -60
  69. data/lib/capybara/spec/session/within_frame_spec.rb +24 -26
  70. data/lib/capybara/spec/session/within_spec.rb +119 -121
  71. data/lib/capybara/spec/session/within_window_spec.rb +29 -31
  72. data/lib/capybara/spec/spec_helper.rb +84 -0
  73. data/lib/capybara/spec/test_app.rb +5 -3
  74. data/lib/capybara/spec/views/form.erb +1 -0
  75. data/lib/capybara/spec/views/with_html.erb +6 -1
  76. data/lib/capybara/spec/views/with_js.erb +1 -0
  77. data/lib/capybara/version.rb +1 -1
  78. data/spec/basic_node_spec.rb +2 -2
  79. data/spec/capybara_spec.rb +9 -0
  80. data/spec/dsl_spec.rb +22 -10
  81. data/spec/rack_test_spec.rb +28 -23
  82. data/spec/result_spec.rb +51 -0
  83. data/spec/rspec/features_spec.rb +19 -0
  84. data/spec/rspec/matchers_spec.rb +6 -0
  85. data/spec/rspec_spec.rb +1 -1
  86. data/spec/selenium_spec.rb +11 -25
  87. data/spec/server_spec.rb +2 -2
  88. data/spec/spec_helper.rb +1 -46
  89. metadata +41 -98
  90. data/lib/capybara/spec/session.rb +0 -183
  91. data/lib/capybara/spec/session/javascript.rb +0 -290
  92. data/lib/capybara/util/save_and_open_page.rb +0 -45
  93. data/spec/save_and_open_page_spec.rb +0 -155
@@ -1,183 +0,0 @@
1
- require 'capybara/spec/test_app'
2
- require 'nokogiri'
3
-
4
- Dir[File.dirname(__FILE__)+'/session/*'].each { |group| require group }
5
-
6
- module Quietly
7
- def silence_stream(stream)
8
- old_stream = stream.dup
9
- stream.reopen(RbConfig::CONFIG['host_os'] =~ /rmswin|mingw/ ? 'NUL:' : '/dev/null')
10
- stream.sync = true
11
- yield
12
- ensure
13
- stream.reopen(old_stream)
14
- end
15
-
16
- def quietly
17
- silence_stream(STDOUT) do
18
- silence_stream(STDERR) do
19
- yield
20
- end
21
- end
22
- end
23
- end
24
-
25
- shared_examples_for "session" do
26
- def extract_results(session)
27
- YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.text.lstrip
28
- end
29
-
30
- include Quietly
31
-
32
- after do
33
- @session.reset_session!
34
- end
35
-
36
- describe '#body' do
37
- it "should return the unmodified page body" do
38
- @session.visit('/')
39
- @session.body.should include('Hello world!')
40
- end
41
-
42
- if "".respond_to?(:encoding)
43
- context "encoding of response between ascii and utf8" do
44
- it "should be valid with html entities" do
45
- @session.visit('/with_html_entities')
46
- lambda { @session.body.encode!("UTF-8") }.should_not raise_error
47
- end
48
-
49
- it "should be valid without html entities" do
50
- @session.visit('/with_html')
51
- lambda { @session.body.encode!("UTF-8") }.should_not raise_error
52
- end
53
- end
54
- end
55
- end
56
-
57
- describe '#html' do
58
- it "should return the unmodified page body" do
59
- # html and body should be aliased, but we can't just check for
60
- # method(:html) == method(:body) because these shared examples get run
61
- # against the DSL, which uses forwarding methods. So we test behavior.
62
- @session.visit('/')
63
- @session.html.should include('Hello world!')
64
- end
65
- end
66
-
67
- describe '#source' do
68
- it "should return the unmodified page source" do
69
- @session.visit('/')
70
- @session.source.should include('Hello world!')
71
- end
72
- end
73
-
74
- describe '#reset_session!' do
75
- it "removes cookies" do
76
- @session.visit('/set_cookie')
77
- @session.visit('/get_cookie')
78
- @session.body.should include('test_cookie')
79
-
80
- @session.reset_session!
81
- @session.visit('/get_cookie')
82
- @session.body.should_not include('test_cookie')
83
- end
84
-
85
- it "resets current url, host, path" do
86
- @session.visit '/foo'
87
- @session.current_url.should_not be_empty
88
- @session.current_host.should_not be_empty
89
- @session.current_path.should == '/foo'
90
-
91
- @session.reset_session!
92
- [nil, '', 'about:blank'].should include @session.current_url
93
- @session.current_host.should be_nil
94
- @session.current_path.should be_nil
95
- end
96
-
97
- it "resets page body" do
98
- @session.visit('/with_html')
99
- @session.body.should include('This is a test')
100
- @session.find('.//h1').text.should include('This is a test')
101
-
102
- @session.reset_session!
103
- @session.body.should_not include('This is a test')
104
- @session.should have_no_selector('.//h1')
105
- end
106
-
107
- it "raises any errors caught inside the server" do
108
- expect do
109
- quietly { @session.visit("/error") }
110
- @session.reset_session!
111
- end.to raise_error(TestApp::TestAppError)
112
- @session.visit("/")
113
- @session.current_path.should == "/"
114
- end
115
- end
116
-
117
- it_should_behave_like "node"
118
- it_should_behave_like "visit"
119
- it_should_behave_like "all"
120
- it_should_behave_like "first"
121
- it_should_behave_like "attach_file"
122
- it_should_behave_like "check"
123
- it_should_behave_like "choose"
124
- it_should_behave_like "click_link_or_button"
125
- it_should_behave_like "click_button"
126
- it_should_behave_like "click_link"
127
- it_should_behave_like "fill_in"
128
- it_should_behave_like "find_button"
129
- it_should_behave_like "find_field"
130
- it_should_behave_like "find_link"
131
- it_should_behave_like "find_by_id"
132
- it_should_behave_like "find"
133
- it_should_behave_like "has_text"
134
- it_should_behave_like "has_css"
135
- it_should_behave_like "has_selector"
136
- it_should_behave_like "has_xpath"
137
- it_should_behave_like "has_link"
138
- it_should_behave_like "has_button"
139
- it_should_behave_like "has_field"
140
- it_should_behave_like "has_select"
141
- it_should_behave_like "has_table"
142
- it_should_behave_like "select"
143
- it_should_behave_like "text"
144
- it_should_behave_like "uncheck"
145
- it_should_behave_like "unselect"
146
- it_should_behave_like "within"
147
- it_should_behave_like "current_url"
148
-
149
- it "should encode complex field names, like array[][value]" do
150
- @session.visit('/form')
151
- @session.fill_in('address1_city', :with =>'Paris')
152
- @session.fill_in('address1_street', :with =>'CDG')
153
- @session.fill_in('address1_street', :with =>'CDG')
154
- @session.select("France", :from => 'address1_country')
155
-
156
- @session.fill_in('address2_city', :with => 'Mikolaiv')
157
- @session.fill_in('address2_street', :with => 'PGS')
158
- @session.select("Ukraine", :from => 'address2_country')
159
-
160
- @session.click_button "awesome"
161
-
162
- addresses=extract_results(@session)["addresses"]
163
- addresses.should have(2).addresses
164
-
165
- addresses[0]["street"].should == 'CDG'
166
- addresses[0]["city"].should == 'Paris'
167
- addresses[0]["country"].should == 'France'
168
-
169
- addresses[1]["street"].should == 'PGS'
170
- addresses[1]["city"].should == 'Mikolaiv'
171
- addresses[1]["country"].should == 'Ukraine'
172
- end
173
- end
174
-
175
- describe Capybara::Session do
176
- context 'with non-existant driver' do
177
- it "should raise an error" do
178
- running {
179
- Capybara::Session.new(:quox, TestApp).driver
180
- }.should raise_error(Capybara::DriverNotFoundError)
181
- end
182
- end
183
- end
@@ -1,290 +0,0 @@
1
- shared_examples_for "session with javascript support" do
2
- describe 'all JS specs' do
3
- before do
4
- Capybara.default_wait_time = 1
5
- end
6
-
7
- after do
8
- Capybara.default_wait_time = 0
9
- end
10
-
11
- describe 'Node#drag_to' do
12
- it "should drag and drop an object" do
13
- @session.visit('/with_js')
14
- element = @session.find('//div[@id="drag"]')
15
- target = @session.find('//div[@id="drop"]')
16
- element.drag_to(target)
17
- @session.find('//div[contains(., "Dropped!")]').should_not be_nil
18
- end
19
- end
20
-
21
- describe 'Node#reload' do
22
- context "without automatic reload" do
23
- before { Capybara.automatic_reload = false }
24
- it "should reload the current context of the node" do
25
- @session.visit('/with_js')
26
- node = @session.find(:css, '#reload-me')
27
- @session.click_link('Reload!')
28
- sleep(0.3)
29
- node.reload.text.should == 'RELOADED'
30
- node.text.should == 'RELOADED'
31
- end
32
-
33
- it "should reload a parent node" do
34
- @session.visit('/with_js')
35
- node = @session.find(:css, '#reload-me').find(:css, 'em')
36
- @session.click_link('Reload!')
37
- sleep(0.3)
38
- node.reload.text.should == 'RELOADED'
39
- node.text.should == 'RELOADED'
40
- end
41
-
42
- it "should not automatically reload" do
43
- @session.visit('/with_js')
44
- node = @session.find(:css, '#reload-me')
45
- @session.click_link('Reload!')
46
- sleep(0.3)
47
- running { node.text.should == 'RELOADED' }.should raise_error
48
- end
49
- after { Capybara.automatic_reload = true }
50
- end
51
-
52
- context "with automatic reload" do
53
- it "should reload the current context of the node automatically" do
54
- @session.visit('/with_js')
55
- node = @session.find(:css, '#reload-me')
56
- @session.click_link('Reload!')
57
- sleep(0.3)
58
- node.text.should == 'RELOADED'
59
- end
60
-
61
- it "should reload a parent node automatically" do
62
- @session.visit('/with_js')
63
- node = @session.find(:css, '#reload-me').find(:css, 'em')
64
- @session.click_link('Reload!')
65
- sleep(0.3)
66
- node.text.should == 'RELOADED'
67
- end
68
-
69
- it "should reload a node automatically when using find" do
70
- @session.visit('/with_js')
71
- node = @session.find(:css, '#reload-me')
72
- @session.click_link('Reload!')
73
- sleep(0.3)
74
- node.find(:css, 'a').text.should == 'RELOADED'
75
- end
76
-
77
- it "should not reload nodes which haven't been found" do
78
- @session.visit('/with_js')
79
- node = @session.all(:css, '#the-list li')[1]
80
- @session.click_link('Fetch new list!')
81
- sleep(0.3)
82
- running { node.text.should == 'Foo' }.should raise_error
83
- running { node.text.should == 'Bar' }.should raise_error
84
- end
85
- end
86
- end
87
-
88
- describe '#find' do
89
- it "should allow triggering of custom JS events" do
90
- # Not supported by Selenium without resorting to JavaScript execution
91
- # http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_How_can_I_trigger_arbitrary_events_on_the_page?
92
- unless @session.mode == :selenium
93
- @session.visit('/with_js')
94
- @session.find(:css, '#with_focus_event').trigger(:focus)
95
- @session.should have_css('#focus_event_triggered')
96
- end
97
- end
98
- end
99
-
100
- describe '#html' do
101
- it "should return the current state of the page" do
102
- @session.visit('/with_js')
103
- @session.html.should include('I changed it')
104
- @session.html.should_not include('This is text')
105
- end
106
- end
107
-
108
- [:body, :source].each do |method|
109
- describe "##{method}" do
110
- it "should return the original, unmodified source of the page" do
111
- # Not supported by Selenium. See for example
112
- # http://stackoverflow.com/questions/6050805
113
- unless @session.mode == :selenium
114
- @session.visit('/with_js')
115
- @session.send(method).should include('This is text')
116
- @session.send(method).should_not include('I changed it')
117
- end
118
- end
119
- end
120
- end
121
-
122
- describe "#evaluate_script" do
123
- it "should evaluate the given script and return whatever it produces" do
124
- @session.visit('/with_js')
125
- @session.evaluate_script("1+3").should == 4
126
- end
127
- end
128
-
129
- describe "#execute_script" do
130
- it "should execute the given script and return nothing" do
131
- @session.visit('/with_js')
132
- @session.execute_script("$('#change').text('Funky Doodle')").should be_nil
133
- @session.should have_css('#change', :text => 'Funky Doodle')
134
- end
135
- end
136
-
137
- describe '#find' do
138
- it "should wait for asynchronous load" do
139
- @session.visit('/with_js')
140
- @session.click_link('Click me')
141
- @session.find(:css, "a#has-been-clicked").text.should include('Has been clicked')
142
- end
143
-
144
- context "with frozen time" do
145
- it "raises an error suggesting that Capybara is stuck in time" do
146
- @session.visit('/with_js')
147
- now = Time.now
148
- Time.stub(:now).and_return(now)
149
- expect { @session.find('//isnotthere') }.to raise_error(Capybara::FrozenInTime)
150
- end
151
- end
152
- end
153
-
154
- describe '#click_link_or_button' do
155
- it "should wait for asynchronous load" do
156
- @session.visit('/with_js')
157
- @session.click_link('Click me')
158
- @session.click_link_or_button('Has been clicked')
159
- end
160
- end
161
-
162
- describe '#click_link' do
163
- it "should wait for asynchronous load" do
164
- @session.visit('/with_js')
165
- @session.click_link('Click me')
166
- @session.click_link('Has been clicked')
167
- end
168
- end
169
-
170
- describe '#click_button' do
171
- it "should wait for asynchronous load" do
172
- @session.visit('/with_js')
173
- @session.click_link('Click me')
174
- @session.click_button('New Here')
175
- end
176
- end
177
-
178
- describe '#fill_in' do
179
- it "should wait for asynchronous load" do
180
- @session.visit('/with_js')
181
- @session.click_link('Click me')
182
- @session.fill_in('new_field', :with => 'Testing...')
183
- end
184
-
185
- context 'on a pre-populated textfield with a reformatting onchange' do
186
- it 'should only trigger onchange once' do
187
- @session.fill_in('with_change_event', :with => 'some value')
188
- @session.find(:css, '#with_change_event').value.should == 'some value'
189
- end
190
- end
191
- end
192
-
193
- describe '#check' do
194
- it "should trigger associated events" do
195
- @session.visit('/with_js')
196
- @session.check('checkbox_with_event')
197
- @session.should have_css('#checkbox_event_triggered');
198
- end
199
- end
200
-
201
- describe '#has_xpath?' do
202
- it "should wait for content to appear" do
203
- @session.visit('/with_js')
204
- @session.click_link('Click me')
205
- @session.should have_xpath("//input[@type='submit' and @value='New Here']")
206
- end
207
- end
208
-
209
- describe '#has_no_xpath?' do
210
- it "should wait for content to disappear" do
211
- @session.visit('/with_js')
212
- @session.click_link('Click me')
213
- @session.should have_no_xpath("//p[@id='change']")
214
- end
215
- end
216
-
217
- describe '#has_css?' do
218
- it "should wait for content to appear" do
219
- @session.visit('/with_js')
220
- @session.click_link('Click me')
221
- @session.should have_css("input[type='submit'][value='New Here']")
222
- end
223
- end
224
-
225
- describe '#has_no_xpath?' do
226
- it "should wait for content to disappear" do
227
- @session.visit('/with_js')
228
- @session.click_link('Click me')
229
- @session.should have_no_css("p#change")
230
- end
231
- end
232
-
233
- describe '#has_content?' do
234
- it "should wait for content to appear" do
235
- @session.visit('/with_js')
236
- @session.click_link('Click me')
237
- @session.should have_content("Has been clicked")
238
- end
239
- end
240
-
241
- describe '#has_no_content?' do
242
- it "should wait for content to disappear" do
243
- @session.visit('/with_js')
244
- @session.click_link('Click me')
245
- @session.should have_no_content("I changed it")
246
- end
247
- end
248
-
249
- describe '#has_text?' do
250
- it "should wait for text to appear" do
251
- @session.visit('/with_js')
252
- @session.click_link('Click me')
253
- @session.should have_text("Has been clicked")
254
- end
255
- end
256
-
257
- describe '#has_no_text?' do
258
- it "should wait for text to disappear" do
259
- @session.visit('/with_js')
260
- @session.click_link('Click me')
261
- @session.should have_no_text("I changed it")
262
- end
263
- end
264
-
265
- describe "#current_path" do
266
- it "is affected by pushState" do
267
- @session.visit("/with_js")
268
- @session.execute_script("window.history.pushState({}, '', '/pushed')")
269
- @session.current_path.should == "/pushed"
270
- end
271
-
272
- it "is affected by replaceState" do
273
- @session.visit("/with_js")
274
- @session.execute_script("window.history.replaceState({}, '', '/replaced')")
275
- @session.current_path.should == "/replaced"
276
- end
277
- end
278
- end
279
- end
280
-
281
- shared_examples_for "session without javascript support" do
282
- describe "#evaluate_script" do
283
- before{ @session.visit('/with_simple_html') }
284
- it "should raise an error" do
285
- running {
286
- @session.evaluate_script('3 + 3')
287
- }.should raise_error(Capybara::NotSupportedByDriverError)
288
- end
289
- end
290
- end