How to click on '+ Add to Friends' - watir

I am trying to click on '+ Add to Friends'.
browser.div(:class, "+ Add to Friends").click and browser.div(:text, "+ Add to Friends").click
But get: Element is not currently visible and so may not be interacted with
<div data-friend="5004" onclick="return {'b-profileFriendsButton': {'friend': '5004' }}" class=" b-profileFriendsButton_mode_0 i-bem b-profileFriendsButton_js_inited">
<div class="b-profileFriendsButton__text b-profileFriendsButton__text_mode_2">Friends</div>
<div class="b-profileFriendsButton__hover b-profileFriendsButton__hover_mode_2 b-profileFriendsButton__deleteFromFriends">– Delete From Friends</div>
<div class="b-profileFriendsButton__text b-profileFriendsButton__text_mode_1">Friends</div>
<div class="b-profileFriendsButton__hover b-profileFriendsButton__hover_mode_1 b-profileFriendsButton__deleteFromFriends">– Delete From Friends</div>
<div class="b-profileFriendsButton__text b-profileFriendsButton__text_mode_0 b-profileFriendsButton__addToFriends">+ Add to Friends</div>
<div class="b-profileFriendsButton__hover b-profileFriendsButton__hover_mode_0 b-profileFriendsButton__addToFriends">+ Add to Friends</div>
</div>

There is no <div> tag with a class attribute of "+ Add to Friends", so browser.div(:class, "+ Add to Friends").click shouldn't work at all. To use a :class locator in this case, you'd do something like this:
browser.div(:class, "b-profileFriendsButton__text b-profileFriendsButton__text_mode_0 b-profileFriendsButton__addToFriends").click
And there are 2 <div> tags containing a "+ Add to Friends" text string, so a compound locator using :text and :index should help identify the correct one. For example:
browser.div(:text => "+ Add to Friends", :index => 0).click
Lastly, try using the when_present method to wait for page elements to become fully enabled:
browser.div(:text => "+ Add to Friends", :index => 0).when_present.click

Please try this.
Since we have two +Add to friends. Use Regular expression and index properties to click.
browser.div(:class=>/addToFriends/, :index=>0).click
browser.div(:class=>/addToFriends/, :index=>1).click

Here is the solution:
browser.div(:class => "b-profilePage__button").click
browser.div(:class => "b-profileFriendsButton__hover b-profileFriendsButton__hover_mode_0 b-profileFriendsButton__addToFriends").click

Related

how to click on edit a button in front of Particular text in Cypress

I want to click on the edit button in front of if found Yes in the third column(Yes is also have botton)
element
I was using below code in test case but didn't work
`cy.get(':nth-child(6)').contains('Yes').within(() => {
cy.get('.btn.btn-xs.btn-edit').click()
})
or
`cy.get(':nth-child(6)').contains('Yes').find(button).eq(1).click()
HTML Table Structure
<tr role="row" class="even">
<td class="sorting_1">
abc
</td>
<td>xyz</td>
<td>aws</td>
<td>No</td>
<td>No</td>
<td>"Yes"
<button data-role="remove" id="support_22_abc" class="btn btn-rejecttxt" onclick="deletevm(this,'3','3:5659','22','abc','22_abc','284')"><i class="fa fa-times-circle" data-original-title="Remove Mapping" data-toggle="tooltip"></i></button></td>
<td>No</td>
<td>
<div class="btn-group">
<a href="http://192.168.0.1:8080/edit">
<button class="btn btn-xs btn-edit">
<i class="fa fa-pencil" data-original-title="Edit/Update row data" data-toggle="tooltip" data-placement="top"></i></button></a>
</div></td></tr>
If I'm reading it correctly, you want the 3rd <td> after the one with "Yes ".
Not sure what :nth-child(6) is selecting, but try this
cy.contains('td', 'Yes')
.siblings()
.eq(6) // 6th sibling
.find('button.btn.btn-xs.btn-edit')
.click()
Assuming .btn.btn-xs.btn-edit is the correct selector for edit button. You can directly use the eq command to click the edit button on the third row.
cy.get('.btn.btn-xs.btn-edit').eq(2).click()
Based on the available info, I came up with this. Here we are looping through the all the tr first and then using within we are scoping the next commands inside the same tr. Now using eq(5) we are searching for the Yes button, and if we found the it, then we click the Edit button.
cy.get('tr').each(($ele) => {
//Loop through all tr
cy.wrap($ele).within(() => {
//scope the next commands within the same tr
cy.get('td')
.eq(5)
.invoke('text')
.then((text) => {
//here eq(5) gets the sixth td element in the row
if (text.includes('Yes')) {
cy.get('.btn.btn-xs.btn-edit').click()
}
})
})
})

geb cant find checkbox element

there is this piece of code that provides a checkbox following from a link to the T&C.
<div class="checkbox accept_agreement">
<label class="control-label" for="step_data_accept_agreement">
<input type="hidden" name="step_data[accept_agreement]" value="0">
<input type="checkbox" name="step_data[accept_agreement]" id="step_data_accept_agreement" value="1">
<label for="step_data_accept_agreement">
<a target="_blank" href="/lanevillkor/">
<font><font>I agree, have read and stored the terms and conditions</font></font>
</a>
</label>
</label>
</div>
Now, I am working on a spock test using geb, and I try to retrieve the checkbox element
<input type="checkbox" name="step_data[accept_agreement]" id="step_data_accept_agreement" value="1">
to do so i have tried many things without the expected output. i was expected that something like
$("#step_data_accept_agreement").click() would be pretty straight forward but it is not. in the other side if I put $("[for='step_data_accept_agreement'] label").click() it clicks the link.
I tried to become as more specific but nothing looks to return the element correctly.
one of my last attempts was
termsAndConditionsOption(wait: true) { $("#step_data_accept_agreement", name: "step_data[accept_agreement]") }
and the error message, as in the other cases too, was in one sentence
element not visible
What do I miss?
So the solution was to use js to click the checkbox. The simpliest way is:
def agreeOnTermsAndConditionsAccept() {
String mouseClickEvt = """
var evt = new MouseEvent('click', {
bubbles: true,
cancelable: true,
view: window
});
arguments[0].dispatchEvent(evt);
"""
browser.js.exec(termsAndConditionsOption.firstElement(), mouseClickEvt)
}
Geb provides js support to work with javascript, as we find in the documentation. Also another link shows how to simulate a click event with pure javascript.
This was required as the checkbox cant be found as it is hidden. With javascript we can 'see' the position of the element and perform an action in the location that we want. iniMouseEvent can be used as well as it is documentanted here

Cannot find a way to tap() this element (wd,nodejs)

I have a DOM like this:
<form id="frmResendPassword" role="form" method="post">
<div class="form-group">...</div>
<span class="pull-right">
<button type="submit" class="btn btn-sm btn-default">
Resend Password</button>
</span>
</form>
I want to tap the "Resend Password" button.
I have tried many different selectors such as:
elementByClassName("btn-default")
elementById("frmResendPassword")
elementByName("Resend Password")
elementByCss(thecsspath)
ect.... none of them perform the tap()...
however they do not throw a element not found error....
so im confused. can some one please help
update:
Here is the basic automation code... its very basic
it("should send text to phone", function(){
sleep.sleep(5)
return browser
.elementByName("mobileNo")
.sendKeys(usrnme)
.elementByCss("#frmResendPassword button[type=submit]")
.tap()
})
It types the mobile number in fine, however it seems to just ignore pressing the button.
My guess is that the selector is the problem. Try this:
elementByCss("button[type=submit]")
or if that doesn't uniquely identify it, maybe this:
elementByCss("#frmResendPassword button[type=submit]")
In English that means a button with type value of submit that has an ancestor of a form where the id(#) is frmResendPassword
This is how I solved it, thanks to mrfreester
it("should send text to phone", function(){
sleep.sleep(5)
return browser
.elementByName("mobileNo")
.sendKeys(usrnme)
.elementByCss("#frmResendPassword button[type=submit]")
.click()
})

MVC 5 / Bind dropdownlist including disabled values

(My first quesion, I'm quite impressed :) )
First, please excuse my English, I'm French ;)
My issue is about DropDownList which is linked(bind) to a required field (F, int) of an object O (edited in a view V) and contains a list of elements (LE), some of them disabled.
The behavior I want in the view :
when I create an object, the validation must trigg if nothing
is selected in the list (OK)
when I create an object, the disabled elements of the list must not be selectable (OK)
when I edit an object, if the field is among enabled values, same behavior (OK)
when I edit an object, if the field is among disabled values, it must be displayed and selected when viewed (OK)
when I edit an object, if the field is among disabled values, when I post data, the client validation must authorize disabled values to be validated (OK with a little javascript)
My issue :
when I edit an object, if the field is among disabled values, when I
post data, the model contains null for the field linked to the
dropdownlist even if I include an hidden field with the Id.
Here is some of my code to help understand my issue.
Any idea of how I could include disabled values of my dropdown list in the model when I post data ?
Thanks for any help !
View :
<div class="col-md-3">
#Html.DropDownListFor(model => model.Currency.Id, (SelectList)ViewBag.Currencies, new { #class = "form-control ignore-desactivated" })
#Html.ValidationMessageFor(model => model.Currency, "", new { #class = "text-danger" })
</div>
JS :
$(function () {
$('form').validate().settings.ignore = '.ignore-desactivated';
});
Source when edition :
<div class="col-md-3">
<select class="form-control ignore-desactivated" data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="Currency_Id" name="Currency.Id">
<option value="-1"></option>
<option disabled="disabled" value="9">Angolan kwanza (desactivated)</option>
<option value="10">Argentine peso</option>
<option disabled="disabled" selected="selected" value="1">Euro (desactivated)</option>
<option disabled="disabled" value="56">Gibraltar pound (desactivated)</option>
<option value="3">Great Britain Pound</option>
</select>
<span class="field-validation-valid text-danger" data-valmsg-for="Currency" data-valmsg-[replace][1]="true"></span>
</div>
My model when I want to save data :
https://i.stack.imgur.com/jQ9aH.png
... and I found an answer a few minutes after asking it (thanks to my colleagues)...
I don't know if that's correct, but a little js code to remove disabled items before the post did the trick :
//Delete disabled elements of lists before submit
$('form').submit(function () {
$('.ignore-desactivated').each(function () {
$(this).children().each(function () {
$(this).removeAttr('disabled');
});
})
})

How to edit a custom DisplayWithIdFor?

I have created a DisplayWithIdFor using the following code and it works showing the information I wish it to.
public static class DisplayWithIDHelper
{
public static MvcHtmlString DisplayWithIdForApplication<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string wrapperTag = "div")
{
var id = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression));
return MvcHtmlString.Create(string.Format("<{0} style=\"color: #003F51; margin-left: 87px;\" class=\"{1}\">{2}</{0}>", wrapperTag, id, helper.DisplayFor(expression)));
}
}
My problem is simple, when I use the custom helper I end up with the label saying Application and the displayfor holding the name of the application showing with no space between them. see below.
Lastly here is the code for the image above:
<form>
<fieldset>
<p>
#Html.LabelFor(model => model.changeStatus.usersName)
#Html.DisplayFor(model => model.changeStatus.usersName)
#Html.HiddenFor(model => model.changeStatus.usersName)
#Html.ValidationMessageFor(model => model.changeStatus.usersName)
</p>
<p style="display: inline; float: left">
#Html.LabelFor(model => model.changeStatus.application)
#Html.DisplayWithIdForApplication(model => model.changeStatus.application)
#Html.HiddenFor(model => model.changeStatus.application)
#Html.ValidationMessageFor(model => model.changeStatus.application)
</p>
<p>
#Html.LabelFor(model => model.changeStatus.reasons)
#Html.TextAreaFor(model => model.changeStatus.reasons, new { #cols = "80", #rows = "4", #class = "k-textbox" })
<span style="color: red;"> #Html.ValidationMessageFor(model => model.changeStatus.reasons)</span>
</p>
<!-- Allow form submission with keyboard without duplicating the dialog button -->
<input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
</fieldset>
</form>
Can anyone explain how to add the spacing between the two Html Helpers?
any additional code can be supplied like the Jquery popup code.
Thank you.
Edit:
Just to make things a little clearer I have to get the application name from the row of a kendo grid that is selected and set the name in the jquery using the following code:
$("div[class='changeStatus_application']").html(applicationName);
To simplify and ensure everything is acting the same, remove the:
style="display: inline; float: left"
from the second paragraph tag and use an element like a span instead of a div (block level element) in your helper.
You may then want to alter the margin left on your DisplayWithIDHelper.
Also try using classes instead of style attributes. You can then change the look of your site through your style sheet without having to recompile plus styles are centralised; easier to maintain.

Resources