一些JS运行后如何让Capybara检查可见性?

Kev*_*vis 79 ruby integration-testing rspec capybara

加载页面后,我有运行和隐藏的代码,并根据xhr返回的数据显示各种项目.

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

it "should not show the blah" do
    page.find('#blah').visible?.should be_true
end 
Run Code Online (Sandbox Code Playgroud)

当我在上下文中手动转到该测试运行的页面时,#blah 并不像我预期的那样可见.我怀疑Capybara正在查看页面的初始状态(在这种情况下是不可见的),在JS运行之前评估DOM的状态并且未通过测试.

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

任何想法将不胜感激!我希望我不必在这里故意拖延,感觉不稳定,会减慢速度.

Jon*_*n M 127

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

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

expect(page).to have_selector('#blah', visible: true)
Run Code Online (Sandbox Code Playgroud)

我没有尝试过,但是ignore_hidden_elements如果你想find总是等待可见元素,那么配置选项在这里也很有用.

  • 如果有人最初错过@Kevin的注释(像我一样),你必须在包含块上有`js:true`才能使用. (6认同)
  • 这太棒了.它帮助我:`expect(page).to have_selector('#flash-message',visible:false,text:"签名成功")` - 感谢您发布此答案 (3认同)

Bjö*_*ann 35

这是另一种方法,对我来说非常好用:

find(:css, "#some_element").should be_visible
Run Code Online (Sandbox Code Playgroud)

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

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

这将断言一个元素已被隐藏.

  • 这实际上是一个比"page.should have_selector ..."更好的变体,因为如果一个失败的文本,它会说该元素实际上是显式不可见的,而提到的变体只是唤起'没有匹配'的错误,这有点令人沮丧. (3认同)

Zub*_*bin 20

如果要检查某个元素是否在页面上但是不可见,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)
Run Code Online (Sandbox Code Playgroud)


Jig*_*hel 9

使用:

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

我有一个Rails应用程序,其中有一个链接,点击时应该提交一个AJAX发布请求并返回一个JS响应.

链接代码:

 link_to("Send Notification", notification_path(user_id: user_id), remote: true, method: :post)
Run Code Online (Sandbox Code Playgroud)

JS响应(.js.haml文件)应切换链接所在页面上的以下隐藏div:

 #notification_status(style='display:none')
Run Code Online (Sandbox Code Playgroud)

js.haml文件内容:

:plain
  var notificationStatusContainer = $('#notification_status');
  notificationStatusContainer.val("#{@notification_status_msg}");
  notificationStatusContainer.show();
Run Code Online (Sandbox Code Playgroud)

我正在测试我使用Cucumber发送通知并向用户显示通知状态消息的场景(带有内置Capybara支持的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)
Run Code Online (Sandbox Code Playgroud)

上述任何一项都不适用于我,并且我的步骤失败.在上面列出的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)'
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为以下声明正确传递:

page.has_selector?('#notification_status')
Run Code Online (Sandbox Code Playgroud)

事实上,我使用了检查页面源代码

  print page.html
Run Code Online (Sandbox Code Playgroud)

出现了

<div style='' id='notification_status'></div>
Run Code Online (Sandbox Code Playgroud)

这是预料之中的.

最后我发现这个链接capybara断言元素的属性,它显示了如何以原始方式检查元素的属性.

另外我在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.
Run Code Online (Sandbox Code Playgroud)

因此我得出的结论是,当测试元素的可见性时,不依赖于水豚的可见效果?使用CSS选择器时的方法,并使用链接capybara中建议的解决方案断言元素的属性

我想出了以下内容:

 module CustomMatchers
   def should_be_visible(css_selector)
    find(css_selector)['style'].should_not include('display:none', 'display: none')
   end
 end

 World(CustomMatchers)
Run Code Online (Sandbox Code Playgroud)

用法:

should_be_visible('#notification_status')
Run Code Online (Sandbox Code Playgroud)


Cir*_*四事件 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>
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

另一个常见问题是默认值visible:

  • 它使用的是false(看到两个可见和不可见的元素),
  • 目前是 true
  • Capybara.ignore_hidden_elements选项控制.

参考.

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


sma*_*nse 5

您可能希望查看此帖子,该帖子提供了一个等待所有ajax请求完成的示例方法:

def wait_for_ajax(timeout = Capybara.default_wait_time)
  page.wait_until(timeout) do
    page.evaluate_script 'jQuery.active == 0'
  end
end
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案将来不兼容,因为`wait_until`被[从Capybara 2中删除](http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara). (5认同)