Added auto-waiting #contain and #have_selector matchers for Selenium

This commit is contained in:
Bryan Helmkamp 2008-12-02 21:55:09 -05:00
parent 0fb3ed6b11
commit 0888c683a3
4 changed files with 134 additions and 1 deletions

View File

@ -1,5 +1,5 @@
# Supports using the matchers in controller, helper, and view specs if you're
# using rspec-rails. Just add a require statement to spec/spec_helper.rb:
# using rspec-rails. Just add a require statement to spec/spec_helper.rb or env.rb:
#
# require 'webrat/rspec-rails'
#

View File

@ -81,6 +81,14 @@ module Webrat
@_result = Test::Unit::TestResult.new
end
def response
webrat_session.response
end
def wait_for(*args, &block)
webrat_session.wait_for(*args, &block)
end
end
end
end

View File

@ -0,0 +1,80 @@
module Webrat
module Selenium
module Matchers
class HaveSelector
def initialize(expected)
@expected = expected
end
def matches?(response)
response.session.wait_for do
response.selenium.is_element_present("css=#{@expected}")
end
end
# ==== Returns
# String:: The failure message.
def failure_message
"expected following text to match selector #{@expected}:\n#{@document}"
end
# ==== Returns
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected following text to not match selector #{@expected}:\n#{@document}"
end
end
def have_selector(content)
HaveSelector.new(content)
end
class HasContent #:nodoc:
def initialize(content)
@content = content
end
def matches?(response)
if @content.is_a?(Regexp)
text_finder = "regexp:#{@content.source}"
else
text_finder = @content
end
response.session.wait_for do
response.selenium.is_text_present(text_finder)
end
end
# ==== Returns
# String:: The failure message.
def failure_message
"expected the following element's content to #{content_message}:\n#{@element}"
end
# ==== Returns
# String:: The failure message to be displayed in negative matches.
def negative_failure_message
"expected the following element's content to not #{content_message}:\n#{@element}"
end
def content_message
case @content
when String
"include \"#{@content}\""
when Regexp
"match #{@content.inspect}"
end
end
end
# Matches the contents of an HTML document with
# whatever string is supplied
def contain(content)
HasContent.new(content)
end
end
end
end

View File

@ -1,4 +1,21 @@
module Webrat
class TimeoutError < WebratError
end
class SeleniumResponse
attr_reader :body
attr_reader :session
def initialize(session, body)
@session = session
@body = body
end
def selenium
session.selenium
end
end
class SeleniumSession
def initialize(*args) # :nodoc:
@ -18,6 +35,10 @@ module Webrat
webrat_deprecate :fills_in, :fill_in
def response
SeleniumResponse.new(self, response_body)
end
def response_body #:nodoc:
selenium.get_html_source
end
@ -100,6 +121,30 @@ module Webrat
selenium.key_up(locator, key_code)
end
def wait_for(params={})
timeout = params[:timeout] || 5
message = params[:message] || "Timeout exceeded"
begin_time = Time.now
while (Time.now - begin_time) < timeout
value = nil
begin
value = yield
rescue ::Spec::Expectations::ExpectationNotMetError, ::Selenium::CommandError, Webrat::WebratError
value = nil
end
return value if value
sleep 0.25
end
raise Webrat::TimeoutError.new(message + " (after #{timeout} sec)")
true
end
def selenium
return $browser if $browser
setup