futuresinc-webrat 0.4.4.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +333 -0
- data/MIT-LICENSE.txt +19 -0
- data/README.rdoc +85 -0
- data/Rakefile +156 -0
- data/install.rb +1 -0
- data/lib/webrat/core/configuration.rb +98 -0
- data/lib/webrat/core/elements/area.rb +31 -0
- data/lib/webrat/core/elements/element.rb +33 -0
- data/lib/webrat/core/elements/field.rb +403 -0
- data/lib/webrat/core/elements/form.rb +103 -0
- data/lib/webrat/core/elements/label.rb +31 -0
- data/lib/webrat/core/elements/link.rb +92 -0
- data/lib/webrat/core/elements/select_option.rb +35 -0
- data/lib/webrat/core/locators/area_locator.rb +38 -0
- data/lib/webrat/core/locators/button_locator.rb +54 -0
- data/lib/webrat/core/locators/field_by_id_locator.rb +37 -0
- data/lib/webrat/core/locators/field_labeled_locator.rb +56 -0
- data/lib/webrat/core/locators/field_locator.rb +25 -0
- data/lib/webrat/core/locators/field_named_locator.rb +41 -0
- data/lib/webrat/core/locators/form_locator.rb +19 -0
- data/lib/webrat/core/locators/label_locator.rb +34 -0
- data/lib/webrat/core/locators/link_locator.rb +66 -0
- data/lib/webrat/core/locators/locator.rb +20 -0
- data/lib/webrat/core/locators/select_option_locator.rb +59 -0
- data/lib/webrat/core/locators.rb +20 -0
- data/lib/webrat/core/logging.rb +21 -0
- data/lib/webrat/core/matchers/have_content.rb +73 -0
- data/lib/webrat/core/matchers/have_selector.rb +74 -0
- data/lib/webrat/core/matchers/have_tag.rb +21 -0
- data/lib/webrat/core/matchers/have_xpath.rb +147 -0
- data/lib/webrat/core/matchers.rb +4 -0
- data/lib/webrat/core/methods.rb +61 -0
- data/lib/webrat/core/mime.rb +29 -0
- data/lib/webrat/core/save_and_open_page.rb +50 -0
- data/lib/webrat/core/scope.rb +350 -0
- data/lib/webrat/core/session.rb +281 -0
- data/lib/webrat/core/xml/hpricot.rb +19 -0
- data/lib/webrat/core/xml/nokogiri.rb +76 -0
- data/lib/webrat/core/xml/rexml.rb +24 -0
- data/lib/webrat/core/xml.rb +115 -0
- data/lib/webrat/core.rb +14 -0
- data/lib/webrat/core_extensions/blank.rb +58 -0
- data/lib/webrat/core_extensions/deprecate.rb +8 -0
- data/lib/webrat/core_extensions/detect_mapped.rb +12 -0
- data/lib/webrat/core_extensions/meta_class.rb +6 -0
- data/lib/webrat/core_extensions/nil_to_param.rb +5 -0
- data/lib/webrat/core_extensions/tcp_socket.rb +27 -0
- data/lib/webrat/mechanize.rb +74 -0
- data/lib/webrat/merb.rb +9 -0
- data/lib/webrat/merb_session.rb +65 -0
- data/lib/webrat/rack.rb +24 -0
- data/lib/webrat/rails.rb +105 -0
- data/lib/webrat/rspec-rails.rb +13 -0
- data/lib/webrat/selenium/application_server.rb +71 -0
- data/lib/webrat/selenium/location_strategy_javascript/button.js +12 -0
- data/lib/webrat/selenium/location_strategy_javascript/label.js +16 -0
- data/lib/webrat/selenium/location_strategy_javascript/webrat.js +5 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratlink.js +9 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js +15 -0
- data/lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js +5 -0
- data/lib/webrat/selenium/matchers/have_content.rb +66 -0
- data/lib/webrat/selenium/matchers/have_selector.rb +49 -0
- data/lib/webrat/selenium/matchers/have_tag.rb +72 -0
- data/lib/webrat/selenium/matchers/have_xpath.rb +45 -0
- data/lib/webrat/selenium/matchers.rb +4 -0
- data/lib/webrat/selenium/merb_application_server.rb +48 -0
- data/lib/webrat/selenium/rails_application_server.rb +42 -0
- data/lib/webrat/selenium/selenium_extensions.js +6 -0
- data/lib/webrat/selenium/selenium_rc_server.rb +80 -0
- data/lib/webrat/selenium/selenium_session.rb +241 -0
- data/lib/webrat/selenium/sinatra_application_server.rb +35 -0
- data/lib/webrat/selenium.rb +80 -0
- data/lib/webrat/sinatra.rb +44 -0
- data/lib/webrat.rb +34 -0
- data/vendor/selenium-server.jar +0 -0
- metadata +147 -0
@@ -0,0 +1,281 @@
|
|
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
|
+
else
|
30
|
+
raise WebratError.new(<<-STR)
|
31
|
+
Unknown Webrat mode: #{Webrat.configuration.mode.inspect}
|
32
|
+
|
33
|
+
Please ensure you have a Webrat configuration block that specifies a mode
|
34
|
+
in your test_helper.rb, spec_helper.rb, or env.rb (for Cucumber).
|
35
|
+
|
36
|
+
This configure block supercedes the need to require "webrat/<framework>".
|
37
|
+
|
38
|
+
For example:
|
39
|
+
|
40
|
+
Webrat.configure do |config|
|
41
|
+
config.mode = :rails
|
42
|
+
end
|
43
|
+
STR
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Session
|
48
|
+
extend Forwardable
|
49
|
+
include Logging
|
50
|
+
include SaveAndOpenPage
|
51
|
+
attr_reader :current_url
|
52
|
+
attr_reader :elements
|
53
|
+
|
54
|
+
def initialize(context = nil) #:nodoc:
|
55
|
+
@http_method = :get
|
56
|
+
@data = {}
|
57
|
+
@default_headers = {}
|
58
|
+
@custom_headers = {}
|
59
|
+
@context = context
|
60
|
+
|
61
|
+
reset
|
62
|
+
end
|
63
|
+
|
64
|
+
def current_dom #:nodoc:
|
65
|
+
current_scope.dom
|
66
|
+
end
|
67
|
+
|
68
|
+
# For backwards compatibility -- removing in 1.0
|
69
|
+
def current_page #:nodoc:
|
70
|
+
page = OpenStruct.new
|
71
|
+
page.url = @current_url
|
72
|
+
page.http_method = @http_method
|
73
|
+
page.data = @data
|
74
|
+
page
|
75
|
+
end
|
76
|
+
|
77
|
+
def doc_root #:nodoc:
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def header(key, value)
|
82
|
+
@custom_headers[key] = value
|
83
|
+
end
|
84
|
+
|
85
|
+
def http_accept(mime_type)
|
86
|
+
header('Accept', Webrat::MIME.mime_type(mime_type))
|
87
|
+
end
|
88
|
+
|
89
|
+
def basic_auth(user, pass)
|
90
|
+
encoded_login = ["#{user}:#{pass}"].pack("m*")
|
91
|
+
header('HTTP_AUTHORIZATION', "Basic #{encoded_login}")
|
92
|
+
end
|
93
|
+
|
94
|
+
def headers #:nodoc:
|
95
|
+
@default_headers.dup.merge(@custom_headers.dup)
|
96
|
+
end
|
97
|
+
|
98
|
+
def request_page(url, http_method, data) #:nodoc:
|
99
|
+
h = headers
|
100
|
+
h['HTTP_REFERER'] = @current_url if @current_url
|
101
|
+
|
102
|
+
debug_log "REQUESTING PAGE: #{http_method.to_s.upcase} #{url} with #{data.inspect} and HTTP headers #{h.inspect}"
|
103
|
+
if h.empty?
|
104
|
+
send "#{http_method}", url, data || {}
|
105
|
+
else
|
106
|
+
send "#{http_method}", url, data || {}, h
|
107
|
+
end
|
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 == 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_by_xpath
|
257
|
+
def_delegators :current_scope, :field_with_id
|
258
|
+
def_delegators :current_scope, :select_option
|
259
|
+
|
260
|
+
private
|
261
|
+
|
262
|
+
def response_location
|
263
|
+
response.headers["Location"]
|
264
|
+
end
|
265
|
+
|
266
|
+
def current_host
|
267
|
+
URI.parse(current_url).host || "www.example.com"
|
268
|
+
end
|
269
|
+
|
270
|
+
def response_location_host
|
271
|
+
URI.parse(response_location).host || "www.example.com"
|
272
|
+
end
|
273
|
+
|
274
|
+
def reset
|
275
|
+
@elements = {}
|
276
|
+
@_scopes = nil
|
277
|
+
@_page_scope = nil
|
278
|
+
end
|
279
|
+
|
280
|
+
end
|
281
|
+
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
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Webrat
|
2
|
+
|
3
|
+
def self.rexml_document(stringlike)
|
4
|
+
stringlike = stringlike.body.to_s if stringlike.respond_to?(:body)
|
5
|
+
|
6
|
+
case stringlike
|
7
|
+
when REXML::Document
|
8
|
+
stringlike.root
|
9
|
+
when REXML::Node, Array
|
10
|
+
stringlike
|
11
|
+
else
|
12
|
+
begin
|
13
|
+
REXML::Document.new(stringlike.to_s).root
|
14
|
+
rescue REXML::ParseException => e
|
15
|
+
if e.message.include?("second root element")
|
16
|
+
REXML::Document.new("<fake-root-element>#{stringlike}</fake-root-element>").root
|
17
|
+
else
|
18
|
+
raise e
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
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
|
data/lib/webrat/core.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "webrat/core/configuration"
|
2
|
+
require "webrat/core/xml"
|
3
|
+
require "webrat/core/xml/nokogiri"
|
4
|
+
require "webrat/core/logging"
|
5
|
+
require "webrat/core/elements/form"
|
6
|
+
require "webrat/core/scope"
|
7
|
+
require "webrat/core/elements/link"
|
8
|
+
require "webrat/core/elements/area"
|
9
|
+
require "webrat/core/elements/label"
|
10
|
+
require "webrat/core/elements/select_option"
|
11
|
+
require "webrat/core/session"
|
12
|
+
require "webrat/core/methods"
|
13
|
+
require "webrat/core/matchers"
|
14
|
+
require "webrat/core/save_and_open_page"
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class Object #:nodoc:
|
2
|
+
# An object is blank if it's false, empty, or a whitespace string.
|
3
|
+
# For example, "", " ", +nil+, [], and {} are blank.
|
4
|
+
#
|
5
|
+
# This simplifies
|
6
|
+
#
|
7
|
+
# if !address.nil? && !address.empty?
|
8
|
+
#
|
9
|
+
# to
|
10
|
+
#
|
11
|
+
# if !address.blank?
|
12
|
+
def blank?
|
13
|
+
respond_to?(:empty?) ? empty? : !self
|
14
|
+
end
|
15
|
+
|
16
|
+
# An object is present if it's not blank.
|
17
|
+
def present?
|
18
|
+
!blank?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class NilClass #:nodoc:
|
23
|
+
def blank?
|
24
|
+
true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class FalseClass #:nodoc:
|
29
|
+
def blank?
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class TrueClass #:nodoc:
|
35
|
+
def blank?
|
36
|
+
false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Array #:nodoc:
|
41
|
+
alias_method :blank?, :empty?
|
42
|
+
end
|
43
|
+
|
44
|
+
class Hash #:nodoc:
|
45
|
+
alias_method :blank?, :empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
class String #:nodoc:
|
49
|
+
def blank?
|
50
|
+
self !~ /\S/
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class Numeric #:nodoc:
|
55
|
+
def blank?
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class TCPSocket
|
2
|
+
|
3
|
+
def self.wait_for_service_with_timeout(options)
|
4
|
+
start_time = Time.now
|
5
|
+
|
6
|
+
until listening_service?(options)
|
7
|
+
verbose_wait
|
8
|
+
|
9
|
+
if options[:timeout] && (Time.now > start_time + options[:timeout])
|
10
|
+
raise SocketError.new("Socket did not open within #{options[:timeout]} seconds")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.wait_for_service_termination_with_timeout(options)
|
16
|
+
start_time = Time.now
|
17
|
+
|
18
|
+
while listening_service?(options)
|
19
|
+
verbose_wait
|
20
|
+
|
21
|
+
if options[:timeout] && (Time.now > start_time + options[:timeout])
|
22
|
+
raise SocketError.new("Socket did not terminate within #{options[:timeout]} seconds")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|