2012-01-10 32 views
70

加载页面后,我有运行并隐藏和显示基于xhr返回的数据的各种项目的代码。如何使一些JS运行后水豚检查能见度?

我的集成测试看起来是这样的:

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

当我手动去的网页在本次测试中运行的背景下,#blah是可见如我所料。我怀疑Capybara正在查看页面的初始状态(在这种情况下是不可见的),评估DOM的状态并在JS运行之前未通过测试。

是的,我设置了包含描述块:)

任何想法,将不胜感激在:js => true!我希望我不必在这里有意拖延,这会让人感觉不舒服,会让事情放缓。

+1

行的东西是什么驱动程序是什么?一旦XHR完成,预期的HTML是什么? – 2014-10-15 09:08:45

回答

115

我认为这里的find声明是隐含的等待声明,因此Capybara会等待,直到元素在页面上,但不会等待它变为可见。

在这里,你会想水豚,以等待出现明显的元素,它应该通过指定visible选项可以实现:

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

我还没有尝试过,但ignore_hidden_elements配置选项可能是如果您希望find始终等待可见元素,则此处也很有用。

+5

如果有人最初错过了@凯文的笔记(像我一样),你必须在包含的块上有'js:true'才能工作。 – 2014-05-01 15:34:19

+2

这太棒了。它帮助我:'expect(page).to have_selector('#flash-message',visible:false,text:“已成功登录”) - 感谢发布此答案 – 2015-06-04 16:35:28

+0

可见选项对于我在测试jQuery向下滑动元素的可见性时。我必须使用expect(find('#blah')。visible?)。to be_falsey。 – trueinViso 2016-01-27 18:15:23

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 
+5

这个解决方案不是未来兼容的,因为'wait_until' [从Capybara 2中移除](http://www.elabs.se/blog/53-why-wait_until-was-removed-from -capybara)。 – parhamr 2013-09-18 19:58:41

+1

使用'超时。超时“ – 2015-01-16 16:23:09

+0

更好地使用Selenium :: WebDriver :: Wait' – Nakilon 2016-07-07 12:18:36

17

如果你想查询某个元素在页面上,但不可见, 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) 
+1

由于ajax – 2013-02-13 21:56:48

+0

@ Marc-AndréLafortune,您不能使用'should_not'来测试使用水豚的ajax Capybara.javascript_driver 。 – Zubin 2013-02-14 22:36:37

+1

with javascript_drive,'have_css'会在放弃之前等待整个超时时间,因为它期望找到该元素。例如。你必须使用'should have_no_content'而不是'should_not have_content'。 – 2013-02-15 06:16:54

34

这是另一种方式来做到这一点,对我的工作完全正常:

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

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

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

它会断言一个元素已被隐藏。

+1

'不应该be_visible'对我来说不太好,因为Capybara运行'wait_until {base.visible? }元素#可见时?被调用。 – 2012-12-24 09:55:28

+1

@ phng-nguyn,#wait_until已从近期版本的水豚中删除。 – solidcell 2013-02-20 18:07:52

+3

这实际上是一个比“page.should have_selector ...”更好的变体,因为如果失败的文本,它会说该元素实际上是不可见的,而提到的变体只是唤起“没有匹配”错误,这有点令人沮丧。 – installero 2013-03-13 13:13:09

9

使用:

Ruby:  ruby 1.9.3dev (2011-09-23 revision 33323) [i686-linux] 
Rails: 3.2.9 
Capybara: 2.0.3 

我有一个Rails应用程序,其中有点击它应提交AJAX POST请求,并返回一个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(); 

我是在试探我发送通知并显示 的场景向使用黄瓜的用户发送通知状态消息(黄瓜栏,内置 水豚支持

我试图测试有ID的元素:在我一步definition.For这个成功的响应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) 

无论上述工作对我和我的失败步上面所列的.out 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,它显示了如何以原始方式检查元素的属性。

此外,我发现在水豚文件中可见?方法(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') 
1

在这里其他的答案是最好的方式以“等待”元素。不过,我发现这对我正在工作的网站无效。基本上,需要点击的元素在完成加载后的函数之前是可见的。这是在几分之一秒内,但我发现我的测试运行得很快,偶尔点击按钮,什么也没有发生。我设法做这个化妆班布尔表达式来解决它:

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方法应该是第一次尝试,但如果它只是不会工作试试这个

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> 

唯一机架测试认为,作为看不见的是直列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 

鬼驱人也有类似的行为,但它可以处理内部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 

硒的行为完全不同:如果认为一个空元素不可见和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选项控制。

Reference

完全可运行测试on my GitHub

+1

很好的答案 - 感谢您付出的努力。使用多个驱动程序测试套件中元素的可见性并非易事。 – 2015-03-09 15:02:29

+1

“它曾经是假的(看到可见和不可见的元素),目前是真实的,并且由Capybara.ignore_hidden_​​elements选项控制。” 查看此博客文章的更多信息: http://www.elabs.se/blog/60-introducing-capybara-2-1 – rizidoro 2015-04-09 17:22:27

2

现在接受的答案有点过时,因为'should'是不赞成的语法。这些日子,你会更好地沿着expect(page).not_to have_css('#blah', visible: :hidden)