Виберіть батьківський елемент відомого елемента в Selenium


116

У мене є певний елемент, який я можу вибрати за допомогою Selenium 1.

На жаль, мені потрібно натиснути батьківський елемент, щоб отримати бажану поведінку. Елемент, який я можу легко знайти, має атрибут не вибір, що робить його мертвим для клацання. Як перейти вгору за допомогою XPath ?

Відповіді:


169

Тут є пара варіантів. Зразок коду є на 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();

41
А якщо ви хочете перейти до бабусі і дідуся, використовуйте By.Xpath ("../ ..").
Монсеньйор

@Monsignor працює точно так само , як шляху до файлів ... або шлях URL: stackoverflow.com/questions/8577636 /../../ questions / 8577636 / ...
jpaugh

Жоден із цих XPaths не є правильним для використання з Selenium. Потрібно використовувати, By.xpath(“./..”)щоб правильно користуватися деревом DOM під час використання element.findElement. Провідний "./" необхідний для встановлення контекстного вузла.
JimEvans

35

Трохи більше про 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">


Привіт @Anderson Мені потрібна допомога з моїм запитанням. У вас є час, щоб подивитися? Спасибі заздалегідь. stackoverflow.com/questions/54647055 / ...

18

Розглянемо ваш DOM як

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

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

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

Пояснення: Виберіть вузол на основі значення його дочірнього вузла


Якщо ми шукаємо, divякий знову вкладений у кілька дівок, то замість того, .//spanщоб By.xpath("//div[.//span[text()='Close']]")ми могли використовувати *//span, він буде шукати більшість батьківських елементів діви даного проміжку. Зараз це виглядатиме такdriver.findElement(By.xpath("//div[*//span[text()='Close']]"));
Jai Prak

14

Погляньте на можливі осі XPath , напевно, ви шукаєтеparent . Залежно від того, як ви знаходите перший елемент, ви можете просто налаштувати xpath для цього.

Крім того, ви можете спробувати синтаксис з двома крапками , ..який вибирає батьківську частину поточного вузла.


5

Це може бути корисно для когось іншого: Використання цього зразка 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 дівом як батьківського.

Трюк полягає в тому, що ви можете зменшити області пошуку для елемента, спершу перейшовши до батьківського, а потім шукаючи нащадка цього батьківського для потрібного вам елемента. Інші синтаксиси подібні following-sibling::h2також можуть використовуватися в деяких випадках. Це означає наступного елемента h2. Це буде працювати для елементів на одному рівні, маючи одного батьківського.


0

Це можна зробити, використовуючи / parent :: node () на xpath. Просто додайте / parent :: node () до дочірніх елементів xpath.

Наприклад: Нехай xpath дочірнього елемента є childElementXpath .

Тоді xpath його безпосереднього предка був би childElementXpath / parent :: node () .

Наступним його предком був би Xpath childElementXpath / parent :: node () / parent :: node ()

і так далі..

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


0

Ми можемо вибрати батьківський тег за допомогою Selenium наступним чином:

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

це допоможе вам знайти бабусю та дідуся з відомого Елементу. Просто видаліть один (/ ..), щоб знайти безпосередній батьківський елемент.

Подібно до:

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

Є деякі інші способи цього здійснити, але це справно працювало для мене.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.