web-dev-qa-db-fra.com

Comment sélectionner uniquement les éléments visibles à l'aide de XPath?

J'ai une application GWT pour laquelle j'essaie d'écrire des tests en utilisant Selenium .

J'utilise XPath pour identifier les éléments sur la page des tests. L'utilisation de id ne fonctionnera pas car les valeurs id sont générées automatiquement par GWT et peuvent changer. Les choses ont bien commencé quand j'ai réalisé que je pouvais trouver des boutons par leurs étiquettes comme suit:

//button[.='OK']

Cependant, lorsque j'ai commencé à exécuter plusieurs tests, j'ai commencé à avoir des problèmes. J'ai réalisé que le problème était toutes les différentes "pages" de l'application GWT une fois générées par le Javascript restent dans le HTML dans des éléments cachés <div>. Cela signifiait que mes tests Selenium cliquaient parfois sur des boutons cachés au lieu du bouton visible dans la vue actuelle.

En examinant le HTML avec Firebug , il semble que GWT masque les éléments <div> En ajoutant display: none À leur attribut style. Cela signifie que je peux trouver tous les boutons OK masqués comme suit:

//div[contains(@style,'display: none')]//button[.='OK']

Cela trouvera tous les boutons OK cachés, c'est-à-dire les boutons qui ont un ancêtre <div> Qui est caché en ayant display: none Dans le style.

Ma question est: comment utiliser XPath pour trouver uniquement les boutons OK visibles? Comment trouver les boutons qui n'ont aucun élément ancêtre <div> Avec display: none Dans le style?

45
Dave Webb

Cela devrait fonctionner:

.//button[.='OK' and not(ancestor::div[contains(@style,'display:none')])
and not(ancestor::div[contains(@style,'display: none')])]

MODIFIER:

L'expression plus simple et plus efficace ci-dessous:

//div[not(contains(@style,'display:none'))]//button[.='OK']

ne fonctionne pas correctement car chaque bouton a au moins une div visible dans ses ancêtres.

55
Julian Aubourg

Selenium 2 Webdriver nous donne l'option de la méthode isDisplayed () qui traite ce problème. Beau travail des contributeurs de Selenium.

12
Hari Reddy

//div[(contains(@style,'display: block'))]//button[@id='buttonid']

Cela a fonctionné pour moi. Comme 'display: none' représentant des blocs cachés, 'display: block' représente le bloc actuellement affiché et nous pouvons spécifier les balises internes à identifier comme ci-dessus

0
Vinitha V