How to click the button which is placed in the same row with a <td /> containing specific text in Selenium?

Question:

I want to click button of a row who has a <td /> element containing a specific text in the same row. This is the architecture:

<tbody xpath="1">
 <tr role="row" class="odd">
  <td class=" grdIslemlerYanYana" tabindex="0" style="width: 110.767px;">
   <div class="btn-group  btn-group-sm">
    <a class="btn btn-ajaxbutton btn-sm  btn-primary" data-ajaxsendmethod="post" data-url="..."> <i class="fa fa-search"></i> İncele </a>
   </div>
  </td>
  <td>766964</td>
  <td class="sorting_1">997149</td>
  <td>BLABLA</td>
  <td>Genel Destek Programı</td>
  <td>18/04/2017</td><td>Onaylandı</td>
  <td>Aktif</td>
  <td>BLABLA</td>
  <td style="display: none;">BLABLA</td>
  <td style="display: none;"></td>
 </tr>

 <tr role="row" class="even">
  <td class=" grdIslemlerYanYana" tabindex="0" style="width: 110.767px;">
   <div class="btn-group  btn-group-sm">
    <a class="btn btn-ajaxbutton btn-sm  btn-primary" data-ajaxsendmethod="post" data-url="..."> 
    <i class="fa fa-search"></i> İncele </a>
   </div>
  </td>
  <td>766964</td>
  <td class="sorting_1">997149</td>
  <td>BLABLA</td>
  <td>Mikro ve Küçük İşletmelere Hızlı Destek Programı</td>
  <td>10/01/2022</td>
  <td>Onaylandı</td>
  <td>Aktif</td>
  <td>BLABLA</td>
  <td style="display: none;">BLABLA</td>
  <td style="display: none;">3</td>
 </tr>

 <tr role="row" class="odd">
  <td class=" grdIslemlerYanYana" tabindex="0" style="width: 110.767px;">
   <div class="btn-group  btn-group-sm">
    <a class="btn btn-ajaxbutton btn-sm  btn-primary" data-ajaxsendmethod="post" data-url="...> 
     <i class="fa fa-search"></i> İncele 
    </a>
   </div>
  </td>
  <td>766964</td>
  <td class="sorting_1">997149</td><td>BLABlA</td>
  <td>İşletme Geliştirme Destek Programı</td>
  <td>20/01/2022</td><td>Onaylandı</td>
  <td>Aktif</td><td>BLABlA</td>
  <td style="display: none;">BLABlA</td>
  <td style="display: none;"></td>
 </tr>
</tbody>

Also I am attaching the SS here, showing what I am trying to do:

enter image description here

Format is like this(without any logic currently): driver.find_element(By.XPATH, "//td[contains(text(),'Mikro ve Küçük İşletmelere Hızlı Destek Programı')]").click()

I got very confused. I am trying to click the blue "INCELE" button which is inside the same row having a <td /> containing string of "Mikro ve Küçük İşletmelere Hızlı Destek Programı" (I mean the second button on this page, but its place differs on different pages, therefore I should get the row with this text only).

Any help?

Asked By: Anthon Santhez

||

Answers:

This can be done with the following XPath locator:

//tr[.//td[contains(.,'Mikro ve Küçük İşletmelere Hızlı Destek Programı')]]//a[contains(@class,'btn-primary')]

Here we locating the tr parent element based on td with the specified text content and then we are locating the a button inside the parent tr element.
I guess the button element is the a element I used here. Otherwise it could be div element wrapping it…
So, the selenium command could be

driver.find_element(By.XPATH, "//tr[.//td[contains(.,'Mikro ve Küçük İşletmelere Hızlı Destek Programı')]]//a[contains(@class,'btn-primary')]").click()

UPD
I will try to describe the logic better.
First of all the //tr[.//td[contains(.,'Mikro ve Küçük İşletmelere Hızlı Destek Programı')]] is to find the table row tr element based on some it child. And the //a[contains(@class,'btn-primary')] is to find a button inside that row.
So, in the //tr[.//td[contains(.,'Mikro ve Küçük İşletmelere Hızlı Destek Programı')]] expression the //tr is coming for element with tr tag name.
What else we know about this tr, this row? It contains (inside it) some td element with Mikro ve Küçük İşletmelere Hızlı Destek Programı text. This is what [.//td[contains(.,'Mikro ve Küçük İşletmelere Hızlı Destek Programı')]] comes for.
The dot . is coming to say "from here".
While regular // is telling you "search from the top of the DOM until you find the match, the .// is saying "search inside the current node until you find the match.
So, //tr[.//td[contains(.,'Mikro ve Küçük İşletmelere Hızlı Destek Programı')]] is actually saying "from the top of the DOM find element with tr tag name. Now, inside this tr element find td element containing text Mikro ve Küçük İşletmelere Hızlı Destek Programı.
Of cause, if during searching the DOM we find some tr but could not find inside it the td with predefined text we will continue to the next tr and search inside it until we find a match and return that node element or in case of no match nothing will be returned and Selenium will throw corresponding exception.

Answered By: Prophet
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.