diff --git a/.gitignore b/.gitignore index 023f45e..786969e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ log .loadpath *.swp results +test_apps \ No newline at end of file diff --git a/History.txt b/History.txt index c3c6f97..3d4c7b9 100644 --- a/History.txt +++ b/History.txt @@ -6,9 +6,13 @@ * Removed auto-require of webrat/rails when requiring webrat when RAILS_ENV is defined - In your env.rb file, ensure you have: + In your env.rb or test_helper.rb file, ensure you have something like: - require "webrat/rails" + require "webrat" + + Webrat.configure do |config| + config.mode = :rails + end * Major enhancements @@ -16,7 +20,10 @@ * Use Hpricot and REXML when not parsing with Nokogiri (on JRuby, for example) * Minor enhancements - * Now sets the mode with configuration.mode in the block (Mike Gaffney, Ticket #85) + * Added assert_contain, assert_not_contain [#86] (Mike Gaffney) + * Maximize the browser window after initializing Selenium (Luke Melia) + * Better inspect output for Webrat elements + * Sets the Webrat mode with Configuration#mode= in the config block [#85] (Mike Gaffney) * Detect if the document is XML or HTML using the Content-Type when in Rails mode * Expose #selenium method for direct access to Selenium client * Check nokogiri gem version before requiring nokogiri @@ -50,6 +57,8 @@ * Raise Webrat::PageLoadError when a failure occurs so that application exceptions can be more accurately tested (Ryan Briones) * Helpful error message for missing option in select box. [#40] (Ben Mabey) + * Extracted save_and_open page to make it usable in Selenium mode (Luke Melia) + * Added save_and_open_screengrab for Selenium mode (Luke Melia) * Bug fixes @@ -66,6 +75,13 @@ * Extend Rails' ActionController::IntegrationTest instead of ActionController::Integration::Session (Fixes using Webrat's #select method and avoids usage of method_missing) + * Ensure that Webrat::MechanizeSession.request_page always uses an absolute + URL. (Graham Ashton) + * Strip anchor tags from URIs before passing to Rails integration session + (Noah Davis) + * Treat text and regexp when matching Selenium buttons (Ross Kaffenberger) + * Allow SeleniumSession's click_button to be called without an argument without + blowing up (Luke Melia) == 0.3.2 / 2008-11-08 diff --git a/README.rdoc b/README.rdoc index 35b5c0c..f08a62d 100644 --- a/README.rdoc +++ b/README.rdoc @@ -59,11 +59,12 @@ To install the latest code as a plugin: (_Note:_ This may be less stable than us script/plugin install git://github.com/brynary/webrat.git -In your test_helper.rb, spec_helper.rb, or env.rb (for Cucumber) add: +In your test_helper.rb or env.rb (for Cucumber) add: require "webrat" + Webrat.configure do |config| - config.mode = Webrat::Configuration::RAILS_MODE + config.mode = :rails end == Install with Merb diff --git a/lib/webrat.rb b/lib/webrat.rb index c80d952..dde942e 100644 --- a/lib/webrat.rb +++ b/lib/webrat.rb @@ -7,7 +7,7 @@ module Webrat class WebratError < StandardError end - VERSION = '0.3.2.1' + VERSION = '0.3.2.2' def self.require_xml gem "nokogiri", ">= 1.0.6" diff --git a/lib/webrat/core.rb b/lib/webrat/core.rb index 26d9962..5d8a57e 100644 --- a/lib/webrat/core.rb +++ b/lib/webrat/core.rb @@ -11,3 +11,4 @@ require "webrat/core/elements/select_option" require "webrat/core/session" require "webrat/core/methods" require "webrat/core/matchers" +require "webrat/core/save_and_open_page" diff --git a/lib/webrat/core/elements/element.rb b/lib/webrat/core/elements/element.rb index 6261d9f..a8784a2 100644 --- a/lib/webrat/core/elements/element.rb +++ b/lib/webrat/core/elements/element.rb @@ -24,6 +24,10 @@ module Webrat Webrat::XML.xpath_to(@element) end + def inspect + "#<#{self.class} @element=#{element.inspect}>" + end + end end \ No newline at end of file diff --git a/lib/webrat/core/save_and_open_page.rb b/lib/webrat/core/save_and_open_page.rb new file mode 100644 index 0000000..a3c97f5 --- /dev/null +++ b/lib/webrat/core/save_and_open_page.rb @@ -0,0 +1,50 @@ +module Webrat + module SaveAndOpenPage + # Saves the page out to RAILS_ROOT/tmp/ and opens it in the default + # web browser if on OS X. Useful for debugging. + # + # Example: + # save_and_open_page + def save_and_open_page + return unless File.exist?(saved_page_dir) + + filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.html" + + File.open(filename, "w") do |f| + f.write rewrite_css_and_image_references(response_body) + end + + open_in_browser(filename) + end + + def open_in_browser(path) # :nodoc + platform = ruby_platform + if platform =~ /cygwin/ || platform =~ /win32/ + `rundll32 url.dll,FileProtocolHandler #{path.gsub("/", "\\\\")}` + elsif platform =~ /darwin/ + `open #{path}` + end + end + + def rewrite_css_and_image_references(response_html) # :nodoc: + return response_html unless doc_root + response_html.gsub(/"\/(stylesheets|images)/, doc_root + '/\1') + end + + def saved_page_dir #:nodoc: + File.expand_path(".") + end + + def doc_root #:nodoc: + nil + end + + private + + # accessor for testing + def ruby_platform + RUBY_PLATFORM + end + + end +end \ No newline at end of file diff --git a/lib/webrat/core/session.rb b/lib/webrat/core/session.rb index 0ca3ffa..fe4f44c 100644 --- a/lib/webrat/core/session.rb +++ b/lib/webrat/core/session.rb @@ -2,6 +2,7 @@ require "forwardable" require "ostruct" require "webrat/core/mime" +require "webrat/core/save_and_open_page" module Webrat # A page load or form submission returned an unsuccessful response code (500-599) @@ -30,6 +31,7 @@ module Webrat class Session extend Forwardable include Logging + include SaveAndOpenPage attr_reader :current_url attr_reader :elements @@ -43,23 +45,6 @@ module Webrat reset end - - # Saves the page out to RAILS_ROOT/tmp/ and opens it in the default - # web browser if on OS X. Useful for debugging. - # - # Example: - # save_and_open_page - def save_and_open_page - return unless File.exist?(saved_page_dir) - - filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.html" - - File.open(filename, "w") do |f| - f.write rewrite_css_and_image_references(response_body) - end - - open_in_browser(filename) - end def current_dom #:nodoc: current_scope.dom @@ -78,10 +63,6 @@ module Webrat nil end - def saved_page_dir #:nodoc: - File.expand_path(".") - end - def header(key, value) @custom_headers[key] = value end @@ -172,20 +153,6 @@ module Webrat end webrat_deprecate :visits, :visit - - def open_in_browser(path) # :nodoc - platform = ruby_platform - if platform =~ /cygwin/ || platform =~ /win32/ - `rundll32 url.dll,FileProtocolHandler #{path.gsub("/", "\\\\")}` - elsif platform =~ /darwin/ - `open #{path}` - end - end - - def rewrite_css_and_image_references(response_html) # :nodoc: - return response_html unless doc_root - response_html.gsub(/"\/(stylesheets|images)/, doc_root + '/\1') - end # Subclasses can override this to show error messages without html def formatted_error #:nodoc: @@ -247,9 +214,5 @@ module Webrat @_page_scope = nil end - # accessor for testing - def ruby_platform - RUBY_PLATFORM - end end end diff --git a/lib/webrat/mechanize.rb b/lib/webrat/mechanize.rb index 6f1a656..41fe41b 100644 --- a/lib/webrat/mechanize.rb +++ b/lib/webrat/mechanize.rb @@ -6,6 +6,10 @@ module Webrat #:nodoc: attr_accessor :response alias :page :response + def request_page(url, http_method, data) #:nodoc: + super(absolute_url(url), http_method, data) + end + def get(url, data, headers_argument_not_used = nil) @response = mechanize.get(url, data) end @@ -36,6 +40,35 @@ module Webrat #:nodoc: end def_delegators :mechanize, :basic_auth + + def absolute_url(url) #:nodoc: + current_host, current_path = split_current_url + if url =~ Regexp.new('^https?://') + url + elsif url =~ Regexp.new('^/') + current_host + url + elsif url =~ Regexp.new('^\.') + current_host + absolute_path(current_path, url) + else + url + end + end + + private + def split_current_url + current_url =~ Regexp.new('^(https?://[^/]+)(/.*)?') + [Regexp.last_match(1), Regexp.last_match(2)] + end + def absolute_path(current_path, url) + levels_up = url.split('/').find_all { |x| x == '..' }.size + ancestor = if current_path.nil? + "" + else + current_path.split("/")[0..(-1 - levels_up)].join("/") + end + descendent = url.split("/")[levels_up..-1] + "#{ancestor}/#{descendent}" + end end end diff --git a/lib/webrat/rails.rb b/lib/webrat/rails.rb index 216a966..f3f8379 100644 --- a/lib/webrat/rails.rb +++ b/lib/webrat/rails.rb @@ -1,4 +1,6 @@ require "webrat" + +require "action_controller" require "action_controller/integration" module Webrat @@ -48,15 +50,18 @@ module Webrat def do_request(http_method, url, data, headers) #:nodoc: update_protocol(url) - integration_session.request_via_redirect(http_method, remove_protocol(url), data, headers) + url = normalize_url(url) + integration_session.request_via_redirect(http_method, url, data, headers) end - def remove_protocol(href) #:nodoc: - if href =~ %r{^https?://www.example.com(/.*)} - $LAST_MATCH_INFO.captures.first - else - href + # remove protocol, host and anchor + def normalize_url(href) #:nodoc: + uri = URI.parse(href) + normalized_url = uri.path + if uri.query + normalized_url += "?" + uri.query end + normalized_url end def update_protocol(href) #:nodoc: diff --git a/lib/webrat/selenium.rb b/lib/webrat/selenium.rb index 21e333a..3e8b999 100644 --- a/lib/webrat/selenium.rb +++ b/lib/webrat/selenium.rb @@ -38,14 +38,10 @@ module Webrat # To use Webrat's Selenium support, you'll need the selenium-client gem installed. # Activate it with (for example, in your env.rb): # - # require "webrat/selenium" - # - # Then, if you're using Cucumber, configure it to use a - # Webrat::Selenium::Rails::World as the scenario context by adding - # the following to env.rb: - # - # World do - # Webrat::Selenium::Rails::World.new + # require "webrat" + # + # Webrat.configure do |config| + # config.mode = :selenium # end # # == Dropping down to the selenium-client API @@ -72,31 +68,26 @@ module Webrat # your Webrat::Selenium tests ignoring the concurrency issues that can plague in-browser # testing, so long as you're using the Webrat API. module Selenium - - module Rails #:nodoc: - class World < ::ActionController::IntegrationTest - include Webrat::Selenium::Matchers - - def initialize #:nodoc: - @_result = Test::Unit::TestResult.new - end - - def response - webrat_session.response - end - - def wait_for(*args, &block) - webrat_session.wait_for(*args, &block) - end - + module Methods + def response + webrat_session.response + end + + def wait_for(*args, &block) + webrat_session.wait_for(*args, &block) + end + + def save_and_open_screengrab + webrat_session.save_and_open_screengrab end end end - end module ActionController #:nodoc: IntegrationTest.class_eval do include Webrat::Methods + include Webrat::Selenium::Methods + include Webrat::Selenium::Matchers end end diff --git a/lib/webrat/selenium/selenium_session.rb b/lib/webrat/selenium/selenium_session.rb index 0b61e95..460269e 100644 --- a/lib/webrat/selenium/selenium_session.rb +++ b/lib/webrat/selenium/selenium_session.rb @@ -1,3 +1,5 @@ +require "webrat/core/save_and_open_page" + module Webrat class TimeoutError < WebratError end @@ -17,6 +19,7 @@ module Webrat end class SeleniumSession + include Webrat::SaveAndOpenPage def initialize(*args) # :nodoc: end @@ -53,7 +56,7 @@ module Webrat def click_button(button_text_or_regexp = nil, options = {}) if button_text_or_regexp.is_a?(Hash) && options == {} pattern, options = nil, button_text_or_regexp - else + elsif button_text_or_regexp pattern = adjust_if_regexp(button_text_or_regexp) end pattern ||= '*' @@ -160,6 +163,20 @@ module Webrat webrat_deprecate :browser, :selenium + + def save_and_open_screengrab + return unless File.exist?(saved_page_dir) + + filename = "#{saved_page_dir}/webrat-#{Time.now.to_i}.png" + + if $browser.chrome_backend? + $browser.capture_entire_page_screenshot(filename, '') + else + $browser.capture_screenshot(filename) + end + open_in_browser(filename) + end + protected def setup #:nodoc: @@ -175,6 +192,7 @@ module Webrat extend_selenium define_location_strategies + $browser.window_maximize end def teardown_at_exit #:nodoc: @@ -191,7 +209,7 @@ module Webrat if text_or_regexp.is_a?(Regexp) "evalregex:#{text_or_regexp.inspect}" else - text_or_regexp + "evalregex:/#{text_or_regexp}/" end end diff --git a/spec/api/click_button_spec.rb b/spec/api/click_button_spec.rb index 6e19c80..e639b66 100644 --- a/spec/api/click_button_spec.rb +++ b/spec/api/click_button_spec.rb @@ -330,7 +330,7 @@ describe "click_button" do end it "should properly handle HTML entities in textarea default values" do - pending "needs bug fix" do + spec = lambda do with_html <<-HTML
+ + HTML + + webrat_session.should_receive(:get).with("/form2", "email" => "test@example.com") + within ".important" do + fill_in "Email", :with => "test@example.com" + end + + submit_form "form2" + end + end + it "should not find buttons outside of the scope" do with_html <<-HTML diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 640b41d..d2012bf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -7,27 +7,9 @@ begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end webrat_path = File.expand_path(File.dirname(__FILE__) + "/../lib/") $LOAD_PATH.unshift(webrat_path) unless $LOAD_PATH.include?(webrat_path) -require "merb-core" -require "webrat/merb" - require "webrat" require File.expand_path(File.dirname(__FILE__) + "/fakes/test_session") -Spec::Runner.configure do |config| - include Webrat::Methods - - def with_html(html) - raise "This doesn't look like HTML. Wrap it in a tag" unless html =~ /^\s*<[^Hh>]*html/i - webrat_session.response_body = html - end - - def with_xml(xml) - raise "This looks like HTML" if xml =~ /^\s*<[^Hh>]*html/i - webrat_session.response_body = xml - end - -end - module Webrat @@previous_config = nil @@ -38,10 +20,30 @@ module Webrat def self.reset_for_test @@configuration = @@previous_config if @@previous_config end +end + +Spec::Runner.configure do |config| + include Webrat::Methods - class Configuration - def mode_for_test= (mode) - @mode = mode - end + def with_html(html) + raise "This doesn't look like HTML. Wrap it in a tag" unless html =~ /^\s*<[^Hh>]*html/i + webrat_session.response_body = html end + + def with_xml(xml) + raise "This looks like HTML" if xml =~ /^\s*<[^Hh>]*html/i + webrat_session.response_body = xml + end + + config.before :each do + Webrat.cache_config_for_test + end + + config.after :each do + Webrat.reset_for_test + end +end + +Webrat.configure do |config| + config.mode = :merb end \ No newline at end of file diff --git a/spec/webrat/core/configuration_spec.rb b/spec/webrat/core/configuration_spec.rb index b03f499..6c22565 100755 --- a/spec/webrat/core/configuration_spec.rb +++ b/spec/webrat/core/configuration_spec.rb @@ -4,14 +4,6 @@ describe Webrat::Configuration do predicate_matchers[:parse_with_nokogiri] = :parse_with_nokogiri? predicate_matchers[:open_error_files] = :open_error_files? - before do - Webrat.cache_config_for_test - end - - after do - Webrat.reset_for_test - end - it "should have a mode" do Webrat.configuration.should respond_to(:mode) end diff --git a/spec/webrat/core/field_spec.rb b/spec/webrat/core/field_spec.rb index fa741f9..1a3fdd9 100644 --- a/spec/webrat/core/field_spec.rb +++ b/spec/webrat/core/field_spec.rb @@ -1,6 +1,20 @@ require File.expand_path(File.dirname(__FILE__) + "/../../spec_helper") module Webrat + describe Field do + it "should have nice inspect output" do + html = <<-HTML + + + + HTML + + element = Webrat::XML.css_search(Webrat::XML.document(html), "input").first + checkbox = CheckboxField.new(nil, element) + checkbox.inspect.should =~ /#