Merge branch 'master' of git@github.com:jrun/webrat

This commit is contained in:
Jeremy Burks 2008-10-27 21:29:28 -05:00
commit d03ed0238c
44 changed files with 451 additions and 324 deletions

View File

@ -11,10 +11,12 @@
* Minor enhancements * Minor enhancements
* Add #http_accept for including MIME type HTTP "Accept" headers (Ryan Briones)
* Add #header to support inclusion of custom HTTP headers (Ryan Briones)
* Consider response codes 200-499 as successful enough to not raise a Webrat error (David Leal)
* Add #field_labeled for looking up form fields by label (David Chelimsky)
* Add Webrat.root method for cross-framework support (Krzysztof Zylawy) * Add Webrat.root method for cross-framework support (Krzysztof Zylawy)
* Add #select_date for quickly filling out Rails-style date fields (Alex Lang) * Add support for clicking areas of an image map (Alex Lang)
* Support selecting options by their values (Alex Lang)
* Support for clicking areas of an image map (Alex Lang)
* Add should_see and should_not_see for verifying HTML response bodys * Add should_see and should_not_see for verifying HTML response bodys
* Support relative links, including href="?foo=bar" (Kyle Hargraves) * Support relative links, including href="?foo=bar" (Kyle Hargraves)
* Separated Rails-specific code from the Webrat core to make it easier to use Webrat with other environments * Separated Rails-specific code from the Webrat core to make it easier to use Webrat with other environments

View File

@ -40,6 +40,7 @@ lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.js
lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js lib/webrat/selenium/location_strategy_javascript/webratselectwithoption.js
lib/webrat/selenium/selenium_session.rb lib/webrat/selenium/selenium_session.rb
lib/webrat/sinatra/sinatra_session.rb lib/webrat/sinatra/sinatra_session.rb
manifest.diff
mechanize_spike.rb mechanize_spike.rb
selenium_spike.rb selenium_spike.rb
spec/api/attaches_file_spec.rb spec/api/attaches_file_spec.rb
@ -61,12 +62,13 @@ spec/api/within_spec.rb
spec/fakes/test_session.rb spec/fakes/test_session.rb
spec/integration/rails_spec.rb spec/integration/rails_spec.rb
spec/rcov.opts spec/rcov.opts
spec/spec.opts
spec/spec_helper.rb spec/spec_helper.rb
spec/webrat/core/logging_spec.rb spec/webrat/core/logging_spec.rb
spec/webrat/core/session_spec.rb spec/webrat/core/session_spec.rb
spec/webrat/mechanize/mechanize_session_spec.rb spec/webrat/mechanize/mechanize_session_spec.rb
spec/webrat/merb/helper.rb spec/webrat/merb/helper.rb
spec/webrat/merb/indifferent_access_spec.rb
spec/webrat/merb/session_spec.rb
spec/webrat/rails/helper.rb spec/webrat/rails/helper.rb
spec/webrat/rails/rails_session_spec.rb spec/webrat/rails/rails_session_spec.rb
webrat.gemspec webrat.gemspec

View File

@ -24,11 +24,11 @@ Initial development was sponsored by [EastMedia](http://www.eastmedia.com).
=== Synopsis === Synopsis
def test_sign_up def test_sign_up
visits "/" visit "/"
clicks_link "Sign up" click_link "Sign up"
fills_in "Email", :with => "good@example.com" fill_in "Email", :with => "good@example.com"
selects "Free account" select "Free account"
clicks_button "Register" click_button "Register"
... ...
end end
@ -83,7 +83,7 @@ You could also unpack the gem into vendor/plugins.
- Rails >= 1.2.6 - Rails >= 1.2.6
- Hpricot >= 0.6 - Hpricot >= 0.6
- Rails integration tests in Test::Unit _or_ - Rails integration tests in Test::Unit _or_
- RSpec stories (using an RSpec version >= revision 2997) - Cucumber
=== Authors === Authors

View File

@ -35,36 +35,25 @@ def remove_task(task_name)
Rake.application.remove_task(task_name) Rake.application.remove_task(task_name)
end end
def set_file_list
if ENV['TEST_MODE'] == "merb"
list = FileList['spec/**/*_spec.rb']
list = list.find_all do |file| !file.match("rails") end
return list
else
return FileList['spec/**/*_spec.rb']
end
end
remove_task "test" remove_task "test"
remove_task "test_deps" remove_task "test_deps"
desc "Run all specs in spec directory" desc "Run API and Core specs"
Spec::Rake::SpecTask.new do |t| Spec::Rake::SpecTask.new do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""] t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = set_file_list t.spec_files = FileList['spec/**/*_spec.rb']
end end
desc "Run all specs in spec directory with RCov" desc "Run all specs in spec directory with RCov"
Spec::Rake::SpecTask.new(:rcov) do |t| Spec::Rake::SpecTask.new(:rcov) do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""] t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = set_file_list t.spec_files = FileList['spec/**/*_spec.rb']
t.rcov = true t.rcov = true
t.rcov_opts = lambda do t.rcov_opts = lambda do
IO.readlines(File.dirname(__FILE__) + "/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten IO.readlines(File.dirname(__FILE__) + "/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
end end
end end
require 'spec/rake/verify_rcov' require 'spec/rake/verify_rcov'
RCov::VerifyTask.new(:verify_rcov => :rcov) do |t| RCov::VerifyTask.new(:verify_rcov => :rcov) do |t|
t.threshold = 96.2 # Make sure you have rcov 0.7 or higher! t.threshold = 96.2 # Make sure you have rcov 0.7 or higher!

View File

@ -1,3 +1,5 @@
Fix #within scoping for forms that exist outside the scope
Figure out what the deal is with #select not working
Restore SSL support for Rails (See 73d3b72108254c0f1ad00e63f8e712115cc8ca7c) Restore SSL support for Rails (See 73d3b72108254c0f1ad00e63f8e712115cc8ca7c)
Full support for multiple forms on a page Full support for multiple forms on a page
Track the current form based on the location of the last manipulated input, use this as a default for clicks_button Track the current form based on the location of the last manipulated input, use this as a default for clicks_button

View File

@ -1,12 +1,18 @@
require "rubygems"
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
module Webrat module Webrat
VERSION = '0.2.2' VERSION = '0.2.2'
def self.root def self.root
defined?(RAILS_ROOT) ? RAILS_ROOT : Merb.root defined?(RAILS_ROOT) ? RAILS_ROOT : Merb.root
end end
end end
require "rubygems" # require "webrat/merb/param_parser"
# require "webrat/merb/url_encoded_pair_parser"
require "webrat/core"
require File.dirname(__FILE__) + "/webrat/core" require "webrat/rails" if defined?(RAILS_ENV)
require File.dirname(__FILE__) + "/webrat/rails" if defined?(RAILS_ENV) require "webrat/merb" if defined?(Merb)
require File.dirname(__FILE__) + "/webrat/merb" if defined?(Merb)

View File

@ -1,3 +1,9 @@
Dir[File.join(File.dirname(__FILE__), "core", "*.rb")].sort.each do |file| require "webrat/core/logging"
require File.expand_path(file) require "webrat/core/flunk"
end require "webrat/core/form"
require "webrat/core/scope"
require "webrat/core/link"
require "webrat/core/area"
require "webrat/core/label"
require "webrat/core/select_option"
require "webrat/core/session"

View File

@ -1,4 +1,7 @@
require "cgi" require "cgi"
require "webrat/core_extensions/blank"
require "webrat/core_extensions/nil_to_param"
require "webrat/merb/param_parser"
module Webrat module Webrat
class Field class Field
@ -31,11 +34,11 @@ module Webrat
end end
def matches_id?(id) def matches_id?(id)
matches?(self.id, id) @element["id"] == id.to_s
end end
def matches_name?(name) def matches_name?(name)
matches?(self.name, name) @element["name"] == name.to_s
end end
def matches_label?(label_text) def matches_label?(label_text)
@ -70,14 +73,6 @@ module Webrat
protected protected
def matches?(string, string_or_regex)
if string_or_regex.is_a?(Regexp)
string_or_regex.match string
else
string == string_or_regex
end
end
def id def id
@element["id"] @element["id"]
end end
@ -207,6 +202,10 @@ module Webrat
raise_error_if_disabled raise_error_if_disabled
set(@element["value"] || "on") set(@element["value"] || "on")
end end
def checked?
@element["checked"] == "checked"
end
def uncheck def uncheck
raise_error_if_disabled raise_error_if_disabled
@ -308,7 +307,7 @@ module Webrat
class SelectField < Field class SelectField < Field
def find_option(text) def find_option(text)
options.detect { |o| o.matches_text?(text) || o.matches_value?(text)} options.detect { |o| o.matches_text?(text) }
end end
protected protected

View File

@ -1,3 +1,6 @@
require "webrat/core/field"
require "webrat/core_extensions/blank"
module Webrat module Webrat
class Form class Form
attr_reader :element attr_reader :element
@ -17,12 +20,14 @@ module Webrat
nil nil
end end
def find_select_option(option_text, field_name_pattern = nil) def find_select_option(option_text)
select_fields = fields_by_type([SelectField]) select_fields = fields_by_type([SelectField])
select_fields.select{|field| field_name_pattern.nil? || field.matches_name?(field_name_pattern) || field.matches_id?(field_name_pattern)}.each do |select_field|
select_fields.each do |select_field|
result = select_field.find_option(option_text) result = select_field.find_option(option_text)
return result if result return result if result
end end
nil nil
end end

View File

@ -1,3 +1,5 @@
require "webrat/core_extensions/blank"
module Webrat module Webrat
class Link class Link
@ -6,8 +8,8 @@ module Webrat
@element = element @element = element
end end
def click(method = nil, options = {}) def click(options = {})
method ||= http_method method = options[:method] || http_method
return if href =~ /^#/ && method == :get return if href =~ /^#/ && method == :get
options[:javascript] = true if options[:javascript].nil? options[:javascript] = true if options[:javascript].nil?

View File

@ -1,5 +1,10 @@
module Webrat module Webrat
module Logging module Logging
def warn_log(message) # :nodoc:
return unless logger
logger.warn message
end
def debug_log(message) # :nodoc: def debug_log(message) # :nodoc:
return unless logger return unless logger

29
lib/webrat/core/mime.rb Normal file
View File

@ -0,0 +1,29 @@
module Webrat
module MIME
def self.mime_type(string_or_symbol)
if string_or_symbol.is_a?(String)
string_or_symbol
else
case string_or_symbol
when :text then "text/plain"
when :html then "text/html"
when :js then "text/javascript"
when :css then "text/css"
when :ics then "text/calendar"
when :csv then "text/csv"
when :xml then "application/xml"
when :rss then "application/rss+xml"
when :atom then "application/atom+xml"
when :yaml then "application/x-yaml"
when :multipart_form then "multipart/form-data"
when :url_encoded_form then "application/x-www-form-urlencoded"
when :json then "application/json"
else
raise ArgumentError.new("Invalid Mime type: #{string_or_symbol.inspect}")
end
end
end
end
end

View File

@ -1,4 +1,6 @@
require "cgi" require "cgi"
require "webrat/core_extensions/blank"
require "webrat/merb/url_encoded_pair_parser"
module Webrat module Webrat
class ParamParser class ParamParser

View File

@ -1,4 +1,6 @@
require "hpricot" require "hpricot"
require "webrat/core/form"
require "webrat/core/assertions"
module Webrat module Webrat
class Scope class Scope
@ -12,22 +14,6 @@ module Webrat
@selector = selector @selector = selector
end end
def selects_date(date_string, options = {})
id_or_name = options[:from]
date = Date.parse date_string
year_option = find_select_option(date.year.to_s, /#{id_or_name.to_s}.*1i/)
month_option = find_select_option(date.month.to_s, /#{id_or_name.to_s}.*2i/)
day_option = find_select_option(date.day.to_s, /#{id_or_name.to_s}.*3i/)
flunk("Could not find date picker for #{date_string}") if year_option.nil? || month_option.nil? || day_option.nil?
year_option.choose
month_option.choose
day_option.choose
end
alias_method :select_date, :selects_date
# Verifies an input field or textarea exists on the current page, and stores a value for # Verifies an input field or textarea exists on the current page, and stores a value for
# it which will be sent when the form is submitted. # it which will be sent when the form is submitted.
# #
@ -115,59 +101,48 @@ module Webrat
# Issues a request for the URL pointed to by a link on the current page, # Issues a request for the URL pointed to by a link on the current page,
# follows any redirects, and verifies the final page load was successful. # follows any redirects, and verifies the final page load was successful.
# #
# clicks_link has very basic support for detecting Rails-generated # clicks_link has very basic support for detecting Rails-generated
# JavaScript onclick handlers for PUT, POST and DELETE links, as well as # JavaScript onclick handlers for PUT, POST and DELETE links, as well as
# CSRF authenticity tokens if they are present. # CSRF authenticity tokens if they are present.
# #
# Javascript imitation can be disabled by passing the option :javascript => false # Javascript imitation can be disabled by passing the option :javascript => false
# #
# Passing a :method in the options hash overrides the HTTP method used
# for making the link request
#
# Example: # Example:
# clicks_link "Sign up" # clicks_link "Sign up"
# #
# clicks_link "Sign up", :javascript => false # clicks_link "Sign up", :javascript => false
#
# clicks_link "Sign up", :method => :put
def clicks_link(link_text, options = {}) def clicks_link(link_text, options = {})
find_link(link_text).click(nil, options) find_link(link_text).click(options)
end end
alias_method :click_link, :clicks_link alias_method :click_link, :clicks_link
# Works like clicks_link, but forces a GET request def clicks_get_link(link_text) # :nodoc:
# clicks_link link_text, :method => :get
# Example:
# clicks_get_link "Log out"
def clicks_get_link(link_text)
find_link(link_text).click(:get)
end end
alias_method :click_get_link, :clicks_get_link alias_method :click_get_link, :clicks_get_link
# Works like clicks_link, but issues a DELETE request instead of a GET def clicks_delete_link(link_text) # :nodoc:
# clicks_link link_text, :method => :delete
# Example:
# clicks_delete_link "Log out"
def clicks_delete_link(link_text)
find_link(link_text).click(:delete)
end end
alias_method :click_delete_link, :clicks_delete_link alias_method :click_delete_link, :clicks_delete_link
# Works like clicks_link, but issues a POST request instead of a GET def clicks_post_link(link_text) # :nodoc:
# clicks_link link_text, :method => :post
# Example:
# clicks_post_link "Vote"
def clicks_post_link(link_text)
find_link(link_text).click(:post)
end end
alias_method :click_post_link, :clicks_post_link alias_method :click_post_link, :clicks_post_link
# Works like clicks_link, but issues a PUT request instead of a GET def clicks_put_link(link_text) # :nodoc:
# clicks_link link_text, :method => :put
# Example:
# clicks_put_link "Update profile"
def clicks_put_link(link_text)
find_link(link_text).click(:put)
end end
alias_method :click_put_link, :clicks_put_link alias_method :click_put_link, :clicks_put_link
@ -191,6 +166,10 @@ module Webrat
@dom ||= Hpricot(scoped_html) @dom ||= Hpricot(scoped_html)
end end
def field_labeled(label)
find_field(label, TextField, TextareaField, CheckboxField, RadioField, HiddenField)
end
protected protected
def scoped_html def scoped_html

View File

@ -14,10 +14,6 @@ module Webrat
end end
end end
def matches_value?(value)
@element.attributes['value'] == value.to_s
end
def choose def choose
@select.raise_error_if_disabled @select.raise_error_if_disabled
@select.set(value) @select.set(value)

View File

@ -1,6 +1,8 @@
require "forwardable" require "forwardable"
require "ostruct" require "ostruct"
require "webrat/core/mime"
module Webrat module Webrat
class Session class Session
extend Forwardable extend Forwardable
@ -13,6 +15,7 @@ module Webrat
@http_method = :get @http_method = :get
@data = {} @data = {}
@default_headers = {} @default_headers = {}
@custom_headers = {}
end end
# Saves the page out to RAILS_ROOT/tmp/ and opens it in the default # Saves the page out to RAILS_ROOT/tmp/ and opens it in the default
@ -52,13 +55,22 @@ module Webrat
def saved_page_dir def saved_page_dir
File.expand_path(".") File.expand_path(".")
end 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) def basic_auth(user, pass)
@default_headers['HTTP_AUTHORIZATION'] = "Basic " + ["#{user}:#{pass}"].pack("m*") encoded_login = ["#{user}:#{pass}"].pack("m*")
header('HTTP_AUTHORIZATION', "Basic #{encoded_login}")
end end
def headers def headers
@default_headers.dup @default_headers.dup.merge(@custom_headers.dup)
end end
def request_page(url, http_method, data) def request_page(url, http_method, data)
@ -82,7 +94,7 @@ module Webrat
end end
def success_code? def success_code?
(200..299).include?(response_code) (200..499).include?(response_code)
end end
def exception_caught? def exception_caught?
@ -151,7 +163,6 @@ module Webrat
def_delegators :current_scope, :uncheck, :unchecks def_delegators :current_scope, :uncheck, :unchecks
def_delegators :current_scope, :choose, :chooses def_delegators :current_scope, :choose, :chooses
def_delegators :current_scope, :select, :selects def_delegators :current_scope, :select, :selects
def_delegators :current_scope, :select_date, :selects_date
def_delegators :current_scope, :attach_file, :attaches_file def_delegators :current_scope, :attach_file, :attaches_file
def_delegators :current_scope, :click_area, :clicks_area def_delegators :current_scope, :click_area, :clicks_area
def_delegators :current_scope, :click_link, :clicks_link def_delegators :current_scope, :click_link, :clicks_link
@ -162,5 +173,6 @@ module Webrat
def_delegators :current_scope, :click_button, :clicks_button def_delegators :current_scope, :click_button, :clicks_button
def_delegators :current_scope, :should_see def_delegators :current_scope, :should_see
def_delegators :current_scope, :should_not_see def_delegators :current_scope, :should_not_see
def_delegators :current_scope, :field_labeled
end end
end end

View File

@ -1,5 +1,6 @@
require "cgi" require "cgi"
require "strscan" require "strscan"
require "webrat/core_extensions/hash_with_indifferent_access"
class UrlEncodedPairParser < StringScanner #:nodoc: class UrlEncodedPairParser < StringScanner #:nodoc:
attr_reader :top, :parent, :result attr_reader :top, :parent, :result

View File

@ -0,0 +1,58 @@
class Object
# An object is blank if it's false, empty, or a whitespace string.
# For example, "", " ", +nil+, [], and {} are blank.
#
# This simplifies
#
# if !address.nil? && !address.empty?
#
# to
#
# if !address.blank?
def blank?
respond_to?(:empty?) ? empty? : !self
end
# An object is present if it's not blank.
def present?
!blank?
end
end
class NilClass #:nodoc:
def blank?
true
end
end
class FalseClass #:nodoc:
def blank?
true
end
end
class TrueClass #:nodoc:
def blank?
false
end
end
class Array #:nodoc:
alias_method :blank?, :empty?
end
class Hash #:nodoc:
alias_method :blank?, :empty?
end
class String #:nodoc:
def blank?
self !~ /\S/
end
end
class Numeric #:nodoc:
def blank?
false
end
end

View File

@ -122,4 +122,10 @@ class HashWithIndifferentAccess < Hash
end end
end end
class Hash
def with_indifferent_access
hash = HashWithIndifferentAccess.new(self)
hash.default = self.default
hash
end
end

View File

@ -0,0 +1,5 @@
class NilClass
def to_param
nil
end
end

View File

@ -1,5 +1,3 @@
require "rubygems"
require "mechanize" require "mechanize"
require "webrat/mechanize/mechanize_session"
require File.dirname(__FILE__) + "/mechanize/mechanize_session"

View File

@ -1,6 +1,4 @@
Dir[File.join(File.dirname(__FILE__), "merb", "*.rb")].sort.each do |file| require "webrat/core"
require File.expand_path(file)
end
module Webrat module Webrat
class Session class Session
@ -32,7 +30,8 @@ module Webrat
@response.status @response.status
end end
protected protected
def do_request(url, data, headers, method) def do_request(url, data, headers, method)
@response = request(url, :params => (data && data.any?) ? data : nil, :headers => headers, :method => method) @response = request(url, :params => (data && data.any?) ? data : nil, :headers => headers, :method => method)
self.get(@response.headers['Location'], nil, @response.headers) if @response.status == 302 self.get(@response.headers['Location'], nil, @response.headers) if @response.status == 302

View File

@ -1,12 +0,0 @@
class Hash
def with_indifferent_access
hash = HashWithIndifferentAccess.new(self)
hash.default = self.default
hash
end
end
class NilClass
def to_param
nil
end
end

View File

@ -1,3 +1,4 @@
require File.dirname(__FILE__) + "/rails/redirect_actions" require "webrat/core"
require File.dirname(__FILE__) + "/rails/rails_session" require "webrat/rails/redirect_actions"
require File.dirname(__FILE__) + "/rails/session" require "webrat/rails/rails_session"
require "webrat/rails/session"

View File

@ -1,5 +1,3 @@
require "rubygems"
require "selenium" require "selenium"
require "webrat/selenium/selenium_session"
require File.dirname(__FILE__) + "/selenium/selenium_session"

View File

@ -86,6 +86,14 @@ module Webrat
def checks(label_text) def checks(label_text)
@selenium.check("webrat=#{label_text}") @selenium.check("webrat=#{label_text}")
end end
def is_ordered(*args)
@selenium.is_ordered(*args)
end
def dragdrop(*args)
@selenium.dragdrop(*args)
end
protected protected

View File

@ -1,10 +0,0 @@
require "lib/webrat"
require "lib/webrat/mechanize"
include Webrat
sess = MechanizeSession.new
sess.visits "http://www.google.com/"
sess.fills_in "q", :with => "Webrat"
sess.clicks_button
sess.save_and_open_page

View File

@ -1,34 +0,0 @@
require 'rubygems'
require "lib/webrat"
require "lib/webrat/selenium"
require 'selenium'
include Webrat
# To try it out:
#
# Install the required gem
# > sudo gem install Selenium
#
# Fire up the Selenium proxy server
# > selenium
#
# Run this script
# > ruby selenium_spike.rb
@sel = Selenium::SeleniumDriver.new("localhost", 4444, "*chrome", "http://localhost", 15000)
@sel.start
sess = SeleniumSession.new(@sel)
sess.visits "http://www.google.com/"
sess.fills_in "q", :with => "Webrat"
sess.clicks_link 'Images'
sess.clicks_button 'Search'
sess.selects 'Small images', :from => 'imagesize'
sess.clicks_link 'Preferences'
sess.chooses 'Do not filter'
sess.checks 'Open search results in a new browser window'
sess.clicks_button
sess.save_and_open_page
@sel.stop

View File

@ -21,10 +21,22 @@ describe "clicks_area" do
<area href="/page" title="Berlin" id="berlin" shape="poly" alt="Berlin" coords="180,89,180" /> <area href="/page" title="Berlin" id="berlin" shape="poly" alt="Berlin" coords="180,89,180" />
</map> </map>
EOS EOS
@session.response_code = 404 @session.response_code = 501
lambda { @session.clicks_area "Berlin" }.should raise_error lambda { @session.clicks_area "Berlin" }.should raise_error
end end
[200, 300, 400, 499].each do |status|
it "should consider the #{status} status code as success" do
@session.response_body = <<-EOS
<map name="map_de" id="map_de">
<area href="/page" title="Berlin" id="berlin" shape="poly" alt="Berlin" coords="180,89,180" />
</map>
EOS
@session.response_code = status
lambda { @session.clicks_area "Berlin" }.should_not raise_error
end
end
it "should fail if the area doesn't exist" do it "should fail if the area doesn't exist" do
@session.response_body = <<-EOS @session.response_body = <<-EOS
<map name="map_de" id="map_de"> <map name="map_de" id="map_de">

View File

@ -50,10 +50,22 @@ describe "clicks_button" do
<input type="submit" /> <input type="submit" />
</form> </form>
EOS EOS
@session.response_code = 404 @session.response_code = 501
lambda { @session.clicks_button }.should raise_error lambda { @session.clicks_button }.should raise_error
end end
[200, 300, 400, 499].each do |status|
it "should consider the #{status} status code as success" do
@session.response_body = <<-EOS
<form action="/login">
<input type="submit" />
</form>
EOS
@session.response_code = status
lambda { @session.clicks_button }.should_not raise_error
end
end
it "should submit the first form by default" do it "should submit the first form by default" do
@session.response_body = <<-EOS @session.response_body = <<-EOS
<form method="get" action="/form1"> <form method="get" action="/form1">

View File

@ -18,7 +18,7 @@ describe "clicks_link" do
<a href="/page">Link text</a> <a href="/page">Link text</a>
EOS EOS
@session.should_receive(:get).with("/page", {}) @session.should_receive(:get).with("/page", {})
@session.clicks_get_link "Link text" @session.clicks_link "Link text", :method => :get
end end
it "should click delete links" do it "should click delete links" do
@ -26,7 +26,7 @@ describe "clicks_link" do
<a href="/page">Link text</a> <a href="/page">Link text</a>
EOS EOS
@session.should_receive(:delete).with("/page", {}) @session.should_receive(:delete).with("/page", {})
@session.clicks_delete_link "Link text" @session.clicks_link "Link text", :method => :delete
end end
@ -35,7 +35,7 @@ describe "clicks_link" do
<a href="/page">Link text</a> <a href="/page">Link text</a>
EOS EOS
@session.should_receive(:post).with("/page", {}) @session.should_receive(:post).with("/page", {})
@session.clicks_post_link "Link text" @session.clicks_link "Link text", :method => :post
end end
it "should click put links" do it "should click put links" do
@ -43,7 +43,7 @@ describe "clicks_link" do
<a href="/page">Link text</a> <a href="/page">Link text</a>
EOS EOS
@session.should_receive(:put).with("/page", {}) @session.should_receive(:put).with("/page", {})
@session.clicks_put_link "Link text" @session.clicks_link "Link text", :method => :put
end end
it "should click rails javascript links with authenticity tokens" do it "should click rails javascript links with authenticity tokens" do
@ -155,10 +155,20 @@ describe "clicks_link" do
@session.response_body = <<-EOS @session.response_body = <<-EOS
<a href="/page">Link text</a> <a href="/page">Link text</a>
EOS EOS
@session.response_code = 404 @session.response_code = 501
lambda { @session.clicks_link "Link text" }.should raise_error lambda { @session.clicks_link "Link text" }.should raise_error
end end
[200, 300, 400, 499].each do |status|
it "should consider the #{status} status code as success" do
@session.response_body = <<-EOS
<a href="/page">Link text</a>
EOS
@session.response_code = status
lambda { @session.clicks_link "Link text" }.should_not raise_error
end
end
it "should fail is the link doesn't exist" do it "should fail is the link doesn't exist" do
@session.response_body = <<-EOS @session.response_body = <<-EOS
<a href="/page">Link text</a> <a href="/page">Link text</a>

View File

@ -0,0 +1,111 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe "field_labeled" do
class << self
def using_this_html html
before(:each) do
@session = Webrat::TestSession.new
@session.response_body = html
end
end
def field_labeled label
@label = label
yield
end
def should_return_a type, opts
it "should return a textfield" do
@session.field_labeled(opts[:for]).should be_an_instance_of(type)
end
end
def with_an_id_of id, opts
it "should return an element with the correct id" do
@session.field_labeled(opts[:for]).should match_id(id)
end
end
def should_raise_error_matching regexp, opts
it "should raise with wrong label" do
lambda {
@session.field_labeled(opts[:for])
}.should raise_error(regexp)
end
end
end
def match_id(id)
simple_matcher "element with id #{id.inspect}" do |element, matcher|
element.matches_id? id
end
end
describe "finding a text field" do
using_this_html <<-EOS
<form>
<label for="element_42">The Label</label>
<input type="text" id="element_42">
</form>
EOS
should_return_a Webrat::TextField, :for => "The Label"
with_an_id_of "element_42", :for => "The Label"
should_raise_error_matching /Could not find .* "Other Label"/, :for => "Other Label"
end
describe "finding a text field" do
using_this_html <<-EOS
<form>
<label for="element_42">The Label</label>
<input type="hidden" id="element_42">
</form>
EOS
should_return_a Webrat::HiddenField, :for => "The Label"
with_an_id_of "element_42", :for => "The Label"
should_raise_error_matching /Could not find .* "Other Label"/, :for => "Other Label"
end
describe "finding a checkbox" do
using_this_html <<-EOS
<form>
<label for="element_42">The Label</label>
<input type="checkbox" id="element_42">
</form>
EOS
should_return_a Webrat::CheckboxField, :for => "The Label"
with_an_id_of "element_42", :for => "The Label"
should_raise_error_matching /Could not find .* "Other Label"/, :for => "Other Label"
end
describe "finding a radio button" do
using_this_html <<-EOS
<form>
<label for="element_42">The Label</label>
<input type="radio" id="element_42">
</form>
EOS
should_return_a Webrat::RadioField, :for => "The Label"
with_an_id_of "element_42", :for => "The Label"
should_raise_error_matching /Could not find .* "Other Label"/, :for => "Other Label"
end
describe "finding a text area" do
using_this_html <<-EOS
<form>
<label for="element_42">The Label</label>
<textarea id="element_42"></textarea>
</form>
EOS
should_return_a Webrat::TextareaField, :for => "The Label"
with_an_id_of "element_42", :for => "The Label"
should_raise_error_matching /Could not find .* "Other Label"/, :for => "Other Label"
end
end

View File

@ -1,111 +0,0 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
describe "date_selects" do
before do
@session = Webrat::TestSession.new
@example_date_select = <<-EOS
<form method="post" action="/login">
<label for="created_at">Created at</label><br />
<select id="created_at_1i" name="created_at(1i)">
<option value="2002">2002</option>
<option value="2003">2003</option>
</select>
<select id="created_at_2i" name="created_at(2i)">
<option value="11">November</option>
<option value="12">December</option>
</select>
<select id="created_at_3i" name="created_at(3i)">
<option value="1">1</option>
<option value="2">2</option>
</select>
<input type="button" value="submit"/>
</form>
EOS
end
it "should fail if option not found" do
@session.response_body = @example_date_select
lambda { @session.selects_date "2008-07-13"}.should raise_error
end
it "should fail if option not found in list specified by element name" do
@session.response_body = @example_date_select
lambda { @session.selects_date "2008-07-13", :from => "created_at" }.should raise_error
end
it "should fail if specified list not found" do
@session.response_body = <<-EOS
<form method="get" action="/login">
<select name="month"><option value="1">January</option></select>
</form>
EOS
lambda { @session.selects_date "2003-12-01", :from => "created_at" }.should raise_error
end
it "should send value from option" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<label for="updated_at">Created at</label><br />
<select id="updated_at_1i" name="updated_at(1i)">
<option value=""></option>
<option value="2003">2003</option>
</select>
<select id="updated_at_2i" name="updated_at(2i)">
<option value=""></option>
<option value="12">December</option>
</select>
<select id="updated_at_3i" name="updated_at(3i)">
<option value=""></option>
<option value="1">1</option>
</select>
<label for="created_at">Created at</label><br />
<select id="created_at_1i" name="created_at(1i)">
<option value="2003">2003</option>
</select>
<select id="created_at_2i" name="created_at(2i)">
<option value="12">December</option>
</select>
<select id="created_at_3i" name="created_at(3i)">
<option value="1">1</option>
</select>
<input type="button" value="submit"/>
</form>
EOS
@session.should_receive(:post).with("/login", "created_at(1i)" => "2003", 'created_at(2i)' => '12', 'created_at(3i)' => '1', "updated_at(1i)" => "", 'updated_at(2i)' => '', 'updated_at(3i)' => '')
@session.selects_date '2003-12-01', :from => "created_at"
@session.clicks_button
end
it "should work without specifying the field name or label" do
@session.response_body = @example_date_select
@session.should_receive(:post).with("/login", "created_at(1i)" => "2003", 'created_at(2i)' => '12', 'created_at(3i)' => '1')
@session.selects_date '2003-12-01'
@session.clicks_button
end
it "should correctly set day and month when there are the same options available" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<label for="created_at">Created at</label><br />
<select id="created_at_1i" name="created_at(1i)">
<option value="2003">2003</option>
</select>
<select id="created_at_2i" name="created_at(2i)">
<option value="1">January</option>
<option value="12">December</option>
</select>
<select id="created_at_3i" name="created_at(3i)">
<option value="1">1</option>
<option value="12">12</option>
</select>
<input type="button" value="submit"/>
</form>
EOS
@session.should_receive(:post).with("/login", "created_at(1i)" => "2003", 'created_at(2i)' => '12', 'created_at(3i)' => '1')
@session.selects_date '2003-12-01'
@session.clicks_button
end
end

View File

@ -108,18 +108,6 @@ describe "selects" do
@session.clicks_button @session.clicks_button
end end
it "should send value from option in list specified by value" do
@session.response_body = <<-EOS
<form method="post" action="/login">
<select name="start_month"><option value="s1">January</option></select>
<input type="submit" />
</form>
EOS
@session.should_receive(:post).with("/login", "start_month" => "s1")
@session.selects "s1", :from => "start_month"
@session.clicks_button
end
it "should send value from option in list specified by label" do it "should send value from option in list specified by label" do
@session.response_body = <<-EOS @session.response_body = <<-EOS
<form method="post" action="/login"> <form method="post" action="/login">

View File

@ -12,10 +12,17 @@ describe "visits" do
end end
it "should assert valid response" do it "should assert valid response" do
@session.response_code = 404 @session.response_code = 501
lambda { @session.visits("/") }.should raise_error lambda { @session.visits("/") }.should raise_error
end end
[200, 300, 400, 499].each do |status|
it "should consider the #{status} status code as success" do
@session.response_code = status
lambda { @session.visits("/") }.should_not raise_error
end
end
it "should require a visit before manipulating page" do it "should require a visit before manipulating page" do
lambda { @session.fills_in "foo", :with => "blah" }.should raise_error lambda { @session.fills_in "foo", :with => "blah" }.should raise_error
end end
@ -33,4 +40,4 @@ describe "visits with referer" do
@session.visits("/") @session.visits("/")
end end
end end

View File

@ -6,15 +6,7 @@ require "spec/interop/test"
begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end
require File.expand_path(File.dirname(__FILE__) + "/../lib/webrat") require File.expand_path(File.dirname(__FILE__) + "/../lib/webrat")
require File.dirname(__FILE__) + "/fakes/test_session" require File.expand_path(File.dirname(__FILE__) + "/fakes/test_session")
if ["rails","merb"].include?(ENV["TEST_MODE"])
require File.join(File.dirname(__FILE__), "webrat", "#{ENV["TEST_MODE"]}", "helper.rb")
else
puts "Assuming test mode is Rails... for Merb set TEST_MODE=merb and rerun."
ENV["TEST_MODE"] = 'rails'
require File.join(File.dirname(__FILE__), "webrat", "#{ENV["TEST_MODE"]}", "helper.rb")
end
Spec::Runner.configure do |config| Spec::Runner.configure do |config|
# Nothing to configure yet # Nothing to configure yet

View File

@ -0,0 +1,15 @@
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
module Webrat
describe CheckboxField do
it "should say it is checked if it is" do
checkbox = CheckboxField.new(nil, (Hpricot("<input type='checkbox' checked='checked'>")/'input').first)
checkbox.should be_checked
end
it "should say it is not checked if it is not" do
checkbox = CheckboxField.new(nil, (Hpricot("<input type='checkbox'>")/'input').first)
checkbox.should_not be_checked
end
end
end

View File

@ -1,12 +1,10 @@
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
describe Webrat::Logging do describe Webrat::Logging do
include Webrat::Logging
it "should log to RAILS_DEFAULT_LOGGER" do it "should not log if there is no logger" do
logger = mock("logger") klass = Class.new
RAILS_DEFAULT_LOGGER = logger klass.send(:include, Webrat::Logging)
logger.should_receive(:debug).with("Testing") klass.new.debug_log "Testing"
debug_log "Testing"
end end
end end

View File

@ -29,5 +29,41 @@ describe Webrat::Session do
current_page.should_not be_nil current_page.should_not be_nil
current_page.should respond_to(:url) current_page.should respond_to(:url)
end end
it "should allow custom headers to be set" do
session = Webrat::Session.new
session.header('Accept', 'application/xml')
session.instance_variable_get(:@custom_headers)['Accept'].should == 'application/xml'
end
it "should return a copy of the headers to be sent" do
session = Webrat::Session.new
session.instance_eval {
@default_headers = {'HTTP_X_FORWARDED_FOR' => '192.168.1.1'}
@custom_headers = {'Accept' => 'application/xml'}
}
session.headers.should == {'HTTP_X_FORWARDED_FOR' => '192.168.1.1', 'Accept' => 'application/xml'}
end
describe "#http_accept" do
before(:each) do
@session = Webrat::Session.new
end
it "should set the Accept header with the string Mime type" do
@session.http_accept('application/xml')
@session.headers['Accept'].should == 'application/xml'
end
it "should set the Accept head with the string value of the symbol Mime type" do
@session.http_accept(:xml)
@session.headers['Accept'].should == 'application/xml'
end
it "should raise an error if a symbol Mime type is passed that does not exist" do
lambda { @session.http_accept(:oogabooga) }.should raise_error(ArgumentError)
end
end
end end

View File

@ -1,4 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + "/../../../lib/webrat/mechanize") require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
require "mechanize"
require "webrat/mechanize"
describe Webrat::MechanizeSession do describe Webrat::MechanizeSession do
before(:each) do before(:each) do

View File

@ -1,5 +1,5 @@
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper") require File.expand_path(File.dirname(__FILE__) + '/helper')
unless ENV["TEST_MODE"] == "merb" #TODO - Rob
describe "attaches_file" do describe "attaches_file" do
before do before do
@session = Webrat::TestSession.new @session = Webrat::TestSession.new
@ -69,5 +69,4 @@ describe "attaches_file" do
@session.attaches_file "Picture", @filename, "image/png" @session.attaches_file "Picture", @filename, "image/png"
@session.clicks_button @session.clicks_button
end end
end
end end

View File

@ -1,7 +1,9 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
require "active_support" require "active_support"
silence_warnings do silence_warnings do
require "action_controller" require "action_controller"
require "action_controller/integration" require "action_controller/integration"
end end
require File.expand_path(File.dirname(__FILE__) + "/../../../lib/webrat/rails")
require "webrat/rails"

View File

@ -1,4 +1,4 @@
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper') require File.expand_path(File.dirname(__FILE__) + '/helper')
describe Webrat::RailsSession do describe Webrat::RailsSession do
it "should require a Rails Integration session to be initialized" do it "should require a Rails Integration session to be initialized" do