capybara 1.1.4 → 2.0.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.
- data/{History.txt → History.md} +138 -0
- data/License.txt +22 -0
- data/README.md +850 -0
- data/lib/capybara/cucumber.rb +2 -5
- data/lib/capybara/driver/base.rb +6 -6
- data/lib/capybara/driver/node.rb +3 -2
- data/lib/capybara/dsl.rb +13 -124
- data/lib/capybara/helpers.rb +33 -0
- data/lib/capybara/node/actions.rb +16 -30
- data/lib/capybara/node/base.rb +56 -13
- data/lib/capybara/node/element.rb +18 -30
- data/lib/capybara/node/finders.rb +28 -90
- data/lib/capybara/node/matchers.rb +121 -73
- data/lib/capybara/node/simple.rb +13 -11
- data/lib/capybara/query.rb +78 -0
- data/lib/capybara/rack_test/browser.rb +27 -39
- data/lib/capybara/rack_test/driver.rb +13 -3
- data/lib/capybara/rack_test/node.rb +31 -2
- data/lib/capybara/result.rb +72 -0
- data/lib/capybara/rspec/features.rb +4 -1
- data/lib/capybara/rspec/matchers.rb +33 -63
- data/lib/capybara/rspec.rb +7 -4
- data/lib/capybara/selector.rb +97 -34
- data/lib/capybara/selenium/driver.rb +15 -62
- data/lib/capybara/selenium/node.rb +14 -21
- data/lib/capybara/server.rb +32 -27
- data/lib/capybara/session.rb +90 -50
- data/lib/capybara/spec/fixtures/another_test_file.txt +1 -0
- data/lib/capybara/spec/public/jquery-ui.js +791 -0
- data/lib/capybara/spec/public/jquery.js +9046 -0
- data/lib/capybara/spec/public/test.js +3 -0
- data/lib/capybara/spec/session/all_spec.rb +61 -59
- data/lib/capybara/spec/session/assert_selector.rb +123 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +72 -55
- data/lib/capybara/spec/session/body_spec.rb +21 -0
- data/lib/capybara/spec/session/check_spec.rb +68 -48
- data/lib/capybara/spec/session/choose_spec.rb +32 -18
- data/lib/capybara/spec/session/click_button_spec.rb +263 -232
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +40 -29
- data/lib/capybara/spec/session/click_link_spec.rb +96 -96
- data/lib/capybara/spec/session/current_url_spec.rb +88 -10
- data/lib/capybara/spec/session/evaluate_script_spec.rb +6 -0
- data/lib/capybara/spec/session/execute_script_spec.rb +7 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +119 -103
- data/lib/capybara/spec/session/find_button_spec.rb +16 -14
- data/lib/capybara/spec/session/find_by_id_spec.rb +16 -14
- data/lib/capybara/spec/session/find_field_spec.rb +23 -21
- data/lib/capybara/spec/session/find_link_spec.rb +15 -14
- data/lib/capybara/spec/session/find_spec.rb +93 -115
- data/lib/capybara/spec/session/first_spec.rb +51 -85
- data/lib/capybara/spec/session/has_button_spec.rb +22 -24
- data/lib/capybara/spec/session/has_css_spec.rb +190 -205
- data/lib/capybara/spec/session/has_field_spec.rb +170 -144
- data/lib/capybara/spec/session/has_link_spec.rb +26 -29
- data/lib/capybara/spec/session/has_select_spec.rb +161 -109
- data/lib/capybara/spec/session/has_selector_spec.rb +94 -100
- data/lib/capybara/spec/session/has_table_spec.rb +22 -88
- data/lib/capybara/spec/session/has_text_spec.rb +195 -0
- data/lib/capybara/spec/session/has_xpath_spec.rb +100 -96
- data/lib/capybara/spec/session/headers.rb +4 -17
- data/lib/capybara/spec/session/html_spec.rb +15 -0
- data/lib/capybara/spec/session/node_spec.rb +205 -0
- data/lib/capybara/spec/session/reset_session_spec.rb +42 -0
- data/lib/capybara/spec/session/response_code.rb +4 -17
- data/lib/capybara/spec/session/save_page_spec.rb +46 -0
- data/lib/capybara/spec/session/screenshot.rb +13 -0
- data/lib/capybara/spec/session/select_spec.rb +99 -88
- data/lib/capybara/spec/session/source_spec.rb +12 -0
- data/lib/capybara/spec/session/text_spec.rb +15 -12
- data/lib/capybara/spec/session/uncheck_spec.rb +22 -17
- data/lib/capybara/spec/session/unselect_spec.rb +69 -58
- data/lib/capybara/spec/session/visit_spec.rb +74 -0
- data/lib/capybara/spec/session/within_frame_spec.rb +31 -0
- data/lib/capybara/spec/session/within_spec.rb +118 -131
- data/lib/capybara/spec/session/within_window_spec.rb +38 -0
- data/lib/capybara/spec/spec_helper.rb +84 -0
- data/lib/capybara/spec/test_app.rb +32 -6
- data/lib/capybara/spec/views/form.erb +12 -10
- data/lib/capybara/spec/views/host_links.erb +2 -2
- data/lib/capybara/spec/views/tables.erb +6 -66
- data/lib/capybara/spec/views/with_html.erb +9 -4
- data/lib/capybara/spec/views/with_js.erb +11 -7
- data/lib/capybara/version.rb +1 -1
- data/lib/capybara.rb +125 -6
- data/spec/basic_node_spec.rb +17 -5
- data/spec/capybara_spec.rb +9 -0
- data/spec/dsl_spec.rb +31 -17
- data/spec/rack_test_spec.rb +157 -0
- data/spec/result_spec.rb +51 -0
- data/spec/rspec/features_spec.rb +19 -2
- data/spec/rspec/matchers_spec.rb +170 -89
- data/spec/rspec_spec.rb +1 -3
- data/spec/selenium_spec.rb +53 -0
- data/spec/server_spec.rb +37 -25
- data/spec/spec_helper.rb +1 -30
- metadata +39 -31
- data/README.rdoc +0 -722
- data/lib/capybara/spec/driver.rb +0 -301
- data/lib/capybara/spec/session/current_host_spec.rb +0 -68
- data/lib/capybara/spec/session/has_content_spec.rb +0 -106
- data/lib/capybara/spec/session/javascript.rb +0 -306
- data/lib/capybara/spec/session.rb +0 -154
- data/lib/capybara/util/save_and_open_page.rb +0 -44
- data/lib/capybara/util/timeout.rb +0 -27
- data/spec/driver/rack_test_driver_spec.rb +0 -89
- data/spec/driver/selenium_driver_spec.rb +0 -37
- data/spec/save_and_open_page_spec.rb +0 -155
- data/spec/session/rack_test_session_spec.rb +0 -55
- data/spec/session/selenium_session_spec.rb +0 -26
- data/spec/string_spec.rb +0 -77
- data/spec/timeout_spec.rb +0 -28
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
Capybara::SpecHelper.spec '#within_frame', :requires => [:frames] do
|
|
2
|
+
before(:each) do
|
|
3
|
+
@session.visit('/within_frames')
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
it "should find the div in frameOne" do
|
|
7
|
+
@session.within_frame("frameOne") do
|
|
8
|
+
@session.find("//*[@id='divInFrameOne']").text.should eql 'This is the text of divInFrameOne'
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
it "should find the div in FrameTwo" do
|
|
12
|
+
@session.within_frame("frameTwo") do
|
|
13
|
+
@session.find("//*[@id='divInFrameTwo']").text.should eql 'This is the text of divInFrameTwo'
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
it "should find the text div in the main window after finding text in frameOne" do
|
|
17
|
+
@session.within_frame("frameOne") do
|
|
18
|
+
@session.find("//*[@id='divInFrameOne']").text.should eql 'This is the text of divInFrameOne'
|
|
19
|
+
end
|
|
20
|
+
@session.find("//*[@id='divInMainWindow']").text.should eql 'This is the text for divInMainWindow'
|
|
21
|
+
end
|
|
22
|
+
it "should find the text div in the main window after finding text in frameTwo" do
|
|
23
|
+
@session.within_frame("frameTwo") do
|
|
24
|
+
@session.find("//*[@id='divInFrameTwo']").text.should eql 'This is the text of divInFrameTwo'
|
|
25
|
+
end
|
|
26
|
+
@session.find("//*[@id='divInMainWindow']").text.should eql 'This is the text for divInMainWindow'
|
|
27
|
+
end
|
|
28
|
+
it "should return the result of executing the block" do
|
|
29
|
+
@session.within_frame("frameOne") { "return value" }.should eql "return value"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -1,178 +1,165 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
end
|
|
1
|
+
Capybara::SpecHelper.spec '#within' do
|
|
2
|
+
before do
|
|
3
|
+
@session.visit('/with_scope')
|
|
4
|
+
end
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
end
|
|
12
|
-
@session.body.should include('Bar')
|
|
6
|
+
context "with CSS selector" do
|
|
7
|
+
it "should click links in the given scope" do
|
|
8
|
+
@session.within(:css, "#for_bar li[contains('With Simple HTML')]") do
|
|
9
|
+
@session.click_link('Go')
|
|
13
10
|
end
|
|
11
|
+
@session.should have_content('Bar')
|
|
12
|
+
end
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
end
|
|
19
|
-
@session.should have_content('First Name')
|
|
14
|
+
it "should assert content in the given scope" do
|
|
15
|
+
@session.within(:css, "#for_foo") do
|
|
16
|
+
@session.should_not have_content('First Name')
|
|
20
17
|
end
|
|
18
|
+
@session.should have_content('First Name')
|
|
19
|
+
end
|
|
21
20
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
end
|
|
26
|
-
@session.body.should include('Bar')
|
|
21
|
+
it "should accept additional options" do
|
|
22
|
+
@session.within(:css, "#for_bar li", :text => 'With Simple HTML') do
|
|
23
|
+
@session.click_link('Go')
|
|
27
24
|
end
|
|
25
|
+
@session.should have_content('Bar')
|
|
28
26
|
end
|
|
27
|
+
end
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
end
|
|
35
|
-
@session.body.should include('Bar')
|
|
29
|
+
context "with XPath selector" do
|
|
30
|
+
it "should click links in the given scope" do
|
|
31
|
+
@session.within(:xpath, "//div[@id='for_bar']//li[contains(.,'With Simple HTML')]") do
|
|
32
|
+
@session.click_link('Go')
|
|
36
33
|
end
|
|
34
|
+
@session.should have_content('Bar')
|
|
37
35
|
end
|
|
36
|
+
end
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
@session.body.should include('Bar')
|
|
38
|
+
context "with the default selector" do
|
|
39
|
+
it "should use XPath" do
|
|
40
|
+
@session.within("//div[@id='for_bar']//li[contains(.,'With Simple HTML')]") do
|
|
41
|
+
@session.click_link('Go')
|
|
45
42
|
end
|
|
43
|
+
@session.should have_content('Bar')
|
|
46
44
|
end
|
|
45
|
+
end
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
context "with Node rather than selector" do
|
|
48
|
+
it "should click links in the given scope" do
|
|
49
|
+
node_of_interest = @session.find(:css, "#for_bar li[contains('With Simple HTML')]")
|
|
51
50
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
end
|
|
55
|
-
@session.body.should include('Bar')
|
|
51
|
+
@session.within(node_of_interest) do
|
|
52
|
+
@session.click_link('Go')
|
|
56
53
|
end
|
|
54
|
+
@session.should have_content('Bar')
|
|
57
55
|
end
|
|
56
|
+
end
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
end
|
|
65
|
-
@session.body.should include('Bar')
|
|
58
|
+
context "with the default selector set to CSS" do
|
|
59
|
+
before { Capybara.default_selector = :css }
|
|
60
|
+
it "should use CSS" do
|
|
61
|
+
@session.within("#for_bar li[contains('With Simple HTML')]") do
|
|
62
|
+
@session.click_link('Go')
|
|
66
63
|
end
|
|
67
|
-
|
|
64
|
+
@session.should have_content('Bar')
|
|
68
65
|
end
|
|
66
|
+
after { Capybara.default_selector = :xpath }
|
|
67
|
+
end
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
context "with nested scopes" do
|
|
70
|
+
it "should respect the inner scope" do
|
|
71
|
+
@session.within("//div[@id='for_bar']") do
|
|
72
|
+
@session.within(".//li[contains(.,'Bar')]") do
|
|
73
73
|
@session.click_link('Go')
|
|
74
74
|
end
|
|
75
|
-
@session.body.should include('Bar')
|
|
76
75
|
end
|
|
76
|
+
@session.should have_content('Another World')
|
|
77
|
+
end
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
@session.click_link('Go')
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
@session.body.should include('Another World')
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
it "should respect the outer scope" do
|
|
89
|
-
@session.within("//div[@id='another_foo']") do
|
|
90
|
-
@session.within(".//li[contains(.,'With Simple HTML')]") do
|
|
91
|
-
@session.click_link('Go')
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
@session.body.should include('Hello world')
|
|
79
|
+
it "should respect the outer scope" do
|
|
80
|
+
@session.within("//div[@id='another_foo']") do
|
|
81
|
+
@session.within(".//li[contains(.,'With Simple HTML')]") do
|
|
82
|
+
@session.click_link('Go')
|
|
95
83
|
end
|
|
96
84
|
end
|
|
85
|
+
@session.should have_content('Hello world')
|
|
86
|
+
end
|
|
87
|
+
end
|
|
97
88
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
end
|
|
102
|
-
}.should raise_error(Capybara::ElementNotFound)
|
|
89
|
+
it "should raise an error if the scope is not found on the page" do
|
|
90
|
+
expect do
|
|
91
|
+
@session.within("//div[@id='doesnotexist']") do
|
|
103
92
|
end
|
|
93
|
+
end.to raise_error(Capybara::ElementNotFound)
|
|
94
|
+
end
|
|
104
95
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
end
|
|
115
|
-
}.should_not change { @session.has_xpath?(".//div[@id='another_foo']") }.from(true)
|
|
96
|
+
it "should restore the scope when an error is raised" do
|
|
97
|
+
expect do
|
|
98
|
+
@session.within("//div[@id='for_bar']") do
|
|
99
|
+
expect do
|
|
100
|
+
expect do
|
|
101
|
+
@session.within(".//div[@id='doesnotexist']") do
|
|
102
|
+
end
|
|
103
|
+
end.to raise_error(Capybara::ElementNotFound)
|
|
104
|
+
end.to_not change { @session.has_xpath?(".//div[@id='another_foo']") }.from(false)
|
|
116
105
|
end
|
|
117
|
-
end
|
|
106
|
+
end.to_not change { @session.has_xpath?(".//div[@id='another_foo']") }.from(true)
|
|
107
|
+
end
|
|
118
108
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
@session.click_button('Go')
|
|
129
|
-
end
|
|
130
|
-
extract_results(@session)['first_name'].should == 'Dagobert'
|
|
131
|
-
end
|
|
109
|
+
it "should fill in a field and click a button" do
|
|
110
|
+
@session.within("//li[contains(.,'Bar')]") do
|
|
111
|
+
@session.click_button('Go')
|
|
112
|
+
end
|
|
113
|
+
extract_results(@session)['first_name'].should == 'Peter'
|
|
114
|
+
@session.visit('/with_scope')
|
|
115
|
+
@session.within("//li[contains(.,'Bar')]") do
|
|
116
|
+
@session.fill_in('First Name', :with => 'Dagobert')
|
|
117
|
+
@session.click_button('Go')
|
|
132
118
|
end
|
|
119
|
+
extract_results(@session)['first_name'].should == 'Dagobert'
|
|
133
120
|
end
|
|
121
|
+
end
|
|
134
122
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
123
|
+
Capybara::SpecHelper.spec '#within_fieldset' do
|
|
124
|
+
before do
|
|
125
|
+
@session.visit('/fieldsets')
|
|
126
|
+
end
|
|
139
127
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
end
|
|
145
|
-
extract_results(@session)['villain_name'].should == 'Goldfinger'
|
|
128
|
+
it "should restrict scope to a fieldset given by id" do
|
|
129
|
+
@session.within_fieldset("villain_fieldset") do
|
|
130
|
+
@session.fill_in("Name", :with => 'Goldfinger')
|
|
131
|
+
@session.click_button("Create")
|
|
146
132
|
end
|
|
133
|
+
extract_results(@session)['villain_name'].should == 'Goldfinger'
|
|
134
|
+
end
|
|
147
135
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
end
|
|
153
|
-
extract_results(@session)['villain_name'].should == 'Goldfinger'
|
|
136
|
+
it "should restrict scope to a fieldset given by legend" do
|
|
137
|
+
@session.within_fieldset("Villain") do
|
|
138
|
+
@session.fill_in("Name", :with => 'Goldfinger')
|
|
139
|
+
@session.click_button("Create")
|
|
154
140
|
end
|
|
141
|
+
extract_results(@session)['villain_name'].should == 'Goldfinger'
|
|
155
142
|
end
|
|
143
|
+
end
|
|
156
144
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
145
|
+
Capybara::SpecHelper.spec '#within_table' do
|
|
146
|
+
before do
|
|
147
|
+
@session.visit('/tables')
|
|
148
|
+
end
|
|
161
149
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
end
|
|
167
|
-
extract_results(@session)['girl_name'].should == 'Christmas'
|
|
150
|
+
it "should restrict scope to a fieldset given by id" do
|
|
151
|
+
@session.within_table("girl_table") do
|
|
152
|
+
@session.fill_in("Name", :with => 'Christmas')
|
|
153
|
+
@session.click_button("Create")
|
|
168
154
|
end
|
|
155
|
+
extract_results(@session)['girl_name'].should == 'Christmas'
|
|
156
|
+
end
|
|
169
157
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
end
|
|
175
|
-
extract_results(@session)['villain_name'].should == 'Quantum'
|
|
158
|
+
it "should restrict scope to a fieldset given by legend" do
|
|
159
|
+
@session.within_table("Villain") do
|
|
160
|
+
@session.fill_in("Name", :with => 'Quantum')
|
|
161
|
+
@session.click_button("Create")
|
|
176
162
|
end
|
|
163
|
+
extract_results(@session)['villain_name'].should == 'Quantum'
|
|
177
164
|
end
|
|
178
165
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Capybara::SpecHelper.spec '#within_window', :requires => [:windows] do
|
|
2
|
+
before(:each) do
|
|
3
|
+
@session.visit('/within_popups')
|
|
4
|
+
end
|
|
5
|
+
after(:each) do
|
|
6
|
+
@session.within_window("firstPopup") do
|
|
7
|
+
@session.evaluate_script('window.close()')
|
|
8
|
+
end
|
|
9
|
+
@session.within_window("secondPopup") do
|
|
10
|
+
@session.evaluate_script('window.close()')
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "should find the div in firstPopup" do
|
|
15
|
+
@session.within_window("firstPopup") do
|
|
16
|
+
@session.find("//*[@id='divInPopupOne']").text.should eql 'This is the text of divInPopupOne'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
it "should find the div in secondPopup" do
|
|
20
|
+
@session.within_window("secondPopup") do
|
|
21
|
+
@session.find("//*[@id='divInPopupTwo']").text.should eql 'This is the text of divInPopupTwo'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
it "should find the divs in both popups" do
|
|
25
|
+
@session.within_window("secondPopup") do
|
|
26
|
+
@session.find("//*[@id='divInPopupTwo']").text.should eql 'This is the text of divInPopupTwo'
|
|
27
|
+
end
|
|
28
|
+
@session.within_window("firstPopup") do
|
|
29
|
+
@session.find("//*[@id='divInPopupOne']").text.should eql 'This is the text of divInPopupOne'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
it "should find the div in the main window after finding a div in a popup" do
|
|
33
|
+
@session.within_window("secondPopup") do
|
|
34
|
+
@session.find("//*[@id='divInPopupTwo']").text.should eql 'This is the text of divInPopupTwo'
|
|
35
|
+
end
|
|
36
|
+
@session.find("//*[@id='divInMainWindow']").text.should eql 'This is the text for divInMainWindow'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require "rspec"
|
|
2
|
+
require "capybara"
|
|
3
|
+
require "capybara/rspec" # Required here instead of in rspec_spec to avoid RSpec deprecation warning
|
|
4
|
+
require "capybara/spec/test_app"
|
|
5
|
+
require "capybara/spec/spec_helper"
|
|
6
|
+
require "nokogiri"
|
|
7
|
+
|
|
8
|
+
module Capybara
|
|
9
|
+
module SpecHelper
|
|
10
|
+
class << self
|
|
11
|
+
def configure(config)
|
|
12
|
+
filter = lambda do |requires, metadata|
|
|
13
|
+
if requires and metadata[:skip]
|
|
14
|
+
requires.any? do |require|
|
|
15
|
+
metadata[:skip].include?(require)
|
|
16
|
+
end
|
|
17
|
+
else
|
|
18
|
+
false
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
config.filter_run_excluding :requires => filter
|
|
22
|
+
config.before do
|
|
23
|
+
Capybara.app = TestApp
|
|
24
|
+
|
|
25
|
+
Capybara.configure do |config|
|
|
26
|
+
config.default_selector = :xpath
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
Capybara.default_wait_time = 1
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def spec(name, options={}, &block)
|
|
34
|
+
@specs ||= []
|
|
35
|
+
@specs << [name, options, block]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def run_specs(session, name, options={})
|
|
39
|
+
specs = @specs
|
|
40
|
+
describe Capybara::Session, name, options do
|
|
41
|
+
include Capybara::SpecHelper
|
|
42
|
+
before do
|
|
43
|
+
@session = session
|
|
44
|
+
end
|
|
45
|
+
after do
|
|
46
|
+
@session.reset_session!
|
|
47
|
+
end
|
|
48
|
+
specs.each do |name, options, block|
|
|
49
|
+
describe name, options do
|
|
50
|
+
class_eval(&block)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end # class << self
|
|
56
|
+
|
|
57
|
+
def silence_stream(stream)
|
|
58
|
+
old_stream = stream.dup
|
|
59
|
+
stream.reopen(RbConfig::CONFIG['host_os'] =~ /rmswin|mingw/ ? 'NUL:' : '/dev/null')
|
|
60
|
+
stream.sync = true
|
|
61
|
+
yield
|
|
62
|
+
ensure
|
|
63
|
+
stream.reopen(old_stream)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def quietly
|
|
67
|
+
silence_stream(STDOUT) do
|
|
68
|
+
silence_stream(STDERR) do
|
|
69
|
+
yield
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def extract_results(session)
|
|
75
|
+
YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.text.lstrip
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
RSpec.configure do |config|
|
|
81
|
+
Capybara::SpecHelper.configure(config)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
Dir[File.dirname(__FILE__)+'/session/*'].each { |group| require group }
|
|
@@ -3,8 +3,14 @@ require 'rack'
|
|
|
3
3
|
require 'yaml'
|
|
4
4
|
|
|
5
5
|
class TestApp < Sinatra::Base
|
|
6
|
+
class TestAppError < StandardError; end
|
|
7
|
+
|
|
6
8
|
set :root, File.dirname(__FILE__)
|
|
7
9
|
set :static, true
|
|
10
|
+
set :raise_errors, true
|
|
11
|
+
set :show_exceptions, false
|
|
12
|
+
|
|
13
|
+
# Also check lib/capybara/spec/views/*.erb for pages not listed here
|
|
8
14
|
|
|
9
15
|
get '/' do
|
|
10
16
|
'Hello world! <a href="with_html">Relative</a>'
|
|
@@ -22,8 +28,22 @@ class TestApp < Sinatra::Base
|
|
|
22
28
|
redirect '/landed'
|
|
23
29
|
end
|
|
24
30
|
|
|
31
|
+
get '/referer_base' do
|
|
32
|
+
'<a href="/get_referer">direct link</a>' +
|
|
33
|
+
'<a href="/redirect_to_get_referer">link via redirect</a>' +
|
|
34
|
+
'<form action="/get_referer" method="get"><input type="submit"></form>'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
get '/redirect_to_get_referer' do
|
|
38
|
+
redirect '/get_referer'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
get '/get_referer' do
|
|
42
|
+
request.referer.nil? ? "No referer" : "Got referer: #{request.referer}"
|
|
43
|
+
end
|
|
44
|
+
|
|
25
45
|
get '/host' do
|
|
26
|
-
"Current host is #{request.scheme}://#{request.host}"
|
|
46
|
+
"Current host is #{request.scheme}://#{request.host}:#{request.port}"
|
|
27
47
|
end
|
|
28
48
|
|
|
29
49
|
get '/redirect/:times/times' do
|
|
@@ -72,7 +92,7 @@ class TestApp < Sinatra::Base
|
|
|
72
92
|
end
|
|
73
93
|
|
|
74
94
|
get '/redirect_secure' do
|
|
75
|
-
redirect "https://#{request.host}/host"
|
|
95
|
+
redirect "https://#{request.host}:#{request.port}/host"
|
|
76
96
|
end
|
|
77
97
|
|
|
78
98
|
get '/slow_response' do
|
|
@@ -98,6 +118,10 @@ class TestApp < Sinatra::Base
|
|
|
98
118
|
redirect '/get_header'
|
|
99
119
|
end
|
|
100
120
|
|
|
121
|
+
get '/error' do
|
|
122
|
+
raise TestAppError, "some error"
|
|
123
|
+
end
|
|
124
|
+
|
|
101
125
|
get '/:view' do |view|
|
|
102
126
|
erb view.to_sym
|
|
103
127
|
end
|
|
@@ -107,7 +131,7 @@ class TestApp < Sinatra::Base
|
|
|
107
131
|
end
|
|
108
132
|
|
|
109
133
|
post '/upload_empty' do
|
|
110
|
-
if params[:form]
|
|
134
|
+
if params[:form][:file].nil?
|
|
111
135
|
'Successfully ignored empty file field.'
|
|
112
136
|
else
|
|
113
137
|
'Something went wrong.'
|
|
@@ -127,9 +151,11 @@ class TestApp < Sinatra::Base
|
|
|
127
151
|
|
|
128
152
|
post '/upload_multiple' do
|
|
129
153
|
begin
|
|
130
|
-
buffer = []
|
|
131
|
-
|
|
132
|
-
|
|
154
|
+
buffer = ["#{params[:form][:multiple_documents].size}"]
|
|
155
|
+
params[:form][:multiple_documents].each do |doc|
|
|
156
|
+
buffer << "Content-type: #{doc[:type]}"
|
|
157
|
+
buffer << "File content: #{doc[:tempfile].read}"
|
|
158
|
+
end
|
|
133
159
|
buffer.join(' | ')
|
|
134
160
|
rescue
|
|
135
161
|
'No files uploaded'
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<label for="form_last_name">Last Name</label>
|
|
33
33
|
<input type="text" name="form[last_name]" value="Smith" id="form_last_name"/>
|
|
34
34
|
</p>
|
|
35
|
-
|
|
35
|
+
|
|
36
36
|
<p>
|
|
37
37
|
<label for="form_name_explanation">Explanation of Name</label>
|
|
38
38
|
<textarea name="form[name_explanation]" id="form_name_explanation"></textarea>
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
<label for="form_schmooo">Schmooo</label>
|
|
48
48
|
<input type="schmooo" name="form[schmooo]" value="This is Schmooo!" id="form_schmooo"/>
|
|
49
49
|
</p>
|
|
50
|
-
|
|
50
|
+
|
|
51
51
|
<p>
|
|
52
52
|
<label>Street<br/>
|
|
53
53
|
<input type="text" maxlength="" name="form[street]" value="Sesame street 66"/>
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
<label for="form_image">Image</label>
|
|
75
75
|
<input type="file" name="form[image]" id="form_image"/>
|
|
76
76
|
</p>
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
<p>
|
|
79
79
|
<input type="hidden" name="form[token]" value="12345" id="form_token"/>
|
|
80
80
|
</p>
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
<p>
|
|
156
156
|
<label for="form_underwear">Underwear</label>
|
|
157
157
|
<select name="form[underwear][]" id="form_underwear" multiple="multiple">
|
|
158
|
-
<option selected="selected">
|
|
158
|
+
<option selected="selected">Boxerbriefs</option>
|
|
159
159
|
<option>Boxers</option>
|
|
160
160
|
<option selected="selected">Briefs</option>
|
|
161
161
|
<option selected="selected">Commando</option>
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
<option selected="selected" value="thermal">Long Johns</option>
|
|
164
164
|
</select>
|
|
165
165
|
</p>
|
|
166
|
-
|
|
166
|
+
|
|
167
167
|
<p>
|
|
168
168
|
<span>First address<span>
|
|
169
169
|
<label for='address1_street'>Street</label>
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
<input type="text" name="form[addresses][][street]" value="" id="address2_street">
|
|
186
186
|
|
|
187
187
|
<label for='address2_city'>City</label>
|
|
188
|
-
<input type="text" name="form[addresses][][city]" value="" id="address2_city">
|
|
188
|
+
<input type="text" name="form[addresses][][city]" value="" id="address2_city">
|
|
189
189
|
|
|
190
190
|
<label for='address2_country'>Country</label>
|
|
191
191
|
<select name="form[addresses][][country]" id="address2_country">
|
|
@@ -253,6 +253,7 @@
|
|
|
253
253
|
<button type="submit" id="click_me_123" title="Click Title button" value="click_me">Click me!</button>
|
|
254
254
|
<button type="submit" name="form[no_value]">No Value!</button>
|
|
255
255
|
<button id="no_type">No Type!</button>
|
|
256
|
+
<input type="button" disabled value="Disabled button"/>
|
|
256
257
|
</p>
|
|
257
258
|
</form>
|
|
258
259
|
|
|
@@ -274,6 +275,7 @@
|
|
|
274
275
|
</p>
|
|
275
276
|
|
|
276
277
|
<p>
|
|
278
|
+
<input type="hidden" name="form[dummy]" value="ensure params[:form] exists"/>
|
|
277
279
|
<input type="submit" value="Upload Empty"/>
|
|
278
280
|
<p>
|
|
279
281
|
</form>
|
|
@@ -285,12 +287,12 @@
|
|
|
285
287
|
</p>
|
|
286
288
|
|
|
287
289
|
<p>
|
|
288
|
-
<label for="form_document">Document</label>
|
|
290
|
+
<label for="form_document">Single Document</label>
|
|
289
291
|
<input type="file" name="form[document]" id="form_document"/>
|
|
290
292
|
</p>
|
|
291
|
-
|
|
293
|
+
|
|
292
294
|
<p>
|
|
293
|
-
<input type="submit" value="Upload"/>
|
|
295
|
+
<input type="submit" value="Upload Single"/>
|
|
294
296
|
<p>
|
|
295
297
|
</form>
|
|
296
298
|
|
|
@@ -337,7 +339,7 @@
|
|
|
337
339
|
<label for="html5_color">Html5 Color</label>
|
|
338
340
|
<input type="color" name="form[html5_color]" value="#FFFFFF" id="html5_color"/>
|
|
339
341
|
</p>
|
|
340
|
-
|
|
342
|
+
|
|
341
343
|
<p>
|
|
342
344
|
<input type="submit" name="form[html5_submit]" value="html5_submit"/>
|
|
343
345
|
</p>
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<p>
|
|
2
2
|
<a href="/host">Relative Host</a>
|
|
3
|
-
<a href="
|
|
3
|
+
<a href="<%= params[:absolute_host] %>/host">Absolute Host</a>
|
|
4
4
|
</p>
|
|
5
5
|
|
|
6
6
|
<form action="/host">
|
|
7
7
|
<p><input type="submit" value="Relative Host"/></p>
|
|
8
8
|
</form>
|
|
9
9
|
|
|
10
|
-
<form action="
|
|
10
|
+
<form action="<%= params[:absolute_host] %>/host">
|
|
11
11
|
<p><input type="submit" value="Absolute Host"/></p>
|
|
12
12
|
</form>
|