1

I want to click on a button in a row using XPath if the cell within the certain row contains the text Reconciliation.

Below is the html of the website (I cannot share the link because it's an internal website):

<tbody>
<tr class="header">
<th scope="col" style="width:25px;">&nbsp;</th>
<th scope="col" style="width:25px;">&nbsp;</th>
<th scope="col" style="width:25px;">&nbsp;</th>
<th align="center" scope="col" style="width:50px;">ID</th>
<th align="center" scope="col" style="width:200px;">Project</th>
<th align="center" scope="col" style="width:300px;">Task</th>
<th align="center" scope="col" style="width:100px;">Lock</th>
<th align="center" scope="col" style="width:100px;">Person</th>
<th align="center" scope="col" style="width:100px;">First Date</th>
<th align="center" scope="col" style="width:130px;">Second Date</th>
</tr>
<tr>
<td><span><a href="/placeholder/DisplayTask.aspx?taskWflId=UADMERR2-PBIZCAL2-974f892e-eb51-42b7-bef6-6587ec7f76a2&amp;wklist=ADMIN&amp;prjId=12345&amp;prd=1" target="_self"><img src="/sth/open.gif" border="0" alt="Open this task"></a></span></td>
<td><span><a href="/placeholder/DisplayProcessHistory.aspx?prjId=12345&amp;prd=1" target="_blank"><img src="/sth/history.gif" border="0" alt="Show project history"></a></span></td>
<td><span><a href="/placeholder/DisplayProcessStatus.aspx?prjId=12345&amp;prd=1" target="_blank"><img src="/sth/roadmap.gif" border="0" alt="Show project roadmap"></a></span></td>
<td><span><a href="Worklist.aspx?IssueSourceIds=12345" target="_self" style="text-decoration:none">12345</a></span></td>
<td><span>"Product name placeholder"</span></td>
////Referenetial is in the line below
<td><span><span class="error">Reconciliation Error</span><br>A technical error has occured.</span></td>
<td><span></span></td>
<td><span>ADMIN</span></td>
<td><span>01-08-2022</span></td>
<td><span>01-08-2022 13:26:07</span></td>
</tr>
<tr class="alternate">
<td><span><a href="/placeholder/DisplayTask.aspx?taskWflId=UFUPPUB1-MLOTFUP1-332ce59b-7773-4098-9dd0-0a3ae790dea1&amp;wklist=FOLLOW_UP&amp;prjId=12345&amp;prd=1" target="_self"><img src="/sth/open.gif" border="0" alt="Open this task"></a></span></td>
<td><span><a href="/placeholder/DisplayProcessHistory.aspx?prjId=12345&amp;prd=1" target="_blank"><img src="/sth/history.gif" border="0" alt="Show project history"></a></span></td>
<td><span><a href="/placeholder/DisplayProcessStatus.aspx?prjId=12345&amp;prd=1" target="_blank"><img src="/sth/roadmap.gif" border="0" alt="Show project roadmap"></a></span></td>
<td><span><a href="Worklist.aspx?IssueSourceIds=12345" target="_self" style="text-decoration:none">12345</a></span></td>
<td><span>"Product name placeholder"</span></td>
<td><span><span class="followup">Issue Follow Up</span><br>Summary &amp; Status.<br>Concerned issue: "Product name placeholder"</span></td>
<td><span></span></td>
<td><span>FOLLOW_UP</span></td>
<td><span>01-08-2022</span></td>
<td><span>29-07-2022 10:05:07</span></td>
</tr>
<tr>
<td><span><a href="/placeholder/DisplayTask.aspx?taskWflId=UFUPADM1-MLOTFUP1-d02d29e7-f2c7-4a1c-9313-62ff652c1aa4&amp;wklist=ADMIN&amp;prjId=12345&amp;prd=1" target="_self"><img src="/sth/open.gif" border="0" alt="Open this task"></a></span></td>
<td><span><a href="/placeholder/DisplayProcessHistory.aspx?prjId=12345&amp;prd=1" target="_blank"><img src="/sth/history.gif" border="0" alt="Show project history"></a></span></td>
<td><span><a href="/placeholder/DisplayProcessStatus.aspx?prjId=12345&amp;prd=1" target="_blank"><img src="/sth/roadmap.gif" border="0" alt="Show project roadmap"></a></span></td>
<td><span><a href="Worklist.aspx?IssueSourceIds=12345" target="_self" style="text-decoration:none">12345</a></span></td>
<td><span>"Product name placeholder"</span></td>
<td><span><span class="followupAdmin">Issue Follow Up ADMIN</span><br>Summary, Status &amp; Admin Tools.<br>Concerned issue: "Product name placeholder"</span></td>
<td><span></span></td>
<td><span>ADMIN</span></td>
<td><span>01-08-2022</span></td>
<td><span>29-07-2022 10:05:07</span></td>
</tr>
</tbody>

May I ask how could this be achieved?

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Silver
  • 21
  • 5

3 Answers3

1

There appear to be three "buttons" on the page but you didn't specify which one to click. I'm going to assume you want to click the "Open this task" button.

You need to build an XPath to find the element that contains the "Reconciliation Error" text. We're going to start at the TR since the given table row will contain not only the "Reconciliation Error" text but also the IMG/button we want to click.

//tr//span[text()='Reconciliation Error']
^ find a TR anywhere in the DOM
    ^ that has a SPAN descendant that contains the specified text

This XPath returns the SPAN, not the button we want. We convert the SPAN portion of the locator to a property of the TR so that it will return the TR instead of the SPAN.

//tr[.//span[text()='Reconciliation Error']]

Now we append the locator portion that will find the IMG/button that we want to click from the TR we've already located.

//tr[.//span[text()='Reconciliation Error']]//img[@alt='Open this task']
                                              ^ find the IMG that contains "Open this task" as the alt text

Now that we have the locator, we just have to wait for the element to be clickable and then click it.

WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//tr[.//span[text()='Reconciliation Error']]//img[@alt='Open this task']"))).click()

Here are the other two buttons as well. You can see it's the same code, the XPath changes slightly based on the alt text we're looking for on the desired IMG.

Show project history

WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//tr[.//span[text()='Reconciliation Error']]//img[@alt='Show project history']"))).click()

Show project roadmap

WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//tr[.//span[text()='Reconciliation Error']]//img[@alt='Show project roadmap']"))).click()
JeffC
  • 22,180
  • 5
  • 32
  • 55
0

I would do something like the following. It will dynamically find the "Reconciliation" text in a row even when the table might contain more or less rows than you posted. It will then click the first link, under ID, in the same row.

table = driver.find_element_by_tag_name("table")
rows = table.find_elements_by_tag_name("tr")

for row in rows:
    if row.get_attribute("class") != "header": # skip the header row
    
        # get the contents of the span
        spanContent = row.find_element_by_css_selector("td:nth-of-type(6) > span").get_attribute("innerHTML")
        
        if (spanContent.find("Reconciliation") != -1): # find the text, -1 is not found
            # click the first link (ID) in this row
            row.find_element_by_css_selector("td:nth-of-type(1) > span > a > img").click()
            
            break
Javageddon
  • 76
  • 3
  • You should spend some time learning locators. In your first two lines, you are scraping the page twice when it could be handled by a simple locator like a CSS selector, "table tr ...". – JeffC Aug 19 '22 at 18:40
  • That's why I said "something like"! I was trying to make it simple so that a newbie could understand rather than going straight in with an over the top hard to understand example. – Javageddon Aug 19 '22 at 19:00
0

The <td> containing the text Reconciliation is:

<td>
    <span>
        <span class="error">Reconciliation Error</span>
        <br>
        A technical error has occured.
    </span>
</td>

To click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:

  • Clicking <span>:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//td/span[.//span[contains(., 'Reconciliation')]]"))).click()
    
  • Clicking <td>:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//td[./span[.//span[contains(., 'Reconciliation')]]]"))).click()
    
  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352