138 votes

Sélectionner l'élément parent d'un élément connu dans Selenium

J'ai un certain élément que je peux sélectionner avec Sélénium 1.

Malheureusement, je dois cliquer sur l'élément parent pour obtenir le comportement souhaité. L'élément que je peux facilement localiser a un attribut non sélectionnable, ce qui le rend impossible à cliquer. Comment puis-je naviguer vers le haut avec XPath ?

214voto

acdcjunior Points 19898

Il y a plusieurs possibilités. L'exemple de code est en Java, mais un portage vers d'autres langages devrait être simple.

Java :

WebElement myElement = driver.findElement(By.id("myDiv"));
WebElement parent = (WebElement) ((JavascriptExecutor) driver).executeScript(
                                   "return arguments[0].parentNode;", myElement);

XPath :

WebElement myElement = driver.findElement(By.id("myDiv"));
WebElement parent = myElement.findElement(By.xpath("./.."));

L'obtention du pilote à partir du WebElement

Note : Comme vous pouvez le voir, pour la version JavaScript, vous aurez besoin de l'option driver . Si vous n'y avez pas accès directement, vous pouvez le récupérer à partir du site Web de la Commission européenne. WebElement en utilisant :

WebDriver driver = ((WrapsDriver) myElement).getWrappedDriver();

48 votes

Et si vous voulez naviguer vers le grand-parent, utilisez By.Xpath("../..").

0 votes

@Monsignor Fonctionne comme les chemins de fichiers... ou les chemins URL : stackoverflow.com/questions/8577636/../../questions/8577636/

2 votes

Aucun de ces XPaths n'est correct pour une utilisation avec Selenium. Il faut utiliser By.xpath(“./..”) pour remonter correctement l'arbre DOM lors de l'utilisation de element.findElement . Le premier "./" est nécessaire pour définir le nœud de contexte.

47voto

Andersson Points 31774

Un peu plus sur XPath axes

Disons que nous avons les éléments suivants HTML structure :

<div class="third_level_ancestor">
    <nav class="second_level_ancestor">
        <div class="parent">
            <span>Child</span>
        </div>
    </nav>
</div>
  1. //span/parent::* - retours tout qui est le parent direct.

Dans ce cas, la sortie est <div class="parent">

  1. //span/parent::div[@class="parent"] - renvoie l'élément parent seulement du type de nœud exact et seulement si le prédicat spécifié est Vrai.

Sortie : <div class="parent">

  1. //span/ancestor::* - retours todo ancêtres (y compris les parents).

Sortie : <div class="parent"> , <nav class="second_level_ancestor"> , <div class="third_level_ancestor"> ...

  1. //span/ancestor-or-self::* - retours todo ancêtres y l'élément actuel lui-même.

Sortie : <span>Child</span> , <div class="parent"> , <nav class="second_level_ancestor"> , <div class="third_level_ancestor"> ...

  1. //span/ancestor::div[2] - renvoie le deuxième ancêtre (à partir du parent) du type div .

Sortie : <div class="third_level_ancestor">

0 votes

Bonjour @Anderson J'ai besoin d'aide pour ma question. Avez-vous le temps de jeter un coup d'oeil ? Merci d'avance. stackoverflow.com/questions/54647055/

22voto

Bhuvanesh Mani Points 449

Considérons que votre DOM est

<a>
    <!-- some other icons and texts -->
    <span>Close</span>
</a>

Maintenant que vous avez besoin de sélectionner la balise parent 'a' sur la base de <span> le texte, puis utilisez

driver.findElement(By.xpath("//a[.//span[text()='Close']]"));

Explication : Sélectionnez le nœud en fonction de la valeur de son nœud enfant.

1 votes

Si nous recherchons div qui est à nouveau imbriqué avec plusieurs divs, alors au lieu de .//span sur By.xpath("//div[.//span[text()='Close']]") nous pouvons utiliser *//span il cherchera l'élément div le plus parent du span donné. Maintenant, cela ressemblera à ceci driver.findElement(By.xpath("//div[*//span[text()='Close']]"‌​));

14voto

prestomanifesto Points 4135

Jetez un coup d'œil aux possibilités Axes XPath vous êtes probablement à la recherche de parent . En fonction de la façon dont vous trouvez le premier élément, vous pourriez simplement ajuster le xpath pour cela.

Vous pouvez également essayer le syntaxe à double point , .. qui sélectionne le parent du nœud actuel.

5voto

papigee Points 824

Cela pourrait être utile à quelqu'un d'autre : En utilisant cet exemple de code html

<div class="ParentDiv">
    <label for="label">labelName</label>
    <input type="button" value="elementToSelect">
</div>
<div class="DontSelect">
    <label for="animal">pig</label>
    <input type="button" value="elementToSelect">
</div>

Si, par exemple, je veux sélectionner un élément dans la même section (par exemple div) comme étiquette, vous pouvez utiliser ceci

//label[contains(., 'labelName')]/parent::*//input[@value='elementToSelect'] 

Cela signifie simplement qu'il faut chercher une étiquette (qui peut être n'importe quoi comme a , h2 ) appelé labelName . Naviguez jusqu'au parent de cette étiquette (c'est à dire div class="ParentDiv" ). Cherchez dans les descendants de ce parent pour trouver tout élément enfant ayant la valeur de elementToSelect . Ainsi, il ne sélectionnera pas le deuxième elementToSelect con DontSelect div comme parent.

L'astuce est que vous pouvez réduire les zones de recherche d'un élément en naviguant d'abord vers le parent, puis en recherchant dans les descendants de ce parent l'élément dont vous avez besoin. Autres syntaxes comme following-sibling::h2 peut également être utilisé dans certains cas. Cela signifie que l'élément frère suivant h2 . Cela fonctionnera pour les éléments de même niveau, ayant le même parent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X