加载页面后,我有运行和隐藏的代码,并根据xhr返回的数据显示各种项目。
我的集成测试看起来像这样:
it "should not show the blah" do
page.find('#blah').visible?.should be_true
end
当我在上下文中手动转到该测试页面时,#blah 并不像我期望的那样可见。我怀疑Capybara正在查看页面的初始状态(在这种情况下是不可见的),在JS运行之前评估DOM的状态并且未通过测试。
是的,我在包含的describe块上设置了:js => true
:)
任何想法都将不胜感激!我希望我不必在这里故意拖延,感觉不稳定,会减慢速度。
答案 0 :(得分:124)
我认为这里的find
语句是隐含等待的语句,所以Capybara会等到元素出现在页面上,但不会等到它变为可见。
在这里,您希望Capybara等待可见元素出现,这应该可以通过指定visible
选项来实现:
expect(page).to have_selector('#blah', visible: true)
我还没有尝试过,但如果您希望ignore_hidden_elements
始终等待可见元素,那么find
配置选项在这里也很有用。
答案 1 :(得分:35)
这是另一种方法,对我来说非常好:
find(:css, "#some_element").should be_visible
特别是对于更复杂的查找,例如
find(:css, "#comment_stream_list li[data-id='#{@id3}']").should_not be_visible
会断言元素已被隐藏。
答案 2 :(得分:19)
如果要检查某个元素是否在页面上但是不可见,visible: false
将无法正常工作。让我难过了一点。
以下是如何操作:
# assert element is present, regardless of visibility
page.should have_css('#some_element', :visible => false)
# assert visible element is not present
page.should have_no_css('#some_element', :visible => true)
答案 3 :(得分:9)
使用:
Ruby: ruby 1.9.3dev (2011-09-23 revision 33323) [i686-linux]
Rails: 3.2.9
Capybara: 2.0.3
我有一个Rails应用程序,其中有一个链接,当点击时应该提交一个AJAX帖子请求并返回一个JS响应。
链接代码:
link_to("Send Notification", notification_path(user_id: user_id), remote: true, method: :post)
JS响应(.js.haml文件)应切换链接所在页面上的以下隐藏div:
#notification_status(style='display:none')
js.haml文件内容:
:plain
var notificationStatusContainer = $('#notification_status');
notificationStatusContainer.val("#{@notification_status_msg}");
notificationStatusContainer.show();
我正在测试我发送通知和显示通知的方案 使用Cucumber向用户发送通知状态消息(内置的 cucumber-rails gem) 水豚支持)
我试图测试ID为 notification_status 的元素是否可见 在我的步骤定义中成功响应。为此,我尝试了以下语句:
page.find('#notification_status').should be_visible
page.should have_selector('#notification_status', visible: true)
page.should have_css('#notification_status', visible: true)
page.find('#notification_status', visible: true)
page.find(:css, 'div#notification_status', visible: true)
上述任何一项都不适用于我,也未能成功。上面列出了5个片段 最后4个因以下错误而失败:
'expected to find css "#notification_status" but there were no matches. Also found "", which matched the selector but not all filters. (Capybara::ExpectationNotMet)'
这很奇怪,因为以下陈述正确传递:
page.has_selector?('#notification_status')
事实上,我使用
检查了页面源代码 print page.html
出现了
<div style='' id='notification_status'></div>
这是预期的。
最后我发现这个链接capybara assert attributes of an element显示了如何以原始方式检查元素的属性。
我在Capybara文档中发现可见吗?方法(http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Element#visible%3F-instance_method) 以下信息:
Not all drivers support CSS, so the result may be inaccurate.
因此,当得出测试元素的可见性时,我得出结论 不依赖于水豚的可见效果?使用CSS选择器时的方法 并使用链接capybara assert attributes of an element
中建议的解决方案我想出了以下内容:
module CustomMatchers
def should_be_visible(css_selector)
find(css_selector)['style'].should_not include('display:none', 'display: none')
end
end
World(CustomMatchers)
用法:
should_be_visible('#notification_status')
答案 4 :(得分:8)
可见的方法不明显
失败可能来自对被认为是否可见的误解,因为它不是显而易见的,不是驱动程序可移植的,并且记录不足。一些测试:
HTML:
<div id="visible-empty" ></div>
<div id="visible-empty-background" style="width:10px; height:10px; background:black;"></div>
<div id="visible-empty-background-same" style="width:10px; height:10px; background:white;"></div>
<div id="visible-visibility-hidden" style="visibility:hidden;" >a</div>
<div id="visible-display-none" style="display:none;" >a</div>
Rack测试认为唯一不可见的是内联display: none
(不是内部CSS,因为它不做选择器):
!all('#visible-empty', visible: true).empty? or raise
!all('#visible-empty-background', visible: true).empty? or raise
!all('#visible-empty-background-same', visible: true).empty? or raise
!all('#visible-visibiility-hidden', visible: true).empty? or raise
all('#visible-display-none', visible: true).empty? or raise
Poltergeist有类似的行为,但它可以处理内部CSS和Js style.display
操作:
Capybara.current_driver = :poltergeist
!all('#visible-empty', visible: true).empty? or raise
!all('#visible-empty-background', visible: true).empty? or raise
!all('#visible-empty-background-same', visible: true).empty? or raise
!all('#visible-visibiility-hidden', visible: true).empty? or raise
all('#visible-display-none', visible: true).empty? or raise
Selenium的行为完全不同:如果认为空元素不可见且visibility-hidden
以及display: none
:
Capybara.current_driver = :selenium
all('#visible-empty', visible: true).empty? or raise
!all('#visible-empty-background', visible: true).empty? or raise
!all('#visible-empty-background-same', visible: true).empty? or raise
all('#visible-visibiility-hidden', visible: true).empty? or raise
all('#visible-display-none', visible: true).empty? or raise
另一个常见问题是默认值visible
:
false
(看 可见和不可见的元素),true
Capybara.ignore_hidden_elements
选项控制。完整的可运行测试on my GitHub。
答案 5 :(得分:5)
您可能需要查看this post,它提供了一个等待所有ajax请求完成的示例方法:
def wait_for_ajax(timeout = Capybara.default_wait_time)
page.wait_until(timeout) do
page.evaluate_script 'jQuery.active == 0'
end
end
答案 6 :(得分:2)
现在接受的答案有点过时,因为'should'已被弃用语法。这些天你最好做一些expect(page).not_to have_css('#blah', visible: :hidden)
答案 7 :(得分:1)
这里的其他答案是“等待”元素的最佳方式。但是我发现这对我正在处理的网站不起作用。基本上,需要点击的元素在完全加载后面的函数之前是可见的。这是几分之一秒,但我发现我的测试运行得如此之快,以至于它点击按钮并没有发生任何事情。我设法通过这个make-shift布尔表达式解决它:
if page.has_selector?('<css-that-appears-after-click>')
puts ('<Some-message-you-want-printed-in-the-output>')
else
find('<css-for-the-button-to-click-again>', :match == :first).trigger('click')
end
基本上它使用水豚的默认等待时间来寻找应该出现的东西,如果不存在则会重试你的点击。
我再次说我应该首先尝试should have_selector
方法,但如果它不起作用,请试试这个