Selenium will not select drop down option due to visibility issues - python

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.

Related

Web Scraping with Selenium - Detecting a dropdown menu

Selenium version 3.141.0
I'm writing a web scraping script that should select a certain option from a dropdown menu with Selenium webdriver. The problem is, I cannot seem to detect this dropdown menu element. I tried detecting it with Class and by CSS selector, but it's still undetectable.
the dropdown menu is a status menu, it contains:
Draft
Submitted
Reviewed
Released
Rejected
Obsolete
This is the HTML code of the part of the page where the dropdown menu is:
<div class="controls col-md-5 angular2-multiselect" id="status-field">
<ctf-angular2-multiselect class="defaultSettings ng-valid ng-touched ng-dirty">
<div class="cuppa-dropdown" qa-name="dropdown-multiselect">
<div class="selected-list" tabindex="0">
<div class="c-btn" qa-name="toggle-dropdown-statusField">
<!----><!----><!---->
<span>
<!----><span qa-name="item-0">Draft</span>
</span>
<!----><!----><!---->
<div class="dropdown-caret"></div>
</div>
</div>
<div class="dropdown-container" qa-name="dropdown" hidden="">
<div class="dropdown-list">
<div class="list-area" qa-name="list-area">
<!----><!----><!----><!----><!---->
<ul class="lazyContainer">
<!----><!---->
<span>
<!---->
<li class="pure-checkbox single-select-label-selected">
<!----><label qa-name="item-0" title="Draft" class="single-select-label">Draft</label>
</li>
<li class="pure-checkbox">
<!----><label qa-name="item-1" title="Submitted" class="single-select-label">Submitted</label>
</li>
<li class="pure-checkbox">
<!----><label qa-name="item-2" title="Reviewed" class="single-select-label">Reviewed</label>
</li>
<li class="pure-checkbox">
<!----><label qa-name="item-3" title="Released" class="single-select-label">Released</label>
</li>
<li class="pure-checkbox">
<!----><label qa-name="item-4" title="Rejected" class="single-select-label">Rejected</label>
</li>
<li class="pure-checkbox">
<!----><label qa-name="item-5" title="Obsolete" class="single-select-label">Obsolete</label>
</li>
</span>
<!---->
</ul>
<!----><!----><!----><!---->
</div>
</div>
</div>
</div>
</ctf-angular2-multiselect>
</div>
Apparently I'm not that good with HTML, so I was depending on IDs to detect elements in the previous codes I wrote. This code doesn't have any.
This is how the GUI looks like:
Picture of GUI
I tried using classes to detect the dropdown menu like this:
Select(driver.find_element(By.CSS_SELECTOR, 'ctf-angular2-multiselect')).select_by_value("Released")
But it doesn't work.
Trying to detect with ID like this:
Select(driver.find_element_by_id('status-field')).select_by_value("Released")
doesn't work either
You have at least two challenges to overcome:
This isn't a normal html select. You need to click on things through Selenium.
The 'dropdown-container' is hidden. You need click on whatever opens it first.
Should we assume the div with the 'c-btn' class opens the drop down? I'd normally check in chrome
dev tools if that element has event listeners or use chrome to
save element as a variable and run a js click on it to verify it's
the right element to click before adding it in selenium
Once .dropdown-container is not longer hidden. I think your life would be easier with using xpath to select the list elements. to select the 'Released' option, the xpath would just be //label[#title='Released']
You can also use chrome dev tools to verify xpath selections before adding to your selenium script.
With python selenium, you can then click on your xpath selection like this:
driver.find_element(
By.XPATH, "//label[#title='Released']").click()

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>)

Cannot click a radio button inside a span Selenium Python

I am trying to click into a radio button inside a span. Trying to execute:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
chromeDriver = webdriver.Chrome()
chromeDriver.get('https://www.flytap.com/pt-br/')
#Works Fine
chromeDriver.find_element_by_id('origin')
origin.click()
origin.clear()
origin.send_keys('(RIO) Rio De Janeiro - todos os aeroportos , Brasil')
origin.click()
#Where I got the error
milesBox = chromeDriver.find_element_by_id("booking-type-2").click()
#Also tried:
milesBox = chromeDriver.find_element_by_id("booking-type-2").send_keys(Keys.ENTER)
#And, finally:
milesBox = chromeDriver.find_element_by_id("booking-type-2").send_keys(Keys.SPACE)
Here is the error I got:
ElementNotVisibleException: Message: element not visible
HTML code:
<!-- Payment Methods START -->
<fieldset id="booking-payment-drag" class="booking-payment">
<div class="toolbar-radio-wrapper">
<legend class="ipt-label">Reservar com:</legend>
</div>
<div class="toolbar-radio-wrapper">
<div class="radio">
<span class="checked"><input type="radio" id="booking-type-1" name="booking-type" value="1" checked></span>
</div>
<label for="booking-type-1" class="ipt-label">Dinheiro</label>
</div>
<div class="toolbar-radio-wrapper js-country-not-eligible">
<div class="radio">
<span class=""><input type="radio" id="booking-type-2" name="booking-type" value="2"></span>
</div>
<label for="booking-type-2" class="ipt-label">Milhas</label>
</div>
<div class="toolbar-radio-wrapper">
<div class="radio is-disabled js-country-eligible">
<span class=""><input type="radio" id="booking-type-3" name="booking-type" value="3" disabled></span>
</div>
<label for="booking-type-3" class="ipt-label">Miles&Cash</label>
</div>
</fieldset>
As per the HTML you have shared to click on the radio button beside the <label> with text as Milhas you can use the following line of code :
chromeDriver.find_element_by_xpath("//input[#id='booking-type-2' and #name='booking-type']").click()
You can use this xpath
//div[#class='radio']//span//input[#id='booking-type-1']
//div[#class='radio']//span//input[#id='booking-type-2']
//div[#class='radio is-disabled js-country-eligible']//span//input[#id='booking-type-3']
It seems like the origin element's dropdown covers the radio button you are trying to click. Maybe you could change the order of operations though? Clicking the destination element also opens up the section where the radio button is but it doesn't seem to cover it. This is a quick example of clicking that radio button and then you could go fillout the origin input after.
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.flytap.com/pt-br/')
destination = driver.find_element_by_id('destination')
destination.click()
miles_box = driver.find_element_by_id('booking-type-2')
miles_box.click()

NoSuchElementException in Selenium Webdriver in python

div class="row-fluid">
<div id="sfx" class="span12">
<ui-view>
<div class="row-fluid fa-rep-nav">
<div id="test"></div>
<div class="row-fluid">
<div id="sfx" class="span12">
<ui-view>
<div class="row-fluid">
<div class="span12">
<div class="ledger-btn-block clearfix">
<form class="ng-pristine ng-valid" name="reportGenForm">
<span class="input-append ledger-date-block fa-block-pull-left">
<label class="ledger-label">Select‌·Report:‌· </label>
<select class="select_report_type ng-pristine ng-untouched ng-valid" ng-model="selectedReport" ng-options="str.name for str in reportType">
<label class="ledger-label"> ‌·Date‌·Range:‌· </label>
<input class="date-picker report-date-input ng-pristine ng-untouched ng-valid" date-range-picker="" readonly="" ng-model="sfxReportModel.date" options="selectedReport.opts" min="selectedReport.opts.minDate" max="selectedReport.opts.maxDate" type="text">
<i class="icon-calendar add-on no-border-radius"></i>
</span>
I have used all the method of locating an element which are applicable here. I have also used time.sleep() function so that the page on which I am locating element can load successfully before finding, but even then also location is not appearing.Here is the pic of html code. Highlighted is the one I want to locate.
I have used methods like find_element_by_xpath and find_by_class_name where i get xpath using Firebug but getting the same errorenter image description here. I need help in locating "select" tag.
As far as I understood you want to select the dropdown. Use the following code in python to select a dropdown value
from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_xpath("//select[#class='select_report_type ng-pristine ng-untouched ng-valid']"))
select.select_by_index(1)
// OR
select.select_by_visible_text("text")
// OR
select.select_by_value(value)
Let me know if still facing same issue or any further things

Categories