-
-
Save nruth/b2500074749e9f56e0b7 to your computer and use it in GitHub Desktop.
# -*- encoding : utf-8 -*- | |
module PayStripeHelpers | |
# must be used with driver: :selenium (or :sauce?) | |
def pay_stripe | |
sleep(0.7) # wait for the js to create the popup in response to pressing the button | |
within_frame 'stripe_checkout_app' do # must be selenium | |
# fill_in 'card_number', with: '4242424242424242' no longer works | |
4.times {page.driver.browser.find_element(:id, 'card_number').send_keys('4242')} | |
# fill_in 'cc-exp', with: '5/2018' no longer works | |
page.driver.browser.find_element(:id, 'cc-exp').send_keys '5' | |
page.driver.browser.find_element(:id, 'cc-exp').send_keys '18' | |
page.driver.browser.find_element(:id, 'cc-csc').send_keys '123' | |
find('button[type="submit"]').click | |
end | |
# wait for stripe to finish and change the page; default is 2 seconds | |
find("body[data-tests-page='member/dashboard']", wait: 30) | |
end | |
end | |
if respond_to?(:World) #cucumber | |
World(PayStripeHelpers) | |
else | |
RSpec.configure do |config| | |
config.include PayStripeHelpers, :type => :feature | |
end | |
end |
Thanks! :wait: did the job!
We added address collection and made a few tweaks:
find('#submitButton', text: 'Payment Info').click
then leave the frame and call
within_frame 'stripe_checkout_app' do
again before filling in the card details
unfortunately this is all really really brittle, and in the end I've just kept one test that hits their javascript, and replaced the rest with this:
expect(page).to have_css('iframe[name="stripe_checkout_app"]')
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();")
which assumes checkout works correctly, and just tests your server's API calls when it's given a valid stripe token.
The js injected into the browser is almost the same as the code in our checkout.js form handler.
The various page.driver. ....
can be simplified to e.g.
4.times {find('#card_number').send_keys('4242')}
Here's an updated version of this snippet that worked for me:
stripe_card_number = '4242424242424242'
within_frame 'stripe_checkout_app' do
# must use `find_field` since the credit card field does not have a static ID
find_field('Card number').send_keys(stripe_card_number)
find_field('MM / YY').send_keys "01#{DateTime.now.year + 1}"
find_field('CVC').send_keys '123'
find('button[type="submit"]').click
end
You are my hero!
Adding address stuff to @iloveitaly 's answer. This stuff still works as of late(ish) 2017.
within_frame 'stripe_checkout_app' do
find_field('Name').send_keys 'Some Person'
find_field('Street').send_keys '123 Sunshine Pl.'
find_field('City').send_keys 'Seattle'
find_field('ZIP Code').send_keys '98112'
find('button[type="submit"]').click
find_field('Card number').send_keys '4242424242424242'
find_field('MM / YY').send_keys "01#{DateTime.now.year + 1}"
find_field('CVC').send_keys '123'
find('button[type="submit"]').click
end
for v3 (was able to find iframe only by position)
def fill_stripe(card, cvc, exp)
iframes = all('iframe')
card_iframe = iframes[0]
cvc_iframe = iframes[1]
exp_iframe = iframes[2]
within_frame card_iframe do
card.chars.each do |piece|
find_field('cardnumber').send_keys(piece)
end
end
within_frame cvc_iframe do
cvc.chars.each do |piece|
find_field('cvc').send_keys(piece)
end
end
within_frame exp_iframe do
exp.chars.each do |piece|
find_field('exp-date').send_keys(piece)
end
end
end
Modified to work with Stripe Card Element:
def fill_stripe_element(card,exp, cvc, postal='')
card_iframe = all('iframe')[0]
within_frame card_iframe do
card.chars.each do |piece|
find_field('cardnumber').send_keys(piece)
end
exp.chars.each do |piece|
find_field('exp-date').send_keys(piece)
end
cvc.chars.each do |piece|
find_field('cvc').send_keys(piece)
end
postal.chars.each do |piece|
find_field('postal').send_keys(piece)
end
end
end
Thanks @bhbryant!
Is this still working for you ? It's not working for me anymore... This is what I'm seeing
- Stripe DOES in fact initialize an
iframe
; without Stripe on the page, noiframe
is found - However, with Stripe and within that
iframe
, if I search for a genericinput
element, it defaults to an input I had put on the page
It's as if Stripe's iframe
is "deflecting" to my regular view...
I added some helpers for Stripe SCA in case anyone needs that: https://gorails.com/blog/fill-in-stripe-elements-js-for-sca-3d-secure-2-and-capybara
Was wondering if there was any update to this for Stripe's Payment Element? Have been struggling to get this to work with the new way. Oddly, I can get it to work within a pry, but not when it runs by itself.
Thank you, this is lovely!