how to select a dropdown value in selenium webdriver using node.js - javascript

I have following HTML structure:
<button class="dropdown-toggle selectpicker btn btn-primary" data-toggle="dropdown" type="button" data-id="strategic_reseller_country" title="United States">
<div class="dropdown-menu open" style="max-height: 245.6px; overflow: hidden; min-height: 40px;">
<ul class="dropdown-menu inner selectpicker" role="menu" style="max-height: 243.6px; overflow-y: auto; min-height: 38px;">
<li class="" rel="0">
<a class="" style="" tabindex="0">
<span class="text"/>
<i class="glyphicon glyphicon-ok icon-ok check-mark"/>
</a>
</li>
<li rel="1">
<a class="" style="" tabindex="0">
<span class="text">Andorra</span>
<i class="glyphicon glyphicon-ok icon-ok check-mark"/>
</a>
</li>
<li rel="2">
<a class="" style="" tabindex="0">
<span class="text">United Arab Emirates</span>
<i class="glyphicon glyphicon-ok icon-ok check-mark"/>
</a>
</li>
<li rel="3">
<a class="" style="" tabindex="0">
<span class="text">Afghanistan</span>
<i class="glyphicon glyphicon-ok icon-ok check-mark"/>
</a>
</li>
<li rel="4">
<li rel="5">
<li rel="6">
<li rel="7">
<li rel="8">
<li rel="9">
<a class="" style="" tabindex="0">
<span class="text">Netherlands Antilles</span>
<i class="glyphicon glyphicon-ok icon-ok check-mark"/>
</a>
</li>
</ul>
</div>
So how could I get the item from list?
I am new to Node.Js (JavaScript) so I don't know how to achieve it in node.Js but it can be achieved in java as follows :
Select dropdown = new Select(driver.findElement(By.class("dropdown-menu inner selectpicker")));
dropdown.selectByVisibleText("Andorra");

Just click the desired option.
driver.findElement(webdriver.By.css('#mySelection > option:nth-child(4)'))
.click();
or by value
driver.findElement(webdriver.By.css('#mySelection > option[value=apple]'))
.click();
Note that I've changed your 'By' to a css selector. I'm lazy and like to just drill into the option from developer tools and select Copy CSS Path (chrome) or Copy Unique Selector (firefox).

You can create a function that select the value you desire
like this...
driver.wait(
until.elementLocated(By.id("continents")), 20000
).then(element => {
selectByVisibleText(element, "Africa")
});
function selectByVisibleText(select, textDesired) {
select.findElements(By.tagName('option'))
.then(options => {
options.map(option => {
option.getText().then(text => {
if (text == textDesired)
option.click();
});
});
});
}

For anyone stuck on this, here is how I did it for a <select> option:
<select id='mySelection'>
<option value='0'>Hello</option>
<option value='1'>Everybody</option>
<option value='2'>Got</option>
<option value='3'>It</option>
</select>
In Selenium for NodeJS, you would grab the It <option>:
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
driver.findElement(webdriver.By.id('mySelection')).sendKeys('It');
When you .sendKeys() for the option it has to equal the text displayed to the user in the dropdown.
In your case just grab the parent element then sendKeys() for the child element.

I would use Cheerio for this.
module.exports = {
"login": function (browser) {
var cheerio = require("cheerio")
browser
.url("http://www.wikipedia.org")
.waitForElementVisible('body', 1000)
.waitForElementVisible('select#searchLanguage', 1000)
.source(function(result) { // .source() dump the page source in the variable
$ = cheerio.load(result.value)
var num_languages = $('select#searchLanguage option').length
console.log('Wikipedia.org Languages: ' + num_languages);
})
.end();
}
};
or simply using the .execute() command

If you have
<select id='mySelection'>
<option value='cat'>Cat!</option>
<option value='dog'>Dog!</option>
<option value='rat'>Rat!</option>
</select>
You can use the method sendKeys passing either the value or the text
driver.findElement(webdriver.By.id('mySelection')).sendKeys('Rat!');
or
driver.findElement(webdriver.By.id('mySelection')).sendKeys('rat');

Related

bootstrap button dropdown set selected value to li

I am having a select box in my form, and after page loading, it is then transformed to bootstrap button before the select box. I can't set the selected value for the converted bootstrap button drop-down li.
<button type="button" class="btn dropdown-toggle btn-default" data-toggle="dropdown" data-id="Occupation" title="-- Please select Occupation--">
<span class="filter-option pull-left">-- Please select Occupation--</span> <span class="bs-caret">
<span class="caret"></span></span></button>
<div class="dropdown-menu open"><ul class="dropdown-menu inner" role="menu">
<li data-original-index="0" class="selected"><a tabindex="0" class="" style="" data-tokens="null"><span class="text">-- Please select Occupation--</span><span class="glyphicon glyphicon-ok check-mark"></span></a></li>
<li data-original-index="1"><a tabindex="0" class="" style="" data-tokens="null"><span class="text">Salaried</span><span class="glyphicon glyphicon-ok check-mark"></span></a></li>
<li data-original-index="2"><a tabindex="0" class="" style="" data-tokens="null"><span class="text">Business</span><span class="glyphicon glyphicon-ok check-mark"></span></a></li>
<li data-original-index="3"><a tabindex="0" class="" style="" data-tokens="null"><span class="text">Above 18 Years</span><span class="glyphicon glyphicon-ok check-mark"></span></a></li></ul></div>
<select name="Occupation" class="form-control show-tick" required="" tabindex="-98">
<option value="">-- Please select Occupation--</option>
<option value="Salaried">Salaried</option>
<option value="Business">Business</option>
<option value="Above 18">Above 18 Years</option>
</select>
I am having the value in localStorage.getItem('Occupation'), and I tried to set the value to that li by using
$('#Occupation ul li').eq(1).find('span').eq(1).text(localStorage.getItem('Occupation')); //not worked
$('#Occupation').parents('.btn-group').find('.dropdown-toggle').html(localStorage.getItem('Occupation')+' <span class="caret"></span>'); //not worked
$("#Occupation li a").filter("[value=" + localStorage.getItem('Occupation') + "]"); //not worked
$("#Occupation").html(localStorage.getItem('Occupation') + ' <span class="caret"></span>'); //not worked
Could someone suggest to me a solution to set the value to that drop-down?
Thanks :)
Upon checking, there is a plugin (bootstrap-select) installed in my site. That plugin modifies my select box to the bootstrap button.
Then I visited the plugin site and got a solution,
$('select[name="Occupation"]').selectpicker('val', localStorage.getItem('Occupation'));

display error when no option is selected from select box

I am facing one problem, I want to show an error when the user has not selected any service from selectbox. I have two checkboxes of Nails and Hair, when user selects the Nails checkbox then, the user must have to select the service from the selectbox. If the user does not select the Hair checkbox then, the selectbox is not mandatory that is below Hair. If both are checked and then both below service must be selected with span serror message. Here is my html:-
enter code here
<div class="one-row">
<div class="div_img_part-2">
<span class="img_part_class-2"><img src="http://localhost:8000/images/ServiceImages/48031.png">
</span>
<span class="text_part_class-2">
<p class="custom-checkbox firstpart">
<input class="firstdisable" type="checkbox" id="0" name="services[]" value="1">
<label for="0">Nails</label>
</p>
</span>
<select id="checkSelect-0" name="service_type[Nails]" class="selectpicker" style="display: none;">
<option value="">Select Service</option>
<option value="Salon">Salon</option>
<option value="Mobile beautician">Mobile beautician</option>
<option value="Both">Both</option>
</select>
<div class="btn-group bootstrap-select">
<button type="button" class="btn dropdown-toggle selectpicker btn-default" data-toggle="dropdown" data-id="checkSelect-0" title="Select Service"><span class="filter-option pull-left">Select Service</span> <span class="caret"></span></button>
<div class="dropdown-menu open">
<ul class="dropdown-menu inner selectpicker" role="menu">
<li rel="0" class="selected"><a tabindex="0" class="" style=""><span class="text">Select Service</span><i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
<li rel="1"><a tabindex="0" class="" style=""><span class="text">Salon</span><i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
<li rel="2"><a tabindex="0" class="" style=""><span class="text">Mobile beautician</span><i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
<li rel="3"><a tabindex="0" class="" style=""><span class="text">Both</span><i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
</ul>
</div>
</div>
<span id="serviceError-0" style="color: rgb(169, 68, 66);">Please select service</span>
</div>
<div class="div_img_part-2">
<span class="img_part_class-2"><img src="http://localhost:8000/images/ServiceImages/55643.png">
</span>
<span class="text_part_class-2">
<p class="custom-checkbox firstpart">
<input class="firstdisable" type="checkbox" id="1" name="services[]" value="2">
<label for="1">Hair</label>
</p>
</span>
<select id="checkSelect-1" name="service_type[Hair]" class="selectpicker" style="display: none;">
<option value="">Select Service</option>
<option value="Salon">Salon</option>
<option value="Mobile beautician">Mobile beautician</option>
<option value="Both">Both</option>
</select>
<div class="btn-group bootstrap-select dropup">
<button type="button" class="btn dropdown-toggle selectpicker btn-default" data-toggle="dropdown" data-id="checkSelect-1" title="Salon" aria-expanded="false"><span class="filter-option pull-left">Salon</span> <span class="caret"></span></button>
<div class="dropdown-menu open" style="max-height: 519.375px; overflow: hidden; min-height: 92px;">
<ul class="dropdown-menu inner selectpicker" role="menu" style="max-height: 507.375px; overflow-y: auto; min-height: 80px;">
<li rel="0" class=""><a tabindex="0" class="" style=""><span class="text">Select Service</span><i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
<li rel="1" class="selected"><a tabindex="0" class="" style=""><span class="text">Salon</span><i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
<li rel="2"><a tabindex="0" class="" style=""><span class="text">Mobile beautician</span><i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
<li rel="3"><a tabindex="0" class="" style=""><span class="text">Both</span><i class="glyphicon glyphicon-ok icon-ok check-mark"></i></a></li>
</ul>
</div>
</div>
<span id="serviceError-1" style="color:#A94442; display:none;">Please select service</span>
</div>
Image:-
Now you see that every category having own selectbox
Here is my jquery code :-
$("#checkservice").on('click',function() { // click event on submit button
var n = $( "input:checked" ).length; //
if(n == 0) {
alert("Please Select atleast One Service"); return false;
}
for (var i = 0; i <= 1; i++) {
if ($('#'+i).is(":checked")) {
if ($("#checkSelect-"+i).val() === "") {
$("#serviceError-"+i).show();
return false;
}
}
}
});
This jquery code works only for first checkbox when i select nails and not select any service it will show error but when i select hair checkbox its not showing error
Image:-
I am using laravel framework. Please help me
function onSubmit()
{
var fields = $("input[name='list']").serializeArray();
if (fields.length == 0)
{
alert('nothing selected');
// cancel submit
return false;
}
else
{
alert(fields.length + " items selected");
}
}
// register event on form, not submit button
$('#subscribeForm').submit(onSubmit)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="POST" id="subscribeForm">
<fieldset id="cbgroup">
<div><input name="list" id="list0" type="checkbox" value="newsletter0" >zero</div>
<div><input name="list" id="list1" type="checkbox" value="newsletter1" >one</div>
<div><input name="list" id="list2" type="checkbox" value="newsletter2" >two</div>
</fieldset>
<input name="submit" type="submit" value="submit">
</form>

Populate f.hidden_field with f.select value

I am looking at how to populate a hidden_field with the value of a f.select field however I am having difficulty. I was going to use javascript but the html created from my haml makes it difficult to assign an id to the select I wish to pass the value from.
= f.select :trial, [['Yes', 'true'], ['No', 'false']], {}, :id => "free-trial", class: 'selectpicker mandatory'
This generates the following html
<div class="col-sm-4">
<select class="selectpicker mandatory" id="free-trial" name="campaign[trial]" style="display: none;">
<option value="true">Yes</option>
<option value="false" selected="selected">No</option>
</select>
<div class="btn-group bootstrap-select mandatory">
<button type="button" class="btn dropdown-toggle" data-toggle="dropdown" data-id="free-trial" data-original-title="" title="">
<span class="filter-option pull-left">No</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" style="max-height: 133px; overflow-y: auto; min-height: 0px;">
<li rel="0">
<a tabindex="0" class="">
<span class="text">
Yes
</span>
<i class="icon-ok check-mark"></i>
</a>
</li>
<li rel="1" class="selected">
<a tabindex="0" class="">
<span class="text">No</span>
<i class="icon-ok check-mark"></i>
</a>
</li>
</ul>
</div>
</div>
This html when display is actually two selects one hidden with the ID assigned and a second which is displayed without the id associated. As a result my clicking on the visible select means the associated jquery doesnt fire.
If i understood you properly, you want catch value from select to hidden_input. You can use jquery to do that:
$('#free-trial').on('change', function(){
var val = $(this).val();
$('#your_hidden_input').attr('value', val);
}

Copy last array object to be added to same array

I hope this is quite simple. I'm trying to add the last object in a array to the array again.
Like this:
arr = [1, 2]
result = [1, 2, 2]
Just with this code instead:
$scope.template = {
ressource: {
level: [{
gain: [],
cost: []
}]
}
};
$scope.addLevel = function() {
var last = $scope.template.ressource.level[$scope.template.ressource.level.length - 1];
$scope.template.ressource.level.push(last);
};
However I'm getting this error:
Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: level in template.ressource.level, Duplicate key: object:51, Duplicate value: {"gain":[],"cost":[]}
EDIT
So i've tried the track by but I don't seem to be getting anything new so here is the HTML part of my code where I use the gain and cost values:
<div ng-show="template.type === 'building'" class="vertical-spacing">
<label>Ressource gain per level</label>
<ul class="list-group">
<li ng-repeat="level in template.ressource.level track by $id(level)"
class="list-group-item"
ng-hide="template.ressource.level.indexOf(level) === 0">
<span>
Level: {{ template.ressource.level.indexOf(level) }}
</span>
<span class="pull-right">
<a href="" ng-click="removeLevel(level)">
<span class="glyphicon glyphicon-remove"></span>
</a>
</span>
<ul>
<li class="list-group-item" ng-repeat="gain in level.gain track by $id(gain)">
<div class="form-inline">
<div class="form-group">
<label>Amount</label>
<input type="number"
class="form-control"
ng-model="gain.amount"
min="1"
required>
</div>
<div class="form-group">
<label>Ressource</label>
<select required
ng-model="gain.ressource"
ng-init="gain.ressource = gain.ressource || ressources.basic[0]"
ng-options="ressource._id as ressource.name | capitalize for ressource in ressources.basic"
class="form-control selectWidth">
<option style="display:none" value="" disabled>select a ressource</option>
</select>
</div>
<span class="pull-right">
<a href="" ng-click="removeGain(level, gain)">
<span class="glyphicon glyphicon-remove"></span>
</a>
</span>
</div>
</li>
</ul>
<span>
<a href="" ng-click="addGain(level)" ng-hide="(level.gain.length + 1) > ressources.basic.length">
<span class="glyphicon glyphicon-plus"></span> Add ressource
</a>
</span>
</li>
</ul>
<span>
<a href="" ng-click="addLevel()">
<span class="glyphicon glyphicon-plus"></span> Add level
</a>
</span>
</div>
<div ng-show="template.type === 'building'" class="vertical-spacing">
<label>Ressource cost per level</label>
<ul class="list-group">
<li ng-repeat="level in template.ressource.level track by $id(level)"
class="list-group-item"
ng-hide="template.ressource.level.indexOf(level) === 0">
<span>
Level: {{ template.ressource.level.indexOf(level) }}
</span>
<span class="pull-right">
<a href="" ng-click="removeLevel(level)">
<span class="glyphicon glyphicon-remove"></span>
</a>
</span>
<ul>
<li class="list-group-item" ng-repeat="cost in level.cost track by $id(cost)">
<div class="form-inline">
<div class="form-group">
<label>Amount</label>
<input type="number"
class="form-control"
ng-model="cost.amount"
min="1"
required>
</div>
<div class="form-group">
<label>Ressource</label>
<select required
ng-model="cost.ressource"
ng-init="cost.ressource = cost.ressource || ressources.categories[0]"
ng-options="ressource._id as ressource.name | capitalize for ressource in ressources.categories"
class="form-control selectWidth">
<option style="display:none" value="" disabled>select a ressource</option>
</select>
</div>
<span class="pull-right">
<a href="" ng-click="removeCost(level, cost)">
<span class="glyphicon glyphicon-remove"></span>
</a>
</span>
</div>
</li>
</ul>
<span>
<a href="" ng-click="addCost(level)" ng-hide="(level.cost.length + 1) > ressources.categories.length">
<span class="glyphicon glyphicon-plus"></span> Add ressource
</a>
</span>
</li>
</ul>
<span>
<a href="" ng-click="addLevel()">
<span class="glyphicon glyphicon-plus"></span> Add level
</a>
</span>
</div>
The error now states:
Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: level in template.ressource.level track by $id(level), Duplicate key: object:51, Duplicate value: {"gain":[],"cost":[]}
You have an angular error. Use track by in your ng-repeat.
<div ng-repeat="n in template.ressource.level track by $index">
Reference
https://docs.angularjs.org/api/ng/directive/ngRepeat#tracking-and-duplicates
By default, ngRepeat does not allow duplicate items in arrays. This is because when there are duplicates, it is not possible to maintain a one-to-one mapping between collection items and DOM elements.
If you do need to repeat duplicate items, you can substitute the default tracking behavior with your own using the track by expression.

AngularJS form validation on a bootstrap dropdown

Is it possible to add AngularJS to a Boostrap dropdown (not a <select/>, but rather the Javascript component)? This is what I have:
<div class="form-group has-feedback" ng-class="{'has-error': editorForm.example.$invalid && !editorForm.example.$pristine, 'has-success': editorForm.example.$valid && !editorForm.example.$pristine}">
<label for="example">Example</label>
<div class="dropdown" id="example" style="width: 90%">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdown"
data-toggle="dropdown">
{{exampleLabel}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li data-ng-repeat="example in examples" role="presentation"><a
role="menuitem" tabindex="-1"
data-ng-click="selectExample(example)"
href="javascript:void(0);">{{example.label}}</a>
</li>
</ul>
</div>
$scope.selectExample = function(val) {
$scope.example = val;
}
Is there a way for me to programatically set the validity in selectExample?
Add this hidden text box:
<input type="text" name="exampleLabel" ng-model="exampleLabel" hidden required />
and add this validation after the dropdown
<span class="text-danger" ng-show="myForm.exampleLabel.$error.required">
validation message
</span>
Add input type="hidden":
<form class="form-validation" name="actin_form">
<div uib-dropdown>
<input type="hidden" name="nameVal" ng-model="nameValModel" required/>
<button type="button" ng-class="{'input-error': actin_form.nameVal.$invalid}" class="btn" uib-dropdown-toggle>
<span>{{nameValModel}}</span>
</button>
<ul class="dropdown-menu">
<li ng-repeat="type in list" class="text-wrap">
<span>{{type.name}}</span>
</li>
</ul>
</div>
</form>
This work for me.hope you can get some idea.
<style>
.dropdown-has-error{
border-color: #a94442;//bootsrtap warning color
}
</style>
add ng-class directive to the dropdown button
ng-class="{'dropdown-has-error' : example == ''}
in the controller
$scope.example = '';
$scope.selectExample = function(val) {
$scope.example = val;
}
or you can check condition as in the above post,
ng-class="{'dropdown-has-error' : myForm.exampleLabel.$error.required}

Categories

Resources