capybara 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/Manifest.txt +39 -0
  2. data/README.rdoc +181 -57
  3. data/Rakefile +7 -16
  4. data/config.ru +6 -0
  5. data/lib/capybara.rb +19 -9
  6. data/lib/capybara/cucumber.rb +4 -0
  7. data/lib/capybara/driver/base.rb +25 -8
  8. data/lib/capybara/driver/celerity_driver.rb +108 -0
  9. data/lib/capybara/driver/culerity_driver.rb +1 -70
  10. data/lib/capybara/driver/rack_test_driver.rb +57 -25
  11. data/lib/capybara/driver/selenium_driver.rb +28 -10
  12. data/lib/capybara/dsl.rb +7 -4
  13. data/lib/capybara/node.rb +50 -29
  14. data/lib/capybara/rails.rb +1 -1
  15. data/lib/capybara/save_and_open_page.rb +1 -1
  16. data/lib/capybara/searchable.rb +45 -0
  17. data/lib/capybara/server.rb +11 -4
  18. data/lib/capybara/session.rb +94 -94
  19. data/lib/capybara/wait_until.rb +23 -0
  20. data/lib/capybara/xpath.rb +55 -41
  21. data/spec/capybara_spec.rb +18 -0
  22. data/spec/driver/celerity_driver_spec.rb +17 -0
  23. data/spec/driver/culerity_driver_spec.rb +3 -0
  24. data/spec/driver/rack_test_driver_spec.rb +3 -0
  25. data/spec/driver/remote_culerity_driver_spec.rb +19 -0
  26. data/spec/driver/remote_selenium_driver_spec.rb +18 -0
  27. data/spec/driver/selenium_driver_spec.rb +2 -0
  28. data/spec/drivers_spec.rb +51 -5
  29. data/spec/dsl/all_spec.rb +38 -0
  30. data/spec/dsl/attach_file_spec.rb +66 -0
  31. data/spec/dsl/check_spec.rb +28 -0
  32. data/spec/dsl/choose_spec.rb +28 -0
  33. data/spec/dsl/click_button_spec.rb +183 -0
  34. data/spec/dsl/click_link_spec.rb +88 -0
  35. data/spec/dsl/click_spec.rb +26 -0
  36. data/spec/dsl/current_url_spec.rb +10 -0
  37. data/spec/dsl/fill_in_spec.rb +83 -0
  38. data/spec/dsl/find_button_spec.rb +18 -0
  39. data/spec/dsl/find_field_spec.rb +24 -0
  40. data/spec/dsl/find_link_spec.rb +19 -0
  41. data/spec/dsl/find_spec.rb +36 -0
  42. data/spec/dsl/has_content_spec.rb +103 -0
  43. data/spec/dsl/has_css_spec.rb +109 -0
  44. data/spec/dsl/has_xpath_spec.rb +115 -0
  45. data/spec/dsl/locate_spec.rb +38 -0
  46. data/spec/dsl/select_spec.rb +27 -0
  47. data/spec/dsl/uncheck_spec.rb +29 -0
  48. data/spec/dsl/within_spec.rb +145 -0
  49. data/spec/fixtures/capybara.jpg +0 -0
  50. data/spec/public/test.js +27 -0
  51. data/spec/searchable_spec.rb +61 -0
  52. data/spec/server_spec.rb +47 -0
  53. data/spec/session/celerity_session_spec.rb +27 -0
  54. data/spec/session/culerity_session_spec.rb +1 -0
  55. data/spec/session/rack_test_session_spec.rb +1 -0
  56. data/spec/session/selenium_session_spec.rb +1 -0
  57. data/spec/session_spec.rb +32 -903
  58. data/spec/session_with_headers_support_spec.rb +13 -0
  59. data/spec/session_with_javascript_support_spec.rb +165 -0
  60. data/spec/session_without_headers_support_spec.rb +15 -0
  61. data/spec/session_without_javascript_support_spec.rb +15 -0
  62. data/spec/spec_helper.rb +12 -0
  63. data/spec/test_app.rb +9 -1
  64. data/spec/views/form.erb +38 -0
  65. data/spec/views/postback.erb +13 -0
  66. data/spec/views/with_html.erb +13 -0
  67. data/spec/views/with_js.erb +9 -24
  68. data/spec/views/with_simple_html.erb +1 -1
  69. data/spec/wait_until_spec.rb +28 -0
  70. data/spec/xpath_spec.rb +34 -3
  71. metadata +54 -5
@@ -0,0 +1,27 @@
1
+ module SelectSpec
2
+ shared_examples_for "select" do
3
+ describe "#select" do
4
+ before do
5
+ @session.visit('/form')
6
+ end
7
+
8
+ it "should select an option from a select box by id" do
9
+ @session.select("Finish", :from => 'form_locale')
10
+ @session.click_button('awesome')
11
+ extract_results(@session)['locale'].should == 'fi'
12
+ end
13
+
14
+ it "should select an option from a select box by label" do
15
+ @session.select("Finish", :from => 'Locale')
16
+ @session.click_button('awesome')
17
+ extract_results(@session)['locale'].should == 'fi'
18
+ end
19
+
20
+ context "with a locator that doesn't exist" do
21
+ it "should raise an error" do
22
+ running { @session.select('foo', :from => 'does not exist') }.should raise_error(Capybara::ElementNotFound)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module UncheckSpec
2
+ shared_examples_for "uncheck" do
3
+ describe "#uncheck" do
4
+ before do
5
+ @session.visit('/form')
6
+ end
7
+
8
+ it "should uncheck a checkbox by id" do
9
+ @session.uncheck("form_pets_hamster")
10
+ @session.click_button('awesome')
11
+ extract_results(@session)['pets'].should include('dog')
12
+ extract_results(@session)['pets'].should_not include('hamster')
13
+ end
14
+
15
+ it "should uncheck a checkbox by label" do
16
+ @session.uncheck("Hamster")
17
+ @session.click_button('awesome')
18
+ extract_results(@session)['pets'].should include('dog')
19
+ extract_results(@session)['pets'].should_not include('hamster')
20
+ end
21
+
22
+ context "with a locator that doesn't exist" do
23
+ it "should raise an error" do
24
+ running { @session.uncheck('does not exist') }.should raise_error(Capybara::ElementNotFound)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,145 @@
1
+ module WithinSpec
2
+ shared_examples_for "within" do
3
+ describe '#within' do
4
+ before do
5
+ @session.visit('/with_scope')
6
+ end
7
+
8
+ context "with CSS selector" do
9
+ it "should click links in the given scope" do
10
+ @session.within(:css, "ul li[contains('With Simple HTML')]") do
11
+ @session.click_link('Go')
12
+ end
13
+ @session.body.should include('Bar')
14
+ end
15
+ end
16
+
17
+ context "with XPath selector" do
18
+ it "should click links in the given scope" do
19
+ @session.within(:xpath, "//li[contains(.,'With Simple HTML')]") do
20
+ @session.click_link('Go')
21
+ end
22
+ @session.body.should include('Bar')
23
+ end
24
+ end
25
+
26
+ context "with the default selector" do
27
+ it "should use XPath" do
28
+ @session.within("//li[contains(., 'With Simple HTML')]") do
29
+ @session.click_link('Go')
30
+ end
31
+ @session.body.should include('Bar')
32
+ end
33
+ end
34
+
35
+ context "with the default selector set to CSS" do
36
+ after do
37
+ Capybara.default_selector = :xpath
38
+ end
39
+
40
+ it "should use CSS" do
41
+ Capybara.default_selector = :css
42
+ @session.within("ul li[contains('With Simple HTML')]") do
43
+ @session.click_link('Go')
44
+ end
45
+ @session.body.should include('Bar')
46
+ end
47
+ end
48
+
49
+ context "with click_link" do
50
+ it "should click links in the given scope" do
51
+ @session.within("//li[contains(.,'With Simple HTML')]") do
52
+ @session.click_link('Go')
53
+ end
54
+ @session.body.should include('Bar')
55
+ end
56
+
57
+ context "with nested scopes" do
58
+ it "should respect the inner scope" do
59
+ @session.within("//div[@id='for_bar']") do
60
+ @session.within("//li[contains(.,'Bar')]") do
61
+ @session.click_link('Go')
62
+ end
63
+ end
64
+ @session.body.should include('Another World')
65
+ end
66
+
67
+ it "should respect the outer scope" do
68
+ @session.within("//div[@id='another_foo']") do
69
+ @session.within("//li[contains(.,'With Simple HTML')]") do
70
+ @session.click_link('Go')
71
+ end
72
+ end
73
+ @session.body.should include('Hello world')
74
+ end
75
+ end
76
+
77
+ it "should raise an error if the scope is not found on the page" do
78
+ running {
79
+ @session.within("//div[@id='doesnotexist']") do
80
+ end
81
+ }.should raise_error(Capybara::ElementNotFound)
82
+ end
83
+ end
84
+
85
+ context "with forms" do
86
+ it "should fill in a field and click a button" do
87
+ @session.within("//li[contains(.,'Bar')]") do
88
+ @session.click_button('Go')
89
+ end
90
+ extract_results(@session)['first_name'].should == 'Peter'
91
+ @session.visit('/with_scope')
92
+ @session.within("//li[contains(.,'Bar')]") do
93
+ @session.fill_in('First Name', :with => 'Dagobert')
94
+ @session.click_button('Go')
95
+ end
96
+ extract_results(@session)['first_name'].should == 'Dagobert'
97
+ end
98
+ end
99
+ end
100
+
101
+ describe '#within_fieldset' do
102
+ before do
103
+ @session.visit('/fieldsets')
104
+ end
105
+
106
+ it "should restrict scope to a fieldset given by id" do
107
+ @session.within_fieldset("villain_fieldset") do
108
+ @session.fill_in("Name", :with => 'Goldfinger')
109
+ @session.click_button("Create")
110
+ end
111
+ extract_results(@session)['villain_name'].should == 'Goldfinger'
112
+ end
113
+
114
+ it "should restrict scope to a fieldset given by legend" do
115
+ @session.within_fieldset("Villain") do
116
+ @session.fill_in("Name", :with => 'Goldfinger')
117
+ @session.click_button("Create")
118
+ end
119
+ extract_results(@session)['villain_name'].should == 'Goldfinger'
120
+ end
121
+ end
122
+
123
+ describe '#within_table' do
124
+ before do
125
+ @session.visit('/tables')
126
+ end
127
+
128
+ it "should restrict scope to a fieldset given by id" do
129
+ @session.within_table("girl_table") do
130
+ @session.fill_in("Name", :with => 'Christmas')
131
+ @session.click_button("Create")
132
+ end
133
+ extract_results(@session)['girl_name'].should == 'Christmas'
134
+ end
135
+
136
+ it "should restrict scope to a fieldset given by legend" do
137
+ @session.within_table("Villain") do
138
+ @session.fill_in("Name", :with => 'Quantum')
139
+ @session.click_button("Create")
140
+ end
141
+ extract_results(@session)['villain_name'].should == 'Quantum'
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,27 @@
1
+ var activeRequests = 0;
2
+ $(function() {
3
+ $('#change').text('I changed it');
4
+ $('#drag').draggable();
5
+ $('#drop').droppable({
6
+ drop: function(event, ui) {
7
+ ui.draggable.remove();
8
+ $(this).html('Dropped!');
9
+ }
10
+ });
11
+ $('#clickable').click(function() {
12
+ var link = $(this);
13
+ setTimeout(function() {
14
+ $(link).after('<a href="#">Has been clicked</a>');
15
+ $(link).after('<input type="submit" value="New Here">');
16
+ $(link).after('<input type="text" id="new_field">');
17
+ $('#change').remove();
18
+ }, 500);
19
+ return false;
20
+ });
21
+ $('#waiter').change(function() {
22
+ activeRequests = 1;
23
+ setTimeout(function() {
24
+ activeRequests = 0;
25
+ }, 500);
26
+ });
27
+ });
@@ -0,0 +1,61 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ module Capybara
4
+
5
+ describe Searchable do
6
+ class Klass
7
+ include Searchable
8
+
9
+ def all_unfiltered(locator, options = {})
10
+ []
11
+ end
12
+
13
+ end
14
+
15
+ describe "#all" do
16
+ before do
17
+ @searchable = Klass.new
18
+ end
19
+
20
+ it "should return unfiltered list without options" do
21
+ node1 = stub(Node)
22
+ node2 = stub(Node)
23
+ @searchable.should_receive(:all_unfiltered).with('//x').and_return([node1, node2])
24
+ @searchable.all('//x').should == [node1, node2]
25
+ end
26
+
27
+ context "with :text filter" do
28
+ before do
29
+ @node1 = stub(Node, :text => 'node one text')
30
+ @node2 = stub(Node, :text => 'node two text')
31
+ @searchable.stub(:all_unfiltered).and_return([@node1, @node2])
32
+ end
33
+
34
+ it "should accept regular expression" do
35
+ @searchable.all('//x', :text => /node one/).should == [@node1]
36
+ @searchable.all('//x', :text => /node two/).should == [@node2]
37
+ end
38
+
39
+ it "should accept text" do
40
+ @searchable.all('//x', :text => "node one").should == [@node1]
41
+ @searchable.all('//x', :text => "node two").should == [@node2]
42
+ end
43
+ end
44
+
45
+ context "with :visible filter" do
46
+ before do
47
+ @visible_node = stub(Node, :visible? => true)
48
+ @hidden_node = stub(Node, :visible? => false)
49
+ @searchable.stub(:all_unfiltered).and_return([@visible_node, @hidden_node])
50
+ end
51
+
52
+ it "should filter out hidden nodes" do
53
+ @searchable.all('//x', :visible => true).should == [@visible_node]
54
+ end
55
+
56
+ end
57
+
58
+ end #all
59
+ end
60
+
61
+ end
@@ -0,0 +1,47 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__))
2
+
3
+ describe Capybara::Server do
4
+
5
+ it "should spool up a rack server" do
6
+ @app = proc { |env| [200, {}, "Hello Server!"]}
7
+ @server = Capybara::Server.new(@app)
8
+
9
+ @res = Net::HTTP.start(@server.host, @server.port) { |http| http.get('/') }
10
+
11
+ @res.body.should include('Hello Server')
12
+ end
13
+
14
+ it "should find an available port" do
15
+ @app1 = proc { |env| [200, {}, "Hello Server!"]}
16
+ @app2 = proc { |env| [200, {}, "Hello Second Server!"]}
17
+
18
+ @server1 = Capybara::Server.new(@app1)
19
+ @server2 = Capybara::Server.new(@app2)
20
+
21
+ @res1 = Net::HTTP.start(@server1.host, @server1.port) { |http| http.get('/') }
22
+ @res1.body.should include('Hello Server')
23
+
24
+ @res2 = Net::HTTP.start(@server2.host, @server2.port) { |http| http.get('/') }
25
+ @res2.body.should include('Hello Second Server')
26
+ end
27
+
28
+ it "should use the server if it already running" do
29
+ @app1 = proc { |env| [200, {}, "Hello Server!"]}
30
+ @app2 = proc { |env| [200, {}, "Hello Second Server!"]}
31
+
32
+ @server1a = Capybara::Server.new(@app1)
33
+ @server1b = Capybara::Server.new(@app1)
34
+ @server2a = Capybara::Server.new(@app2)
35
+ @server2b = Capybara::Server.new(@app2)
36
+
37
+ @res1 = Net::HTTP.start(@server1b.host, @server1b.port) { |http| http.get('/') }
38
+ @res1.body.should include('Hello Server')
39
+
40
+ @res2 = Net::HTTP.start(@server2b.host, @server2b.port) { |http| http.get('/') }
41
+ @res2.body.should include('Hello Second Server')
42
+
43
+ @server1a.port.should == @server1b.port
44
+ @server2a.port.should == @server2b.port
45
+ end
46
+
47
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ if RUBY_PLATFORM =~ /java/
4
+ describe Capybara::Driver::Celerity do
5
+ before do
6
+ @session = Capybara::Session.new(:celerity, TestApp)
7
+ end
8
+
9
+ describe '#driver' do
10
+ it "should be a rack test driver" do
11
+ @session.driver.should be_an_instance_of(Capybara::Driver::Celerity)
12
+ end
13
+ end
14
+
15
+ describe '#mode' do
16
+ it "should remember the mode" do
17
+ @session.mode.should == :celerity
18
+ end
19
+ end
20
+
21
+ it_should_behave_like "session"
22
+ it_should_behave_like "session with javascript support"
23
+ it_should_behave_like "session with headers support"
24
+ end
25
+ else
26
+ puts "#{File.basename(__FILE__)} requires JRuby; skipping.."
27
+ end
@@ -20,5 +20,6 @@ describe Capybara::Session do
20
20
 
21
21
  it_should_behave_like "session"
22
22
  it_should_behave_like "session with javascript support"
23
+ it_should_behave_like "session with headers support"
23
24
  end
24
25
  end
@@ -20,5 +20,6 @@ describe Capybara::Session do
20
20
 
21
21
  it_should_behave_like "session"
22
22
  it_should_behave_like "session without javascript support"
23
+ it_should_behave_like "session with headers support"
23
24
  end
24
25
  end
@@ -20,5 +20,6 @@ describe Capybara::Session do
20
20
 
21
21
  it_should_behave_like "session"
22
22
  it_should_behave_like "session with javascript support"
23
+ it_should_behave_like "session without headers support"
23
24
  end
24
25
  end
@@ -1,5 +1,4 @@
1
1
  require File.expand_path('spec_helper', File.dirname(__FILE__))
2
-
3
2
  require 'nokogiri'
4
3
 
5
4
  shared_examples_for "session" do
@@ -22,912 +21,43 @@ shared_examples_for "session" do
22
21
  end
23
22
  end
24
23
 
25
- describe '#click' do
26
- it "should click on a link" do
27
- @session.visit('/with_html')
28
- @session.click('labore')
29
- @session.body.should include('<h1>Bar</h1>')
30
- end
31
-
32
- it "should click on a button" do
33
- @session.visit('/form')
34
- @session.click('awe123')
35
- extract_results(@session)['first_name'].should == 'John'
36
- end
37
-
38
- context "with a locator that doesn't exist" do
39
- it "should raise an error" do
40
- @session.visit('/with_html')
41
- running do
42
- @session.click('does not exist')
43
- end.should raise_error(Capybara::ElementNotFound)
44
- end
45
- end
46
- end
47
-
48
- describe '#click_link' do
49
- before do
50
- @session.visit('/with_html')
51
- end
52
-
53
- context "with id given" do
54
- it "should take user to the linked page" do
55
- @session.click_link('foo')
56
- @session.body.should include('Another World')
57
- end
58
- end
59
-
60
- context "with text given" do
61
- it "should take user to the linked page" do
62
- @session.click_link('labore')
63
- @session.body.should include('<h1>Bar</h1>')
64
- end
65
- end
66
-
67
- context "with title given" do
68
- it "should take user to the linked page" do
69
- @session.click_link('awesome title')
70
- @session.body.should include('<h1>Bar</h1>')
71
- end
72
- end
73
-
74
- context "with a locator that doesn't exist" do
75
- it "should raise an error" do
76
- running do
77
- @session.click_link('does not exist')
78
- end.should raise_error(Capybara::ElementNotFound)
79
- end
80
- end
81
-
82
- it "should follow redirects" do
83
- @session.click_link('Redirect')
84
- @session.body.should include('You landed')
85
- end
86
- end
87
-
88
- describe '#click_button' do
89
- before do
90
- @session.visit('/form')
91
- end
92
-
93
- context "with multiple values with the same name" do
94
- it "should use the latest given value" do
95
- @session.check('Terms of Use')
96
- @session.click_button('awesome')
97
- extract_results(@session)['terms_of_use'].should == '1'
98
- end
99
- end
100
-
101
- context "with value given on a submit button" do
102
- before do
103
- @session.click_button('awesome')
104
- @results = extract_results(@session)
105
- end
106
-
107
- it "should serialize and submit text fields" do
108
- @results['first_name'].should == 'John'
109
- end
110
-
111
- it "should escape fields when submitting" do
112
- @results['phone'].should == '+1 555 7021'
113
- end
114
-
115
- it "should serialize and submit password fields" do
116
- @results['password'].should == 'seeekrit'
117
- end
118
-
119
- it "should serialize and submit hidden fields" do
120
- @results['token'].should == '12345'
121
- end
122
-
123
- it "should not serialize fields from other forms" do
124
- @results['middle_name'].should be_nil
125
- end
126
-
127
- it "should submit the button that was clicked, but not other buttons" do
128
- @results['awesome'].should == 'awesome'
129
- @results['crappy'].should be_nil
130
- end
131
-
132
- it "should serialize radio buttons" do
133
- @results['gender'].should == 'female'
134
- end
135
-
136
- it "should serialize check boxes" do
137
- @results['pets'].should include('dog', 'hamster')
138
- @results['pets'].should_not include('cat')
139
- end
140
-
141
- it "should serialize text areas" do
142
- @results['description'].should == 'Descriptive text goes here'
143
- end
144
-
145
- it "should serialize select tag with values" do
146
- @results['locale'].should == 'en'
147
- end
148
-
149
- it "should serialize select tag without values" do
150
- @results['region'].should == 'Norway'
151
- end
152
-
153
- it "should serialize first option for select tag with no selection" do
154
- @results['city'].should == 'London'
155
- end
156
-
157
- it "should not serialize a select tag without options" do
158
- @results['tendency'].should be_nil
159
- end
160
- end
161
-
162
- context "with id given on a submit button" do
163
- it "should submit the associated form" do
164
- @session.click_button('awe123')
165
- extract_results(@session)['first_name'].should == 'John'
166
- end
167
- end
168
-
169
- context "with value given on an image button" do
170
- it "should submit the associated form" do
171
- @session.click_button('okay')
172
- extract_results(@session)['first_name'].should == 'John'
173
- end
174
- end
175
-
176
- context "with id given on an image button" do
177
- it "should submit the associated form" do
178
- @session.click_button('okay556')
179
- extract_results(@session)['first_name'].should == 'John'
180
- end
181
- end
182
-
183
- context "with text given on a button defined by <button> tag" do
184
- it "should submit the associated form" do
185
- @session.click_button('Click me')
186
- extract_results(@session)['first_name'].should == 'John'
187
- end
188
- end
189
-
190
- context "with id given on a button defined by <button> tag" do
191
- it "should submit the associated form" do
192
- @session.click_button('click_me_123')
193
- extract_results(@session)['first_name'].should == 'John'
194
- end
195
- end
196
-
197
- context "with value given on a button defined by <button> tag" do
198
- it "should submit the associated form" do
199
- @session.click_button('click_me')
200
- extract_results(@session)['first_name'].should == 'John'
201
- end
202
- end
203
-
204
- context "with a locator that doesn't exist" do
205
- it "should raise an error" do
206
- running do
207
- @session.click_button('does not exist')
208
- end.should raise_error(Capybara::ElementNotFound)
209
- end
210
- end
211
-
212
- it "should serialize and send GET forms" do
213
- @session.visit('/form')
214
- @session.click_button('med')
215
- @results = extract_results(@session)
216
- @results['middle_name'].should == 'Darren'
217
- @results['foo'].should be_nil
218
- end
219
-
220
- it "should follow redirects" do
221
- @session.click_button('Go FAR')
222
- @session.body.should include('You landed')
223
- end
224
- end
225
-
226
- describe "#fill_in" do
227
- before do
228
- @session.visit('/form')
229
- end
230
-
231
- it "should fill in a text field by id" do
232
- @session.fill_in('form_first_name', :with => 'Harry')
233
- @session.click_button('awesome')
234
- extract_results(@session)['first_name'].should == 'Harry'
235
- end
236
-
237
- it "should fill in a text field by label" do
238
- @session.fill_in('First Name', :with => 'Harry')
239
- @session.click_button('awesome')
240
- extract_results(@session)['first_name'].should == 'Harry'
241
- end
242
-
243
- it "should favour exact label matches over partial matches" do
244
- @session.fill_in('Name', :with => 'Harry Jones')
245
- @session.click_button('awesome')
246
- extract_results(@session)['name'].should == 'Harry Jones'
247
- end
248
-
249
- it "should fill in a textarea by id" do
250
- @session.fill_in('form_description', :with => 'Texty text')
251
- @session.click_button('awesome')
252
- extract_results(@session)['description'].should == 'Texty text'
253
- end
254
-
255
- it "should fill in a textarea by label" do
256
- @session.fill_in('Description', :with => 'Texty text')
257
- @session.click_button('awesome')
258
- extract_results(@session)['description'].should == 'Texty text'
259
- end
260
-
261
- it "should fill in a password field by id" do
262
- @session.fill_in('form_password', :with => 'supasikrit')
263
- @session.click_button('awesome')
264
- extract_results(@session)['password'].should == 'supasikrit'
265
- end
266
-
267
- it "should fill in a password field by label" do
268
- @session.fill_in('Password', :with => 'supasikrit')
269
- @session.click_button('awesome')
270
- extract_results(@session)['password'].should == 'supasikrit'
271
- end
272
-
273
- context "with a locator that doesn't exist" do
274
- it "should raise an error" do
275
- running do
276
- @session.fill_in('does not exist', :with => 'Blah blah')
277
- end.should raise_error(Capybara::ElementNotFound)
278
- end
279
- end
280
- end
281
-
282
- describe "#choose" do
283
- before do
284
- @session.visit('/form')
285
- end
286
-
287
- it "should choose a radio button by id" do
288
- @session.choose("gender_male")
289
- @session.click_button('awesome')
290
- extract_results(@session)['gender'].should == 'male'
291
- end
292
-
293
- it "should choose a radio button by label" do
294
- @session.choose("Both")
295
- @session.click_button('awesome')
296
- extract_results(@session)['gender'].should == 'both'
297
- end
298
-
299
- context "with a locator that doesn't exist" do
300
- it "should raise an error" do
301
- running { @session.choose('does not exist') }.should raise_error(Capybara::ElementNotFound)
302
- end
303
- end
304
- end
305
-
306
- describe "#check" do
307
- before do
308
- @session.visit('/form')
309
- end
310
-
311
- it "should check a checkbox by id" do
312
- @session.check("form_pets_cat")
313
- @session.click_button('awesome')
314
- extract_results(@session)['pets'].should include('dog', 'cat', 'hamster')
315
- end
316
-
317
- it "should check a checkbox by label" do
318
- @session.check("Cat")
319
- @session.click_button('awesome')
320
- extract_results(@session)['pets'].should include('dog', 'cat', 'hamster')
321
- end
322
-
323
- context "with a locator that doesn't exist" do
324
- it "should raise an error" do
325
- running { @session.check('does not exist') }.should raise_error(Capybara::ElementNotFound)
326
- end
327
- end
328
- end
329
-
330
- describe "#uncheck" do
331
- before do
332
- @session.visit('/form')
333
- end
334
-
335
- it "should uncheck a checkbox by id" do
336
- @session.uncheck("form_pets_hamster")
337
- @session.click_button('awesome')
338
- extract_results(@session)['pets'].should include('dog')
339
- extract_results(@session)['pets'].should_not include('hamster')
340
- end
341
-
342
- it "should uncheck a checkbox by label" do
343
- @session.uncheck("Hamster")
344
- @session.click_button('awesome')
345
- extract_results(@session)['pets'].should include('dog')
346
- extract_results(@session)['pets'].should_not include('hamster')
347
- end
348
-
349
- context "with a locator that doesn't exist" do
350
- it "should raise an error" do
351
- running { @session.uncheck('does not exist') }.should raise_error(Capybara::ElementNotFound)
352
- end
353
- end
354
- end
355
-
356
- describe "#select" do
357
- before do
358
- @session.visit('/form')
359
- end
360
-
361
- it "should select an option from a select box by id" do
362
- @session.select("Finish", :from => 'form_locale')
363
- @session.click_button('awesome')
364
- extract_results(@session)['locale'].should == 'fi'
365
- end
366
-
367
- it "should select an option from a select box by label" do
368
- @session.select("Finish", :from => 'Locale')
369
- @session.click_button('awesome')
370
- extract_results(@session)['locale'].should == 'fi'
371
- end
372
-
373
- context "with a locator that doesn't exist" do
374
- it "should raise an error" do
375
- running { @session.select('foo', :from => 'does not exist') }.should raise_error(Capybara::ElementNotFound)
376
- end
377
- end
378
- end
379
-
380
- describe '#has_content?' do
381
- it "should be true if the given content is on the page at least once" do
382
- @session.visit('/with_html')
383
- @session.should have_content('est')
384
- @session.should have_content('Lorem')
385
- @session.should have_content('Redirect')
386
- end
387
-
388
- it "should be true if scoped to an element which has the content" do
389
- @session.visit('/with_html')
390
- @session.within("//a[@title='awesome title']") do
391
- @session.should have_content('labore')
392
- end
393
- end
394
-
395
- it "should be false if the given content is not on the page" do
396
- @session.visit('/with_html')
397
- @session.should_not have_content('xxxxyzzz')
398
- @session.should_not have_content('monkey')
399
- end
400
-
401
- it 'should handle single quotes in the content' do
402
- @session.visit('/with-quotes')
403
- @session.should have_content("can't")
404
- end
405
-
406
- it 'should handle double quotes in the content' do
407
- @session.visit('/with-quotes')
408
- @session.should have_content(%q{"No," he said})
409
- end
410
-
411
- it 'should handle mixed single and double quotes in the content' do
412
- @session.visit('/with-quotes')
413
- @session.should have_content(%q{"you can't do that."})
414
- end
415
- end
416
-
417
- describe '#has_xpath?' do
418
- before do
419
- @session.visit('/with_html')
420
- end
421
-
422
- it "should be true if the given selector is on the page" do
423
- @session.should have_xpath("//p")
424
- @session.should have_xpath("//p//a[@id='foo']")
425
- @session.should have_xpath("//p[contains(.,'est')]")
426
- end
427
-
428
- it "should be false if the given selector is not on the page" do
429
- @session.should_not have_xpath("//abbr")
430
- @session.should_not have_xpath("//p//a[@id='doesnotexist']")
431
- @session.should_not have_xpath("//p[contains(.,'thisstringisnotonpage')]")
432
- end
433
-
434
- it "should respect scopes" do
435
- @session.within "//p[@id='first']" do
436
- @session.should have_xpath("//a[@id='foo']")
437
- @session.should_not have_xpath("//a[@id='red']")
438
- end
439
- end
440
-
441
- context "with count" do
442
- it "should be true if the content is on the page the given number of times" do
443
- @session.should have_xpath("//p", :count => 3)
444
- @session.should have_xpath("//p//a[@id='foo']", :count => 1)
445
- @session.should have_xpath("//p[contains(.,'est')]", :count => 1)
446
- end
447
-
448
- it "should be false if the content is on the page the given number of times" do
449
- @session.should_not have_xpath("//p", :count => 6)
450
- @session.should_not have_xpath("//p//a[@id='foo']", :count => 2)
451
- @session.should_not have_xpath("//p[contains(.,'est')]", :count => 5)
452
- end
453
-
454
- it "should be false if the content isn't on the page at all" do
455
- @session.should_not have_xpath("//abbr", :count => 2)
456
- @session.should_not have_xpath("//p//a[@id='doesnotexist']", :count => 1)
457
- end
458
- end
459
-
460
- context "with text" do
461
- it "should discard all matches where the given string is not contained" do
462
- @session.should have_xpath("//p//a", :text => "Redirect", :count => 1)
463
- @session.should_not have_xpath("//p", :text => "Doesnotexist")
464
- end
465
-
466
- it "should discard all matches where the given regexp is not matched" do
467
- @session.should have_xpath("//p//a", :text => /re[dab]i/i, :count => 1)
468
- @session.should_not have_xpath("//p//a", :text => /Red$/)
469
- end
470
- end
471
- end
472
-
473
- describe '#has_css?' do
474
- before do
475
- @session.visit('/with_html')
476
- end
477
-
478
- it "should be true if the given selector is on the page" do
479
- @session.should have_css("p")
480
- @session.should have_css("p a#foo")
481
- end
482
-
483
- it "should be false if the given selector is not on the page" do
484
- @session.should_not have_css("abbr")
485
- @session.should_not have_css("p a#doesnotexist")
486
- @session.should_not have_css("p.nosuchclass")
487
- end
488
-
489
- it "should respect scopes" do
490
- @session.within "//p[@id='first']" do
491
- @session.should have_css("a#foo")
492
- @session.should_not have_css("a#red")
493
- end
494
- end
495
-
496
- context "with count" do
497
- it "should be true if the content is on the page the given number of times" do
498
- @session.should have_css("p", :count => 3)
499
- @session.should have_css("p a#foo", :count => 1)
500
- end
501
-
502
- it "should be false if the content is on the page the given number of times" do
503
- @session.should_not have_css("p", :count => 6)
504
- @session.should_not have_css("p a#foo", :count => 2)
505
- end
506
-
507
- it "should be false if the content isn't on the page at all" do
508
- @session.should_not have_css("abbr", :count => 2)
509
- @session.should_not have_css("p a.doesnotexist", :count => 1)
510
- end
511
- end
512
-
513
- context "with text" do
514
- it "should discard all matches where the given string is not contained" do
515
- @session.should have_css("p a", :text => "Redirect", :count => 1)
516
- @session.should_not have_css("p a", :text => "Doesnotexist")
517
- end
518
-
519
- it "should discard all matches where the given regexp is not matched" do
520
- @session.should have_css("p a", :text => /re[dab]i/i, :count => 1)
521
- @session.should_not have_css("p a", :text => /Red$/)
522
- end
523
- end
524
- end
525
-
526
- describe "#attach_file" do
527
- before do
528
- @session.visit('/form')
529
- end
530
-
531
- context "with normal form" do
532
- it "should set a file path by id" do
533
- @session.attach_file "form_image", __FILE__
534
- @session.click_button('awesome')
535
- extract_results(@session)['image'].should == File.basename(__FILE__)
536
- end
537
-
538
- it "should set a file path by label" do
539
- @session.attach_file "Image", __FILE__
540
- @session.click_button('awesome')
541
- extract_results(@session)['image'].should == File.basename(__FILE__)
542
- end
543
- end
544
-
545
- context "with multipart form" do
546
- before do
547
- @test_file_path = File.expand_path('fixtures/test_file.txt', File.dirname(__FILE__))
548
- end
549
-
550
- it "should set a file path by id" do
551
- @session.attach_file "form_document", @test_file_path
552
- @session.click_button('Upload')
553
- @session.body.should include(File.read(@test_file_path))
554
- end
555
-
556
- it "should set a file path by label" do
557
- @session.attach_file "Document", @test_file_path
558
- @session.click_button('Upload')
559
- @session.body.should include(File.read(@test_file_path))
560
- end
561
-
562
- it "should not break if no file is submitted" do
563
- @session.click_button('Upload')
564
- @session.body.should include('No file uploaded')
565
- end
566
- end
567
-
568
- context "with a locator that doesn't exist" do
569
- it "should raise an error" do
570
- running { @session.attach_file('does not exist', 'foo.txt') }.should raise_error(Capybara::ElementNotFound)
571
- end
572
- end
573
- end
574
-
575
- describe '#find_field' do
576
- before do
577
- @session.visit('/form')
578
- end
579
-
580
- it "should find any field" do
581
- @session.find_field('Dog').value.should == 'dog'
582
- @session.find_field('form_description').text.should == 'Descriptive text goes here'
583
- @session.find_field('Region')[:name].should == 'form[region]'
584
- end
585
-
586
- it "should be nil if the field doesn't exist" do
587
- @session.find_field('Does not exist').should be_nil
588
- end
589
-
590
- it "should be aliased as 'field_labeled' for webrat compatibility" do
591
- @session.field_labeled('Dog').value.should == 'dog'
592
- @session.field_labeled('Does not exist').should be_nil
593
- end
594
- end
595
-
596
- describe '#find_link' do
597
- before do
598
- @session.visit('/with_html')
599
- end
600
-
601
- it "should find any field" do
602
- @session.find_link('foo').text.should == "ullamco"
603
- @session.find_link('labore')[:href].should == "/with_simple_html"
604
- end
605
-
606
- it "should return nil if the field doesn't exist" do
607
- @session.find_link('Does not exist').should be_nil
608
- end
609
- end
610
-
611
- describe '#find_button' do
612
- before do
613
- @session.visit('/form')
614
- end
615
-
616
- it "should find any field" do
617
- @session.find_button('med')[:id].should == "mediocre"
618
- @session.find_button('crap321').value.should == "crappy"
619
- end
620
-
621
- it "should return nil if the field doesn't exist" do
622
- @session.find_button('Does not exist').should be_nil
623
- end
624
- end
625
-
626
- describe '#all' do
627
- before do
628
- @session.visit('/with_html')
629
- end
630
-
631
- it "should find all elements using the given locator" do
632
- @session.all('//p').should have(3).elements
633
- @session.all('//h1').first.text.should == 'This is a test'
634
- @session.all("//input[@id='test_field']").first[:value].should == 'monkey'
635
- end
636
-
637
- it "should return an empty array when nothing was found" do
638
- @session.all('//div').should be_empty
639
- end
640
-
641
- it "should accept an XPath instance" do
642
- @session.visit('/form')
643
- @xpath = Capybara::XPath.text_field('Name')
644
- @result = @session.all(@xpath)
645
- @result.map(&:value).should include('Smith', 'John', 'John Smith')
646
- end
647
-
648
- context "within a scope" do
649
- before do
650
- @session.visit('/with_scope')
651
- end
652
-
653
- it "should find any element using the given locator" do
654
- @session.within(:xpath, "//div[@id='for_bar']") do
655
- @session.all('//li').should have(2).elements
656
- end
657
- end
658
- end
659
- end
660
-
661
- describe '#find' do
662
- before do
663
- @session.visit('/with_html')
664
- end
665
-
666
- it "should find the first element using the given locator" do
667
- @session.find('//h1').text.should == 'This is a test'
668
- @session.find("//input[@id='test_field']")[:value].should == 'monkey'
669
- end
670
-
671
- it "should return nil when nothing was found" do
672
- @session.find('//div').should be_nil
673
- end
674
-
675
- it "should accept an XPath instance and respect the order of paths" do
676
- @session.visit('/form')
677
- @xpath = Capybara::XPath.text_field('Name')
678
- @session.find(@xpath).value.should == 'John Smith'
679
- end
680
-
681
- context "within a scope" do
682
- before do
683
- @session.visit('/with_scope')
684
- end
685
-
686
- it "should find the first element using the given locator" do
687
- @session.within(:xpath, "//div[@id='for_bar']") do
688
- @session.find('//li').text.should =~ /With Simple HTML/
689
- end
690
- end
24
+ describe '#body' do
25
+ it "should return the unmodified page body" do
26
+ @session.visit('/')
27
+ @session.body.should include('Hello world!')
691
28
  end
692
29
  end
693
30
 
694
- describe '#wait_for' do
695
- before do
696
- @session.visit('/with_html')
697
- end
698
-
699
- it "should find the first element using the given locator" do
700
- @session.wait_for('//h1').text.should == 'This is a test'
701
- @session.wait_for("//input[@id='test_field']")[:value].should == 'monkey'
702
- end
703
-
704
- it "should return nil when nothing was found" do
705
- @session.wait_for('//div').should be_nil
706
- end
707
-
708
- it "should accept an XPath instance and respect the order of paths" do
709
- @session.visit('/form')
710
- @xpath = Capybara::XPath.text_field('Name')
711
- @session.wait_for(@xpath).value.should == 'John Smith'
712
- end
713
-
714
- context "within a scope" do
715
- before do
716
- @session.visit('/with_scope')
717
- end
718
-
719
- it "should find the first element using the given locator" do
720
- @session.within(:xpath, "//div[@id='for_bar']") do
721
- @session.wait_for('//li').text.should =~ /With Simple HTML/
722
- end
723
- end
724
- end
725
- end
726
-
727
- describe '#within' do
728
- before do
729
- @session.visit('/with_scope')
730
- end
731
-
732
- context "with CSS selector" do
733
- it "should click links in the given scope" do
734
- @session.within(:css, "ul li[contains('With Simple HTML')]") do
735
- @session.click_link('Go')
736
- end
737
- @session.body.should include('<h1>Bar</h1>')
738
- end
739
- end
740
-
741
- context "with XPath selector" do
742
- it "should click links in the given scope" do
743
- @session.within(:xpath, "//li[contains(.,'With Simple HTML')]") do
744
- @session.click_link('Go')
745
- end
746
- @session.body.should include('<h1>Bar</h1>')
747
- end
748
- end
749
-
750
- context "with the default selector" do
751
- it "should use XPath" do
752
- @session.within("//li[contains(., 'With Simple HTML')]") do
753
- @session.click_link('Go')
754
- end
755
- @session.body.should include('<h1>Bar</h1>')
756
- end
757
- end
758
-
759
- context "with the default selector set to CSS" do
760
- after do
761
- Capybara.default_selector = :xpath
762
- end
763
-
764
- it "should use CSS" do
765
- Capybara.default_selector = :css
766
- @session.within("ul li[contains('With Simple HTML')]") do
767
- @session.click_link('Go')
768
- end
769
- @session.body.should include('<h1>Bar</h1>')
770
- end
771
- end
772
-
773
- context "with click_link" do
774
- it "should click links in the given scope" do
775
- @session.within("//li[contains(.,'With Simple HTML')]") do
776
- @session.click_link('Go')
777
- end
778
- @session.body.should include('<h1>Bar</h1>')
779
- end
780
-
781
- context "with nested scopes" do
782
- it "should respect the inner scope" do
783
- @session.within("//div[@id='for_bar']") do
784
- @session.within("//li[contains(.,'Bar')]") do
785
- @session.click_link('Go')
786
- end
787
- end
788
- @session.body.should include('Another World')
789
- end
790
-
791
- it "should respect the outer scope" do
792
- @session.within("//div[@id='another_foo']") do
793
- @session.within("//li[contains(.,'With Simple HTML')]") do
794
- @session.click_link('Go')
795
- end
796
- end
797
- @session.body.should include('Hello world')
798
- end
799
- end
800
-
801
- it "should raise an error if the scope is not found on the page" do
802
- running {
803
- @session.within("//div[@id='doesnotexist']") do
804
- end
805
- }.should raise_error(Capybara::ElementNotFound)
806
- end
807
- end
808
-
809
- context "with forms" do
810
- it "should fill in a field and click a button" do
811
- @session.within("//li[contains(.,'Bar')]") do
812
- @session.click_button('Go')
813
- end
814
- extract_results(@session)['first_name'].should == 'Peter'
815
- @session.visit('/with_scope')
816
- @session.within("//li[contains(.,'Bar')]") do
817
- @session.fill_in('First Name', :with => 'Dagobert')
818
- @session.click_button('Go')
819
- end
820
- extract_results(@session)['first_name'].should == 'Dagobert'
821
- end
822
- end
823
- end
824
-
825
- describe '#within_fieldset' do
826
- before do
827
- @session.visit('/fieldsets')
828
- end
829
-
830
- it "should restrict scope to a fieldset given by id" do
831
- @session.within_fieldset("villain_fieldset") do
832
- @session.fill_in("Name", :with => 'Goldfinger')
833
- @session.click_button("Create")
834
- end
835
- extract_results(@session)['villain_name'].should == 'Goldfinger'
836
- end
837
-
838
- it "should restrict scope to a fieldset given by legend" do
839
- @session.within_fieldset("Villain") do
840
- @session.fill_in("Name", :with => 'Goldfinger')
841
- @session.click_button("Create")
842
- end
843
- extract_results(@session)['villain_name'].should == 'Goldfinger'
844
- end
845
- end
846
-
847
- describe '#within_table' do
848
- before do
849
- @session.visit('/tables')
850
- end
851
-
852
- it "should restrict scope to a fieldset given by id" do
853
- @session.within_table("girl_table") do
854
- @session.fill_in("Name", :with => 'Christmas')
855
- @session.click_button("Create")
856
- end
857
- extract_results(@session)['girl_name'].should == 'Christmas'
858
- end
859
-
860
- it "should restrict scope to a fieldset given by legend" do
861
- @session.within_table("Villain") do
862
- @session.fill_in("Name", :with => 'Quantum')
863
- @session.click_button("Create")
864
- end
865
- extract_results(@session)['villain_name'].should == 'Quantum'
866
- end
867
- end
868
-
869
- end
870
-
871
- shared_examples_for "session without javascript support" do
872
- describe "#evaluate_script" do
873
- before{ @session.visit('/with_js') }
874
- it "should raise an error" do
875
- running {
876
- @session.evaluate_script("1+5")
877
- }.should raise_error(Capybara::NotSupportedByDriverError)
878
- end
879
- end
31
+ describe '#source' do
32
+ it "should return the unmodified page source" do
33
+ @session.visit('/')
34
+ @session.source.should include('Hello world!')
35
+ end
36
+ end
37
+
38
+ it_should_behave_like "all"
39
+ it_should_behave_like "attach_file"
40
+ it_should_behave_like "check"
41
+ it_should_behave_like "choose"
42
+ it_should_behave_like "click"
43
+ it_should_behave_like "click_button"
44
+ it_should_behave_like "click_link"
45
+ it_should_behave_like "fill_in"
46
+ it_should_behave_like "find_button"
47
+ it_should_behave_like "find_field"
48
+ it_should_behave_like "find_link"
49
+ it_should_behave_like "find"
50
+ it_should_behave_like "has_content"
51
+ it_should_behave_like "has_css"
52
+ it_should_behave_like "has_css"
53
+ it_should_behave_like "has_xpath"
54
+ it_should_behave_like "select"
55
+ it_should_behave_like "uncheck"
56
+ it_should_behave_like "locate"
57
+ it_should_behave_like "within"
58
+ it_should_behave_like "current_url"
880
59
  end
881
60
 
882
- shared_examples_for "session with javascript support" do
883
- describe "#evaluate_script" do
884
- before{ @session.visit('/with_js') }
885
- it "should return the evaluated script" do
886
- @session.evaluate_script("1+3").should == 4
887
- end
888
- end
889
-
890
- describe '#wait_for' do
891
- it "should wait for asynchronous load" do
892
- @session.visit('/with_js')
893
- @session.click_link('Click me')
894
- @session.wait_for("//a[contains(.,'Has been clicked')]")[:href].should == '#'
895
- end
896
- end
897
-
898
- describe '#click' do
899
- it "should wait for asynchronous load" do
900
- @session.visit('/with_js')
901
- @session.click_link('Click me')
902
- @session.click('Has been clicked')
903
- end
904
- end
905
-
906
- describe '#click_link' do
907
- it "should wait for asynchronous load" do
908
- @session.visit('/with_js')
909
- @session.click_link('Click me')
910
- @session.click_link('Has been clicked')
911
- end
912
- end
913
-
914
- describe '#click_button' do
915
- it "should wait for asynchronous load" do
916
- @session.visit('/with_js')
917
- @session.click_link('Click me')
918
- @session.click_button('New Here')
919
- end
920
- end
921
-
922
- describe '#fill_in' do
923
- it "should wait for asynchronous load" do
924
- @session.visit('/with_js')
925
- @session.click_link('Click me')
926
- @session.fill_in('new_field', :with => 'Testing...')
927
- end
928
- end
929
-
930
- end
931
61
 
932
62
  describe Capybara::Session do
933
63
  context 'with non-existant driver' do
@@ -938,4 +68,3 @@ describe Capybara::Session do
938
68
  end
939
69
  end
940
70
  end
941
-