Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capybara with subdomains - default_host

I have an app that uses subdomains to switch databases (multi-tenancy). I'm trying to use Capybara for integration testing, and it really relies a lot on subdomains.

My understanding was that setting Capybara.default_host= to something would make all my requests come from this host. This doesn't seem to be the case. In this post, the author recommends just visiting the explicit url with a host, but this becomes a bit annoying if I'm navigating all over the place. I'd like to just set the host, then be able to use my rails paths as expected. Not sure what I'm doing wrong, but here's what I've tried:

# spec_helper.rb RSpec.configure do |config|   config.before(:each, :type => :request) do     Capybara.default_host = 'http://app.mydomain.com'   end end  # in some_integration_spec.rb before do   puts "Capybara.default_host: #{Capybara.default_host}"   puts "some_app_url: #{some_app_url}" end 

This yields the output:

Capybara.default_host: http://app.mydomain.com some_app_url: http://www.example.com/some_path 

What am I doing wrong? default_host appears to do nothing. As I say, I don't want to have to say visit(Capybara.default_host + some_app_path) as that's a bit annoying each time. Why else does this default_host option exist?

like image 529
brad Avatar asked Jun 30 '11 14:06

brad


2 Answers

I'm not sure of the intended use of default_host, but app_host does what you need. I've found I first need to call the rails session method host! in order to set the host string that will be passed to controllers in the request object.

Then you need to set Capybara.app_host to tell Capybara to call your app via the web server instead of just making the calls in process. If you don't do that then Capybara wigs out when it encounters redirects and drops the host information in the second request.

I'm not sure why this doesn't take care of the Rails request end of things automatically, but I've found that unless I set the host in both places explicitly, then I get inconsistent results.

def set_host (host)   host! host   Capybara.app_host = "http://" + host end  before(:each) do   set_host "lvh.me:3000" end 

Then you can just use relative paths to access pages.

Update:

Capybara 2.x and rspec-rails 2.12.0 introduced "Feature" specs for running Capybara acceptance tests. The new FeatureExampleGroup module in rspec-rails is different from RequestExampleGroup and no longer has access to the rack-test host! method. Now you want to use default_url_options instead:

def set_host (host)   # host! host   default_url_options[:host] = host   Capybara.app_host = "http://" + host end 
like image 177
Lachlan Cotter Avatar answered Oct 12 '22 01:10

Lachlan Cotter


When you need to change the URL to include the subdomain, you can specify the app_host in your step definitions. Use a domain like lvh.me since it points to 127.0.0.1:

Capybara.app_host = "http://#{subdomain}.lvh.me" 

Capybara assumes that when you're specifying an app_host that you're testing a remote server running on port 80, but in our case, we're testing a local app which is running on a random port specified by Capybara. To fix this, in your env.rb file, add this line:

Capybara.always_include_port = true 

Now when you visit a page of your app...

visit '/page' 

...the url will specify the subdomain as well as the port that the app is running on.

FYI: This worked for me using Capybara 2.0.2.

like image 36
Andrew Avatar answered Oct 12 '22 00:10

Andrew