[select] Select parent element of known element in Selenium

I have a certain element that I can select with Selenium 1.

Unfortunately I need to click the parent element to get the desired behaviour. The element I can easily locate has attribute unselectable, making it dead for clicking. How do I navigate upwards with XPath?

This question is related to select xpath selenium parent

The answer is


Little more about XPath axes

Lets say we have below HTML structure:

<div class="third_level_ancestor">
    <nav class="second_level_ancestor">
        <div class="parent">
            <span>Child</span>
        </div>
    </nav>
</div>
  1. //span/parent::* - returns any element which is direct parent.

In this case output is <div class="parent">

  1. //span/parent::div[@class="parent"] - returns parent element only of exact node type and only if specified predicate is True.

Output: <div class="parent">

  1. //span/ancestor::* - returns all ancestors (including parent).

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

  1. //span/ancestor-or-self::* - returns all ancestors and current element itself.

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

  1. //span/ancestor::div[2] - returns second ancestor (starting from parent) of type div.

Output: <div class="third_level_ancestor">


You can do this by using /parent::node() in the xpath. Simply append /parent::node() to the child elements xpath.

For example: Let xpath of child element is childElementXpath.

Then xpath of its immediate ancestor would be childElementXpath/parent::node().

Xpath of its next ancestor would be childElementXpath/parent::node()/parent::node()

and so on..

Also, you can navigate to an ancestor of an element using 'childElementXpath/ancestor::*[@attr="attr_value"]'. This would be useful when you have a known child element which is unique but has a parent element which cannot be uniquely identified.


There are a couple of options there. The sample code is in Java, but a port to other languages should be straightforward.

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

Obtaining the driver from the WebElement

Note: As you can see, for the JavaScript version you'll need the driver. If you don't have direct access to it, you can retrieve it from the WebElement using:

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

Take a look at the possible XPath axes, you are probably looking for parent. Depending on how you are finding the first element, you could just adjust the xpath for that.

Alternatively you can try the double-dot syntax, .. which selects the parent of the current node.


Let's consider your DOM as

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

Now that you need to select parent tag 'a' based on <span> text, then use

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

Explanation: Select the node based on its child node's value


We can select the parent tag with the help of Selenium as follows:

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

this will help you to find the grandparent of the known Element. Just Remove one (/..) to find the immediate Parent Element.

Like:

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

There are some other ways to implement this, but it worked fine for me.


This might be useful for someone else: Using this sample 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>

If for example, I want to select an element in the same section (e.g div) as a label, you can use this

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

This just means, look for a label (it could anything like a, h2) called labelName. Navigate to the parent of that label (i.e. div class="ParentDiv"). Search within the descendants of that parent to find any child element with the value of elementToSelect. With this, it will not select the second elementToSelect with DontSelect div as parent.

The trick is that you can reduce search areas for an element by navigating to the parent first and then searching descendant of that parent for the element you need. Other Syntax like following-sibling::h2 can also be used in some cases. This means the sibling following element h2. This will work for elements at the same level, having the same parent.


Examples related to select

Warning: Use the 'defaultValue' or 'value' props on <select> instead of setting 'selected' on <option> SQL query to check if a name begins and ends with a vowel Angular2 *ngFor in select list, set active based on string from object SQL: Two select statements in one query How to get selected value of a dropdown menu in ReactJS DATEDIFF function in Oracle How to filter an array of objects based on values in an inner array with jq? Select unique values with 'select' function in 'dplyr' library how to set select element as readonly ('disabled' doesnt pass select value on server) Trying to use INNER JOIN and GROUP BY SQL with SUM Function, Not Working

Examples related to xpath

Xpath: select div that contains class AND whose specific child element contains text XPath: difference between dot and text() How to set "value" to input web element using selenium? How to click a href link using Selenium XPath: Get parent node from child node What is the difference between absolute and relative xpaths? Which is preferred in Selenium automation testing? How to use XPath preceding-sibling correctly Selenium and xPath - locating a link by containing text How to verify an XPath expression in Chrome Developers tool or Firefox's Firebug? Concatenate multiple node values in xpath

Examples related to selenium

SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 81 session not created: This version of ChromeDriver only supports Chrome version 74 error with ChromeDriver Chrome using Selenium Selenium: WebDriverException:Chrome failed to start: crashed as google-chrome is no longer running so ChromeDriver is assuming that Chrome has crashed WebDriverException: unknown error: DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser Class has been compiled by a more recent version of the Java Environment How to configure ChromeDriver to initiate Chrome browser in Headless mode through Selenium? How to make Firefox headless programmatically in Selenium with Python? element not interactable exception in selenium web automation Selenium Web Driver & Java. Element is not clickable at point (x, y). Other element would receive the click How do you fix the "element not interactable" exception?

Examples related to parent

parent & child with position fixed, parent overflow:hidden bug How can I return to a parent activity correctly? How to call a parent method from child class in javascript? Make div (height) occupy parent remaining height jQuery: get parent tr for selected radio button Select parent element of known element in Selenium fork() child and parent processes How do I get the n-th level parent of an element in jQuery? How to delete parent element using jQuery PHP Accessing Parent Class Variable