unitarias pruebas ruby-on-rails ruby-on-rails-3 testing capybara stripe-payments

ruby on rails - unitarias - ¿Cómo escribir pruebas de integración para la comprobación de bandas en Rails?



rspec (5)

He golpeado el muro tratando de escribir una prueba de integración para el checkout.js [ https://checkout.stripe.com/checkout.js ] de Stripe para mi aplicación Rails 3.2.

La verificación de fill_in funciona correctamente para mí cuando se prueba manualmente (usando las claves de prueba de Stripe), pero no puedo hacer que Capybara detecte y fill_in el campo de correo electrónico en el iframe modal de fill_in .

Estoy usando poltergeist para javascript sin cabeza, aunque también lo he probado con capybara-webkit e incluso con selenio con el mismo problema.

Lo que estoy tratando de probar es el flujo completo de suscripción, para mostrar que un nuevo usuario puede crear una cuenta de suscriptor después de ingresar sus detalles de pago en Stripe, pero no puedo pasar la ventana emergente de pago de Stripe.

Aquí está mi before .. do :

describe "show Stripe checkout", :js => true do before do visit pricing_path click_button ''plan-illuminated'' stripe_iframe = all(''iframe[name=stripe_checkout_app]'').last Capybara.within_frame stripe_iframe do fill_in "email", :with => "[email protected]" fill_in "billing-name", :with => "Mr Name" fill_in "billing-street", :with => "test Street" fill_in "billing-zip", :with => 10000 fill_in "billing-city", :with => "Berlin" click_button "Payment Info" end end it { should have_selector(''button'', text: "Subscribe") } end

Que errores con:

Failure/Error: Capybara.within_frame stripe_iframe do Capybara::Poltergeist::TimeoutError: Timed out waiting for response to {"name":"push_frame","args":[null]}

Si cambio el intento de elegir el iframe correcto (sugerido aquí: problemas con Capybara para completar el modo JS ) así:

# stripe_iframe = all(''iframe[name=stripe_checkout_app]'').last # Capybara.within_frame stripe_iframe do Capybara.within_frame ''stripe_checkout_app'' do

Todavía me sale el similar:

Capybara::Poltergeist::TimeoutError: Timed out waiting for response to {"name":"push_frame","args":["stripe_checkout_app"]}

Parece que cualquiera que sea la gema de prueba de javascript que use, rspec / capybara no puede encontrar el iframe de comprobación de rayas. Cuando verifico con Selenium veo que se presiona el botón Choose this Plan y la ventana emergente de Checkout, pero la especificación agota el tiempo de espera para que se complete el campo de correo electrónico.

¿Algunas ideas?

Ya lo he intentado

  • Varias formas de elegir o encontrar el campo de correo electrónico.
  • Actualizando todas mis gemas.
  • Usar StripeMock antes de esto (no es que deba involucrarse, ¿verdad?).
  • Ejecutando las mismas pruebas en el propio sitio de Stripe, que dan los mismos errores:

Pruebas con:

visit "https://stripe.com/docs/checkout" click_button ''Pay with Card'' stripe_iframe = all(''iframe[name=stripe_checkout_app]'').last Capybara.within_frame stripe_iframe do fill_in ''Email'', with: ''[email protected]'' sleep 3 end

Dependiendo del método que utilice para seleccionar el iframe, recibo los mismos errores. Usando solo Capybara.within_frame ''stripe_checkout_app'' do :

Failure/Error: Capybara.within_frame stripe_iframe do Capybara::Poltergeist::TimeoutError: Timed out waiting for response to {"name":"push_frame","args":[null]}

o usando Selenium con stripe_iframe = all(''iframe[name=stripe_checkout_app]'').last

Failure/Error: Unable to find matching line from backtrace SystemStackError: stack level too deep

o incluso simplemente:

Failure/Error: fill_in ''Email'', with: ''[email protected]'' Capybara::ElementNotFound: cannot fill in, no text field, text area or password field with id, name, or label ''Email'' found

... dependiendo de la prueba que esté usando la gema de javascript.

Cualquier ayuda o sabiduría es muy apreciada!


He estado luchando con esto por algún tiempo (como lo muestra la esencia james) y al final descubrí que es demasiado frágil y demasiado lento para probar la comprobación de js.

En su lugar, puede usar lo siguiente (ruby, capybara, selenium) para apalear checkout.js y publicar su formulario con un token de banda:

# optionally ensure the iframe was opened expect(page).to have_css(''iframe[name="stripe_checkout_app"]'') # post the form token = Stripe::Token.create( :card => { :number => "4242424242424242", :exp_month => 7, :exp_year => 2019, :cvc => "314", address_line1: Faker::Address.street_address, address_city: Faker::Address.city, address_zip: Faker::Address.postcode, address_country: ''United Kingdom'' }, ) page.execute_script("$(''#payment_token'').val(''#{token.id}'');") page.execute_script("$(''#our-stripe-payment-form'').submit();")

nb esto supone que ya tiene la api gema de banda cargada en su entorno de prueba (por su aplicación de rieles) y tiene una clave API registrada, etc. De lo contrario, consulte la documentación .


No pude obtener ninguna de las soluciones aquí hasta ahora para trabajar para mí, y luego leyendo este post: https://gist.github.com/nruth/b2500074749e9f56e0b7 Me di cuenta de que la clave era agregar un retraso en la prueba para dar la Banda es suficiente para 1) cargar la ventana de verificación y 2) procesar el token.

Por esa razón, el único código que pude obtener para trabajar fue este (siéntase libre de jugar con el tiempo):

SELENIO

describe "test stripe" do, js: true, driver: :selenium do before do ... # fill in order form or whatever click_button "checkout_with_stripe" sleep(2) # allows stripe_checkout_app frame to load stripe_iframe = all(''iframe[name=stripe_checkout_app]'').last Capybara.within_frame stripe_iframe do page.execute_script(%Q{ $(''input#email'').val(''[email protected]''); }) page.execute_script(%Q{ $(''input#card_number'').val(''4242424242424242''); }) page.execute_script(%Q{ $(''input#cc-exp'').val(''08/44''); }) page.execute_script(%Q{ $(''input#cc-csc'').val(''999''); }) page.execute_script(%Q{ $(''#submitButton'').click(); }) sleep(3) # allows stripe_checkout_app to submit end end it "should successfully process the request" do ... # test should pass end end

Para Capybara-webkit , el truco para sleep no funcionó ni lamentablemente la solución de @ Ryan, y me cansé de intentar resolver esto, así que simplemente me detuve, pero espero que alguien más lo obtenga porque prefiero usar webkit para razones de velocidad! (Estaba usando capybara-webkit 1.3.0 )

En caso de que ayude, aquí están mis versiones relevantes:

selenium-webdriver 2.35.1 rspec-rails 2.14.2 capybara 2.1.0 stripe 1.16.0 da216fd rails 4.1.1 ruby 2.1.2


Probé la respuesta de James y la modifiqué para mi entorno actual. Aquí está mi código (especificación del sistema con Chrome sin cabeza):

require ''rails_helper'' describe ''Orders'', type: :system do before do # Temporarily change default_max_wait_time to wait for Stripe response @old_wait_time = Capybara.default_max_wait_time Capybara.default_max_wait_time = 10 end after do Capybara.default_max_wait_time = @old_wait_time end scenario ''Payment via Stripe'', js: true do visit payment_path click_button ''Pay with Card'' # Use VCR to avoid actual data creation VCR.use_cassette ''orders/payment_via_stripe'' do expect(page).to have_css(''iframe[name="stripe_checkout_app"]'') stripe_iframe = all(''iframe[name=stripe_checkout_app]'').last Capybara.within_frame stripe_iframe do # Set values by placeholders fill_in ''Card number'', with: ''4242424242424242'' fill_in ''MM / YY'', with: ''08/44'' fill_in ''CVC'', with: ''999'' # You might need to fill more fields... click_button ''Pay $9.99'' end # Confirm payment completed expect(page).to have_content ''Payment completed.'' end end end

Estoy usando:

  • Selenio-webdriver 3.14.0
  • rspec-rails 3.8.0
  • capibara 3.7.1
  • raya 3.26.0
  • carriles 5.2.1
  • ruby 2.5.1
  • vcr 4.0.0
  • webmock 3.4.2
  • Cromo 69

Mi aplicación está construida de acuerdo con https://stripe.com/docs/checkout/rails .


¡Problema resuelto!

Con un poco de ayuda de Parov a través de su pregunta y respuesta similares [ Poltergeist Stripe checkout.js ] localicé el problema utilizando una versión antigua de Capybara ''~> 1.1.2'' y el posterior efecto de dependencia que esto tuvo en las diversas pruebas de JavaScript. gemas (es decir, selenio, capybara-webkit, poltergeist ...).

Hacer una bundle update del bundle update de Capybara a 2.3.0, y así llevar a poltergeist a 1.5.1, con Selenio-webdriver en 2.42.0 y capybara-webkit en 1.1.0, hace que (casi) todo funcione.

Para el selenio, este método a través de la captura de problemas de Capybara en JS modal funciona:

stripe_iframe = all(''iframe[name=stripe_checkout_app]'').last Capybara.within_frame stripe_iframe do fill_in "email", with: "[email protected]" ... end

Sin embargo, eso no funciona en poltergeist o capybara-webkit.

Para poltergeist, la sugerencia de parov funciona:

stripe = page.driver.window_handles.last page.within_window stripe do fill_in "email", with: "[email protected]" ... end

Para capybara-webkit no pude hacer que nada funcionara, aunque dado que tenía algo que trabajaba con Poltergeist, no dediqué mucho tiempo a encontrar una solución para capybara-webkit.

¿Comentarios?


Para capybara-webkit , pude hacer que esto funcionara:

stripe_iframe = page.driver.window_handles.last page.within_window stripe_iframe do fill_in "email", with: "[email protected]" ... end