Selenium how to access two controls of same css class - css

I am doing testing using selenium ide.
My objective is to verify the following
1) Max and Min length property of text boxes.
2) Verify the texts of the labels
My html code is as below:
<div class="control-group">
<label class="control-label" for="input01">Email</label>
<div class="controls">
<input name="data[Salon][username]" class="span4" id="username" placeholder="Username or Email" type="text"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="input01">Password</label>
<div class="controls">
<input name="data[Salon][password]" class="span4" id="password" placeholder="Required" type="password"/>
</div>
But in the above I am facing following problems:
a) I have problem in accessing the labels for assertText or assertElementPresent since they are having same class name.
b) I don't know how verify the Max and Min length property of the Text boxes.
And please note that when I am trying to use
document.getElementsByClassName("control-label")
I am getting the following error:
[error] locator not found: document.getElementsByClassName("control-lable"), error = TypeError: e.scrollIntoView is not a function

You can access first label via:
css=div[class='control-group'] label[class='control-label']:contains('Email')
You can access second lavel via:
css=div[class='control-group'] label[class='control-label']:contains('Password')
Use these with command assertElementPresent, "contains" in element locator allows you to verify text in it.
Also you can use xpath:
//div[#class='control-group']//label[#class='control-label'][text()='Email']
//div[#class='control-group']//label[#class='control-label'][text()='Password']
Usually maxlength property is set as attribute of the input, but i can't see it in your html code.. But you can try:
storeAttribute (Selenium IDE's command) and as target you can use xpath:
/div[#class='control-group']//label[#class='control-label'][text()='Email']/#maxlength save it to some var (eg set to the value field smthg like attLength) and then echo this var like: Selenium IDE's command echo and as put to the target field ${attLength}

Related

How to create textbox with fixed label in Material Design Lite?

When I was reading the documentation in Material Design Lite's official page, no class name is mentioned for the fixed label with a textbox. In case of textarea they have a solution. But same code like the following one is creating only placeholder instead of a label for input type = "text".
<div class="mdl-textfield mdl-js-textfield">
<input class="mdl-textfield__input" type="text" id="sample5">
<label class="mdl-textfield__label" for="sample5">Text lines...</label>
</div>
I haven't seen this documented anywhere but it was annoying me so I delved into the SCSS to see what I could do. No changes to CSS are required. I managed to solve it by doing the following:
Add the mdl-textfield--floating-label has-placeholder classes to the outer <div> element.
Add a placeholder attribute to the <input> element, it can contain a value or remain empty; either way it will still work.
This will force the label to float above the input, instead of acting as a placeholder.
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label has-placeholder">
<input class="mdl-textfield__input" type="text" id="sample5" placeholder="">
<label class="mdl-textfield__label" for="sample5">Text lines...</label>
</div>

ASP.NET Core using two models in single form

I am using Tuple to pass two models inside the view like code given below.
#model Tuple<AdvanceSearchModel, List<SearchUserModel>>
<form role="search" method="post" action="/Public/AdvanceSearch">
<div class="form-group">
<label>Name</label>
<input name="FullNames" type="text" class="form-control" value=""/>
</div>
<div class="form-group">
<label>Product</label>
<input name="Products" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label>Location:</label>
<input name="Location" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label>State</label>
<input name="States" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label>Country</label>
<input name="Countries" type="text" class="form-control" value=""/>
</div>
</form>
All the name attributes inside inputs are of AdvanceSearchModel. How do I use tag helper such as asp-for when passing multiple model to the views containing one or multiple forms? Also how do I retain values of the form after submitting the form in above scenario?
As you can see in the source code of InputTagHelper
You can see it creates the name attribute based on the (lambda) expression in html-tag:asp-for.
what you need
You need a form name tag like this SearchUserModel[0].Location
Where:
SearchUserModel is the property name on the model which is in the controller method you post to
[0] is the index in the list
Location is the property on the iten in the list the SearchUserModel instance
My suggestion
Not to do
Extend the InputTagHelper and add a prefix option (which adds a prefex to the name).
Use a view model Not a tuple!
Create a partial view that only takes SearchUserModel + a prefix (like an int for which row in the list it is for example: usermodel[1])
In your view loop over the list and call the partial.
result
#model SearchUserModel
<input asp-for="Location" my-prefix="ListItem[#Model.Id]" class="form-control" />
Better longterm option
Make a HTML template on how SearchUserModel part of the form should look.
Do ajax call to get the data or put the data as json in your view. (or take step 3 from what not to do)
Generate the form with well structured javascript.
On submit Instead of submitting the form, parse the from to json and send this as json ajax call.
Why do i say this? It is easier to debug if you get weird databindings in your controller.
That said, option 1 is perfectly fine but it might lead to problems later, as it is very static template, you wont be able to add or remove rows easily.
References for proper html name tags for lists:
http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx
How does MVC 4 List Model Binding work?

How to select an element by refrencing the inside element of a nested class

For this html code, I want to select an element using CSS.
I need to select "Cvv2 required" by referencing validatedMessage. I was thinking of trying .validateMessage + .Cvv2.required .However, that didn't work. It seems "Cvv2 required" is after "CCNumber required". But I need to reference "validatedMessage" which is inside "CCNumber required". I don't even know thats the proper jargon to explain this relationship....
<div class="CCNumber required">
<label id="label">Credit Card Number:</label>
<input name="test" type="text" class="wrong">
<span class="validatedMessage">Required</span> <br>
</div>
<div class="Cvv2 required">
<a> What's this</a><br>
</div>
This is not currently possible with pure CSS.
You are looking for some kind of "contains" query, which is not available.
https://css-tricks.com/child-and-sibling-selectors/#article-header-id-4

Fetching the value of a mdl-textfield

I have the following mdl-textfield:
<div class="mdl-textfield mdl-js-textfield" id="step_condition">
<textarea class="mdl-textfield__input" type="text" rows="25"> </textarea>
<label class="mdl-textfield__label" for="step_json">Step condition</label>
</div>
To set the value of the field I use:
$("#step_condition").get(0).MaterialTextfield.change('100');
My questions are:
is this the correct way of setting the value of the field?
is there a similar way to fetch the value of the field?
I know I can fetch the value directly from the textarea, but somehow it seems to make more sense to use the API.
You should add an id to the textarea itself, like:
<div class="mdl-textfield mdl-js-textfield" >
<textarea class="mdl-textfield__input" type="text" rows="25" id="step_json"></textarea>
<label class="mdl-textfield__label" for="step_json">Step condition</label>
</div>
Look at the example on the official specifications, there is no id at the div level. http://www.getmdl.io/components/index.html#textfields-section
To set up the value of the field you could do
$("#step_json").val("100");
However you will have to deal with the fact that the label is not removed automatically. This post should help: https://github.com/google/material-design-lite/issues/903

Can't find element using xpath

So, here are two divs
<div class="th_pr"><input id="user_email" class="accounts_input" type="text" size="30" placeholder="Email" name="user[email]"></input><p class="accounts_error_text" style="display: block;">
email is invalid
</p></div>
<div class="th_pr"><input id="user_password" class="accounts_input" type="password" size="30" placeholder="Password" name="user[password]" autocomplete="off"></input><p class="accounts_error_text" style="display: block;">
password can't be blank
</p></div>
I need to get those elements with texts "email is invalid" and "password can't be blank" by text, cause it will differ depending on input.
I've been trying to complete this using xpath :
By.xpath("//p[contains(.,'email is invalid')]")
and
By.xpath("//p[contains(.,'password be blank')]")
but i get nothing.
resultEmail = ExpectedConditions.invisibilityOfElementLocated(By.xpath("//p[contains(.,'email is invalid')]")).apply(driver);
returns true, although the element is visible.
Please help.
Try xpath
//input[#id='user_email']/following-sibling::p
//input[#id='user_password']/following-sibling::p
Then you have
WebElement emailParagraph = driver.findElement(By.xpath("//input[#id='user_email']/following-sibling::p"));
System.out.println(emailParagraph.getText());
Did you try using the text() method within the xpath?
driver.findElement(By.xpath("//p[contains(text(), 'email is invalid')]"));
Rather than using the .?
Please try this:
WebElement userEmailErrorMessage = driver.findElement(By.cssSelector("div[class=\"th_pr\"]:nth-child(1) > p"));
WebElement userPasswordErrorMessage = driver.findElement(By.cssSelector("div[class=\"th_pr\"]:nth-child(2) > p"));
Using these elements you will be able to read the error messages for the respective input controls.

Resources