XPath of the edit button is //*[#id="edit_1088"] - ruby

My query is I need to click on the first edit link on the table. The table has 7 columns and rows will be incremented dynamically.
HTML Code for first row:
<tr role="row" class="odd">
<td>
<form method="GET" target="_blank" action>...</form>
<td> ALLOCATION CHANGE</td>
<td class="right"></td>
<td> SATTER, KRAIG</td>
<td> CAFEMANAGER1</td>
<td class="sorting_1">03/08/2016 17:00</td>
<td class="edit_icon" id="edit_1088" onclick="on EditClick(1088)">
<span class="view_icon" style="margin-left: 40%;"></span>
</td>
</tr>
Note: the ID of the edit button keep on changing as the row increments.
Mycode in cucumber -ruby -capybara
And /^I click on the Expresso image$/ do
find(:xpath, '//*[#id="l1row"]/span').click
find('tr:odd > td:edit_icon [id="edit_"] match: first').click
sleep 10
end
Error Message: invalid selector: An invalid or illegal selector was specified

Update based on the posted HTML -
Note: Your first <td> isn't closed, I'm assuming thats just an error when you were adding the HTML to the question.
So from the HTML posted you don't actually have an edit link you just have a td you need to click on - the one in the first row with an id beginning with "edit_" so
find('tr:first-child > td[id^="edit_"]').click
The attempt you posted in your question won't work because there is no such CSS selector as odd or edit_icon and find needs valid CSS selectors (or XPath if you specify XPath or set it as your default)
Previous Answer Based on the wording of the question:
If this is a table then you can do what you want with CSS and not worry about XPath.
find('tr:first-child > td:last-child [id^="edit_"]')
will find the element whose id starts with "edit_" in the last td in the first row. If your rows and columns are not actually a table you'll need to provide some example HTML of what you're talking about.

Related

Datatable : sort column with HTML elements

I'm trying to sort a column such as :
<td> <span class="badge badge-light">300 €</span> jean-yves#gmail.com </td>
Where the content of the badge (300 €) is the amount I want to be used for the sort.
Without the badge, the sort is working without problem, but it doesn't seem to work with the badge.
SOLUTION 1
See columns.type option which you can set to 'html' to have HTML tags removed for ordering and searching.
SOLUTION 2
Alternatively you can tell DataTables value you want to use for sorting using data- attributes, see HTML5 data-* attributes - cell data.
For example:
<td data-order="300"> <span class="badge badge-light">300 €</span> jean-yves#gmail.com </td>

How do you select two different tags via xpath, both at different levels, when one of them is optional

I have a situation where the data is a mix of these format on the same page. In other words, some rows will show up as:
some lengthy XPATH_X uptill here:
<td/>
<td>
I Need this element td
</td>
<td/>
<td/>
<td/>
<td/>
and a few other rows will show in this format:
the same lengthy XPATH_X uptill here:
<td/>
<td>
<span>
I Need this element span
</span>
</td>
<td/>
<td/>
<td/>
<td/>
Please note that there are no differentiating attributes for each of the td tags. I need to select the second row (td) in both the cases.
I'm trying to catch both of the elements using the following xpath:
XPATH_X/*[self::td[position()=2] or self::td[position()=2]/span]
I tried this out on the page but for some reason it doesn't select anything.
Can someone please help me out with this? I've spent more than 2 hours on this already.
You should try XPATH_X/td[2]//text() to retrieve the text whether it's at the root of the td or in a child tag
You can test it here ; in this test I retrieve three results :
the text inside a span inside a td
the text at the root of a td
both the texts at the root of a td and inside the enclosed span (if this doesn't work for you and the text of the td should be retrieved only if there's no span, use XPATH_X/td[position()=2 and not(./span)]/text() | XPATH_X/td[2]/span/text() instead)
To retrieve the elements containing text nodes rather than the text node themselves, you can use the following :
XPATH_X/td[2]//self::node()[text()]

How to write XPATH in nested elements of siblings

I have such DOM structure:
<td>
<div class="name">Max</div>
</td>
<td>Sales Officer</td>
<td>mail#mail.com</td>
<td class="links">
<a class="edit" href="/edit"><i class="second"></i>Edit Profile</a>
</td>
The main goal is to click on Edit button for particular user. And I have different users (they are in another rows of table).
I need to get xpath which contains the combination of name Max and text Edit Profile.
The main problem for me that both elements are in sibling td tags.
I've never written anything similar before.
//a[text()='Max'] //i[text()='Edit Profile']
What should I add between this to xpathes?
This one should do the trick:
//td[a="Max"]/following-sibling::td/a[.="Edit Profile"]

xpath with multiple contains statements do not function correctly

I have html code as follows below. I am trying to access it with selenium. If I do a
//*[contains(text(),'Add OfficeContract (Portal)')]
it finds several (there is more html that has more occurrences). So I want to find a specific instance but when I try
//*[contains(text(),'Add OfficeContract (Portal)') and contains(text(),'7121995')]
There are no matches found. SImpy doing
//*[contains(text(),'7121995')]
Finds all sorts of stuff (html is full of that string)
HTML CODE
<tr class="pd" valign="top"><br>
<td> </td><br>
<td nowrap="">SQAAUTO</td><br>
<td nowrap="">01/30/2014 9:47:48 AM</td><br>
<td><br>
<b>Add OfficeContract (Portal)</b><br>
<br><br>
Office Id 7121995<br>
<br><br>
Contract ID added: "8976504"<br>
<br><br>
Term Date added: "12/31/9999"<br>
<br><br>
</td><br>
</tr>
I believe the issue here is that the two strings are not found together in the same element (based on your sample).
For the above xpath to return a result you would need an element like this:
<b>Add OfficeContract (Portal) 7121995</b>

How do I find if there's a second element exists with the same name with selenium using XPath?

I already know the Text of an element in the table:
string title1 = Driver.FindElement(
By.XPath(
".//[#id='ctl00_ContentPlaceHolder1_BreakdownGridView_ctl02_TitleLabel']"
)).Text;
How do I verify if there's a second element in the table that has the same text as title1?
Here is my Table structure:
<tr class="alt" style="background-color:White;height:110px;">
<td>
<span id="ctl00_ContentPlaceHolder1_BreakdownGridView_ctl03_WindowStartLabel" tabindex="1">
01/13/2013
</span>
</td>
<td>
<span id="ctl00_ContentPlaceHolder1_BreakdownGridView_ctl03_ShowLabel" tabindex="1">
Lea‌​der of the Pack
</span>
</td>
<td>
<span id="ctl00_ContentPlaceHolder1_BreakdownGridView_ctl03_TitleLabel">
Love at First Bite
</span>
</td>
<td>
<span id="ctl00_ContentPlaceHolder1_BreakdownGridView_ctl03_PremiereLabel">
01/12/2013 22:00
</span>
</td>
...
</tr>
After getting title1 try implement logic something like below to find how many elements are there with the same text
int count=driver.findElements(By.xpath("//table[#id='urTable']//*[text()='"+title1+"']")).size();
Based on the count it is easy to find how many elements are there with same text.
In your table structure, doing an xpath query as below would select all the span tags.
//tr/td/span
Now, xpath can be used to select the span tags with specific text as follows:
//tr/td/span[text() = "Text you're matching against"]
/* in your case*/
//tr/td/span[text() = title1]
This is to get spans consist that text....(partial match)
int count= driver.FindElements(
By.XPath(
".//span[contains(text(),'"+titleOneText+"')]"
)).size();
This is to get spans text is same....(full match)
int count= driver.FindElements(
By.XPath(
".//span[text()='"+titleOneText+"']"
)).size();
Based on your question if same xpath value having 2 elements. Just see the static value of particular element and take as xpath. it will work definitely. for example
save & cancel button having same xpath value
driver.find_element_by_xpath("//*[#id='id_sav']")-save
driver.find_element_by_xpath("//*[#id='id_sav']")-cancel
here we can use static element value
driver.find_element_by_xpath("//a[text()='save']")-save
driver.find_element_by_xpath("//a[text()='cancel']")-cancel

Resources