Как написать интеграционные тесты для проверки Stripe на Rails?
Я ударил стену, пытаясь написать тест интеграции для Stripe checkout.js [https://checkout.stripe.com/checkout.js] для моего приложения Rails 3.2.
Выполнение проверок на полосах работает корректно для меня при проверке вручную (с использованием клавиш тестирования Stripe), но я не могу заставить Capybara обнаружить и fill_in
поле электронной почты в модуле checkout iframe.
Я использую полтергейст для безголового javascript, хотя также тестировал это с помощью capybara-webkit и даже селена с той же проблемой.
То, что я пытаюсь проверить, - это полный поток подписки на подписку, чтобы показать, что новый пользователь может создать учетную запись абонента после ввода своих платежных реквизитов в Stripe, но я не могу пройти мимо всплывающего окна Stripe.
Вот мой 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
Какие ошибки с:
Failure/Error: Capybara.within_frame stripe_iframe do
Capybara::Poltergeist::TimeoutError:
Timed out waiting for response to {"name":"push_frame","args":[null]}
Если я поменяю попытку выбрать правильный iframe (предлагаемый здесь: проблема с Capybara, заполняющая JS-модальный), вот так:
# stripe_iframe = all('iframe[name=stripe_checkout_app]').last
# Capybara.within_frame stripe_iframe do
Capybara.within_frame 'stripe_checkout_app' do
Я все равно получаю подобное:
Capybara::Poltergeist::TimeoutError:
Timed out waiting for response to {"name":"push_frame","args":["stripe_checkout_app"]}
Похоже, что в зависимости от того, какой я использую javascript для тестирования, rspec/capybara не может найти проверку iframe в Stripe. Когда я проверю с помощью Selenium, я вижу кнопку Choose this Plan
нажатой и всплывающее окно Checkout, но время истекает, ища поле электронной почты для заполнения.
Любые идеи?
Я уже пробовал:
- Различные способы выбора или поиска поля электронной почты.
- Обновление всех моих драгоценных камней.
- Использование StripeMock до этого (не так, чтобы оно было задействовано, верно?).
- Выполнение тех же тестов с собственным сайтом Stripe, которые дают те же ошибки:
Тестирование с помощью:
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
В зависимости от того, какой метод я использую для выбора iframe, я получаю те же ошибки. Используя только 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]}
или с использованием селена с stripe_iframe = all('iframe[name=stripe_checkout_app]').last
:
Failure/Error: Unable to find matching line from backtrace
SystemStackError:
stack level too deep
или даже просто:
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
... в зависимости от того, какой тест javascript я использую.
Приветствуется любая помощь или мудрость!
Ответы
Ответ 1
Я не мог получить какие-либо решения, которые до сих пор работают для меня, а затем читать это сообщение: https://gist.github.com/nruth/b2500074749e9f56e0b7 Я понял, что ключ должен был добавить задержка на тест, чтобы дать полосе достаточно времени, чтобы 1) загрузить окно проверки и 2) обработать токен.
По этой причине единственным кодом, с которым я мог бы работать, было это (не стесняйтесь играть со временем):
СЕЛЕН
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
Для Capybara-webkit трюк sleep
не работал и не грустно делал решение @Ryan, и я слишком устал, пытаясь понять это, поэтому я просто остановился, но, надеюсь, кто-то иначе это получится, потому что я предпочел бы использовать webkit по причинам скорости! (Я использовал capybara-webkit 1.3.0
)
В случае, если это помогает, вот мои соответствующие версии:
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
Ответ 2
Проблема решена!
С некоторой помощью от parov через его похожий вопрос и ответ [Poltergeist Stripe checkout.js] Я отследил проблему до использования старой версии Capybara '~ > 1.1.2 'и последующий эффект зависимостей, который это имело на различных драгоценных камнях javascript (например, selenium, capybara-webkit, poltergeist...).
Выполнение bundle update
Capybara до 2.3.0, и поэтому приведение полтергейста в 1.5.1, с селеном-webdriver на 2.42.0 и capybara-webkit в 1.1.0, получает (почти) все, что работает.
Для селена этот метод через заполнение проблемы Capybara в JS modal работает:
stripe_iframe = all('iframe[name=stripe_checkout_app]').last
Capybara.within_frame stripe_iframe do
fill_in "email", with: "[email protected]"
...
end
Однако это не работает в poltergeist или capybara-webkit.
Для полтергейста работает предложение parov:
stripe = page.driver.window_handles.last
page.within_window stripe do
fill_in "email", with: "[email protected]"
...
end
Для capybara-webkit Я не смог ничего работать, хотя, учитывая, что у меня что-то работало с полтергейстом, я не уделял слишком много времени поиску решения capybara-webkit.
Комментарии?
Ответ 3
Я боролся с этим в течение некоторого времени (как показывает james james), и, в конце концов, он слишком хрупкий и слишком медленный, чтобы проверить чек.
Вместо этого вы можете использовать следующие (ruby, capybara, selenium) для stub checkout.js и опубликовать свою форму с помощью токена полосы:
# 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();")
n.b. это предполагает, что у вас уже есть stripe api gem, загруженный в тестовую среду (вашим приложением rails), и у вас есть зарегистрированный ключ API и т.д., иначе см. docs.
Ответ 4
Для capybara-webkit я смог заставить это работать:
stripe_iframe = page.driver.window_handles.last
page.within_window stripe_iframe do
fill_in "email", with: "[email protected]"
...
end