1

I'm using Selenium and Ruby with IE 11 / and chrome

I'm trying to write a script that finds a specific piece of text in a table and returns the column and row which it exists.

I've found some close examples online but they were just returning the value in a cell, not returning the location of the text.

To find the object (text) itself I was using

  varObject = driver.find_element(:xpath, "//*[contains(text(),'#{varDevice}')]")

 driver.execute_script("arguments[0].style.border='3px solid red'", varObject) #Make sure I'm pointing to the correct text.

I wish I could attach the code for the table itself, but unfortunately I'm not allowed to share any code what-so-ever.

My goal is to take a table which column 1 row x has a checkbox and the text I'm trying to find is in column 2 row x and grab the row so that I will be able to click on checkbox in column 1 row x. Clicking on the checkbox is the easy part once I figure out what X is of the text I'm searching.

Example:

 <html>
 <body>
   <table>
     <tr>
       <td>
           *A check box*
       </td>
       <td> 192.168.0.0
       </td>
     </tr>

     <tr>
       <td>
           *A check box*
       </td>
       <td> 192.168.0.100
       </td>
     </tr>
   </body>

In this scenario I want to look for 192.168.0.100 and return that it is in row 2 so that I can click on the checkbox in row 2.

Thanks

user3531858
  • 155
  • 5
  • 17
  • How are you finding the text currently? Please [update your question](https://stackoverflow.com/posts/47097530/edit) to show some code. – Tom Lord Nov 03 '17 at 14:16
  • This is what I've used a couple of time to find the object. varDevice in this case is the static IP of a Printer. varObject = driver.find_element(:xpath, "//*[contains(text(),'#{varDevice}')]") – user3531858 Nov 03 '17 at 14:23
  • ...And what does the HTML look like? Again, I repeat, can you please [edit your question](https://stackoverflow.com/posts/47097530/edit) to provide a [mcve] of them problem you are trying to solve? There are different answers that may be better suited to different situations. For example, see [this similar question](https://stackoverflow.com/questions/788225/table-row-and-column-number-in-jquery). – Tom Lord Nov 03 '17 at 14:31
  • Thanks everyone. I took JeffC comment to get the code to work correctly. Now i need to take Tom Lord comments to make it a bit more robust. Is there a way to check and give credit to all of you? I ended up using this varObject = driver.find_element(:xpath, "//*[../following-sibling::td[contains(.,'192.168.0.01')]]") varObject.click – user3531858 Nov 03 '17 at 18:09

2 Answers2

0

There are a few ways you could achieve this, such as:

  1. Searching through the table:

    • Iterate through the table rows.
    • Look for the text match in column 2
    • When found, click the checkbox in column 1.
  2. Finding the adjacent column via relative xpath:

    • Find the element with a text match (i.e. exactly what you have already)
    • Find the relative column by applying an xpath like /../td[1] to the above.
  3. As you initially suggested, by finding the row number in the table:

    • Find the element with a text match, like above.
    • Use some clever xpath logic to determine the row number.

As a side note, I'd suggest making your current xpath a bit more specific than "search the whole page". At some point, you're bound to detect completely the wrong thing by mistake. Instead, you can do something like:

//td[contains(text(),'#{varDevice}')]
Tom Lord
  • 27,404
  • 4
  • 50
  • 77
  • Are you really advocating an absolute XPath? That is going to be super fragile and I can't think of a time (other than actual XML) where that would be a good idea. – JeffC Nov 03 '17 at 15:20
  • No, sorry - that's a little misleading. All I really meant to say is "search inside a table, not anywhere on the whole page". (Edited my answer.) – Tom Lord Nov 03 '17 at 15:51
  • More feedback... Instead of `//*/table` you can just use `//table` but I would just shorten the whole thing to `//td[contains(text(),'#{varDevice}')]`. There isn't going to be a `TD` that isn't inside a table anyway so all the stuff before it is essentially implied and not really necessary. It shortens the XPath significantly. – JeffC Nov 03 '17 at 16:32
0

I'm assuming that the checkbox is an INPUT. If it's not, you can adjust the XPath.

//input[../following-sibling::td[contains(.,'192.168.0.100')]]

This will find an INPUT whose parent (the TD) has a sibling TD that contains the IP you are looking for. It works with the HTML provided but I'm guessing the HTML you posted is not complete so you probably will have to adjust it.

JeffC
  • 22,180
  • 5
  • 32
  • 55