Skip to content
Browse files

Make sure that relative paths in a remote context are treated as remo…

…te. Closes #2
  • Loading branch information...
1 parent 1549596 commit 3aad71d5cdf17af23ef34b0e0da4899895ed9ed9 @jeroenvandijk jeroenvandijk committed Oct 19, 2010
View
1 Gemfile
@@ -9,4 +9,5 @@ group :development do
gem 'rspec', '~> 2.0.0.beta.22'
gem "sinatra"
gem "mongrel", '~> 1.2.pre'
+ gem "ruby-debug"
end
View
8 Gemfile.lock
@@ -22,13 +22,15 @@ GEM
remote: http://rubygems.org/
specs:
celerity (0.8.2)
+ columnize (0.3.1)
culerity (0.2.12)
daemons (1.0.10)
diff-lcs (1.1.2)
ffi (0.6.3)
rake (>= 0.8.7)
gem_plugin (0.2.3)
json_pure (1.4.6)
+ linecache (0.43)
mechanize (1.0.0)
nokogiri (>= 1.2.1)
mime-types (1.16)
@@ -50,6 +52,11 @@ GEM
rspec-mocks (2.0.0.beta.22)
rspec-core (= 2.0.0.beta.22)
rspec-expectations (= 2.0.0.beta.22)
+ ruby-debug (0.10.3)
+ columnize (>= 0.1)
+ ruby-debug-base (~> 0.10.3.0)
+ ruby-debug-base (0.10.3)
+ linecache (>= 0.3)
rubyzip (0.9.4)
selenium-webdriver (0.0.28)
ffi (>= 0.6.1)
@@ -68,4 +75,5 @@ DEPENDENCIES
mechanize (~> 1.0.0)
mongrel (~> 1.2.pre)
rspec (~> 2.0.0.beta.22)
+ ruby-debug
sinatra
View
40 lib/capybara/driver/mechanize_driver.rb
@@ -30,7 +30,7 @@ def follow_redirect!
unless response.redirect?
raise "Last response was not a redirect. Cannot follow_redirect!"
end
-
+
location = if last_request_remote?
remote_response.page.response['Location']
else
@@ -43,31 +43,35 @@ def follow_redirect!
def get(url, params = {}, headers = {})
if remote?(url)
process_remote_request(:get, url)
- else
+ else
+ register_local_request
super
end
end
def post(url, params = {}, headers = {})
if remote?(url)
process_remote_request(:post, url, params, headers)
- else
+ else
+ register_local_request
super
end
end
def put(url, params = {}, headers = {})
if remote?(url)
process_remote_request(:put, url)
- else
+ else
+ register_local_request
super
end
end
def delete(url, params = {}, headers = {})
if remote?(url)
process_remote_request(:delete, url, params, headers)
- else
+ else
+ register_local_request
super
end
end
@@ -79,7 +83,12 @@ def remote?(url)
false
else
host = URI.parse(url).host
- !(host.nil? || host.include?(Capybara.default_host))
+
+ if host.nil? && last_request_remote?
+ true
+ else
+ !(host.nil? || host.include?(Capybara.default_host))
+ end
end
end
@@ -90,15 +99,28 @@ def remote?(url)
def last_request_remote?
!!@last_request_remote
end
+
+ def register_local_request
+ @last_remote_host = nil
+ @last_request_remote = false
+ end
def process_remote_request(method, url, *options)
if remote?(url)
- url = File.join((Capybara.app_host || Capybara.default_host), url) if URI.parse(url).host.nil?
+ remote_uri = URI.parse(url)
+
+ if remote_uri.host.nil?
+ remote_host = @last_remote_host || Capybara.app_host || Capybara.default_host
+ url = File.join(remote_host, url)
+ url = "http://#{url}" unless url.include?("http")
+ else
+ @last_remote_host = "#{remote_uri.host}:#{remote_uri.port}"
+ end
+
reset_cache
@agent.send *( [method, url] + options)
+
@last_request_remote = true
- else
- @last_request_remote = false
end
end
View
2 lib/capybara/mechanize.rb
@@ -1,3 +1,5 @@
+require 'capybara'
+
module Capybara
module Driver
autoload :Mechanize, 'capybara/driver/mechanize_driver'
View
16 lib/capybara/spec/extended_test_app.rb
@@ -8,7 +8,21 @@ class ExtendedTestApp < TestApp#< Sinatra::Base
end
get '/host' do
- "current host is #{request.host}"
+ "current host is #{request.host}:#{request.port}, method get"
+ end
+
+ get '/form_with_relative_action_to_host' do
+ %{<form action="/host" method="post">
+ <input type="submit" value="submit" />
+ </form>}
+ end
+
+ get '/relative_link_to_host' do
+ %{<a href="/host">host</a>}
+ end
+
+ post '/host' do
+ "current host is #{request.host}:#{request.port}, method post"
end
end
View
56 spec/driver/mechanize_driver_spec.rb
@@ -32,31 +32,62 @@
end
it "should treat urls as remote" do
- @driver.remote?('http://www.remote.com').should be true
+ @driver.should be_remote('http://www.remote.com')
end
end
context "with a default url, no app host" do
before :each do
- Capybara.default_host = 'local.com'
+ Capybara.default_host = 'www.local.com'
end
it "should treat urls with the same host names as local" do
- @driver.remote?('http://www.local.com').should be false
+ @driver.should_not be_remote('http://www.local.com')
end
it "should treat other urls as remote" do
- @driver.remote?('http://www.remote.com').should be true
+ @driver.should be_remote('http://www.remote.com')
+ end
+
+ it "should treat relative paths as remote if the previous request was remote" do
+ @driver.visit('http://www.remote.com')
+ @driver.should be_remote('/some_relative_link')
+ end
+
+ it "should treat relative paths as local if the previous request was local" do
+ @driver.visit('http://www.local.com')
+ @driver.should_not be_remote('/some_relative_link')
end
it "should receive the right host" do
@driver.visit('http://www.local.com/host')
- @driver.body.should include('local.com')
+ @driver.body.should == "current host is www.local.com:80, method get"
+ end
+
+ it "should always switch to the right context" do
+ @driver.visit('http://www.local.com/host')
+ should_be_a_local_get
+
+ @driver.visit('/host')
+ should_be_a_local_get
+ @driver.should_not be_remote('/first_local')
+
+ @driver.visit("#{REMOTE_TEST_URL}/host")
+ should_be_a_remote_get
+ @driver.should be_remote('/first_remote')
+
+ @driver.visit('/host')
+ should_be_a_remote_get
+ @driver.should be_remote('/second_remote')
+
+ @driver.visit('http://www.local.com/host')
+ should_be_a_local_get
+ @driver.should_not be_remote('/second_local')
end
it "should follow redirects from local to remote" do
@driver.visit("http://www.local.com/redirect_to/#{REMOTE_TEST_URL}/host")
- @driver.body.should include(REMOTE_TEST_HOST)
+ should_be_a_remote_get
end
after :each do
@@ -66,13 +97,20 @@
it "should include the right host when remote" do
@driver.visit("#{REMOTE_TEST_URL}/host")
- @driver.body.should include(REMOTE_TEST_HOST)
+ should_be_a_remote_get
end
-
it "should follow redirects from remote to local" do
@driver.visit("#{REMOTE_TEST_URL}/redirect_to/http://www.local.com/host")
- @driver.body.should include('local.com')
+ should_be_a_local_get
+ end
+
+ def should_be_a_remote_get
+ @driver.body.should == "current host is #{REMOTE_TEST_HOST}, method get"
+ end
+
+ def should_be_a_local_get
+ @driver.body.should == "current host is www.local.com:80, method get"
end
end
View
13 spec/session/mechanize_spec.rb
@@ -4,6 +4,7 @@
context 'with mechanize driver' do
before do
@session = Capybara::Session.new(:mechanize, TestApp)
+ Capybara.default_host = "www.local.com"
end
describe '#driver' do
@@ -25,6 +26,18 @@
@session.body.should == 'The requested object was deleted'
end
end
+
+ it "should use the last remote url when following relative links" do
+ @session.visit("#{REMOTE_TEST_URL}/relative_link_to_host")
+ @session.click_link "host"
+ @session.body.should == "current host is #{REMOTE_TEST_HOST}, method get"
+ end
+
+ it "should use the last remote url when submitting a form with a relative action" do
+ @session.visit("#{REMOTE_TEST_URL}/form_with_relative_action_to_host")
+ @session.click_button "submit"
+ @session.body.should == "current host is #{REMOTE_TEST_HOST}, method post"
+ end
it_should_behave_like "session"
it_should_behave_like "session without javascript support"
View
2 spec/session/remote_mechanize_spec.rb
@@ -35,7 +35,7 @@
end
end
- # Pending: Still 12 failing tests here (result is 658 examples, 12 failures, instead of 350 examples)
+ # Pending: Still 16 (and before the last remote mode commit 13) failing tests here (result is 658 examples, 16 failures, instead of 354 examples)
# it_should_behave_like "session"
it_should_behave_like "session without javascript support"
View
5 spec/spec_helper.rb
@@ -18,11 +18,12 @@
config.after do
Capybara.default_selector = :xpath
end
+ # config.filter_run :focus => true
end
# Until this library is merged with capybara there needs to be a local app and you need to add
# 127.0.0.1 capybara-testapp.heroku.com to your host file
# Run the app with the following line:
# ruby -rrubygems lib/capybara/spec/extended_test_app.rb
-REMOTE_TEST_HOST = "capybara-testapp.heroku.com"
-REMOTE_TEST_URL = "http://#{REMOTE_TEST_HOST}:8070"
+REMOTE_TEST_HOST = "capybara-testapp.heroku.com:8070"
+REMOTE_TEST_URL = "http://#{REMOTE_TEST_HOST}"

0 comments on commit 3aad71d

Please sign in to comment.
Something went wrong with that request. Please try again.