I've been trying to make a selection from a drop down but cannot seem to figure out how.
Here's what I'm trying to get:
<div id="quote-status" class="panel panel-default">
<div class="panel-heading">
<a class="clickable" ng-click="toggleCollapse();">
<i class="glyphicon glyphicon-expand ng-hide" ng-show="collapsed"></i>
<i class="glyphicon glyphicon-collapse-down" ng-hide="collapsed"></i>
<strong>Quote Status</strong>
</a>
</div>
<div class="panel-body collapse in" collapse="collapsed" style="height: auto;">
<div class="row">
<!-- ngIf: quote.quoteLabels && (quote.quoteLabels.length > 0) -->
</div>
<div class="row">
<div class="col-md-3">
<p><b>* Choose a Status:</b></p>
<select class="form-control ng-pristine ng-valid" ng-model="quote.labelId" ng-change="statusSelectChange()" ng-options="i.id as i.labelName group by i.categoryName for i in labelTypes | filter:{ active : '1' } | orderBy:'priority'">
<option value="" class=""></option>
<optgroup label="Potential Customer">
<option value="0">Low Priority</option>
</optgroup>
</select>
</div>
</div>
</div>
I would like to set option 0 as my value. I'm trying to get the value using:
myselect = Select(driver.find_element_by_class_name("form-control"))
myselect.select_by_value("0")
For this given example, it says that the element is an input, not a select object, when it try to use ng-valid or ng-pristine I get:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"class name","selector":"ng-valid"
Not sure what to do at this point. We're using angular.js on top of a php built web app.
-
Your classname selector is not correct. You have compound classes in your angular JS code, while you're using a single classname to access it. You need to access this using all classnames. Also, this can be easily done using protractor using ng-model locator (in case you want to try it)demouser123– demouser1232017年04月12日 23:23:26 +00:00Commented Apr 12, 2017 at 23:23
-
@bad_deadpool Thanks, I did some digging and found something promising called pytractor, however it doesnt seem to be actively developed or maintained. I'm going to take a shot at using protractor now.QAguy– QAguy2017年04月13日 22:15:56 +00:00Commented Apr 13, 2017 at 22:15
4 Answers 4
This is working for me using UI's Select option. e.g.:
from selenium.webdriver.support.ui import Select
driver = webdriver.Chrome()
# Locate the Sector and create a Select object
select_element = Select(driver.find_element_by_css_selector(".form-control"))
# this will print out strings available for selection on select_element, used in visible text below
print [o.text for o in select_element.options]
# select by visible text
select_element.select_by_visible_text("Low Priority")
# or select by value
select_element.select_by_value('0')
# or select by option index
select_element.select_by_index(1)
Documentation here and some credit to Daniel Abel here.
I'm a bit concerned your error may be coming from somewhere else as the error you're getting is selenium unable to find an element with the class of ng-valid
, which isn't included in your example selenium code. Also, with Angular be sure to throw in a wait for the angular page to load. Like:
from selenium.webdriver.support.ui import WebDriverWait # Import at top of file
from selenium.webdriver.support import expected_conditions as EC
# Selenium waits for the page to load, but not necessarily the angular app
wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located('ng-valid'))
You may want to use protractor anyway as it has some custom locators for angular and will wait for ng-app to load by default.
def select_dropdown_value(self, locator, value):
selectOption = Select(self.driver.find_element(*locator))
option_selected = selectOption.select_by_value(value)
One of the best features of Python is interactive debugger pdb.
So every time I am not sure how a Python feature works, I drop to debugger and interrogate the object instance for method and how it works:
import pdb
pdb.set_trace()
which can be done on single line, easier to comment/uncomment:
import pdb; pdb.set_trace()
Put this after you created the myselect
object, and try it. dir(myselect)
will show you all the methods it has. More fun than reading the docs - but you still should read the docs, and use this trick to test your understanding.
I don't normally use python for my automation work so I apologize that I can't speak to the exact problem you're experiencing with your code, however in the languages I'm more familiar with I usually shortcut "choose an option from a dropdown" by interacting directly with the option and ignoring a two-click approach.
driver.findElement(by.xpath("//select[@ng-model='quote.labelId']/option[@value='0']")).click()
Here I look for the select tag you're trying to interact with (for your provided html, narrowing by ng-model was excessive), look for its child with the value you're trying to get, then I select it with a click.