web-dev-qa-db-fra.com

Comment créer une condition dans le rapporteur pour quand un élément existe ou non

J'utilise Protractor JS. Et le site est écrit en Angular JS.

J'ai donc un interrupteur à bascule. Et j'ai remarqué que la valeur de l'interrupteur à bascule passe de vrai à faux et faux à vrai lorsque vous l'éteignez ou l'allumez.

J'essaie de créer une condition lorsque Protractor visite ma page quand il voit l'interrupteur à bascule "désactivé", il l'activera. Si l'interrupteur à bascule est déjà "activé", il le désactivera d'abord, puis le réactivera.

J'ai trouvé ce code, mais pour une raison quelconque, il ne fonctionne pas:

 if( expect(element(By.id('toggle-switch')).element(By.css('[value="false"]')).isDisplayed()) ) {
            element(By.id('toggle-switch')).click();
            console.log('in the if')
       }

       else{
           element(By.id('toggle-switch')).click();
           browser.sleep(3000);
           element(By.id('toggle-switch')).click();
           console.log('in the else')
       }

Ce code semble fonctionner uniquement pour l'instruction if. Pour une raison quelconque, il n'ira jamais à l'autre. Voici l'erreur que je reçois:

NoSuchElementError: Aucun élément trouvé à l'aide du localisateur: By.cssSelector ("[value = \" false\"]")

Alors j'ai essayé

.isPresent() au lieu de .isDisplayed() Je ne reçois plus l'erreur ci-dessus, mais pour une raison quelconque lorsque j'utilise .isPresent (), il va toujours à l'instruction if et ne l'exécute que, et jamais l'instruction else. Aucune erreur affichée.

S'il y a une meilleure façon, faites-le moi savoir. Cela semble très limitatif de ne pas pouvoir créer des conditions adéquates dans ce cadre.

24
adbarads

N'oubliez pas que isDisplayed() renvoie une promesse, vous pouvez essayer avec:

element(anyFinder).isDisplayed().then(function(result) {
    if ( result ) {
        //Whatever if it is true (displayed)
    } else {
        //Whatever if it is false (not displayed)
    }
});
33
Lautaro Cozzani

isDisplayed() ne fonctionnait pas pour moi. L'API a peut-être été modifiée. isPresent() est ma solution:

    var logoutButton =  element(by.css('[ng-click="log_out()"]'));
    logoutButton.isPresent().then(function(result) {
    if ( result ) {
        logoutButton.click();
    } else {
        //do nothing
    }
    });
20
Ebru Yener

Le problème est que isDisplayed() , comme beaucoup de méthodes dans WebDriverJS/Protractor, renvoie un promesse qui par définition est "véridique" ce qui rend difficile le débogage de problèmes comme celui-ci.

Travaillons à travers un exemple pour mieux comprendre.

Imaginez, vous avez le code suivant, qui peut sembler correct au premier coup d'œil:

var Elm = $("#myid");
if (Elm.isDisplayed()) {
    // do smth
} else {
    // do smth else
}

Maintenant, il a un grave problème. do smth else Partie ne sera jamais atteinte, puisque Elm.isDisplayed() n'est pas une valeur booléenne - c'est une promesse. Même si l'élément n'est pas affiché, la partie // do smth Sera toujours exécutée.

Au lieu de cela, si vous devez vérifier la valeur de isDisplayed() à utiliser dans une expression conditionnelle, vous devez résoudre la promesse avec then() explicitement:

var Elm = $("#myid");
Elm.isDisplayed().then(function (isDisplayed) {
  if (isDisplayed) {
      // do smth
  } else {
      // do smth else
  }
});

Il existe également un moyen d'attraper ce type d'erreurs sans même exécuter le code - statiquement avec ESLint et plugin eslint-plugin-protractor . Il y a un règle pertinente qui surveille si certaines méthodes Protractor sont utilisées directement dans les conditions if.

Voici ce qu'il produirait pour le code ci-dessus:

$ eslint test.js
test.js
  2:1  warning  Unexpected "isDisplayed()" inside if condition  protractor/no-promise-in-if
6
alecxe

Ou essayez cette solution implémentée du haut de ma tête, Planifie une commande pour tester si un élément est présent sur la page. Si des erreurs se produisent lors de l'évaluation de l'attente, elles seront autorisées à se propager.

function alwaysSwitchOn(element) {
   browser.driver.isElementPresent(element).then(function(isPresent) {
      if (isPresent) {
        isPresent = true;
      } 
      else {
        browser.driver.wait(function () {
          return browser.driver.isElementPresent(element);
        }, 5000);
      }
      // to fail the test, then uncomment this line
      //expect(isPresent).toBeTruthy();
   }).then(function () {
      if (element.getAttribute('value') === 'OFF') {
         element.click();
      }
      else {
         // turn it OFF
         element.click();
         // turn it back ON
         element.click();
      }
   });
}

fn utilise pour continuer à essayer encore et encore pendant 5 secondes jusqu'à ce que ce soit true. si l'élément est introuvable dans 5 sec, il en résultera un code d'erreur; Aucun élément de ce type n'est trouvé. Remarque: si la condition est remplie avant l'attente (5s), Elle se déplacera rapidement vers then(...).

1
Simple-Solution