Проблемы с Capybara в JS modal
Позвольте мне начать с подтверждения того, что это не дубликат (в том, что ответы, опубликованные там, не исправили мою проблему). Этот пост - это, по сути, моя точная проблема: Capybara не может найти поля формы в модуле Stripe, чтобы заполнить их.
Здесь моя спецификация Capybara:
describe 'checkout', type: :feature, js: true do
it 'checks out correctly' do
visit '/'
page.should have_content 'Amount: $20.00'
page.find('#button-two').click_button 'Pay with Card'
Capybara.within_frame 'stripe_checkout_app' do
fill_in 'Email', with: '[email protected]'
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
Текст этой спецификации - моя самая последняя попытка. Ошибка Capybara Unable to find field "Email"
.
Что я пробовал
- Эта последняя попытка заполнить поле текстом-заполнителем, предложенным здесь
- Поиск поля электронной почты с помощью атрибута name (например,
fill_in 'email', with: '[email protected]'
)
- С и без хэшей
type: :feature
и js: true
в describe
- С вызовом
within_frame
и без него <<27 >
- Попытка найти вход css (например,
page.find('.emailInput input').set('[email protected]'
)
- Добавление блока
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: '[email protected]'
...
end
end
Я тоже пробовал это с помощью полтергейста.
Какое безумие в этом заключается в том, что я изменил драйвер Capybara от полтергейста до селена /Firefox, и я могу физически видеть, как драйвер открывает страницу, нажимая кнопку и поднимая модальность.
Любые мысли о том, как заставить Capybara взаимодействовать с этой формой?
Изменить
Я также попытался вставить binding.pry
туда и отладить pry gem. HTML страницы в точке, где модальные нагрузки - это несколько элементов, а затем теги script, которые динамически вставляют JS в начало iframe. Смотрите этот снимок экрана DOM в точке, где поражен binding.pry
(после того, как модальное окно открывается в форме Stripe):
![enter image description here]()
Итак, <div class="emailInput">
явно там, но page.has_selector?('.emailInput')
возвращает false в консоль pry.
Здесь - это описание GitHub того, что происходит, когда я печатаю page.html
из привязки pry как следующую строку после Capybara.within_frame 'stripe_checkout_app' do
. То есть это разметка с точки зрения Capybara, и это сильно отличается от DOM, как показано на скриншоте DOM фактической формы, когда она появляется на экране, показанной выше. Как вы можете видеть, нет никаких входов или чего-либо, с чем можно работать в разметке, которую видит Capybara.
Update
Вот разметка для формы, содержащей JS, которая выполняет модальную. (Разметка находится в haml).
%form{ action: "/charge?amount=1400", method: 'post', class: 'payment', id: 'fourteen' }
%article
%label.amount
%span Amount: $14.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 }
Ответы
Ответ 1
Я не могу воспроизвести эту проблему на странице Stripe demo checkout.
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: '[email protected]' # it visible that field becomes filled in
sleep 3 # just to inspect that manually
end
Проблема, описанная вами, состоит в том, что существует два iframe с именем stripe_checkout_app
. within_frame
находит первый из них, который не содержит полей фактурирования. Чтобы найти второй iframe, вы можете сделать, например:
stripe_iframe = all('iframe[name=stripe_checkout_app]').last
within_frame stripe_iframe do
# your code here
end
Ответ 2
У вас нет 50 комментариев для комментариев, но вы попробовали добавить некоторое время ожидания на capybara, чтобы модальное время полностью загрузилось, я столкнулся с подобной проблемой, используя testcafe и дав ей 2-3 секунды ожидания. трюк.
Ответ 3
Просто выкидывая идею здесь, так как я застрял в этих маленьких проблемных проблемах и знаю, как это расстраивает их... Как только я просто пытался заставить Capybara нажать кнопку "Закрыть" в Twitter Модифицированное диалоговое окно Bootstrap. Оказывается, чтобы заставить его работать, мне пришлось заключить модальный HTML-код Bootstrap в тег "form", а затем Capybara смог его найти. Интересно, является ли что-то вроде этого вашей проблемой?
Ответ 4
Capybara fill_in использует css ids не классы. Пример
<input autofocus="autofocus" class="center" id="user_login" name="user[login]" placeholder="Username/Email" type="text" >
Вы также можете использовать <input>
вместо <div>
Ответ 5
Попробуйте с помощью Poltergeist, используя методы переключения окон
https://github.com/jonleighton/poltergeist#window-switching
stripe = page.driver.window_handles.last
page.within_window stripe do
fill_in "Email", :with => "[email protected]"
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 latina.