Select a button on the form of a webpage - xpath

I am trying to click on upload button which is inside a <form> tag.
I am using java with selenium. I tried with xpath locator to click on button but unable to identify it.
Html Code:
<form id="sportForm" action="/sportmetadata/saveSport" method="post" enctype="multipart/form-data">
<table>
<tr class="hidden">
<td class="lbl-dialog">Id</font></td>
<td>
<td class="lbl-dialog width200" >Background for Team </td>
<td>
<input type="button" class="btn btn-default btn-command btn-upload" value="Upload" onClick="openFileBrowser('sp_backgroundUploadId')" />
<input id="sp_backgroundUploadId" multiple type="file" class="no-display" name="backgroundUpload" />
<input id="backgroundDelesectUpload" value="Clear" type="button" onclick="clearSelection('sp_backgroundUploadId','sp_backgroundDisplayTableId');" class="btn btn-default btn-command btn-upload" />
</td>
</tr>
Please help
Thanks in advance

Locate Upload button using xpath locator.
//input[#value='Upload'][#type='button']
Explanation:- Use value and type attribute of <input> tag.
Suggestion:- Instead of using absolute xpath, use relative xpath.
OR
Locate Upload button using cssSelector
input[value='Upload'][type='button']
Explanation:- Use value and type attribute of <input> tag.

You should try to avoid XPATH directly copied from browsers as they are not stable ones. When I copy xpath from my browser with the same HTML code I get
//*[#id="sportForm"]/table/tbody/tr/td[4]/input[1] which is different from what you have posted
You should build your xpath more intellegently
This should work
//input[#type='button' and #value='Upload']

You can use cssSelector to identify as follows:
driver.findElement(By.cssSelector("#sportForm > table > tr td:nth-child(3)>input"))

Related

Thymeleaf generates URL with no query parameters, but '?' appears

I'm working on a simple Spring Boot MVC application using Thymeleaf.
Part of the thymeleaf code:
<tr th:each="dept: ${departments}">
<td th:text="${dept.getId()}"></td>
<td th:text="${dept.getName()}"></td>
<td>
<form th:object="${dept}" th:action="#{'/departments/' + ${dept.getId()}}">
<button class="btn btn-secondary">Details</button>
</form>
</td>
<td>
<form th:object="${dept}" th:action="#{/departments/{id}/edit(id=${dept.getId()})}">
<button class="btn btn-secondary">Edit</button>
</form>
</td>
<td>
<form th:object="${dept}" th:action="#{/departments/{id}(id=${dept.getId()})}" th:method="delete">
<button class="btn btn-secondary">Delete</button>
</form>
</td>
</tr>
The UI interface looks like this:
When clicking on the Edit button (same goes for the Details one), it loads correctly, but the URL generates the ? character for other query parameters, but there are actually none (for example http://localhost:8089/departments/3/edit?).
The controller code is:
#GetMapping("/{id}/edit")
public String editDepartment(#PathVariable("id") String departmentId, Model model) {
var department = departmentService.getDepartmentById(Long.valueOf(departmentId));
model.addAttribute("department", department);
return "edit-department"; // returns view
}
My problem is with the ? character that is being displayed. I don't want it to appear as there are no query parameters. Any help?
It's adding a question ? because you are submitting an empty form. Why not just use a link styled as a button?
<a class="btn btn-secondary" th:href="#{/departments/{id}/edit(id=${dept.id})}" role="button">Edit</a>
Try
<form th:object="${dept}" th:action="#{/departments/edit/{id}(id=${dept.getId()})}">

How to filter data in Thymeleaf table

I'm a new Thymeleaf developer (Spring-Boot 2.1.5 environment).
I want to implement filtering over a list from an Input. When I enter the name of the client in the input it appears on a table (without submit button).
<form th:action="#{/clientslistbypage}" method="get" th:object="${Clients}" class="form-inline" >
<input type="text" name="client" th:value="${client}" id="clientSearch" >
<!-- <input type="submit" name="clients" th:value="Search">-->
</form>
I tried the Projection and Collection function but I do not know how to dynamically assign the input value to the Collection formula.(${Clients.?[firstName >='here i want to insert the value of the Searche Input']})
<tr th:each = "c: ${Clients.?[firstName >='']}" >
<td th:text = "${c.id}"></td>
<td th:text = "${c.firstName}"></td>
<td th:text = "${c.LAST_NAME} "></td>
</tr>
I tried DANDELION but unfortunately, do not run under Spring-Boot 2.1.5.
any proposal, tutorial, or example is welcome

Uploading file by label tag in capybara

I have problem uploading file by using capybara and cucumber.
The HTML is the following
<div class="dyn-crm-upload-btn-container">
<label class="btn btn-primary btn-sm" data-bind="visible: newCrmBtnEnabled, enabled: fileEditEnabled">
<i class="fa fa-plus"></i>
<span data-bind="i18n:panels.partnerCrm.new" data-i18n="panels.partnerCrm.new">NEW</span>
<input id="dyn-crm-file-input" class="dyn-crm-upload-btn" type="file" name="file" accept=".csv" data-bind="events: { change: setFileToNewName }"></label>
</div>
And if I have manualy choosed a file, the HTML is following in a new div
<div data-bind="visible: fileUploadVisible" class="dyn-crm-file-upload" style="">
<input type="text" data-bind="value: fileToUpload.name, i18n:[placeholder]panels.partnerCrm.fileUpload.enterName" maxlength="20" class="k-textbox dyn-crm-filename" id="dynCrmFilename" data-value-update="keyup" data-i18n="[placeholder]panels.partnerCrm.fileUpload.enterName" placeholder="File name">
<input type="button" data-bind="click: uploadFileCrmFile,i18n:[value]panels.partnerCrm.fileUpload.upload" value="Upload" class="btn btn-primary" data-i18n="[value]panels.partnerCrm.fileUpload.upload"><div class="file-upload-progress-container">
</div>
I have tried this
attach_file(find('file',:visible=>false),File.absolute_path('C:/Users/user/test.csv'))
And this
attach_file('file',File.absolute_path('C:/Users/user/test.csv'))
And some other variations, but I get the following error
Unable to find file field "file"
Or when using id
Unable to find file field "dyn-crm-file-input"
Also I have tried to execute some scripts before attach_file upload.
I'm using
cucumber 2.1.0
ruby 2.1.6
nokogiri 1.6.6.2
capybara 2.4.4
selenium-webdriver 2.47.1
Thanks in advance :)
EDITED
Here is the link for the css picture:
css picture.
As I imagined, you will have to use jQuery to change the display:none of your element to display:block, for example.
To achieve tis, you can try with this just before attaching the file:
page.execute_script("$('.dyn-crm-upload-btn-container').css('display','block')")
Capybara generally can't call attach_file on a non visible file input. To work around this you need to use #execute_script to modify the file inputs css so it becomes visible on the page and then use attach_file on it.

Form Submit using a Javascript to invoke webflow transition, doesn't take the updated value on form

I am trying to invoke a form submit using javascript (jquery) to invoke a webflow transition. It works and the submit invokes the desired transition. But, the updated radio button values is not reflected on the model object which is posted.
Here is the code:
<form:form method="post" action="#" commandName="infoModel" name="pageForm">
<form:input type="input" path="testMsg" id="success" />
<input type="button" id="clearSelections" value="Clear Selections">
<div class="question">
<h4><c:out value="${infoModel.questionInfo.description}"/> </h4>
<form:radiobuttons path="infoModel.answerId"
itemValue="answerId" itemLabel="answerDescription" items="${infoModel.answers}" delimiter="<br/>" />
</div>
<input type="submit" name="_eventId_saveQualitativeInput" value="Save" id="save" />
$(document).ready(function() {
$('#tabs').tabs();
//Clear selections (copy is server-side)
$('#clearSelections').click(function() {
//$('input[type="radio"]').prop('checked', false);
$('input[type="radio"]').removeAttr('checked');
$('#save').trigger('click');
});
});
</form:form>
The form:radiobutton, generates the below html:
<div class="question">
<h4>Is this a general obligation of the entity representing a full faith and credit pledge? </h4>
<span>
<input type="radio" checked="checked" value="273" name="infoModel.answerId" id="infoModel.answerId1">
<label for="infoModel.answerId1">Yes</label>
</span>
<span><br>
<input type="radio" value="274" name="infoModel.answerId" id="infoModel.answerId2">
<label for="infoModel.answerId2">No</label>
</span>
<br>
<span class="error"></span>
</div>
The input id= "success" value is registered and when the control goes to the server, the value of input id= "success" is updated in the "infoModel" object. But the value of answerId is not updated on the "infoModel" object.
Thoughts if i am missing something in the form:radiobutton element or if there is something else wrong?
Thanks in advance!
EDIT:::::::
Thanks mico! that makes sense. I stripped of some of the code first time to make it precise, but i have a list which is being used for building the radio-buttons, below is the code:
<c:forEach items="${infoModel.list["index"]}" var="qa" varStatus="rowCount">
<div class="question">
<h4><c:out value="${question.questionInfo.description}"/> </h4>
<form:radiobuttons path="list["index"][${rowCount.index}].answerId" itemValue="answerId" itemLabel="answerDescription" items="${question.answers}" delimiter="<br/>" />
<br>
</div>
</c:forEach>
Could you please suggest how i could try this one out?
NOTE: The same code works on a regular form submit on click of a button of type submit. Its the javascript form submit which is not working. I also tried to do whatever i want to do in javascript and then invoke the button.trigger('click'); form got submitted but the changes made on form in my javascript didnt reflect.
With commandName inside a form:form tag you set "Name of the model attribute under which the form object is exposed" (see Spring Documentation). Then in path you should tell the continuation of the path inside the model attribute.
With this said I would only drop the extra word infoModel from path="infoModel.answerId" and have it rewritten as path="answerId" there under the form:radiobutton.

How to edit a list of child entities in Spring 3 MVC

How would I edit an entity with child rows in Spring 3 MVC?
I'd like a form like:
<forms:form>
<p>Parent name <forms:input path="model.name" type="text" /></p>
<p>Children:
<ul>
<s:foreach in="${model.children}" var="${child} varStatus="row">
<li>
name: <forms:input path="model.children[${row.index}].name" />
<button name="?">delete</button>
</li>
</s:foreach>
</ul>
</p>
<p><button name="?">add child</button></p>
</forms:form>
I'm having a lot of trouble getting this to work in Spring 3.
I would love to be able to:
edit child properties inline on the parent's form, with validation etc.
delete children inline on the parent's form
add children inline on the parent's form
Have you checked out jqGrid?
If you want DIY, then have a nested loop and create the crud links in the inner loop.
An HTML table might be appropriate for presentation.
Here is part of the "child" loop.
<tbody style="background: #ccc">
<c:forEach items="${parent.children}" var="work">
<tr>
<td>${work.id}</td>
<td>${work.title}</td>
<spring:url var="editWorkUrl" value="/work/edit/${work.id}" />
<spring:url var="deleteWorkUrl" value="/work/delete/${work.id}" />
<td>Edit
</td>
<td>Delete
</td>
</tr>
</c:forEach>
</tbody>

Resources