Search code examples
javaselenium-webdriverdescendant

How do I append a "descendant" clause next to an xpath variable?


This is what my code looks like

    public void someTest() {
      String x = "/html/body/div/div["
      String y = "]/a"
         for (int i = 1; i < 5; i++){
            String links = x + i + y;
            driver.findElement(By.xpath(links)).click(); // This will iteratively go to the next link and click on it
         }
    }

What I'm trying to achieve, however, is that once it clicks on the link, it should then look for descendant links and click on those as well. So is there a way of doing that? If I try something like the following, would that work?

    driver.findElement(By.xpath(links/descendant::a).click(); 

Solution

  • It's a fragile way of coding, altering the xpath as you go through the loop. Instead, I recommend using the findElements method and looping through the elements it returns, something like this:

    public void someTest() {
     xpath xpath_findlinks = "/html/body/div/div/a";
     xpath relative_xpath = "./..//a";
     for (WebElement eachlink : driver.findElements(By.xpath(xpath_findlinks))) {
      eachlink.click();
      for (WebElement descendantlink : eachlink.FindElements(By.xpath(relative_xpath))) {
       descendantlink.click();
      }
     }
    }
    

    Note a crucial difference. The first time you call findElements it's on the driver, so it's looking through the entire html; but the second time, it's called as a method of a particular element (the current link), so you can use it to find elements relative to that link - e.g. to find descendants.

    I recommend using this structure; however, without knowing your overall html it's hard to know what relative xpath to use. The one I have provided is just an example of what a relative xpath might look like, with the distinctive start of ./.