Капибара проблема заполнения JS modal
позвольте мне начать с подтверждения что это не дубликат (в том, что ответы там выложены не решить мою проблему). этот пост по существу моя точная проблема: капибара не может найти поля формы в модальной полосе, чтобы заполнить их.
вот моя спецификация капибары:
describe 'checkout', type: :feature, js: true do
it 'checks out correctly' do
visit '/'
page.should have_content 'Amount: .00'
page.find('#button-two').click_button 'Pay with Card'
Capybara.within_frame 'stripe_checkout_app' do
fill_in 'Email', with: 'example@example.com'
fill_in 'Name', with: 'Nick Cox'
fill_in 'Street', with: '123 Anywhere St.'
fill_in 'ZIP', with: '98117'
fill_in 'City', with: 'Seattle'
click_button 'Payment Info'
fill_in 'Card number', with: '4242424242424242' #test card number
fill_in 'MM/YY', with: '02/22'
fill_in 'CVC', with: '222'
click_button 'Pay'
end
page.should have_content 'Thanks'
end
end
текст в этой спецификации-моя последняя попытка. ошибка капибары Unable to find field "Email"
.
что я пробовал
- это самая последняя попытка заполнения поля текстом-заполнителем, как было предложено здесь
- Поиск поля электронной почты по атрибуту name (например,
fill_in 'email', with: 'example@example.com'
) - и
type: :feature
иjs: true
хэши вdescribe
- и
within_frame
вызов наCapybara
- попытка найти вход с помощью css (например,
page.find('.emailInput input').set('example@example.com'
) - добавлять
within
блок:within('.panel') do
вокруг входных данных формы (сбой сUnable to find css ".panel"
) - добавлять
sleep 3
перед предыдущим шагом, если он ищет этот div слишком рано (не удается сUnable to find css ".panel"
) - добавление вызова
find
(а такжеpage.find
) и передача формы манипуляции в виде блока (С и безwithin
блок вложен в тегfind
блок):
Capybara.within_frame 'stripe_checkout_app' do
page.find('.panel') do
fill_in 'Email', with: 'example@example.com'
...
end
end
я также пробовал это с полтергейстом.
что сводит с ума в этом это то, что я изменил драйвер Capybara с poltergeist обратно на selenium/Firefox, и я физически вижу, как драйвер открывает страницу, нажимает кнопку и вызывает модальный.
есть мысли о том, как заставить капибару взаимодействовать с этой формой?
редактировать
я также попытался вставить binding.pry
там и отладка с pry gem. HTML-код страницы в момент модальной загрузки - это несколько элементов, а затем теги скриптов, которые динамически вставляйте JS в головку iframe. См. Этот скриншот DOM в точке, где binding.pry
попадает (после того, как откроется модальное окно с формой полосы):
, так что <div class="emailInput">
явно там, но page.has_selector?('.emailInput')
возвращает false в консоли pry.
здесь это GitHub суть того, что происходит, когда я печатаю page.html
из привязки pry в качестве следующей строки после Capybara.within_frame 'stripe_checkout_app' do
. то есть, это разметка С точки зрения Capybara, и это сильно отличается от DOM, как показано на скриншоте DOM фактической формы, когда она появляется на экране, показанном выше. как вы можете видеть, в разметке, которую видит Capybara, нет входов или чего-либо, с чем можно работать.
обновление
вот разметка для формы, которая содержит JS, который выполняет модальный. (Разметка в haml).
%form{ action: "/charge?amount=1400", method: 'post', class: 'payment', id: 'fourteen' }
%article
%label.amount
%span Amount: .00
.stripejs#button-one
%script{ src: 'https://checkout.stripe.com/checkout.js', class:'stripe-button', :'data-key' => settings.publishable_key, :'data-name' => 'Slow Coffee', :'data-description' => '2 8oz. bags (2/month)', :'data-shipping-address' => true }
5 ответов
Я не могу воспроизвести эту проблему в отношении демонстрационная страница проверки Stripe's.
require "capybara"
sess = Capybara::Session.new(:selenium)
sess.visit("https://stripe.com/docs/checkout")
sess.click_button('Pay with Card')
sess.within_frame('stripe_checkout_app') do
sess.fill_in 'Email', with: 'test@example.com' # it's visible that field becomes filled in
sleep 3 # just to inspect that manually
end
проблема, описанная вами, заключается в том, что есть два iframes с именем stripe_checkout_app
. within_frame
находит первый из них, который не содержит биллинговую поля. Чтобы найти второй iframe вы можете сделать, например:
stripe_iframe = all('iframe[name=stripe_checkout_app]').last
within_frame stripe_iframe do
# your code here
end
У вас нет 50 rep для комментариев, но вы пытались добавить некоторое время ожидания на capybara, поэтому модальный имеет время для полной загрузки, я столкнулся с аналогичной проблемой с помощью testcafe и дал ему 2-3 секунд ожидания.
просто выбрасываю идею здесь, так как я застрял на этих маленьких идиосинкратических проблемах и знаю, насколько они могут быть разочаровывающими....Однажды я просто пытался заставить капибару нажать кнопку "Закрыть"в модальном диалоговом окне Twitter Bootstrap. Оказывается, чтобы заставить его работать, мне пришлось вложить модальный html-код Bootstrap в тег "form", а затем Capybara смог его найти. Интересно, это ваша проблема?
Capybara fill_in использует идентификаторы css, а не классы. Пример
<input autofocus="autofocus" class="center" id="user_login" name="user[login]" placeholder="Username/Email" type="text" >
вы также можете использовать <input>
вместо <div>
попробуйте с Poltergeist, используя методы переключения окна
https://github.com/jonleighton/poltergeist#window-switching
stripe = page.driver.window_handles.last
page.within_window stripe do
fill_in "Email", :with => "test@test.com"
fill_in 'Card number', with: '4242424242424242' #test card number
fill_in 'MM / YY', with: '02/22'
fill_in 'CVC', with: '222'
click_button 'Pay'
end
Я нашел решение в этом испанском блог: объектов: театр numerica латина.