Капибара проблема заполнения 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 попадает (после того, как откроется модальное окно с формой полосы):

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, нет входов или чего-либо, с чем можно работать.

обновление

вот разметка для формы, которая содержит 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 латина.