Skip to content

Commit

Permalink
Merge remote branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
trammel committed Nov 9, 2009
2 parents 0aa10cd + f51b745 commit bc283d8
Show file tree
Hide file tree
Showing 36 changed files with 597 additions and 169 deletions.
16 changes: 14 additions & 2 deletions History.txt
@@ -1,22 +1,34 @@
== Git
== 0.6.rc1 / 2009-09-22

REMOVED: Support for Hpricot + REXML as an alternative to Nokogiri.

Hpricot and REXML were difficult to work with, REXML is terribly slow,
and Nokogiri is recommended even by the author of Hpricot (_why). Now
that Nokogiri works on JRuby, Webrat is going to use it as it's sole
that Nokogiri works on JRuby, Webrat is going to use it as its sole
XML backend.

CHANGED: Due to a reorganization, if you're currently requiring "webrat/rspec-rails",
please change your code to require "webrat/integrations/rspec-rails"

* Minor enhancements

* When a timeout occurs in wait_for, include the HTML from Selenium in the exception
* Update the Merb support to be based directly on Rack (Simon Rozet)
* Support multiple select fields (Kieran P)
* When locating select options, always match against text, not HTML

* Bug fixes

* Fix logger issue when running inside Cucumber (Damian Janowski)
* Fix various issues related to submitting values with HTML entities (Kieran P)
* Call #to_i on the :count option in matchers (Michael Christenson II)
* Fix bug where multiline param values were getting truncated

== 0.5.3 / 2009-08-27

* Minor enhancements

* Remove unnecessary requires which are to the wrong paths on Edge Rails

== 0.5.1 / 2009-08-18

Expand Down
69 changes: 37 additions & 32 deletions Rakefile
Expand Up @@ -2,7 +2,12 @@ require "rubygems"

begin
require 'jeweler'

rescue LoadError
desc "Install gem using sudo"
task(:install) do
$stderr.puts "Jeweler not available. `gem install jeweler` to install this gem"
end
else
Jeweler::Tasks.new do |s|
s.name = "webrat"
s.author = "Bryan Helmkamp"
Expand All @@ -25,36 +30,35 @@ Most Ruby web frameworks and testing frameworks are supported.
s.add_dependency "nokogiri", ">= 1.2.0"
s.add_dependency "rack", ">= 1.0"

# TODO: Add development dependencies
s.add_development_dependency "rails", ">= 2.3"
s.add_development_dependency "merb-core", ">= 1.0"
s.add_development_dependency "launchy"
end

Jeweler::RubyforgeTasks.new
rescue LoadError
puts "Jeweler not available. Install it with: gem install jeweler"
end

# require 'spec'
require 'spec/rake/spectask'
require 'spec/rake/verify_rcov'

desc "Run API and Core specs"
Spec::Rake::SpecTask.new do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = FileList['spec/public/**/*_spec.rb'] + FileList['spec/private/**/*_spec.rb']
end

desc "Run all specs in spec directory with RCov"
Spec::Rake::SpecTask.new(:rcov) do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = FileList['spec/public/**/*_spec.rb'] + FileList['spec/private/**/*_spec.rb']
t.rcov = true
t.rcov_opts = lambda do
IO.readlines(File.dirname(__FILE__) + "/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
begin
require 'spec/rake/spectask'
rescue LoadError
desc "Run specs"
task(:spec) { $stderr.puts '`gem install rspec` to run specs' }
else
desc "Run API and Core specs"
Spec::Rake::SpecTask.new do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = FileList['spec/public/**/*_spec.rb'] + FileList['spec/private/**/*_spec.rb']
end
end

RCov::VerifyTask.new(:verify_rcov => :rcov) do |t|
t.threshold = 96.2 # Make sure you have rcov 0.7 or higher!
desc "Run all specs in spec directory with RCov"
Spec::Rake::SpecTask.new(:rcov) do |t|
t.spec_opts = ['--options', "\"#{File.dirname(__FILE__)}/spec/spec.opts\""]
t.spec_files = FileList['spec/public/**/*_spec.rb'] + FileList['spec/private/**/*_spec.rb']
t.rcov = true
t.rcov_opts = lambda do
IO.readlines(File.dirname(__FILE__) + "/spec/rcov.opts").map {|l| l.chomp.split " "}.flatten
end
end
end

desc "Run everything against multiruby"
Expand Down Expand Up @@ -109,18 +113,18 @@ task :spec_deps do
end
end

task :prepare do
system "ln -s ../../../../.. ./spec/integration/rails/vendor/plugins/webrat"
end

namespace :spec do
desc "Run the integration specs"
task :integration => ["integration:rails", "integration:merb", "integration:sinatra", "integration:rack", "integration:mechanize"]
task :integration => [
"integration:rack",
"integration:sinatra",
"integration:merb",
"integration:mechanize",
"integration:rails:webrat",
"integration:rails:selenium",
]

namespace :integration do
desc "Run the Rails integration specs"
task :rails => ['rails:webrat'] #,'rails:selenium'] currently not running selenium as it doesn't pass.

namespace :rails do
task :selenium do
Dir.chdir "spec/integration/rails" do
Expand Down Expand Up @@ -178,6 +182,7 @@ end

if defined?(Jeweler)
task :spec => :check_dependencies
task :build => :gemspec
end

task :default => :spec
2 changes: 2 additions & 0 deletions lib/webrat.rb
Expand Up @@ -2,6 +2,8 @@
require "nokogiri"

module Webrat
VERSION = "0.6.rc1"

autoload :MechanizeAdapter, "webrat/adapters/mechanize"
autoload :MerbAdapter, "webrat/adapters/merb"
autoload :RackAdapter, "webrat/adapters/rack"
Expand Down
17 changes: 1 addition & 16 deletions lib/webrat/adapters/rails.rb
Expand Up @@ -11,21 +11,6 @@ def initialize(session)
@integration_session = session
end

# The Rails version of within supports passing in a model and Webrat
# will apply a scope based on Rails' dom_id for that model.
#
# Example:
# within User.last do
# click_link "Delete"
# end
def within(selector_or_object, &block)
if selector_or_object.is_a?(String)
super
else
super('#' + dom_id(selector_or_object), &block)
end
end

def doc_root
File.expand_path(File.join(RAILS_ROOT, 'public'))
end
Expand Down Expand Up @@ -93,4 +78,4 @@ def response #:nodoc:
integration_session.response
end
end
end
end
89 changes: 84 additions & 5 deletions lib/webrat/core/elements/field.rb
Expand Up @@ -38,7 +38,12 @@ def self.load(session, element)
def self.field_class(element)
case element.name
when "button" then ButtonField
when "select" then SelectField
when "select"
if element.attributes["multiple"].nil?
SelectField
else
MultipleSelectField
end
when "textarea" then TextareaField
else
case element["type"]
Expand Down Expand Up @@ -82,14 +87,16 @@ def raise_error_if_disabled
def to_param
return nil if disabled?

case Webrat.configuration.mode
params = case Webrat.configuration.mode
when :rails
parse_rails_request_params("#{name}=#{escaped_value}")
when :merb
::Merb::Parse.query("#{name}=#{escaped_value}")
else
{ name => value }
{ name => [*@value].first.to_s }
end

unescape_params(params)
end

def set(value)
Expand Down Expand Up @@ -132,7 +139,22 @@ def name
end

def escaped_value
CGI.escape([*@value].first.to_s)
CGI.escape(@value.to_s)
end

# Because we have to escape it before sending it to the above case statement,
# we have to make sure we unescape each value when it gets back so assertions
# involving characters like <, >, and & work as expected
def unescape_params(params)
case params.class.name
when 'Hash', 'Mash'
params.each { |key,value| params[key] = unescape_params(value) }
params
when 'Array'
params.collect { |value| unescape_params(value) }
else
CGI.unescapeHTML(params)
end
end

def labels
Expand Down Expand Up @@ -385,24 +407,81 @@ def self.xpath_search
class SelectField < Field #:nodoc:

def self.xpath_search
[".//select"]
[".//select[not(@multiple)]"]
end

def options
@options ||= SelectOption.load_all(@session, @element)
end

def unset(value)
@value = nil
end

protected

def default_value
selected_options = @element.xpath(".//option[@selected = 'selected']")
selected_options = @element.xpath(".//option[position() = 1]") if selected_options.empty?

selected_options.map do |option|
return "" if option.nil?
option["value"] || option.inner_html
end.uniq.first
end

end

class MultipleSelectField < Field #:nodoc:

def self.xpath_search
[".//select[@multiple='multiple']"]
end

def options
@options ||= SelectOption.load_all(@session, @element)
end

def set(value)
@value << value
end

def unset(value)
@value.delete(value)
end

# We have to overide how the uri string is formed when dealing with multiples
# Where normally a select field might produce name=value with a multiple,
# we need to form something like name[]=value1&name[]=value2
def to_param
return nil if disabled?

uri_string = @value.collect {|value| "#{name}=#{CGI.escape(value)}"}.join("&")
params = case Webrat.configuration.mode
when :rails
parse_rails_request_params(uri_string)
when :merb
::Merb::Parse.query(uri_string)
else
{ name => @value }
end

unescape_params(params)
end

protected

# Overwrite SelectField definition because we don't want to select the first option
# (mutliples don't select the first option unlike their non multiple versions)
def default_value
selected_options = @element.xpath(".//option[@selected = 'selected']")

selected_options.map do |option|
return "" if option.nil?
option["value"] || option.inner_html
end.uniq
end

end

end
13 changes: 13 additions & 0 deletions lib/webrat/core/elements/select_option.rb
Expand Up @@ -12,6 +12,15 @@ def choose
select.set(value)
end

def unchoose
select.raise_error_if_disabled
select.unset(value)
end

def inner_text
@element.inner_text
end

protected

def select
Expand All @@ -31,5 +40,9 @@ def value
@element["value"] || @element.inner_html
end

def label
@element.inner_html
end

end
end
8 changes: 4 additions & 4 deletions lib/webrat/core/locators/select_option_locator.rb
Expand Up @@ -19,17 +19,17 @@ def locate

field.options.detect do |o|
if @option_text.is_a?(Regexp)
o.element.inner_html =~ @option_text
o.element.inner_text =~ @option_text
else
o.element.inner_html == @option_text.to_s
o.inner_text == @option_text.to_s
end
end
else
option_element = option_elements.detect do |o|
if @option_text.is_a?(Regexp)
o.inner_html =~ @option_text
o.inner_text =~ @option_text
else
o.inner_html == @option_text.to_s
o.inner_text == @option_text.to_s
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/webrat/core/matchers/have_xpath.rb
Expand Up @@ -15,7 +15,7 @@ def matches?(stringlike, &block)
matched = matches(stringlike)

if @options[:count]
matched.size == @options[:count] && (!@block || @block.call(matched))
matched.size == @options[:count].to_i && (!@block || @block.call(matched))
else
matched.any? && (!@block || @block.call(matched))
end
Expand Down
1 change: 1 addition & 0 deletions lib/webrat/core/methods.rb
Expand Up @@ -39,6 +39,7 @@ def webrat_session
:unchecks, :uncheck,
:chooses, :choose,
:selects, :select,
:unselects, :unselect,
:attaches_file, :attach_file,
:current_page,
:current_url,
Expand Down

0 comments on commit bc283d8

Please sign in to comment.