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" >
<td tabindex="0" style="width: 110.767px;">
<div >
<a data-ajaxsendmethod="post" data-url="..."> <i ></i> İncele </a>
</div>
</td>
<td>766964</td>
<td >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" >
<td tabindex="0" style="width: 110.767px;">
<div >
<a data-ajaxsendmethod="post" data-url="...">
<i ></i> İncele </a>
</div>
</td>
<td>766964</td>
<td >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" >
<td tabindex="0" style="width: 110.767px;">
<div >
<a data-ajaxsendmethod="post" data-url="...>
<i ></i> İncele
</a>
</div>
</td>
<td>766964</td>
<td >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:
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?
CodePudding user response:
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.