Sélectionnez l'élément parent de l'élément connu dans Selenium

116

J'ai un certain élément que je peux sélectionner avec Selenium 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 mort pour un clic. Comment naviguer vers le haut avec XPath ?

fl
la source

Réponses:

169

Il y a quelques options ici. L'exemple de code est en Java, mais un portage vers d'autres langues doit être simple.

JavaScript:

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("./.."));

Obtention du pilote du WebElement

Remarque: comme vous pouvez le voir, pour la version JavaScript, vous aurez besoin du driver. Si vous n'y avez pas d'accès direct, vous pouvez le récupérer à l' WebElementaide de:

WebDriver driver = ((WrapsDriver) myElement).getWrappedDriver();
acdcjunior
la source
41
Et si vous souhaitez accéder au grand-parent, utilisez By.Xpath ("../ ..").
Monsignor
@Monsignor Fonctionne comme les chemins de fichiers ... ou les chemins d'URL: stackoverflow.com/questions/8577636
/../../questions
Aucun de ces XPath n'est correct pour une utilisation avec Selenium. Il faut l'utiliser By.xpath(“./..”)pour remonter correctement l'arborescence DOM lors de l'utilisation element.findElement. Le premier «./» est requis pour définir le nœud de contexte.
JimEvans
35

Un peu plus sur XPath axes

Disons que nous avons la HTMLstructure ci-dessous :

<div class="third_level_ancestor">
    <nav class="second_level_ancestor">
        <div class="parent">
            <span>Child</span>
        </div>
    </nav>
</div>
  1. //span/parent::*- renvoie tout élément qui est un parent direct.

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

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

Production: <div class="parent">

  1. //span/ancestor::*- renvoie tous les ancêtres (y compris le parent).

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

  1. //span/ancestor-or-self::*- renvoie tous les ancêtres et l'élément courant 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) de type div.

Production: <div class="third_level_ancestor">

Andersson
la source
Bonjour @Anderson J'ai besoin d'aide pour ma question Avez-vous le temps de jeter un coup d'œil? Merci d'avance. stackoverflow.com/questions/54647055/…
18

Considérons votre DOM comme

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

Maintenant que vous devez sélectionner la balise parent «a» en fonction du <span>texte, 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

Bhuvanesh Mani
la source
Si nous recherchons divce qui est à nouveau imbriqué avec plusieurs divs, alors au lieu de .//spanin, By.xpath("//div[.//span[text()='Close']]")nous pouvons l'utiliser *//span, il recherchera la plupart des éléments div parent d'un span donné. Maintenant, cela ressemblera à cecidriver.findElement(By.xpath("//div[*//span[text()='Close']]"));
Jai Prak
14

Jetez un œil aux axes XPath possibles que vous recherchez probablement parent. En fonction de la manière dont vous trouvez le premier élément, vous pouvez simplement ajuster le xpath pour cela.

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

pré-manifeste
la source
5

Cela peut être utile pour quelqu'un d'autre: Utilisation de 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, recherchez une étiquette (il pourrait quelque chose comme a, h2) a appelé labelName. Accédez au parent de cette étiquette (c'est-à-dire div class="ParentDiv"). Recherchez dans les descendants de ce parent pour trouver tout élément enfant avec la valeurelementToSelect . Avec cela, il ne sélectionnera pas le second elementToSelectavec DontSelectdiv comme parent.

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

papigee
la source
0

Vous pouvez le faire en utilisant / parent :: node () dans xpath. Ajoutez simplement / parent :: node () aux éléments enfants xpath.

Par exemple: Soit xpath de l'élément enfant soit childElementXpath .

Alors xpath de son ancêtre immédiat serait childElementXpath / parent :: node () .

Xpath de son prochain ancêtre serait childElementXpath / parent :: node () / parent :: node ()

etc..

Vous pouvez également accéder à un ancêtre d'un élément à l'aide de 'childElementXpath/ancestor::*[@attr="attr_value"]'. Cela serait utile lorsque vous avez un élément enfant connu qui est unique mais qui a un élément parent qui ne peut pas être identifié de manière unique.

Johnes Jose
la source
0

Nous pouvons sélectionner la balise parent à l'aide de Selenium comme suit:

driver.findElement(By.xpath("//table[@id='abc']//div/nobr[.='abc']/../.."));

cela vous aidera à trouver le grand-parent de l'élément connu. Retirez simplement un (/ ..) pour trouver l'élément parent immédiat.

Comme:

driver.findElement(By.xpath("//table[@id='abc']//div/nobr[.='abc']/..));

Il existe d'autres moyens de l'implémenter, mais cela a bien fonctionné pour moi.

Utsav Jain
la source