2012-01-10 82 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)