在一些 JS 运行后,如何让水豚检查可见性?

加载页面之后,我有了运行、隐藏和显示各种基于 xhr 返回数据的项目的代码。

我的积分测试是这样的:

it "should not show the blah" do
page.find('#blah').visible?.should be_true
end

当我手动转到这个测试运行的上下文中的页面时,正如我所期望的那样,# bla 是 没有可见的。我怀疑 Capybara 正在查看页面的初始状态(在本例中是不可见的) ,评估 DOM 的状态并在 JS 运行之前失败测试。

是的,我在包含描述块上设置了 :js => true:)

任何想法都将不胜感激!我希望我不会故意拖延,这样会让事情变得缓慢。

84329 次浏览

我认为这里的 find语句是一个隐式等待语句,所以 Capybara 会等到元素出现在页面上,但不会等到它变得可见。

在这里,您希望 Capybara 等待可见元素出现,这应该可以通过指定 visible选项来实现:

expect(page).to have_selector('#blah', visible: true)

我还没有试过,但是如果您希望 find总是等待可见的元素,那么 ignore_hidden_elements配置选项在这里可能也很有用。

您可能想看看 这篇文章,它提供了一个等待所有 ajax 请求完成的示例方法:

def wait_for_ajax(timeout = Capybara.default_wait_time)
page.wait_until(timeout) do
page.evaluate_script 'jQuery.active == 0'
end
end

如果您想检查某个元素是否在页面上但不可见,那么 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)

这是另一种对我非常有效的方法:

find(:css, "#some_element").should be_visible

特别是对于更复杂的发现,如

find(:css, "#comment_stream_list li[data-id='#{@id3}']").should_not be_visible

断言某个元素已被隐藏。

使用:

 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();

我正在测试发送通知和显示 通知状态消息给使用黄瓜(< em > 黄瓜-轨道宝石内置 支持水豚

我试图测试具有 id: 通知 _ 状态的元素是否可见 关于我的步骤定义中的成功应对。为此,我尝试了以下陈述:

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)

以上两种方法对我都不管用,我的步骤都失败了 最后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 文档中找到了可见方法(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 的可见? 方法的结果 并使用 link < a href = “ https://stackoverflow./questions/5153550/capybara-asser- properties-of-an-element”> capybara 断言元素的属性中建议的解决方案

我想到了以下几点:

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

这里的其他答案是“等待”元素的最佳方式。然而,我发现这不工作的网站,我的工作。基本上,需要单击的元素在完全加载后面的函数之前是可见的。这是在几分之一秒,但我发现我的测试运行得如此之快,有时它点击按钮,什么也没有发生。我设法通过使用这个临时的布尔表达式来解决这个问题:

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方法应该首先尝试,但如果它只是不工作,尝试这一点

可见的含义并不明显

失败可能来自于对什么被认为是可见的或不可见的误解,因为它不是显而易见的,不是驱动程序可移植的,而且文档不足。一些测试:

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选项控制。

参考

完全可运行测试 在我的 GitHub 上

现在已经接受的答案有点过时了,因为“ should”的语法已经过时了。如今,你最好做一些类似于 expect(page).not_to have_css('#blah', visible: :hidden)的事情