public
Description: Webrat - Ruby Acceptance Testing for Web applications
Homepage: http://gitrdoc.com/brynary/webrat/tree/master/
Clone URL: git://github.com/brynary/webrat.git
webrat / lib / webrat / core / session.rb
100644 229 lines (183 sloc) 5.872 kb
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
require "forwardable"
require "ostruct"
 
require "webrat/core/mime"
require "webrat/core/save_and_open_page"
 
module Webrat
  # A page load or form submission returned an unsuccessful response code (500-599)
  class PageLoadError < WebratError
  end
 
  def self.session_class
    case Webrat.configuration.mode
    when :rails
      RailsSession
    when :merb
      MerbSession
    when :selenium
      SeleniumSession
    when :rack
      RackSession
    when :sinatra
      SinatraSession
    when :mechanize
      MechanizeSession
    else
      raise WebratError.new(<<-STR)
Unknown Webrat mode: #{Webrat.configuration.mode.inspect}
 
Please ensure you have a Webrat configuration block that specifies a mode
in your test_helper.rb, spec_helper.rb, or env.rb (for Cucumber).
For example:
 
Webrat.configure do |config|
config.mode = :rails
end
STR
    end
  end
 
  class Session
    extend Forwardable
    include Logging
    include SaveAndOpenPage
 
    attr_reader :current_url
    attr_reader :elements
 
    def initialize(context = nil) #:nodoc:
      @http_method = :get
      @data = {}
      @default_headers = {}
      @custom_headers = {}
      @context = context
 
      reset
    end
 
    def current_dom #:nodoc:
      current_scope.dom
    end
 
    # For backwards compatibility -- removing in 1.0
    def current_page #:nodoc:
      page = OpenStruct.new
      page.url = @current_url
      page.http_method = @http_method
      page.data = @data
      page
    end
 
    def doc_root #:nodoc:
      nil
    end
 
    def header(key, value)
      @custom_headers[key] = value
    end
 
    def http_accept(mime_type)
      header('Accept', Webrat::MIME.mime_type(mime_type))
    end
 
    def basic_auth(user, pass)
      encoded_login = ["#{user}:#{pass}"].pack("m*")
      header('HTTP_AUTHORIZATION', "Basic #{encoded_login}")
    end
 
    def headers #:nodoc:
      @default_headers.dup.merge(@custom_headers.dup)
    end
 
    def request_page(url, http_method, data) #:nodoc:
      h = headers
      h['HTTP_REFERER'] = @current_url if @current_url
 
      debug_log "REQUESTING PAGE: #{http_method.to_s.upcase} #{url} with #{data.inspect} and HTTP headers #{h.inspect}"
      if h.empty?
        send "#{http_method}", url, data || {}
      else
        send "#{http_method}", url, data || {}, h
      end
 
      save_and_open_page if exception_caught? && Webrat.configuration.open_error_files?
      raise PageLoadError.new("Page load was not successful (Code: #{response_code.inspect}):\n#{formatted_error}") unless success_code?
 
      reset
 
      @current_url = url
      @http_method = http_method
      @data = data
 
      request_page(response.location, :get, data) if response.redirect?
 
      return response
    end
 
    def success_code? #:nodoc:
      (200..499).include?(response_code)
    end
 
    def exception_caught? #:nodoc:
      response_body =~ /Exception caught/
    end
 
    def current_scope #:nodoc:
      scopes.last || page_scope
    end
 
    # Reloads the last page requested. Note that this will resubmit forms
    # and their data.
    def reloads
      request_page(@current_url, @http_method, @data)
    end
 
    webrat_deprecate :reload, :reloads
 
 
    # Works like click_link, but only looks for the link text within a given selector
    #
    # Example:
    # click_link_within "#user_12", "Vote"
    def click_link_within(selector, link_text)
      within(selector) do
        click_link(link_text)
      end
    end
 
    webrat_deprecate :clicks_link_within, :click_link_within
 
    def within(selector)
      scopes.push(Scope.from_scope(self, current_scope, selector))
      ret = yield(current_scope)
      scopes.pop
      return ret
    end
 
    # Issues a GET request for a page, follows any redirects, and verifies the final page
    # load was successful.
    #
    # Example:
    # visit "/"
    def visit(url = nil, http_method = :get, data = {})
      request_page(url, http_method, data)
    end
 
    webrat_deprecate :visits, :visit
 
    # Subclasses can override this to show error messages without html
    def formatted_error #:nodoc:
      response_body
    end
 
    def scopes #:nodoc:
      @_scopes ||= []
    end
 
    def page_scope #:nodoc:
      @_page_scope ||= Scope.from_page(self, response, response_body)
    end
 
    def dom
      page_scope.dom
    end
 
    def xml_content_type?
      false
    end
 
    def simulate
      return if Webrat.configuration.mode == :selenium
      yield
    end
 
    def automate
      return unless Webrat.configuration.mode == :selenium
      yield
    end
 
    def_delegators :current_scope, :fill_in, :fills_in
    def_delegators :current_scope, :set_hidden_field
    def_delegators :current_scope, :submit_form
    def_delegators :current_scope, :check, :checks
    def_delegators :current_scope, :uncheck, :unchecks
    def_delegators :current_scope, :choose, :chooses
    def_delegators :current_scope, :select, :selects
    def_delegators :current_scope, :select_datetime, :selects_datetime
    def_delegators :current_scope, :select_date, :selects_date
    def_delegators :current_scope, :select_time, :selects_time
    def_delegators :current_scope, :attach_file, :attaches_file
    def_delegators :current_scope, :click_area, :clicks_area
    def_delegators :current_scope, :click_link, :clicks_link
    def_delegators :current_scope, :click_button, :clicks_button
    def_delegators :current_scope, :field_labeled
    def_delegators :current_scope, :field_by_xpath
    def_delegators :current_scope, :field_with_id
    def_delegators :current_scope, :select_option
 
  private
 
    def reset
      @elements = {}
      @_scopes = nil
      @_page_scope = nil
    end
 
  end
end