capybara 0.2.0 → 0.3.0

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 (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
-