Issues with using subdomains with Cucumber/Capybara

Question!

I have successfully added the ability to use dynamic subdomains within my application. The issue is that when I run my Cucumber tests, I receive the following error when my application performs a redirect_to which contains a subdomain:

features/step_definitions/web_steps.rb:27
the scheme http does not accept registry part: test_url.example.com (or bad hostname?)

I have a signup controller action that creates the user and the account chosen and redirects the the user to the logout method with the subdomain specified based on what the user selected as the subdomain in the sign up form. Here is the code for the redirect action that happens once the user and account models are created and saved:

redirect_to :controller => "sessions", :action => "destroy", :subdomain => @account.site_address

Here are my rails 3 routes:

constraints(Subdomain) do
  resources :sessions
  match 'login', :to => 'sessions#new', :as => :login
  match 'logout', :to => 'sessions#destroy', :as => :logout
  match '/' => 'accounts#show'
end

Here is the code I have so far for the Subdomain class which is specified in the constraint above:

class Subdomain
  def self.matches?(request)
    request.subdomain.present? && request.subdomain != "www"
  end
end

I added UrlHelper to the ApplicationController:

class ApplicationController < ActionController::Base
  include UrlHelper
  protect_from_forgery
end

This is the code for the above UrlHelper class:

module UrlHelper
  def with_subdomain(subdomain)
    subdomain = (subdomain || "")
    subdomain += "." unless subdomain.empty?
    [subdomain, request.domain, 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
end

All of this code above allows me to run subdomains fine within the local browser. The issue above happens when I run my Cucumber test. The test clicks the signup button which in turn calls the redirect_to and throws the exception listed above.

Here is what my gem file looks like:

require 'subdomain'

SomeApp::Application.routes.draw do

  resources :accounts, :only => [:new, :create]
  match 'signup', :to => 'accounts#new'

  constraints(Subdomain) do
    resources :sessions
    match 'login', :to => 'sessions#new', :as => :login
    match 'logout', :to => 'sessions#destroy', :as => :logout

    match '/' => 'accounts#show'
  end
end

Could you please let be know an additional method to have my tests work now? I would be interested in either a fix or a way I can test my methods without using subdomains (for example a mocked out method that retrieves the account name).



Answers

I have this same pattern in my code. I use Capybara (but not Cucumber), and I was able to get around it like this:

    # user creates an account that will have a new subdomain
    click_button "Get Started"  
    host! "testyco.myapp.com"

    # user is now visiting app on new subdomain
    visit "/register/get_started/"   Resetkey.first.resetkey
    assert_contain("Get Started Guide")

The host! command effectively changes the host as it appears to the app from the test request.

EDIT: Just realized this was working with webrat, but not capybara (i'm using both, phasing out webrat now.) The way I'm doing it in capybara is to either click a link to a new domain (capybara follows it) or to:

 visit "http://testyco.myapp.com/register"

EDIT: Another update. Found a method that works without having to use the full URL in every event.

        host! "test.hiringthing.com"
        Capybara.app_host = "http://test.hiringthing.com"

In the test setup.

By : Joshua


This video can help you solving your question :)
By: admin