capybara 0.3.9 → 0.4.0.rc
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +43 -1
- data/README.rdoc +168 -98
- data/lib/capybara.rb +77 -15
- data/lib/capybara/driver/base.rb +21 -16
- data/lib/capybara/driver/celerity_driver.rb +39 -41
- data/lib/capybara/driver/culerity_driver.rb +2 -1
- data/lib/capybara/driver/node.rb +66 -0
- data/lib/capybara/driver/rack_test_driver.rb +66 -67
- data/lib/capybara/driver/selenium_driver.rb +43 -47
- data/lib/capybara/dsl.rb +44 -6
- data/lib/capybara/node.rb +185 -24
- data/lib/capybara/node/actions.rb +170 -0
- data/lib/capybara/node/finders.rb +150 -0
- data/lib/capybara/node/matchers.rb +360 -0
- data/lib/capybara/rails.rb +1 -0
- data/lib/capybara/selector.rb +52 -0
- data/lib/capybara/server.rb +68 -87
- data/lib/capybara/session.rb +221 -207
- data/lib/capybara/spec/driver.rb +45 -35
- data/lib/capybara/spec/public/test.js +1 -1
- data/lib/capybara/spec/session.rb +28 -53
- data/lib/capybara/spec/session/all_spec.rb +7 -3
- data/lib/capybara/spec/session/check_spec.rb +50 -52
- data/lib/capybara/spec/session/click_button_spec.rb +9 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +37 -0
- data/lib/capybara/spec/session/current_url_spec.rb +7 -0
- data/lib/capybara/spec/session/find_button_spec.rb +4 -2
- data/lib/capybara/spec/session/find_by_id_spec.rb +4 -2
- data/lib/capybara/spec/session/find_field_spec.rb +7 -3
- data/lib/capybara/spec/session/find_link_spec.rb +5 -3
- data/lib/capybara/spec/session/find_spec.rb +71 -6
- data/lib/capybara/spec/session/has_field_spec.rb +1 -1
- data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
- data/lib/capybara/spec/session/has_xpath_spec.rb +4 -4
- data/lib/capybara/spec/session/javascript.rb +25 -5
- data/lib/capybara/spec/session/select_spec.rb +16 -2
- data/lib/capybara/spec/session/unselect_spec.rb +8 -1
- data/lib/capybara/spec/session/within_spec.rb +5 -5
- data/lib/capybara/spec/views/form.erb +65 -1
- data/lib/capybara/spec/views/popup_one.erb +8 -0
- data/lib/capybara/spec/views/popup_two.erb +8 -0
- data/lib/capybara/spec/views/with_html.erb +5 -0
- data/lib/capybara/spec/views/within_popups.erb +25 -0
- data/lib/capybara/{save_and_open_page.rb → util/save_and_open_page.rb} +3 -3
- data/lib/capybara/util/timeout.rb +27 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/capybara_spec.rb +18 -8
- data/spec/driver/celerity_driver_spec.rb +10 -14
- data/spec/driver/culerity_driver_spec.rb +4 -3
- data/spec/driver/rack_test_driver_spec.rb +39 -2
- data/spec/driver/remote_culerity_driver_spec.rb +5 -7
- data/spec/driver/remote_selenium_driver_spec.rb +7 -10
- data/spec/driver/selenium_driver_spec.rb +3 -2
- data/spec/dsl_spec.rb +5 -14
- data/spec/save_and_open_page_spec.rb +19 -19
- data/spec/server_spec.rb +22 -10
- data/spec/session/celerity_session_spec.rb +17 -21
- data/spec/session/culerity_session_spec.rb +3 -3
- data/spec/session/rack_test_session_spec.rb +2 -2
- data/spec/session/selenium_session_spec.rb +2 -2
- data/spec/spec_helper.rb +27 -6
- data/spec/{wait_until_spec.rb → timeout_spec.rb} +14 -14
- metadata +88 -46
- data/lib/capybara/searchable.rb +0 -54
- data/lib/capybara/spec/session/click_spec.rb +0 -24
- data/lib/capybara/spec/session/locate_spec.rb +0 -65
- data/lib/capybara/wait_until.rb +0 -28
- data/lib/capybara/xpath.rb +0 -179
- data/spec/searchable_spec.rb +0 -66
- data/spec/xpath_spec.rb +0 -180
@@ -12,6 +12,13 @@ shared_examples_for "unselect" do
|
|
12
12
|
extract_results(@session)['underwear'].should_not include('Commando')
|
13
13
|
end
|
14
14
|
|
15
|
+
it "should unselect an option without a select box" do
|
16
|
+
@session.unselect('Commando')
|
17
|
+
@session.click_button('awesome')
|
18
|
+
extract_results(@session)['underwear'].should include('Briefs', 'Boxer Briefs')
|
19
|
+
extract_results(@session)['underwear'].should_not include('Commando')
|
20
|
+
end
|
21
|
+
|
15
22
|
it "should unselect an option from a select box by label" do
|
16
23
|
@session.unselect('Commando', :from => 'Underwear')
|
17
24
|
@session.click_button('awesome')
|
@@ -47,7 +54,7 @@ shared_examples_for "unselect" do
|
|
47
54
|
|
48
55
|
context "with an option that doesn't exist" do
|
49
56
|
it "should raise an error" do
|
50
|
-
running { @session.unselect('Does not Exist', :from => 'form_underwear') }.should raise_error(Capybara::
|
57
|
+
running { @session.unselect('Does not Exist', :from => 'form_underwear') }.should raise_error(Capybara::ElementNotFound)
|
51
58
|
end
|
52
59
|
end
|
53
60
|
end
|
@@ -53,7 +53,7 @@ shared_examples_for "within" do
|
|
53
53
|
context "with nested scopes" do
|
54
54
|
it "should respect the inner scope" do
|
55
55
|
@session.within("//div[@id='for_bar']") do
|
56
|
-
@session.within("
|
56
|
+
@session.within(".//li[contains(.,'Bar')]") do
|
57
57
|
@session.click_link('Go')
|
58
58
|
end
|
59
59
|
end
|
@@ -62,7 +62,7 @@ shared_examples_for "within" do
|
|
62
62
|
|
63
63
|
it "should respect the outer scope" do
|
64
64
|
@session.within("//div[@id='another_foo']") do
|
65
|
-
@session.within("
|
65
|
+
@session.within(".//li[contains(.,'With Simple HTML')]") do
|
66
66
|
@session.click_link('Go')
|
67
67
|
end
|
68
68
|
end
|
@@ -82,12 +82,12 @@ shared_examples_for "within" do
|
|
82
82
|
@session.within("//div[@id='for_bar']") do
|
83
83
|
running {
|
84
84
|
running {
|
85
|
-
@session.within("
|
85
|
+
@session.within(".//div[@id='doesnotexist']") do
|
86
86
|
end
|
87
87
|
}.should raise_error(Capybara::ElementNotFound)
|
88
|
-
}.should_not change { @session.has_xpath?("
|
88
|
+
}.should_not change { @session.has_xpath?(".//div[@id='another_foo']") }.from(false)
|
89
89
|
end
|
90
|
-
}.should_not change { @session.has_xpath?("
|
90
|
+
}.should_not change { @session.has_xpath?(".//div[@id='another_foo']") }.from(true)
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -155,8 +155,27 @@
|
|
155
155
|
<option selected="selected">Briefs</option>
|
156
156
|
<option selected="selected">Commando</option>
|
157
157
|
<option selected="selected">Frenchman's Pantalons</option>
|
158
|
+
<option selected="selected" value="thermal">Long Johns</option>
|
158
159
|
</select>
|
159
160
|
</p>
|
161
|
+
|
162
|
+
<p>
|
163
|
+
<span>First address<span>
|
164
|
+
<label for='address1_street'>Street</label>
|
165
|
+
<input type="text" name="form[addresses][][street]" value="" id="address1_street">
|
166
|
+
|
167
|
+
<label for='address1_city'>City</label>
|
168
|
+
<input type="text" name="form[addresses][][city]" value="" id="address1_city">
|
169
|
+
</p>
|
170
|
+
|
171
|
+
<p>
|
172
|
+
<span>Second address<span>
|
173
|
+
<label for='address2_street'>Street</label>
|
174
|
+
<input type="text" name="form[addresses][][street]" value="" id="address2_street">
|
175
|
+
|
176
|
+
<label for='address2_city'>City</label>
|
177
|
+
<input type="text" name="form[addresses][][city]" value="" id="address2_city">
|
178
|
+
</p>
|
160
179
|
|
161
180
|
<div style="display:none;">
|
162
181
|
<label for="form_first_name_hidden">
|
@@ -165,6 +184,50 @@
|
|
165
184
|
</label>
|
166
185
|
</div>
|
167
186
|
|
187
|
+
<p>
|
188
|
+
<label for="form_disabled_text_field">
|
189
|
+
Disabled Text Field
|
190
|
+
<input type="text" name="form[disabled_text_field]" value="Should not see me" id="form_disabled_text_field" disabled="disabled" />
|
191
|
+
</label>
|
192
|
+
</p>
|
193
|
+
|
194
|
+
<p>
|
195
|
+
<label for="form_disabled_textarea">
|
196
|
+
Disabled Textarea
|
197
|
+
<textarea name="form[disabled_textarea]" value="Should not see me" id="form_disabled_textarea" disabled="disabled"></textarea>
|
198
|
+
</label>
|
199
|
+
</p>
|
200
|
+
|
201
|
+
<p>
|
202
|
+
<label for="form_disabled_checkbox">
|
203
|
+
Disabled Checkbox
|
204
|
+
<input type="checkbox" name="form[disabled_checkbox]" value="Should not see me" id="form_disabled_checkbox" checked="checked" disabled="disabled" />
|
205
|
+
</label>
|
206
|
+
</p>
|
207
|
+
|
208
|
+
<p>
|
209
|
+
<label for="form_disabled_radio">
|
210
|
+
Disabled Checkbox
|
211
|
+
<input type="radio" name="form[disabled_radio]" value="Should not see me" id="form_disabled_radio" checked="checked" disabled="disabled" />
|
212
|
+
</label>
|
213
|
+
</p>
|
214
|
+
|
215
|
+
<p>
|
216
|
+
<label for="form_disabled_select">
|
217
|
+
Disabled Select
|
218
|
+
<select name="form[disabled_select]" id="form_disabled_select" disabled="disabled">
|
219
|
+
<option value="Should not see me" selected="selected">Should not see me</option>
|
220
|
+
</select>
|
221
|
+
</label>
|
222
|
+
</p>
|
223
|
+
|
224
|
+
<p>
|
225
|
+
<label for="form_disabled_file">
|
226
|
+
Disabled File
|
227
|
+
<input type="file" name="form[disabled_file]" value="/should/not/see/me" id="form_disabled_file" disabled="disabled" />
|
228
|
+
</label>
|
229
|
+
</p>
|
230
|
+
|
168
231
|
<p>
|
169
232
|
<input type="button" name="form[fresh]" id="fresh_btn" value="i am fresh"/>
|
170
233
|
<input type="submit" name="form[awesome]" id="awe123" value="awesome"/>
|
@@ -172,10 +235,11 @@
|
|
172
235
|
<input type="image" name="form[okay]" id="okay556" value="okay" alt="oh hai thar"/>
|
173
236
|
<button type="submit" id="click_me_123" value="click_me">Click me!</button>
|
174
237
|
<button type="submit" name="form[no_value]">No Value!</button>
|
238
|
+
<button id="no_type">No Type!</button>
|
175
239
|
</p>
|
176
240
|
</form>
|
177
241
|
|
178
|
-
<form action="/form/get?foo=bar" method="get">
|
242
|
+
<form id="get-form" action="/form/get?foo=bar" method="get">
|
179
243
|
<p>
|
180
244
|
<label for="form_middle_name">Middle Name</label>
|
181
245
|
<input type="text" name="form[middle_name]" value="Darren" id="form_middle_name"/>
|
@@ -41,3 +41,8 @@
|
|
41
41
|
<div id="hidden_via_ancestor">Inside element with hidden ancestor</div>
|
42
42
|
<a href="/with_simple_html" title="awesome title" class="simple">hidden link</a>
|
43
43
|
</div>
|
44
|
+
|
45
|
+
<ul>
|
46
|
+
<li id="john_monkey">Monkey John</li>
|
47
|
+
<li id="paul_monkey">Monkey Paul</li>
|
48
|
+
</ul>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>With Popups</title>
|
4
|
+
<script language="javascript" type="text/javascript">
|
5
|
+
<!--
|
6
|
+
|
7
|
+
function popItUp(name, url) {
|
8
|
+
newwindow=window.open(url,name,'height=200,width=150');
|
9
|
+
if (window.focus) { newwindow.focus() }
|
10
|
+
return false;
|
11
|
+
}
|
12
|
+
|
13
|
+
function init() {
|
14
|
+
popItUp('firstPopup', '/popup_one');
|
15
|
+
popItUp('secondPopup', '/popup_two');
|
16
|
+
}
|
17
|
+
window.onload = init;
|
18
|
+
|
19
|
+
// -->
|
20
|
+
</script>
|
21
|
+
</head>
|
22
|
+
<body>
|
23
|
+
<div id="divInMainWindow">This is the text for divInMainWindow</div>
|
24
|
+
</body>
|
25
|
+
</html>
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module Capybara
|
2
|
-
|
3
|
-
extend(self)
|
4
|
-
|
2
|
+
class << self
|
5
3
|
def save_and_open_page(html)
|
6
4
|
name = File.join(*[Capybara.save_and_open_page_path, "capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}.html"].compact)
|
7
5
|
|
@@ -17,6 +15,8 @@ module Capybara
|
|
17
15
|
open_in_browser(tempfile.path)
|
18
16
|
end
|
19
17
|
|
18
|
+
protected
|
19
|
+
|
20
20
|
def open_in_browser(path) # :nodoc
|
21
21
|
require "launchy"
|
22
22
|
Launchy::Browser.run(path)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Capybara
|
2
|
+
class << self
|
3
|
+
|
4
|
+
##
|
5
|
+
# Provides timeout similar to standard library Timeout, but avoids threads
|
6
|
+
#
|
7
|
+
def timeout(seconds = 1, driver = nil, &block)
|
8
|
+
start_time = Time.now
|
9
|
+
|
10
|
+
result = nil
|
11
|
+
|
12
|
+
until result
|
13
|
+
return result if result = yield
|
14
|
+
|
15
|
+
delay = seconds - (Time.now - start_time)
|
16
|
+
if delay <= 0
|
17
|
+
raise TimeoutError
|
18
|
+
end
|
19
|
+
|
20
|
+
driver && driver.wait_until(delay)
|
21
|
+
|
22
|
+
sleep(0.05)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/lib/capybara/version.rb
CHANGED
data/spec/capybara_spec.rb
CHANGED
@@ -1,18 +1,28 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require 'capybara'
|
1
|
+
require 'spec_helper'
|
4
2
|
|
5
3
|
describe Capybara do
|
6
|
-
|
4
|
+
|
7
5
|
describe 'default_wait_time' do
|
8
6
|
after do
|
9
|
-
Capybara.default_wait_time =
|
7
|
+
Capybara.default_wait_time = @previous_default_time
|
10
8
|
end
|
11
|
-
|
9
|
+
|
12
10
|
it "should be changeable" do
|
11
|
+
@previous_default_time = Capybara.default_wait_time
|
13
12
|
Capybara.default_wait_time = 5
|
14
13
|
Capybara.default_wait_time.should == 5
|
15
14
|
end
|
16
15
|
end
|
17
|
-
|
18
|
-
|
16
|
+
|
17
|
+
describe '.register_driver' do
|
18
|
+
it "should add a new driver" do
|
19
|
+
Capybara.register_driver :schmoo do |app|
|
20
|
+
Capybara::Driver::RackTest.new(app)
|
21
|
+
end
|
22
|
+
session = Capybara::Session.new(:schmoo, TestApp)
|
23
|
+
session.visit('/')
|
24
|
+
session.body.should include("Hello world!")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -1,17 +1,13 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@driver = Capybara::Driver::Celerity.new(TestApp)
|
7
|
-
end
|
8
|
-
|
9
|
-
it_should_behave_like "driver"
|
10
|
-
it_should_behave_like "driver with javascript support"
|
11
|
-
it_should_behave_like "driver with header support"
|
12
|
-
it_should_behave_like "driver with status code support"
|
13
|
-
it_should_behave_like "driver with cookies support"
|
3
|
+
describe Capybara::Driver::Celerity, :jruby => :platform do
|
4
|
+
before(:all) do
|
5
|
+
@driver = TestSessions::Celerity.driver
|
14
6
|
end
|
15
|
-
|
16
|
-
|
7
|
+
|
8
|
+
it_should_behave_like "driver"
|
9
|
+
it_should_behave_like "driver with javascript support"
|
10
|
+
it_should_behave_like "driver with header support"
|
11
|
+
it_should_behave_like "driver with status code support"
|
12
|
+
it_should_behave_like "driver with cookies support"
|
17
13
|
end
|
@@ -1,8 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Capybara::Driver::Culerity, :jruby => :installed do
|
2
4
|
|
3
|
-
describe Capybara::Driver::Culerity do
|
4
5
|
before(:all) do
|
5
|
-
@driver =
|
6
|
+
@driver = TestSessions::Culerity.driver
|
6
7
|
end
|
7
8
|
|
8
9
|
it_should_behave_like "driver"
|
@@ -1,8 +1,22 @@
|
|
1
|
-
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
def capture(*streams)
|
6
|
+
streams.map! { |stream| stream.to_s }
|
7
|
+
begin
|
8
|
+
result = StringIO.new
|
9
|
+
streams.each { |stream| eval "$#{stream} = result" }
|
10
|
+
yield
|
11
|
+
ensure
|
12
|
+
streams.each { |stream| eval("$#{stream} = #{stream.upcase}") }
|
13
|
+
end
|
14
|
+
result.string
|
15
|
+
end
|
2
16
|
|
3
17
|
describe Capybara::Driver::RackTest do
|
4
18
|
before do
|
5
|
-
@driver =
|
19
|
+
@driver = TestSessions::RackTest.driver
|
6
20
|
end
|
7
21
|
|
8
22
|
it "should throw an error when no rack app is given" do
|
@@ -11,6 +25,29 @@ describe Capybara::Driver::RackTest do
|
|
11
25
|
end.should raise_error(ArgumentError)
|
12
26
|
end
|
13
27
|
|
28
|
+
if '1.9'.respond_to?(:encode)
|
29
|
+
describe "with non-binary parameters" do
|
30
|
+
|
31
|
+
it "should convert attribute values to binary" do
|
32
|
+
output = capture(:stderr) {
|
33
|
+
@driver.visit('/mypage', :param => 'µ')
|
34
|
+
}.should_not =~ %r{warning: regexp match /.../n against to UTF-8 string}
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should convert attribute with Array to binary" do
|
38
|
+
output = capture(:stderr) {
|
39
|
+
@driver.visit('/mypage', :param => ['µ'])
|
40
|
+
}.should_not =~ %r{warning: regexp match /.../n against to UTF-8 string}
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should convert path to binary" do
|
44
|
+
output = capture(:stderr) {
|
45
|
+
@driver.visit('/mypage'.encode('utf-8'))
|
46
|
+
}.should_not =~ %r{warning: regexp match /.../n against to UTF-8 string}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
14
51
|
it_should_behave_like "driver"
|
15
52
|
it_should_behave_like "driver with header support"
|
16
53
|
it_should_behave_like "driver with status code support"
|
@@ -1,22 +1,20 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Capybara::Driver::Culerity do
|
3
|
+
describe Capybara::Driver::Culerity, :jruby => :installed do
|
4
4
|
before(:all) do
|
5
5
|
Capybara.app_host = "http://capybara-testapp.heroku.com"
|
6
|
-
|
7
|
-
@driver = Capybara::Driver::Culerity.new(TestApp)
|
6
|
+
@driver = TestSessions::Culerity.driver
|
8
7
|
end
|
9
|
-
|
8
|
+
|
10
9
|
after(:all) do
|
11
10
|
Capybara.app_host = nil
|
12
|
-
Capybara.run_server = true
|
13
11
|
end
|
14
12
|
|
15
13
|
it "should navigate to a fully qualified remote page" do
|
16
14
|
@driver.visit('http://capybara-testapp.heroku.com/foo')
|
17
15
|
@driver.body.should include('Another World')
|
18
16
|
end
|
19
|
-
|
17
|
+
|
20
18
|
it_should_behave_like "driver"
|
21
19
|
it_should_behave_like "driver with javascript support"
|
22
20
|
it_should_behave_like "driver with header support"
|
@@ -1,19 +1,16 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Capybara::Driver::Selenium do
|
4
|
-
before
|
5
|
-
Capybara.app_host = "http://capybara-testapp.heroku.com"
|
6
|
-
|
7
|
-
|
8
|
-
after(:all) do
|
9
|
-
Capybara.app_host = nil
|
4
|
+
before do
|
5
|
+
#Capybara.app_host = "http://capybara-testapp.heroku.com"
|
6
|
+
@driver = TestSessions::Selenium.driver
|
10
7
|
end
|
11
8
|
|
12
|
-
|
13
|
-
|
9
|
+
after do
|
10
|
+
Capybara.app_host = nil
|
14
11
|
end
|
15
12
|
|
16
13
|
it_should_behave_like "driver"
|
17
14
|
it_should_behave_like "driver with javascript support"
|
18
15
|
it_should_behave_like "driver without status code support"
|
19
|
-
end
|
16
|
+
end
|