13

Rails 3, pepino 0.9.4, 0.4.0 Carpinchorieles, capibara y subdominios: cómo visitar determinado subdominio

quiero probar mis funciones con subdominio. He encontrado que la solución:

Given /^I visit subdomain "(.+)"$/ do |sub| 
    Capybara.default_host = "#{sub}.example.com" #for Rack::Test 
    Capybara.app_host = "http://#{sub}.example.com:9887" if Capybara.current_driver == :culerity 
end 

Funciona si funciono cucumber features/subdomain.feature pero fracasa si funciono cucumber features! Es increíble, pero es verdad. Me he registrado URLs actuales y es subdomain.example.com de cucumber features/subdomain.feature y www.example.com para cucumber features para un escenario con

Scenario: subdomain scenario 
    Given I visit subdomain "subdomain" 

en ambos casos!

No sé la razón ...

¿Hay mejor manera para probar subdominios con capibara?

Respuesta

12

De acuerdo, esto es lo que debería ser un truco de Capybara bastante sencillo y fácil de entender que produzca el comportamiento deseado, es decir, poder crear una nueva sesión cada vez que cambie de subdominios. Esto es útil para sitios donde un usuario se registra en un dominio (lo que da como resultado la creación de un subdominio para su cuenta) y luego necesita navegar hacia ese subdominio.

Antes que nada (y esta parte es bastante común para las otras soluciones que existen), siga adelante y descubra cómo cambiar Capybara.default_host en un paso de Cucumber. Lo hice así:

Then /^I switch the subdomain to (\w+)$/ do |s| 
    Capybara.default_host = "#{s}.smackaho.st" 
end 

palillo de este paso en su función de pepino en el punto donde desea que el nuevo subdominio que desea utilizar. Por ejemplo:

When I open the email 
Then I should see "http://acme.rightbonus.com/users/confirmation" in the email body 

Given I switch the subdomain to acme 
When I follow "Click here to finish setting up your account" in the email 
Then I should be on the user confirmation page for acme 

Ahora para el monkeypatching mágico que hace que esto funcione. Básicamente, desea que Capybara sea lo suficientemente inteligente como para detectar cuándo el subdominio ha cambiado y restablecer su objeto de sesión RackTest.

# features/support/capybara.rb 

class Capybara::Driver::RackTest 
    # keep track of the default host you started with 
    def initialize(app) 
    raise ArgumentError, 
     "rack-test requires a rack application, but none was given" unless app 
    @app = app 
    @default_host = Capybara.default_host 
    end 

    def process(method, path, attributes = {}) 
    reset_if_host_has_changed 
    path = ["http://", @default_host, path].join 
    return if path.gsub(/^#{request_path}/, '') =~ /^#/ 
    path = request_path + path if path =~ /^\?/ 
    send(method, to_binary(path), to_binary(attributes), env) 
    follow_redirects! 
    end 

    private 

    def build_rack_mock_session # :nodoc: 
    puts "building a new Rack::MockSession for " + Capybara.default_host 
    Rack::MockSession.new(app, Capybara.default_host || "www.example.com") 
    end 

    def reset_if_host_has_changed 
    if @default_host != Capybara.default_host 
     reset! # clears the existing MockSession 
     @default_host = Capybara.default_host 
    end 
    end 
end 

Este parche funciona con Capybara 0.4.1.1 y probablemente no funcione con diferentes versiones a menos que se modifique. Buena suerte.

+0

Sí! Solución interesante Pero tiene un problema. Si utilizo "muéstrame la página", obtuve: esperado: "/ admin/companies", got: "/ home/user/webdev/project/public/admin/companies" (utilizando ==) (RSpec :: Expectations :: ExpectationNotMetError) – petRUShka

+0

¿Y cuál es la descripción del paso "Entonces debería estar en la página de confirmación de usuario para acme"? – petRUShka

1

Tuve el mismo problema por un tiempo y mi prueba a veces tenía que cambiar o redirigir entre subdominios.

dado este paso:

When /^(?:|I)go to "(.+)"$/ do |url| 
    visit url 
end 

When I go to "http://mysubdomain.example.org" obras en la prueba de rack, pero si se le redirige mediante la aplicación o sigue un enlace a alguna otra ruta al host vuelve al sistema principal por omisión.

Hay un fork of rack-test por hassox que asegura que la prueba en rack realiza un seguimiento del host utilizado en la solicitud anterior.

Por lo tanto, en mi Gemfile, antes de requerir capibara:

gem 'rack-test', :git => "https://github.com/hassox/rack-test.git" 

Ahora bien, si tengo que golpear un subdominio en particular (o la aplicación me redirige a uno, como secure.myapp.com/sign_in) Estoy seguro de que la característica puede leer más como un navegador se comportaría: me permitirá permanecer en el subdominio actual hasta que lo use, usando visit("somesubdomain.example.org") de capybara, o la aplicación lo redirecciona a un host diferente.

5

Si sus necesidades no incluyen nada que ver con las sesiones, y todo lo que está buscando está de visita en un subdominio diferente, yo escribimos esta función:

def visit_with_subdomain(uri, options = {}) 
    domain = Capybara.default_host 
    port = Capybara.server_port 
    subdomain = options[:subdomain] 
    visit "http://#{subdomain}.#{domain}:#{port}#{uri}" 
end 

se le puede llamar así:

visit_with_subdomain some_path, subdomain: some_subdomain 
+0

Esta es la solución más simple. Gracias. –

Cuestiones relacionadas