capybara 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Manifest.txt +4 -0
- data/README.rdoc +31 -9
- data/Rakefile +1 -2
- data/lib/capybara.rb +1 -1
- data/lib/capybara/cucumber.rb +1 -5
- data/lib/capybara/driver/rack_test_driver.rb +1 -1
- data/lib/capybara/dsl.rb +6 -2
- data/lib/capybara/rails.rb +4 -0
- data/lib/capybara/save_and_open_page.rb +6 -2
- data/lib/capybara/session.rb +185 -163
- data/spec/save_and_open_page_spec.rb +43 -0
- data/spec/session_spec.rb +60 -1
- data/spec/test_app.rb +5 -1
- data/spec/views/buttons.erb +4 -0
- data/spec/views/fieldsets.erb +29 -0
- data/spec/views/form.erb +1 -0
- data/spec/views/tables.erb +62 -0
- metadata +6 -12
data/Manifest.txt
CHANGED
@@ -27,13 +27,17 @@ spec/drivers_spec.rb
|
|
27
27
|
spec/dsl_spec.rb
|
28
28
|
spec/fixtures/test_file.txt
|
29
29
|
spec/public/jquery.js
|
30
|
+
spec/save_and_open_page_spec.rb
|
30
31
|
spec/session/culerity_session_spec.rb
|
31
32
|
spec/session/rack_test_session_spec.rb
|
32
33
|
spec/session/selenium_session_spec.rb
|
33
34
|
spec/session_spec.rb
|
34
35
|
spec/spec_helper.rb
|
35
36
|
spec/test_app.rb
|
37
|
+
spec/views/buttons.erb
|
38
|
+
spec/views/fieldsets.erb
|
36
39
|
spec/views/form.erb
|
40
|
+
spec/views/tables.erb
|
37
41
|
spec/views/with_html.erb
|
38
42
|
spec/views/with_js.erb
|
39
43
|
spec/views/with_scope.erb
|
data/README.rdoc
CHANGED
@@ -10,10 +10,18 @@ a DSL for interacting with a webapplication. It is agnostic about the driver
|
|
10
10
|
running your tests and currently comes bundled with rack-test, Culerity and
|
11
11
|
Selenium support built in.
|
12
12
|
|
13
|
-
==
|
13
|
+
== Install:
|
14
|
+
|
15
|
+
Capybara is hosted on Gemcutter, install it with:
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
+
sudo gem install capybara
|
18
|
+
|
19
|
+
== Development:
|
20
|
+
|
21
|
+
* Source hosted at {GitHub}[http://github.com/jnicklas/capybara].
|
22
|
+
* Please direct questions, discussions at the {mailing list}[http://groups.google.com/group/ruby-capybara].
|
23
|
+
* Report issues on {GitHub Issues}[http://github.com/jnicklas/capybara/issues]
|
24
|
+
* Pull requests are very welcome!
|
17
25
|
|
18
26
|
== Using Capybara with Cucumber
|
19
27
|
|
@@ -145,18 +153,24 @@ For ultimate control, you can instantiate and use a session manually.
|
|
145
153
|
end
|
146
154
|
session.click_link 'Sign in'
|
147
155
|
|
148
|
-
==
|
156
|
+
== XPath and CSS
|
149
157
|
|
150
|
-
Capybara
|
158
|
+
Capybara does not try to guess what kind of selector you are going to give it,
|
159
|
+
if you want to use CSS with your 'within' declarations for example, you'll need
|
160
|
+
to do:
|
161
|
+
|
162
|
+
within(:css, 'ul li') { ... }
|
151
163
|
|
152
|
-
|
164
|
+
Alternatively you can set the default selector to CSS, which may help if you are
|
165
|
+
moving from Webrat and used CSS a lot, or simply generally prefer CSS:
|
166
|
+
|
167
|
+
Capybara.default_selector = :css
|
168
|
+
within('ul li') { ... }
|
153
169
|
|
154
170
|
== Gotchas:
|
155
171
|
|
156
172
|
* Install JRuby and the 'celerity' gem, version 0.7.4 (0.7.5 has a bug with
|
157
|
-
password fields) under JRuby for Culerity support.
|
158
|
-
teh edge version of Culerity until a new gem release becomes available, since
|
159
|
-
0.2.3 does not work (at all!) with Capybara.
|
173
|
+
password fields) under JRuby for Culerity support.
|
160
174
|
|
161
175
|
* Everything is *case sensitive*. Capybara heavily relies on XPath, which
|
162
176
|
doesn't support case insensitive searches.
|
@@ -186,6 +200,14 @@ Capybara is hosted on Gemcutter, install it with:
|
|
186
200
|
<tt><a href="/same/url#"></tt> instead. You can achieve this in Rails with
|
187
201
|
<tt>link_to('foo', :anchor => '')</tt>
|
188
202
|
|
203
|
+
== Contributors:
|
204
|
+
|
205
|
+
The following people have dedicated their time and effort to Capybara:
|
206
|
+
|
207
|
+
* Jonas Nicklas
|
208
|
+
* Dennis Rogenius
|
209
|
+
* Rob Holland
|
210
|
+
|
189
211
|
== License:
|
190
212
|
|
191
213
|
(The MIT License)
|
data/Rakefile
CHANGED
data/lib/capybara.rb
CHANGED
data/lib/capybara/cucumber.rb
CHANGED
@@ -7,10 +7,6 @@ After do
|
|
7
7
|
Capybara.reset_sessions!
|
8
8
|
end
|
9
9
|
|
10
|
-
require 'database_cleaner'
|
11
|
-
require 'database_cleaner/cucumber'
|
12
|
-
DatabaseCleaner.strategy = :truncation
|
13
|
-
|
14
10
|
Before('@javascript') do
|
15
11
|
Capybara.current_driver = Capybara.javascript_driver
|
16
12
|
end
|
@@ -29,4 +25,4 @@ end
|
|
29
25
|
|
30
26
|
After do
|
31
27
|
Capybara.use_default_driver
|
32
|
-
end
|
28
|
+
end
|
@@ -37,7 +37,7 @@ class Capybara::Driver::RackTest
|
|
37
37
|
def click
|
38
38
|
if tag_name == 'a'
|
39
39
|
driver.visit(self[:href])
|
40
|
-
elsif tag_name == 'input' and %w(submit image).include?(type)
|
40
|
+
elsif (tag_name == 'input' or tag_name == 'button') and %w(submit image).include?(type)
|
41
41
|
Form.new(driver, form).submit(self)
|
42
42
|
end
|
43
43
|
end
|
data/lib/capybara/dsl.rb
CHANGED
@@ -9,7 +9,7 @@ module Capybara
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def current_driver
|
12
|
-
@current_driver || default_driver
|
12
|
+
@current_driver || default_driver
|
13
13
|
end
|
14
14
|
alias_method :mode, :current_driver
|
15
15
|
|
@@ -18,13 +18,17 @@ module Capybara
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def use_default_driver
|
21
|
-
@current_driver = nil
|
21
|
+
@current_driver = nil
|
22
22
|
end
|
23
23
|
|
24
24
|
def current_session
|
25
25
|
session_pool["#{current_driver}#{app.object_id}"] ||= Capybara::Session.new(current_driver, app)
|
26
26
|
end
|
27
27
|
|
28
|
+
def current_session?
|
29
|
+
session_pool.has_key?("#{current_driver}#{app.object_id}")
|
30
|
+
end
|
31
|
+
|
28
32
|
def reset_sessions!
|
29
33
|
@session_pool = nil
|
30
34
|
end
|
data/lib/capybara/rails.rb
CHANGED
@@ -3,10 +3,14 @@ module Capybara
|
|
3
3
|
extend(self)
|
4
4
|
|
5
5
|
def save_and_open_page(html)
|
6
|
-
|
7
|
-
|
6
|
+
name="capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}.html"
|
7
|
+
|
8
|
+
FileUtils.touch(name) unless File.exist?(name)
|
9
|
+
|
10
|
+
tempfile = File.new(name,'w')
|
8
11
|
tempfile.write(rewrite_css_and_image_references(html))
|
9
12
|
tempfile.close
|
13
|
+
|
10
14
|
open_in_browser(tempfile.path)
|
11
15
|
end
|
12
16
|
|
data/lib/capybara/session.rb
CHANGED
@@ -1,190 +1,212 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
:
|
5
|
-
:text_area => proc { |id| "//textarea[@id='#{id}']" },
|
6
|
-
:password_field => proc { |id| "//input[@type='password'][@id='#{id}']" },
|
7
|
-
:radio => proc { |id| "//input[@type='radio'][@id='#{id}']" },
|
8
|
-
:hidden_field => proc { |id| "//input[@type='hidden'][@id='#{id}']" },
|
9
|
-
:checkbox => proc { |id| "//input[@type='checkbox'][@id='#{id}']" },
|
10
|
-
:select => proc { |id| "//select[@id='#{id}']" },
|
11
|
-
:file_field => proc { |id| "//input[@type='file'][@id='#{id}']" }
|
12
|
-
}
|
13
|
-
|
14
|
-
attr_reader :mode, :app
|
15
|
-
|
16
|
-
def initialize(mode, app)
|
17
|
-
@mode = mode
|
18
|
-
@app = app
|
19
|
-
end
|
1
|
+
module Capybara
|
2
|
+
|
3
|
+
class << self
|
4
|
+
attr_writer :default_selector
|
20
5
|
|
21
|
-
|
22
|
-
|
23
|
-
when :rack_test
|
24
|
-
Capybara::Driver::RackTest.new(app)
|
25
|
-
when :culerity
|
26
|
-
Capybara::Driver::Culerity.new(app)
|
27
|
-
when :selenium
|
28
|
-
Capybara::Driver::Selenium.new(app)
|
29
|
-
else
|
30
|
-
raise Capybara::DriverNotFoundError, "no driver called #{mode} was found"
|
6
|
+
def default_selector
|
7
|
+
@default_selector ||= :xpath
|
31
8
|
end
|
32
9
|
end
|
33
10
|
|
34
|
-
|
35
|
-
driver.visit(path)
|
36
|
-
end
|
37
|
-
|
38
|
-
def click_link(locator)
|
39
|
-
find_link(locator).click
|
40
|
-
end
|
11
|
+
class Session
|
41
12
|
|
42
|
-
|
43
|
-
|
44
|
-
|
13
|
+
FIELDS_PATHS = {
|
14
|
+
:text_field => proc { |id| "//input[@type='text'][@id='#{id}']" },
|
15
|
+
:text_area => proc { |id| "//textarea[@id='#{id}']" },
|
16
|
+
:password_field => proc { |id| "//input[@type='password'][@id='#{id}']" },
|
17
|
+
:radio => proc { |id| "//input[@type='radio'][@id='#{id}']" },
|
18
|
+
:hidden_field => proc { |id| "//input[@type='hidden'][@id='#{id}']" },
|
19
|
+
:checkbox => proc { |id| "//input[@type='checkbox'][@id='#{id}']" },
|
20
|
+
:select => proc { |id| "//select[@id='#{id}']" },
|
21
|
+
:file_field => proc { |id| "//input[@type='file'][@id='#{id}']" }
|
22
|
+
}
|
45
23
|
|
46
|
-
|
47
|
-
find_field(locator, :text_field, :text_area, :password_field).set(options[:with])
|
48
|
-
end
|
49
|
-
|
50
|
-
def choose(locator)
|
51
|
-
find_field(locator, :radio).set(true)
|
52
|
-
end
|
53
|
-
|
54
|
-
def check(locator)
|
55
|
-
find_field(locator, :checkbox).set(true)
|
56
|
-
end
|
57
|
-
|
58
|
-
def uncheck(locator)
|
59
|
-
find_field(locator, :checkbox).set(false)
|
60
|
-
end
|
61
|
-
|
62
|
-
def select(value, options={})
|
63
|
-
find_field(options[:from], :select).select(value)
|
64
|
-
end
|
65
|
-
|
66
|
-
def attach_file(locator, path)
|
67
|
-
find_field(locator, :file_field).set(path)
|
68
|
-
end
|
24
|
+
attr_reader :mode, :app
|
69
25
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
def has_content?(content)
|
75
|
-
has_xpath?("//*[contains(.,'#{content}')]")
|
76
|
-
end
|
77
|
-
|
78
|
-
def has_xpath?(path, options={})
|
79
|
-
results = find(path)
|
80
|
-
if options[:text]
|
81
|
-
results = filter_by_text(results, options[:text])
|
26
|
+
def initialize(mode, app)
|
27
|
+
@mode = mode
|
28
|
+
@app = app
|
82
29
|
end
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
30
|
+
|
31
|
+
def driver
|
32
|
+
@driver ||= case mode
|
33
|
+
when :rack_test
|
34
|
+
Capybara::Driver::RackTest.new(app)
|
35
|
+
when :culerity
|
36
|
+
Capybara::Driver::Culerity.new(app)
|
37
|
+
when :selenium
|
38
|
+
Capybara::Driver::Selenium.new(app)
|
39
|
+
else
|
40
|
+
raise Capybara::DriverNotFoundError, "no driver called #{mode} was found"
|
41
|
+
end
|
87
42
|
end
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
has_xpath?(css_to_xpath(path), options)
|
92
|
-
end
|
93
|
-
|
94
|
-
def within(kind, scope=nil)
|
95
|
-
kind, scope = :xpath, kind unless scope
|
96
|
-
scope = css_to_xpath(scope) if kind == :css
|
97
|
-
raise Capybara::ElementNotFound, "scope '#{scope}' not found on page" if find(scope).empty?
|
98
|
-
scopes.push(scope)
|
99
|
-
yield
|
100
|
-
scopes.pop
|
101
|
-
end
|
102
|
-
|
103
|
-
def within_fieldset(locator)
|
104
|
-
within "//fieldset[@id='#{locator}' or contains(legend,'#{locator}')]" do
|
105
|
-
yield
|
43
|
+
|
44
|
+
def visit(path)
|
45
|
+
driver.visit(path)
|
106
46
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
within "//table[@id='#{locator}' or contains(caption,'#{locator}')]" do
|
111
|
-
yield
|
47
|
+
|
48
|
+
def click_link(locator)
|
49
|
+
find_link(locator).click
|
112
50
|
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def save_and_open_page
|
116
|
-
require 'capybara/save_and_open_page'
|
117
|
-
Capybara::SaveAndOpenPage.save_and_open_page(body)
|
118
|
-
end
|
119
51
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
raise Capybara::ElementNotFound, "no field of kind #{kinds.inspect} with id or label '#{locator}' found" unless field
|
124
|
-
field
|
125
|
-
end
|
126
|
-
alias_method :field_labeled, :find_field
|
127
|
-
|
128
|
-
def find_link(locator)
|
129
|
-
link = find("//a[@id='#{locator}' or contains(.,'#{locator}') or @title='#{locator}']").first
|
130
|
-
raise Capybara::ElementNotFound, "no link with title, id or text '#{locator}' found" unless link
|
131
|
-
link
|
132
|
-
end
|
133
|
-
|
134
|
-
def find_button(locator)
|
135
|
-
button = find("//input[@type='submit' or @type='image'][@id='#{locator}' or @value='#{locator}']").first
|
136
|
-
raise Capybara::ElementNotFound, "no button with value or id '#{locator}' found" unless button
|
137
|
-
button
|
138
|
-
end
|
52
|
+
def click_button(locator)
|
53
|
+
find_button(locator).click
|
54
|
+
end
|
139
55
|
|
140
|
-
|
56
|
+
def fill_in(locator, options={})
|
57
|
+
find_field(locator, :text_field, :text_area, :password_field).set(options[:with])
|
58
|
+
end
|
141
59
|
|
142
|
-
|
143
|
-
|
144
|
-
|
60
|
+
def choose(locator)
|
61
|
+
find_field(locator, :radio).set(true)
|
62
|
+
end
|
63
|
+
|
64
|
+
def check(locator)
|
65
|
+
find_field(locator, :checkbox).set(true)
|
66
|
+
end
|
67
|
+
|
68
|
+
def uncheck(locator)
|
69
|
+
find_field(locator, :checkbox).set(false)
|
70
|
+
end
|
71
|
+
|
72
|
+
def select(value, options={})
|
73
|
+
find_field(options[:from], :select).select(value)
|
74
|
+
end
|
75
|
+
|
76
|
+
def attach_file(locator, path)
|
77
|
+
find_field(locator, :file_field).set(path)
|
78
|
+
end
|
79
|
+
|
80
|
+
def body
|
81
|
+
driver.body
|
82
|
+
end
|
145
83
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
84
|
+
def has_content?(content)
|
85
|
+
has_xpath?("//*[contains(.,#{sanitized_xpath_string(content)})]")
|
86
|
+
end
|
87
|
+
|
88
|
+
def has_xpath?(path, options={})
|
89
|
+
results = find(path)
|
90
|
+
if options[:text]
|
91
|
+
results = filter_by_text(results, options[:text])
|
92
|
+
end
|
93
|
+
if options[:count]
|
94
|
+
results.size == options[:count]
|
95
|
+
else
|
96
|
+
results.size > 0
|
153
97
|
end
|
154
98
|
end
|
155
|
-
end
|
156
99
|
|
157
|
-
|
158
|
-
|
159
|
-
|
100
|
+
def has_css?(path, options={})
|
101
|
+
has_xpath?(css_to_xpath(path), options)
|
102
|
+
end
|
160
103
|
|
161
|
-
|
162
|
-
|
163
|
-
|
104
|
+
def within(kind, scope=nil)
|
105
|
+
kind, scope = Capybara.default_selector, kind unless scope
|
106
|
+
scope = css_to_xpath(scope) if kind == :css
|
107
|
+
raise Capybara::ElementNotFound, "scope '#{scope}' not found on page" if find(scope).empty?
|
108
|
+
scopes.push(scope)
|
109
|
+
yield
|
110
|
+
scopes.pop
|
111
|
+
end
|
164
112
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
return element if element
|
113
|
+
def within_fieldset(locator)
|
114
|
+
within "//fieldset[@id='#{locator}' or contains(legend,'#{locator}')]" do
|
115
|
+
yield
|
116
|
+
end
|
170
117
|
end
|
171
|
-
return nil
|
172
|
-
end
|
173
118
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
119
|
+
def within_table(locator)
|
120
|
+
within "//table[@id='#{locator}' or contains(caption,'#{locator}')]" do
|
121
|
+
yield
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def save_and_open_page
|
126
|
+
require 'capybara/save_and_open_page'
|
127
|
+
Capybara::SaveAndOpenPage.save_and_open_page(body)
|
128
|
+
end
|
129
|
+
|
130
|
+
def find_field(locator, *kinds)
|
131
|
+
kinds = FIELDS_PATHS.keys if kinds.empty?
|
132
|
+
field = find_field_by_id(locator, *kinds) || find_field_by_label(locator, *kinds)
|
133
|
+
raise Capybara::ElementNotFound, "no field of kind #{kinds.inspect} with id or label '#{locator}' found" unless field
|
134
|
+
field
|
135
|
+
end
|
136
|
+
alias_method :field_labeled, :find_field
|
137
|
+
|
138
|
+
def find_link(locator)
|
139
|
+
link = find("//a[@id='#{locator}' or contains(.,'#{locator}') or @title='#{locator}']").first
|
140
|
+
raise Capybara::ElementNotFound, "no link with title, id or text '#{locator}' found" unless link
|
141
|
+
link
|
142
|
+
end
|
143
|
+
|
144
|
+
def find_button(locator)
|
145
|
+
button = find("//input[@type='submit' or @type='image'][@id='#{locator}' or @value='#{locator}']").first \
|
146
|
+
|| find("//button[@id='#{locator}' or @value='#{locator}' or contains(.,'#{locator}')]").first
|
147
|
+
raise Capybara::ElementNotFound, "no button with value or id or text '#{locator}' found" unless button
|
148
|
+
button
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
|
153
|
+
def css_to_xpath(css)
|
154
|
+
Nokogiri::CSS.xpath_for(css).first
|
155
|
+
end
|
156
|
+
|
157
|
+
def filter_by_text(nodes, text)
|
158
|
+
nodes.select do |node|
|
159
|
+
case text
|
160
|
+
when String
|
161
|
+
node.text.include?(text)
|
162
|
+
when Regexp
|
163
|
+
node.text =~ text
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def current_scope
|
169
|
+
scopes.join('')
|
170
|
+
end
|
171
|
+
|
172
|
+
def scopes
|
173
|
+
@scopes ||= []
|
174
|
+
end
|
175
|
+
|
176
|
+
def find_field_by_id(locator, *kinds)
|
177
|
+
kinds.each do |kind|
|
178
|
+
path = FIELDS_PATHS[kind]
|
179
|
+
element = find(path.call(locator)).first
|
179
180
|
return element if element
|
180
181
|
end
|
182
|
+
return nil
|
183
|
+
end
|
184
|
+
|
185
|
+
def find_field_by_label(locator, *kinds)
|
186
|
+
kinds.each do |kind|
|
187
|
+
label = find("//label[contains(.,'#{locator}')]").first
|
188
|
+
if label
|
189
|
+
element = find_field_by_id(label[:for], kind)
|
190
|
+
return element if element
|
191
|
+
end
|
192
|
+
end
|
193
|
+
return nil
|
194
|
+
end
|
195
|
+
|
196
|
+
def find(locator)
|
197
|
+
locator = current_scope.to_s + locator
|
198
|
+
driver.find(locator)
|
199
|
+
end
|
200
|
+
|
201
|
+
def sanitized_xpath_string(string)
|
202
|
+
if string =~ /'/
|
203
|
+
string = string.split("'", -1).map do |substr|
|
204
|
+
"'#{substr}'"
|
205
|
+
end.join(%q{,"'",})
|
206
|
+
"concat(#{string})"
|
207
|
+
else
|
208
|
+
"'#{string}'"
|
209
|
+
end
|
181
210
|
end
|
182
|
-
return nil
|
183
|
-
end
|
184
|
-
|
185
|
-
def find(locator)
|
186
|
-
locator = current_scope.to_s + locator
|
187
|
-
driver.find(locator)
|
188
211
|
end
|
189
|
-
|
190
212
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require File.expand_path('spec_helper', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'capybara/save_and_open_page'
|
4
|
+
require 'launchy'
|
5
|
+
describe Capybara::SaveAndOpenPage do
|
6
|
+
describe "#save_save_and_open_page" do
|
7
|
+
before do
|
8
|
+
|
9
|
+
@time = Time.new.strftime("%Y%m%d%H%M%S")
|
10
|
+
@name = "capybara-#{@time}.html"
|
11
|
+
|
12
|
+
@temp_file = mock("FILE")
|
13
|
+
@temp_file.stub!(:write)
|
14
|
+
@temp_file.stub!(:close)
|
15
|
+
@temp_file.stub!(:path).and_return(@name)
|
16
|
+
|
17
|
+
File.should_receive(:exist?).and_return true
|
18
|
+
File.should_receive(:new).and_return @temp_file
|
19
|
+
|
20
|
+
@html = <<-HTML
|
21
|
+
<html>
|
22
|
+
<head>
|
23
|
+
</head>
|
24
|
+
<body>
|
25
|
+
<h1>test</h1>
|
26
|
+
</body>
|
27
|
+
<html>
|
28
|
+
HTML
|
29
|
+
|
30
|
+
Launchy::Browser.stub(:run)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should create a new temporary file" do
|
34
|
+
@temp_file.should_receive(:write).with @html
|
35
|
+
Capybara::SaveAndOpenPage.save_and_open_page @html
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should open the file in the browser" do
|
39
|
+
Capybara::SaveAndOpenPage.should_receive(:open_in_browser).with(@name)
|
40
|
+
Capybara::SaveAndOpenPage.save_and_open_page @html
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/spec/session_spec.rb
CHANGED
@@ -145,6 +145,27 @@ shared_examples_for "session" do
|
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
148
|
+
context "with text given on a button defined by <button> tag" do
|
149
|
+
it "should submit the associated form" do
|
150
|
+
@session.click_button('Click me')
|
151
|
+
extract_results(@session)['first_name'].should == 'John'
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "with id given on a button defined by <button> tag" do
|
156
|
+
it "should submit the associated form" do
|
157
|
+
@session.click_button('click_me_123')
|
158
|
+
extract_results(@session)['first_name'].should == 'John'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "with value given on a button defined by <button> tag" do
|
163
|
+
it "should submit the associated form" do
|
164
|
+
@session.click_button('click_me')
|
165
|
+
extract_results(@session)['first_name'].should == 'John'
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
148
169
|
context "with a locator that doesn't exist" do
|
149
170
|
it "should raise an error" do
|
150
171
|
running do
|
@@ -304,6 +325,21 @@ shared_examples_for "session" do
|
|
304
325
|
@session.should_not have_content('xxxxyzzz')
|
305
326
|
@session.should_not have_content('monkey')
|
306
327
|
end
|
328
|
+
|
329
|
+
it 'should handle single quotes in the content' do
|
330
|
+
@session.visit('/with-quotes')
|
331
|
+
@session.should have_content("can't")
|
332
|
+
end
|
333
|
+
|
334
|
+
it 'should handle double quotes in the content' do
|
335
|
+
@session.visit('/with-quotes')
|
336
|
+
@session.should have_content(%q{"No," he said})
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'should handle mixed single and double quotes in the content' do
|
340
|
+
@session.visit('/with-quotes')
|
341
|
+
@session.should have_content(%q{"you can't do that."})
|
342
|
+
end
|
307
343
|
end
|
308
344
|
|
309
345
|
describe '#has_xpath?' do
|
@@ -542,7 +578,30 @@ shared_examples_for "session" do
|
|
542
578
|
@session.body.should include('<h1>Bar</h1>')
|
543
579
|
end
|
544
580
|
end
|
545
|
-
|
581
|
+
|
582
|
+
context "with the default selector" do
|
583
|
+
it "should use XPath" do
|
584
|
+
@session.within("//li[contains(., 'With Simple HTML')]") do
|
585
|
+
@session.click_link('Go')
|
586
|
+
end
|
587
|
+
@session.body.should include('<h1>Bar</h1>')
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
context "with the default selector set to CSS" do
|
592
|
+
after do
|
593
|
+
Capybara.default_selector = :xpath
|
594
|
+
end
|
595
|
+
|
596
|
+
it "should use CSS" do
|
597
|
+
Capybara.default_selector = :css
|
598
|
+
@session.within("ul li[contains('With Simple HTML')]") do
|
599
|
+
@session.click_link('Go')
|
600
|
+
end
|
601
|
+
@session.body.should include('<h1>Bar</h1>')
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
546
605
|
context "with click_link" do
|
547
606
|
it "should click links in the given scope" do
|
548
607
|
@session.within("//li[contains(.,'With Simple HTML')]") do
|
data/spec/test_app.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
<form action="/form" method="post">
|
2
|
+
<fieldset id="agent_fieldset">
|
3
|
+
<legend>Agent</legend>
|
4
|
+
|
5
|
+
<p>
|
6
|
+
<label for="form_agent_name">Name</label>
|
7
|
+
<input type="text" name="form[agent_name]" value="James" id="form_agent_name"/>
|
8
|
+
</p>
|
9
|
+
|
10
|
+
<p>
|
11
|
+
<input type="submit" value="Create"/>
|
12
|
+
</p>
|
13
|
+
</fieldset>
|
14
|
+
</form>
|
15
|
+
|
16
|
+
<form action="/form" method="post">
|
17
|
+
<fieldset id="villain_fieldset">
|
18
|
+
<legend>Villain</legend>
|
19
|
+
|
20
|
+
<p>
|
21
|
+
<label for="form_villain_name">Name</label>
|
22
|
+
<input type="text" name="form[villain_name]" value="Ernst" id="form_villain_name"/>
|
23
|
+
</p>
|
24
|
+
|
25
|
+
<p>
|
26
|
+
<input type="submit" value="Create"/>
|
27
|
+
</p>
|
28
|
+
</fieldset>
|
29
|
+
</form>
|
data/spec/views/form.erb
CHANGED
@@ -85,6 +85,7 @@
|
|
85
85
|
<input type="submit" name="form[awesome]" id="awe123" value="awesome"/>
|
86
86
|
<input type="submit" name="form[crappy]" id="crap321" value="crappy"/>
|
87
87
|
<input type="image" name="form[okay]" id="okay556" value="okay"/>
|
88
|
+
<button type="submit" id="click_me_123" value="click_me">Click me!</button>
|
88
89
|
</p>
|
89
90
|
</form>
|
90
91
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
<form action="/form" method="post">
|
2
|
+
<table id="agent_table">
|
3
|
+
<caption>Agent</caption>
|
4
|
+
|
5
|
+
<tr>
|
6
|
+
<td>
|
7
|
+
<label for="form_agent_name">Name</label>
|
8
|
+
</td>
|
9
|
+
<td>
|
10
|
+
<input type="text" name="form[agent_name]" value="James" id="form_agent_name"/>
|
11
|
+
</td>
|
12
|
+
</tr>
|
13
|
+
|
14
|
+
<tr>
|
15
|
+
<td colspan="2">
|
16
|
+
<input type="submit" value="Create"/>
|
17
|
+
</td>
|
18
|
+
</tr>
|
19
|
+
</table>
|
20
|
+
</form>
|
21
|
+
|
22
|
+
<form action="/form" method="post">
|
23
|
+
<table id="girl_table">
|
24
|
+
<caption>Girl</caption>
|
25
|
+
|
26
|
+
<tr>
|
27
|
+
<td>
|
28
|
+
<label for="form_girl_name">Name</label>
|
29
|
+
</td>
|
30
|
+
<td>
|
31
|
+
<input type="text" name="form[girl_name]" value="Vesper" id="form_girl_name"/>
|
32
|
+
</td>
|
33
|
+
</tr>
|
34
|
+
|
35
|
+
<tr>
|
36
|
+
<td colspan="2">
|
37
|
+
<input type="submit" value="Create"/>
|
38
|
+
</td>
|
39
|
+
</tr>
|
40
|
+
</table>
|
41
|
+
</form>
|
42
|
+
|
43
|
+
<form action="/form" method="post">
|
44
|
+
<table id="villain_table">
|
45
|
+
<caption>Villain</caption>
|
46
|
+
|
47
|
+
<tr>
|
48
|
+
<td>
|
49
|
+
<label for="form_villain_name">Name</label>
|
50
|
+
</td>
|
51
|
+
<td>
|
52
|
+
<input type="text" name="form[villain_name]" value="Ernst" id="form_villain_name"/>
|
53
|
+
</td>
|
54
|
+
</tr>
|
55
|
+
|
56
|
+
<tr>
|
57
|
+
<td colspan="2">
|
58
|
+
<input type="submit" value="Create"/>
|
59
|
+
</td>
|
60
|
+
</tr>
|
61
|
+
</table>
|
62
|
+
</form>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonas Nicklas
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-30 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -62,16 +62,6 @@ dependencies:
|
|
62
62
|
- !ruby/object:Gem::Version
|
63
63
|
version: 0.5.2
|
64
64
|
version:
|
65
|
-
- !ruby/object:Gem::Dependency
|
66
|
-
name: database_cleaner
|
67
|
-
type: :runtime
|
68
|
-
version_requirement:
|
69
|
-
version_requirements: !ruby/object:Gem::Requirement
|
70
|
-
requirements:
|
71
|
-
- - ">="
|
72
|
-
- !ruby/object:Gem::Version
|
73
|
-
version: 0.2.3
|
74
|
-
version:
|
75
65
|
- !ruby/object:Gem::Dependency
|
76
66
|
name: sinatra
|
77
67
|
type: :development
|
@@ -148,13 +138,17 @@ files:
|
|
148
138
|
- spec/dsl_spec.rb
|
149
139
|
- spec/fixtures/test_file.txt
|
150
140
|
- spec/public/jquery.js
|
141
|
+
- spec/save_and_open_page_spec.rb
|
151
142
|
- spec/session/culerity_session_spec.rb
|
152
143
|
- spec/session/rack_test_session_spec.rb
|
153
144
|
- spec/session/selenium_session_spec.rb
|
154
145
|
- spec/session_spec.rb
|
155
146
|
- spec/spec_helper.rb
|
156
147
|
- spec/test_app.rb
|
148
|
+
- spec/views/buttons.erb
|
149
|
+
- spec/views/fieldsets.erb
|
157
150
|
- spec/views/form.erb
|
151
|
+
- spec/views/tables.erb
|
158
152
|
- spec/views/with_html.erb
|
159
153
|
- spec/views/with_js.erb
|
160
154
|
- spec/views/with_scope.erb
|