Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium, Java. Need to select ancestor element inside table by Xpath

I have an HTML page containing the following code :

<table class="report" style="width:100%">
   <tbody>
      <tr>
         <th/>
         <th>Position Open
            <br>
            <span class="timestamp">27/7/2016 16:12:12</span>
            </br>
         </th>
         <th>Position closed
            <br>
            <span class="timestamp">27/7/2016 16:12:42</span>
            </br>
         </th>
      </tr>
      <tr>
         <td>
            <span dir="ltr">EURJPY</span>
         </td>
         <td>116.098</td>
         <td>116.156</td>
      </tr>
   </tbody>
</table>

On this page I have another table with the same class attribute "report" but only this table contains texts "Position Open" and "Position Closed". I need to select elements containing the "EURJPY", "116.098" and "116.156" data. These elements content is changing i.e. instead of "EURJPY" may appear "EURUSD" or "GBPCAD" etc. I tried the following code:

driver.findElement(By.xpath("//span[text()='Position Open']/ancestor::table[@class='report'](//tr)[2]/td/span")).getAttribute("textContent");  

to get the first required field text but got the Invalid selector error.

like image 438
Prophet Avatar asked Mar 08 '26 11:03

Prophet


1 Answers

Your XPath is close but there were a couple issues.

//span[text()='Position Open']/ancestor::table[@class='report'](//tr)[2]/td/span
  1. You are searching for a SPAN that contains the text 'Position Open' when in fact it is a TH that contains the text.

    //th[text()='Position Open']/ancestor::table[@class='report'](//tr)[2]/td/span
    
  2. (//tr) should be corrected to //tr

    //th[text()='Position Open']/ancestor::table[@class='report']//tr[2]/td/span
    
  3. What you want is the text contained in the TD, not the SPAN. If you pull the text from the TD you can get the text you want from all three elements. If you pull the SPAN, then you will also need to pull the last two TDs. This way is just simpler.

  4. ...and finally, the TH contains more than just the text you are looking for. Use .contains() to get a match.

    //th[text()='Position Open']/ancestor::table[@class='report']//tr[2]/td
    

So we take that XPath and put it into Java code and we get the below.

List<WebElement> tds = driver.findElements(By.xpath("//th[contains(text(),'Position Open')]/ancestor::table[@class='report']//tr[2]/td"));
for (WebElement td : tds)
{
    System.out.println(td.getText());
}
like image 160
JeffC Avatar answered Mar 11 '26 00:03

JeffC