capybara 0.1.2 → 0.1.3
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/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
|