Xpath to get value from a table - selenium

I am trying to get items and price values
Website: https://www.rahulshettyacademy.com/seleniumPractise/#/
<div class="cart-info">
<table>
<tbody>
<tr>
<td>Items</td>
<td>:</td>
<td><strong>0</strong>
</td>
</tr><tr>
<td>Price</td>
<td>:</td>
<td><strong>0</strong>
</td>
What I have tried:
.//*[#class='cart-info']//td/..//strong
Problem:
The locator above shows 2 of 2. Even when I try .//*[#class='cart-info']//td/..//strong[1] ,I still get 2 of 2. What can I change in my xpath so that I can locate that Item and Price individually ? Thanks in advance for your time.

You can use this for items value:
//div[#class='cart-info']/table/tbody/tr[1]/td[3]/strong
and this for price value:
//div[#class='cart-info']/table/tbody/tr[2]/td[3]/strong

Try the below.
(.//*[#class='cart-info']//td/..//strong)[1]

To complete, another short options :
//tr[td[.="Items"]]//strong
//tr[td[.="Price"]]//strong

Related

htmx: How to swap table row with hx-swap-oob?

I want to use hx-swap-oob to replace a table row of the existing page "out of band".
in browser:
<table>
<tr id="offer_1">....</tr>
<tr id="offer_2">....</tr> (old)
<tr id="offer_3">....</tr>
</table>
From Server to client:
<table hx-swap-oob="outerHTML:#offer_2" hx-select="#offer_2">
<tr id="offer_2"> .... </tr> (new)
</table>
But up to now this is the result:
<table>
<tr id="offer_1">....</tr>
<table hx-swap-oob="outerHTML:#offer_2" hx-select="#offer_2">
<tr id="offer_2"> .... </tr> (new)
</table>
<tr id="offer_3">....</tr>
</table>
I guess hx-select does not get evaluated when htmx get this snippet from the server.
How can I swap a row out-of-band?
Take a look at the new extension multi-swap.
https://htmx.org/extensions/multi-swap/
It allows swapping multiple elements marked with the id attribute.
For each element it is possible to choose which swap method should be used.
This does work:
<tr hx-swap-oob="true" id="offer_2"> .... </tr> (new)
But it has a drawback:
You need to modify the method which creates this row. Depending on your context, you might already have a method for this. Why modify this method, just because the result of this method should get used out-of-band?
If you use Django, this snippet could get used to add the hx-swap-oob attribute after the HTML got created:
def add_oob_attribute(html):
"""
I would like to avoid this ugly hack
https://github.com/bigskysoftware/htmx/issues/423
"""
assert isinstance(html, SafeString)
new, count = re.subn(r'(<\S+)', r'\1 hx-swap-oob="true"', html, count=1)
if not count == 1:
raise ValueError(f'Could not add hx-swap-oob: {html}')
return mark_safe(new)
I created an issue to find a better solution in the future:
https://github.com/bigskysoftware/htmx/issues/423

Click on a table link in selenium webdriver

Please find the sample code below
<tbody>
<tr>
<td class="menubox">
<table id="menubar" border="0">
<tbody>
<tr id="mytr">
<td class="level1" id="panel" onclick="popupwin onmouseover="this.classname onclick="popupwin"> menu1</td>
<td class="level1" id="panel" onclick="popupwin onmouseover="this.classname onclick="popupwin"> menu2</td>
<td class="level1" id="panel" onclick="popupwin onmouseover="this.classname onclick="popupwin"> menu3</td>
I am tring to access the menu3 column which is a link by xpath
//table[#id='menubar']/tbody/tr/td[3] but throwing an error no such element
found. could any one suggest what is wrong in the xpath ?
can you please try this:-
//tr[#id='mytr']//td[3]
Not sure why your Xpath wasn't working, your table structure and xpath is matching together.
However please try following xpath which might work. and if the website your testing is public. please provide the link.
//tr[#id='mytr']/td[contains(text(),'menu3')]

PHPUnit, Selenium - Click on link in row based on the value of another column in the same row

I think it's a stupid question, but I cant find an answer. I have table with many columns (name, date, link, etc.). I want to click on link based on the "name" value.
Here is short example:
<tr>
<td>
name value
</td>
<td>
date
</td>
<td>
<a href="">
link
</a>
</td>
</tr>
<tr>
the same format with different values
</tr>
Thanks for answers
This xpath will work for you, I think:
//td[contains(text(), 'name value')]/../td/a
It will find the <td> that contains 'name value', go back up to the containing <tr>, then back down to the <td> that has a<a> as a child in the same <tr>.
If I understand phpunit correctly, the command will look something like this:
$this->click("xpath=//td[contains(text(), 'name value')]/../td/a");

Is it possible to find the index of <tr> in selenium?

For example, I have a table like this:
<tbody>
<tr>aaaa</tr>
<tr>bbbb</tr>
<tr>cccc</tr>
</tbody>
Now, I want to find the index of the <tr> which contains the text "bbbb". I already get the <tr> element by searching the text. Now I want to know if it is possible to get the index of the <tr> (which is 1). Thanks.
You could do something like this:
List<WebElement> trElements = driver.findElements(By.cssSelector("tbody>tr"));
int trIndex = trElements.indexOf("bbbb");

Selenium RC: how to click an item present in column of a table

Say i have a table contains nos of rows which is not known. exp
column1 column2 column3
xxx yyy "Search Profile"
Column3 for each row contains a Link "Search Profile" now it's clear here that xpath of this link will be changing according to the row. now i want to search a string in column 2 and if present then needs to click it's column3 link.
Can anybody please let me know how to search and click it?
Given a page like this:
<html><head></head><body>
<table>
<tbody>
<tr>
<td>Number</td>
<td>Name</td>
<td>Link</td>
</tr>
<tr>
<td>1</td>
<td>Tom</td>
<td>Link</td>
</tr>
<tr>
<td>2</td>
<td>Jane</td>
<td>Link</td>
</tr>
<tr>
<td>3</td>
<td>Jill</td>
<td>Link</td>
</tr>
</tbody>
</table>
</body></html>
You could locate the correct value by using XPATH to first find the name of the user. Then relative to that name you could target the third column relative to the found name in the table.
selenium.click("//table/tbody/tr/td[text()='Jane']/parent::tr/td[3]")
In this example it finds the first instance of and exact match of 'Jane' in the second column. Then it backs up to the row and targets (and clicks on) the third column.
I'd suggest using selenium.click and giving it the target you're looking for. If you know what text you're searching for in the column 2, you can put that in an XPath expression and click on his friend in column 3.
Something along the lines of :
selenium.click("//table[#id='yourTableID']/descendant::tr[td[.='"column2text"']]/td[3]/button);
Do a count of rows in the generated table. int rolesTableRowCount = selenium.getXpathCount("//table[#id='your_table_id']/tbody/tr").intValue();
If the count meets your expected result, you could store the text in a specific cell. String var = selenium.getText("element_locator");
Check if the contents of var matches your test string.
If it does click the "Search Profile" link in Column 3.