通过 Capybara (v2) 与 Bootstrap 模态交互时出现问题

Posted

技术标签:

【中文标题】通过 Capybara (v2) 与 Bootstrap 模态交互时出现问题【英文标题】:Trouble interacting with Bootstrap modals via Capybara (v2) 【发布时间】:2013-01-07 11:17:51 【问题描述】:

在 Rails 应用程序中,我尝试使用 Capybara 和 capybara-webkit 驱动程序在 Rspec 中测试 Bootstrap modal 和 jQuery TokenInput field。有问题的部分如下:

click_link 'Create Team Modal'
sleep 1

within('div#modal_popup') do
  fill_in 'input#token-input-team_name', with: 'Fancy team name'
  sleep 1
  fill_in 'input#token-input-team_name', with: '\t'
  sleep 1

  click_button 'Create Team'
end

page.should have_content('Fancy team name')
点击按钮获取模态 TokenInput 填写团队名称 模拟 Tab 键以将其选中 创建团队 验证名称是否显示在页面上

这仅适用于所有sleep 1s;否则 Capybara 在have_content 崩溃,最终导致服务器错误,因为永远无法正确选择团队名称。然而,其他没有 TokenInput 字段的 Bootstrap 模式在加载之前不需要sleep 1

说了这么多,有什么办法可以摆脱睡眠并让这一切正常进行吗? Capybara 2 取出了wait_until(有充分的理由),因为它会在默认等待时间内等待测试某些东西……但这似乎并没有反映在我的上述测试中;就好像水豚在进入/退出这个模式时没有参与那个等待期。有人对此有经验吗?使用 Rails 3.2.10、Rspec 2.12、Capybara 2、capybara-webkit 0.14.0、TokenInput 1.6。

【问题讨论】:

这可能会有所帮助:blog.crowdint.com/2013/09/20/… 另见github.com/teamcapybara/capybara/issues/1890 【参考方案1】:

尝试在测试环境 layouts/application.html.erb 中禁用动画

<% if Rails.env.test? %>
 <style type="text/css">
    .modal.fade, .fade 
      -webkit-transition: opacity 0.01s;
      -moz-transition: opacity 0.01s;
      -ms-transition: opacity 0.01s;
      -o-transition: opacity 0.01s;
      transition: opacity 0.01s;
    
 </style>
<%end%>

【讨论】:

正如@matt 链接的croudint article 中指出的那样,这也可以放在单独的样式表中。 这适用于哪个版本的 Bootstrap?我遇到了同样的问题,但我使用的是 Bootstrap 3,上面的建议似乎没有解决我的问题。【参考方案2】:

我建议在测试环境中添加 falowing css:

  div, a, span, footer, header 
      -webkit-transition: none !important;
      -moz-transition: none !important;
      -ms-transition: none !important;
      -o-transition: none !important;
      transition: none !important;
  

  .modal 
    display: none !important;
  

  .modal.in 
    display: block !important;
  

  .modal-backdrop 
    display: none !important;
  

在body的and中添加这个js:

$(".fade").removeClass("fade");

这解决了我使用 capybara 和 bootstrap 的大部分问题。

【讨论】:

还需要(在我的情况下)使用gem 'capybara-webkit'【参考方案3】:

我们只是这样做,它似乎工作(例如点击$('.tp-header-login'):

# instead of find(".tp-header-login")

find(".tp-header-login") # still do the find so you are sure its loaded then...
execute_script "$('.tp-header-login').click()"

【讨论】:

【参考方案4】:

对于那些希望避免Rails.env.___? hacks* 的人来说,以下似乎在避免在基于 Bootstrap 的模式上测试 jQuery UI drag-and-drop functionality 时出现问题(到目前为止 - 手指交叉)。

首先,我们已经在 “等待” 模态框出现,使用这样的辅助方法:

def wait_for_modal_to_appear
  modal = wait_until 
    # Look for the modal by ID/whatever...
  
  raise Capybara::ModalNotFound.new('...') if modal.nil?
  return modal
end

然而,当我们尝试在该模式中拖放元素时,我们仍然遇到了一些虚假问题。在return 行之前添加了以下代码,似乎 成功了:

page.execute_script("document.getElementById('#modal[:id]').classList.remove('fade');")

* 最近正是这样的 hack 导致需要在与我合作的公司进行紧急部署......一个糟糕的代码更改设法使其投入生产,因为它仅由 if Rails.env.production? 限定符激活;否则它会失败一半的测试套件。

【讨论】:

以上是关于通过 Capybara (v2) 与 Bootstrap 模态交互时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

Capybara 可以与 Turbolinks 一起玩吗?

资产预编译后,RSpec / Capybara测试不会通过

如何模拟与 Capybara 共享地理位置?

配置 Capybara + Selenium 以通过 SSL 进行测试

Rails - 失去与集成测试和 Capybara 的会话 - CSRF 相关?

Capybara 请求规范与 JS 的问题 - 找不到模型