web-dev-qa-db-fra.com

Rapporteur: en attente d'un élément présent mais non affiché

J'ai écrit un test pour vérifier si un élément est visible à l'écran, dans mon cas un panneau pliable angular-ui-bootstrap, alias "l'avertissement". Le code fonctionne, mais les tests échouaient ~ 75% du temps.

Il y a une animation d'effondrement sur l'affichage de l '"avertissement", et je ne peux pas fermer l'animation pour les tests, car c'est une animation jquery. L'avertissement est toujours "présent" dans le DOM, juste effondré lorsqu'il n'y a aucune raison de l'afficher.

Au début, j'ai testé avec ce code, ce qui est assez simple:

expect(element('.warning').isDisplayed()).toEqual(true);

Le problème est survenu lorsque j'ai eu besoin de tester que l'élément est pas affiché, par exemple : une fois l'avertissement affiché, une action entraîne son effondrement.

Ce test:

expect(element('.warning').isDisplayed()).toEqual(false);

ne passera que si l'animation a commencé. Il échouera lorsque la condition est vérifiée alors que l'élément est toujours affiché.

J'ai trouvé deux solutions.

Le plus simple en utilisant une ptor.driver.sleep(2000). Est ralentit mes tests et n'est pas acceptable.

Le dur, moche, mais ça me donne de bons résultats:

exports.isWarningDisplayed = function (expectedVisibility) {
  return ptor.driver.wait(function () {
     if (expectedVisibility) {
       return element(by.css('.warning')).isDisplayed().then(function(visibility) {
         return visibility === expectedVisibility;
       });
      } else {
        return element.all(by.css('.warning .collapse.in')).then(function(items) {
          return items.length === 0;
       });
      }
    }, 2000).then(function() {
      return element.all(by.css('.warning .collapse.in'));
    }).then(function (items) {
      return items.length > 0;
    });
};

Mon problème est qu'il se sent terriblement mal. Avez-vous trouvé une meilleure façon de gérer cette situation? Mon attente serait d'avoir quelque chose comme:

expect(element('.warning').not.isDisplayed()).toEqual(true);

... mais il n'y a pas de .not dans le rapporteur ou webDriver AFAIK.

14
Julien Bérubé

J'ai eu un problème similaire - vouloir tester quand un élément n'est plus désactivé. J'ai eu du mal à essayer de contourner les choses sans le test .not, puis j'ai réalisé que je pouvais simplement déplacer le test `` non '' dans le sélecteur css:

// we're looking for when the element doesn't have a .disabled class
var availableElement = by.css('.some-class:not(.disabled)');
browser.wait(function() {
  return ptor.isElementPresent(availableElement);
}, 30000);

expect(ptor.isElementPresent(availableElement)).toBeTruthy();

Je ne sais pas si cela aide mais j'ai eu un moment de clarté alors j'ai pensé partager.

18
mattgi

En utilisant l'élémentexplorer ( https://github.com/angular/protractor/blob/master/docs/debugging.md ) J'ai regardé l'objet rapporteur et trouvé une réponse qui fonctionne merveilleusement pour moi:

var el = element(by.id('visibleElementId'));
browser.driver.wait(protractor.until.elementIsNotVisible(el));
8
Al Joslin
expect(ptor.isElementPresent(by.css('.warning'))).toBe(false);

C'est une autre façon de vérifier si quelque chose est affiché sur la page ou non

2
Liam's musings

D'après mon expérience, il s'agit d'un problème "triste" courant. Vous savez que votre code est écrit correctement, mais le test a échoué en raison d'attentes. Par exemple, dans Chrome j'obtiens la prochaine erreur dans la console:

<erreur inconnue: l'élément n'est pas cliquable au point (952, 275). >

J'ai donc créé une fonction distincte dans ma classe WebDriver et semble que cela fonctionne:

this.waitElementToBeShown = function (elmLocator) {
        browser.sleep(500);
        browser.wait(function () {
            return (elmLocator).isPresent();
        }, 3000);
        browser.wait(function () {
            return (elmLocator).isDisplayed();
        }, 3000);
    }
0
Alex Svyatenko