2016-03-07 19:52:19 -05:00
|
|
|
# frozen_string_literal: true
|
2011-04-05 11:42:12 -04:00
|
|
|
class Capybara::RackTest::Browser
|
|
|
|
include ::Rack::Test::Methods
|
|
|
|
|
2011-08-30 05:20:29 -04:00
|
|
|
attr_reader :driver
|
2011-04-05 11:42:12 -04:00
|
|
|
attr_accessor :current_host
|
|
|
|
|
2011-08-30 05:20:29 -04:00
|
|
|
def initialize(driver)
|
|
|
|
@driver = driver
|
|
|
|
end
|
|
|
|
|
|
|
|
def app
|
|
|
|
driver.app
|
|
|
|
end
|
|
|
|
|
|
|
|
def options
|
|
|
|
driver.options
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def visit(path, attributes = {})
|
|
|
|
reset_host!
|
2012-01-20 07:24:40 -05:00
|
|
|
process_and_follow_redirects(:get, path, attributes)
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def submit(method, path, attributes)
|
|
|
|
path = request_path if not path or path.empty?
|
2012-01-20 07:24:40 -05:00
|
|
|
process_and_follow_redirects(method, path, attributes, {'HTTP_REFERER' => current_url})
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def follow(method, path, attributes = {})
|
2015-04-14 15:46:00 -04:00
|
|
|
return if path.gsub(/^#{Regexp.escape(request_path)}/, '').start_with?('#') || path.downcase.start_with?('javascript:')
|
2012-01-20 07:24:40 -05:00
|
|
|
process_and_follow_redirects(method, path, attributes, {'HTTP_REFERER' => current_url})
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
|
2012-01-20 07:24:40 -05:00
|
|
|
def process_and_follow_redirects(method, path, attributes = {}, env = {})
|
|
|
|
process(method, path, attributes, env)
|
2012-07-12 10:57:27 -04:00
|
|
|
if driver.follow_redirects?
|
2012-07-12 11:03:28 -04:00
|
|
|
driver.redirect_limit.times do
|
2012-07-12 10:57:27 -04:00
|
|
|
process(:get, last_response["Location"], {}, env) if last_response.redirect?
|
|
|
|
end
|
2012-07-12 11:03:28 -04:00
|
|
|
raise Capybara::InfiniteRedirectError, "redirected more than #{driver.redirect_limit} times, check for infinite redirects." if last_response.redirect?
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-01-20 07:24:40 -05:00
|
|
|
def process(method, path, attributes = {}, env = {})
|
2011-04-05 11:42:12 -04:00
|
|
|
new_uri = URI.parse(path)
|
2011-11-02 12:24:54 -04:00
|
|
|
method.downcase! unless method.is_a? Symbol
|
2011-04-05 11:42:12 -04:00
|
|
|
|
2012-09-06 04:46:54 -04:00
|
|
|
new_uri.path = request_path if path.start_with?("?")
|
2013-11-10 08:31:08 -05:00
|
|
|
new_uri.path = "/" if new_uri.path.empty?
|
2012-09-06 04:46:54 -04:00
|
|
|
new_uri.path = request_path.sub(%r(/[^/]*$), '/') + new_uri.path unless new_uri.path.start_with?('/')
|
|
|
|
new_uri.scheme ||= @current_scheme
|
|
|
|
new_uri.host ||= @current_host
|
|
|
|
new_uri.port ||= @current_port unless new_uri.default_port == @current_port
|
2011-07-18 15:09:44 -04:00
|
|
|
|
2012-09-06 04:46:54 -04:00
|
|
|
@current_scheme = new_uri.scheme
|
|
|
|
@current_host = new_uri.host
|
|
|
|
@current_port = new_uri.port
|
2011-07-18 15:09:44 -04:00
|
|
|
|
2011-04-05 11:42:12 -04:00
|
|
|
reset_cache!
|
2012-09-06 04:46:54 -04:00
|
|
|
send(method, new_uri.to_s, attributes, env.merge(options[:headers] || {}))
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def current_url
|
2011-07-29 19:14:31 -04:00
|
|
|
last_request.url
|
2011-04-07 10:17:51 -04:00
|
|
|
rescue Rack::Test::Error
|
|
|
|
""
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def reset_host!
|
2012-09-06 04:46:54 -04:00
|
|
|
uri = URI.parse(Capybara.app_host || Capybara.default_host)
|
|
|
|
@current_scheme = uri.scheme
|
|
|
|
@current_host = uri.host
|
|
|
|
@current_port = uri.port
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
def reset_cache!
|
|
|
|
@dom = nil
|
|
|
|
end
|
|
|
|
|
|
|
|
def dom
|
2013-04-29 16:50:14 -04:00
|
|
|
@dom ||= Capybara::HTML(html)
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
|
2013-02-19 12:03:26 -05:00
|
|
|
def find(format, selector)
|
2013-02-18 15:35:24 -05:00
|
|
|
if format==:css
|
2013-02-18 17:41:44 -05:00
|
|
|
dom.css(selector, Capybara::RackTest::CSSHandlers.new)
|
2013-02-16 16:26:01 -05:00
|
|
|
else
|
|
|
|
dom.xpath(selector)
|
|
|
|
end.map { |node| Capybara::RackTest::Node.new(self, node) }
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
|
2012-11-20 08:22:19 -05:00
|
|
|
def html
|
2011-04-05 11:42:12 -04:00
|
|
|
last_response.body
|
|
|
|
rescue Rack::Test::Error
|
2011-11-15 10:57:18 -05:00
|
|
|
""
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
2013-11-10 08:31:08 -05:00
|
|
|
|
2013-02-06 14:36:55 -05:00
|
|
|
def title
|
2015-05-28 15:10:13 -04:00
|
|
|
if dom.respond_to? :title
|
|
|
|
dom.title
|
|
|
|
else
|
|
|
|
#old versions of nokogiri don't have #title - remove in 3.0
|
|
|
|
dom.xpath('/html/head/title | /html/title').first.text
|
|
|
|
end
|
2013-02-06 14:36:55 -05:00
|
|
|
end
|
2013-11-10 08:31:08 -05:00
|
|
|
|
2011-04-05 11:42:12 -04:00
|
|
|
protected
|
|
|
|
|
2011-05-19 11:50:06 -04:00
|
|
|
def build_rack_mock_session
|
2011-05-26 06:16:28 -04:00
|
|
|
reset_host! unless current_host
|
2012-12-02 20:51:50 -05:00
|
|
|
Rack::MockSession.new(app, current_host)
|
2011-05-19 11:50:06 -04:00
|
|
|
end
|
|
|
|
|
2011-04-05 11:42:12 -04:00
|
|
|
def request_path
|
2011-04-06 03:36:05 -04:00
|
|
|
last_request.path
|
|
|
|
rescue Rack::Test::Error
|
2013-05-15 16:33:17 -04:00
|
|
|
"/"
|
2011-04-05 11:42:12 -04:00
|
|
|
end
|
|
|
|
end
|