class Capybara::RackTest::Browser

Attributes

current_host[RW]
driver[R]

Public Class Methods

new(driver) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 9
def initialize(driver)
  @driver = driver
  @current_fragment = nil
end

Public Instance Methods

app() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 14
def app
  driver.app
end
build_uri(path) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 77
def build_uri(path)
  uri = URI.parse(path)
  base_uri = base_relative_uri_for(uri)

  uri.path = base_uri.path + uri.path unless uri.absolute? || uri.path.start_with?('/')

  if base_uri.absolute?
    base_uri.merge(uri)
  else
    uri.scheme ||= @current_scheme
    uri.host ||= @current_host
    uri.port ||= @current_port unless uri.default_port == @current_port
    uri
  end
end
current_url() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 93
def current_url
  uri = build_uri(last_request.url)
  uri.fragment = @current_fragment if @current_fragment
  uri.to_s
rescue Rack::Test::Error
  ''
end
dom() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 110
def dom
  @dom ||= Capybara::HTML(html)
end
find(format, selector) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 114
def find(format, selector)
  if format == :css
    dom.css(selector, Capybara::RackTest::CSSHandlers.new)
  else
    dom.xpath(selector)
  end.map { |node| Capybara::RackTest::Node.new(self, node) }
end
follow(method, path, **attributes) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 41
def follow(method, path, **attributes)
  return if fragment_or_script?(path)

  process_and_follow_redirects(method, path, attributes, 'HTTP_REFERER' => referer_url)
end
html() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 122
def html
  last_response.body
rescue Rack::Test::Error
  ''
end
last_request() click to toggle source
Calls superclass method
# File lib/capybara/rack_test/browser.rb, line 132
def last_request
  raise Rack::Test::Error if @new_visit_request

  super
end
last_response() click to toggle source
Calls superclass method
# File lib/capybara/rack_test/browser.rb, line 138
def last_response
  raise Rack::Test::Error if @new_visit_request

  super
end
options() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 18
def options
  driver.options
end
process(method, path, attributes = {}, env = {}) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 67
def process(method, path, attributes = {}, env = {})
  method = method.downcase
  new_uri = build_uri(path)
  @current_scheme, @current_host, @current_port = new_uri.select(:scheme, :host, :port)
  @current_fragment = new_uri.fragment || @current_fragment
  reset_cache!
  @new_visit_request = false
  send(method, new_uri.to_s, attributes, env.merge(options[:headers] || {}))
end
process_and_follow_redirects(method, path, attributes = {}, env = {}) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 47
def process_and_follow_redirects(method, path, attributes = {}, env = {})
  @current_fragment = build_uri(path).fragment
  process(method, path, attributes, env)
  return unless driver.follow_redirects?

  driver.redirect_limit.times do
    if last_response.redirect?
      if [307, 308].include? last_response.status
        process(last_request.request_method, last_response['Location'], last_request.params, env)
      else
        process(:get, last_response['Location'], {}, env)
      end
    end
  end

  if last_response.redirect? # rubocop:disable Style/GuardClause
    raise Capybara::InfiniteRedirectError, "redirected more than #{driver.redirect_limit} times, check for infinite redirects."
  end
end
refresh() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 29
def refresh
  reset_cache!
  request(last_request.fullpath, last_request.env)
end
reset_cache!() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 106
def reset_cache!
  @dom = nil
end
reset_host!() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 101
def reset_host!
  uri = URI.parse(driver.session_options.app_host || driver.session_options.default_host)
  @current_scheme, @current_host, @current_port = uri.select(:scheme, :host, :port)
end
submit(method, path, attributes) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 34
def submit(method, path, attributes)
  path = request_path if path.nil? || path.empty?
  uri = build_uri(path)
  uri.query = '' if method.to_s.casecmp('get').zero?
  process_and_follow_redirects(method, uri.to_s, attributes, 'HTTP_REFERER' => referer_url)
end
title() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 128
def title
  dom.title
end
visit(path, **attributes) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 22
def visit(path, **attributes)
  @new_visit_request = true
  reset_cache!
  reset_host!
  process_and_follow_redirects(:get, path, attributes)
end

Protected Instance Methods

base_href() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 146
def base_href
  find(:css, 'head > base').first&.[](:href).to_s
end
base_relative_uri_for(uri) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 150
def base_relative_uri_for(uri)
  base_uri = URI.parse(base_href)
  current_uri = URI.parse(safe_last_request&.url.to_s).tap do |c|
    c.path.sub!(%r{/[^/]*$}, '/') unless uri.path.empty?
    c.path = '/' if c.path.empty?
  end

  if [current_uri, base_uri].any?(&:absolute?)
    current_uri.merge(base_uri)
  else
    base_uri.path = current_uri.path if base_uri.path.empty?
    base_uri
  end
end
build_rack_mock_session() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 165
def build_rack_mock_session
  reset_host! unless current_host
  Rack::MockSession.new(app, current_host)
end
request_path() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 170
def request_path
  last_request.path
rescue Rack::Test::Error
  '/'
end
safe_last_request() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 176
def safe_last_request
  last_request
rescue Rack::Test::Error
  nil
end

Private Instance Methods

fragment_or_script?(path) click to toggle source
# File lib/capybara/rack_test/browser.rb, line 184
def fragment_or_script?(path)
  path.gsub(/^#{Regexp.escape(request_path)}/, '').start_with?('#') || path.downcase.start_with?('javascript:')
end
referer_url() click to toggle source
# File lib/capybara/rack_test/browser.rb, line 188
def referer_url
  build_uri(last_request.url).to_s
rescue Rack::Test::Error
  ''
end