teamcapybara--capybara/lib/capybara/rack_test/browser.rb

136 lines
3.2 KiB
Ruby
Raw Normal View History

2016-03-08 00:52:19 +00:00
# frozen_string_literal: true
2018-01-08 20:23:54 +00:00
class Capybara::RackTest::Browser
include ::Rack::Test::Methods
attr_reader :driver
attr_accessor :current_host
def initialize(driver)
@driver = driver
end
def app
driver.app
end
def options
driver.options
end
2017-05-02 01:39:08 +00:00
def visit(path, **attributes)
reset_host!
process_and_follow_redirects(:get, path, attributes)
end
2017-07-04 22:14:55 +00:00
def refresh
reset_cache!
request(last_request.fullpath, last_request.env)
end
def submit(method, path, attributes)
2018-01-09 22:05:50 +00:00
path = request_path if path.nil? || path.empty?
process_and_follow_redirects(method, path, attributes, 'HTTP_REFERER' => current_url)
end
2017-05-02 01:39:08 +00:00
def follow(method, path, **attributes)
2018-05-16 19:47:08 +00:00
return if fragment_or_script?(path)
2018-09-24 16:43:46 +00:00
2018-01-09 22:05:50 +00:00
process_and_follow_redirects(method, path, attributes, 'HTTP_REFERER' => current_url)
end
def process_and_follow_redirects(method, path, attributes = {}, env = {})
process(method, path, attributes, env)
2018-01-09 22:05:50 +00:00
return unless driver.follow_redirects?
driver.redirect_limit.times do
if last_response.redirect?
if [307, 308].include? last_response.status
2018-07-10 21:18:39 +00:00
process(last_request.request_method, last_response['Location'], last_request.params, env)
else
2018-07-10 21:18:39 +00:00
process(:get, last_response['Location'], {}, env)
end
end
end
2018-01-09 22:05:50 +00:00
raise Capybara::InfiniteRedirectError, "redirected more than #{driver.redirect_limit} times, check for infinite redirects." if last_response.redirect?
end
def process(method, path, attributes = {}, env = {})
2018-10-11 17:59:17 +00:00
method = method.downcase
new_uri = build_uri(path)
2018-05-16 19:47:08 +00:00
@current_scheme, @current_host, @current_port = new_uri.select(:scheme, :host, :port)
2011-07-18 19:09:44 +00:00
reset_cache!
send(method, new_uri.to_s, attributes, env.merge(options[:headers] || {}))
end
2018-10-11 17:59:17 +00:00
def build_uri(path)
URI.parse(path).tap do |uri|
uri.path = request_path if path.empty? || path.start_with?('?')
uri.path = '/' if uri.path.empty?
uri.path = request_path.sub(%r{/[^/]*$}, '/') + uri.path unless uri.path.start_with?('/')
uri.scheme ||= @current_scheme
uri.host ||= @current_host
uri.port ||= @current_port unless uri.default_port == @current_port
end
end
def current_url
2011-07-29 23:14:31 +00:00
last_request.url
2011-04-07 14:17:51 +00:00
rescue Rack::Test::Error
2018-07-10 21:18:39 +00:00
''
end
def reset_host!
uri = URI.parse(driver.session_options.app_host || driver.session_options.default_host)
2018-05-16 19:47:08 +00:00
@current_scheme, @current_host, @current_port = uri.select(:scheme, :host, :port)
end
def reset_cache!
@dom = nil
end
def dom
@dom ||= Capybara::HTML(html)
end
def find(format, selector)
2018-01-09 22:05:50 +00:00
if format == :css
dom.css(selector, Capybara::RackTest::CSSHandlers.new)
2013-02-16 21:26:01 +00:00
else
dom.xpath(selector)
end.map { |node| Capybara::RackTest::Node.new(self, node) }
end
def html
last_response.body
rescue Rack::Test::Error
2018-07-10 21:18:39 +00:00
''
end
def title
dom.title
end
protected
def build_rack_mock_session
reset_host! unless current_host
Rack::MockSession.new(app, current_host)
end
def request_path
2011-04-06 07:36:05 +00:00
last_request.path
rescue Rack::Test::Error
2018-07-10 21:18:39 +00:00
'/'
end
2018-05-16 19:47:08 +00:00
private
def fragment_or_script?(path)
path.gsub(/^#{Regexp.escape(request_path)}/, '').start_with?('#') || path.downcase.start_with?('javascript:')
end
end