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,195 @@
|
|
|
1
|
+
Capybara::SpecHelper.spec '#has_text?' do
|
|
2
|
+
it "should be true if the given text is on the page at least once" do
|
|
3
|
+
@session.visit('/with_html')
|
|
4
|
+
@session.should have_text('est')
|
|
5
|
+
@session.should have_text('Lorem')
|
|
6
|
+
@session.should have_text('Redirect')
|
|
7
|
+
@session.should have_text(:'Redirect')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "should be true if scoped to an element which has the text" do
|
|
11
|
+
@session.visit('/with_html')
|
|
12
|
+
@session.within("//a[@title='awesome title']") do
|
|
13
|
+
@session.should have_text('labore')
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should be false if scoped to an element which does not have the text" do
|
|
18
|
+
@session.visit('/with_html')
|
|
19
|
+
@session.within("//a[@title='awesome title']") do
|
|
20
|
+
@session.should_not have_text('monkey')
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should ignore tags" do
|
|
25
|
+
@session.visit('/with_html')
|
|
26
|
+
@session.should_not have_text('exercitation <a href="/foo" id="foo">ullamco</a> laboris')
|
|
27
|
+
@session.should have_text('exercitation ullamco laboris')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should ignore extra whitespace and newlines" do
|
|
31
|
+
@session.visit('/with_html')
|
|
32
|
+
@session.should have_text('text with whitespace')
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "should ignore whitespace and newlines in the search string" do
|
|
36
|
+
@session.visit('/with_html')
|
|
37
|
+
@session.should have_text("text with \n\n whitespace")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "should be false if the given text is not on the page" do
|
|
41
|
+
@session.visit('/with_html')
|
|
42
|
+
@session.should_not have_text('xxxxyzzz')
|
|
43
|
+
@session.should_not have_text('monkey')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'should handle single quotes in the text' do
|
|
47
|
+
@session.visit('/with-quotes')
|
|
48
|
+
@session.should have_text("can't")
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'should handle double quotes in the text' do
|
|
52
|
+
@session.visit('/with-quotes')
|
|
53
|
+
@session.should have_text(%q{"No," he said})
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it 'should handle mixed single and double quotes in the text' do
|
|
57
|
+
@session.visit('/with-quotes')
|
|
58
|
+
@session.should have_text(%q{"you can't do that."})
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'should be false if text is in the title tag in the head' do
|
|
62
|
+
@session.visit('/with_js')
|
|
63
|
+
@session.should_not have_text('with_js')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'should be false if text is inside a script tag in the body' do
|
|
67
|
+
@session.visit('/with_js')
|
|
68
|
+
@session.should_not have_text('a javascript comment')
|
|
69
|
+
@session.should_not have_text('aVar')
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should be false if the given text is on the page but not visible" do
|
|
73
|
+
@session.visit('/with_html')
|
|
74
|
+
@session.should_not have_text('Inside element with hidden ancestor')
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "should be true if the text in the page matches given regexp" do
|
|
78
|
+
@session.visit('/with_html')
|
|
79
|
+
@session.should have_text(/Lorem/)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "should be false if the text in the page doesn't match given regexp" do
|
|
83
|
+
@session.visit('/with_html')
|
|
84
|
+
@session.should_not have_text(/xxxxyzzz/)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "should escape any characters that would have special meaning in a regexp" do
|
|
88
|
+
@session.visit('/with_html')
|
|
89
|
+
@session.should_not have_text('.orem')
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "should accept non-string parameters" do
|
|
93
|
+
@session.visit('/with_html')
|
|
94
|
+
@session.should have_text(42)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "should be true when passed nil" do
|
|
98
|
+
# Historical behavior; no particular reason other than compatibility.
|
|
99
|
+
@session.visit('/with_html')
|
|
100
|
+
@session.should have_text(nil)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should wait for text to appear", :requires => [:js] do
|
|
104
|
+
@session.visit('/with_js')
|
|
105
|
+
@session.click_link('Click me')
|
|
106
|
+
@session.should have_text("Has been clicked")
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
Capybara::SpecHelper.spec '#has_no_text?' do
|
|
111
|
+
it "should be false if the given text is on the page at least once" do
|
|
112
|
+
@session.visit('/with_html')
|
|
113
|
+
@session.should_not have_no_text('est')
|
|
114
|
+
@session.should_not have_no_text('Lorem')
|
|
115
|
+
@session.should_not have_no_text('Redirect')
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
it "should be false if scoped to an element which has the text" do
|
|
119
|
+
@session.visit('/with_html')
|
|
120
|
+
@session.within("//a[@title='awesome title']") do
|
|
121
|
+
@session.should_not have_no_text('labore')
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "should be true if scoped to an element which does not have the text" do
|
|
126
|
+
@session.visit('/with_html')
|
|
127
|
+
@session.within("//a[@title='awesome title']") do
|
|
128
|
+
@session.should have_no_text('monkey')
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it "should ignore tags" do
|
|
133
|
+
@session.visit('/with_html')
|
|
134
|
+
@session.should have_no_text('exercitation <a href="/foo" id="foo">ullamco</a> laboris')
|
|
135
|
+
@session.should_not have_no_text('exercitation ullamco laboris')
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it "should be true if the given text is not on the page" do
|
|
139
|
+
@session.visit('/with_html')
|
|
140
|
+
@session.should have_no_text('xxxxyzzz')
|
|
141
|
+
@session.should have_no_text('monkey')
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it 'should handle single quotes in the text' do
|
|
145
|
+
@session.visit('/with-quotes')
|
|
146
|
+
@session.should_not have_no_text("can't")
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it 'should handle double quotes in the text' do
|
|
150
|
+
@session.visit('/with-quotes')
|
|
151
|
+
@session.should_not have_no_text(%q{"No," he said})
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'should handle mixed single and double quotes in the text' do
|
|
155
|
+
@session.visit('/with-quotes')
|
|
156
|
+
@session.should_not have_no_text(%q{"you can't do that."})
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it 'should be true if text is in the title tag in the head' do
|
|
160
|
+
@session.visit('/with_js')
|
|
161
|
+
@session.should have_no_text('with_js')
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it 'should be true if text is inside a script tag in the body' do
|
|
165
|
+
@session.visit('/with_js')
|
|
166
|
+
@session.should have_no_text('a javascript comment')
|
|
167
|
+
@session.should have_no_text('aVar')
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "should be true if the given text is on the page but not visible" do
|
|
171
|
+
@session.visit('/with_html')
|
|
172
|
+
@session.should have_no_text('Inside element with hidden ancestor')
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "should be true if the text in the page doesn't match given regexp" do
|
|
176
|
+
@session.visit('/with_html')
|
|
177
|
+
@session.should have_no_text(/xxxxyzzz/)
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "should be false if the text in the page matches given regexp" do
|
|
181
|
+
@session.visit('/with_html')
|
|
182
|
+
@session.should_not have_no_text(/Lorem/)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it "should escape any characters that would have special meaning in a regexp" do
|
|
186
|
+
@session.visit('/with_html')
|
|
187
|
+
@session.should have_no_text('.orem')
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "should wait for text to disappear", :requires => [:js] do
|
|
191
|
+
@session.visit('/with_js')
|
|
192
|
+
@session.click_link('Click me')
|
|
193
|
+
@session.should have_no_text("I changed it")
|
|
194
|
+
end
|
|
195
|
+
end
|
|
@@ -1,123 +1,127 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
Capybara::SpecHelper.spec '#has_xpath?' do
|
|
2
|
+
before do
|
|
3
|
+
@session.visit('/with_html')
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
it "should be true if the given selector is on the page" do
|
|
7
|
+
@session.should have_xpath("//p")
|
|
8
|
+
@session.should have_xpath("//p//a[@id='foo']")
|
|
9
|
+
@session.should have_xpath("//p[contains(.,'est')]")
|
|
10
|
+
end
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
it "should be false if the given selector is not on the page" do
|
|
13
|
+
@session.should_not have_xpath("//abbr")
|
|
14
|
+
@session.should_not have_xpath("//p//a[@id='doesnotexist']")
|
|
15
|
+
@session.should_not have_xpath("//p[contains(.,'thisstringisnotonpage')]")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "should use xpath even if default selector is CSS" do
|
|
19
|
+
Capybara.default_selector = :css
|
|
20
|
+
@session.should_not have_xpath("//p//a[@id='doesnotexist']")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should respect scopes" do
|
|
24
|
+
@session.within "//p[@id='first']" do
|
|
25
|
+
@session.should have_xpath(".//a[@id='foo']")
|
|
26
|
+
@session.should_not have_xpath(".//a[@id='red']")
|
|
11
27
|
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should wait for content to appear", :requires => [:js] do
|
|
31
|
+
@session.visit('/with_js')
|
|
32
|
+
@session.click_link('Click me')
|
|
33
|
+
@session.should have_xpath("//input[@type='submit' and @value='New Here']")
|
|
34
|
+
end
|
|
12
35
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@session.
|
|
16
|
-
@session.
|
|
36
|
+
context "with count" do
|
|
37
|
+
it "should be true if the content occurs the given number of times" do
|
|
38
|
+
@session.should have_xpath("//p", :count => 3)
|
|
39
|
+
@session.should have_xpath("//p//a[@id='foo']", :count => 1)
|
|
40
|
+
@session.should have_xpath("//p[contains(.,'est')]", :count => 1)
|
|
41
|
+
@session.should have_xpath("//p//a[@id='doesnotexist']", :count => 0)
|
|
17
42
|
end
|
|
18
43
|
|
|
19
|
-
it "should
|
|
20
|
-
|
|
21
|
-
@session.should_not have_xpath("//p//a[@id='
|
|
44
|
+
it "should be false if the content occurs a different number of times than the given" do
|
|
45
|
+
@session.should_not have_xpath("//p", :count => 6)
|
|
46
|
+
@session.should_not have_xpath("//p//a[@id='foo']", :count => 2)
|
|
47
|
+
@session.should_not have_xpath("//p[contains(.,'est')]", :count => 5)
|
|
48
|
+
@session.should_not have_xpath("//p//a[@id='doesnotexist']", :count => 1)
|
|
22
49
|
end
|
|
50
|
+
end
|
|
23
51
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
end
|
|
52
|
+
context "with text" do
|
|
53
|
+
it "should discard all matches where the given string is not contained" do
|
|
54
|
+
@session.should have_xpath("//p//a", :text => "Redirect", :count => 1)
|
|
55
|
+
@session.should_not have_xpath("//p", :text => "Doesnotexist")
|
|
29
56
|
end
|
|
30
57
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
@session.should have_xpath("//p//a[@id='foo']", :count => 1)
|
|
35
|
-
@session.should have_xpath("//p[contains(.,'est')]", :count => 1)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it "should be false if the content is on the page the given number of times" do
|
|
39
|
-
@session.should_not have_xpath("//p", :count => 6)
|
|
40
|
-
@session.should_not have_xpath("//p//a[@id='foo']", :count => 2)
|
|
41
|
-
@session.should_not have_xpath("//p[contains(.,'est')]", :count => 5)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "should be false if the content isn't on the page at all" do
|
|
45
|
-
@session.should_not have_xpath("//abbr", :count => 2)
|
|
46
|
-
@session.should_not have_xpath("//p//a[@id='doesnotexist']", :count => 1)
|
|
47
|
-
end
|
|
58
|
+
it "should discard all matches where the given regexp is not matched" do
|
|
59
|
+
@session.should have_xpath("//p//a", :text => /re[dab]i/i, :count => 1)
|
|
60
|
+
@session.should_not have_xpath("//p//a", :text => /Red$/)
|
|
48
61
|
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
end
|
|
65
|
+
Capybara::SpecHelper.spec '#has_no_xpath?' do
|
|
66
|
+
before do
|
|
67
|
+
@session.visit('/with_html')
|
|
68
|
+
end
|
|
55
69
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
end
|
|
70
|
+
it "should be false if the given selector is on the page" do
|
|
71
|
+
@session.should_not have_no_xpath("//p")
|
|
72
|
+
@session.should_not have_no_xpath("//p//a[@id='foo']")
|
|
73
|
+
@session.should_not have_no_xpath("//p[contains(.,'est')]")
|
|
61
74
|
end
|
|
62
75
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
76
|
+
it "should be true if the given selector is not on the page" do
|
|
77
|
+
@session.should have_no_xpath("//abbr")
|
|
78
|
+
@session.should have_no_xpath("//p//a[@id='doesnotexist']")
|
|
79
|
+
@session.should have_no_xpath("//p[contains(.,'thisstringisnotonpage')]")
|
|
80
|
+
end
|
|
67
81
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
end
|
|
82
|
+
it "should use xpath even if default selector is CSS" do
|
|
83
|
+
Capybara.default_selector = :css
|
|
84
|
+
@session.should have_no_xpath("//p//a[@id='doesnotexist']")
|
|
85
|
+
end
|
|
73
86
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
@session.
|
|
77
|
-
@session.should have_no_xpath("
|
|
87
|
+
it "should respect scopes" do
|
|
88
|
+
@session.within "//p[@id='first']" do
|
|
89
|
+
@session.should_not have_no_xpath(".//a[@id='foo']")
|
|
90
|
+
@session.should have_no_xpath(".//a[@id='red']")
|
|
78
91
|
end
|
|
92
|
+
end
|
|
79
93
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
94
|
+
it "should wait for content to disappear", :requires => [:js] do
|
|
95
|
+
@session.visit('/with_js')
|
|
96
|
+
@session.click_link('Click me')
|
|
97
|
+
@session.should have_no_xpath("//p[@id='change']")
|
|
98
|
+
end
|
|
84
99
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
100
|
+
context "with count" do
|
|
101
|
+
it "should be false if the content occurs the given number of times" do
|
|
102
|
+
@session.should_not have_no_xpath("//p", :count => 3)
|
|
103
|
+
@session.should_not have_no_xpath("//p//a[@id='foo']", :count => 1)
|
|
104
|
+
@session.should_not have_no_xpath("//p[contains(.,'est')]", :count => 1)
|
|
105
|
+
@session.should_not have_no_xpath("//p//a[@id='doesnotexist']", :count => 0)
|
|
90
106
|
end
|
|
91
107
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
it "should be true if the content is on the page the wrong number of times" do
|
|
100
|
-
@session.should have_no_xpath("//p", :count => 6)
|
|
101
|
-
@session.should have_no_xpath("//p//a[@id='foo']", :count => 2)
|
|
102
|
-
@session.should have_no_xpath("//p[contains(.,'est')]", :count => 5)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
it "should be true if the content isn't on the page at all" do
|
|
106
|
-
@session.should have_no_xpath("//abbr", :count => 2)
|
|
107
|
-
@session.should have_no_xpath("//p//a[@id='doesnotexist']", :count => 1)
|
|
108
|
-
end
|
|
108
|
+
it "should be true if the content occurs a different number of times than the given" do
|
|
109
|
+
@session.should have_no_xpath("//p", :count => 6)
|
|
110
|
+
@session.should have_no_xpath("//p//a[@id='foo']", :count => 2)
|
|
111
|
+
@session.should have_no_xpath("//p[contains(.,'est')]", :count => 5)
|
|
112
|
+
@session.should have_no_xpath("//p//a[@id='doesnotexist']", :count => 1)
|
|
109
113
|
end
|
|
114
|
+
end
|
|
110
115
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
context "with text" do
|
|
117
|
+
it "should discard all matches where the given string is contained" do
|
|
118
|
+
@session.should_not have_no_xpath("//p//a", :text => "Redirect", :count => 1)
|
|
119
|
+
@session.should have_no_xpath("//p", :text => "Doesnotexist")
|
|
120
|
+
end
|
|
116
121
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
end
|
|
122
|
+
it "should discard all matches where the given regexp is matched" do
|
|
123
|
+
@session.should_not have_no_xpath("//p//a", :text => /re[dab]i/i, :count => 1)
|
|
124
|
+
@session.should have_no_xpath("//p//a", :text => /Red$/)
|
|
121
125
|
end
|
|
122
126
|
end
|
|
123
127
|
end
|
|
@@ -1,19 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@session.response_headers['Content-Type'].should =~ %r(text/html)
|
|
6
|
-
end
|
|
7
|
-
end
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
shared_examples_for "session without headers support" do
|
|
11
|
-
describe "#response_headers" do
|
|
12
|
-
before{ @session.visit('/with_simple_html') }
|
|
13
|
-
it "should raise an error" do
|
|
14
|
-
running {
|
|
15
|
-
@session.response_headers
|
|
16
|
-
}.should raise_error(Capybara::NotSupportedByDriverError)
|
|
17
|
-
end
|
|
1
|
+
Capybara::SpecHelper.spec '#response_headers' do
|
|
2
|
+
it "should return response headers", :requires => [:response_headers] do
|
|
3
|
+
@session.visit('/with_simple_html')
|
|
4
|
+
@session.response_headers['Content-Type'].should =~ %r(text/html)
|
|
18
5
|
end
|
|
19
6
|
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Capybara::SpecHelper.spec '#html' do
|
|
2
|
+
it "should return the unmodified page body" do
|
|
3
|
+
# html and body should be aliased, but we can't just check for
|
|
4
|
+
# method(:html) == method(:body) because these shared examples get run
|
|
5
|
+
# against the DSL, which uses forwarding methods. So we test behavior.
|
|
6
|
+
@session.visit('/')
|
|
7
|
+
@session.html.should include('Hello world!')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "should return the current state of the page", :requires => [:js] do
|
|
11
|
+
@session.visit('/with_js')
|
|
12
|
+
@session.html.should include('I changed it')
|
|
13
|
+
@session.html.should_not include('This is text')
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Capybara::SpecHelper.spec "node" do
|
|
2
|
+
before do
|
|
3
|
+
@session.visit('/with_html')
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
it "should act like a session object" do
|
|
7
|
+
@session.visit('/form')
|
|
8
|
+
@form = @session.find(:css, '#get-form')
|
|
9
|
+
@form.should have_field('Middle Name')
|
|
10
|
+
@form.should have_no_field('Languages')
|
|
11
|
+
@form.fill_in('Middle Name', :with => 'Monkey')
|
|
12
|
+
@form.click_button('med')
|
|
13
|
+
extract_results(@session)['middle_name'].should == 'Monkey'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "should scope CSS selectors" do
|
|
17
|
+
@session.find(:css, '#second').should have_no_css('h1')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
describe "#parent" do
|
|
21
|
+
it "should have a reference to its parent if there is one" do
|
|
22
|
+
@node = @session.find(:css, '#first')
|
|
23
|
+
@node.parent.should == @node.session.document
|
|
24
|
+
@node.find(:css, '#foo').parent.should == @node
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "#text" do
|
|
29
|
+
it "should extract node texts" do
|
|
30
|
+
@session.all('//a')[0].text.should == 'labore'
|
|
31
|
+
@session.all('//a')[1].text.should == 'ullamco'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should return document text on /html selector" do
|
|
35
|
+
@session.visit('/with_simple_html')
|
|
36
|
+
@session.all('/html')[0].text.should == 'Bar'
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
describe "#[]" do
|
|
41
|
+
it "should extract node attributes" do
|
|
42
|
+
@session.all('//a')[0][:class].should == 'simple'
|
|
43
|
+
@session.all('//a')[1][:id].should == 'foo'
|
|
44
|
+
@session.all('//input')[0][:type].should == 'text'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "should extract boolean node attributes" do
|
|
48
|
+
@session.find('//input[@id="checked_field"]')[:checked].should be_true
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "#value" do
|
|
53
|
+
it "should allow retrieval of the value" do
|
|
54
|
+
@session.find('//textarea[@id="normal"]').value.should == 'banana'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "should not swallow extra newlines in textarea" do
|
|
58
|
+
@session.find('//textarea[@id="additional_newline"]').value.should == "\nbanana"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe "#set" do
|
|
63
|
+
it "should allow assignment of field value" do
|
|
64
|
+
@session.first('//input').value.should == 'monkey'
|
|
65
|
+
@session.first('//input').set('gorilla')
|
|
66
|
+
@session.first('//input').value.should == 'gorilla'
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
describe "#tag_name" do
|
|
71
|
+
it "should extract node tag name" do
|
|
72
|
+
@session.all('//a')[0].tag_name.should == 'a'
|
|
73
|
+
@session.all('//a')[1].tag_name.should == 'a'
|
|
74
|
+
@session.all('//p')[1].tag_name.should == 'p'
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe "#visible?" do
|
|
79
|
+
it "should extract node visibility" do
|
|
80
|
+
@session.first('//a').should be_visible
|
|
81
|
+
|
|
82
|
+
@session.find('//div[@id="hidden"]').should_not be_visible
|
|
83
|
+
@session.find('//div[@id="hidden_via_ancestor"]').should_not be_visible
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe "#checked?" do
|
|
88
|
+
it "should extract node checked state" do
|
|
89
|
+
@session.visit('/form')
|
|
90
|
+
@session.find('//input[@id="gender_female"]').should be_checked
|
|
91
|
+
@session.find('//input[@id="gender_male"]').should_not be_checked
|
|
92
|
+
@session.first('//h1').should_not be_checked
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe "#selected?" do
|
|
97
|
+
it "should extract node selected state" do
|
|
98
|
+
@session.visit('/form')
|
|
99
|
+
@session.find('//option[@value="en"]').should be_selected
|
|
100
|
+
@session.find('//option[@value="sv"]').should_not be_selected
|
|
101
|
+
@session.first('//h1').should_not be_selected
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe "#==" do
|
|
106
|
+
it "preserve object identity" do
|
|
107
|
+
(@session.find('//h1') == @session.find('//h1')).should be_true
|
|
108
|
+
(@session.find('//h1') === @session.find('//h1')).should be_true
|
|
109
|
+
(@session.find('//h1').eql? @session.find('//h1')).should be_false
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
describe "#trigger", :requires => [:js, :trigger] do
|
|
114
|
+
it "should allow triggering of custom JS events" do
|
|
115
|
+
@session.visit('/with_js')
|
|
116
|
+
@session.find(:css, '#with_focus_event').trigger(:focus)
|
|
117
|
+
@session.should have_css('#focus_event_triggered')
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
describe '#drag_to', :requires => [:js, :drag] do
|
|
122
|
+
it "should drag and drop an object" do
|
|
123
|
+
@session.visit('/with_js')
|
|
124
|
+
element = @session.find('//div[@id="drag"]')
|
|
125
|
+
target = @session.find('//div[@id="drop"]')
|
|
126
|
+
element.drag_to(target)
|
|
127
|
+
@session.find('//div[contains(., "Dropped!")]').should_not be_nil
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe '#reload', :requires => [:js] do
|
|
132
|
+
context "without automatic reload" do
|
|
133
|
+
before { Capybara.automatic_reload = false }
|
|
134
|
+
it "should reload the current context of the node" do
|
|
135
|
+
@session.visit('/with_js')
|
|
136
|
+
node = @session.find(:css, '#reload-me')
|
|
137
|
+
@session.click_link('Reload!')
|
|
138
|
+
sleep(0.3)
|
|
139
|
+
node.reload.text.should == 'has been reloaded'
|
|
140
|
+
node.text.should == 'has been reloaded'
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "should reload a parent node" do
|
|
144
|
+
@session.visit('/with_js')
|
|
145
|
+
node = @session.find(:css, '#reload-me').find(:css, 'em')
|
|
146
|
+
@session.click_link('Reload!')
|
|
147
|
+
sleep(0.3)
|
|
148
|
+
node.reload.text.should == 'has been reloaded'
|
|
149
|
+
node.text.should == 'has been reloaded'
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
it "should not automatically reload" do
|
|
153
|
+
@session.visit('/with_js')
|
|
154
|
+
node = @session.find(:css, '#reload-me')
|
|
155
|
+
@session.click_link('Reload!')
|
|
156
|
+
sleep(0.3)
|
|
157
|
+
expect { node.text.to == 'has been reloaded' }.to raise_error
|
|
158
|
+
end
|
|
159
|
+
after { Capybara.automatic_reload = true }
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
context "with automatic reload" do
|
|
163
|
+
it "should reload the current context of the node automatically" do
|
|
164
|
+
@session.visit('/with_js')
|
|
165
|
+
node = @session.find(:css, '#reload-me')
|
|
166
|
+
@session.click_link('Reload!')
|
|
167
|
+
sleep(0.3)
|
|
168
|
+
node.text.should == 'has been reloaded'
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "should reload a parent node automatically" do
|
|
172
|
+
@session.visit('/with_js')
|
|
173
|
+
node = @session.find(:css, '#reload-me').find(:css, 'em')
|
|
174
|
+
@session.click_link('Reload!')
|
|
175
|
+
sleep(0.3)
|
|
176
|
+
node.text.should == 'has been reloaded'
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
it "should reload a node automatically when using find" do
|
|
180
|
+
@session.visit('/with_js')
|
|
181
|
+
node = @session.find(:css, '#reload-me')
|
|
182
|
+
@session.click_link('Reload!')
|
|
183
|
+
sleep(0.3)
|
|
184
|
+
node.find(:css, 'a').text.should == 'has been reloaded'
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
it "should not reload nodes which haven't been found" do
|
|
188
|
+
@session.visit('/with_js')
|
|
189
|
+
node = @session.all(:css, '#the-list li')[1]
|
|
190
|
+
@session.click_link('Fetch new list!')
|
|
191
|
+
sleep(0.3)
|
|
192
|
+
expect { node.text.to == 'Foo' }.to raise_error
|
|
193
|
+
expect { node.text.to == 'Bar' }.to raise_error
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "should reload nodes with options" do
|
|
197
|
+
@session.visit('/with_js')
|
|
198
|
+
node = @session.find(:css, 'em', :text => "reloaded")
|
|
199
|
+
@session.click_link('Reload!')
|
|
200
|
+
sleep(1)
|
|
201
|
+
node.text.should == 'has been reloaded'
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|