How to select option in drop down protractorjs e2e tests
Solution 1
I had a similar problem, and eventually wrote a helper function that selects dropdown values.
I eventually decided that I was fine selecting by option number, and therefore wrote a method that takes an element and the optionNumber, and selects that optionNumber. If the optionNumber is null it selects nothing (leaving the dropdown unselected).
var selectDropdownbyNum = function ( element, optionNum ) {
if (optionNum){
var options = element.all(by.tagName('option'))
.then(function(options){
options[optionNum].click();
});
}
};
I wrote a blog post if you want more detail, it also covers verifying the text of the selected option in a dropdown: http://technpol.wordpress.com/2013/12/01/protractor-and-dropdowns-validation/
Solution 2
For me worked like a charm
element(by.cssContainingText('option', 'BeaverBox Testing')).click();
Solution 3
An elegant approach would involve making an abstraction similar to what other selenium language bindings offer out-of-the-box (e.g. Select
class in Python or Java).
Let's make a convenient wrapper and hide implementation details inside:
var SelectWrapper = function(selector) {
this.webElement = element(selector);
};
SelectWrapper.prototype.getOptions = function() {
return this.webElement.all(by.tagName('option'));
};
SelectWrapper.prototype.getSelectedOptions = function() {
return this.webElement.all(by.css('option[selected="selected"]'));
};
SelectWrapper.prototype.selectByValue = function(value) {
return this.webElement.all(by.css('option[value="' + value + '"]')).click();
};
SelectWrapper.prototype.selectByPartialText = function(text) {
return this.webElement.all(by.cssContainingText('option', text)).click();
};
SelectWrapper.prototype.selectByText = function(text) {
return this.webElement.all(by.xpath('option[.="' + text + '"]')).click();
};
module.exports = SelectWrapper;
Usage example (note how readable and easy-to-use it is):
var SelectWrapper = require('select-wrapper');
var mySelect = new SelectWrapper(by.id('locregion'));
# select an option by value
mySelect.selectByValue('4');
# select by visible text
mySelect.selectByText('BoxLox');
Solution taken from the following topic: Select -> option abstraction.
FYI, created a feature request: Select -> option abstraction.
Solution 4
element(by.model('parent_id')).sendKeys('BKN01');
Solution 5
To access a specific option you need to provide the nth-child() selector:
ptor.findElement(protractor.By.css('select option:nth-child(1)')).click();
Ranjan Bhambroo
Updated on July 28, 2021Comments
-
Ranjan Bhambroo almost 3 years
I am trying to select an option from a drop down for the angular e2e tests using protractor.
Here is the code snippet of the select option:
<select id="locregion" class="create_select ng-pristine ng-invalid ng-invalid-required" required="" ng-disabled="organization.id !== undefined" ng-options="o.id as o.name for o in organizations" ng-model="organization.parent_id"> <option value="?" selected="selected"></option> <option value="0">Ranjans Mobile Testing</option> <option value="1">BeaverBox Testing</option> <option value="2">BadgerBox</option> <option value="3">CritterCase</option> <option value="4">BoxLox</option> <option value="5">BooBoBum</option> </select>
I have tried:
ptor.findElement(protractor.By.css('select option:1')).click();
This gives me the following error:
An invalid or illegal string was specified Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01' System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.9', java.version: '1.6.0_65' Driver info: driver.version: unknown
I have also tried:
ptor.findElement(protractor.By.xpath('/html/body/div[2]/div/div[4]/div/div/div/div[3]/ng-include/div/div[2]/div/div/organization-form/form/div[2]/select/option[3]')).click();
This gives me the following error:
ElementNotVisibleError: Element is not currently visible and so may not be interacted with Command duration or timeout: 9 milliseconds Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01' System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.9', java.version: '1.6.0_65' Session ID: bdeb8088-d8ad-0f49-aad9-82201c45c63f Driver info: org.openqa.selenium.firefox.FirefoxDriver Capabilities [{platform=MAC, acceptSslCerts=true, javascriptEnabled=true, browserName=firefox, rotatable=false, locationContextEnabled=true, version=24.0, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true, browserConnectionEnabled=true, nativeEvents=false, webStorageEnabled=true, applicationCacheEnabled=false, takesScreenshot=true}]
Can anyone please help me with this problem or throw some light on what i might be doing wrong here.
-
jpw over 10 yearsThis does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post.
-
bekite over 10 years@jpw is my answer wrong. or is it simply the formulation of my answer thats wrong?
-
jpw over 10 yearsThe formulation of an answer as a question is why. I don't know if it's the correct answer. If it is you should formulate it as such.
-
Ranjan Bhambroo over 10 years@bekite Didn't work for me.Still getting the error Element Not visible error when i tried your suggestion
-
PaulL almost 10 yearsMinor note - v0.22 only (I just went to replace my code with this today, and had to upgrade to get it)
-
Christopher Marshall over 9 yearsIs there a way for targeting elements using this? Such as having duplicate State select menus.
-
Joel Kornbluh over 9 yearsChristopher,
ElementFinder
is chain-able, so you can do:element(by.css('.specific-select')).element(by.cssContainingText('option', 'BeaverBox Testing')).click();
-
Avi Cherry almost 9 yearsTo wait for angular to finish up pending processing, use protractor's
waitForAngular()
method. -
TrueWill over 8 yearsNote that you can get partial matches, so 'Small' will match 'Extra Small'.
-
user115014 over 8 yearsTo add to TrueWill's comment: The down side of this solution is that if you have two similar options it will use the last found option - which threw up errors based on the wrong selection. What worked for me was stackoverflow.com/a/25333326/1945990
-
YoBre over 8 yearsIt is the most correct for me. With cssContainingText not you make sure to capture the desired field. Just think if you have 2 selectbox with the same values. +1
-
Michiel over 8 yearsWhy do you use 'return' in the select funtions? Is that necessary?
-
alecxe over 8 years@Michiel good point. Might be necessary if you want to explicitly resolve the promise returned by
click()
. Thanks. -
Luan Nguyen almost 8 yearsI just use this:
element(by.model('selectModel')).click(); element(by.css('md-option[value="searchOptionValue"]')).click();
-
ESP32 almost 8 yearsSorry, what is BKN01?
-
Milan Kumar over 7 years@Gerfried BKN01 is the text which you want to select from the drop down.
-
Milan Kumar over 7 years@GalBracha Sorry didn't get you
-
gbruins over 7 yearsHere's another approach:
mdSelectElement.getAttribute('aria-owns').then( function(val) { let selectMenuContainer = element(by.id(val)); selectMenuContainer.element(by.css('md-option[value="foo"]')).click(); } );
-
Anuj K.C. over 7 yearsvar orderTest = element(by.model('ctrl.supplier.orderTest')) orderTest.$('[value="1"]').click(); am getting error By(css selector, [value="3"])
-
David Casillas about 7 yearsUsing this method the value of
form.$pristine
was not updated . Using thesendKeys()
way worked ok for me. -
zs2020 about 7 yearsIf you have another option which share same prefex as BKN01, it will not work. A random one will be picked up.
-
Justin about 6 yearsDidn't work for me, got element.findElements is not a function.
-
twm over 5 yearsIf a partial match is a problem, you can use a RegExp instead of a string.
-
double-beep almost 4 yearsWhile this code may solve the question, including an explanation of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please edit your answer to add explanations and give an indication of what limitations and assumptions apply. From Review
-
javafueled over 3 yearsThis probably will not work in Angular 2+ applications where
model
andbinding
are not available. Still. -
Sergey Pleshakov about 3 yearseven if it works, there are multiple problems with this code. 1. It's not clear why variable
options
is created if the output of the command is alwaysundefined
. 2. For getting one element out of elementArrayFinder, it's better (and easier) to use .get() method. 3. If you pass an element to the function, thenelement.all
statement won't work. 4. It's better to useasync
functions these days. Here is an example stackoverflow.com/a/66110526/9150146