Express guide to a rails 3.2+ testing custom app subdomains using cucumber capybara with a pow setup... along with devise mailer config helper example (useful if you need to test various auth situations for custom subdomains in a rails app).
If you haven't used pow, I wouldn't recommend it for local web dev... there's much better gems for local web dev like unicorn-rails or passenger nginx standalone are far better choices IMHO. I use pow for all the local name redirects to a port like explained below, with a rails dev server listening on that port running unicorn-rails.
So we're going to use it for the awesome subdomain redirect to a local customapp.dev on a specific port magic mojo.
First install pow.cx
- now go to pow.cx and install
- cd ~/.pow
- echo 3000 > theappname && echo 3030 > theappnametest
- now pow will redirect all requests to theappname.dev to port 3000
- and now pow will redirect all requests to theappnametest.dev to port 3030
- we've created two ports to be able to work in the development env and execute cukes in the test env at the same time
Now go to your cucumber's env.rb file add the following:
Capybara.server_port = 3030
Capybara.default_host = 'theappnametest.dev'
Capybara.app_host = 'http://www.theappnametest.dev'
Next modify the rails environment test.rb file by adding the following:
config.action_mailer.default_url_options = { :host => 'theappnametest.dev' }
So with the above done you can switch around subdomains all you like in your cucumber features and steps by calling:
Capybara.app_host = "http://#{@user.subdomain}.theappnametest.dev"
Need it to work with devise mailers?
Create a url_heleper.rb file like:
module UrlHelper
## subdomain helpers ##
def with_subdomain(subdomain)
subdomain = (subdomain || "")
subdomain += "." unless subdomain.empty?
[subdomain, request.host, request.port_string].join
end
def url_for(options = nil)
if options.kind_of?(Hash) && options.has_key?(:subdomain)
options[:host] = with_subdomain(options.delete(:subdomain))
end
super
end
## sets the subdomain in the mailer based off of the current request ##
def set_mailer_url_options
ActionMailer::Base.default_url_options[:host] = with_subdomain(request.subdomain)
end
## for building links at runtime
def build_url_or_path_for(url_or_path = '')
url_or_path = eval(url_or_path) if url_or_path =~ /_path|_url|@/
url_or_path
end
end
Next Add this to your application.rb:
config.to_prepare do
Devise::Mailer.class_eval do
helper :url
end
end
All the devise mailer links can now take the subdomain param so they build correctly:
confirmation_url(@resource, confirmation_token: @resource.confirmation_token, subdomain: @resource.account.subdomain) %>
This comment has been minimized.
Nice work man. I didn't realize Pow could forward to different ports.