ventajas pruebas metodologia ejemplo automatizadas automatización ruby-on-rails rspec devise capybara csrf

ruby-on-rails - metodologia - pruebas automatizadas selenium



Rieles-Perdida de sesión con pruebas de integración y carpincho-¿relacionado con CSRF? (4)

Estoy usando Rails 3.1.0.rc4 y estoy trabajando en hacer pruebas de integración con el nuevo DSL y Rspec parecidos a los de Carpincho (usando la autenticación Devise)

El problema que estoy teniendo es que cuando ejecuto una prueba de integración, el controlador de prueba de rack de capibara parece perder completamente la sesión de inicio de sesión del usuario, de hecho, la sesión parece desaparecer por completo.

Después de días de depuración, estoy completamente enterado de por qué. Yendo línea por línea a través de la pila de middleware, creo que he descartado el problema de algo que está sucediendo en ActiveRecord::SessionStore . He leído aquí que Rails borrará una sesión si no puede validar el token CSRF, lo que me hace creer que tengo algo mal configurado y, por alguna razón, esta prueba no está autenticando el token CSRF correctamente. .

Esto es lo que está en mi session_store.rb en el directorio / initializers:

MyApp::Application.config.session_store :active_record_store

¿Alguien que sepa sobre la protección de CSRF en los rieles tiene pistas sobre por qué esto puede estar pasando?

Además, aquí hay algunas cosas a tener en cuenta:

  • lo que intento probar realmente funciona dentro del navegador, solo esta prueba deja caer la sesión
  • parece que la sesión se descarta después de enviar un formulario al que la url de acción se dirige a otro servidor. Estoy usando la gema VCR para capturar las solicitudes / respuestas a este servidor externo en la prueba, y aunque creo que he descartado la solicitud externa como problema, esto puede tener algo que ver directamente con el token CSRF que no se autentica, así limpiando la sesión.
  • otras pruebas que implican el inicio de sesión / uso de sesiones no son sesiones que caen

¿Alguien puede darme pistas sobre qué está sucediendo aquí exactamente, y por qué la única prueba parece abandonar arbitrariamente su sesión y fallar en mí? He hecho muchas depuraciones y he intentado todo lo que puedo pensar.


Soy nuevo en capibara también y estaba teniendo un problema similar.

Estaba intentando iniciar sesión con un usuario que hace algo como esto:

post user_session_path, :user => {:email => user.email, :password => ''superpassword''}

Y eso funcionaba bien hasta que intenté hacer algo con el carpincho, como visitar una página y simplemente probar si el usuario había iniciado sesión. Esta simple prueba no estaba pasando:

visit root_path page.should have_content("logout") #if the user is logged in then the logout link should be present

Al principio pensé que el carpincho estaba limpiando las sesiones, pero estaba equivocado. Lo que me tomó un tiempo darme cuenta es que el carpincho del controlador está usando maneja sus propias sesiones, por lo que, desde el punto de vista del capibara, mi usuario nunca ingresó. Para hacerlo, tienes que hacerlo así.

page.driver.post user_session_path, :user => {:email => user.email, :password => ''superpassword''}

No estoy seguro si este es tu caso, pero espero que ayude.


La forma manual de hacerlo es muy simple:

it "does something after login" do password = "secretpass" user = Factory(:user, :password => password) visit login_path fill_in "Email", :with => user.email fill_in "Password", :with => password click_button "Log in" visit # somewhere else and do something end

A continuación, puede dividir esto en una función en su ''spec_helper.rb'':

# at the bottom of ''spec_helper.rb'' def make_user_and_login password = "secretpass" @user = Factory(:user, :password => password) visit login_path fill_in "Email", :with => @user.email fill_in "Password", :with => password click_button "Log in" end

y úsala en cualquiera de tus pruebas (probablemente solicites las especificaciones):

it "does something after login" do make_user_and_login # now test something that requires a logged in user # you have access to the @user instance variable end


Esto podría ser una click_button ''Sign in'' pero creo que terminaremos en mal estado luego de hacer click_button ''Sign in'' y llamar a visit elsewhere inmediatamente después.

Mi teoría es que cuando hacemos clic en el botón, la solicitud aún no se ha completado y la matamos al visitar otra ruta.

De la documentación de Capibara:

Al emitir instrucciones a la DSL, como:

click_link(''foo'') click_link(''bar'') expect(page).to have_content(''baz'')

Si al hacer clic en el enlace foo se desencadena un proceso asíncrono, como una solicitud Ajax, cuando se complete se agregará el enlace de la barra a la página, se esperaría que al hacer clic en el enlace de la barra fallara, ya que ese enlace aún no existe. Sin embargo, Capybara es lo suficientemente inteligente como para volver a intentar encontrar el enlace durante un breve período de tiempo antes de darse por vencido y lanzar un error.

Si este es el caso, la solución es simple: déle a Capybara algo que buscar y espere hasta que se complete la solicitud. Esto puede ser tan simple como agregar:

expect(page).to have_text(''Signed in as [email protected]'')


Pude solucionar este error estableciendo este valor en true en config / initializers / test.rb

# Disable request forgery protection in test environment config.action_controller.allow_forgery_protection = true

De antemano, las etiquetas CSRF <meta> no se imprimían en <head> . Después de cambiar este valor, finalmente aparecen.