Click on element with capybara - ruby-on-rails

I have a yes/no slider on a web page that i need to interact with. I need to click on one of the elements so that the value changes from true to false or false to true. Using the id i can get the value of the element with
find_field('passcode_policies__allow_simple').find('option[selected]').value
But i have tried over and over to simulate a click on this object to change the value and have been unsuccessful.
<div class="control-group">
<select class="toggle" id="passcode_policies__allow_simple" name="passcode_policies[][allow_simple]" style="display: none; " tabindex="-1">
<option value="true" selected="selected">Yes</option>
<option value="false">No</option>
</select>
<div class="ui-switch off" tabindex="0">
<div class="ui-switch-mask">
<div class="ui-switch-master" style="left: -38px; ">
<div class="ui-switch-upper">
<span class="ui-switch-handle" style="left: 33px; "></span>
</div>
<div class="ui-switch-lower">
<div class="ui-switch-labels">
Yes
No
</div>
</div>
</div>
</div>
<div class="ui-switch-middle" style="width: 60px; ">
</div>
</div>
<label class="inline">Allow simple value</label>
<span class="help-block">Permit the use of repeating, ascending, and descending character sequences</span>
</div>

If you're using Selenium, headless webkit or phantomjs (poltergeist gem) you should be able to call the simple
click_link 'Yes'
but if you're just using straight up capybara you will have to interact with the select element with something like
select('Yes', :from => 'passcode_policies__allow_simple')
and you can check the visibility and whatnot with this capybara: page.should have_no_content doesn't work correctly for display:none element

Working solution:
within(:css, '#passcode_policies__allow_simple + .ui-switch') do
click_link 'No'
end

Related

Going through a dropbox in Capybara?

I have a drop down menu. I want capybara to go through it and find the specific element and click on it. I'm currently trying to do a within clause and having it iterate through the list and find this element: "Cow_poop"
<div class="ant-select-selection ant-select-selection--single" role="combobox" aria-autocomplete="list" aria-haspopup="true" aria-controls="7256666c-da5f-48d6-c8fc-a249a4ed0fc9" aria-expanded="false" tabindex="0">
<div class="ant-select-selection__rendered">
<div class="ant-select-selection-selected-value" title="cow_poop" style="display: block; opacity: 1;">cow_poop</div>
<div class="ant-select-search ant-select-search--inline" style="display: none;">
<div class="ant-select-search__field__wrap">
<input autocomplete="off" class="ant-select-search__field" value="">
<span class="ant-select-search__field__mirror"> </span>
</div>
</div>
</div>
<span class="ant-select-arrow" unselectable="on" style="user-select: none;">
<i aria-label="icon: down" class="anticon anticon-down ant-select-arrow-icon">
<svg viewBox="64 64 896 896" focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true">
<path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path>
</svg>
</i>
</span>
</div>
So in this html tag. I have a dropdown menu and I'm trying to select the value cow_poop. The way I'm currently doing it is this way.
within('ant-select-selection') do
find('cow_poop').click
end
The problem with this method is that it's not working.
. is missing before the class name, it should be
within('.ant-select-selection')
You can also use:
within('.ant-select-selection') do
find('div.ant-select-selection-selected-value', text: 'cow_poop').click
end
Alternative
find (:xpath, "//div[text()='cow_poop']").click

Rails Capybara fill in angular form without id and name on fields

For a very specific use case, after a transaction I need to login into another system (build with Angular) to fill in a form. Login works OK, navigating to the correct link to create a new record showing the modal form works. Now there is a field I need to enter which autopopulates a list in style of
<ul>
<li><a class="ng-scope ng-binding"><strong>AAA</strong></a></li>
<li><a class="ng-scope ng-binding"><strong>BBB</strong></a></li>
</ul>
None of the UL, LI, or A elements have an id or a name. How can I select the first option from the LI?
rails 5.2
capybara
selenium
html snippet of the page
<form id="addedit-transfer_form" class="form-horizontal form-condensed ng-scope ng-invalid ng-invalid-required ng-dirty" ng-controller="RepeaterCtrl">
<!-- ngRepeat: line in repeaterLines --><table class="table table-striped table-condensed ng-scope" ng-repeat="line in repeaterLines">
<tr class="offset1">
<td>
<input name="model[0][Destinations][0][ShipmentLicenseType]" type="hidden" value="Licensed">
<div class="control-group">
<label class="control-label"><strong class="ng-binding">Destination 1</strong></label>
<div class="controls">
<div class="input-append">
<input autocomplete="off" class="js-validated-element validate[required] ng-dirty ng-invalid ng-invalid-required" placeholder="Type part of the License Number..." required="" spellcheck="false" type="text" ng-model="destination.RecipientId" typeahead="facility.Id as facility.LicenseNumber + ' | ' + facility.FacilityName for facility in preload.repeaterData.DestinationFacilities | orderBy:'LicenseNumber' | filter:$viewValue | limitTo:10" typeahead-editable="true" ng-blur="globalMethods.typeaheadValidator(preload.repeaterData.DestinationFacilities, 'Id', destination, 'RecipientId');" typeahead-input-formatter="globalMethods.typeaheadFormatter(preload.repeaterData.DestinationFacilities, destination.RecipientId, 'Id', 'LicenseNumber');" typeahead-on-select="validateSelection(preload.repeaterData.DestinationFacilities, [[$parent.$index, 'Destinations', 'Transfer'], $index], ['Id', 'RecipientId'], 'LicenseNumber', false, false, preload.defaults.destinationLine);" id="form-validation-field-0">
<ul class="typeahead dropdown-menu ng-isolate-scope" ng-style="{display: isOpen()&&'block' || 'none', top: position.top+'px', left: position.left+'px'}" typeahead-popup="" matches="matches" active="activeIdx" select="select(activeIdx)" query="query" position="position" style="display: block; top: 57px; left: 182px;">
<!-- ngRepeat: match in matches --><li ng-repeat="match in matches" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)" class="ng-scope active">
<a tabindex="-1" bind-html-unsafe="match.label | typeaheadHighlight:query" class="ng-scope ng-binding"><strong>020-100815612A0</strong> | 12/12 INDO</a>
</li><!-- end ngRepeat: match in matches -->
</ul>
<button class="js-destinationsearch-0-0 btn js-destinationsearch" data-id-field="Id,RecipientId" data-index="0" data-sublists="0,Destinations" data-sibling-validator="typeahead-on-select" data-popover-updater="" type="button" data-original-title="" title="">
<span class="icon-search"></span>
</button>
<input name="model[0][Destinations][0][RecipientId]" type="hidden" value="">
</div>
<button class="btn btn-info btn-mini" type="button" ng-click="removeLine($index, line.Destinations, true, preload.defaults.destinationLine); preload.methods.createNewControls();">
<span class="icon-minus-sign ng-hide" ng-hide="line.Destinations.length === 1"></span><span ng-show="line.Destinations.length === 1" class="">(clear)</span>
</button>
</div>
</div>
enter correct info in the field with placeholder placeholder="Type part of the License Number..." works then showing the ul/li part which requires a select to set the hidden field
You don't mention how you need to select from that list, but if you just need to click it you could do
click_link('AAA')
If you need more specific than that you could do
find('li > a', text: 'AAA').click
etc.
This assumes you've already sent the relevant keystrokes to the input to make the list appear.

materializecss read radio button

New to materializecss, trying to read radio button and not having any luck.
<form class="main" id="sponsorform" novalidate="novalidate" style="max-width: 480px;margin: 40px auto;">
:
<div>
<div class="row">
<div class="input-field col s12">
<p>Choose race to sponsor</p>
<p>
<input type="radio" name="race" id="wdf">
<label for="wdf">Women's Distance Festival</label>
</p>
<p>
<input type="radio" name="race" id="msm">
<label for="msm">Market Street Mile</label>
</p>
</div>
</div>
<div class="row">
<div class="input-field col s6">
<button class="waves-effect waves-light btn submit-btn" type="submit" onclick="nextOrSubmitPage(); return false;">Next</button>
</div>
</div>
</div>
When I click on one of the options, the circle gets highlighted but using chrome inspect I do not see any change to the dom.
And when I try to read I see either
$('input[name=race]:checked').val()
"on"
or I get an error `Cannot read property 'val' of null
Not sure what changes in between the two behaviors, though.`
Note: this is all within google apps script. Not sure if that is relevant or not.
Ok, after some hacking around, I found the following seems to work
$('input[name=race]:checked').attr('id')
Not sure if there's a better way to do this, but as I said it seems to work.
This may solve your problem.
$("input[name=group1]:checked").next().text();

ng-model not working for certain attributes in angularJS

Hi I encountered a problem with ng-model. I want to create an edit page for admin user to edit the rest of the user's permission level.
So, I listed out all the user's attributes in the edit page, and these attributes should display the current values.
I can update all the attributes correctly, however, the problem is that when visiting the edit page, only certain attributes are displayed while some are not. I think it is the problem with ng-model.
code snippets from my _form.html.erb
<div class="col-md-12 space-1" ng-class="{ 'has-error' : form['email'].$invalid }">
<label class="control-label">Email</label>
<div class="input-icon right">
<i ng-show="form['email'].$invalid" class="fa fa-warning tooltips" data-original-title="{{errors['email']}}" data-container="body"></i>
<input ng-model= "user.email" name="email" type="text" class="form-control">
</div>
</div>
<br>
<div class="col-md-12 space-1" ng-class="{ 'has-error' : form['events'].$invalid }">
<label class="control-label">Event Permission Level : {{user.activities.events}}</label>
<div class="input-icon right">
<i ng-show="form['events'].$invalid" class="fa fa-warning tooltips" data-original-title="{{errors['events']}}" data-container="body"></i>
<input ng-model= "user.activities.events" name="activities.events" type="range" max="2" min="0" class="form-control">
</div>
</div>
<br>
<div class="col-md-12 space-1" ng-class="{ 'has-error' : form['admin_events'].$invalid }">
<label class="control-label">Admin Event Permission Level : {{user.activities.admin_events}}</label>
<div class="input-icon right">
<i ng-show="form['admin_events'].$invalid" class="fa fa-warning tooltips" data-original-title="{{errors['admin_events']}}" data-container="body"></i>
<input ng-model= "user.activities.admin_events" name="activities.admin_events" type="range" max="2" min="0" class="form-control">
</div>
</div>
<br>
The code above shows 3 different ng-models, 1.user.email, 2.user.activities.events 3.user.activities.admin_events
The way I process them is the same, but when visiting the edit page, only email and events attributes displayed the current value, but not admin_events. I can update their values alright, but I cannot get admin_events to display its current value when visiting the edit page. This is weird isn't it. I mean if I can see the value of events, why can't I see the value of admin_event since they all belong to the user variable.
Can anyone explain why is it like this? It is very confusing for me. Thank you very much.
As it solved the problem, I quote myself from the comments :
If only user.activities.admin_events is not working, it may be related to the _ notation. Try camel case user.activities.adminEvents or user.activities['admin_events'].

is it possible to place select menu and input type in a same line?

I want to place select menu and input type in a same line.
This is the link to jsfiddle demo.
html
<div class="lin">
<select data-inline="true">
<option>1</option>
<option>hello</option>
</select>
I tried it using style but i didn't get please any one help me.
Just place it in a grid, jQuery Mobile has available solution.
Working example: http://jsfiddle.net/Gajotres/26uph/
HTML:
<div class="ui-grid-a">
<div class="ui-block-a"><input type="text"/></div>
<div class="ui-block-b"><select><option>1</option><option>2</option></select></div>
</div><!-- /grid-a -->
HTML:
<div class="left">
<select data-inline="true">
<option>1</option>
<option>hello</option>
</select>
</div>
<div class="right">
<input type="text" name="txt" value=""/>
</div>
<div class="clear">
</div>
CSS:
.left{
display:inline;
float: left
}
.right{
float:right;
}
.clear{
clear:both;
}
take a look: http://jsfiddle.net/DRs8p/3/

Resources