Robot Framework - get span element from table - python

I'm trying to write some test cases to automatically test my websites but I'm having trouble clicking on checkbox witch is situated on every single row in the left column. User can click on every cell in the row he wants and checkbox will became checked or unchcked..
But I'm not able to simulate this click into table cell. First I'm trying to get some cell into variable and then to click on this cell using this variable like this:
Page Should Contain Element xpath=//div[contains(#id,'-tableCtrlCnt')]
${item1} Get Table Cell xpath=//div[contains(#id,'-tableCtrlCnt')]/table/tbody 1 2
Click Element ${item1}
But I'm getting error on the second line of code, I just cannot get the column.
The error/fail is:
Cell in table xpath=//div[contains(#id,'-tableCtrlCnt')]/table/tbody
in row #2 and column #2 could not be found.
And this is how part of my html code looks like:
<div id="__table1-tableCtrlCnt" class="sapUiTableCtrlCnt" style="height: 160px;">
<table id="__table1-table" role="presentation" data-sap-ui-table-acc-covered="overlay,nodata" class="sapUiTableCtrl sapUiTableCtrlRowScroll sapUiTableCtrlScroll" style="min-width:648px">
<tbody>
<tr id="__table1-rows-row0" data-sap-ui="__table1-rows-row0" class="sapUiTableRowEven sapUiTableTr" data-sap-ui-rowindex="0" role="row" title="Click to select or press SHIFT and click to select a range" style="height: 32px;">
<td role="rowheader" aria-labelledby="__table1-ariarowheaderlabel" headers="__table1-colsel" aria-owns="__table1-rowsel0"></td>
<td id="__table1-rows-row0-col0" tabindex="-1" role="gridcell" headers="__table1_col0" aria-labelledby="__table1-0" style="text-align:left" class="sapUiTableTd sapUiTableTdFirst">
<div class="sapUiTableCell">
<span id="__text37-col0-row0" data-sap-ui="__text37-col0-row0" title="1010" class="sapMText sapMTextMaxWidth sapMTextNoWrap sapUiSelectable" style="text-align:left">1010
</span>
</div>
</td>
<td id="__table1-rows-row0-col1" tabindex="-1" role="gridcell" headers="__table1_col1" aria-labelledby="__table1-1" style="text-align:left" class="sapUiTableTd">
<div class="sapUiTableCell">
<span id="__text38-col1-row0" data-sap-ui="__text38-col1-row0" title="Company Code 1010" class="sapMText sapMTextMaxWidth sapMTextNoWrap sapUiSelectable" style="text-align:left">Company Code 1010
</span>
</div>
</td>
</tr>
...
</tbody>
</table>
</div>
Don't you have any idea how to solve this click into table issue?

Check whether this helps you-
${item1} Get Table Cell xpath=//table[contains(#id,'__table1-table')] 1 2
OR
${item1} = Get Text //table[contains(#id,'__table1-table')]//tr[1]//td[2]//div/span

Related

Python xPath looping for TR table rows but object empty

Hi we are running this code and it is driving my crazy
we capture a data table in table this works
then grab all th and it's text in sizes this works
then we want to grab all underlying rows in TR; and after loop over columns in rows : does not work! the color_rows object is always empty .. but when testing with xpath in the browser it does! work ... why? how?
My question is: how can I grab the tbody/tr's?
Expected flow
loop over TR's
Access, TR 1 by 1, get 1st TD
Get all TD's data that have class form-control
table = response.xpath('//div[#class="content"]//table[contains(#class,"table")]')
sizes = table.xpath('./thead//th/text()').getall()[1:] #works!
color_rows = table.xpath('./tbody/tr') #does not work! object empty
for color_row in color_rows:
color = color_row.xpath('/td[1]/b/text()').get().strip()
print(color)
stocks = color_row.xpath('/td/div[input[#class="form-control"]]/div//text()').getall()
for size, stock in zip(sizes, stocks)
Our html data looks like this
<table class="table">
<thead>
<tr>
<th id="ctl00_cphCEShop_colColore" class="text-left" colspan="2">Colore</th>
<th>S</th>
<th>M</th>
<th>L</th>
</tr>
</thead>
<tbody>
<tr>
<td id="x">
<b>White</b>
<input type="hidden" name="data" value="3230/201">
</td>
<td id="avail">
Avail:
</td>
<td id="1">
<div>
<input name="cell" type="text" class="form-control">
<div class="text-center">179</div>
</div>
</td>
<td id="2">
<div>
<input name="cell" type="text" class="form-control">
<div class="text-center">360</div>
</div>
</td>
etc etc
Apparently tbody tags are often omitted in HTML but aded by the browser.
In this case there was no (real) body tag making the xpath object miss!
And hence the troubles with xpath (if you really think the tbody tag is there)
Why do browsers insert tbody element into table elements?

Xpath with sibling not working with button click

I am Trying to navigate an html table of appointments. Each row contains a different date, so I need to find the correct row by searching by date, which is td[1] of a 10 column row. The last column, td[10] contains the button to click for more info. So, I need to search by date and then click the button at the end of the table for more info.
I tested the xpath, and it seems to be correct:
.//*[#id='id_past_appointments']/tbody/tr/td[contains(text(), 'Sep 28, 2016')]//following-sibling::*[9]/div/a[2]
However, when I make it part of a Selenium Python command, with the click at the end, I get the following error: "Element is not clickable at point (925.4500122070312, 11.5). Other element would receive the click: "
Here is my Selenium code:
browser.find_element_by_xpath(".//*[#id='id_past_appointments']/tbody /tr/td[contains(text(), 'Sep 28, 2016')]//following-sibling::*[9]/div/a[2]").click()
Here is a copy of the html:
<tr>
<td>Wed Sep 28, 2016 9:45a.m.</td>
<td>Dr. Smiley Schutes</td>
<td>Medicine followup</td>
<td>
<td>Exam 1</td>
<td></td>
<td>Balance Due</td>
<td align="left">2</td>
<td>
<td style="text-align: right;">
<div class="btn-group">
<a class="btn btn-small btn-link" href="/appointments/37135832">
<i class="icon-pencil"></i>
Edit Appointment
</a>
<a class="btn btn-small" target="_blank" href="/clinical_note/edit/37135832/lock/">
<i class="icon-lock"></i>
View Note
</a>
</div>
</td>
Any ideas on how to adjust this so that the click works?
hasc

Selenium, Python. Gives no such element: Unable to locate element error whether the button is there

I am working on my test case which includes sending values to the input fields for buying tickets. But for this case selenium gives me unable to locate element error while I am trying to locate input field named itemq_3728, the problem is the page is changing the name of input field every time it reopens the page.
How can I locate the input field ?
I try the XPath but can't achieve the goal and also couldn't write it relative to the name of the ticket
<table id="bms_tickets" width="90%" cellspacing="5" cellpadding="0" class="bms_tickets table">
<thead>
<tr>
<th>NAME</th>
<th width="240px">PRICE</th>
<th width="100px">QUANTITY</th>
</tr>
</thead>
<tbody id="resTypesTable">
<tr id="bms_restype_3728" class="bms_restype">
<td class="bms_restype_desc">
Gen Ad
<div style="font-size:10px;margin-left:5px;">
</div>
</td>
<td class="bms_restype_price">
$10.00
<input type="hidden" name="pay_itemq_3728" value="10.00">
</td>
<td class="bms_restype_qty">
<input type="text" name="itemq_3728" value="0" placeholder="1" min="1">
</td>
</tr>
</tbody>
</table>
Hope this will help assuming only numeric path of name changes after pageload:
'//td[#class="bms_restype_qty"]//input[starts-­‐with(#name,"itemq")]'
You can locate it using cssSelector as below :-
driver.find_element_by_css_selector("td.bms_restype_qty > input[type='text']")
Or if you're interested to locate this element using xpath you can locate it wrt Gen Ad name column text as below :-
driver.find_element_by_xpath(".//td[normalize-space(.)='Gen Ad' and #class = 'bms_restype_desc']/following-sibling::td[#class='bms_restype_qty']/input")
Or
driver.find_element_by_xpath(".//tr[td[normalize-space(.)='Gen Ad']]/td[#class='bms_restype_qty']/input")

Selenium: How do I get a text within a <td> tag and then click the Javascript link of it's sibling?

I have a list of forms that I need to edit one by one wherein I have to identify the form title first and then click the JavaScript link to open it's editing template.
In the sample code below, I need to identify the text Another Custom Form (Mobile) which is the form title and then click the a href link whose onclick value is editProjectFormType. It is the second sibling of form title. I am trying to perform this task in Python.
<tr class="trbg2">
<td width="10%" align="left" nowrap="nowrap">
<div align="center">
<input type="checkbox" name="selectedFormType" value="2192454$$rmymiK" checked="checked">
</div>
</td>
<td width="10%" align="left" nowrap="nowrap"><img src="https://dmsak.qa.asite.com/images/dots.gif" width="6" height="15">!!!!!!!!!!!!!!!!!!!!!!!!!!!!Ashish_test!!!!!!!!!!</td>
<td width="10%" align="left">Custom forms</td>
<td width="10%" align="center">ACFM</td>
<td width="24%">Another Custom Form (Mobile)</td>
<td width="20%">Custom</td>
<td align="center" width="15%">
<a href="javascript:void(0);" onclick="editProjectFormType('2192454$$rmymiK');">
<img src="https://dmsak.qa.asite.com/images/i_editfgt.gif" width="16" height="20" border="0">
</a>
</td>
<td align="center" width="15%">
<a href="javascript:void(0);" onclick="downloadFormTemplate('2192454$$rmymiK');">
<img src="https://dmsak.qa.asite.com/images/f_dow_tmple.gif" width="22" height="22" border="0" alt="Click here to Download Template" title="Click here to Download Template">
</a>
</td>
</tr>
I have used the following incomplete code so far and not sure what do I do next
button = browser.find_elements_by_tag_name('td')
for txt in button:
if txt == "Another Custom Form (Mobile)":
You can perform click on link with following single xPath where you can provide text Another Custom Form (Mobile) to identify their following-sibling and get that link as as below :-
link = browser.find_element_by_xpath("//td[contains(text(),'Another Custom Form (Mobile)')]/following-sibling::td/a[contains(#onclick, 'editProjectFormType')]")
link.click()
Edited..
Implement WebDriverWait to get the element as below :-
link = WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.XPATH, "//td[contains(text(),'Another Custom Form (Mobile)')]/following-sibling::td/a[contains(#onclick, 'editProjectFormType')]")))
link.click()
Note:- if target element is inside a frame. you need to switch to that frame first as browser.switch_to_frame("frame name or id") then go to find the target element as above.
Hope it will help you...:)
I would approach this by:
creating a class to represent a row in this table, say "MyRow", which has method to interact with each column as a field in the class.
using Selenium to find all of the rows in the table, returning a list of instances of this class.
loop thru the list looking for the row that matches the target name :
for (MyRow myRow : allRows) {
if (myRow.name.equals("Another Custom Form (Mobile)")) {
return myRow;
}
}
click on the link in the target row's column. myRow.editProjectForm()
The first one worked for me with some modification.
I have 3 buttons in single td, with other 4 td have texts. I have to click on specific button based on the one td value (e.g customer_name). Below is working the code.
self.driver.find_element_by_xpath(
"//td[contains(text(),'" + customer_name + "')]/following-sibling::td/button[text()='Accept']"
).click()

xPath: Difficulties matching expression with actual source code

From this Deutsche Börse web page, under the table header Issuer I want to get the string content 'db X-trackers' in the cell next to the one with Name in it.
Using my web browser, I inspect that table area and get the code, which I've pasted into this XML tree just so that I can test my xPath.
<root>
<div class="row">
<div class="col-lg-12">
<h2>Issuer</h2>
</div>
</div>
<div class="table-responsive">
<table class="table">
<tbody>
<tr>
<td>Name</td>
<td class="text-right">db X-trackers</td>
</tr>
</tbody>
</table>
</div>
</root>
According to FreeFormatter.com, my xPath below succeeds in retrieving the correct element (Text='db X-trackers'):
my_xpath = "//h2['Issuer']/ancestor::div[#class='row']/following-sibling::div//td['Name']/following-sibling::td[1]/text()"
Note: It goes to <h2>Issuer</h2> first to identify the right place to start working from.
However, when I run this on the actual web page using Selenium WebDriver, None is returned.
def get_sibling(driver, my_xpath):
try:
find_value = driver.find_element_by_xpath(my_xpath).text
except NoSuchElementException:
return None
else:
value = re.search(r"(.+)", find_value).group()
return value
I don't believe anything is wrong in the function itself, so either the xPath must be faulty or there is something in the actual web page source code that throws it off.
When studying the actual Source code in Chrome, it looks a bit messier than what I see with Inspector, which is what I used to create the little XML tree above.
<div class="box">
<div class="row">
<div class="col-lg-12">
<h2>Issuer</h2>
</div>
</div>
<div class="table-responsive">
<table class="table">
<tbody>
<tr>
<td >
Name
</td>
<td class="text-right" >
db X-trackers
</td>
</tr>
<tr>
<td >
Product Family
</td>
<td class="text-right" >
db X-trackers
</td>
</tr>
<tr>
<td >
Homepage
</td>
<td class="text-right" >
<a target="_blank" href="http://www.etf.db.com">www.etf.db.com</a>
</td>
</tr>
</tbody>
</table>
</div>
Are there some peculiarities in the source code above, or is my xPath (or function) wrong?
I would use the following and following-sibling axis:
//h2[. = "Issuer"]/following::table//td[. = "Name"]/following-sibling::td
First we locate the h2 element, then get the following table element. In the table element we look for the td element with Name text and then get the following td sibling.

Categories

Resources