capybara 2.0.0.beta2 → 2.0.0.beta4

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