We're having difficulties trying to figure out why our "expenses" doesn't show up in our webpage.
The expenses is a subclass to the superclass "rental", and we've written:
<td th:text="${expenses.rental_id}"></td>
We've also tried with:
<td th:text="${rental.rental_id}"></td>
but none of the above works.
The error:
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "expenses.full_price" (template: "home/expenses" - line 54, col 9)
[It seems like it's here, the problem happen]
<td th:text="${expenses.rental_id}"></td>
<td th:text="${expenses.base_cost}"></td>
<td th:text="${expenses.rental_end_date}"></td>
<td th:text="${expenses.end_time}"></td>
<td th:text="${expenses.drop_off}"></td>
<td th:text="${expenses.drop_off_extra}"></td>
<td th:text="${expenses.km_end}"></td>
<td th:text="${expenses.repair_fee}"></td>
<td th:text="${expenses.fuel_level}"></td>
<td th:text="${expenses.full_price}"></td>
<td>
<a th:href="#{'/updateExpenses/'+${expenses.rental_id}}">
<button>Edit Expenses</button>
</a>
[This is our homecontroller, we're using when getting the error]
#GetMapping("/expenses/{rental_id}")
public String expenses(#PathVariable("rental_id") int rental_id, Model model){
model.addAttribute("expenses", expensesService.findExpensesById(rental_id));
return "home/expenses";
}
[The button that should send us to the page.]
<a th:href="#{'/expenses/'+${rental.rental_id}}">
<button>Expenses</button>
</a>
[The SQL statement we're trying to use.]
public Expenses findExpensesById(int rental_id){
String sql = "SELECT * FROM expenses WHERE rental_id = ?";
RowMapper<Expenses> rowMapper = new BeanPropertyRowMapper<>(Expenses.class);
Expenses e = template.queryForObject(sql, rowMapper, rental_id);
return e;
}
[We do have both getters and setters for full_price]
public double getFull_price(){
return full_price;
}
public void setFull_price(double full_price) {
this.full_price = full_price;
}
The field is called full_price everywhere. Even in the databasse.
private double full_price;
I m encountering a problem with the '\n' or in thymleaf the problem is i need to enter to a new line. I have iteretate inside the inside of cell. I m getting the content but just in one line and i want one tweet under the other inside the cell. and i saw as well some similiar topic but it is not working in my case.
This is what i m getting:
How should i manage it to go in the next line inside one cell.
The Thymleaf code:
<tr>
<td th:text="${user.id}">1</td>
<td th:text="${user.getUsername()}">Hamdo</td>
<span th:each="tweet : ${tweets}">
<td th:text="${tweet.content} " ><br/>
<br/>
</td>
</span>
The controller :
#GetMapping({"", "/", "/index", "/index.html"})
public String followers(Principal principal, Model model) {
User user=userService.getUser(principal.getName());
model.addAttribute("tweets",
tweetService.tweetsFromUser(principal.getName()));
model.addAttribute("user",user);
return "index";
}
The service class:
private List<TweetDTO> tweetsFromUser(User user) {
return tweetRepository.findAllByAuthor(user).stream().map(TweetDTO::new).collect(toList());
}
You don't need the extra span... just loop inside of the <td />, like this:
<tr>
<td th:text="${user.id}">1</td>
<td th:text="${user.username}">Hamdo</td>
<td>
<p th:each="tweet : ${tweets}" th:text="${tweet.content}" />
</td>
</tr>
I have the following table and I am wanting to verify that "Vendor Assignment Expired" is in between "Vendor Accepted Assignment" and "Vendor Declined Assignment". What would be the best way to go about doing this?
<table cellspacing="0" cellpadding="0" border="0" style="table-layout: fixed; width: 100%; visibility: inherit;" id="x:1011327536.4:mkr:dataTbl.hdn" mkr="dataTbl.hdn">
<tbody id="x:1011327536.12:mkr:rows:nw:1" class="ig_ListItem igg_ListItem" nw="1" mkr="rows">
<tr id="x:1011327536.13:adr:0:tag:" tag="" adr="0" type="row">
<td class="grdCell" style="width:46%;" idx="0" adr="0" type="cell"> Update Disclosure Date </td>
</tr>
<!--[600001]-->
<tr id="x:1011327536.13:adr:1:tag:" class="ig_ListAlt igg_ListAlt" tag="" adr="1" type="row">
<td class="grdCell" idx="0" adr="0" type="cell"> Vendor Accepted Assignment </td>
</tr>
<!--[101020]-->
<tr id="x:1011327536.13:adr:2:tag:" tag="" adr="2" type="row">
<td class="grdCell" idx="0" adr="0" type="cell"> Vendor Assignment Expired </td>
</tr>
<!--[900101]-->
<tr id="x:1011327536.13:adr:3:tag:" class="ig_ListAlt igg_ListAlt" tag="" adr="3" type="row">
<td class="grdCell" idx="0" adr="0" type="cell"> Vendor Declined Assignment </td>
</tr>
<!--[900102]-->
<tr id="x:1011327536.13:adr:4:tag:" tag="" adr="4" type="row">
<td class="grdCell" idx="0" adr="0" type="cell"> Conditionally Declined </td>
</tr>
I know I can loop through each item like this:
List<WebElement> row = getDriver().findElements(By.cssSelector(".igg_ListItem > tr > td:nth-child(1)"));
for(WebElement el : row)
{
el.getText();
}
I'm just not sure how to capture the values to perform the assertion that the text displays between the other 2.
You can try this -
List<WebElement> row = getDriver().findElements(By.cssSelector(".igg_ListItem > tr > td:nth-child(1)"));
for (int i =0; i<row.size();i++) {
String status = row.get(i).getText();
if (status.equalsIgnoreCase("Vendor Assignment Expired")) {
if (row.get(i-1).getText().equalsIgnoreCase("Vendor Accepted Assignment")
&& row.get(i+1).getText().equalsIgnoreCase("Vendor Declined Assignment"))
System.out.println("Yes it between those values");
break;
}
}
Let me know if it works! Cheers!
You can use something like below:
Get next column Text and assert it with expected value.
String declinedAssignment = driver.findElement(By.xpath("//tr[td[text()=/"Vendor Assignment Expired/"]]//following-sibling::tr/td")).getText();
Get previous column Text and assert it with expected value.
String acceptedAssignment = driver.findElement(By.xpath("//tr[td[text()=/"Vendor Assignment Expired/"]]//preceding-sibling::tr/td")).getText();
<table id="tblListViewHeader" class="adminlist" cellspacing="1" cellpadding="0" style="table-layout: fixed; width: 1003px;">
<tbody>
</table>
</td>
</tr>
<tr>
<td>
<div id="divListView" style="width: 100%; height: 300px; overflow: auto; display: block;">
<table id="tblListView" class="adminlist" cellspacing="1" cellpadding="0" style="table-layout: fixed; width: 100%;">
<tbody data-bind="template: { name: 'ActiveGradeTemplate', foreach: ActiveGrade }">
<tr class="row0">
<td data-bind="text:$index()+1" style="width: 5%;">1</td>
<td data-bind="text: GradeName" style="width: 20%;">Vantage Point</td>
<td align="right" data-bind="text: DisplayCreatedDate" style="width: 10%;">27 Mar 2013</td>
<td align="right" data-bind="text: CreatedByUser" style="width: 10%;">Name</td>
<td align="right" data-bind="text: DisplayModifiedDate" style="width: 10%;">27 Mar 2013</td>
<td align="right" data-bind="text: ModifiedByUser" style="width: 10%;">Name</td>
<td align="center" data-bind="text: Status" style="width: 5%;">Active</td>
<td align="center" style="width: 10%;">
<a id="lnkEdit_7" data-bind="click: $root.lnkEdit, attr:{'id':'lnkEdit_' + GradeID}" href="#">Edit</a>
<span id="spanEdit_7" data-bind="attr:{'id':'spanEdit_' + GradeID}"></span>
</td>
</tr>
<tr class="row0">
<td data-bind="text:$index()+1" style="width: 5%;">2</td>
<td data-bind="text: GradeName" style="width: 20%;">test grade</td>
<td align="right" data-bind="text: DisplayCreatedDate" style="width: 10%;">Yesterday</td>
<td align="right" data-bind="text: CreatedByUser" style="width: 10%;">Name</td>
<td align="right" data-bind="text: DisplayModifiedDate" style="width: 10%;">Yesterday</td>
<td align="right" data-bind="text: ModifiedByUser" style="width: 10%;">Name</td>
<td align="center" data-bind="text: Status" style="width: 5%;">Active</td>
<td align="center" style="width: 10%;">
<a id="lnkEdit_11" data-bind="click: $root.lnkEdit, attr:{'id':'lnkEdit_' + GradeID}" href="#">Edit</a>
<span id="spanEdit_11" data-bind="attr:{'id':'spanEdit_' + GradeID}"></span>
</td>
</tr>
How can I retrieve the td values for each and every row, this is for Dynamic generation. All the tr class names are the same: <tr class="row0">. How do I retreive the table data for the above formatted table?
Try below code, this will print all cells data,
// Grab the table
WebElement table = driver.findElement(By.id("divListView"));
// Now get all the TR elements from the table
List<WebElement> allRows = table.findElements(By.tagName("tr"));
// And iterate over them, getting the cells
for (WebElement row : allRows) {
List<WebElement> cells = row.findElements(By.tagName("td"));
// Print the contents of each cell
for (WebElement cell : cells) {
System.out.println(cell.getText());
}
}
// Grab the table
WebElement table = driver.findElement(By.id("table-6"));
//Get number of rows in table
int numOfRow = table.findElements(By.tagName("tr")).size();
//Get number of columns In table.
int numOfCol = driver.findElements(By.xpath("//*[#id='table-6']/tbody/tr[1]/td")).size();
//divided Xpath In three parts to pass Row_count and Col_count values.
String first_part = "//*[#id='table-6']/tbody/tr[";
String second_part = "]/td[";
String third_part = "]";
//take the second column values
int j=2;
//List to store the second column
List<String> secondColumnList=new ArrayList<String>();
//Loop through the rows and get the second column and put it in a list
for (int i=1; i<=numOfRow; i++){
//Prepared final xpath of specific cell as per values of i and j.
String final_xpath = first_part+i+second_part+j+third_part;
//Will retrieve value from located cell and print It.
String test_name = driver.findElement(By.xpath(final_xpath)).getText();
secondColumnList.add(test_name);
System.out.println(test_name);
}
Dynamic table data capturing:
1.First of all Capture Table Head Count.
[int tHeadCount = driver.findElements(By.xpath("//table//tr//th")).size();]
2.Capture Table Row Count in which row your actual data exists.
[-in my point of view i need data from first row it self, so i am hard coding it to zero.]
If you want please add one for loop to existing code.
3.The actual solution starts from here.
Following is function call "Deposited By" is table heading text of corresponding table data.
String tableDataValue = managePackageTableData("Deposited By");
public String managePackageTableData(String columnName) {
//In Following line i am capturing table contains how many headers.
int tHeadCount = driver.findElements(By.xpath("//table//tr//th")).size();
int statusIndex = 0;
for(int i=0;i<tHeadCount-1;i++)
{
String theadValue = driver.findElements(By.className("table")).get(0).findElements(By.tagName("tr")).get(0).findElements(By.tagName("th")).get(i).getText();
if(theadValue.equalsIgnoreCase(columnName))
{
statusIndex = i;
break;
}
}
String tableData = driver.findElements(By.tagName("tbody")).get(0).findElements(By.tagName("tr")).get(0).findElements(By.tagName("td")).get(statusIndex).getText();
return tableData;
}
You have many options, but there's mine.
You catch all tds into a list.
List<WebElement> tdlist = driver.findElements(By.cssSelector("table[id='divListView'] tr td"));
and if you want to have the value, you can use a loop.
for(WebElement el: tdlist) {
Systeme.out.println(el.getText());
}
Check out this
Most common Challenge Automation tester face during iterating through Table and list. they often want to find some value from the table cell or list and want to perform action on the same value or find corresponding other element in the same block and perform action on it.
http://qeworks.com/iterate-table-lists-selenium-webdriver/
I have done this code using TestComplete and have replicated it now with Selenium C#, I have learnt this hard way but will work for any table control and you don't have to hardcode any xpath elements in it. Also if you have a nested table control within a td like for example where you have a nested table structure where your data is interpreted like below(happens in complex tables when you use developer express grids or angular grid controls).This case if you see the td tag again has a nested table structure which again has duplicate data. You can either capture such data or leave it depending on the case using the code which I am giving below.
Html
<table>
<tr>
<td>Account #
<table>
<tr>
<td>
Account #
</td>
</tr>
</table>
</td>
<td>Name
<table>
<tr>
<td>
Name
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>1234
<table>
<tr>
<td>
1234
</td>
</tr>
</table>
</td>
<td>Bharat
<table>
<tr>
<td>
Bharat
</td>
</tr>
</table>
</td>
</tr>
</table>
Code
public List<TableDataCollection> StoreHtmlTableToList(IWebElement tblObj)
{
DataTable dataTbl = new DataTable();
int rowIndex = 1;
try
{
_tblDataCollection = new List<TableDataCollection>();
var tblRows = ((IJavaScriptExecutor)DriverContext.Driver).ExecuteScript("return arguments[0].rows; ", tblObj);
if (tblRows != null)
{
//Iterate through each row of the table
foreach (IWebElement tr in (IEnumerable)tblRows)
{
int colIndx = 1;
// Iterate through each cell of the table row
var tblCols = ((IJavaScriptExecutor)DriverContext.Driver).ExecuteScript("return arguments[0].cells; ", tr);
foreach (IWebElement td in (IEnumerable)tblCols)
{
//loop through any child or nested table structures if you want using the same approach
//Write Table to List : This part is not done yet
//Print the values
Console.WriteLine("Row[" + rowIndex.ToString() + "] Col[" + colIndx.ToString() + "] : " + td.Text);
colIndx++;
}
rowIndex++;
}
}
}
catch (Exception)
{
throw;
}
return _tblDataCollection;
}
# Ripon Al Wasim
The below code will helps you to find values column by column
WebElement customtable = t.driver.findElement(By.cssSelector("div.custom-table"));
List<WebElement> r = customtable.findElements(By.tagName("tr"));
for (WebElement row : r) {
List<WebElement> d = row.findElements(By.tagName("td"));
for(int i = 0; i<d.size(); i++) {
if(i==0) {
WebElement x =d.get(i);
JavascriptExecutor js = (JavascriptExecutor) t.driver;
js.executeScript("arguments[0].scrollIntoView();", x);
System.out.println(i+"."+d.get(i).getText()+"\n");
if(d.get(i).getText().contains(searchtext)) {
System.out.println(i+".yes\n");
}
else
{
System.out.println("No\n");
}
}
}
}
its working for me.
//tbody/tr
this will give you the total no of row-
//tbody/tr/td
this will give you all the cell for the above rows and you can iterate it based on your requiredment.
Below are different approach we can follow to handle dynamic data in application [Its not for dynamic elements];
Using excel approach;
a. Get the web-element of the field
b. Get its text .
c. Store the data in the excel and validate with actual result pattern.
Note : There are multiple data validation options in excel like compare columns, get duplicate etc..
Using collection;
a. Get the web-element of the field.
b. Get its data inside the collection [List, set, map etc]
c. Write the java code to compare the pattern of the application data.
i. Pattern can be data type, data length, data range ,Decimal places of amount field or other ,currency type, date and time pattern etc.
ii. You can write the java conditions to verify the values of charts/graphs/dashboard if you are using in your application.
d. Compare the actual data pattern[from the collection] and the expected data pattern[From the java code]
Use JDBC API to handle it through the database where you can check the actual data by using different commands.
I can`t seem to send the right entity key to servlet in my web app. I am using javascript method to submit the form with the data via a button.
The code is divide into jstl code:
<c:if test="${!empty MOFornecedorList}">
<div id="RightColumn">
<%-- Search Box --%>
<div class="searchform">
<form id="formsearch" name="formsearch" method="post" action="<c:url value='FProcurar'/>">
<span>
<input name="searchBox" class="editbox_search" id="editbox_search" size="80" maxlength="100" value="Pesquisa" type="text" />
</span>
<input name="btnsearch" class="button_search" value="Pesquisa" type="button"/>
</form>
<div class="clr"></div>
<h>Criterio de Pesquisa: </h>
<select name="Type">
<option value="1">ID</option>
<option value="2">Nome</option>
<option value="3">Email</option>
<option value="4">Fax</option>
<option value="5">Endereço</option>
</select>
</div>
<%-- END Search Box --%>
<div class="clr"></div>
<table id="ProductTable" class="detailsTable">
<tr class="header">
<th colspan="9" >Modificar Fornecedor</th>
</tr>
<tr class="tableHeading">
<td>ID</td>
<td>Nome</td>
<td>Endereço</td>
<td>Nº de Celular</td>
<td>Nº de Telefone</td>
<td>Email</td>
<td>Fax</td>
<td>Descrição</td>
<td></td>
</tr>
<c:forEach var="MOForn" items="${MOFornecedorList}" varStatus="iter">
<tr class="${'white'} tableRow">
<td>${MOForn.getFid()}</td>
<td>${MOForn.getFNome()}</td>
<td>${MOForn.getFEndereco()}</td>
<td>${MOForn.getFNCel()}</td>
<td>${MOForn.getFNTel()}</td>
<td>${MOForn.getFEmail()}</td>
<td>${MOForn.getFFax()}</td>
<td>${MOForn.getFDescricao()}</td>
<td>
<form action="<c:url value='FMOb'/>" method="post" name="FModifi">
<input type="hidden"
name="MOForn"
value="${MOForn.fid}">
<input type="button"
value="Modificar" onclick="ModF()">
</form>
</td>
</tr>
</c:forEach>
</table>
</div>
</c:if>
the javascript method
function ModF() {
jConfirm('Modificar o Fornecedor?', 'Confirmação', function(r) {
if (r == true) {
$("form[name='FModifi']").submit();
} else {
return false;
}
});
}
and the controller code:
//Check if fornecedor as been selected
int Fid = Integer.parseInt(request.getParameter("MOForn"));
//Get fornecedor object and set it to variable
Forn = transManager.getEnt(Fid,"fornecedor");
request.setAttribute("Forn",Forn);
PagesInF="FModificar";
request.setAttribute("PagesInF", PagesInF);
userPath = "/Fornecedor";
Now when i test the code the jstl will read 5 records in the item MOFornecedorList in ascending order and a button will be created in the last column.
When the button is pressed for example in the third record the JavaScript method Modf() is invoked and a confirm dialog is shown.
When the user presses the OK button the form FModifi is submitted.
Then the servlet will receive a the request to open the page FMOb where the hidden input for the button pressed will be retrieved and put in a variable type int and some other code will execute.
But the value that the form submit's is the wrong one. ex:
1 - button - MOforn = 1
2 - button - MOforn = 2
3 - button - MOforn = 3 (clicked)
4 - button - MOforn = 4
5 - button - MOforn = 5
The Form should send the value of 3 but sends the value of 5.
So please if anyone as any ideas please share.
You've multiple forms with the same name. Your JS function isn't submitting the form from which it was been called, but it is submitting the last occurrence of the form with that name in the HTML DOM tree.
You need to replace
<input type="button" value="Modificar" onclick="ModF()">
by
<input type="button" value="Modificar" onclick="confirmSubmit(this.form)">
and rewrite the function as follows:
function confirmSubmit(form) {
jConfirm('Modificar o Fornecedor?', 'Confirmação', function(confirmed) {
if (confirmed) {
form.submit();
}
}
}
I'd also suggest to use more self-documenting variable and function names like presented above, so that your code is easier understandable and maintainable in long term (not only for yourself, but also for others, for example the ones on Stackoverflow.com from who you expect an answer when you post a question...)