Выберите родительский элемент известного элемента в Selenium - PullRequest
88 голосов
/ 20 декабря 2011

У меня есть определенный элемент, который я могу выбрать с помощью Selenium 1.

К сожалению, мне нужно щелкнуть родительский элемент, чтобы получить желаемое поведение.Элемент, который я легко могу найти, имеет атрибут unselectable, что делает его мертвым для щелчка.Как мне перейти вверх с XPath ?

Ответы [ 7 ]

138 голосов
/ 01 августа 2013

Есть несколько вариантов.Пример кода на Java, но порт на другие языки должен быть простым.

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

Получение драйвера изWebElement

Примечание: Как видите, для версии JavaScript вам понадобится driver.Если у вас нет прямого доступа к нему, вы можете получить его из WebElement, используя:

WebDriver driver = ((WrapsDriver) myElement).getWrappedDriver();
25 голосов
/ 19 августа 2017

Немного больше о XPath axes

Допустим, у нас есть структура ниже HTML:

<div class="third_level_ancestor">
    <nav class="second_level_ancestor">
        <div class="parent">
            <span>Child</span>
        </div>
    </nav>
</div>
  1. //span/parent::* - возвращает любой элемент , который является прямым родителем.

В этом случае вывод будет <div class="parent">

  1. //span/parent::div[@class="parent"] - возвращает родительский элемент только точного типа узла и только , если указанный предикат равен True.

Вывод: <div class="parent">

  1. //span/ancestor::* - возвращает всех предков (включая родителя).

Вывод: <div class="parent">, <nav class="second_level_ancestor">, <div class="third_level_ancestor"> ...

  1. //span/ancestor-or-self::* - возвращает всех предков и самого текущего элемента.

Вывод: <span>Child</span>, <div class="parent">, <nav class="second_level_ancestor">, <div class="third_level_ancestor"> ...

  1. //span/ancestor::div[2] - возвращает второго предка (начиная с родителя) типа div.

Вывод: <div class="third_level_ancestor">

14 голосов
/ 20 декабря 2011

Посмотрите на возможные оси XPath , вы, вероятно, ищете parent.В зависимости от того, как вы находите первый элемент, вы можете просто настроить xpath для этого.

В качестве альтернативы вы можете попробовать синтаксис с двумя точками , .., который выбирает родительский элемент длятекущий узел.

13 голосов
/ 23 марта 2017

Давайте рассмотрим ваш DOM как

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

Теперь, когда вам нужно выбрать родительский тег 'a' на основе <span> текста, затем используйте

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

Объяснение: выберите узел на основе значения его дочернего узла

4 голосов
/ 25 января 2017

Это может быть полезно для кого-то еще: Используя этот пример 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>

Если, например, я хочу выбрать элемент в том же разделе (например, div) в качестве метки, вы можете использовать это

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

Это просто означает, что ищите метку (это может быть что-нибудь вроде a, h2) с именем labelName.Перейдите к родителю этого ярлыка (например, div class="ParentDiv").Выполните поиск среди потомков этого родителя, чтобы найти любой дочерний элемент со значением elementToSelect.При этом он не выберет второй elementToSelect с DontSelect div в качестве родителя.

Хитрость в том, что вы можете уменьшить области поиска для элемента, сначала перейдя к родителю, а затем выполнив поиск потомка этого элемента.родитель для элемента, который вам нужен.Другой синтаксис, такой как following-sibling::h2, также может быть использован в некоторых случаях.Это означает, что следующий элемент h2.Это будет работать для элементов того же уровня, имеющих одного и того же родителя.

0 голосов
/ 11 сентября 2017

Мы можем выбрать родительский тег с помощью Selenium следующим образом:

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

это поможет вам найти прародителя известного элемента.Просто удалите один (/ ..), чтобы найти ближайший родительский элемент.

Например:

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

Есть несколько других способов реализовать это, но у меня это работало нормально.

0 голосов
/ 08 декабря 2016

Вы можете сделать это, используя / parent :: node () в xpath.Просто добавьте / parent :: node () к дочерним элементам xpath.

Например: пусть xpath дочернего элемента равен childElementXpath .

Тогда xpath его непосредственного предка будет childElementXpath / parent :: node () .

Xpath его следующего предка будет childElementXpath / parent :: node () / parent :: node ()

и т. Д.

Также вы можете перейти к предку элемента, используя 'childElementXpath/ancestor::*[@attr="attr_value"]'.Это было бы полезно, если у вас есть известный дочерний элемент, который уникален, но имеет родительский элемент, который не может быть однозначно идентифицирован.

...