web-dev-qa-db-fra.com

Nightwatchjs: comment vérifier si l'élément existe sans créer d'erreur / échec / exception

Dans la page que je teste, deux boutons peuvent s'afficher: BASIC ou ADVANCED.

Je veux pouvoir dire si le bouton AVANCÉ s'affiche - et si oui, cliquez dessus.

Si le bouton BASIC s'affiche, je ne veux rien faire et continuer mon test.

Toutes les options de Nightwatchjs que j'ai expérimentées génèrent un message d'échec. Par exemple, si je "waitforpresent" ou "waitforvisible" et que le bouton n'est pas là, cela génère une erreur/échec. Je veux juste savoir quel bouton est présent pour pouvoir prendre une décision dans mon code.

Voici ce que j'ai essayé:

try { 
    browser.isVisible('#advanced-search', function(result) {console.log(result.state); }) 
} catch (myError) 
{ 
    console.log(myError); 
}

Pensées?

19
Aaron Kuehn

Vous pouvez y parvenir en utilisant "élément" du protocole Selenium et une fonction de rappel pour vérifier l'état du résultat afin de déterminer si l'élément a été trouvé. Par exemple:

browser.element('css selector', '#advanced-search', function(result){
    if(result.status != -1){
        //Element exists, do something
    } else{
        //Element does not exist, do something else
    }
});
15
EricM

Vous semblez être sur la bonne voie avec isVisible. Depuis la veille nocturne documentation , nous voyons que dans le rappel, vous pouvez vérifier le result.value propriété pour voir si l'élément était visible ou non, c'est-à-dire:

browser.isVisible('#advanced-search', results => {
  if (results.value) { /* is visible */ }
  else { /* is not visible */ }
});

Alternativement, vous pouvez utiliser l'approche suggérée par Saifur. Appelez l'API de Selenium .elements, puis vérifiez la longueur du tableau de résultats:

browser.elements('css selector', '#advanced-search', results => {
  if (results.value.length > 0) { /* element exists */ }
  else { /* element does not exist */ }
});

En fait, cela pourrait être enveloppé dans une commande personnalisée :

// isPresent.js
module.exports.command = function (selector, callback) {
  return this.elements('css selector', selector, results => {
    if (results.status !== 0) { // some error occurred, handle accordingly
    }

    callback(results.value.length > 0);
  });
};

alors en code normal, vous pouvez l'appeler comme ceci:

browser.isPresent('#advanced-search', advancedSearchPresent => {
  // make decisions here
}

Si vous allez effectuer des appels API supplémentaires dans le rappel, il peut être judicieux de tout envelopper dans un .perform appel:

browser.perform((_, done) => {
  browser.isPresent('#advanced-search', advancedSearchPresent => {

    // ...do more stuff...

    done();
  });
});

Quant à savoir pourquoi le .perform est nécessaire, this pourrait être utile.

5
dwoodwardgb

Mon équipe utilise une seule fonction pour s'authentifier avec quelques formulaires de connexion différents, et nous utilisons une commande personnalisée appelée ifElementExists pour accomplir la logique de branchement afin de comprendre sur quel formulaire nous nous trouvons. Nous l'utilisons également sur quelques autres pages qui n'ont pas de meilleure méthode pour déterminer l'état actuel.

import { CustomCommandShorthand } from './customCommands';
import { isFunction } from 'lodash';

exports.command = function ifElementExists(this: CustomCommandShorthand, selector: string, ifTrue: Function, ifFalse?: Function) {
    this.perform(() => {
        if (!isFunction(ifTrue)) {
            throw new Error(`The second argument must be callable. You passed a ${typeof ifTrue} instead of a function.`);
        }

        this.element('css selector', selector, function ifElementExistsCallback({ status }) {
            if (status !== -1) {
                return ifTrue();
            }

            if (isFunction(ifFalse)) {
                ifFalse();
            }
        });
    })
}
1
SgtPooki

La syntaxe pourrait être peu large. Pas très familier avec NightWatchJS. Cependant, le concept reste le même.

//I would not wait for a element that should not exist
//rather I would find the list of the element and see if the count is greater than 0
//and if so, we know the element exists
browser.findElements(webdriver.By.css('#advanced-search')).then(function(elements){
    if(elements.length> 0){
        console.log(elements.length);
    }
});

Voir d'autres exemples ici

1
Saifur