honkster-webrat 0.4.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/History.txt +358 -0
  2. data/MIT-LICENSE.txt +19 -0
  3. data/README.rdoc +85 -0
  4. data/Rakefile +200 -0
  5. data/install.rb +1 -0
  6. data/lib/webrat.rb +31 -0
  7. data/lib/webrat/core.rb +14 -0
  8. data/lib/webrat/core/configuration.rb +102 -0
  9. data/lib/webrat/core/elements/area.rb +31 -0
  10. data/lib/webrat/core/elements/element.rb +33 -0
  11. data/lib/webrat/core/elements/field.rb +411 -0
  12. data/lib/webrat/core/elements/form.rb +103 -0
  13. data/lib/webrat/core/elements/label.rb +31 -0
  14. data/lib/webrat/core/elements/link.rb +93 -0
  15. data/lib/webrat/core/elements/select_option.rb +35 -0
  16. data/lib/webrat/core/locators.rb +20 -0
  17. data/lib/webrat/core/locators/area_locator.rb +38 -0
  18. data/lib/webrat/core/locators/button_locator.rb +54 -0
  19. data/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
  20. data/lib/webrat/core/locators/field_labeled_locator.rb +56 -0
  21. data/lib/webrat/core/locators/field_locator.rb +25 -0
  22. data/lib/webrat/core/locators/field_named_locator.rb +41 -0
  23. data/lib/webrat/core/locators/form_locator.rb +19 -0
  24. data/lib/webrat/core/locators/label_locator.rb +34 -0
  25. data/lib/webrat/core/locators/link_locator.rb +74 -0
  26. data/lib/webrat/core/locators/locator.rb +20 -0
  27. data/lib/webrat/core/locators/select_option_locator.rb +59 -0
  28. data/lib/webrat/core/logging.rb +24 -0
  29. data/lib/webrat/core/matchers.rb +4 -0
  30. data/lib/webrat/core/matchers/have_content.rb +73 -0
  31. data/lib/webrat/core/matchers/have_selector.rb +74 -0
  32. data/lib/webrat/core/matchers/have_tag.rb +21 -0
  33. data/lib/webrat/core/matchers/have_xpath.rb +147 -0
  34. data/lib/webrat/core/methods.rb +63 -0
  35. data/lib/webrat/core/mime.rb +29 -0
  36. data/lib/webrat/core/save_and_open_page.rb +48 -0
  37. data/lib/webrat/core/scope.rb +350 -0
  38. data/lib/webrat/core/session.rb +291 -0
  39. data/lib/webrat/core/xml.rb +115 -0
  40. data/lib/webrat/core/xml/hpricot.rb +19 -0
  41. data/lib/webrat/core/xml/nokogiri.rb +76 -0
  42. data/lib/webrat/core/xml/rexml.rb +24 -0
  43. data/lib/webrat/core_extensions/blank.rb +58 -0
  44. data/lib/webrat/core_extensions/deprecate.rb +8 -0
  45. data/lib/webrat/core_extensions/detect_mapped.rb +12 -0
  46. data/lib/webrat/core_extensions/meta_class.rb +6 -0
  47. data/lib/webrat/core_extensions/nil_to_param.rb +5 -0
  48. data/lib/webrat/core_extensions/tcp_socket.rb +27 -0
  49. data/lib/webrat/mechanize.rb +74 -0
  50. data/lib/webrat/merb.rb +9 -0
  51. data/lib/webrat/merb_multipart_support.rb +27 -0
  52. data/lib/webrat/merb_session.rb +80 -0
  53. data/lib/webrat/rack.rb +24 -0
  54. data/lib/webrat/rack_test.rb +32 -0
  55. data/lib/webrat/rails.rb +105 -0
  56. data/lib/webrat/rspec-rails.rb +10 -0
  57. data/lib/webrat/selenium.rb +81 -0
  58. data/lib/webrat/selenium/application_server_factory.rb +40 -0
  59. data/lib/webrat/selenium/application_servers.rb +5 -0
  60. data/lib/webrat/selenium/application_servers/base.rb +46 -0
  61. data/lib/webrat/selenium/application_servers/external.rb +26 -0
  62. data/lib/webrat/selenium/application_servers/merb.rb +50 -0
  63. data/lib/webrat/selenium/application_servers/rails.rb +44 -0
  64. data/lib/webrat/selenium/application_servers/sinatra.rb +37 -0
  65. data/lib/webrat/selenium/location_strategy_javascript/button.js +19 -0
  66. data/lib/webrat/selenium/location_strategy_javascript/label.js +24 -0
  67. data/lib/webrat/selenium/location_strategy_javascript/webrat.js +5 -0
  68. data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +12 -0
  69. data/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
  70. data/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
  71. data/lib/webrat/selenium/matchers.rb +4 -0
  72. data/lib/webrat/selenium/matchers/have_content.rb +66 -0
  73. data/lib/webrat/selenium/matchers/have_selector.rb +49 -0
  74. data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
  75. data/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
  76. data/lib/webrat/selenium/selenium_extensions.js +6 -0
  77. data/lib/webrat/selenium/selenium_rc_server.rb +84 -0
  78. data/lib/webrat/selenium/selenium_session.rb +252 -0
  79. data/lib/webrat/selenium/silence_stream.rb +18 -0
  80. data/lib/webrat/sinatra.rb +44 -0
  81. data/vendor/selenium-server.jar +0 -0
  82. metadata +145 -0
@@ -0,0 +1,291 @@
1
+ require "forwardable"
2
+ require "ostruct"
3
+
4
+ require "webrat/core/mime"
5
+ require "webrat/core/save_and_open_page"
6
+
7
+ module Webrat
8
+ # A page load or form submission returned an unsuccessful response code (500-599)
9
+ class PageLoadError < WebratError
10
+ end
11
+
12
+ class InfiniteRedirectError < WebratError
13
+ end
14
+
15
+ def self.session_class
16
+ case Webrat.configuration.mode
17
+ when :rails
18
+ RailsSession
19
+ when :merb
20
+ MerbSession
21
+ when :selenium
22
+ SeleniumSession
23
+ when :rack
24
+ RackSession
25
+ when :sinatra
26
+ SinatraSession
27
+ when :mechanize
28
+ MechanizeSession
29
+ when :rack_test
30
+ RackTestSession
31
+ else
32
+ raise WebratError.new(<<-STR)
33
+ Unknown Webrat mode: #{Webrat.configuration.mode.inspect}
34
+
35
+ Please ensure you have a Webrat configuration block that specifies a mode
36
+ in your test_helper.rb, spec_helper.rb, or env.rb (for Cucumber).
37
+
38
+ This configure block supercedes the need to require "webrat/<framework>".
39
+
40
+ For example:
41
+
42
+ Webrat.configure do |config|
43
+ config.mode = :rails
44
+ end
45
+ STR
46
+ end
47
+ end
48
+
49
+ class Session
50
+ extend Forwardable
51
+ include Logging
52
+ include SaveAndOpenPage
53
+ attr_reader :current_url
54
+ attr_reader :elements
55
+
56
+ def initialize(context = nil) #:nodoc:
57
+ @http_method = :get
58
+ @data = {}
59
+ @default_headers = {}
60
+ @custom_headers = {}
61
+ @context = context
62
+
63
+ reset
64
+ end
65
+
66
+ def current_dom #:nodoc:
67
+ current_scope.dom
68
+ end
69
+
70
+ # For backwards compatibility -- removing in 1.0
71
+ def current_page #:nodoc:
72
+ warn "current_page is deprecated and will be going away in the next release. Use current_url instead."
73
+ page = OpenStruct.new
74
+ page.url = @current_url
75
+ page.http_method = @http_method
76
+ page.data = @data
77
+ page
78
+ end
79
+
80
+ def doc_root #:nodoc:
81
+ nil
82
+ end
83
+
84
+ def header(key, value)
85
+ @custom_headers[key] = value
86
+ end
87
+
88
+ def http_accept(mime_type)
89
+ header('Accept', Webrat::MIME.mime_type(mime_type))
90
+ end
91
+
92
+ def basic_auth(user, pass)
93
+ encoded_login = ["#{user}:#{pass}"].pack("m*")
94
+ header('HTTP_AUTHORIZATION', "Basic #{encoded_login}")
95
+ end
96
+
97
+ def headers #:nodoc:
98
+ @default_headers.dup.merge(@custom_headers.dup)
99
+ end
100
+
101
+ def request_page(url, http_method, data) #:nodoc:
102
+ h = headers
103
+ h['HTTP_REFERER'] = @current_url if @current_url
104
+
105
+ debug_log "REQUESTING PAGE: #{http_method.to_s.upcase} #{url} with #{data.inspect} and HTTP headers #{h.inspect}"
106
+
107
+ process_request(http_method, url, data, h)
108
+
109
+ save_and_open_page if exception_caught? && Webrat.configuration.open_error_files?
110
+ raise PageLoadError.new("Page load was not successful (Code: #{response_code.inspect}):\n#{formatted_error}") unless success_code?
111
+
112
+ reset
113
+
114
+ @current_url = url
115
+ @http_method = http_method
116
+ @data = data
117
+
118
+ if internal_redirect?
119
+ check_for_infinite_redirects
120
+ request_page(response_location, :get, {})
121
+ end
122
+
123
+ return response
124
+ end
125
+
126
+ def check_for_infinite_redirects
127
+ if current_url == response_location
128
+ @_identical_redirect_count ||= 0
129
+ @_identical_redirect_count += 1
130
+ end
131
+
132
+ if infinite_redirect_limit_exceeded?
133
+ raise InfiniteRedirectError.new("#{Webrat.configuration.infinite_redirect_limit} redirects to the same URL (#{current_url.inspect})")
134
+ end
135
+ end
136
+
137
+ def infinite_redirect_limit_exceeded?
138
+ Webrat.configuration.infinite_redirect_limit &&
139
+ (@_identical_redirect_count || 0) > Webrat.configuration.infinite_redirect_limit
140
+ end
141
+
142
+ def success_code? #:nodoc:
143
+ (200..499).include?(response_code)
144
+ end
145
+
146
+ def redirect? #:nodoc:
147
+ (response_code / 100).to_i == 3
148
+ end
149
+
150
+ def internal_redirect?
151
+ return false unless redirect?
152
+ #should keep internal_redirects if the subdomain changes
153
+ current_host_domain = current_host.split('.')[-2..-1].join('.') rescue current_host
154
+ response_location_host_domain = response_location_host.split('.')[-2..-1].join('.') rescue response_location_host
155
+ current_host_domain == response_location_host_domain
156
+ end
157
+
158
+ #easy helper to pull out where we were redirected to
159
+ def redirected_to
160
+ redirect? ? response_location : nil
161
+ end
162
+
163
+ def exception_caught? #:nodoc:
164
+ response_body =~ /Exception caught/
165
+ end
166
+
167
+ def current_scope #:nodoc:
168
+ scopes.last || page_scope
169
+ end
170
+
171
+ # Reloads the last page requested. Note that this will resubmit forms
172
+ # and their data.
173
+ def reload
174
+ request_page(@current_url, @http_method, @data)
175
+ end
176
+
177
+ webrat_deprecate :reloads, :reload
178
+
179
+
180
+ # Works like click_link, but only looks for the link text within a given selector
181
+ #
182
+ # Example:
183
+ # click_link_within "#user_12", "Vote"
184
+ def click_link_within(selector, link_text)
185
+ within(selector) do
186
+ click_link(link_text)
187
+ end
188
+ end
189
+
190
+ webrat_deprecate :clicks_link_within, :click_link_within
191
+
192
+ def within(selector)
193
+ scopes.push(Scope.from_scope(self, current_scope, selector))
194
+ ret = yield(current_scope)
195
+ scopes.pop
196
+ return ret
197
+ end
198
+
199
+ # Issues a GET request for a page, follows any redirects, and verifies the final page
200
+ # load was successful.
201
+ #
202
+ # Example:
203
+ # visit "/"
204
+ def visit(url = nil, http_method = :get, data = {})
205
+ request_page(url, http_method, data)
206
+ end
207
+
208
+ webrat_deprecate :visits, :visit
209
+
210
+ # Subclasses can override this to show error messages without html
211
+ def formatted_error #:nodoc:
212
+ response_body
213
+ end
214
+
215
+ def scopes #:nodoc:
216
+ @_scopes ||= []
217
+ end
218
+
219
+ def page_scope #:nodoc:
220
+ @_page_scope ||= Scope.from_page(self, response, response_body)
221
+ end
222
+
223
+ def dom
224
+ page_scope.dom
225
+ end
226
+
227
+ def xml_content_type?
228
+ false
229
+ end
230
+
231
+ def simulate
232
+ return if Webrat.configuration.mode == :selenium
233
+ yield
234
+ end
235
+
236
+ def automate
237
+ return unless Webrat.configuration.mode == :selenium
238
+ yield
239
+ end
240
+
241
+ def_delegators :current_scope, :fill_in, :fills_in
242
+ def_delegators :current_scope, :set_hidden_field
243
+ def_delegators :current_scope, :submit_form
244
+ def_delegators :current_scope, :check, :checks
245
+ def_delegators :current_scope, :uncheck, :unchecks
246
+ def_delegators :current_scope, :choose, :chooses
247
+ def_delegators :current_scope, :select, :selects
248
+ def_delegators :current_scope, :select_datetime, :selects_datetime
249
+ def_delegators :current_scope, :select_date, :selects_date
250
+ def_delegators :current_scope, :select_time, :selects_time
251
+ def_delegators :current_scope, :attach_file, :attaches_file
252
+ def_delegators :current_scope, :click_area, :clicks_area
253
+ def_delegators :current_scope, :click_link, :clicks_link
254
+ def_delegators :current_scope, :click_button, :clicks_button
255
+ def_delegators :current_scope, :field_labeled
256
+ def_delegators :current_scope, :field_named
257
+ def_delegators :current_scope, :field_by_xpath
258
+ def_delegators :current_scope, :field_with_id
259
+ def_delegators :current_scope, :select_option
260
+ def_delegators :current_scope, :field_named
261
+
262
+ private
263
+
264
+ def process_request(http_method, url, data, headers)
265
+ if headers.empty?
266
+ send "#{http_method}", url, data || {}
267
+ else
268
+ send "#{http_method}", url, data || {}, headers
269
+ end
270
+ end
271
+
272
+ def response_location
273
+ response.headers["Location"]
274
+ end
275
+
276
+ def current_host
277
+ URI.parse(current_url).host || @custom_headers["Host"] || "www.example.com"
278
+ end
279
+
280
+ def response_location_host
281
+ URI.parse(response_location).host || "www.example.com"
282
+ end
283
+
284
+ def reset
285
+ @elements = {}
286
+ @_scopes = nil
287
+ @_page_scope = nil
288
+ end
289
+
290
+ end
291
+ end
@@ -0,0 +1,115 @@
1
+ require "webrat/core/xml/nokogiri"
2
+ require "webrat/core/xml/hpricot"
3
+ require "webrat/core/xml/rexml"
4
+
5
+ module Webrat #:nodoc:
6
+ module XML #:nodoc:
7
+
8
+ def self.document(stringlike) #:nodoc:
9
+ if Webrat.configuration.parse_with_nokogiri?
10
+ Webrat.nokogiri_document(stringlike)
11
+ else
12
+ Webrat.rexml_document(Webrat.hpricot_document(stringlike).to_html)
13
+ end
14
+ end
15
+
16
+ def self.html_document(stringlike) #:nodoc:
17
+ if Webrat.configuration.parse_with_nokogiri?
18
+ Webrat.html_nokogiri_document(stringlike)
19
+ else
20
+ Webrat.rexml_document(Webrat.hpricot_document(stringlike).to_html)
21
+ end
22
+ end
23
+
24
+ def self.xml_document(stringlike) #:nodoc:
25
+ if Webrat.configuration.parse_with_nokogiri?
26
+ Webrat.xml_nokogiri_document(stringlike)
27
+ else
28
+ Webrat.rexml_document(Webrat.hpricot_document(stringlike).to_html)
29
+ end
30
+ end
31
+
32
+ def self.to_html(element)
33
+ if Webrat.configuration.parse_with_nokogiri?
34
+ element.to_html
35
+ else
36
+ element.to_s
37
+ end
38
+ end
39
+
40
+ def self.inner_html(element)
41
+ if Webrat.configuration.parse_with_nokogiri?
42
+ element.inner_html
43
+ else
44
+ element.text
45
+ end
46
+ end
47
+
48
+ def self.all_inner_text(element)
49
+ if Webrat.configuration.parse_with_nokogiri?
50
+ element.inner_text
51
+ else
52
+ Hpricot(element.to_s).children.first.inner_text
53
+ end
54
+ end
55
+
56
+ def self.inner_text(element)
57
+ if Webrat.configuration.parse_with_nokogiri?
58
+ element.inner_text
59
+ else
60
+ if defined?(Hpricot::Doc) && element.is_a?(Hpricot::Doc)
61
+ element.inner_text
62
+ else
63
+ element.text
64
+ end
65
+ end
66
+ end
67
+
68
+ def self.xpath_to(element)
69
+ if Webrat.configuration.parse_with_nokogiri?
70
+ element.path
71
+ else
72
+ element.xpath
73
+ end
74
+ end
75
+
76
+ def self.attribute(element, attribute_name)
77
+ return element[attribute_name] if element.is_a?(Hash)
78
+
79
+ if Webrat.configuration.parse_with_nokogiri?
80
+ element[attribute_name]
81
+ else
82
+ element.attributes[attribute_name]
83
+ end
84
+ end
85
+
86
+ def self.xpath_at(*args)
87
+ xpath_search(*args).first
88
+ end
89
+
90
+ def self.css_at(*args)
91
+ css_search(*args).first
92
+ end
93
+
94
+ def self.xpath_search(element, *searches)
95
+ searches.flatten.map do |search|
96
+ if Webrat.configuration.parse_with_nokogiri?
97
+ element.xpath(search)
98
+ else
99
+ REXML::XPath.match(element, search)
100
+ end
101
+ end.flatten.compact
102
+ end
103
+
104
+ def self.css_search(element, *searches) #:nodoc:
105
+ xpath_search(element, css_to_xpath(*searches))
106
+ end
107
+
108
+ def self.css_to_xpath(*selectors)
109
+ selectors.map do |rule|
110
+ Nokogiri::CSS.xpath_for(rule, :prefix => ".//")
111
+ end.flatten.uniq
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,19 @@
1
+ module Webrat
2
+
3
+ def self.hpricot_document(stringlike)
4
+ return stringlike.dom if stringlike.respond_to?(:dom)
5
+
6
+ if Hpricot::Doc === stringlike
7
+ stringlike
8
+ elsif Hpricot::Elements === stringlike
9
+ stringlike
10
+ elsif StringIO === stringlike
11
+ Hpricot(stringlike.string)
12
+ elsif stringlike.respond_to?(:body)
13
+ Hpricot(stringlike.body.to_s)
14
+ else
15
+ Hpricot(stringlike.to_s)
16
+ end
17
+ end
18
+
19
+ end
@@ -0,0 +1,76 @@
1
+ require "webrat/core_extensions/meta_class"
2
+
3
+ module Webrat
4
+
5
+ def self.nokogiri_document(stringlike) #:nodoc:
6
+ return stringlike.dom if stringlike.respond_to?(:dom)
7
+
8
+ if Nokogiri::HTML::Document === stringlike
9
+ stringlike
10
+ elsif Nokogiri::XML::NodeSet === stringlike
11
+ stringlike
12
+ elsif StringIO === stringlike
13
+ Nokogiri::HTML(stringlike.string)
14
+ elsif stringlike.respond_to?(:body)
15
+ Nokogiri::HTML(stringlike.body.to_s)
16
+ else
17
+ Nokogiri::HTML(stringlike.to_s)
18
+ end
19
+ end
20
+
21
+ def self.html_nokogiri_document(stringlike) #:nodoc:
22
+ return stringlike.dom if stringlike.respond_to?(:dom)
23
+
24
+ if Nokogiri::HTML::Document === stringlike
25
+ stringlike
26
+ elsif Nokogiri::XML::NodeSet === stringlike
27
+ stringlike
28
+ elsif StringIO === stringlike
29
+ Nokogiri::HTML(stringlike.string)
30
+ elsif stringlike.respond_to?(:body)
31
+ Nokogiri::HTML(stringlike.body.to_s)
32
+ else
33
+ Nokogiri::HTML(stringlike.to_s)
34
+ end
35
+ end
36
+
37
+ def self.xml_nokogiri_document(stringlike) #:nodoc:
38
+ return stringlike.dom if stringlike.respond_to?(:dom)
39
+
40
+ if Nokogiri::HTML::Document === stringlike
41
+ stringlike
42
+ elsif Nokogiri::XML::NodeSet === stringlike
43
+ stringlike
44
+ elsif StringIO === stringlike
45
+ Nokogiri::XML(stringlike.string)
46
+ elsif stringlike.respond_to?(:body)
47
+ Nokogiri::XML(stringlike.body.to_s)
48
+ else
49
+ Nokogiri::XML(stringlike.to_s)
50
+ end
51
+ end
52
+
53
+ def self.define_dom_method(object, dom) #:nodoc:
54
+ object.meta_class.send(:define_method, :dom) do
55
+ dom
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+
62
+ module Nokogiri #:nodoc:
63
+ module CSS #:nodoc:
64
+ class XPathVisitor #:nodoc:
65
+
66
+ def visit_pseudo_class_text(node) #:nodoc:
67
+ "@type='text'"
68
+ end
69
+
70
+ def visit_pseudo_class_password(node) #:nodoc:
71
+ "@type='password'"
72
+ end
73
+
74
+ end
75
+ end
76
+ end