2014-04-03 12 views
93

Ich versuche zu testen, ob ein Element mit Winkelmesser sichtbar ist. Hier ist, was das Element wie folgt aussieht:Wie verwende ich den Winkelmesser, um zu prüfen, ob ein Element sichtbar ist?

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

Wenn in der Chromkonsole, kann ich diesen jQuery-Selektor verwenden, um zu testen, ob das Element sichtbar ist:

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

aber wenn ich versuche, das gleiche zu tun im Winkelmesser bekomme ich diesen Fehler zur Laufzeit:

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

Warum ist das nicht gültig? Wie kann ich mit dem Winkelmesser auf Sichtbarkeit prüfen?

+0

Hey @limp_chimp meine unten Antwort hat Ihnen geholfen? –

+0

@limp_chimp für Dinge wie Sichtbarkeit, denken Sie daran, AngularJS Client-DOM-Unit-Tests zu verwenden. Sie sind viel schneller zu laufen und leichter zu entwickeln. – Offirmo

Antwort

124

Dies sollte es tun:

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

Winkelmesser Erinnern $ nicht jQuery ist und :visible ist nicht noch ein Teil available CSS selectors + pseudo-selectors

Mehr Infos unter https://stackoverflow.com/a/13388700/511069

+1

Aw Mann. So cool. Genau das musste ich feststellen können. Vielen Dank, Alter. – racl101

+1

Das ist einfach falsch. Schau dir die Antwort unten an! – asenovm

+2

Die folgende Antwort verwendet auch 'isDisplayed()', aber expandiert nur, um das Versprechen der Vollständigkeit zu erfüllen, obwohl dieser Schritt optional ist und nur für die Einbeziehung von Bedingungen in Ihre Tests gedacht ist, was eine schlechte Übung ist. @asenovm kannst du deinen "This is plain wrong" Kommentar weiter ausführen? –

68

Der richtige Weg für Wenn Sie die Sichtbarkeit eines Elements mit dem Winkelmesser prüfen, rufen Sie die Methode isDisplayed auf. Sie sollten jedoch vorsichtig sein, da isDisplayed keinen booleschen, sondern einen promise liefert, der die bewertete Sichtbarkeit liefert. Ich habe viele Codebeispiele gesehen, die diese Methode falsch verwenden und daher ihre tatsächliche Sichtbarkeit nicht bewerten.

Beispiel die Sichtbarkeit eines Elements für immer:

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

Allerdings müssen Sie diese nicht benötigen, wenn Sie nur die Sichtbarkeit des Elements überprüft (im Gegensatz zu bekommen es im Gegensatz), weil Winkelmesser Patches Jasmine erwarten() So wartet es immer darauf, dass Versprechen gelöst werden. Siehe github.com/angular/jasminewd

So können Sie einfach tun:

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

Da Sie verwenden AngularJS die Sichtbarkeit dieses Elements zu steuern, können Sie auch seine Klasse überprüfen Sie das Attribut für ng-hide wie folgt aus:

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

Ich hatte ein ähnliches Problem, in dem ich nur Rückgabeelemente wollte, die in einem Seitenobjekt sichtbar waren. Ich habe festgestellt, dass ich die css :not verwenden kann. Im Falle dieser Ausgabe, das sollten Sie tun, ...

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

Im Rahmen einer Seite Objekt können Sie nur diejenigen Elemente erhalten, die auch auf diese Weise sichtbar sind. Z.B. eine Seite mit mehreren Positionen gegeben, wo einige sind nur sichtbar, können Sie verwenden:

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

Dies wird Ihnen alle sichtbar i.icon s zurückkehren mehrere Elemente in DOM mit dem gleichen Klassennamen

+1

isDisplayed() sollte im erwarteten Bereich sein, wie @leoGallucci es erklärte. – Striped

3

Wenn es. Aber nur eines der Elemente ist sichtbar.

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

In diesem Beispiel Filter nimmt eine Sammlung von Elementen, und gibt ein einziges sichtbares Element unter Verwendung wirdangezeigt().

+0

Dies ist eine großartige Antwort; Betrachte den Fall, in dem es kein solches Element gibt! $ ('. text-input-input') würde den Benutzer elegant alarmieren; Dies könnte fehlschlagen, weil 'filteredElement.length === 0'? –

1

Diese Antwort wird robust genug sein, um für Elemente zu arbeiten, die nicht auf der Seite sind und daher fehlerfrei ausfallen (keine Ausnahme auslösen), wenn der Selektor das Element nicht finden konnte.

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

Um die Sichtbarkeit zu warten

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

Xpath Trick, um nur sichtbare Elemente finden

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