File: browser.rb

package info (click to toggle)
ruby-capybara 2.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 948 kB
  • ctags: 516
  • sloc: ruby: 7,998; makefile: 4
file content (114 lines) | stat: -rw-r--r-- 2,824 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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

  def visit(path, attributes = {})
    reset_host!
    process_and_follow_redirects(:get, path, attributes)
  end

  def submit(method, path, attributes)
    path = request_path if not path or path.empty?
    process_and_follow_redirects(method, path, attributes, {'HTTP_REFERER' => current_url})
  end

  def follow(method, path, attributes = {})
    return if path.gsub(/^#{request_path}/, '').start_with?('#')
    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)
    if driver.follow_redirects?
      driver.redirect_limit.times do
        process(:get, last_response["Location"], {}, env) if last_response.redirect?
      end
      raise Capybara::InfiniteRedirectError, "redirected more than #{driver.redirect_limit} times, check for infinite redirects." if last_response.redirect?
    end
  end

  def process(method, path, attributes = {}, env = {})
    new_uri = URI.parse(path)
    method.downcase! unless method.is_a? Symbol

    new_uri.path = request_path if path.start_with?("?")
    new_uri.path = "/" if new_uri.path.empty?
    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

    @current_scheme = new_uri.scheme
    @current_host = new_uri.host
    @current_port = new_uri.port

    reset_cache!
    send(method, new_uri.to_s, attributes, env.merge(options[:headers] || {}))
  end

  def current_url
    last_request.url
  rescue Rack::Test::Error
    ""
  end

  def reset_host!
    uri = URI.parse(Capybara.app_host || Capybara.default_host)
    @current_scheme = uri.scheme
    @current_host = uri.host
    @current_port = uri.port
  end

  def reset_cache!
    @dom = nil
  end

  def dom
    @dom ||= Capybara::HTML(html)
  end

  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

  def html
    last_response.body
  rescue Rack::Test::Error
    ""
  end

  def title
    dom.xpath("//title").text
  end

protected

  def build_rack_mock_session
    reset_host! unless current_host
    Rack::MockSession.new(app, current_host)
  end

  def request_path
    last_request.path
  rescue Rack::Test::Error
    "/"
  end
end