capybara 0.4.0 → 0.4.1.rc
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +35 -0
- data/README.rdoc +60 -19
- data/lib/capybara.rb +81 -5
- data/lib/capybara/driver/base.rb +1 -6
- data/lib/capybara/driver/celerity_driver.rb +19 -9
- data/lib/capybara/driver/node.rb +8 -0
- data/lib/capybara/driver/rack_test_driver.rb +42 -29
- data/lib/capybara/driver/selenium_driver.rb +11 -3
- data/lib/capybara/dsl.rb +11 -0
- data/lib/capybara/node/actions.rb +4 -14
- data/lib/capybara/node/base.rb +47 -0
- data/lib/capybara/node/document.rb +17 -0
- data/lib/capybara/node/element.rb +178 -0
- data/lib/capybara/node/finders.rb +78 -27
- data/lib/capybara/node/matchers.rb +40 -11
- data/lib/capybara/node/simple.rb +116 -0
- data/lib/capybara/rspec.rb +18 -0
- data/lib/capybara/server.rb +5 -10
- data/lib/capybara/session.rb +7 -16
- data/lib/capybara/spec/driver.rb +16 -1
- data/lib/capybara/spec/session.rb +1 -0
- data/lib/capybara/spec/session/all_spec.rb +5 -0
- data/lib/capybara/spec/session/attach_file_spec.rb +6 -0
- data/lib/capybara/spec/session/click_link_or_button_spec.rb +2 -3
- data/lib/capybara/spec/session/find_spec.rb +0 -6
- data/lib/capybara/spec/session/first_spec.rb +72 -0
- data/lib/capybara/spec/session/has_css_spec.rb +107 -1
- data/lib/capybara/spec/session/has_field_spec.rb +60 -0
- data/lib/capybara/spec/session/has_select_spec.rb +40 -0
- data/lib/capybara/spec/session/javascript.rb +4 -13
- data/lib/capybara/spec/session/within_spec.rb +10 -3
- data/lib/capybara/spec/test_app.rb +20 -1
- data/lib/capybara/spec/views/form.erb +27 -0
- data/lib/capybara/spec/views/with_html.erb +21 -5
- data/lib/capybara/util/save_and_open_page.rb +8 -5
- data/lib/capybara/version.rb +1 -1
- data/spec/basic_node_spec.rb +77 -0
- data/spec/capybara_spec.rb +18 -0
- data/spec/dsl_spec.rb +26 -0
- data/spec/rspec_spec.rb +47 -0
- data/spec/save_and_open_page_spec.rb +83 -7
- data/spec/server_spec.rb +20 -0
- data/spec/session/rack_test_session_spec.rb +10 -0
- data/spec/string_spec.rb +77 -0
- metadata +306 -295
- data/lib/capybara/node.rb +0 -221
@@ -25,12 +25,15 @@ module Capybara
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def rewrite_css_and_image_references(response_html) # :nodoc:
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
root = Capybara.asset_root
|
29
|
+
return response_html unless root
|
30
|
+
directories = Dir.new(root).entries.select { |name|
|
31
|
+
(root+name).directory? and not name.to_s =~ /^\./
|
32
|
+
}
|
33
|
+
if not directories.empty?
|
34
|
+
response_html.gsub!(/("|')\/(#{directories.join('|')})/, '\1' + root.to_s + '/\2')
|
32
35
|
end
|
33
|
-
response_html
|
36
|
+
return response_html
|
34
37
|
end
|
35
38
|
end
|
36
39
|
end
|
data/lib/capybara/version.rb
CHANGED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Capybara do
|
4
|
+
describe '.string' do
|
5
|
+
let :string do
|
6
|
+
Capybara.string <<-STRING
|
7
|
+
<div id="page">
|
8
|
+
<div id="content">
|
9
|
+
<h1 data="fantastic">Awesome</h1>
|
10
|
+
<p>Yes it is</p>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div id="footer" style="display: none">
|
14
|
+
<p>c2010</p>
|
15
|
+
<p>Jonas Nicklas</p>
|
16
|
+
<input type="text" name="foo" value="bar"/>
|
17
|
+
<select name="animal">
|
18
|
+
<option>Monkey</option>
|
19
|
+
<option selected="selected">Capybara</option>
|
20
|
+
</select>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
STRING
|
24
|
+
end
|
25
|
+
|
26
|
+
it "allows using matchers" do
|
27
|
+
string.should have_css('#page')
|
28
|
+
string.should_not have_css('#does-not-exist')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "allows using custom matchers" do
|
32
|
+
Capybara.add_selector :lifeform do
|
33
|
+
xpath { |name| "//option[contains(.,'#{name}')]" }
|
34
|
+
end
|
35
|
+
string.should have_selector(:page)
|
36
|
+
string.should_not have_selector(:'does-not-exist')
|
37
|
+
string.should have_selector(:lifeform, "Monkey")
|
38
|
+
string.should_not have_selector(:lifeform, "Gorilla")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "allows using matchers with text option" do
|
42
|
+
string.should have_css('h1', :text => 'Awesome')
|
43
|
+
string.should_not have_css('h1', :text => 'Not so awesome')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "allows finding only visible nodes" do
|
47
|
+
string.all('//p', :text => 'c2010', :visible => true).should be_empty
|
48
|
+
string.all('//p', :text => 'c2010', :visible => false).should have(1).element
|
49
|
+
end
|
50
|
+
|
51
|
+
it "allows finding elements and extracting text from them" do
|
52
|
+
string.find('//h1').text.should == 'Awesome'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "allows finding elements and extracting attributes from them" do
|
56
|
+
string.find('//h1')[:data].should == 'fantastic'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "allows finding elements and extracting the tag name from them" do
|
60
|
+
string.find('//h1').tag_name.should == 'h1'
|
61
|
+
end
|
62
|
+
|
63
|
+
it "allows finding elements and extracting the path" do
|
64
|
+
string.find('//h1').path.should == '/html/body/div/div[1]/h1'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "allows finding elements and extracting the path" do
|
68
|
+
string.find('//input').value.should == 'bar'
|
69
|
+
string.find('//select').value.should == 'Capybara'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "allows finding elements and checking if they are visible" do
|
73
|
+
string.find('//h1').should be_visible
|
74
|
+
string.find('//input').should_not be_visible
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
data/spec/capybara_spec.rb
CHANGED
@@ -25,4 +25,22 @@ describe Capybara do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
describe ".server" do
|
29
|
+
after do
|
30
|
+
Capybara.server {|app, port| Capybara.run_default_server(app, port)}
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should default to a proc that calls run_default_server" do
|
34
|
+
mock_app = mock('app')
|
35
|
+
Capybara.should_receive(:run_default_server).with(mock_app, 8000)
|
36
|
+
Capybara.server.call(mock_app, 8000)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should return a custom server proc" do
|
40
|
+
server = lambda {|app, port|}
|
41
|
+
Capybara.server(&server)
|
42
|
+
Capybara.server.should == server
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
28
46
|
end
|
data/spec/dsl_spec.rb
CHANGED
@@ -56,6 +56,32 @@ describe Capybara do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
describe '#using_driver' do
|
60
|
+
before do
|
61
|
+
Capybara.current_driver.should_not == :selenium
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should set the driver using Capybara.current_driver=' do
|
65
|
+
driver = nil
|
66
|
+
Capybara.using_driver(:selenium) { driver = Capybara.current_driver }
|
67
|
+
driver.should == :selenium
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should reset the driver using Capybara.use_default_driver, even if an exception occurs' do
|
71
|
+
begin
|
72
|
+
Capybara.using_driver(:selenium) { raise "ohnoes!" }
|
73
|
+
rescue Exception
|
74
|
+
end
|
75
|
+
Capybara.current_driver.should == Capybara.default_driver
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should yield the passed block' do
|
79
|
+
called = false
|
80
|
+
Capybara.using_driver(:selenium) { called = true }
|
81
|
+
called.should == true
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
59
85
|
describe '#app' do
|
60
86
|
it "should be changeable" do
|
61
87
|
Capybara.app = "foobar"
|
data/spec/rspec_spec.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'capybara/rspec'
|
3
|
+
|
4
|
+
Capybara.app = TestApp
|
5
|
+
|
6
|
+
describe 'capybara/rspec', :type => :acceptance do
|
7
|
+
it "should include Capybara in rpsec" do
|
8
|
+
visit('/foo')
|
9
|
+
page.body.should include('Another World')
|
10
|
+
end
|
11
|
+
|
12
|
+
context "resetting session" do
|
13
|
+
it "sets a cookie in one example..." do
|
14
|
+
visit('/set_cookie')
|
15
|
+
page.body.should include('Cookie set to test_cookie')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "...then it is not availbable in the next" do
|
19
|
+
visit('/get_cookie')
|
20
|
+
page.body.should_not include('test_cookie')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "setting the current driver" do
|
25
|
+
it "sets the current driver in one example..." do
|
26
|
+
Capybara.current_driver = :selenium
|
27
|
+
end
|
28
|
+
|
29
|
+
it "...then it has returned to the default in the next example" do
|
30
|
+
Capybara.current_driver.should == :rack_test
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "switches to the javascript driver when giving it as metadata", :js => true do
|
35
|
+
Capybara.current_driver.should == Capybara.javascript_driver
|
36
|
+
end
|
37
|
+
|
38
|
+
it "switches to the given driver when giving it as metadata", :driver => :culerity do
|
39
|
+
Capybara.current_driver.should == :culerity
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'capybara/rspec', :type => :other do
|
44
|
+
it "should not include Capybara" do
|
45
|
+
expect { visit('/') }.to raise_error(NoMethodError)
|
46
|
+
end
|
47
|
+
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
require 'capybara/util/save_and_open_page'
|
4
4
|
require 'launchy'
|
5
5
|
describe Capybara do
|
6
|
-
describe ".
|
6
|
+
describe ".save_and_open_page" do
|
7
7
|
before do
|
8
8
|
@time = Time.new.strftime("%Y%m%d%H%M%S")
|
9
9
|
|
@@ -14,9 +14,25 @@ describe Capybara do
|
|
14
14
|
@html = <<-HTML
|
15
15
|
<html>
|
16
16
|
<head>
|
17
|
+
<script type="text/javascript" src="/javascripts/prototype.js?123"/>
|
17
18
|
</head>
|
18
19
|
<body>
|
19
20
|
<h1>test</h1>
|
21
|
+
<p>
|
22
|
+
Some images (note differing whitespace closing tag):
|
23
|
+
<img src="/images/image1.jpeg" />
|
24
|
+
<img src="/images/image2.jpeg"/>
|
25
|
+
</p>
|
26
|
+
<p>
|
27
|
+
Some more in a non-existent directory:
|
28
|
+
<img src="/img/image3.jpeg" />
|
29
|
+
<img src="/img/image4.jpeg"/>
|
30
|
+
</p>
|
31
|
+
<p>
|
32
|
+
<a href="/not-here/foo.html">
|
33
|
+
A link to a file in a non-existent directory.
|
34
|
+
</a>
|
35
|
+
</p>
|
20
36
|
</body>
|
21
37
|
<html>
|
22
38
|
HTML
|
@@ -24,14 +40,18 @@ describe Capybara do
|
|
24
40
|
Launchy::Browser.stub(:run)
|
25
41
|
end
|
26
42
|
|
27
|
-
|
28
|
-
|
29
|
-
@name = "capybara-#{@time}.html"
|
43
|
+
def default_file_expectations
|
44
|
+
@name = "capybara-#{@time}.html"
|
30
45
|
|
31
|
-
|
46
|
+
@temp_file.stub!(:path).and_return(@name)
|
32
47
|
|
33
|
-
|
34
|
-
|
48
|
+
File.should_receive(:exist?).and_return true
|
49
|
+
File.should_receive(:new).and_return @temp_file
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "defaults" do
|
53
|
+
before do
|
54
|
+
default_file_expectations
|
35
55
|
end
|
36
56
|
|
37
57
|
it "should create a new temporary file" do
|
@@ -79,5 +99,61 @@ describe Capybara do
|
|
79
99
|
Capybara.save_and_open_page_path = default_setting
|
80
100
|
end
|
81
101
|
end
|
102
|
+
|
103
|
+
describe "rewrite_css_and_image_references" do
|
104
|
+
before do
|
105
|
+
default_file_expectations
|
106
|
+
@asset_root_dir = "/path/to/rails/public"
|
107
|
+
end
|
108
|
+
|
109
|
+
def mock_asset_root_with(directories)
|
110
|
+
@asset_root = Pathname.new(@asset_root_dir)
|
111
|
+
Capybara.should_receive(:asset_root).and_return @asset_root
|
112
|
+
|
113
|
+
dir = mock('asset_root mock dir')
|
114
|
+
Dir.should_receive(:new).with(@asset_root).and_return dir
|
115
|
+
|
116
|
+
dirents = [ '.', '..', 'file.html' ] + directories
|
117
|
+
dir.should_receive(:entries).and_return dirents
|
118
|
+
|
119
|
+
directories_regexp = directories.join('|')
|
120
|
+
FileTest.should_receive(:directory?) \
|
121
|
+
.at_least(dirents.size - 2).times \
|
122
|
+
.and_return { |dir|
|
123
|
+
dir =~ %r!#{@asset_root_dir}/(#{directories_regexp})$!
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
def expected_html_for_asset_root_with(directories)
|
128
|
+
mock_asset_root_with(directories)
|
129
|
+
|
130
|
+
expected_html = @html.clone
|
131
|
+
if not directories.empty?
|
132
|
+
directories_regexp = directories.join('|')
|
133
|
+
expected_html.gsub!(/"(\/(#{directories_regexp})\/)/,
|
134
|
+
'"%s\1' % @asset_root_dir)
|
135
|
+
end
|
136
|
+
|
137
|
+
return expected_html
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_with_directories(directories)
|
141
|
+
@temp_file.should_receive(:write) \
|
142
|
+
.with expected_html_for_asset_root_with(directories)
|
143
|
+
Capybara.save_and_open_page @html
|
144
|
+
end
|
145
|
+
|
146
|
+
context "asset_root contains some directories" do
|
147
|
+
it "should rewrite relative paths to absolute local paths" do
|
148
|
+
test_with_directories([ 'javascripts', 'images' ])
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context "asset_root path contains no directories" do
|
153
|
+
it "should not rewrite any relative paths" do
|
154
|
+
test_with_directories([ ])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
82
158
|
end
|
83
159
|
end
|
data/spec/server_spec.rb
CHANGED
@@ -62,4 +62,24 @@ describe Capybara::Server do
|
|
62
62
|
@server2a.port.should == @server2b.port
|
63
63
|
end
|
64
64
|
|
65
|
+
it "should wait specified time for the app to boot" do
|
66
|
+
@slow_app = proc { |env| sleep(1); [200, {}, "Hello Slow Server!"] }
|
67
|
+
|
68
|
+
Capybara.server_boot_timeout = 1.5
|
69
|
+
@server = Capybara::Server.new(@slow_app).boot
|
70
|
+
|
71
|
+
@res = Net::HTTP.start(@server.host, @server.port) { |http| http.get('/') }
|
72
|
+
@res.body.should include('Hello Slow Server')
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should raise an exception if boot timeout is exceeded" do
|
76
|
+
@slow_app = proc { |env| sleep(1); [200, {}, "Hello Slow Server!"] }
|
77
|
+
|
78
|
+
Capybara.server_boot_timeout = 0.5
|
79
|
+
server = Capybara::Server.new(@slow_app)
|
80
|
+
server.stub(:exit).and_return(:timeout)
|
81
|
+
server.stub(:puts)
|
82
|
+
server.boot.should == :timeout
|
83
|
+
end
|
84
|
+
|
65
85
|
end
|
@@ -26,6 +26,16 @@ describe Capybara::Session do
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
describe "#attach_file" do
|
30
|
+
context "with multipart form" do
|
31
|
+
it "should submit an empty form-data section if no file is submitted" do
|
32
|
+
@session.visit("/form")
|
33
|
+
@session.click_button("Upload Empty")
|
34
|
+
@session.body.should include('Successfully ignored empty file field.')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
29
39
|
it_should_behave_like "session"
|
30
40
|
it_should_behave_like "session without javascript support"
|
31
41
|
it_should_behave_like "session with headers support"
|
data/spec/string_spec.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Capybara do
|
4
|
+
describe '.string' do
|
5
|
+
let :string do
|
6
|
+
Capybara.string <<-STRING
|
7
|
+
<div id="page">
|
8
|
+
<div id="content">
|
9
|
+
<h1 data="fantastic">Awesome</h1>
|
10
|
+
<p>Yes it is</p>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div id="footer" style="display: none">
|
14
|
+
<p>c2010</p>
|
15
|
+
<p>Jonas Nicklas</p>
|
16
|
+
<input type="text" name="foo" value="bar"/>
|
17
|
+
<select name="animal">
|
18
|
+
<option>Monkey</option>
|
19
|
+
<option selected="selected">Capybara</option>
|
20
|
+
</select>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
STRING
|
24
|
+
end
|
25
|
+
|
26
|
+
it "allows using matchers" do
|
27
|
+
string.should have_css('#page')
|
28
|
+
string.should_not have_css('#does-not-exist')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "allows using custom matchers" do
|
32
|
+
Capybara.add_selector :lifeform do
|
33
|
+
xpath { |name| "//option[contains(.,'#{name}')]" }
|
34
|
+
end
|
35
|
+
string.should have_selector(:page)
|
36
|
+
string.should_not have_selector(:'does-not-exist')
|
37
|
+
string.should have_selector(:lifeform, "Monkey")
|
38
|
+
string.should_not have_selector(:lifeform, "Gorilla")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "allows using matchers with text option" do
|
42
|
+
string.should have_css('h1', :text => 'Awesome')
|
43
|
+
string.should_not have_css('h1', :text => 'Not so awesome')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "allows finding only visible nodes" do
|
47
|
+
string.all('//p', :text => 'c2010', :visible => true).should be_empty
|
48
|
+
string.all('//p', :text => 'c2010', :visible => false).should have(1).element
|
49
|
+
end
|
50
|
+
|
51
|
+
it "allows finding elements and extracting text from them" do
|
52
|
+
string.find('//h1').text.should == 'Awesome'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "allows finding elements and extracting attributes from them" do
|
56
|
+
string.find('//h1')[:data].should == 'fantastic'
|
57
|
+
end
|
58
|
+
|
59
|
+
it "allows finding elements and extracting the tag name from them" do
|
60
|
+
string.find('//h1').tag_name.should == 'h1'
|
61
|
+
end
|
62
|
+
|
63
|
+
it "allows finding elements and extracting the path" do
|
64
|
+
string.find('//h1').path.should == '/html/body/div/div[1]/h1'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "allows finding elements and extracting the path" do
|
68
|
+
string.find('//input').value.should == 'bar'
|
69
|
+
string.find('//select').value.should == 'Capybara'
|
70
|
+
end
|
71
|
+
|
72
|
+
it "allows finding elements and checking if they are visible" do
|
73
|
+
string.find('//h1').should be_visible
|
74
|
+
string.find('//input').should_not be_visible
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|