Capybara在JS模式中填补麻烦

时间:2014-03-11 20:21:28

标签: ruby capybara stripe-payments

首先我要确认这不是重复的(因为那里发布的答案没有解决我的问题)。 This post基本上是我的确切问题:Capybara无法在Stripe模式中找到表单字段来填充它们。

这是我的水豚规格:

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: '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

该规范中的文字是我最近的尝试。 Capybara错误为Unable to find field "Email"

我尝试了什么

  • 最近尝试按照建议的here
  • 按占位符文字填写字段
  • 按名称属性查找电子邮件字段(例如fill_in 'email', with: 'example@example.com'
  • type: :feature
  • 中是否有js: truedescribe哈希值
  • within_frame
  • 上进行Capybara调用和不使用page.find('.emailInput input').set('example@example.com'
  • 尝试通过css(例如within
  • 查找输入
  • 在表单输入周围添加within('.panel') do块:Unable to find css ".panel"(以sleep 3失败)
  • 在上一步之前添加Unable to find css ".panel",以防它过早地查找该div(以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 块:

binding.pry

我也曾尝试过与吵闹的对手。

令人抓狂的是,我将Capybara司机从恶作剧者改回了selenium / Firefox,我可以看到司机打开页面,点击按钮并调出模态。

有关如何让Capybara与此表单互动的任何想法?

修改

我还尝试在binding.pry中添加<div class="emailInput">并使用pry gem进行调试。页面的HTML在模态加载的点上是几个元素,然后是脚本标记,动态地将JS插入到iframe的头部。在点击page.has_selector?('.emailInput')的位置(在使用Stripe表单打开模态窗口之后)查看DOM的此屏幕截图:

enter image description here

因此page.html显然在那里,但Capybara.within_frame 'stripe_checkout_app' do在pry控制台中返回false。

Here是GitHub的一个要点,当我从 %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 } 之后的pry绑定作为下一行打印{{1}}时会发生什么。 也就是说,这是Capybara视角的标记,这与DOM的差别很大,如屏幕上显示的实际表单的DOM屏幕截图所示。正如您所见,Capybara看到的标记中没有任何输入或任何可用的东西。

更新

这是包含执行模式的JS的表单的标记。 (标记是haml)。

{{1}}

5 个答案:

答案 0 :(得分:5)

我无法针对Stripe's demo checkout page重现此问题。

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

您描述的问题是因为有两个名称为stripe_checkout_app的iframe。 within_frame发现其中第一个不包含结算字段。要查找第二个iframe,您可以执行以下操作:

stripe_iframe = all('iframe[name=stripe_checkout_app]').last
within_frame stripe_iframe do
  # your code here
end

答案 1 :(得分:4)

不要有50个回复评论,但是,你尝试在水豚上添加一些等待时间以便模态有时间完全加载,我遇到类似的问题使用testcafe并给它2-3秒的等待时间做了伎俩。

答案 2 :(得分:0)

刚刚在这里抛出一个想法,因为我一直坚持这些小的特殊问题,并且知道它们是多么令人沮丧......一旦我试图让Capybara点击Twitter上的“关闭”按钮Bootstrap模式对话框。事实证明,为了让它工作,我不得不将Bootstrap模态html代码包含在“form”标签中,然后Capybara能够找到它。我想知道这样的问题是不是你的问题?

答案 3 :(得分:0)

Capybara fill_in使用css ID而不是类。示例

<input autofocus="autofocus" class="center" id="user_login" name="user[login]" placeholder="Username/Email" type="text" >

您可能还必须使用<input>代替<div>

答案 4 :(得分:-1)

使用窗口切换方法

尝试使用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 latina