brynary-webrat 0.3.2.1 → 0.3.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +14 -5
- data/README.rdoc +1 -1
- data/lib/webrat/core/elements/element.rb +4 -0
- data/lib/webrat/core/elements/field.rb +3 -3
- data/lib/webrat/core/elements/link.rb +0 -4
- data/lib/webrat/core/locators/link_locator.rb +1 -1
- data/lib/webrat/core/methods.rb +12 -6
- data/lib/webrat/core/save_and_open_page.rb +50 -0
- data/lib/webrat/core/scope.rb +14 -2
- data/lib/webrat/core/session.rb +16 -39
- data/lib/webrat/core/xml/nokogiri.rb +32 -0
- data/lib/webrat/core/xml.rb +16 -0
- data/lib/webrat/core.rb +1 -0
- data/lib/webrat/rails.rb +14 -6
- data/lib/webrat/rspec-rails.rb +1 -1
- data/lib/webrat/selenium/matchers.rb +108 -0
- data/lib/webrat/selenium/selenium_session.rb +97 -53
- data/lib/webrat/selenium.rb +55 -7
- data/lib/webrat.rb +3 -1
- metadata +4 -2
data/History.txt
CHANGED
@@ -1,17 +1,26 @@
|
|
1
|
-
== Trunk
|
1
|
+
== Trunk (Git)
|
2
2
|
|
3
|
-
|
3
|
+
* _IMPORTANT_ Breaking change:
|
4
|
+
|
5
|
+
* Removed init.rb auto-require of webrat/rails
|
6
|
+
* Removed auto-require of webrat/rails when requiring webrat when RAILS_ENV is
|
7
|
+
defined
|
8
|
+
|
9
|
+
In your env.rb file, ensure you have:
|
4
10
|
|
5
|
-
|
6
|
-
ad8956070788cf3fa0f2ea5cbcb33867028c8605
|
11
|
+
require "webrat/rails"
|
7
12
|
|
8
13
|
* Major enhancements
|
9
14
|
|
10
|
-
* Use Hpricot and REXML when not parsing with Nokogiri (on JRuby, for example)
|
11
15
|
* Added select_time, select_date, and select_datetime to API. [#36] (Ben Mabey)
|
16
|
+
* Use Hpricot and REXML when not parsing with Nokogiri (on JRuby, for example)
|
12
17
|
|
13
18
|
* Minor enhancements
|
14
19
|
|
20
|
+
* Better inspect output for Webrat elements
|
21
|
+
* Detect if the document is XML or HTML using the Content-Type when in Rails mode
|
22
|
+
* Expose #selenium method for direct access to Selenium client
|
23
|
+
* Check nokogiri gem version before requiring nokogiri
|
15
24
|
* Include the Selenium server jar file in the gem (Bryan Helmkamp, Ben Schwarz)
|
16
25
|
* Added key_down, key_up and fire_event to Selenium session (Fernando Garcia)
|
17
26
|
* Fix outputing README during Rails plugin install (Fernando Garcia)
|
data/README.rdoc
CHANGED
@@ -16,7 +16,7 @@ web application.
|
|
16
16
|
* Browser Simulator for expressive, high level acceptance testing without the
|
17
17
|
performance hit and browser dependency of Selenium or Watir (See Webrat::Session)
|
18
18
|
* Use the same API for Browser Simulator and real Selenium tests using
|
19
|
-
Webrat::
|
19
|
+
Webrat::Selenium when necessary (eg. for testing AJAX interactions)
|
20
20
|
* Supports multiple Ruby web frameworks: Rails, Merb and Sinatra
|
21
21
|
* Supports popular test frameworks: RSpec, Cucumber, Test::Unit and Shoulda
|
22
22
|
* Webrat::Matchers API for verifying rendered HTML using CSS, XPath, etc.
|
@@ -138,7 +138,7 @@ module Webrat
|
|
138
138
|
end
|
139
139
|
|
140
140
|
unless id.blank?
|
141
|
-
@label_elements += Webrat::XML.
|
141
|
+
@label_elements += Webrat::XML.xpath_search(form.element, ".//label[@for = '#{id}']")
|
142
142
|
end
|
143
143
|
|
144
144
|
@label_elements
|
@@ -373,8 +373,8 @@ module Webrat
|
|
373
373
|
protected
|
374
374
|
|
375
375
|
def default_value
|
376
|
-
selected_options = Webrat::XML.
|
377
|
-
selected_options = Webrat::XML.
|
376
|
+
selected_options = Webrat::XML.xpath_search(@element, ".//option[@selected = 'selected']")
|
377
|
+
selected_options = Webrat::XML.xpath_search(@element, ".//option[position() = 1]") if selected_options.empty?
|
378
378
|
|
379
379
|
selected_options.map do |option|
|
380
380
|
return "" if option.nil?
|
data/lib/webrat/core/methods.rb
CHANGED
@@ -7,14 +7,18 @@ module Webrat
|
|
7
7
|
def #{meth}(*args, &blk)
|
8
8
|
webrat_session.#{meth}(*args, &blk)
|
9
9
|
end
|
10
|
-
|
11
|
-
def webrat_session
|
12
|
-
@_webrat_session ||= ::Webrat.session_class.new(self)
|
13
|
-
end
|
14
10
|
RUBY
|
15
11
|
end
|
16
12
|
end
|
17
13
|
|
14
|
+
def webrat
|
15
|
+
webrat_session
|
16
|
+
end
|
17
|
+
|
18
|
+
def webrat_session
|
19
|
+
@_webrat_session ||= ::Webrat.session_class.new(self)
|
20
|
+
end
|
21
|
+
|
18
22
|
# all of these methods delegate to the @session, which should
|
19
23
|
# be created transparently.
|
20
24
|
#
|
@@ -45,9 +49,11 @@ module Webrat
|
|
45
49
|
:request_page, :current_dom,
|
46
50
|
:selects_date, :selects_time, :selects_datetime,
|
47
51
|
:select_date, :select_time, :select_datetime,
|
48
|
-
:wait_for_page_to_load,
|
49
52
|
:field_by_xpath,
|
50
|
-
:field_with_id
|
53
|
+
:field_with_id,
|
54
|
+
:selenium,
|
55
|
+
:simulate, :automate
|
56
|
+
|
51
57
|
|
52
58
|
|
53
59
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Webrat
|
2
|
+
module SaveAndOpenPage
|
3
|
+
# Saves the page out to RAILS_ROOT/tmp/ and opens it in the default
|
4
|
+
# web browser if on OS X. Useful for debugging.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# save_and_open_page
|
8
|
+
def save_and_open_page
|
9
|
+
return unless File.exist?(saved_page_dir)
|
10
|
+
|
11
|
+
filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.html"
|
12
|
+
|
13
|
+
File.open(filename, "w") do |f|
|
14
|
+
f.write rewrite_css_and_image_references(response_body)
|
15
|
+
end
|
16
|
+
|
17
|
+
open_in_browser(filename)
|
18
|
+
end
|
19
|
+
|
20
|
+
def open_in_browser(path) # :nodoc
|
21
|
+
platform = ruby_platform
|
22
|
+
if platform =~ /cygwin/ || platform =~ /win32/
|
23
|
+
`rundll32 url.dll,FileProtocolHandler #{path.gsub("/", "\\\\")}`
|
24
|
+
elsif platform =~ /darwin/
|
25
|
+
`open #{path}`
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def rewrite_css_and_image_references(response_html) # :nodoc:
|
30
|
+
return response_html unless doc_root
|
31
|
+
response_html.gsub(/"\/(stylesheets|images)/, doc_root + '/\1')
|
32
|
+
end
|
33
|
+
|
34
|
+
def saved_page_dir #:nodoc:
|
35
|
+
File.expand_path(".")
|
36
|
+
end
|
37
|
+
|
38
|
+
def doc_root #:nodoc:
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
# accessor for testing
|
45
|
+
def ruby_platform
|
46
|
+
RUBY_PLATFORM
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
data/lib/webrat/core/scope.rb
CHANGED
@@ -279,13 +279,25 @@ module Webrat
|
|
279
279
|
|
280
280
|
def page_dom #:nodoc:
|
281
281
|
return @response.dom if @response.respond_to?(:dom)
|
282
|
-
|
282
|
+
|
283
|
+
if @session.xml_content_type?
|
284
|
+
dom = Webrat::XML.xml_document(@response_body)
|
285
|
+
else
|
286
|
+
dom = Webrat::XML.html_document(@response_body)
|
287
|
+
end
|
288
|
+
|
283
289
|
Webrat.define_dom_method(@response, dom)
|
284
290
|
return dom
|
285
291
|
end
|
286
292
|
|
287
293
|
def scoped_dom #:nodoc:
|
288
|
-
|
294
|
+
source = Webrat::XML.to_html(Webrat::XML.css_search(@scope.dom, @selector).first)
|
295
|
+
|
296
|
+
if @session.xml_content_type?
|
297
|
+
Webrat::XML.xml_document(source)
|
298
|
+
else
|
299
|
+
Webrat::XML.html_document(source)
|
300
|
+
end
|
289
301
|
end
|
290
302
|
|
291
303
|
def locate_field(field_locator, *field_types) #:nodoc:
|
data/lib/webrat/core/session.rb
CHANGED
@@ -2,6 +2,7 @@ require "forwardable"
|
|
2
2
|
require "ostruct"
|
3
3
|
|
4
4
|
require "webrat/core/mime"
|
5
|
+
require "webrat/core/save_and_open_page"
|
5
6
|
|
6
7
|
module Webrat
|
7
8
|
# A page load or form submission returned an unsuccessful response code (500-599)
|
@@ -30,6 +31,7 @@ module Webrat
|
|
30
31
|
class Session
|
31
32
|
extend Forwardable
|
32
33
|
include Logging
|
34
|
+
include SaveAndOpenPage
|
33
35
|
|
34
36
|
attr_reader :current_url
|
35
37
|
attr_reader :elements
|
@@ -43,23 +45,6 @@ module Webrat
|
|
43
45
|
|
44
46
|
reset
|
45
47
|
end
|
46
|
-
|
47
|
-
# Saves the page out to RAILS_ROOT/tmp/ and opens it in the default
|
48
|
-
# web browser if on OS X. Useful for debugging.
|
49
|
-
#
|
50
|
-
# Example:
|
51
|
-
# save_and_open_page
|
52
|
-
def save_and_open_page
|
53
|
-
return unless File.exist?(saved_page_dir)
|
54
|
-
|
55
|
-
filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.html"
|
56
|
-
|
57
|
-
File.open(filename, "w") do |f|
|
58
|
-
f.write rewrite_css_and_image_references(response_body)
|
59
|
-
end
|
60
|
-
|
61
|
-
open_in_browser(filename)
|
62
|
-
end
|
63
48
|
|
64
49
|
def current_dom #:nodoc:
|
65
50
|
current_scope.dom
|
@@ -78,10 +63,6 @@ module Webrat
|
|
78
63
|
nil
|
79
64
|
end
|
80
65
|
|
81
|
-
def saved_page_dir #:nodoc:
|
82
|
-
File.expand_path(".")
|
83
|
-
end
|
84
|
-
|
85
66
|
def header(key, value)
|
86
67
|
@custom_headers[key] = value
|
87
68
|
end
|
@@ -172,20 +153,6 @@ module Webrat
|
|
172
153
|
end
|
173
154
|
|
174
155
|
webrat_deprecate :visits, :visit
|
175
|
-
|
176
|
-
def open_in_browser(path) # :nodoc
|
177
|
-
platform = ruby_platform
|
178
|
-
if platform =~ /cygwin/ || platform =~ /win32/
|
179
|
-
`rundll32 url.dll,FileProtocolHandler #{path.gsub("/", "\\\\")}`
|
180
|
-
elsif platform =~ /darwin/
|
181
|
-
`open #{path}`
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
def rewrite_css_and_image_references(response_html) # :nodoc:
|
186
|
-
return response_html unless doc_root
|
187
|
-
response_html.gsub(/"\/(stylesheets|images)/, doc_root + '/\1')
|
188
|
-
end
|
189
156
|
|
190
157
|
# Subclasses can override this to show error messages without html
|
191
158
|
def formatted_error #:nodoc:
|
@@ -204,6 +171,20 @@ module Webrat
|
|
204
171
|
page_scope.dom
|
205
172
|
end
|
206
173
|
|
174
|
+
def xml_content_type?
|
175
|
+
false
|
176
|
+
end
|
177
|
+
|
178
|
+
def simulate
|
179
|
+
return if Webrat.configuration.mode == :selenium
|
180
|
+
yield
|
181
|
+
end
|
182
|
+
|
183
|
+
def automate
|
184
|
+
return unless Webrat.configuration.mode == :selenium
|
185
|
+
yield
|
186
|
+
end
|
187
|
+
|
207
188
|
def_delegators :current_scope, :fill_in, :fills_in
|
208
189
|
def_delegators :current_scope, :set_hidden_field
|
209
190
|
def_delegators :current_scope, :submit_form
|
@@ -233,9 +214,5 @@ module Webrat
|
|
233
214
|
@_page_scope = nil
|
234
215
|
end
|
235
216
|
|
236
|
-
# accessor for testing
|
237
|
-
def ruby_platform
|
238
|
-
RUBY_PLATFORM
|
239
|
-
end
|
240
217
|
end
|
241
218
|
end
|
@@ -18,6 +18,38 @@ module Webrat
|
|
18
18
|
end
|
19
19
|
end
|
20
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
|
+
|
21
53
|
def self.define_dom_method(object, dom) #:nodoc:
|
22
54
|
object.meta_class.send(:define_method, :dom) do
|
23
55
|
dom
|
data/lib/webrat/core/xml.rb
CHANGED
@@ -12,6 +12,22 @@ module Webrat #:nodoc:
|
|
12
12
|
Webrat.rexml_document(Webrat.hpricot_document(stringlike).to_html)
|
13
13
|
end
|
14
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
|
15
31
|
|
16
32
|
def self.to_html(element)
|
17
33
|
if Webrat.configuration.parse_with_nokogiri?
|
data/lib/webrat/core.rb
CHANGED
data/lib/webrat/rails.rb
CHANGED
@@ -36,6 +36,10 @@ module Webrat
|
|
36
36
|
response.code.to_i
|
37
37
|
end
|
38
38
|
|
39
|
+
def xml_content_type?
|
40
|
+
response.headers["Content-Type"].to_s =~ /xml/
|
41
|
+
end
|
42
|
+
|
39
43
|
protected
|
40
44
|
|
41
45
|
def integration_session
|
@@ -44,15 +48,18 @@ module Webrat
|
|
44
48
|
|
45
49
|
def do_request(http_method, url, data, headers) #:nodoc:
|
46
50
|
update_protocol(url)
|
47
|
-
|
51
|
+
url = normalize_url(url)
|
52
|
+
integration_session.request_via_redirect(http_method, url, data, headers)
|
48
53
|
end
|
49
54
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
+
# remove protocol, host and anchor
|
56
|
+
def normalize_url(href) #:nodoc:
|
57
|
+
uri = URI.parse(href)
|
58
|
+
normalized_url = uri.path
|
59
|
+
if uri.query
|
60
|
+
normalized_url += "?" + uri.query
|
55
61
|
end
|
62
|
+
normalized_url
|
56
63
|
end
|
57
64
|
|
58
65
|
def update_protocol(href) #:nodoc:
|
@@ -82,6 +89,7 @@ module ActionController #:nodoc:
|
|
82
89
|
|
83
90
|
IntegrationTest.class_eval do
|
84
91
|
include Webrat::Methods
|
92
|
+
include Webrat::Matchers
|
85
93
|
end
|
86
94
|
end
|
87
95
|
|
data/lib/webrat/rspec-rails.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Supports using the matchers in controller, helper, and view specs if you're
|
2
|
-
# using rspec-rails. Just add a require statement to spec/spec_helper.rb:
|
2
|
+
# using rspec-rails. Just add a require statement to spec/spec_helper.rb or env.rb:
|
3
3
|
#
|
4
4
|
# require 'webrat/rspec-rails'
|
5
5
|
#
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Webrat
|
2
|
+
module Selenium
|
3
|
+
module Matchers
|
4
|
+
|
5
|
+
class HaveXpath
|
6
|
+
def initialize(expected)
|
7
|
+
@expected = expected
|
8
|
+
end
|
9
|
+
|
10
|
+
def matches?(response)
|
11
|
+
response.session.wait_for do
|
12
|
+
response.selenium.is_element_present("xpath=#{@expected}")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# ==== Returns
|
17
|
+
# String:: The failure message.
|
18
|
+
def failure_message
|
19
|
+
"expected following text to match xpath #{@expected}:\n#{@document}"
|
20
|
+
end
|
21
|
+
|
22
|
+
# ==== Returns
|
23
|
+
# String:: The failure message to be displayed in negative matches.
|
24
|
+
def negative_failure_message
|
25
|
+
"expected following text to not match xpath #{@expected}:\n#{@document}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def have_xpath(xpath)
|
30
|
+
HaveXpath.new(xpath)
|
31
|
+
end
|
32
|
+
|
33
|
+
class HaveSelector
|
34
|
+
def initialize(expected)
|
35
|
+
@expected = expected
|
36
|
+
end
|
37
|
+
|
38
|
+
def matches?(response)
|
39
|
+
response.session.wait_for do
|
40
|
+
response.selenium.is_element_present("css=#{@expected}")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# ==== Returns
|
45
|
+
# String:: The failure message.
|
46
|
+
def failure_message
|
47
|
+
"expected following text to match selector #{@expected}:\n#{@document}"
|
48
|
+
end
|
49
|
+
|
50
|
+
# ==== Returns
|
51
|
+
# String:: The failure message to be displayed in negative matches.
|
52
|
+
def negative_failure_message
|
53
|
+
"expected following text to not match selector #{@expected}:\n#{@document}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def have_selector(content)
|
58
|
+
HaveSelector.new(content)
|
59
|
+
end
|
60
|
+
|
61
|
+
class HasContent #:nodoc:
|
62
|
+
def initialize(content)
|
63
|
+
@content = content
|
64
|
+
end
|
65
|
+
|
66
|
+
def matches?(response)
|
67
|
+
if @content.is_a?(Regexp)
|
68
|
+
text_finder = "regexp:#{@content.source}"
|
69
|
+
else
|
70
|
+
text_finder = @content
|
71
|
+
end
|
72
|
+
|
73
|
+
response.session.wait_for do
|
74
|
+
response.selenium.is_text_present(text_finder)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# ==== Returns
|
79
|
+
# String:: The failure message.
|
80
|
+
def failure_message
|
81
|
+
"expected the following element's content to #{content_message}:\n#{@element}"
|
82
|
+
end
|
83
|
+
|
84
|
+
# ==== Returns
|
85
|
+
# String:: The failure message to be displayed in negative matches.
|
86
|
+
def negative_failure_message
|
87
|
+
"expected the following element's content to not #{content_message}:\n#{@element}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def content_message
|
91
|
+
case @content
|
92
|
+
when String
|
93
|
+
"include \"#{@content}\""
|
94
|
+
when Regexp
|
95
|
+
"match #{@content.inspect}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Matches the contents of an HTML document with
|
101
|
+
# whatever string is supplied
|
102
|
+
def contain(content)
|
103
|
+
HasContent.new(content)
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -1,9 +1,34 @@
|
|
1
|
+
require "webrat/core/save_and_open_page"
|
2
|
+
|
1
3
|
module Webrat
|
4
|
+
class TimeoutError < WebratError
|
5
|
+
end
|
6
|
+
|
7
|
+
class SeleniumResponse
|
8
|
+
attr_reader :body
|
9
|
+
attr_reader :session
|
10
|
+
|
11
|
+
def initialize(session, body)
|
12
|
+
@session = session
|
13
|
+
@body = body
|
14
|
+
end
|
15
|
+
|
16
|
+
def selenium
|
17
|
+
session.selenium
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
2
21
|
class SeleniumSession
|
22
|
+
include Webrat::SaveAndOpenPage
|
3
23
|
|
4
24
|
def initialize(*args) # :nodoc:
|
5
|
-
|
6
|
-
|
25
|
+
end
|
26
|
+
|
27
|
+
def simulate
|
28
|
+
end
|
29
|
+
|
30
|
+
def automate
|
31
|
+
yield
|
7
32
|
end
|
8
33
|
|
9
34
|
def visit(url)
|
@@ -14,11 +39,16 @@ module Webrat
|
|
14
39
|
|
15
40
|
def fill_in(field_identifier, options)
|
16
41
|
locator = "webrat=#{Regexp.escape(field_identifier)}"
|
42
|
+
selenium.wait_for_element locator, 5
|
17
43
|
selenium.type(locator, "#{options[:with]}")
|
18
44
|
end
|
19
45
|
|
20
46
|
webrat_deprecate :fills_in, :fill_in
|
21
47
|
|
48
|
+
def response
|
49
|
+
SeleniumResponse.new(self, response_body)
|
50
|
+
end
|
51
|
+
|
22
52
|
def response_body #:nodoc:
|
23
53
|
selenium.get_html_source
|
24
54
|
end
|
@@ -26,57 +56,34 @@ module Webrat
|
|
26
56
|
def click_button(button_text_or_regexp = nil, options = {})
|
27
57
|
if button_text_or_regexp.is_a?(Hash) && options == {}
|
28
58
|
pattern, options = nil, button_text_or_regexp
|
29
|
-
|
59
|
+
elsif button_text_or_regexp
|
30
60
|
pattern = adjust_if_regexp(button_text_or_regexp)
|
31
61
|
end
|
32
62
|
pattern ||= '*'
|
33
|
-
|
34
|
-
|
63
|
+
locator = "button=#{pattern}"
|
64
|
+
|
65
|
+
selenium.wait_for_element locator, 5
|
66
|
+
selenium.click locator
|
35
67
|
end
|
36
68
|
|
37
69
|
webrat_deprecate :clicks_button, :click_button
|
38
70
|
|
39
71
|
def click_link(link_text_or_regexp, options = {})
|
40
72
|
pattern = adjust_if_regexp(link_text_or_regexp)
|
41
|
-
|
42
|
-
|
73
|
+
locator = "webratlink=#{pattern}"
|
74
|
+
selenium.wait_for_element locator, 5
|
75
|
+
selenium.click locator
|
43
76
|
end
|
44
77
|
|
45
78
|
webrat_deprecate :clicks_link, :click_link
|
46
79
|
|
47
80
|
def click_link_within(selector, link_text, options = {})
|
48
|
-
|
49
|
-
|
81
|
+
locator = "webratlinkwithin=#{selector}|#{link_text}"
|
82
|
+
selenium.wait_for_element locator, 5
|
83
|
+
selenium.click locator
|
50
84
|
end
|
51
85
|
|
52
86
|
webrat_deprecate :clicks_link_within, :click_link_within
|
53
|
-
|
54
|
-
def wait_for_result(wait_type)
|
55
|
-
if wait_type == :ajax
|
56
|
-
wait_for_ajax
|
57
|
-
elsif wait_type == :effects
|
58
|
-
wait_for_effects
|
59
|
-
else
|
60
|
-
wait_for_page_to_load
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def wait_for_page_to_load(timeout = 15000)
|
65
|
-
selenium.wait_for_page_to_load(timeout)
|
66
|
-
end
|
67
|
-
|
68
|
-
def wait_for_ajax(timeout = 15000)
|
69
|
-
selenium.wait_for_condition "Ajax.activeRequestCount == 0", timeout
|
70
|
-
end
|
71
|
-
|
72
|
-
def wait_for_effects(timeout = 15000)
|
73
|
-
selenium.wait_for_condition "window.Effect.Queue.size() == 0", timeout
|
74
|
-
end
|
75
|
-
|
76
|
-
def wait_for_ajax_and_effects
|
77
|
-
wait_for_ajax
|
78
|
-
wait_for_effects
|
79
|
-
end
|
80
87
|
|
81
88
|
def select(option_text, options = {})
|
82
89
|
id_or_name_or_label = options[:from]
|
@@ -86,30 +93,28 @@ module Webrat
|
|
86
93
|
else
|
87
94
|
select_locator = "webratselectwithoption=#{option_text}"
|
88
95
|
end
|
96
|
+
|
97
|
+
selenium.wait_for_element select_locator, 5
|
89
98
|
selenium.select(select_locator, option_text)
|
90
99
|
end
|
91
100
|
|
92
101
|
webrat_deprecate :selects, :select
|
93
102
|
|
94
103
|
def choose(label_text)
|
95
|
-
|
104
|
+
locator = "webrat=#{label_text}"
|
105
|
+
selenium.wait_for_element locator, 5
|
106
|
+
selenium.click locator
|
96
107
|
end
|
97
108
|
|
98
109
|
webrat_deprecate :chooses, :choose
|
99
110
|
|
100
111
|
def check(label_text)
|
101
|
-
|
112
|
+
locator = "webrat=#{label_text}"
|
113
|
+
selenium.wait_for_element locator, 5
|
114
|
+
selenium.check locator
|
102
115
|
end
|
103
116
|
|
104
117
|
webrat_deprecate :checks, :check
|
105
|
-
|
106
|
-
def is_ordered(*args) #:nodoc:
|
107
|
-
selenium.is_ordered(*args)
|
108
|
-
end
|
109
|
-
|
110
|
-
def dragdrop(*args) #:nodoc:
|
111
|
-
selenium.dragdrop(*args)
|
112
|
-
end
|
113
118
|
|
114
119
|
def fire_event(field_identifier, event)
|
115
120
|
locator = "webrat=#{Regexp.escape(field_identifier)}"
|
@@ -126,12 +131,52 @@ module Webrat
|
|
126
131
|
selenium.key_up(locator, key_code)
|
127
132
|
end
|
128
133
|
|
129
|
-
def
|
134
|
+
def wait_for(params={})
|
135
|
+
timeout = params[:timeout] || 5
|
136
|
+
message = params[:message] || "Timeout exceeded"
|
137
|
+
|
138
|
+
begin_time = Time.now
|
139
|
+
|
140
|
+
while (Time.now - begin_time) < timeout
|
141
|
+
value = nil
|
142
|
+
|
143
|
+
begin
|
144
|
+
value = yield
|
145
|
+
rescue ::Spec::Expectations::ExpectationNotMetError, ::Selenium::CommandError, Webrat::WebratError
|
146
|
+
value = nil
|
147
|
+
end
|
148
|
+
|
149
|
+
return value if value
|
150
|
+
|
151
|
+
sleep 0.25
|
152
|
+
end
|
153
|
+
|
154
|
+
raise Webrat::TimeoutError.new(message + " (after #{timeout} sec)")
|
155
|
+
true
|
156
|
+
end
|
157
|
+
|
158
|
+
def selenium
|
130
159
|
return $browser if $browser
|
131
160
|
setup
|
132
161
|
$browser
|
133
162
|
end
|
134
163
|
|
164
|
+
webrat_deprecate :browser, :selenium
|
165
|
+
|
166
|
+
|
167
|
+
def save_and_open_screengrab
|
168
|
+
return unless File.exist?(saved_page_dir)
|
169
|
+
|
170
|
+
filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.png"
|
171
|
+
|
172
|
+
if $browser.chrome_backend?
|
173
|
+
$browser.capture_entire_page_screenshot(filename, '')
|
174
|
+
else
|
175
|
+
$browser.capture_screenshot(filename)
|
176
|
+
end
|
177
|
+
open_in_browser(filename)
|
178
|
+
end
|
179
|
+
|
135
180
|
protected
|
136
181
|
|
137
182
|
def setup #:nodoc:
|
@@ -140,15 +185,14 @@ module Webrat
|
|
140
185
|
Webrat.start_app_server
|
141
186
|
end
|
142
187
|
|
143
|
-
|
144
188
|
$browser = ::Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://0.0.0.0:3001")
|
145
189
|
$browser.set_speed(0)
|
146
190
|
$browser.start
|
147
191
|
teardown_at_exit
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
browser
|
192
|
+
|
193
|
+
extend_selenium
|
194
|
+
define_location_strategies
|
195
|
+
$browser.window_maximize
|
152
196
|
end
|
153
197
|
|
154
198
|
def teardown_at_exit #:nodoc:
|
@@ -165,7 +209,7 @@ module Webrat
|
|
165
209
|
if text_or_regexp.is_a?(Regexp)
|
166
210
|
"evalregex:#{text_or_regexp.inspect}"
|
167
211
|
else
|
168
|
-
text_or_regexp
|
212
|
+
"evalregex:/#{text_or_regexp}/"
|
169
213
|
end
|
170
214
|
end
|
171
215
|
|
data/lib/webrat/selenium.rb
CHANGED
@@ -2,6 +2,7 @@ require "webrat"
|
|
2
2
|
gem "selenium-client", ">=1.2.9"
|
3
3
|
require "selenium/client"
|
4
4
|
require "webrat/selenium/selenium_session"
|
5
|
+
require "webrat/selenium/matchers"
|
5
6
|
|
6
7
|
Webrat.configuration.mode = :selenium
|
7
8
|
|
@@ -36,24 +37,71 @@ module Webrat
|
|
36
37
|
system "mongrel_rails stop -c #{RAILS_ROOT} --pid #{pid_file}"
|
37
38
|
end
|
38
39
|
|
39
|
-
|
40
|
+
# To use Webrat's Selenium support, you'll need the selenium-client gem installed.
|
41
|
+
# Activate it with (for example, in your <tt>env.rb</tt>):
|
42
|
+
#
|
43
|
+
# require "webrat/selenium"
|
44
|
+
#
|
45
|
+
# Then, if you're using Cucumber, configure it to use a
|
46
|
+
# <tt>Webrat::Selenium::Rails::World</tt> as the scenario context by adding
|
47
|
+
# the following to <tt>env.rb</tt>:
|
48
|
+
#
|
49
|
+
# World do
|
50
|
+
# Webrat::Selenium::Rails::World.new
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# == Dropping down to the selenium-client API
|
54
|
+
#
|
55
|
+
# If you ever need to do something with Selenium not provided in the Webrat API,
|
56
|
+
# you can always drop down to the selenium-client API using the <tt>selenium</tt> method.
|
57
|
+
# For example:
|
58
|
+
#
|
59
|
+
# When "I drag the photo to the left" do
|
60
|
+
# selenium.dragdrop("id=photo_123", "+350, 0")
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# == Auto-starting of the mongrel and java server
|
64
|
+
#
|
65
|
+
# Webrat will automatically start the Selenium Java server process and an instance
|
66
|
+
# of Mongrel when a test is run. The Mongrel will run in the "selenium" environment
|
67
|
+
# instead of "test", so ensure you've got that defined, and will run on port 3001.
|
68
|
+
#
|
69
|
+
# == Waiting
|
70
|
+
#
|
71
|
+
# In order to make writing Selenium tests as easy as possible, Webrat will automatically
|
72
|
+
# wait for the correct elements to exist on the page when trying to manipulate them
|
73
|
+
# with methods like <tt>fill_in</tt>, etc. In general, this means you should be able to write
|
74
|
+
# your Webrat::Selenium tests ignoring the concurrency issues that can plague in-browser
|
75
|
+
# testing, so long as you're using the Webrat API.
|
76
|
+
module Selenium
|
77
|
+
|
40
78
|
module Rails #:nodoc:
|
41
79
|
class World < ::ActionController::IntegrationTest
|
80
|
+
include Webrat::Selenium::Matchers
|
42
81
|
|
43
82
|
def initialize #:nodoc:
|
44
83
|
@_result = Test::Unit::TestResult.new
|
45
84
|
end
|
46
85
|
|
86
|
+
def response
|
87
|
+
webrat_session.response
|
88
|
+
end
|
89
|
+
|
90
|
+
def wait_for(*args, &block)
|
91
|
+
webrat_session.wait_for(*args, &block)
|
92
|
+
end
|
93
|
+
|
94
|
+
def save_and_open_screengrab
|
95
|
+
webrat_session.save_and_open_screengrab
|
96
|
+
end
|
47
97
|
end
|
48
98
|
end
|
49
99
|
end
|
50
100
|
|
51
101
|
end
|
52
102
|
|
53
|
-
module
|
54
|
-
|
55
|
-
|
56
|
-
include Webrat::Methods
|
57
|
-
end
|
103
|
+
module ActionController #:nodoc:
|
104
|
+
IntegrationTest.class_eval do
|
105
|
+
include Webrat::Methods
|
58
106
|
end
|
59
|
-
end
|
107
|
+
end
|
data/lib/webrat.rb
CHANGED
@@ -7,9 +7,11 @@ module Webrat
|
|
7
7
|
class WebratError < StandardError
|
8
8
|
end
|
9
9
|
|
10
|
-
VERSION = '0.3.2.
|
10
|
+
VERSION = '0.3.2.2'
|
11
11
|
|
12
12
|
def self.require_xml
|
13
|
+
gem "nokogiri", ">= 1.0.6"
|
14
|
+
|
13
15
|
if on_java?
|
14
16
|
# We need Nokogiri's CSS to XPath support, even if using REXML and Hpricot for parsing and searching
|
15
17
|
require "nokogiri/css"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: brynary-webrat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.2.
|
4
|
+
version: 0.3.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan Helmkamp
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-12-25 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -69,6 +69,7 @@ files:
|
|
69
69
|
- lib/webrat/core/matchers.rb
|
70
70
|
- lib/webrat/core/methods.rb
|
71
71
|
- lib/webrat/core/mime.rb
|
72
|
+
- lib/webrat/core/save_and_open_page.rb
|
72
73
|
- lib/webrat/core/scope.rb
|
73
74
|
- lib/webrat/core/session.rb
|
74
75
|
- lib/webrat/core/xml
|
@@ -99,6 +100,7 @@ files:
|
|
99
100
|
- lib/webrat/selenium/location_strategy_javascript/webratlink.js
|
100
101
|
- lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js
|
101
102
|
- lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js
|
103
|
+
- lib/webrat/selenium/matchers.rb
|
102
104
|
- lib/webrat/selenium/selenium_extensions.js
|
103
105
|
- lib/webrat/selenium/selenium_session.rb
|
104
106
|
- lib/webrat/selenium.rb
|