From 2d94653c43a1602d4b12fa34462b10e70f1f3251 Mon Sep 17 00:00:00 2001 From: Guillaume Godet-Bar Date: Fri, 8 May 2009 16:49:35 +0200 Subject: [PATCH 1/2] Webrat manages simple Ajax calls (i.e. which do not affect the dom but e.g. the rails session), using the ajax(http_method, url, data, headers) method) --- lib/webrat/core/locators/locator.rb | 3 ++ lib/webrat/core/methods.rb | 1 + lib/webrat/core/session.rb | 42 ++++++++++++++++++++++++++ lib/webrat/rails.rb | 22 +++++++++++-- spec/integration/rails/config/environment.rb | 2 +- spec/private/rails/rails_session_spec.rb | 7 ++++ 6 files changed, 73 insertions(+), 4 deletions(-) diff --git a/lib/webrat/core/locators/locator.rb b/lib/webrat/core/locators/locator.rb index 45a350c..37a9bb1 100644 --- a/lib/webrat/core/locators/locator.rb +++ b/lib/webrat/core/locators/locator.rb @@ -11,6 +11,9 @@ module Webrat end def locate! + if @session.response_from_xhr? + warn "CONSISTENCY WARNING: Might not be able to fetch element due to javascript call. Following results should be used with caution!" + end locate || raise(NotFoundError.new(error_message)) end diff --git a/lib/webrat/core/methods.rb b/lib/webrat/core/methods.rb index 36efeb8..d95587e 100644 --- a/lib/webrat/core/methods.rb +++ b/lib/webrat/core/methods.rb @@ -27,6 +27,7 @@ module Webrat delegate_to_session \ :visits, :visit, + :ajax, :within, :header, :http_accept, :basic_auth, :save_and_open_page, diff --git a/lib/webrat/core/session.rb b/lib/webrat/core/session.rb index d006ce9..1a8c1fb 100644 --- a/lib/webrat/core/session.rb +++ b/lib/webrat/core/session.rb @@ -95,6 +95,36 @@ For example: @default_headers.dup.merge(@custom_headers.dup) end + + def ajax_page(url, http_method, data) + h = headers + h['HTTP_REFERER'] = @current_url if @current_url + + debug_log "REQUESTING PAGE FROM AJAX: #{http_method.to_s.upcase} #{url} with #{data.inspect} and HTTP headers #{h.inspect}" + if h.empty? + send :xhr, "#{http_method}", url, data || {} + else + send :xhr, "#{http_method}", url, data || {}, h + end + + save_and_open_page if exception_caught? && Webrat.configuration.open_error_files? + raise PageLoadError.new("Page load was not successful (Code: #{response_code.inspect}):\n#{formatted_error}") unless success_code? + + reset + + # @current_url = url # The current url should not be updated, as the ajax call should not trigger a redirect! + @http_method = http_method + @data = data + + if internal_redirect? + check_for_infinite_redirects + request_page(response_location, :get, {}) + end + + return response + end + + def request_page(url, http_method, data) #:nodoc: h = headers h['HTTP_REFERER'] = @current_url if @current_url @@ -204,6 +234,14 @@ For example: def visit(url = nil, http_method = :get, data = {}) request_page(url, http_method, data) end + + # Issues a XHR request on the current page. No guarantee at this time on the actual content of the DOM! + # + # Example: + # ajax :get, "/save_article/23.js" + def ajax(http_method = :get, url = nil, data = {}) + ajax_page(url, http_method, data) + end webrat_deprecate :visits, :visit @@ -228,6 +266,10 @@ For example: false end + def response_from_xhr? + false + end + def simulate return if Webrat.configuration.mode == :selenium yield diff --git a/lib/webrat/rails.rb b/lib/webrat/rails.rb index 0d03cd7..cad477c 100644 --- a/lib/webrat/rails.rb +++ b/lib/webrat/rails.rb @@ -32,7 +32,7 @@ module Webrat end def get(url, data, headers = nil) - do_request(:get, url, data, headers) + code = do_request(:get, url, data, headers) end def post(url, data, headers = nil) @@ -46,6 +46,14 @@ module Webrat def delete(url, data, headers = nil) do_request(:delete, url, data, headers) end + + def xhr(http_method, url, data, headers = nil) + old_response = response.body unless response.blank? + do_request(http_method, url, data, headers, true) + if !response.blank? and response.body.blank? and !old_response.blank? + response.body = old_response + end + end def response_body response.body @@ -59,15 +67,23 @@ module Webrat response.headers["Content-Type"].to_s =~ /xml/ end + def response_from_xhr? + response.headers["Content-Type"].to_s =~ /text\/javascript/ + end + protected def integration_session @context end - def do_request(http_method, url, data, headers) #:nodoc: + def do_request(http_method, url, data, headers, is_ajax = false) #:nodoc: update_protocol(url) - integration_session.send(http_method, normalize_url(url), data, headers) + if is_ajax + integration_session.send(:xhr, http_method, normalize_url(url), data, headers) + else + integration_session.send(http_method, normalize_url(url), data, headers) + end end # remove protocol, host and anchor diff --git a/spec/integration/rails/config/environment.rb b/spec/integration/rails/config/environment.rb index c9b68aa..6d99985 100644 --- a/spec/integration/rails/config/environment.rb +++ b/spec/integration/rails/config/environment.rb @@ -1,4 +1,4 @@ -RAILS_GEM_VERSION = '2.2.2' unless defined? RAILS_GEM_VERSION +# RAILS_GEM_VERSION = '2.2.2' unless defined? RAILS_GEM_VERSION require File.join(File.dirname(__FILE__), 'boot') diff --git a/spec/private/rails/rails_session_spec.rb b/spec/private/rails/rails_session_spec.rb index 978e892..153fbf1 100644 --- a/spec/private/rails/rails_session_spec.rb +++ b/spec/private/rails/rails_session_spec.rb @@ -41,6 +41,13 @@ describe Webrat::RailsSession do rails_session = Webrat::RailsSession.new(@integration_session) rails_session.delete("url", "data", "headers") end + + it "should delegate xhr to the integration session" do + @integration_session.should_receive(:response).twice + @integration_session.should_receive(:xhr).with(:get, "url", "data", "headers") + rails_session = Webrat::RailsSession.new(@integration_session) + rails_session.xhr(:get, "url", "data", "headers") + end context "the URL is a full path" do it "should pass the full url" do -- 1.6.2.1 From 53e87fed1166fa84fc498492344a3d664aefd0e8 Mon Sep 17 00:00:00 2001 From: Guillaume Godet-Bar Date: Fri, 8 May 2009 17:44:43 +0200 Subject: [PATCH 2/2] Minor corrections --- lib/webrat/core/session.rb | 4 +--- lib/webrat/rails.rb | 8 ++++---- spec/private/rails/rails_session_spec.rb | 6 +++--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/webrat/core/session.rb b/lib/webrat/core/session.rb index 1a8c1fb..fcb183e 100644 --- a/lib/webrat/core/session.rb +++ b/lib/webrat/core/session.rb @@ -95,7 +95,6 @@ For example: @default_headers.dup.merge(@custom_headers.dup) end - def ajax_page(url, http_method, data) h = headers h['HTTP_REFERER'] = @current_url if @current_url @@ -106,7 +105,7 @@ For example: else send :xhr, "#{http_method}", url, data || {}, h end - + save_and_open_page if exception_caught? && Webrat.configuration.open_error_files? raise PageLoadError.new("Page load was not successful (Code: #{response_code.inspect}):\n#{formatted_error}") unless success_code? @@ -124,7 +123,6 @@ For example: return response end - def request_page(url, http_method, data) #:nodoc: h = headers h['HTTP_REFERER'] = @current_url if @current_url diff --git a/lib/webrat/rails.rb b/lib/webrat/rails.rb index cad477c..91e7e81 100644 --- a/lib/webrat/rails.rb +++ b/lib/webrat/rails.rb @@ -46,13 +46,13 @@ module Webrat def delete(url, data, headers = nil) do_request(:delete, url, data, headers) end - + def xhr(http_method, url, data, headers = nil) - old_response = response.body unless response.blank? + old_response = response.body unless response.blank? do_request(http_method, url, data, headers, true) - if !response.blank? and response.body.blank? and !old_response.blank? + if response.body.blank? and !old_response.blank? response.body = old_response - end + end end def response_body diff --git a/spec/private/rails/rails_session_spec.rb b/spec/private/rails/rails_session_spec.rb index 153fbf1..5de3c06 100644 --- a/spec/private/rails/rails_session_spec.rb +++ b/spec/private/rails/rails_session_spec.rb @@ -41,12 +41,12 @@ describe Webrat::RailsSession do rails_session = Webrat::RailsSession.new(@integration_session) rails_session.delete("url", "data", "headers") end - + it "should delegate xhr to the integration session" do @integration_session.should_receive(:response).twice - @integration_session.should_receive(:xhr).with(:get, "url", "data", "headers") + @integration_session.should_receive(:xhr).with(:get, "url", "data", "headers") rails_session = Webrat::RailsSession.new(@integration_session) - rails_session.xhr(:get, "url", "data", "headers") + rails_session.xhr(:get, "url", "data", "headers") end context "the URL is a full path" do -- 1.6.2.1