This commit is contained in:
commit
9b72542b95
|
@ -1,4 +1,5 @@
|
||||||
coverage
|
coverage
|
||||||
|
.DS_Store
|
||||||
pkg
|
pkg
|
||||||
doc
|
doc
|
||||||
ri
|
ri
|
||||||
|
|
78
History.txt
78
History.txt
|
@ -2,42 +2,50 @@
|
||||||
|
|
||||||
* Major enhancements
|
* Major enhancements
|
||||||
|
|
||||||
|
* Added Merb support (Gwyn Morfey, Jeremy Burks, Rob Kaufman)
|
||||||
* Added #basic_auth(user, pass) to support HTTP Basic Auth (Aslak Hellesøy)
|
* Added #basic_auth(user, pass) to support HTTP Basic Auth (Aslak Hellesøy)
|
||||||
* Added support for Sinatra and Rack (Aslak Hellesøy)
|
* Added support for Sinatra and Rack (Aslak Hellesøy)
|
||||||
* Added #within for manipulating the current page within a selector scope
|
* Added #within for manipulating the current page within a selector scope
|
||||||
* Add should_see and should_not_see for verifying HTML response bodys
|
|
||||||
* Add support for simulating SSL requests (Luke Melia)
|
* Add support for simulating SSL requests (Luke Melia)
|
||||||
* Add support for file fields via #attaches_file method (Patch from Kyle Hargraves)
|
* Add support for file fields via #attaches_file method (Kyle Hargraves)
|
||||||
* Support relative links, including href="?foo=bar" (Patch from Kyle Hargraves)
|
|
||||||
* Separated Rails-specific code from the Webrat core to make it easier to use Webrat with other environments
|
|
||||||
* Alias visits as visit, clicks_link as click_link, etc. for better readability
|
|
||||||
* Raise error when trying to interact with a disabled form element (Luke Melia)
|
|
||||||
* Don't send disabled form elements to the server (Patch from Nicholas A. Evans)
|
|
||||||
|
|
||||||
* Minor enhancements
|
* Minor enhancements
|
||||||
|
|
||||||
* Add support for redirect_to :back by sending HTTP_REFERER headers (Patch from Hendrik Volkmer)
|
* Add Webrat.root method for cross-framework support (Krzysztof Zylawy)
|
||||||
|
* Add #select_date for quickly filling out Rails-style date fields (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
|
||||||
|
* 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
|
||||||
|
* Alias visits as visit, clicks_link as click_link, etc. for better readability
|
||||||
|
* Raise error when trying to interact with a disabled form element (Luke Melia)
|
||||||
|
* Don't send disabled form elements to the server (Nicholas A. Evans)
|
||||||
|
* Display response body when the page load is not successful (David Leal)
|
||||||
|
* CGI escape form field values (Miha Filej)
|
||||||
|
* Add support for redirect_to :back by sending HTTP_REFERER headers (Hendrik Volkmer)
|
||||||
* Expose current DOM (as an Hpricot object) as #current_dom
|
* Expose current DOM (as an Hpricot object) as #current_dom
|
||||||
* Add support for disabling JavaScript when clicking a link to enable testing of both JS
|
* Add support for disabling JavaScript when clicking a link to enable testing of both JS
|
||||||
and non-JS implementations (Luke Melia and Bryan Helmkamp)
|
and non-JS implementations (Luke Melia and Bryan Helmkamp)
|
||||||
* Support  's as spaces in matching link text (Patch from Luke Melia)
|
* Support  's as spaces in matching link text (Luke Melia)
|
||||||
* Support button elements (Patch from Nick Sieger)
|
* Support button elements (Nick Sieger)
|
||||||
* Support matching select options by regexp (Patch from Kyle Hargraves)
|
* Support matching select options by regexp (Kyle Hargraves)
|
||||||
* save_and_open_page rewrites css and image references to provide a friendlier debugging experience (Luke Melia)
|
* save_and_open_page rewrites css and image references to provide a friendlier debugging experience (Luke Melia)
|
||||||
* Added support for matching alt attributes in fields (primarly for clicks_button) (Patch from Aaron Quint)
|
* Added support for matching alt attributes in fields (primarly for clicks_button) (Aaron Quint)
|
||||||
* Support '&' in submitted values (Patch from Kyle Hargraves)
|
* Support '&' in submitted values (Kyle Hargraves)
|
||||||
* Support clicking links by title (Patch from Dan Barry)
|
* Support clicking links by title (Dan Barry)
|
||||||
* Added missing spec for clicking image buttons (Patch from Tim Harper)
|
* Added missing spec for clicking image buttons (Tim Harper)
|
||||||
* Switched tests to specs, and from Mocha to RSpec's mocking library
|
* Switched tests to specs, and from Mocha to RSpec's mocking library
|
||||||
* Add support to click_button for IDs (Patch from Gwyn Morfey)
|
* Add support to click_button for IDs (Gwyn Morfey)
|
||||||
* Miscellaneous core refactorings (Patch from Jan Suchal)
|
* Miscellaneous core refactorings (Jan Suchal)
|
||||||
|
|
||||||
* Bug fixes
|
* Bug fixes
|
||||||
|
|
||||||
* Don't open blank pages in the browser (Patch from Kyle Hargraves)
|
* Fix initialization of WWW::Mechanize (Derek Kastner)
|
||||||
* Support radio buttons with multiple labels (Patch from Dan Barry)
|
* Don't open blank pages in the browser (Kyle Hargraves)
|
||||||
* Fix load order bug on some platforms (Patch from Ismael Celis)
|
* Support radio buttons with multiple labels (Dan Barry)
|
||||||
* Fix bug with empty select list option (Patch from Kyle Hargraves)
|
* Fix load order bug on some platforms (Ismael Celis)
|
||||||
|
* Fix bug with empty select list option (Kyle Hargraves)
|
||||||
* Fix regression of not sending default values in password fields
|
* Fix regression of not sending default values in password fields
|
||||||
* Don't explode if encountering inputs with no type attribute (assume text)
|
* Don't explode if encountering inputs with no type attribute (assume text)
|
||||||
* Fix bug where choosing a radio button in a series with a default submitted the incorrect field value (Luke Melia)
|
* Fix bug where choosing a radio button in a series with a default submitted the incorrect field value (Luke Melia)
|
||||||
|
@ -50,29 +58,29 @@
|
||||||
* Add radio button support via #chooses method
|
* Add radio button support via #chooses method
|
||||||
* Add basic support for Rails-generated JavaScript link tags
|
* Add basic support for Rails-generated JavaScript link tags
|
||||||
* Add support for checkboxes (Patches from Kyle Hargraves and Jarkko Laine)
|
* Add support for checkboxes (Patches from Kyle Hargraves and Jarkko Laine)
|
||||||
* Add support for textarea fields (Patch from Sacha Schlegel)
|
* Add support for textarea fields (Sacha Schlegel)
|
||||||
|
|
||||||
* 8 Minor enhancements
|
* 8 Minor enhancements
|
||||||
|
|
||||||
* Added reloads method to reload the page (Patch from Kamal Fariz Mahyuddi)
|
* Added reloads method to reload the page (Kamal Fariz Mahyuddi)
|
||||||
* Prevent making a request if clicking on local anchor link (Patch from Kamal Fariz Mahyuddi)
|
* Prevent making a request if clicking on local anchor link (Kamal Fariz Mahyuddi)
|
||||||
* Added clicks_link_within(selector, link_text), allowing restricting link search
|
* Added clicks_link_within(selector, link_text), allowing restricting link search
|
||||||
to within a given css selector (Patch from Luke Melia)
|
to within a given css selector (Luke Melia)
|
||||||
* Allow specifying the input name/label when doing a select (Patch from David Chelimsky)
|
* Allow specifying the input name/label when doing a select (David Chelimsky)
|
||||||
* Raise a specific exception if the developer tries to manipulate form elements before loading a page (Patch from James Deville)
|
* Raise a specific exception if the developer tries to manipulate form elements before loading a page (James Deville)
|
||||||
* Add support for alternate POST, PUT and DELETE link clicking (Patch from Kyle Hargraves)
|
* Add support for alternate POST, PUT and DELETE link clicking (Kyle Hargraves)
|
||||||
* Change clicks_link to find the shortest matching link (Patch from Luke Melia)
|
* Change clicks_link to find the shortest matching link (Luke Melia)
|
||||||
* Improve matching for labels in potentially ambiguous cases
|
* Improve matching for labels in potentially ambiguous cases
|
||||||
|
|
||||||
* 7 Bug fixes
|
* 7 Bug fixes
|
||||||
|
|
||||||
* Fix incorrect serializing of collection inputs, i.e. name contains [] (Patch from Kamal Fariz Mahyuddi)
|
* Fix incorrect serializing of collection inputs, i.e. name contains [] (Kamal Fariz Mahyuddi)
|
||||||
* Serialize empty text field values just like browsers (Patch from Kamal Fariz Mahyuddi)
|
* Serialize empty text field values just like browsers (Kamal Fariz Mahyuddi)
|
||||||
* Quick fix to avoid @dom not initialized warnings (Patch from Kamal Fariz Mahyuddi)
|
* Quick fix to avoid @dom not initialized warnings (Kamal Fariz Mahyuddi)
|
||||||
* Docfix: bad reference to #select method in README (Patch from Luke Melia)
|
* Docfix: bad reference to #select method in README (Luke Melia)
|
||||||
* Ensure Rails-style checkboxes work properly (checkboxes followed by a hidden input with the same name)
|
* Ensure Rails-style checkboxes work properly (checkboxes followed by a hidden input with the same name)
|
||||||
* Fix Edge Rails (a.k.a. 2.0 RC) compatibility (Patch from David Chelimsky)
|
* Fix Edge Rails (a.k.a. 2.0 RC) compatibility (David Chelimsky)
|
||||||
* Support param hashes nested more than one level (Patch from David Chelimsky)
|
* Support param hashes nested more than one level (David Chelimsky)
|
||||||
|
|
||||||
== 0.1.0 / 2007-11-28
|
== 0.1.0 / 2007-11-28
|
||||||
|
|
||||||
|
|
20
Manifest.txt
20
Manifest.txt
|
@ -8,6 +8,7 @@ init.rb
|
||||||
install.rb
|
install.rb
|
||||||
lib/webrat.rb
|
lib/webrat.rb
|
||||||
lib/webrat/core.rb
|
lib/webrat/core.rb
|
||||||
|
lib/webrat/core/area.rb
|
||||||
lib/webrat/core/assertions.rb
|
lib/webrat/core/assertions.rb
|
||||||
lib/webrat/core/field.rb
|
lib/webrat/core/field.rb
|
||||||
lib/webrat/core/flunk.rb
|
lib/webrat/core/flunk.rb
|
||||||
|
@ -20,22 +21,38 @@ lib/webrat/core/select_option.rb
|
||||||
lib/webrat/core/session.rb
|
lib/webrat/core/session.rb
|
||||||
lib/webrat/mechanize.rb
|
lib/webrat/mechanize.rb
|
||||||
lib/webrat/mechanize/mechanize_session.rb
|
lib/webrat/mechanize/mechanize_session.rb
|
||||||
|
lib/webrat/merb.rb
|
||||||
|
lib/webrat/merb/indifferent_access.rb
|
||||||
|
lib/webrat/merb/param_parser.rb
|
||||||
|
lib/webrat/merb/support.rb
|
||||||
|
lib/webrat/merb/url_encoded_pair_parser.rb
|
||||||
|
lib/webrat/rack/rack_session.rb
|
||||||
lib/webrat/rails.rb
|
lib/webrat/rails.rb
|
||||||
lib/webrat/rails/rails_session.rb
|
lib/webrat/rails/rails_session.rb
|
||||||
lib/webrat/rails/redirect_actions.rb
|
lib/webrat/rails/redirect_actions.rb
|
||||||
lib/webrat/rails/session.rb
|
lib/webrat/rails/session.rb
|
||||||
lib/webrat/selenium.rb
|
lib/webrat/selenium.rb
|
||||||
|
lib/webrat/selenium/location_strategy_javascript/button.js
|
||||||
|
lib/webrat/selenium/location_strategy_javascript/label.js
|
||||||
|
lib/webrat/selenium/location_strategy_javascript/webrat.js
|
||||||
|
lib/webrat/selenium/location_strategy_javascript/webratlink.js
|
||||||
|
lib/webrat/selenium/location_strategy_javascript/webratlinkwithin.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
|
||||||
mechanize_spike.rb
|
mechanize_spike.rb
|
||||||
selenium_spike.rb
|
selenium_spike.rb
|
||||||
spec/api/attaches_file_spec.rb
|
spec/api/attaches_file_spec.rb
|
||||||
|
spec/api/basic_auth_spec.rb
|
||||||
spec/api/checks_spec.rb
|
spec/api/checks_spec.rb
|
||||||
spec/api/chooses_spec.rb
|
spec/api/chooses_spec.rb
|
||||||
|
spec/api/clicks_area_spec.rb
|
||||||
spec/api/clicks_button_spec.rb
|
spec/api/clicks_button_spec.rb
|
||||||
spec/api/clicks_link_spec.rb
|
spec/api/clicks_link_spec.rb
|
||||||
spec/api/fills_in_spec.rb
|
spec/api/fills_in_spec.rb
|
||||||
spec/api/reloads_spec.rb
|
spec/api/reloads_spec.rb
|
||||||
spec/api/save_and_open_spec.rb
|
spec/api/save_and_open_spec.rb
|
||||||
|
spec/api/selects_date_spec.rb
|
||||||
spec/api/selects_spec.rb
|
spec/api/selects_spec.rb
|
||||||
spec/api/should_not_see_spec.rb
|
spec/api/should_not_see_spec.rb
|
||||||
spec/api/should_see_spec.rb
|
spec/api/should_see_spec.rb
|
||||||
|
@ -48,5 +65,8 @@ 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/merb/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
|
||||||
|
|
|
@ -59,6 +59,13 @@ tests to break unnecessarily as your application evolves:
|
||||||
|
|
||||||
A test written with Webrat can handle these changes to these without any modifications.
|
A test written with Webrat can handle these changes to these without any modifications.
|
||||||
|
|
||||||
|
=== Merb
|
||||||
|
To avoid losing sessions, you need this in environments/test.rb:
|
||||||
|
|
||||||
|
Merb::Config.use do |c|
|
||||||
|
c[:session_store] = 'memory'
|
||||||
|
end
|
||||||
|
|
||||||
=== Install
|
=== Install
|
||||||
|
|
||||||
To install the latest release:
|
To install the latest release:
|
||||||
|
|
17
Rakefile
17
Rakefile
|
@ -35,28 +35,39 @@ 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 all specs in spec directory"
|
||||||
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 = FileList['spec/**/*_spec.rb']
|
t.spec_files = set_file_list
|
||||||
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 = FileList['spec/**/*_spec.rb']
|
t.spec_files = set_file_list
|
||||||
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 = 97.3 # Make sure you have rcov 0.7 or higher!
|
t.threshold = 96.2 # Make sure you have rcov 0.7 or higher!
|
||||||
end
|
end
|
||||||
|
|
||||||
remove_task "default"
|
remove_task "default"
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
module Webrat
|
module Webrat
|
||||||
VERSION = '0.2.1'
|
VERSION = '0.2.2'
|
||||||
|
def self.root
|
||||||
|
defined?(RAILS_ROOT) ? RAILS_ROOT : Merb.root
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
require "rubygems"
|
require "rubygems"
|
||||||
|
|
||||||
require File.dirname(__FILE__) + "/webrat/core"
|
require File.dirname(__FILE__) + "/webrat/core"
|
||||||
require File.dirname(__FILE__) + "/webrat/rails" if defined?(RAILS_ENV)
|
require File.dirname(__FILE__) + "/webrat/rails" if defined?(RAILS_ENV)
|
||||||
|
require File.dirname(__FILE__) + "/webrat/merb" if defined?(Merb)
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
module Webrat
|
||||||
|
class Area
|
||||||
|
|
||||||
|
def initialize(session, element)
|
||||||
|
@session = session
|
||||||
|
@element = element
|
||||||
|
end
|
||||||
|
|
||||||
|
def click(method = nil, options = {})
|
||||||
|
@session.request_page(absolute_href, :get, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
def matches_text?(id_or_title)
|
||||||
|
matcher = /#{Regexp.escape(id_or_title.to_s)}/i
|
||||||
|
title =~ matcher || id =~ matcher
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def href
|
||||||
|
@element["href"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def title
|
||||||
|
@element["title"]
|
||||||
|
end
|
||||||
|
|
||||||
|
def id
|
||||||
|
@element["id"]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def absolute_href
|
||||||
|
if href =~ /^\?/
|
||||||
|
"#{@session.current_url}#{href}"
|
||||||
|
elsif href !~ %r{^https?://[\w|.]+(/.*)} && (href !~ /^\//)
|
||||||
|
"#{@session.current_url}/#{href}"
|
||||||
|
else
|
||||||
|
href
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,3 +1,5 @@
|
||||||
|
require "cgi"
|
||||||
|
|
||||||
module Webrat
|
module Webrat
|
||||||
class Field
|
class Field
|
||||||
|
|
||||||
|
@ -6,15 +8,14 @@ module Webrat
|
||||||
if %w[submit image].include?(element["type"])
|
if %w[submit image].include?(element["type"])
|
||||||
field_class = "button"
|
field_class = "button"
|
||||||
else
|
else
|
||||||
field_class = element["type"] || "text"
|
field_class = element["type"] || "text" #default type; 'type' attribute is not mandatory
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
field_class = element.name
|
field_class = element.name
|
||||||
end
|
end
|
||||||
|
|
||||||
Webrat.const_get("#{field_class.capitalize}Field")
|
Webrat.const_get("#{field_class.capitalize}Field")
|
||||||
rescue NameError
|
rescue NameError
|
||||||
raise "Invalid field element: #{element.inspect}"
|
raise "Invalid field element: #{element.inspect}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(form, element)
|
def initialize(form, element)
|
||||||
|
@ -30,11 +31,11 @@ module Webrat
|
||||||
end
|
end
|
||||||
|
|
||||||
def matches_id?(id)
|
def matches_id?(id)
|
||||||
@element["id"] == id.to_s
|
matches?(self.id, id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def matches_name?(name)
|
def matches_name?(name)
|
||||||
@element["name"] == name.to_s
|
matches?(self.name, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def matches_label?(label_text)
|
def matches_label?(label_text)
|
||||||
|
@ -56,10 +57,9 @@ module Webrat
|
||||||
|
|
||||||
def to_param
|
def to_param
|
||||||
return nil if disabled?
|
return nil if disabled?
|
||||||
value = @value.to_s.gsub('&', '%26')
|
param_parser.parse_query_parameters("#{name}=#{escaped_value}")
|
||||||
param_parser.parse_query_parameters("#{name}=#{value}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def set(value)
|
def set(value)
|
||||||
@value = value
|
@value = value
|
||||||
end
|
end
|
||||||
|
@ -70,6 +70,14 @@ 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
|
||||||
|
@ -78,6 +86,10 @@ module Webrat
|
||||||
@element["name"]
|
@element["name"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def escaped_value
|
||||||
|
CGI.escape(@value.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
def labels
|
def labels
|
||||||
@labels ||= label_elements.map { |element| Label.new(self, element) }
|
@labels ||= label_elements.map { |element| Label.new(self, element) }
|
||||||
end
|
end
|
||||||
|
@ -109,10 +121,10 @@ module Webrat
|
||||||
def param_parser
|
def param_parser
|
||||||
if defined?(CGIMethods)
|
if defined?(CGIMethods)
|
||||||
CGIMethods
|
CGIMethods
|
||||||
else
|
elsif defined?(ActionController::AbstractRequest)
|
||||||
require "action_controller"
|
|
||||||
require "action_controller/integration"
|
|
||||||
ActionController::AbstractRequest
|
ActionController::AbstractRequest
|
||||||
|
else
|
||||||
|
Webrat::ParamParser #used for Merb
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -138,10 +150,6 @@ module Webrat
|
||||||
def matches_text?(text)
|
def matches_text?(text)
|
||||||
@element.innerHTML =~ /#{Regexp.escape(text.to_s)}/i
|
@element.innerHTML =~ /#{Regexp.escape(text.to_s)}/i
|
||||||
end
|
end
|
||||||
|
|
||||||
# def matches_id?(id)
|
|
||||||
# @element["id"] =~ /^\W*#{Regexp.escape(id.to_s)}/i
|
|
||||||
# end
|
|
||||||
|
|
||||||
def matches_value?(value)
|
def matches_value?(value)
|
||||||
@element["value"] =~ /^\W*#{Regexp.escape(value.to_s)}/i || matches_text?(value) || matches_alt?(value)
|
@element["value"] =~ /^\W*#{Regexp.escape(value.to_s)}/i || matches_text?(value) || matches_alt?(value)
|
||||||
|
@ -172,7 +180,7 @@ module Webrat
|
||||||
else
|
else
|
||||||
checkbox_with_same_name = @form.find_field(name, CheckboxField)
|
checkbox_with_same_name = @form.find_field(name, CheckboxField)
|
||||||
|
|
||||||
if checkbox_with_same_name.to_param.nil?
|
if checkbox_with_same_name.to_param.blank?
|
||||||
super
|
super
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
|
@ -300,7 +308,7 @@ module Webrat
|
||||||
class SelectField < Field
|
class SelectField < Field
|
||||||
|
|
||||||
def find_option(text)
|
def find_option(text)
|
||||||
options.detect { |o| o.matches_text?(text) }
|
options.detect { |o| o.matches_text?(text) || o.matches_value?(text)}
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -17,14 +17,12 @@ module Webrat
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_select_option(option_text)
|
def find_select_option(option_text, field_name_pattern = nil)
|
||||||
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
|
||||||
|
|
||||||
|
@ -105,7 +103,7 @@ module Webrat
|
||||||
def merge_hash_values(a, b) # :nodoc:
|
def merge_hash_values(a, b) # :nodoc:
|
||||||
a.keys.each do |k|
|
a.keys.each do |k|
|
||||||
if b.has_key?(k)
|
if b.has_key?(k)
|
||||||
case [a[k], b[k]].map(&:class)
|
case [a[k], b[k]].map{|value| value.class}
|
||||||
when [Hash, Hash]
|
when [Hash, Hash]
|
||||||
a[k] = merge_hash_values(a[k], b[k])
|
a[k] = merge_hash_values(a[k], b[k])
|
||||||
b.delete(k)
|
b.delete(k)
|
||||||
|
|
|
@ -3,12 +3,14 @@ module Webrat
|
||||||
|
|
||||||
def debug_log(message) # :nodoc:
|
def debug_log(message) # :nodoc:
|
||||||
return unless logger
|
return unless logger
|
||||||
logger.debug(message)
|
logger.debug message
|
||||||
end
|
end
|
||||||
|
|
||||||
def logger # :nodoc:
|
def logger # :nodoc:
|
||||||
if defined? RAILS_DEFAULT_LOGGER
|
if defined? RAILS_DEFAULT_LOGGER
|
||||||
RAILS_DEFAULT_LOGGER
|
RAILS_DEFAULT_LOGGER
|
||||||
|
elsif defined? Merb
|
||||||
|
Merb.logger
|
||||||
else
|
else
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,6 +12,22 @@ 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.
|
||||||
#
|
#
|
||||||
|
@ -91,6 +107,12 @@ module Webrat
|
||||||
|
|
||||||
alias_method :attach_file, :attaches_file
|
alias_method :attach_file, :attaches_file
|
||||||
|
|
||||||
|
def clicks_area(area_name)
|
||||||
|
find_area(area_name).click
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :click_area, :clicks_area
|
||||||
|
|
||||||
# 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.
|
||||||
#
|
#
|
||||||
|
@ -200,10 +222,19 @@ module Webrat
|
||||||
button = form.find_button(value)
|
button = form.find_button(value)
|
||||||
return button if button
|
return button if button
|
||||||
end
|
end
|
||||||
|
|
||||||
flunk("Could not find button #{value.inspect}")
|
flunk("Could not find button #{value.inspect}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_area(area_name)
|
||||||
|
areas.select{|area| area.matches_text?(area_name)}.first || flunk("Could not find area with name #{area_name}")
|
||||||
|
end
|
||||||
|
|
||||||
|
def areas
|
||||||
|
(dom / "area").map do |element|
|
||||||
|
Area.new(@session, element)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def find_link(text, selector = nil)
|
def find_link(text, selector = nil)
|
||||||
matching_links = links_within(selector).select do |possible_link|
|
matching_links = links_within(selector).select do |possible_link|
|
||||||
possible_link.matches_text?(text)
|
possible_link.matches_text?(text)
|
||||||
|
|
|
@ -14,6 +14,10 @@ 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)
|
||||||
|
|
|
@ -73,7 +73,7 @@ module Webrat
|
||||||
end
|
end
|
||||||
|
|
||||||
save_and_open_page if exception_caught?
|
save_and_open_page if exception_caught?
|
||||||
flunk("Page load was not successful (Code: #{response_code.inspect})") unless success_code?
|
flunk("Page load was not successful (Code: #{response_code.inspect}):\n#{formatted_error}") unless success_code?
|
||||||
|
|
||||||
@scope = nil
|
@scope = nil
|
||||||
@current_url = url
|
@current_url = url
|
||||||
|
@ -141,12 +141,19 @@ module Webrat
|
||||||
response_html.gsub(/"\/(stylesheets|images)/, doc_root + '/\1')
|
response_html.gsub(/"\/(stylesheets|images)/, doc_root + '/\1')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Subclasses can override this to show error messages without html
|
||||||
|
def formatted_error
|
||||||
|
response_body
|
||||||
|
end
|
||||||
|
|
||||||
def_delegators :current_scope, :fill_in, :fills_in
|
def_delegators :current_scope, :fill_in, :fills_in
|
||||||
def_delegators :current_scope, :check, :checks
|
def_delegators :current_scope, :check, :checks
|
||||||
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_link, :clicks_link
|
def_delegators :current_scope, :click_link, :clicks_link
|
||||||
def_delegators :current_scope, :click_get_link, :clicks_get_link
|
def_delegators :current_scope, :click_get_link, :clicks_get_link
|
||||||
def_delegators :current_scope, :click_delete_link, :clicks_delete_link
|
def_delegators :current_scope, :click_delete_link, :clicks_delete_link
|
||||||
|
@ -156,4 +163,4 @@ module Webrat
|
||||||
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
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,7 @@ module Webrat
|
||||||
class MechanizeSession < Session
|
class MechanizeSession < Session
|
||||||
|
|
||||||
def initialize(mechanize = WWW::Mechanize.new)
|
def initialize(mechanize = WWW::Mechanize.new)
|
||||||
|
super()
|
||||||
@mechanize = mechanize
|
@mechanize = mechanize
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
Dir[File.join(File.dirname(__FILE__), "merb", "*.rb")].sort.each do |file|
|
||||||
|
require File.expand_path(file)
|
||||||
|
end
|
||||||
|
|
||||||
|
module Webrat
|
||||||
|
class Session
|
||||||
|
include Merb::Test::RequestHelper
|
||||||
|
|
||||||
|
attr_reader :response
|
||||||
|
|
||||||
|
def get(url, data, headers = nil)
|
||||||
|
do_request(url, data, headers, "GET")
|
||||||
|
end
|
||||||
|
|
||||||
|
def post(url, data, headers = nil)
|
||||||
|
do_request(url, data, headers, "POST")
|
||||||
|
end
|
||||||
|
|
||||||
|
def put(url, data, headers = nil)
|
||||||
|
do_request(url, data, headers, "PUT")
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(url, data, headers = nil)
|
||||||
|
do_request(url, data, headers, "DELETE")
|
||||||
|
end
|
||||||
|
|
||||||
|
def response_body
|
||||||
|
@response.body.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def response_code
|
||||||
|
@response.status
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
def do_request(url, data, headers, 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
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Merb::Test::RspecStory
|
||||||
|
def browser
|
||||||
|
@browser ||= Webrat::Session.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
# This class has dubious semantics and we only have it so that
|
||||||
|
# people can write params[:key] instead of params['key']
|
||||||
|
# and they get the same value for both keys.
|
||||||
|
class HashWithIndifferentAccess < Hash
|
||||||
|
def initialize(constructor = {})
|
||||||
|
if constructor.is_a?(Hash)
|
||||||
|
super()
|
||||||
|
update(constructor)
|
||||||
|
else
|
||||||
|
super(constructor)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def default(key = nil)
|
||||||
|
if key.is_a?(Symbol) && include?(key = key.to_s)
|
||||||
|
self[key]
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
|
||||||
|
alias_method :regular_update, :update unless method_defined?(:regular_update)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Assigns a new value to the hash.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# hash = HashWithIndifferentAccess.new
|
||||||
|
# hash[:key] = "value"
|
||||||
|
#
|
||||||
|
def []=(key, value)
|
||||||
|
regular_writer(convert_key(key), convert_value(value))
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Updates the instantized hash with values from the second.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# >> hash_1 = HashWithIndifferentAccess.new
|
||||||
|
# => {}
|
||||||
|
#
|
||||||
|
# >> hash_1[:key] = "value"
|
||||||
|
# => "value"
|
||||||
|
#
|
||||||
|
# >> hash_2 = HashWithIndifferentAccess.new
|
||||||
|
# => {}
|
||||||
|
#
|
||||||
|
# >> hash_2[:key] = "New Value!"
|
||||||
|
# => "New Value!"
|
||||||
|
#
|
||||||
|
# >> hash_1.update(hash_2)
|
||||||
|
# => {"key"=>"New Value!"}
|
||||||
|
#
|
||||||
|
def update(other_hash)
|
||||||
|
other_hash.each_pair { |key, value| regular_writer(convert_key(key), convert_value(value)) }
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :merge!, :update
|
||||||
|
|
||||||
|
# Checks the hash for a key matching the argument passed in
|
||||||
|
def key?(key)
|
||||||
|
super(convert_key(key))
|
||||||
|
end
|
||||||
|
|
||||||
|
alias_method :include?, :key?
|
||||||
|
alias_method :has_key?, :key?
|
||||||
|
alias_method :member?, :key?
|
||||||
|
|
||||||
|
# Fetches the value for the specified key, same as doing hash[key]
|
||||||
|
def fetch(key, *extras)
|
||||||
|
super(convert_key(key), *extras)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns an array of the values at the specified indicies.
|
||||||
|
def values_at(*indices)
|
||||||
|
indices.collect {|key| self[convert_key(key)]}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns an exact copy of the hash.
|
||||||
|
def dup
|
||||||
|
HashWithIndifferentAccess.new(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Merges the instantized and the specified hashes together, giving precedence to the values from the second hash
|
||||||
|
# Does not overwrite the existing hash.
|
||||||
|
def merge(hash)
|
||||||
|
self.dup.update(hash)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Removes a specified key from the hash.
|
||||||
|
def delete(key)
|
||||||
|
super(convert_key(key))
|
||||||
|
end
|
||||||
|
|
||||||
|
def stringify_keys!; self end
|
||||||
|
def symbolize_keys!; self end
|
||||||
|
def to_options!; self end
|
||||||
|
|
||||||
|
# Convert to a Hash with String keys.
|
||||||
|
def to_hash
|
||||||
|
Hash.new(default).merge(self)
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
def convert_key(key)
|
||||||
|
key.kind_of?(Symbol) ? key.to_s : key
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_value(value)
|
||||||
|
case value
|
||||||
|
when Hash
|
||||||
|
value.with_indifferent_access
|
||||||
|
when Array
|
||||||
|
value.collect { |e| e.is_a?(Hash) ? e.with_indifferent_access : e }
|
||||||
|
else
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
require "cgi"
|
||||||
|
|
||||||
|
module Webrat
|
||||||
|
class ParamParser
|
||||||
|
def self.parse_query_parameters(query_string)
|
||||||
|
return {} if query_string.blank?
|
||||||
|
|
||||||
|
pairs = query_string.split('&').collect do |chunk|
|
||||||
|
next if chunk.empty?
|
||||||
|
key, value = chunk.split('=', 2)
|
||||||
|
next if key.empty?
|
||||||
|
value = value.nil? ? nil : CGI.unescape(value)
|
||||||
|
[ CGI.unescape(key), value ]
|
||||||
|
end.compact
|
||||||
|
|
||||||
|
UrlEncodedPairParser.new(pairs).result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,12 @@
|
||||||
|
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
|
|
@ -0,0 +1,96 @@
|
||||||
|
require "cgi"
|
||||||
|
require "strscan"
|
||||||
|
|
||||||
|
class UrlEncodedPairParser < StringScanner #:nodoc:
|
||||||
|
attr_reader :top, :parent, :result
|
||||||
|
|
||||||
|
def initialize(pairs = [])
|
||||||
|
super('')
|
||||||
|
@result = {}
|
||||||
|
pairs.each { |key, value| parse(key, value) }
|
||||||
|
end
|
||||||
|
|
||||||
|
KEY_REGEXP = %r{([^\[\]=&]+)}
|
||||||
|
BRACKETED_KEY_REGEXP = %r{\[([^\[\]=&]+)\]}
|
||||||
|
|
||||||
|
# Parse the query string
|
||||||
|
def parse(key, value)
|
||||||
|
self.string = key
|
||||||
|
@top, @parent = result, nil
|
||||||
|
|
||||||
|
# First scan the bare key
|
||||||
|
key = scan(KEY_REGEXP) or return
|
||||||
|
key = post_key_check(key)
|
||||||
|
|
||||||
|
# Then scan as many nestings as present
|
||||||
|
until eos?
|
||||||
|
r = scan(BRACKETED_KEY_REGEXP) or return
|
||||||
|
key = self[1]
|
||||||
|
key = post_key_check(key)
|
||||||
|
end
|
||||||
|
|
||||||
|
bind(key, value)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# After we see a key, we must look ahead to determine our next action. Cases:
|
||||||
|
#
|
||||||
|
# [] follows the key. Then the value must be an array.
|
||||||
|
# = follows the key. (A value comes next)
|
||||||
|
# & or the end of string follows the key. Then the key is a flag.
|
||||||
|
# otherwise, a hash follows the key.
|
||||||
|
def post_key_check(key)
|
||||||
|
if scan(/\[\]/) # a[b][] indicates that b is an array
|
||||||
|
container(key, Array)
|
||||||
|
nil
|
||||||
|
elsif check(/\[[^\]]/) # a[b] indicates that a is a hash
|
||||||
|
container(key, Hash)
|
||||||
|
nil
|
||||||
|
else # End of key? We do nothing.
|
||||||
|
key
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add a container to the stack.
|
||||||
|
def container(key, klass)
|
||||||
|
type_conflict! klass, top[key] if top.is_a?(Hash) && top.key?(key) && ! top[key].is_a?(klass)
|
||||||
|
value = bind(key, klass.new)
|
||||||
|
type_conflict! klass, value unless value.is_a?(klass)
|
||||||
|
push(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Push a value onto the 'stack', which is actually only the top 2 items.
|
||||||
|
def push(value)
|
||||||
|
@parent, @top = @top, value
|
||||||
|
end
|
||||||
|
|
||||||
|
# Bind a key (which may be nil for items in an array) to the provided value.
|
||||||
|
def bind(key, value)
|
||||||
|
if top.is_a? Array
|
||||||
|
if key
|
||||||
|
if top[-1].is_a?(Hash) && ! top[-1].key?(key)
|
||||||
|
top[-1][key] = value
|
||||||
|
else
|
||||||
|
top << {key => value}.with_indifferent_access
|
||||||
|
push top.last
|
||||||
|
value = top[key]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
top << value
|
||||||
|
end
|
||||||
|
elsif top.is_a? Hash
|
||||||
|
key = CGI.unescape(key)
|
||||||
|
parent << (@top = {}) if top.key?(key) && parent.is_a?(Array)
|
||||||
|
top[key] ||= value
|
||||||
|
return top[key]
|
||||||
|
else
|
||||||
|
raise ArgumentError, "Don't know what to do: top is #{top.inspect}"
|
||||||
|
end
|
||||||
|
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
|
def type_conflict!(klass, value)
|
||||||
|
raise TypeError, "Conflicting types for parameter containers. Expected an instance of #{klass} but found an instance of #{value.class}. This can be caused by colliding Array and Hash parameters like qs[]=value&qs[key]=value. (The parameters received were #{value.inspect}.)"
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,5 +1,5 @@
|
||||||
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
require File.expand_path(File.dirname(__FILE__) + "/../spec_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
|
||||||
|
@ -70,3 +70,4 @@ describe "attaches_file" do
|
||||||
@session.clicks_button
|
@session.clicks_button
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
|
@ -0,0 +1,81 @@
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
||||||
|
|
||||||
|
describe "clicks_area" do
|
||||||
|
before do
|
||||||
|
@session = Webrat::TestSession.new
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should use get by default" 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.should_receive(:get).with("/page", {})
|
||||||
|
@session.clicks_area "Berlin"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should assert valid response" 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 = 404
|
||||||
|
lambda { @session.clicks_area "Berlin" }.should raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should fail if the area doesn't exist" 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
|
||||||
|
|
||||||
|
lambda {
|
||||||
|
@session.clicks_area "Missing area"
|
||||||
|
}.should raise_error
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should not be case sensitive" 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.should_receive(:get).with("/page", {})
|
||||||
|
@session.clicks_area "berlin"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
it "should follow relative links" do
|
||||||
|
@session.stub!(:current_url).and_return("/page")
|
||||||
|
@session.response_body = <<-EOS
|
||||||
|
<map name="map_de" id="map_de">
|
||||||
|
<area href="sub" title="Berlin" id="berlin" shape="poly" alt="Berlin" coords="180,89,180" />
|
||||||
|
</map>
|
||||||
|
EOS
|
||||||
|
@session.should_receive(:get).with("/page/sub", {})
|
||||||
|
@session.clicks_area "Berlin"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should follow fully qualified local links" do
|
||||||
|
@session.response_body = <<-EOS
|
||||||
|
<map name="map_de" id="map_de">
|
||||||
|
<area href="http://www.example.com/page" title="Berlin" id="berlin" shape="poly" alt="Berlin" coords="180,89,180" />
|
||||||
|
</map>
|
||||||
|
EOS
|
||||||
|
@session.should_receive(:get).with("http://www.example.com/page", {})
|
||||||
|
@session.clicks_area "Berlin"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should follow query parameters" do
|
||||||
|
@session.response_body = <<-EOS
|
||||||
|
<map name="map_de" id="map_de">
|
||||||
|
<area href="/page?foo=bar" title="Berlin" id="berlin" shape="poly" alt="Berlin" coords="180,89,180" />
|
||||||
|
</map>
|
||||||
|
EOS
|
||||||
|
@session.should_receive(:get).with("/page?foo=bar", {})
|
||||||
|
@session.clicks_area "Berlin"
|
||||||
|
end
|
||||||
|
end
|
|
@ -144,6 +144,18 @@ describe "fills_in" do
|
||||||
@session.fills_in "user[email]", :with => "foo@example.com"
|
@session.fills_in "user[email]", :with => "foo@example.com"
|
||||||
@session.clicks_button
|
@session.clicks_button
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should work if the input type is not set" do
|
||||||
|
@session.response_body = <<-EOS
|
||||||
|
<form method="post" action="/login">
|
||||||
|
<input id="user_email" name="user[email]" />
|
||||||
|
<input type="submit" />
|
||||||
|
</form>
|
||||||
|
EOS
|
||||||
|
@session.should_receive(:post).with("/login", "user" => {"email" => "foo@example.com"})
|
||||||
|
@session.fills_in "user[email]", :with => "foo@example.com"
|
||||||
|
@session.clicks_button
|
||||||
|
end
|
||||||
|
|
||||||
it "should work with symbols" do
|
it "should work with symbols" do
|
||||||
@session.response_body = <<-EOS
|
@session.response_body = <<-EOS
|
||||||
|
@ -157,4 +169,17 @@ describe "fills_in" do
|
||||||
@session.fills_in :email, :with => "foo@example.com"
|
@session.fills_in :email, :with => "foo@example.com"
|
||||||
@session.clicks_button
|
@session.clicks_button
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should escape field values" do
|
||||||
|
@session.response_body = <<-EOS
|
||||||
|
<form method="post" action="/users">
|
||||||
|
<label for="user_phone">Phone</label>
|
||||||
|
<input id="user_phone" name="user[phone]" type="text" />
|
||||||
|
<input type="submit" />
|
||||||
|
</form>
|
||||||
|
EOS
|
||||||
|
@session.should_receive(:post).with("/users", "user" => {"phone" => "+1 22 33"})
|
||||||
|
@session.fills_in 'Phone', :with => "+1 22 33"
|
||||||
|
@session.clicks_button
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
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
|
|
@ -108,6 +108,18 @@ 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">
|
||||||
|
|
|
@ -5,17 +5,17 @@ require "spec/interop/test"
|
||||||
# gem install redgreen for colored test output
|
# gem install redgreen for colored test output
|
||||||
begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end
|
begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end
|
||||||
|
|
||||||
require "active_support"
|
|
||||||
|
|
||||||
silence_warnings do
|
|
||||||
require "action_controller"
|
|
||||||
require "action_controller/integration"
|
|
||||||
end
|
|
||||||
|
|
||||||
require File.expand_path(File.dirname(__FILE__) + "/../lib/webrat")
|
require File.expand_path(File.dirname(__FILE__) + "/../lib/webrat")
|
||||||
require File.expand_path(File.dirname(__FILE__) + "/../lib/webrat/rails")
|
|
||||||
require File.dirname(__FILE__) + "/fakes/test_session"
|
require 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
|
||||||
end
|
end
|
|
@ -0,0 +1,13 @@
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + "/../../../lib/webrat/mechanize")
|
||||||
|
|
||||||
|
describe Webrat::MechanizeSession do
|
||||||
|
before(:each) do
|
||||||
|
@mech = Webrat::MechanizeSession.new
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "headers method" do
|
||||||
|
it "should return empty headers for a newly initialized session" do
|
||||||
|
@mech.headers.should == {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,2 @@
|
||||||
|
require 'merb-core'
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + "/../../../lib/webrat/merb")
|
|
@ -0,0 +1,48 @@
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + "/helper")
|
||||||
|
|
||||||
|
describe HashWithIndifferentAccess do
|
||||||
|
it "should not update constructor when not a hash" do
|
||||||
|
HashWithIndifferentAccess.should_receive(:update).never
|
||||||
|
HashWithIndifferentAccess.new('test')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should get the default for key" do
|
||||||
|
h = HashWithIndifferentAccess.new(:test => 'me')
|
||||||
|
h.should_receive(:super).never
|
||||||
|
|
||||||
|
h.default(:test).should == 'me'
|
||||||
|
end
|
||||||
|
|
||||||
|
context "a hash with a test value applied" do
|
||||||
|
|
||||||
|
setup do
|
||||||
|
@h = HashWithIndifferentAccess.new
|
||||||
|
@h[:test] = 'me'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should assign a new value" do
|
||||||
|
@h[:test].should == 'me'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return true if asked for existing key" do
|
||||||
|
@h.key?(:test).should be_true
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return array of values for keys" do
|
||||||
|
@h.values_at(:test).should == ['me']
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should merge with another hash" do
|
||||||
|
another = HashWithIndifferentAccess.new(:value => 'test')
|
||||||
|
@h.merge(another).values_at(:test, :value).should == ['me','test']
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should delete the key" do
|
||||||
|
@h.delete(:test)
|
||||||
|
@h.any?.should be_false
|
||||||
|
@h[:test].should be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,43 @@
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper")
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + "/helper")
|
||||||
|
|
||||||
|
describe Webrat::Session do
|
||||||
|
|
||||||
|
it "should not pass empty params if data is and empty hash" do
|
||||||
|
session = Webrat::Session.new
|
||||||
|
response = OpenStruct.new
|
||||||
|
response.status = 200
|
||||||
|
session.should_receive(:request).with('url', {:params=> nil, :method=>"GET", :headers=>nil}).and_return(response)
|
||||||
|
session.get('url', {}, nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
%w{post put delete}.each do |request_method|
|
||||||
|
it "should call do request with method #{request_method.upcase} for a #{request_method} call" do
|
||||||
|
session = Webrat::Session.new
|
||||||
|
response = OpenStruct.new
|
||||||
|
response.status = 200
|
||||||
|
|
||||||
|
session.should_receive(:request).with('url', {:params=>nil, :method=>request_method.upcase, :headers=>nil}).and_return(response)
|
||||||
|
session.send(request_method, 'url', {}, nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "a session with a response" do
|
||||||
|
|
||||||
|
setup do
|
||||||
|
@session = Webrat::Session.new
|
||||||
|
@response = OpenStruct.new
|
||||||
|
@response.status = 200
|
||||||
|
@response.body = 'test response'
|
||||||
|
@session.instance_variable_set(:@response, @response)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return body of a request as a response_body" do
|
||||||
|
@session.response_body.should == @response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return status of a request as a response_code" do
|
||||||
|
@session.response_code.should == @response.status
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
require "active_support"
|
||||||
|
|
||||||
|
silence_warnings do
|
||||||
|
require "action_controller"
|
||||||
|
require "action_controller/integration"
|
||||||
|
end
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + "/../../../lib/webrat/rails")
|
Loading…
Reference in New Issue