2014-04-03 73 views
93

我想測試一個元素是否可見使用量角器。這裏的元素是什麼樣子:如何使用量角器檢查元素是否可見?

<i class="icon-spinner icon-spin ng-hide" ng-show="saving"></i> 

當鉻控制檯,我可以用這個jQuery選擇以測試是否元素可見:

$('[ng-show=saving].icon-spin') 
[ 
<i class=​"icon-spinner icon-spin ng-hide" ng-show=​"saving">​</i>​ 
] 
> $('[ng-show=saving].icon-spin:visible') 
[] 

然而,當我試圖做同樣的在量角器中,我在運行時出現此錯誤:

InvalidElementStateError: 
invalid element state: Failed to execute 'querySelectorAll' on 'Document': 
'[ng-show=saving].icon-spin:visible' is not a valid selector. 

爲什麼這是無效的?如何使用量角器檢查可視性?

+0

嘿@limp_chimp做了我下面的回答幫助你的? –

+0

@limp_chimp針對諸如可見性之類的事情,考慮使用AngularJS客戶端DOM單元測試。他們跑得快得多,而且更容易開發。 – Offirmo

回答

124

這應做到:

expect($('[ng-show=saving].icon-spin').isDisplayed()).toBeTruthy(); 

記住量角器的$不是jQuery和:visible尚未https://stackoverflow.com/a/13388700/511069

+1

胡人。非常酷。這正是我需要能夠確定的。非常感謝你。 – racl101

+1

這顯然是錯誤的。看看下面的答案! – asenovm

+2

下面的答案也使用'isDisplayed()',但只是擴展來解決完整性的承諾,儘管這一步是可選的,只是意味着在測試中包含條件,這是一個不好的做法。 @asenovm能否進一步闡述你的「這是明顯錯誤的」評論? –

68

正確的方式available CSS selectors + pseudo-selectors

更多信息的一部分使用量角器檢查元素的可見性是調用isDisplayed方法。您應該小心,因爲isDisplayed不返回布爾值,而是提供評估的可見性,而不是promise。我見過很多錯誤地使用這種方法的代碼示例,因此不會評估其實際可見性。

示例獲得一個元素的可見性:

element(by.className('your-class-name')).isDisplayed().then(function (isVisible) { 
    if (isVisible) { 
     // element is visible 
    } else { 
     // element is not visible 
    } 
}); 

不過,你不需要這個,如果你只是檢查元素的可見性(而不是得到它),因爲量角器補丁茉莉花期待(),所以它總是等待承諾解決。見github.com/angular/jasminewd

所以,你可以這樣做:

expect(element(by.className('your-class-name')).isDisplayed()).toBeTruthy(); 

由於您使用AngularJS來控制元素的可見性,你也可以檢查它的類屬性的ng-hide這樣的:

var spinner = element.by.css('i.icon-spin'); 
expect(spinner.getAttribute('class')).not.toMatch('ng-hide'); // expect element to be visible 
5

我有一個類似的問題,因爲我只想要在頁面對象中可見的返回元素。我發現我可以使用css :not。在這個問題上的情況下,這應該做你...

expect($('i.icon-spinner:not(.ng-hide)')).isDisplayed().toBeTruthy(); 

在頁面對象的情況下,你可以得到只有那些以這種方式是可見的,以及元素。例如。給出多個項目,其中只有一些是可見的一個頁面,你可以使用:

this.visibileIcons = $$('i.icon:not(.ng-hide)'); 

這將返回所有可見i.icon小號

+1

isDisplayed()應該在@leoGallucci解釋它的期望範圍內。 – Striped

3

如果在DOM多個元素具有相同的類名。但只有一個元素是可見的。

element.all(by.css('.text-input-input')).filter(function(ele){ 
     return ele.isDisplayed(); 
    }).then(function(filteredElement){ 
     filteredElement[0].click(); 
    }); 

在本例中過濾器可以接受元素的集合並返回使用isDisplayed()單個可見元素。

+0

這是一個很好的答案;考慮沒有這種元素的情況! $('。text-input-input')會優雅地提醒用戶;這可能會失敗,因爲'filteredElement.length === 0'? –

1

此答案足夠健壯,可以用於不在頁面上的元素,因此,如果選擇器未能找到元素,將會優雅地失敗(不拋出異常)。

const nameSelector = '[data-automation="name-input"]'; 
const nameInputIsDisplayed =() => { 
    return $$(nameSelector).count() 
     .then(count => count !== 0) 
} 
it('should be displayed',() => { 
    nameInputIsDisplayed().then(isDisplayed => { 
     expect(isDisplayed).toBeTruthy() 
    }) 
}) 
0

要等待的知名度

const EC = protractor.ExpectedConditions; 
browser.wait(EC.visibilityOf(element(by.css('.icon-spinner icon-spin ng-hide')))).then(function() { 
    //do stuff 
}) 

Xpath的把戲,只發現可見的元素

element(by.xpath('//i[not(contains(@style,"display:none")) and @class="icon-spinner icon-spin ng-hide"])) 
相關問題