Comment utiliser protractor pour vérifier si un élément est visible?
J'essaie de tester si un élément est visible à l'aide de protractor. Voici à quoi ressemble l'élément:
<i class="icon-spinner icon-spin ng-hide" ng-show="saving"></i>
Dans la console chrome, je peux utiliser ce sélecteur jQuery pour tester si l'élément est visible:
$('[ng-show=saving].icon-spin')
[
<i class="icon-spinner icon-spin ng-hide" ng-show="saving"></i>
]
> $('[ng-show=saving].icon-spin:visible')
[]
Cependant, quand j'essaie de faire la même chose dans protractor, j'obtiens cette erreur à l'exécution:
InvalidElementStateError:
invalid element state: Failed to execute 'querySelectorAll' on 'Document':
'[ng-show=saving].icon-spin:visible' is not a valid selector.
Pourquoi cela n'est-il pas valide? Comment puis-je vérifier la visibilité à l'aide de protractor?
6 réponses
, Cela devrait le faire:
expect($('[ng-show=saving].icon-spin').isDisplayed()).toBeTruthy();
Rappelez-vous que le Rapporteur $
n'est pas jQuery et que :visible
n'est pas encore une partie de sélecteurs CSS disponibles + pseudo-sélecteurs
Plus d'infos sur https://stackoverflow.com/a/13388700/511069
Le bon moyen de contrôler la visibilité d'un élément avec le Rapporteur est d'appeler le isDisplayed
la méthode. Vous devriez faire attention cependant puisque isDisplayed
ne renvoie pas un booléen, mais plutôt un promise
fournir la visibilité évaluée. J'ai vu beaucoup d'exemples de code qui utilisent cette méthode à tort et n'évaluent donc pas sa visibilité réelle.
Exemple pour obtenir la visibilité d'un élément:
element(by.className('your-class-name')).isDisplayed().then(function (isVisible) {
if (isVisible) {
// element is visible
} else {
// element is not visible
}
});
Cependant, vous n'avez pas besoin de cela si vous vérifient simplement la visibilité de l'élément (par opposition à l'obtenir) parce que protractor patches Jasmine expect() donc il attend toujours que les promesses soient résolues. Voir github.com/angular/jasminewd
Donc vous pouvez simplement faire:
expect(element(by.className('your-class-name')).isDisplayed()).toBeTruthy();
Puisque vous utilisez AngularJS
pour contrôler la visibilité de cet élément, vous pouvez également vérifier son attribut de classe pour ng-hide
comme ceci:
var spinner = element.by.css('i.icon-spin');
expect(spinner.getAttribute('class')).not.toMatch('ng-hide'); // expect element to be visible
J'ai eu un problème similaire, en ce sens que je ne voulais que renvoyer des éléments visibles dans un objet page. J'ai trouvé que je suis capable d'utiliser le css :not
. Dans le cas de ce problème, cela devrait vous faire...
expect($('i.icon-spinner:not(.ng-hide)').isDisplayed()).toBeTruthy();
Dans le contexte d'un objet page, vous ne pouvez obtenir que les éléments qui sont visibles de cette manière. Par exemple. étant donné une page avec plusieurs éléments, où seuls certains sont visibles, vous pouvez utiliser:
this.visibileIcons = $$('i.icon:not(.ng-hide)');
Cela vous renvoie tous visibles i.icon
s
S'il y a plusieurs éléments dans DOM avec le même nom de classe. Mais un seul élément est visible.
element.all(by.css('.text-input-input')).filter(function(ele){
return ele.isDisplayed();
}).then(function(filteredElement){
filteredElement[0].click();
});
Dans cet exemple, le filtre prend une collection d'éléments et renvoie un seul élément visible en utilisant isDisplayed () .
Cette réponse sera suffisamment robuste pour fonctionner pour les éléments qui ne sont pas sur la page, donc échouant gracieusement (ne pas lancer d'exception) si le sélecteur n'a pas réussi à trouver l'élément.
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()
})
})
Pour attendre la visibilité
const EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(element(by.css('.icon-spinner icon-spin ng-hide')))).then(function() {
//do stuff
})
Astuce Xpath pour ne trouver que des éléments visibles
element(by.xpath('//i[not(contains(@style,"display:none")) and @class="icon-spinner icon-spin ng-hide"]))