Selecting item from dropdown - python

I need to use selenium to select an item from a dropdown. The site looks like this
<div class="chosen-drop">
<div class="chosen-search"><input type="text" autocomplete="off"></div>
<ul class="chosen-results">
<li class="active-result style="" data-option-array-index="0">Please choose your main activity</li>
<li class="active-result" style="" data-option-array-index="1">Animals and Pets</li>
<li class="active-result" style="" data-option-array-indexx="2">Art and Culture</li>
<li class="active-result" style="" data-option-array-index="3">Babies</li>
<li class="active-result" style="" data-option-array-index="4">Beauty and Personal Care</li>
<li class="active-result" style="" data-option-array-index="5">Cars</li>
<li class="active-result" style="" data-option-array-index="6">Computer Hardware and Software</li>
</ul>
How can I select/click on "Cars"/data-option-array-index="5"?

I believe you could use a simple css selector to get element you want using :nth-child. For example to get 2 entry you could write such selector:
.choosen-drop ul>li:nth-child(2)

You can do this like, as I know java so I write code in java. First List all the locators in LIST, then using For- Each and If else you can select particular item and perform operations
//Locate all elements in list
List<WebElement> dropEle= driver.findElements(By.xpath("//ul[#class='chosen-results']//li"));
for (WebElement tempEle : dropEle) {
//condition to check text
if(tempEle.getText().contains("Cars"))
{
// Do operations
System.out.println("Pass");
}
}

Related

Selecting an item from a list with Selenium and Python

I'm trying to select an item from a list with selenium / python and am having issues with getting the elements to load and be interactable. I think the problem is the website doesn't load the html for that section until the drop down is clicked but I'm not sure how to go about resolving that. This is what the html looks like if I click view source:
<label data-lang="4003">Impact</label>
<select id="impact">
<option value="" selected data-lang="48">Select</option>
</select>
If I look at it with the chrome inspect tools I see this:
<label data-lang="4003">Impact</label>
<div class="select-wrapper cascading-dropdown-loading initialized">
<span class="caret">▼</span>
<input type="text" class="select-dropdown" readonly="true" data-activates="select-options-e89d2a9c-3be1-67a1-6f4b-32c36b38f6eb" value="Select">
<ul id="select-options-e89d2a9c-3be1-67a1-6f4b-32c36b38f6eb" class="dropdown-content select-dropdown ">
<li class="">
<span>Select</span>
</li>
<li class="">
<span>High</span>
</li>
<li class="">
<span>Medium</span>
</li>
<li class="">
<span>Low</span>
</li>
<li class="">
<span>None</span>
</li>
</ul>
<select id="impact" class="initialized" data-select-id="e89d2a9c-3be1-67a1-6f4b-32c36b38f6eb">
<option value selected data-lang="48">Select</option>
<option value="HIGH">High</option>
<option value="MEDIUM">Medium</option>
<option value="LOW">Low</option>
<option value="NONE">None</option>
</select>
</div>
The data-select-id also seems to be randomly generated, as it changes each time I refresh the page.
So far, I've been able to get a list of the options available using the following code:
select = driver.find_element_by_id("impact")
options = [x for x in select.find_elements_by_tag_name("option")]
for element in options:
print(element.get_attribute("value"))
Attempting to manipulate the list with something like element.click() doesn't seem to work and only gives me the error "Error: Message: element not interactable: Element is not currently visible and may not be manipulated"
I have also tried using Select with code like this with no success. I've used all three select by options, select_by_value, select_by_visible_test and select_by_index with no success.
select = Select(driver.find_element_by_id('impact'))
select = select_by_value("HIGH")
I have also tried exploring select.options which returns a list of objects that look like:
<selenium.webdriver.remote.webelement.WebElement (session="513ab2b2bfc1c3c738af19e69230a763", element="d00bf83d-3772-4357-b6da-1702a12ffda3")>
but I'm not sure how to manipulate these to do anything more with them. The session and element ids also change between runs.
Any help pointing me in the right direction would be greatly appreciated!

Element Not Interactable Exception when using Python selenium Select() function

I have the following HTML code:
<select name="course" id="course" class="standardSelect form-control-sm form-control" data-live-search="true" data-size="10" onchange="displayStudent(this.value);" style="display: none;">
<option value="">Select course</option>
<option value="2">Course A</option>
<option value="71">Course B</option>
<option value="5">Course C</option>
...
</select>
<div class="chosen-container chosen-container-single chosen-container-single-nosearch" title="" id="course_chosen" style="width: 100%;">
<a class="chosen-single">
<span>Select course</span>
</a>
<div class="chosen-drop">
<div class="chosen-search">
<input class="chosen-search-input" type="text" autocomplete="off" readonly="">
</div>
<ul class="chosen-results">
<li class="active-result result-selected" data-option-array-index="0">Select course</li>
<li class="active-result" data-option-array-index="1">Course A</li>
<li class="active-result" data-option-array-index="2">Course B</li>
<li class="active-result" data-option-array-index="3">Course C</li>
...
</ul>
</div>
</div>
I am intending to scrape the content that is displayed when each course is selected. So I have to click on each option and get the page's source code. However I am unable to do so. When I try to select any option either using the select_by_value() or using the select_by_visible_text() functions I get the ElementNotInteractableException. I also tried the select_by_index() function.
Below is the code I used for selecting the option with value = 2:
select_box = Select(browser.find_element_by_xpath("//select[#id='course']"))
select_box.select_by_value('2')
and the error it gives me is:
ElementNotInteractableException: Message: element not interactable: Element is not currently visible and may not be manipulated
(Session info: chrome=80.0.3987.149)
Please help me resolve this exception or any other method that would work on selecting the option from a drop down list.
the select is not displayed style="display: none;" so you cannot click it
I guess on the real side you would have to click on the li element. try to click: //div[#id="course_chosen"]//ul/li[text()="Course A"] (probably after clicking on <span>Select course</span>)

Selenium will not select drop down option due to visibility issues

UPDATED
In my Django settings, when I set DEBUG to false, Selenium is able to interact with the elements. It still does not work when DEBUG is set to true
So I am trying to select one option in a dropdown menu, but when I try to directly access the <select> tag I get the error ElementNotVisibleException: Message: element not interactable.
In the console whenever I click on the dropdown in only refers to an input tag that dynamically changes based on what I click on. Ultimately, I want the test to click on the dropdown and then select 'Tango' as shown in the link below.
My Selenium code is:
from selenium.webdriver import Chrome
from selenium.webdriver.support.ui import Select
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("localhost:8000/")
select = Select(driver.find_element_by_xpath('//*[#id="select-dance"]').click())
select.select_by_value('1')
And HTML:
<form onsubmit="return false;">
<div class="row border-light bg-white rounded-left rounded-right no-gutters">
<div class="col-12 col-lg px-3">
<div class="select-wrapper mdb-select">
<span class="caret"></span>
<input type="text" class="select-dropdown" readonly="true" data-activates="select-options-20f378f1-9560-4598-b8e8-
3ffe496cd688" value="Choose your dance event">
<ul id="select-options-20f378f1-9560-4598-b8e8-3ffe496cd688" class="dropdown-content select-dropdown" style="width: 658px; position:absolute;top: 0px; left: 0px;opacity: 1; display: none;">
<li class="">
<span class="filtrable">Choose your dance event</span></li>
<li class="">
<span class="filtrable">Tango</span></li>
<li class="active selected">
<span class="filtrable">Swing</span>
</li>
<li class="">
<span class="filtrable">Latin/Salsa</span>
</li>
<li class="">
<span class="filtrable">Ballroom</span>
</li>
<li class="">
<span class="filtrable">Bachata</span>
</li>
</ul>
<select class="mdb-select initialized" id="select-dance">
<option value="0">Choose your dance event</option>
<option value="1">Tango</option>
<option value="2">Swing</option>
<option value="3">Latin/Salsa</option>
<option value="4">Ballroom</option>
<option value="5">Bachata</option>
</select>
</div>
</div>
</div>
</div>
</form>
I do not know how to deal with the input tag interfering with the select (it only shows up in the elements console in Chrome).
Thank you!
You can handle by,
driver = webdriver.Chrome()
driver.get("localhost:8000/")
time.sleep(10)
select = Select(driver.find_element_by_id('select-dance'))
select.select_by_value('1')
You can try this,
driver = webdriver.Chrome()
driver.get("localhost:8000/")
time.sleep(10)
driver.find_element_by_id('select-dance').click()
when you click then new list of s will get populated under , then call select tag
select = Select(driver.find_element_by_id('select-dance'))
select.select_by_value('1')
or
select = Select(driver.find_element_by_xpath('//*[#id="select-dance"]'))
select.select_by_value('1')
Your page uses custom Select Component which is not the default html select box. In your case, they have used MDBootstrap Select Component which cannot be interacted using selenium Select class.
Please read this answer for your another question which related to the same issue.

Locating a child of a child in Selenium (Python)

I'm trying to locate two input fields on an unordered menu list, but Selenium is unable to find them. So far I've attempted to locate them by xpath and class name with an ordinal identifier
("//input[#class=x-form-text x-form-field][4]")
but it either doesn't locate the element or it says it is improperly formatted. The only success I've had is if I use the id, but the number on the end changes every time the page loads.
Is there any way to have it locate the menu list, then the list item, and then the input field? I am totally stumped.
Notes about the menu list: It changes size based on resolution and if it becomes much smaller a down arrow icon will appear and the fields towards the bottom of the list will disappear unless that down button is selected.
Here's an example of the html:
<ul id="ext-gen406" class="x-menu-list">
<li id="ext-comp-1237" class="list-item ">
<li id="ext-comp-1238" class="list-item ">
<li id="ext-comp-1239" class="list-item ">
<li id="ext-comp-1240" class="list-item ">
<li id="ext-comp-1241" class="list-item ">
<li id="ext-comp-1242" class="list-item ">
<li id="ext-comp-1207" class="list-item sep-li">
<li id="ext-comp-1243" class="list-item ">
<li id="ext-comp-1244" class="list-item ">
<li id="ext-comp-1208" class="list-item sep-li">
<li id="ext-comp-1245" class="list-item ">
<li id="ext-comp-1246" class="list-item ">
<li id="ext-comp-1247" class="list-item ">
<div class='xtb-text'>Text Field Label</div>
<li id="ext-comp-1248" class="list-item ">
<div id="ext-gen424" class="x-form-field-wrap x-form-field-trigger-wrap">
<input id="ext-comp-1248" class="x-form-text x-form-field"name="ext-comp-1248"
</div>
<li id="ext-comp-1249" class="list-item ">
<li id="ext-comp-1250" class="list-item ">
<div class="x-form-field-wrap x-form-field-trigger-wrap" id="ext-gen426">
<input id="ext-comp-1250" name="ext-comp-1250" class="x-form-text x-form-field"
</div>
<li id="ext-comp-1251" class="list-item ">
<li id="ext-comp-1252" class="list-item ">
</ul>
You can use cssSelector to solve the issue,
driver.find_element_by_css_selector("ul.x-menu-list input.x-form-field:nth-child(1)") //first input box
driver.find_element_by_css_selector("ul.x-menu-list input.x-form-field:nth-child(2)") //second input box
I tried this method and for some reason it only locates the first input field. It doesn't locate any of the other input fields in the list. (There are 12). Can someone provide more information on how to use nth children?
In this case you should try using find_elements to find all input elements and perform certain action on particular element using index below :-
all_inputs = driver.find_elements_by_css_selector("ul.x-menu-list > li.list-item input.x-form-text")
The two input fields that I'm trying to locate are the 9th and 10th input fields in this list.
#now use index to get desire input element
if len(all_inputs) >= 10:
desire_input_9 = all_inputs[8]
desire_input_10 = all_inputs[9]
Ok, so... I finally figured it out!
Here is what worked for me:
driver.find_element_by_xpath("//li/div[contains(text(), 'Text labeling input field')]/../following-sibling::li/div/input")

Not able to select drop-down option using select : UnexpectedTagNameException selenium : python

I apologize if I am doing very basic mistake, i am still new learning webdriver and python.
I am trying to select an option from dropdown using Select Class of python, but i am getting Unexpected TagName exception.
There is no ID present on the Tag, so i cannot detect it using any other method except class or attribute.
HTML Code :
<div class="select-pixels-container ng-scope">
<div class="action group">
<table class="org-agency-advertiser">
<tbody style="background-color: transparent;">
<tr style="background-color: transparent;">
<tr>
<td style="background-color: transparent;">
<select class="mm-select ng-valid localytics-chosen ng-dirty" ng-disabled="disabled('organizations')" ng-options="org.id as org.name for org in logic.organizations | orderBy:'name'" ng-model="logic.organization" chosen="" style="display: none;" data-placeholder="Select an Option">
<div class="chosen-container chosen-container-single" style="width: 175px; background-color: transparent;" title="">
<a class="chosen-single" tabindex="-1" style="background-color: transparent;">
<span style="background-color: transparent;">Select</span>
<div>
</a>
<div class="chosen-drop">
<div class="chosen-search">
<input type="text" autocomplete="off">
</div>
<ul class="chosen-results">
<li class="active-result" style="" data-option-array-index="0">Select</li>
<li class="active-result" style="" data-option-array-index="1">1-800 Hnunagk 100278</li>
<li class="active-result result-selected" style="" data-option-array-index="2">10tc Tatgaa 100179</li>
The code which I have wrote for this section is :
self.driver.find_element_by_css_selector("tbody>tr>td>div>a.chosen-single").click()
select=Select(self.driver.find_element_by_css_selector("tbody>tr>td>div>a[tabindex='-1']"))
select.select_by_index(0)
The exception I am getting is
selenium.common.exceptions.UnexpectedTagNameException: Message: Select only works on <select> elements, not on <a>`
Any help will be appreciated.
All HTML codes hadn't shared but, the basic idea should like this:
self.driver.find_element_by_xpath('//*[#class="chosen-single"]').click()
listItems = self.driver.find_element_by_xpath('//div[#class="chosen-drop"]/ul/li')
for item in listItems: # <li> tags list
if item.get_attribute("data-option-array-index") == "0": # select index
item.click() # if index=0 click
break

Categories