From 01cb16e32a4d6e2f14e0f3747e58a0a0a1b69502 Mon Sep 17 00:00:00 2001 From: Jonas Nicklas Date: Thu, 6 Sep 2012 10:46:54 +0200 Subject: [PATCH] Allow protocol relative URLs, closes #776 --- History.txt | 3 +++ lib/capybara/rack_test/browser.rb | 27 ++++++++++---------- lib/capybara/spec/session/click_link_spec.rb | 5 ++++ lib/capybara/spec/views/with_html.erb | 1 + spec/rack_test_spec.rb | 6 ++--- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/History.txt b/History.txt index 8c301c19..9cd2cb69 100644 --- a/History.txt +++ b/History.txt @@ -59,6 +59,9 @@ * Nodes found via `all` are no longer reloaded. This fixes weird quirks where nodes would seemingly randomly replace themselves with other nodes [Jonas Nicklas] +* RackTest allows protocol relative URLs [Jonas Nicklas] +* Arguments are cast to string where necessary, so that e.g. `click_link(:foo)` works + as expected. [Jonas Nicklas] * Session is only reset if it has been modified, dramatically improves performance if only part of the test suite runs Capybara. [Jonas Nicklas] * Test suite now passes on Ruby 1.8 [Jo Liss] diff --git a/lib/capybara/rack_test/browser.rb b/lib/capybara/rack_test/browser.rb index 167d3753..877e6456 100644 --- a/lib/capybara/rack_test/browser.rb +++ b/lib/capybara/rack_test/browser.rb @@ -45,22 +45,18 @@ class Capybara::RackTest::Browser new_uri = URI.parse(path) method.downcase! unless method.is_a? Symbol - if new_uri.host - @current_host = "#{new_uri.scheme}://#{new_uri.host}" - @current_host << ":#{new_uri.port}" if new_uri.port != new_uri.default_port - end + new_uri.path = request_path if path.start_with?("?") + new_uri.path = request_path.sub(%r(/[^/]*$), '/') + new_uri.path unless new_uri.path.start_with?('/') + new_uri.scheme ||= @current_scheme + new_uri.host ||= @current_host + new_uri.port ||= @current_port unless new_uri.default_port == @current_port - if new_uri.relative? - if path.start_with?('?') - path = request_path + path - elsif not path.start_with?('/') - path = request_path.sub(%r(/[^/]*$), '/') + path - end - path = current_host + path - end + @current_scheme = new_uri.scheme + @current_host = new_uri.host + @current_port = new_uri.port reset_cache! - send(method, path, attributes, env.merge(options[:headers] || {})) + send(method, new_uri.to_s, attributes, env.merge(options[:headers] || {})) end def current_url @@ -70,7 +66,10 @@ class Capybara::RackTest::Browser end def reset_host! - @current_host = (Capybara.app_host || Capybara.default_host) + uri = URI.parse(Capybara.app_host || Capybara.default_host) + @current_scheme = uri.scheme + @current_host = uri.host + @current_port = uri.port end def reset_cache! diff --git a/lib/capybara/spec/session/click_link_spec.rb b/lib/capybara/spec/session/click_link_spec.rb index 284a7625..28aa34d0 100644 --- a/lib/capybara/spec/session/click_link_spec.rb +++ b/lib/capybara/spec/session/click_link_spec.rb @@ -72,6 +72,11 @@ Capybara::SpecHelper.spec '#click_link' do @session.should have_content('This is a test') end + it "should follow protocol relative links" do + @session.click_link('Protocol') + @session.should have_content('Another World') + end + it "should follow redirects" do @session.click_link('Redirect') @session.should have_content('You landed') diff --git a/lib/capybara/spec/views/with_html.erb b/lib/capybara/spec/views/with_html.erb index 488a4edc..7116dba6 100644 --- a/lib/capybara/spec/views/with_html.erb +++ b/lib/capybara/spec/views/with_html.erb @@ -45,6 +45,7 @@ banana Anchor on different page Anchor on same page Relative + Protocol very fine image fine image diff --git a/spec/rack_test_spec.rb b/spec/rack_test_spec.rb index 4e9b11ff..a97e233e 100644 --- a/spec/rack_test_spec.rb +++ b/spec/rack_test_spec.rb @@ -103,15 +103,15 @@ describe Capybara::RackTest::Driver do @driver.visit('/redirect') @driver.response.header['Location'].should be_nil - @driver.browser.current_url.should eq "#{@driver.browser.current_host}/landed" + @driver.browser.current_url.should match %r{/landed$} end it "is possible to not follow redirects" do @driver = Capybara::RackTest::Driver.new(TestApp, :follow_redirects => false) @driver.visit('/redirect') - @driver.response.header['Location'].should eq "#{@driver.browser.current_host}/redirect_again" - @driver.browser.current_url.should eq "#{@driver.browser.current_host}/redirect" + @driver.response.header['Location'].should match %r{/redirect_again$} + @driver.browser.current_url.should match %r{/redirect$} end end