[java] Locating child nodes of WebElements in selenium

I am using selenium to test my web application and I can successfully find tags using By.xpath. However now and then I need to find child nodes within that node.

Example:

<div id="a">
    <div>
        <span />
        <input />
    </div>
</div>

I can do:

WebElement divA = driver.findElement( By.xpath( "//div[@id='a']" ) )

But now I need to find the input, so I could do:

driver.findElement( By.xpath( "//div[@id='a']//input" ) )

However, at that point in code I only have divA, not its xpath anymore... I would like to do something like this:

WebElement input = driver.findElement( divA, By.xpath( "//input" ) );

But such a function does not exist. Can I do this anyhow?

BTW: Sometimes I need to find a <div> that has a certain decendent node. How can I ask in xpath for "the <div> that contains a <span> with the text 'hello world'"?

This question is related to java selenium xpath webdriver

The answer is


The toString() method of Selenium's By-Class produces something like "By.xpath: //XpathFoo"

So you could take a substring starting at the colon with something like this:

String selector = divA.toString().substring(s.indexOf(":") + 2);

With this, you could find your element inside your other element with this:

WebElement input = driver.findElement( By.xpath( selector + "//input" ) );

Advantage: You have to search only once on the actual SUT, so it could give you a bonus in performance.

Disadvantage: Ugly... if you want to search for the parent element with css selectory and use xpath for it's childs, you have to check for types before you concatenate... In this case, Slanec's solution (using findElement on a WebElement) is much better.


For Finding All the ChildNodes you can use the below Snippet

List<WebElement> childs = MyCurrentWebElement.findElements(By.xpath("./child::*"));

        for (WebElement e  : childs)
        {
            System.out.println(e.getTagName());
        }

Note that this will give all the Child Nodes at same level -> Like if you have structure like this :

<Html> 
<body> 
 <div> ---suppose this is current WebElement 
   <a>
   <a>
      <img>
          <a>
      <img>
   <a>

It will give me tag names of 3 anchor tags here only . If you want all the child Elements recursively , you can replace the above code with MyCurrentWebElement.findElements(By.xpath(".//*"));

Hope That Helps !!


If you have to wait there is a method presenceOfNestedElementLocatedBy that takes the "parent" element and a locator, e.g. a By.xpath:

WebElement subNode = new WebDriverWait(driver,10).until(
    ExpectedConditions.presenceOfNestedElementLocatedBy(
        divA, By.xpath(".//div/span")
    )
);

I also found myself in a similar position a couple of weeks ago. You can also do this by creating a custom ElementLocatorFactory (or simply passing in divA into the DefaultElementLocatorFactory) to see if it's a child of the first div - you would then call the appropriate PageFactory initElements method.

In this case if you did the following:

PageFactory.initElements(new DefaultElementLocatorFactory(divA), pageObjectInstance));
// The Page Object instance would then need a WebElement 
// annotated with something like the xpath above or @FindBy(tagName = "input")

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

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 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 webdriver

WebDriverException: unknown error: DevToolsActivePort file doesn't exist while trying to initiate Chrome Browser 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? ImportError: No module named 'selenium' how to use List<WebElement> webdriver How to get attribute of element from Selenium? Selenium Finding elements by class name in python Open web in new tab Selenium + Python When running WebDriver with Chrome browser, getting message, "Only local connections are allowed" even though browser launches properly How can I start InternetExplorerDriver using Selenium WebDriver