How to get text after an element in xpath? - xpath

I have the following code and I am trying to address or read "HERE", using xpath.I am programming java and using page.getFirstByXPath method:
...
<label item = "aaa">
<input class = "bbb"/>
<span class = "ccc">
<span/>
HERE
<label/>
...
Cheers

Try this
driver.findElement(By.xpath("//label[#item='aaa']")).getText();

Related

How to get HTML attribute value in Cypress

I am starting to learn Cypress after few years working with Selenium. In Selenium i'm regularly using GetAttribute() method. As an exercise i'm trying to do the same with Cypress, to print class attribute value from the following HTML element:
<input class="form-control ng-touched ng-pristine ng-valid" max="21" min="1" type="number">
This is my code:
cy.log(cy.get('input').invoke('attr', 'class'));
Output:
log Object{5}
I tried to use Lakitna cypress-commands (https://github.com/Lakitna/cypress-commands) with the code:
cy.log(cy.get('input').attribute('class'));
Output:
cy commands are asynchronous so for logging you need to use .then:
cy.get('input').then(($input) => {
cy.log($input.attr('class'));
});
or
// with assertion
cy.get('input').should('have.attr', 'class').then(cy.log);
If you are looking for the value of the html tag and you end up here, this is the simplest way to do that:
cy.get(`[data-testid="${key}"]`).then(($input) => {
if($input.prop('nodeName') === "SELECT") {
//Select corresponding input to value provided in dropdown lists
} else {
//Input each value provided into each field
cy.get(`[data-testid="${key}"]`).clear().should('have.value', '').type(testMachine[key]).should('have.value', testMachine[key])
}

How evaluating fields from nested object in thymeleaf template?

Given two objects:
public class MVCmodel {
UUID uuid;
NestedObject nestedObject = new NestedObject ();
}
public class NestedObject {
#Size(min = 2, max = 99)
String name = "";
}
thymeleaf template
<tr>
<td>
<input required="true" type="text" th:name="name"
th:value="${mVCmodel.getNestedObject.getName()}"
>
<span th:if="${#fields.hasErrors('name')}"
th:errors="${mVCmodel.getNestedObject().getName()}"
>Name Error
</span>
</td>
</tr>
I get this Error:
Exception evaluating SpringEL expression: "fields.hasErrors('name')"
SpringEL tries to evaluat mVCmodel.name and must fail because there is no field name in MVCmodel.
How to evaluate the field mVCmodel.nestedObject.name?
Your class NestedObject has no field named 'name'.
If you're not using in a form using th:object, you need to use #fields.hasErrors like this:
${#fields.hasErrors('${mVCmodel.nestedObject.name}')}
If you are using th:object, something like this should work:
${#fields.hasErrors('nestedObject.name')}
Difficult to tell from the code you posted. Do you have getters and setters for each of your fields?

How to create AJAX edit form in scala lift for one to many relationship?

I'm trying to create form to edit one to many relationship. I've created two classes:
class StudentGroup extends LongKeyedMapper[StudentGroup] with IdPK with OneToMany[Long, StudentGroup] {
object groupName extends MappedString(this, 20)
object students extends MappedOneToMany(Student,Student.studentGroup)
}
class Student extends LongKeyedMapper[Student] with IdPK {
object firstName extends MappedString(this,35)
object lastName extends MappedString(this,35)
object studentGroup extends MappedLongForeignKey(this, StudentGroup)
}
Then I created a snippet to display a group with following code:
val addStudentContent: NodeSeq = <div>
<input type="text" placeholder="First Name"></input>
<input type="text" placeholder="Last Name"></input>
</div>
def addStudent = AppendHtml("studentlist", addStudentContent)
def render =
"#addstudent" #> SHtml.ajaxButton("Add student", () => addStudent)
Now after clicking 'Add student' button two new fields appeared and I can put first and last name there. Problem is - how to store those data in database? Any hint?
Thanks
There are several ways you can begin to solve this problem. I never use Mapper myself, so there may be a much better way than what I am suggesting. However, something like the Ajax example in Simply Lift should get you started. Applying it to your code, we would get something like the following.
object StudentSnippets {
val addStudentContent: NodeSeq = <form data-lift="form.ajax">
<div data-lift="StudentSnippets.ajaxSubmit"> // Calls ajaxSubmit below
<input name="first" type="text" placeholder="First Name"></input>
<input name="last" type="text" placeholder="Last Name"></input>
<input type="submit" value="Submit"></input>
</div>
</form>
def addStudent = AppendHtml("studentlist", addStudentContent)
def render =
"#addstudent" #> SHtml.ajaxButton("Add student", () => addStudent)
private object first extends RequestVar("")
private object last extends RequestVar("")
def ajaxSumbit = {
"name=first" #> SHtml.text(first.is, first(_), "id" -> "the_name") &
"name=last" #> (SHtml.text(last.is, last(_)) ++
SHtml.hidden(ajaxProcess)) // Calls ajaxProcess below
}
def ajaxProcess = {
println("First is "+first.is)
println("Last is "+last.is)
Noop // This is the JS that will run after submit.
}
}
You can view another approach here on the wiki.
For more help with Lift, I strongly recommend posting your questions to the Lift Google Group. You will find that you get swarmed with Lift help more so than other forums such as SO.

Grails render template

I have this <g:formRemote> having this attributes,
<g:formRemote name="innerForm" id="innerForm"
url="[controller:'user', action:'actionAJAX']"
update="formMessage">
<div id="formMessage">Fill up the fields</div>
<g:render template="form" bean="${newUser}" />
<div class="buttons">
<g:submitButton name="Create User"/>
<input type="reset" value="Cancel"/>
</div>
</g:formRemote>
which upon submit procceeds to a closure having this lines of codes,
def actionAJAX() {
def userInstance = new User(params)
render(template:"error", bean:userInstance)
}
_error.gsp would contain scaffold display of bean error in which violates the domain constraints (nullable, blank, etc.). It would look like this:
<g:hasErrors bean="${userInstance}">
<ul class="errors" role="alert">
<g:eachError bean="${userInstance}" var="error">
<li <g:if test="${error in org.springframework.validation.FieldError}">data-field-id="${error.field}"</g:if>><g:message error="${error}"/></li>
</g:eachError>
</ul>
</g:hasErrors>
message
The problem is that I can't display the errors of the bean [def userInstance = new User] on the _error.gsp. The scenario was only to leave all of the fields of _form.gsp (having the contents of the generate-view and removing all required attribute) but upon submit the closure only returns message on the <div id="formMessage"> which was expected to display all the errors of the domain that violates the domain constraints.
If that is all of the code you are showing, your main problem is you are not calling .validate() or .save(). You must call either one to get errors in your object.
def actionAJAX() {
User userInstance = new User(params)
if ( !user.save() )
{
render(template:"error", model:[userInstance: userInstance])
}
else
{
render(template:"success", model:[userInstance: userInstance])
}
}
Just a quick look at the code, so maybe I'm missing one of many Grails conventions, but you are passing to the render method the userInstance with 'bean' as map key. And then referring to it as ${userInstance}. Try to refer it as ${bean} inside the templeta or pass it like:
render(template:"error", userInstance:userInstance)
It's not an answer for your question, just an additional tip: you can use g:renderErrors tag inside your error template or even instead of it.

Internationalized Labels for Form Components in Wicket

How do I correctly create internationalized labels for my form components so that when displaying feedback messages an internationalized field name is displayed instead of the name of the field in the java code?
I've read this:
https://cwiki.apache.org/WICKET/everything-about-wicket-internationalization.html
as well as the documentation for wicket's xhtml tags:
https://cwiki.apache.org/WICKET/wickets-xhtml-tags.html
<label wicket:for="name">
<wicket:label>
<wicket:message key="label.name"/>
</wicket:label>
</label>
<input wicket:id="name" type="text" wicket:message="placeholder:label.name" />
This results in the following error:
Last cause: Expected close tag for '<wicket:label>' Possible attempt to embed
component(s) '<wicket:message key="label.name"/>' in the body of this
component which discards its body
If I replace the wicket:message with some arbitrary text it displays the text in any associated feedback messages.
(There's a related jira issue: https://issues.apache.org/jira/browse/WICKET-3903 however I still do not understand what has been done to fix this and what I must do ...)
Just found out there is a way to do this in java:
add(new TextField<String>("name").setRequired(true).setLabel(new Model<String>(getString("label.name"))));
Is it possible to somehow do this in a more comfortable way?
I just tested the following:
<form wicket:id="form">
<label for="input"><wicket:message key="input">some input</wicket:message></label>
<input wicket:id="input" type="text" name="input">
<input type="submit" value="submit">
</form>
And in the java class:
Form<HomePage> form = new Form<HomePage>("form"
, new CompoundPropertyModel<HomePage>(this));
wmc.add(form);
TextField textField = new TextField("input");
textField.setRequired(true);
form.add(textField);
In the property file I provided:
input=SomeInputField
This led to the following screen (if I leave the requiered field empty and press submit.
Is this what you are looking for?
Here is an alternative approach to #bert's that has always worked for me (wasn't aware of <wicket:label>)
The text shown for a FormComponent when a validation error occurs can be specified by means of FormComponent.setLabel(IModel). The shown text will be the result of the IModel's getObject().
TextField comp = new TextField("comp");
// Use internationalized text from XML resource file
comp.setLabel(new StringResourceModel("formResources.comp.label", this, null));
Notice this has nothing to do with <label> nor FormComponentLabel. FormComponentLabel is a component that can be used to model <label> tags.
You could even subclass FormComponentLabel to provide the label text based on FormComponent.getLabel(), and maybe output an extra mark when the field is required:
public class MyLabel extends SimpleFormComponentLabel{
private boolean required;
public MyLabel (String id, LabeledWebMarkupContainer labelProvider) {
super(id, labelProvider);
if (labelProvider instanceof FormComponent){
required = ((FormComponent)labelProvider).isRequired();
}
}
protected void onComponentTagBody(final MarkupStream markupStream,
final ComponentTag openTag) {
String mark = "";
if (required){
// could be for instance "*"
mark = getString("formResources.requiredField");
}
String text = getModelObjectAsString() + mark;
replaceComponentTagBody(markupStream, openTag, text);
}
}
{
TextField component = new TextField("component");
component.setRequired(true);
component.setOutputMarkupId(true);
IModel labelModel = new StringResourceModel("formResources.component.label",
this, null);
component.setLabel(labelModel);
add(component);
add(new MyLabel("componentLabel", component);
}
<label wicket:id="componentLabel"/>
<input type="text" wicket:id="component"/>
This way you would have clean way of
Setting the FormComponent's text to an internationalized resource string
Reusing exactly the same resource string transparently for the <label> tag and even adding custom marks to it based on FormComponent's properties.
Another alternative is to use the key attribute of <wicket:label/>, like so:
<label wicket:for="name">
<wicket:label key="label.name">Placeholder label</wicket:label>
</label>
<input wicket:id="name" type="text"/>
Unfortunately this attribute is not documented on the wiki page describing wicket's xhtml tags. All attributes supported are documented using JavaDoc in the class handling the tag (org.apache.wicket.markup.html.form.AutoLabelTextResolver).
The advantage of this alternative is that there is no additional coding required.
Wicket throws an exception to tell you that your <wicket:message> tag will be removed because the body of the <wicket:label> tag is replaced. The problem is you cannot nest the <wicket:message> tag inside the <wicket:label> tag (and shouldn't need to).
either this (Option 1):
<label wicket:for="name">
<wicket:label key="label.name"/>
</label>
<input wicket:id="name" type="text />
or this (Option 2):
<label wicket:for="name">
<wicket:message key="label.name"/>
</label>
<input wicket:id="name" type="text />
should work for you and result in HTML something like the following (assuming the properties file contains label.name=Name):
<label for="someMarkupId">
Name
</label>
<input id="someMarkupId" type="text" />
The difference is that if you set the label for the component through the Java code like so:
component.setLabel(new Model("value set in code"));
then using the Option 1 will result in the label being set to "value set in code", while using Option 2 will still result in the label set to "Name". Also if the label is set through Java code, and the key is missing from the properties file the Option 2 will throw an exception, while Option 1 will simply use the value set in the code.
I prefer this:
<label wicket:for="name"><wicket:label />:</label>
<input type="text" wicket:id="name"></input>
Just make sure to set the label in the FormComponent using setLabel, so the only java needed is:
add(new TextField("name", nameModel).setLabel(Model.of("i18n.name")));
This will be rendered as (in Dutch):
<label id="name63-w-lbl" for="name63">Naam:</label>
<input type="text" value="" name="name" id="name63">

Resources