通过 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 1
s;否则 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 + Selenium 以通过 SSL 进行测试