Selenium xpath with multiple conditions and fetch element value - selenium

I have a condition where tr row which generates dynamic value:
<tbody>
<tr id="24686" tabindex="0">
<td class="nowrap xh-highlight" style="padding: 3px 8px;">Available</td>
</tr>
</tbody>
I have Xpath 1: (//tbody/tr/td[contains(text(),'Available')])[1] which returns
Available
and Xpath 2: //tr[1]/#id which returns
ld_9050427
22707
The condition is that I want to generate one xpath which will return first number whose status is Available and then return its ID. Later on I want to use this same id to carry on later process?
I tried something like below but it didn't work
(//tbody/tr[/#id and/td[contains(text(),'Disponible')]])[1]

If you want to select tr that has id attribute (any) and table cell with text "Available" try
//tr[#id and td='Available']
to extract id value for further use you need get_attribute/getAttribute method

To find the first number whose status is Available and then return its ID you can use the following solution:
xpath:
"//tbody//tr//td[text()='Available']/.."
Note 1: The .. in the xpath refers to the ancestor node
Note 2: As you are looking for the first match with the implemented condition, you have use either:
Python:
find_element_by_xpath()
Java:
findElement()
C#:
FindElement()
Note 3: Finally you have to use getAttribute("id") / get_attribute("id") to extract the value of the id attribute as follows:

Related

Xpath to verify multiple TD to filter 1 unique TR

I need to verify that a <tr> exists which contains 3 <td> with specific values.
There are 100+ <tr> tags on the page. I am trying to filter them using 1 xpath.
for instance if I filter all the <tr> on these 3 values:
//td[contains(text(),'Belgium')]
//td[contains(text(),'be-stelara-cd-uc')]
//td[contains(text(),'2022-07')]
That should return 1 <tr> containing those <td>.
So what I need to do, would be to filter each xpath against the previous leaving a single unique remaining. I came across the | union operator which is almost what I want but instead of combining the results I want to exclude them.
I tried this xpath:
//tr[contains(td/text(), 'Belgium') and contains(td/text(), 'be-stelara-cd-uc') and contains(td/text(), '2022-07')]
html example:
https://prnt.sc/qcmEu0zSvu3S
Edit:
//tr[contains(td/text(), 'Belgium') and contains(td[2]/text(), 'be-stelara-cd-uc') and contains(td[3]/text(), '2022-07')]
This works, I did not realise that the td would check for ordering as well. If possible I would like to tweak the question to come up with a universal solution considering that the order cannot be guaranteed.
If you can rely on the data in the picture, that is: no whitespace and no other inline-elements more than shown, you could try this:
//tr[td[text()= 'Belgium'] and td[text()= 'be-stelara-cd-uc'] and td[contains(text(), '2022-07')]]
If you want to be extra sure and want to filter unwanted space you could try this:
//tr[td[text()[normalize-space()= 'Belgium']] and td[text()[normalize-space()= 'be-stelara-cd-uc']] and td[contains(text(), '2022-07')]]
If more content can be present just use the . and contains() together like this:
//tr[td[contains(., 'Belgium')]and td[contains(., 'be-stelara-cd-uc')]and td[contains(., '2022-07')]]
And to be complete you could also just test the text-content of the tr like this:
//tr[contains(., 'Belgium') and contains(., 'be-stelara-cd-uc') and contains(., '2022-07')]
Use any of the below xpath to identify the tr
//tr[.//td[contains(., 'Belgium')]][.//td[contains(., 'be-stelara-cd-uc')]][.//td[contains(., '2022-07')]]
OR
//tr[contains(., 'Belgium') and contains(., 'be-stelara-cd-uc') and contains(., '2022-07')]

Identify Xpath in a dynamic table using xpath axes

tableenter image description hereI want to write an xpath using axes for the a column value in the table, corresponding to a particular value in the same row.
e.g. I want to print last column value for HDIL.
Xpath that i have tried :
//a[contains (text(), ‘HDIL’)]/following-sibling::td[#class=‘green’]
HTML
<tr>
<td>
<a href="http://demo.guru99.com/">
HDIL </a>
</td>
<td>A</td>
<td>564.6</td>
<td>68.8</td>
<td><font class="green">+ 6.1</font></td>
</tr>
You may find 'table row' with text = 'HDIL' and from this row get the last table cell. E.g. like this:
//tr[td[contains(string(), 'HDIL')]]/td[last()]
or
//tr[td[contains(string(), 'HDIL')]]/td[font]
Or using webDriver I would find all cells for needed row and get the last one:
// C# code;
var lastCell = driver.FindElements(By.XPath("//tr[td[contains(string(), 'HDIL')]]/td")).Last();
Your xpath is written in the way of taking siblings from a but you should take siblings of td that contains a. Your xpath also implies that class='green' is the attribute of td but in fact (according to your example) it is the attribute of font that is child of td.
So the proper xpath would be: //td[a[contains (text(), 'HDIL')]]/following-sibling::td[font[#class='green']].
See test here.

find element by xpath with contains(node()) AND contains(#attribute)

I'm trying to locate an element by checking innerHTML (property node()) and some attribute (e.g. #class).
Both methods works separately but I can't combine them with "and"
HTML part:
<tr class="tableRow1">
<td nowrap="" class="ct">
<input type="CheckBox" name="RowKey" tabindex="17" value="15635">
<img src="/tm/images/1pixel.gif" style="height:9px;width:9px;border:0" name="RowIndicator">
</td>
<td class="lt" title="ID">XXXXX</td><nobr>0021234567</nobr><td class="rt">1.00</td>
</tr>
So I need to locate this node of class="tableRow1" (from many others) by catching this part:
<nobr>002123456</nobr>.
This two works (but catching several elements):
.find_element_by_xpath('//tr[contains(node(), "0021234567")]')
.find_element_by_xpath('//tr[contains(#class, "Row")]')
This one doesn't:
.find_element_by_xpath('//tr[contains(node(),"0021234567") and contains(#class,"Row")]')
Try this XPath-1.0 expression:
descendant::*[contains(node(), "0021234567")]/ancestor::tr[contains(#class, "Row")][1]
or in a complete instruction
.find_element_by_xpath('descendant::*[contains(node(), "0021234567")]/ancestor::tr[contains(#class, "Row")][1]')
This instruction selects the first tr ancestor - which has a class attribute which contains the value Row - of a (global) node() which contains the value 0021234567.
Your two XPath selectors are selecting different nodes.
The node that contains the string is a descendant of the <tr> node with the class name. That is why when you are putting both conditions for one node it doesn't find any matching node.
Try this:
.find_element_by_xpath('//[contains(node(), "0021234567")]/ancestor::tr[contains(#class), "Row"]')
To locate the <tr> nodes which contains the child <nobr> nodes you can use the following solution:
driver.find_element_by_xpath("//nobr//ancestor::tr[contains(#class, 'Row')]")
Note: It is assumed that the innerText within the <nobr> is a variable else the innerText can be included within the XPath expression as well.
So I need to locate this node of class="tableRow1" (from many
others) by catching this part:
<nobr>002123456</nobr>
The XPath expression should be:
//tr[#class='tableRow1'][.//nobr='002123456']
That is the basic. Then you could adjust that to your situation.
Example 1 (many posible classes tokens):
//tr[contains(concat(' ',#class,' '),' tableRow1 ')][.//nobr='002123456']
Example 2 (posible white space in nobr):
//tr[contains(concat(' ',#class,' '),' tableRow1 ')]
[.//nobr[normalize-space()='002123456']]
Example 3 (class token starts with 'tableRow'):
//tr[contains(concat(' ',#class,' '),' tableRow')]
[.//nobr[normalize-space()='002123456']]

Python Selenium auto-test (How to get text of a column)

Using Xpath tool from chrome dev tools, I have been able to get xpath string and a td object. I 'm just wondering how do we find the value of text in a td object using selenium python web-drivers?
for your case you can use .gettext() method of selenium.
Once I found that, the attribute within td which contains the text is changing and i was supposed to fetch the text in those attribute.
like
<td class="table__cell" data-col-index="1">
<div class="ec-table__cell-content ">813.75</div>
</td>
<td class="table__cell" data-col-index="2">
<span class="ec-table__cell-content ">522.12</span>
</td>
So to get text within all td in a list, I used dynamic Xpath way:
By.xpath("//td[contains(#class,'table__cell')]/following::*").getText()
Try to search by xpath. Relatively to some ID.
Example of:
id("body_content")/table/tbody/tr/td[3]
in this case will be shown exact elements of 3rd column only.

How to identify the element name in selenium

The element to match is as follows:
... some html....
<table>
some <tr's>
<tr><td>"caption in a <a> tag"</td><td> result value here </td></tr>
more <tr's>
.... more html
I'm using Selenium IDE but don't see a way to match/capture the result value text anywhere ?
Given
<yyy name="iggy" caption="abcd" level="20"></yyy>
you would want to use
assertAttribute("iggy#caption", "abcd")
This uses the name as a locator and #caption to specify the attribute you want. You could follow it with
assertAttribute("iggy#level", "20")
to check the level attribute. You might use 'validateAttribute' instead of 'assertAttribute'. If you want to capture the attribute value use 'storeAttribute'.