capybara 0.4.1.2 → 1.0.0.beta1
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 +46 -0
- data/README.rdoc +211 -64
- data/lib/capybara.rb +31 -15
- data/lib/capybara/cucumber.rb +12 -16
- data/lib/capybara/dsl.rb +65 -28
- data/lib/capybara/node/actions.rb +7 -5
- data/lib/capybara/node/document.rb +8 -0
- data/lib/capybara/node/finders.rb +11 -7
- data/lib/capybara/node/matchers.rb +32 -6
- data/lib/capybara/node/simple.rb +20 -0
- data/lib/capybara/rack_test/browser.rb +115 -0
- data/lib/capybara/rack_test/driver.rb +77 -0
- data/lib/capybara/rack_test/form.rb +80 -0
- data/lib/capybara/rack_test/node.rb +101 -0
- data/lib/capybara/rspec.rb +11 -3
- data/lib/capybara/rspec/features.rb +22 -0
- data/lib/capybara/rspec/matchers.rb +146 -0
- data/lib/capybara/selector.rb +27 -8
- data/lib/capybara/selenium/driver.rb +148 -0
- data/lib/capybara/selenium/node.rb +91 -0
- data/lib/capybara/session.rb +42 -15
- data/lib/capybara/spec/driver.rb +55 -1
- data/lib/capybara/spec/fixtures/capybara.jpg +0 -0
- data/lib/capybara/spec/public/test.js +7 -2
- data/lib/capybara/spec/session.rb +51 -7
- data/lib/capybara/spec/session/attach_file_spec.rb +9 -6
- data/lib/capybara/spec/session/click_button_spec.rb +35 -0
- data/lib/capybara/spec/session/current_host_spec.rb +62 -0
- data/lib/capybara/spec/session/fill_in_spec.rb +6 -0
- data/lib/capybara/spec/session/find_spec.rb +23 -1
- data/lib/capybara/spec/session/first_spec.rb +39 -6
- data/lib/capybara/spec/session/has_css_spec.rb +30 -0
- data/lib/capybara/spec/session/has_field_spec.rb +47 -11
- data/lib/capybara/spec/session/javascript.rb +0 -1
- data/lib/capybara/spec/session/text_spec.rb +19 -0
- data/lib/capybara/spec/test_app.rb +9 -0
- data/lib/capybara/spec/views/form.erb +8 -3
- data/lib/capybara/spec/views/header_links.erb +7 -0
- data/lib/capybara/spec/views/host_links.erb +12 -0
- data/lib/capybara/spec/views/with_html.erb +6 -2
- data/lib/capybara/spec/views/with_html_entities.erb +1 -0
- data/lib/capybara/spec/views/with_js.erb +4 -0
- data/lib/capybara/util/save_and_open_page.rb +7 -3
- data/lib/capybara/util/timeout.rb +2 -2
- data/lib/capybara/version.rb +1 -1
- data/spec/capybara_spec.rb +1 -1
- data/spec/driver/rack_test_driver_spec.rb +24 -2
- data/spec/driver/selenium_driver_spec.rb +2 -1
- data/spec/dsl_spec.rb +56 -4
- data/spec/rspec/features_spec.rb +45 -0
- data/spec/rspec/matchers_spec.rb +451 -0
- data/spec/rspec_spec.rb +9 -2
- data/spec/save_and_open_page_spec.rb +9 -13
- data/spec/server_spec.rb +4 -0
- data/spec/session/rack_test_session_spec.rb +2 -2
- data/spec/session/selenium_session_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -14
- data/spec/string_spec.rb +1 -1
- metadata +60 -69
- data/lib/capybara/driver/celerity_driver.rb +0 -164
- data/lib/capybara/driver/culerity_driver.rb +0 -26
- data/lib/capybara/driver/rack_test_driver.rb +0 -303
- data/lib/capybara/driver/selenium_driver.rb +0 -161
- data/spec/driver/celerity_driver_spec.rb +0 -13
- data/spec/driver/culerity_driver_spec.rb +0 -14
- data/spec/driver/remote_culerity_driver_spec.rb +0 -22
- data/spec/driver/remote_selenium_driver_spec.rb +0 -16
- data/spec/session/celerity_session_spec.rb +0 -24
- data/spec/session/culerity_session_spec.rb +0 -26
data/lib/capybara.rb
CHANGED
@@ -5,6 +5,7 @@ module Capybara
|
|
5
5
|
class CapybaraError < StandardError; end
|
6
6
|
class DriverNotFoundError < CapybaraError; end
|
7
7
|
class ElementNotFound < CapybaraError; end
|
8
|
+
class FileNotFound < CapybaraError; end
|
8
9
|
class UnselectNotAllowed < CapybaraError; end
|
9
10
|
class NotSupportedByDriverError < CapybaraError; end
|
10
11
|
class TimeoutError < CapybaraError; end
|
@@ -14,7 +15,7 @@ module Capybara
|
|
14
15
|
class << self
|
15
16
|
attr_accessor :asset_root, :app_host, :run_server, :default_host
|
16
17
|
attr_accessor :server_port, :server_boot_timeout
|
17
|
-
attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements
|
18
|
+
attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements, :prefer_visible_elements
|
18
19
|
attr_accessor :save_and_open_page_path
|
19
20
|
|
20
21
|
##
|
@@ -34,6 +35,7 @@ module Capybara
|
|
34
35
|
# [default_selector = :css/:xpath] Methods which take a selector use the given type by default (Default: CSS)
|
35
36
|
# [default_wait_time = Integer] The number of seconds to wait for asynchronous processes to finish (Default: 2)
|
36
37
|
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: false)
|
38
|
+
# [prefer_visible_elements = Boolean] Whether to prefer visible elements over hidden elements (Default: true)
|
37
39
|
#
|
38
40
|
# === DSL Options
|
39
41
|
#
|
@@ -198,10 +200,30 @@ module Capybara
|
|
198
200
|
module Driver
|
199
201
|
autoload :Base, 'capybara/driver/base'
|
200
202
|
autoload :Node, 'capybara/driver/node'
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
203
|
+
|
204
|
+
class Selenium
|
205
|
+
def initialize(*args)
|
206
|
+
raise "Capybara::Driver::Selenium has been renamed to Capybara::Selenium::Driver"
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
class RackTest
|
211
|
+
def initialize(*args)
|
212
|
+
raise "Capybara::Driver::RackTest has been renamed to Capybara::RackTest::Driver"
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
module RackTest
|
218
|
+
autoload :Driver, 'capybara/rack_test/driver'
|
219
|
+
autoload :Node, 'capybara/rack_test/node'
|
220
|
+
autoload :Form, 'capybara/rack_test/form'
|
221
|
+
autoload :Browser, 'capybara/rack_test/browser'
|
222
|
+
end
|
223
|
+
|
224
|
+
module Selenium
|
225
|
+
autoload :Node, 'capybara/selenium/node'
|
226
|
+
autoload :Driver, 'capybara/selenium/driver'
|
205
227
|
end
|
206
228
|
end
|
207
229
|
|
@@ -212,20 +234,14 @@ Capybara.configure do |config|
|
|
212
234
|
config.default_selector = :css
|
213
235
|
config.default_wait_time = 2
|
214
236
|
config.ignore_hidden_elements = false
|
237
|
+
config.prefer_visible_elements = true
|
238
|
+
config.default_host = "http://www.example.com"
|
215
239
|
end
|
216
240
|
|
217
241
|
Capybara.register_driver :rack_test do |app|
|
218
|
-
Capybara::Driver
|
219
|
-
end
|
220
|
-
|
221
|
-
Capybara.register_driver :celerity do |app|
|
222
|
-
Capybara::Driver::Celerity.new(app)
|
223
|
-
end
|
224
|
-
|
225
|
-
Capybara.register_driver :culerity do |app|
|
226
|
-
Capybara::Driver::Culerity.new(app)
|
242
|
+
Capybara::RackTest::Driver.new(app)
|
227
243
|
end
|
228
244
|
|
229
245
|
Capybara.register_driver :selenium do |app|
|
230
|
-
Capybara::Driver
|
246
|
+
Capybara::Selenium::Driver.new(app)
|
231
247
|
end
|
data/lib/capybara/cucumber.rb
CHANGED
@@ -1,30 +1,26 @@
|
|
1
1
|
require 'capybara'
|
2
|
+
|
2
3
|
require 'capybara/dsl'
|
4
|
+
require 'capybara/rspec/matchers'
|
3
5
|
|
4
|
-
World(Capybara)
|
6
|
+
World(Capybara::DSL)
|
7
|
+
World(Capybara::RSpecMatchers)
|
5
8
|
|
6
9
|
After do
|
7
10
|
Capybara.reset_sessions!
|
8
11
|
end
|
9
12
|
|
10
|
-
Before
|
13
|
+
Before '@javascript' do
|
11
14
|
Capybara.current_driver = Capybara.javascript_driver
|
12
15
|
end
|
13
16
|
|
14
|
-
Before
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
21
|
-
|
22
|
-
Before('@culerity') do
|
23
|
-
Capybara.current_driver = :culerity
|
24
|
-
end
|
25
|
-
|
26
|
-
Before('@rack_test') do
|
27
|
-
Capybara.current_driver = :rack_test
|
17
|
+
Before do |scenario|
|
18
|
+
scenario.source_tag_names.each do |tag|
|
19
|
+
driver_name = tag.sub(/^@/, '').to_sym
|
20
|
+
if Capybara.drivers.has_key?(driver_name)
|
21
|
+
Capybara.current_driver = driver_name
|
22
|
+
end
|
23
|
+
end
|
28
24
|
end
|
29
25
|
|
30
26
|
After do
|
data/lib/capybara/dsl.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require 'capybara'
|
2
2
|
|
3
3
|
module Capybara
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:include, Capybara::DSL)
|
6
|
+
warn "`include Capybara` is deprecated please use `include Capybara::DSL` instead."
|
7
|
+
end
|
8
|
+
|
4
9
|
class << self
|
5
|
-
attr_writer :default_driver, :current_driver, :javascript_driver
|
10
|
+
attr_writer :default_driver, :current_driver, :javascript_driver, :session_name
|
6
11
|
|
7
12
|
attr_accessor :app
|
8
13
|
|
@@ -57,7 +62,7 @@ module Capybara
|
|
57
62
|
# @return [Capybara::Session] The currently used session
|
58
63
|
#
|
59
64
|
def current_session
|
60
|
-
session_pool["#{current_driver}
|
65
|
+
session_pool["#{current_driver}:#{session_name}:#{app.object_id}"] ||= Capybara::Session.new(current_driver, app)
|
61
66
|
end
|
62
67
|
|
63
68
|
##
|
@@ -70,6 +75,27 @@ module Capybara
|
|
70
75
|
end
|
71
76
|
alias_method :reset!, :reset_sessions!
|
72
77
|
|
78
|
+
##
|
79
|
+
#
|
80
|
+
# The current session name.
|
81
|
+
#
|
82
|
+
# @return [Symbol] The name of the currently used session.
|
83
|
+
#
|
84
|
+
def session_name
|
85
|
+
@session_name ||= :default
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
#
|
90
|
+
# Yield a block using a specific session name.
|
91
|
+
#
|
92
|
+
def using_session(name)
|
93
|
+
self.session_name = name
|
94
|
+
yield
|
95
|
+
ensure
|
96
|
+
self.session_name = :default
|
97
|
+
end
|
98
|
+
|
73
99
|
private
|
74
100
|
|
75
101
|
def session_pool
|
@@ -77,33 +103,44 @@ module Capybara
|
|
77
103
|
end
|
78
104
|
end
|
79
105
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# def has_header?
|
91
|
-
# page.has_css?('h1')
|
92
|
-
# end
|
93
|
-
# end
|
94
|
-
#
|
95
|
-
# @return [Capybara::Session] The current session object
|
96
|
-
#
|
97
|
-
def page
|
98
|
-
Capybara.current_session
|
99
|
-
end
|
106
|
+
module DSL
|
107
|
+
|
108
|
+
##
|
109
|
+
#
|
110
|
+
# Shortcut to working in a different session. This is useful when Capybara is included
|
111
|
+
# in a class or module.
|
112
|
+
#
|
113
|
+
def using_session(name, &block)
|
114
|
+
Capybara.using_session(name, &block)
|
115
|
+
end
|
100
116
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
117
|
+
##
|
118
|
+
#
|
119
|
+
# Shortcut to accessing the current session. This is useful when Capybara is included in a
|
120
|
+
# class or module.
|
121
|
+
#
|
122
|
+
# class MyClass
|
123
|
+
# include Capybara::DSL
|
124
|
+
#
|
125
|
+
# def has_header?
|
126
|
+
# page.has_css?('h1')
|
127
|
+
# end
|
128
|
+
# end
|
129
|
+
#
|
130
|
+
# @return [Capybara::Session] The current session object
|
131
|
+
#
|
132
|
+
def page
|
133
|
+
Capybara.current_session
|
134
|
+
end
|
135
|
+
|
136
|
+
Session::DSL_METHODS.each do |method|
|
137
|
+
class_eval <<-RUBY, __FILE__, __LINE__+1
|
138
|
+
def #{method}(*args, &block)
|
139
|
+
page.#{method}(*args, &block)
|
140
|
+
end
|
141
|
+
RUBY
|
142
|
+
end
|
107
143
|
end
|
108
144
|
|
145
|
+
extend(Capybara::DSL)
|
109
146
|
end
|
@@ -104,7 +104,7 @@ module Capybara
|
|
104
104
|
#
|
105
105
|
# page.select 'March', :from => 'Month'
|
106
106
|
#
|
107
|
-
# @param [String]
|
107
|
+
# @param [String] value Which option to select
|
108
108
|
# @param [Hash{:from => String}] The id, name or label of the select box
|
109
109
|
#
|
110
110
|
def select(value, options={})
|
@@ -121,13 +121,14 @@ module Capybara
|
|
121
121
|
|
122
122
|
##
|
123
123
|
#
|
124
|
-
# Find a select box on the page and
|
125
|
-
# box is a multiple select, +
|
124
|
+
# Find a select box on the page and unselect a particular option from it. If the select
|
125
|
+
# box is a multiple select, +unselect+ can be called multiple times to unselect more than
|
126
126
|
# one option. The select box can be found via its name, id or label text.
|
127
127
|
#
|
128
|
-
# page.
|
128
|
+
# page.unselect 'March', :from => 'Month'
|
129
129
|
#
|
130
|
-
# @param [String]
|
130
|
+
# @param [String] value Which option to unselect
|
131
|
+
# @param [Hash{:from => String}] The id, name or label of the select box
|
131
132
|
#
|
132
133
|
def unselect(value, options={})
|
133
134
|
if options.has_key?(:from)
|
@@ -152,6 +153,7 @@ module Capybara
|
|
152
153
|
# @param [String] path The path of the file that will be attached
|
153
154
|
#
|
154
155
|
def attach_file(locator, path)
|
156
|
+
raise Capybara::FileNotFound, "cannot attach file, #{path} does not exist" unless File.exist?(path.to_s)
|
155
157
|
msg = "cannot attach file, no file field with id, name, or label '#{locator}' found"
|
156
158
|
find(:xpath, XPath::HTML.file_field(locator), :message => msg).set(path)
|
157
159
|
end
|
@@ -29,8 +29,11 @@ module Capybara
|
|
29
29
|
rescue TimeoutError
|
30
30
|
end
|
31
31
|
unless node
|
32
|
-
options =
|
33
|
-
|
32
|
+
options = extract_normalized_options(args)
|
33
|
+
normalized = Capybara::Selector.normalize(*args)
|
34
|
+
message = options[:message] || "Unable to find #{normalized.name} #{normalized.locator.inspect}"
|
35
|
+
message = normalized.failure_message.call(self, normalized) if normalized.failure_message
|
36
|
+
raise Capybara::ElementNotFound, message
|
34
37
|
end
|
35
38
|
return node
|
36
39
|
end
|
@@ -117,7 +120,7 @@ module Capybara
|
|
117
120
|
def all(*args)
|
118
121
|
options = extract_normalized_options(args)
|
119
122
|
|
120
|
-
Capybara::Selector.normalize(*args).
|
123
|
+
Capybara::Selector.normalize(*args).xpaths.
|
121
124
|
map { |path| find_in_base(path) }.flatten.
|
122
125
|
select { |node| matches_options(node, options) }.
|
123
126
|
map { |node| convert_element(node) }
|
@@ -138,16 +141,17 @@ module Capybara
|
|
138
141
|
#
|
139
142
|
def first(*args)
|
140
143
|
options = extract_normalized_options(args)
|
144
|
+
found_elements = []
|
141
145
|
|
142
|
-
Capybara::Selector.normalize(*args).each do |path|
|
146
|
+
Capybara::Selector.normalize(*args).xpaths.each do |path|
|
143
147
|
find_in_base(path).each do |node|
|
144
148
|
if matches_options(node, options)
|
145
|
-
|
149
|
+
found_elements << convert_element(node)
|
150
|
+
return found_elements.last if not Capybara.prefer_visible_elements or node.visible?
|
146
151
|
end
|
147
152
|
end
|
148
153
|
end
|
149
|
-
|
150
|
-
nil
|
154
|
+
found_elements.first
|
151
155
|
end
|
152
156
|
|
153
157
|
protected
|
@@ -43,11 +43,11 @@ module Capybara
|
|
43
43
|
when options[:between]
|
44
44
|
options[:between] === results.size
|
45
45
|
when options[:count]
|
46
|
-
options[:count] == results.size
|
46
|
+
options[:count].to_i == results.size
|
47
47
|
when options[:maximum]
|
48
|
-
options[:maximum] >= results.size
|
48
|
+
options[:maximum].to_i >= results.size
|
49
49
|
when options[:minimum]
|
50
|
-
options[:minimum] <= results.size
|
50
|
+
options[:minimum].to_i <= results.size
|
51
51
|
else
|
52
52
|
results.size > 0
|
53
53
|
end
|
@@ -75,11 +75,11 @@ module Capybara
|
|
75
75
|
when options[:between]
|
76
76
|
not(options[:between] === results.size)
|
77
77
|
when options[:count]
|
78
|
-
not(options[:count] == results.size)
|
78
|
+
not(options[:count].to_i == results.size)
|
79
79
|
when options[:maximum]
|
80
|
-
not(options[:maximum] >= results.size)
|
80
|
+
not(options[:maximum].to_i >= results.size)
|
81
81
|
when options[:minimum]
|
82
|
-
not(options[:minimum] <= results.size)
|
82
|
+
not(options[:minimum].to_i <= results.size)
|
83
83
|
else
|
84
84
|
results.empty?
|
85
85
|
end
|
@@ -293,6 +293,19 @@ module Capybara
|
|
293
293
|
has_xpath?(XPath::HTML.field(locator), :checked => true)
|
294
294
|
end
|
295
295
|
|
296
|
+
##
|
297
|
+
#
|
298
|
+
# Checks if the page or current node has no radio button or
|
299
|
+
# checkbox with the given label, value or id, that is currently
|
300
|
+
# checked.
|
301
|
+
#
|
302
|
+
# @param [String] locator The label, name or id of a checked field
|
303
|
+
# @return [Boolean] Whether it doesn't exists
|
304
|
+
#
|
305
|
+
def has_no_checked_field?(locator)
|
306
|
+
has_no_xpath?(XPath::HTML.field(locator), :checked => true)
|
307
|
+
end
|
308
|
+
|
296
309
|
##
|
297
310
|
#
|
298
311
|
# Checks if the page or current node has a radio button or
|
@@ -306,6 +319,19 @@ module Capybara
|
|
306
319
|
has_xpath?(XPath::HTML.field(locator), :unchecked => true)
|
307
320
|
end
|
308
321
|
|
322
|
+
##
|
323
|
+
#
|
324
|
+
# Checks if the page or current node has no radio button or
|
325
|
+
# checkbox with the given label, value or id, that is currently
|
326
|
+
# unchecked.
|
327
|
+
#
|
328
|
+
# @param [String] locator The label, name or id of an unchecked field
|
329
|
+
# @return [Boolean] Whether it doesn't exists
|
330
|
+
#
|
331
|
+
def has_no_unchecked_field?(locator)
|
332
|
+
has_no_xpath?(XPath::HTML.field(locator), :unchecked => true)
|
333
|
+
end
|
334
|
+
|
309
335
|
##
|
310
336
|
#
|
311
337
|
# Checks if the page or current node has a select field with the
|
data/lib/capybara/node/simple.rb
CHANGED
@@ -98,6 +98,26 @@ module Capybara
|
|
98
98
|
native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none')]").size == 0
|
99
99
|
end
|
100
100
|
|
101
|
+
##
|
102
|
+
#
|
103
|
+
# Whether or not the element is checked.
|
104
|
+
#
|
105
|
+
# @return [Boolean] Whether the element is checked
|
106
|
+
#
|
107
|
+
def checked?
|
108
|
+
native[:checked]
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
#
|
113
|
+
# Whether or not the element is selected.
|
114
|
+
#
|
115
|
+
# @return [Boolean] Whether the element is selected
|
116
|
+
#
|
117
|
+
def selected?
|
118
|
+
native[:selected]
|
119
|
+
end
|
120
|
+
|
101
121
|
protected
|
102
122
|
|
103
123
|
def find_in_base(xpath)
|
@@ -0,0 +1,115 @@
|
|
1
|
+
class Capybara::RackTest::Browser
|
2
|
+
include ::Rack::Test::Methods
|
3
|
+
|
4
|
+
attr_reader :app, :options
|
5
|
+
attr_accessor :current_host
|
6
|
+
|
7
|
+
def initialize(app, options={})
|
8
|
+
@app = app
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def visit(path, attributes = {})
|
13
|
+
reset_host!
|
14
|
+
process(:get, path, attributes)
|
15
|
+
end
|
16
|
+
|
17
|
+
def submit(method, path, attributes)
|
18
|
+
path = request_path if not path or path.empty?
|
19
|
+
process(method, path, attributes)
|
20
|
+
end
|
21
|
+
|
22
|
+
def follow(method, path, attributes = {})
|
23
|
+
return if path.gsub(/^#{request_path}/, '').start_with?('#')
|
24
|
+
process(method, path, attributes)
|
25
|
+
end
|
26
|
+
|
27
|
+
def follow_redirects!
|
28
|
+
5.times do
|
29
|
+
follow_redirect! if last_response.redirect?
|
30
|
+
end
|
31
|
+
raise Capybara::InfiniteRedirectError, "redirected more than 5 times, check for infinite redirects." if last_response.redirect?
|
32
|
+
end
|
33
|
+
|
34
|
+
def process(method, path, attributes = {})
|
35
|
+
new_uri = URI.parse(path)
|
36
|
+
current_uri = URI.parse(current_url)
|
37
|
+
|
38
|
+
path = request_path + path if path.start_with?('?')
|
39
|
+
path = current_host + path if path.start_with?('/')
|
40
|
+
|
41
|
+
if new_uri.host
|
42
|
+
@current_host = new_uri.scheme + '://' + new_uri.host
|
43
|
+
end
|
44
|
+
|
45
|
+
reset_cache!
|
46
|
+
send(method, to_binary(path), to_binary( attributes ), env)
|
47
|
+
follow_redirects!
|
48
|
+
end
|
49
|
+
|
50
|
+
def current_url
|
51
|
+
last_request.url
|
52
|
+
rescue Rack::Test::Error
|
53
|
+
""
|
54
|
+
end
|
55
|
+
|
56
|
+
def reset_host!
|
57
|
+
@current_host = (Capybara.app_host || Capybara.default_host)
|
58
|
+
end
|
59
|
+
|
60
|
+
def reset_cache!
|
61
|
+
@dom = nil
|
62
|
+
end
|
63
|
+
|
64
|
+
def body
|
65
|
+
dom.to_xml
|
66
|
+
end
|
67
|
+
|
68
|
+
def dom
|
69
|
+
@dom ||= Nokogiri::HTML(source)
|
70
|
+
end
|
71
|
+
|
72
|
+
def find(selector)
|
73
|
+
dom.xpath(selector).map { |node| Capybara::RackTest::Node.new(self, node) }
|
74
|
+
end
|
75
|
+
|
76
|
+
def source
|
77
|
+
last_response.body
|
78
|
+
rescue Rack::Test::Error
|
79
|
+
nil
|
80
|
+
end
|
81
|
+
|
82
|
+
protected
|
83
|
+
|
84
|
+
def to_binary(object)
|
85
|
+
return object unless Kernel.const_defined?(:Encoding)
|
86
|
+
|
87
|
+
if object.respond_to?(:force_encoding)
|
88
|
+
object.dup.force_encoding(Encoding::ASCII_8BIT)
|
89
|
+
elsif object.respond_to?(:each_pair) #Hash
|
90
|
+
{}.tap { |x| object.each_pair {|k,v| x[to_binary(k)] = to_binary(v) } }
|
91
|
+
elsif object.respond_to?(:each) #Array
|
92
|
+
object.map{|x| to_binary(x)}
|
93
|
+
else
|
94
|
+
object
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def request_path
|
99
|
+
last_request.path
|
100
|
+
rescue Rack::Test::Error
|
101
|
+
""
|
102
|
+
end
|
103
|
+
|
104
|
+
def env
|
105
|
+
env = {}
|
106
|
+
begin
|
107
|
+
env["HTTP_REFERER"] = last_request.url
|
108
|
+
rescue Rack::Test::Error
|
109
|
+
# no request yet
|
110
|
+
end
|
111
|
+
env.merge!(options[:headers]) if options[:headers]
|
112
|
+
env
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|