Dropdown Menus in Selenium - Python 3 - python

I am trying to access a dropdown menu using selenium for HTML that looks like this:
<span class="k-pager-sizes k-label">
<span title="" class="k-widget k-dropdown k-header" unselectable="on" role="listbox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-owns="" aria-disabled="false" aria-readonly="false" aria-busy="false" aria-activedescendant="8e90d557-7e8d-4c5c-b906-202fd78c6d0a"><span unselectable="on" class="k-dropdown-wrap k-state-default">
<span unselectable="on" class="k-input">20</span><span unselectable="on" class="k-select">
<span unselectable="on" class="k-icon k-i-arrow-s">select</span>
</span>
</span>
<select data-role="dropdownlist" style="display: none;">
<option value="10">10</option><option value="15">15</option>
<option value="20">20</option><option value="50">50</option>
<option value="100">100</option>
</select>
<span>items per page</span>
I have tried the following without success:
try:
driver = webdriver.Chrome('/Users/opusandcaymus/Election/chromedriver')
driver.get('http://mcad-tx.org/Property-Search-Result?searchtext=Maple%20Branch')
#dropdown=driver.find_element_by_xpath('//*[#id="grid"]/div[3]/span[2]/span/select')
#select = Select(dropdown)
dropdown = driver.find_elements_by_tag_name("option")
for row in dropdown:
print(row.value)
driver.close()
except:
print("error")
driver.close()
raise
Does anyone know how to find the options by the values? I want to select 100 every time the page is opened.

Your select dropdown is hidden so for that i would suggest first make it visible using javascriptexecuter then select the value
Use below code :
element=driver.find_element_by_xpath("//select[#data-role='dropdownlist']")
driver.execute_script("arguments[0].setAttribute('style', 'display: block;')",element)
select = Select(element)
select.select_by_value("100")
And The other way is use Explicitwait
First click on down arrow and of dropdown and then click on value 100
Something like below code in python :
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.XPATH, ".//*[#id='grid']/div[3]/span[2]/span/span/span[2]/span")))
element.click
element = wait.until(EC.visibility_of_element_located((By.XPATH, ".//ul[#data-role='staticlist']/li[5]")))
element.click
Note : please make correction as per python syntax

Related

How to click on hidden select under button

I need to select a URL value, but I don't understand how to do it
<span class="select select_layout_content select_size_s select_theme_normal
queries-filter-item__indicator i-bem select_js_inited _popup-destructor
_popup-destructor_js_inited"
data-bem="{"select":{"live":false}}" title="">
<button class="button button_arrow_down button_theme_normal button_size_s select__button i-bem button_js_inited" type="button" autocomplete="off" role="listbox" aria-haspopup="true" aria-expanded="false" data-bem="{"button":{}}">
<span class="button__text" aria-hidden="true">Total shows</span>
</button>
<select class="select__control" id="uniq16686900391151" tabindex="-1" aria-hidden="true">
<option class="select__option" value="TOTAL_SHOWS_COUNT" selected="selected">Total shows</option>
<option class="select__option" value="TOTAL_CLICKS_COUNT">Clicks count</option>
<option class="select__option" value="AVERAGE_SHOW_POSITION">Average Position</option>
<option class="select__option" value="TOTAL_CTR">CTR, %</option>
<option class="select__option" value="URL">URL</option>
<option class="select__option" value="QUERY">Text</option>
</select>
</span>
My code (the last command) get "Message: element not interactable: Element is not currently visible and may not be manipulated"
# Click on make filter - is works
driver.find_element(By.XPATH, "/html/body/div[3]/div[1]/div[1]/div[2]/div[2]/div/form/span/span").click()
time.sleep(1)
# Click on select button - is works
driver.find_element(By.XPATH, "/html/body/div[3]/div[1]/div[1]/div[2]/div[2]/div/form/div[1]/div/span[1]/button").click()
time.sleep(5)
# Click on URL option
driver.find_element(By.XPATH, "/html/body/div[3]/div[1]/div[1]/div[2]/div[2]/div/form/div[1]/div/span[1]/select/option[5]").click()
I'm not sure if this will work with the element that has the attribute aria-hidden="true".
There is a special class in Selenium for the select elements. First, you need to import the Select class. You can try to use this code:
from selenium.webdriver.support.select import Select
# Click on make filter - is works
driver.find_element(By.XPATH, "/html/body/div[3]/div[1]/div[1]/div[2]/div[2]/div/form/span/span").click()
time.sleep(1)
# Click on select button - is works
driver.find_element(By.XPATH, "/html/body/div[3]/div[1]/div[1]/div[2]/div[2]/div/form/div[1]/div/span[1]/button").click()
time.sleep(5)
# Click on URL option
dropdown = Select(driver.find_element(By.ID, 'uniq16686900391151'))
dropdown.select_by_value('URL')

Can find element within an iframe using Firefox but not Chrome

So I'm trying to write a test for a webpage which has some elements within an iframe. I've been able to successfully run the test using webdriver.Firefox() without any problems but if I switch it over to webdriver.Chrome() I get a timeout exception on the following lines of code:
self.driver.switch_to.frame(0)
self.activity_status = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, '#overview > div.details.w-66 > div > div.duration-and-status > span.status.stat_incomplete#')))
It'd be great to get a solution to this as I'm all out of ideas.
Thanks for your help.
edit, partial html for the page:
<iframe id="iframe_course_details" allowfullscreen="" src="../Course/Details.aspx?HidePageNav=true&IsInIframe=true"></iframe>
Close
Edit (Inactive)
Edit
<span id="ctl00_cph_main_content_area_ucCourseDetails_spn_favourite" class="favourite button tooltipstered" style="display: none;">Favourite</span>
<span id="ctl00_cph_main_content_area_ucCourseDetails_spn_basket_dull" class="add-to-basket button delete tooltipstered" style="display: none;">Enrolled (Remove From Enrolments)</span>
<span id="ctl00_cph_main_content_area_ucCourseDetails_spn_basket" class="add-to-basket button tooltipstered">Add to Enrolments</span>
<span id="ctl00_cph_main_content_area_ucCourseDetails_spn_print" class="print button tooltipstered">Print</span>
</div>
<section id="overview" style="opacity: 1;">
<div id="fullname" class="fullname w-100" style="display: none;">
</div>
<div class="image w-33" style="cursor: pointer;">
<div style="background-image:url(/App_Themes/MainTheme-responsive/Images/Course/webcast.jpg);"></div></div>
<div class="details w-66">
<div class="inner">
<h2>testing activity</h2>
<div class="star-rating-num-ratings">
<div class="star-rating">
<span></span><span></span><span></span><span></span><span></span>
</div>
<span class="num-of-ratings">0 Ratings</span>
</div>
<div class="duration-and-status">
<span class="duration">
<label>
Duration:
</label>
<span>0</span>
</span>
<span class="status stat_incomplete">Started</span>
</div>
Edit 2:
So we've managed to find a solution to this and its even more confusing than the original problem
WebDriverWait(self.driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'iframe_course_details')))
time.sleep(0)
self.activity_status = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//*[#id="overview"]/div[3]/div/div[2]/span[2]')))
I'd be really curious to hear some theories on why this works, it times out without the 'time.sleep(0).
If you reference the iframe directly rather then an integer that will work between Firefox/Chrome.
self.driver.switch_to.frame(driver.find_element_by_name("iframe"))
You can find the iframe element any way you wish e.g by css/xpath etc
As the the desired element is within an <iframe> so to invoke click() on the element you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Code Block:
# as per your comment assuming -> there is only one frame on the page
WebDriverWait(self.driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.TAG_NAME,"iframe")))
self.element = self.activity_status = WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, '#overview > div.details.w-66 > div > div.duration-and-status > span.status.stat_incomplete#')))
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Reference
You can find a relevant detailed discussion in:
Ways to deal with #document under iframe

Scrapy, Selenium, jQuery Dropdown inconsistent behavior with select tag having style="display: none;"

I'm trying to set dropdowns on this page:
The first dropdown and the fourth dropdown are very similar (brands and country). This is the code I'm using for getting the brand (oem) and country:
oem = Select(wd.find_element_by_css_selector("#alBrandsList"))
oem.select_by_visible_text("Acer")
countries = Select(wd.find_element_by_css_selector("#alCountriesList"))
countries.select_by_visible_text("Albania")
The dropdown is technically hidden, but it somehow seems to work for the device/oem dropdown. For the countries dropdown it is saying that the content isn't visible (which it is). Here's the HTML code it's pulling from:
<select class="pretty-dropdown" datatosent="brand" id="alBrandsList" name="alBrandsList" selectorid="alPhoneModelsList" target="/AdvanceLookup/GetPhoneModels/" style="display: none;">
...
</select>
<button type="button" class="ui-multiselect ui-widget ui-state-default ui-corner-all" aria-haspopup="true" style="width: 232px;">
<span class="ui-icon ui-icon-triangle-2-n-s"></span>
<span>Please select brand(s)</span>
</button>
<select class="pretty-dropdown" datatosent="country" id="alCountriesList" name="alCountriesList" selectorid="alCarriersList" target="/AdvanceLookup/GetCarriers/" style="display: none;">
...
</select>
<button type="button" class="ui-multiselect ui-widget ui-state-default ui-corner-all" aria-haspopup="true" style="width: 232px;">
<span class="ui-icon ui-icon-triangle-2-n-s"></span>
<span>Please select country</span>
</button>
Any idea why it works on the first one but not the second one?
As both the <select> tags for the first and the fourth dropdown on the page https://willmyphonework.net/AdvanceLookup is having the property style="display: none; you can't use Select Class. Instead you need to to induce WebDriverWait for the element_to_be_clickable() and you can use the following Locator Strategies:
Code Block:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver.get('https://willmyphonework.net/AdvanceLookup')
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='ui-multiselect ui-widget ui-state-default ui-corner-all']//span[text()='Please select brand(s)']"))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//ul[#class='ui-multiselect-checkboxes ui-helper-reset']//li/label/input[#title='Acer']"))).click()
driver.find_element_by_xpath("//ul[#class='ui-helper-reset']//li/a/span[#class='ui-icon ui-icon-circle-close']").click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='ui-multiselect ui-widget ui-state-default ui-corner-all']//span[text()='Please select country']"))).click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//ul[#class='ui-multiselect-checkboxes ui-helper-reset']//li/label/input[#title='Albania']"))).click()
driver.find_element_by_xpath("//div[#class='ui-multiselect-menu ui-widget ui-widget-content ui-corner-all']//following::ul[6]//a[#class='ui-multiselect-close']/span[#class='ui-icon ui-icon-circle-close']").click()
Browser Snapshot:

How to Click an Element inside a p-dropdown tag using Selenium and Python

<p-dropdown _ngcontent-c16="" autofocus="" placeholder="Select Quota" class="ng-tns-c13-11 ui-inputwrapper-filled ng-untouched ng-pristine ng-valid">
<div class="ng-tns-c13-11 ui-dropdown ui-widget ui-state-default ui-corner-all ui-helper-clearfix" style="width: 234px;">
<div class="ui-helper-hidden-accessible ng-tns-c13-11 ng-star-inserted">
<select class="ng-tns-c13-11" aria-hidden="true" tabindex="-1" aria-label="A">
<option class="ng-tns-c13-11 ng-star-inserted">Select</option>
<option class="ng-tns-c13-11 ng-star-inserted" value="GN">A</option>
<option class="ng-tns-c13-11 ng-star-inserted" value="SS">B</option>
<option class="ng-tns-c13-11 ng-star-inserted" value="LD">C</option>
<option class="ng-tns-c13-11 ng-star-inserted" value="HP">D</option>
<option class="ng-tns-c13-11 ng-star-inserted" value="TQ">E</option>
<option class="ng-tns-c13-11 ng-star-inserted" value="PT">F</option>
<!----></select>
</div>
I need to select a value inside the drop down
the xpath I tried using is :
driver.find_element_by_xpath("//*[#value='LD']").click()
But that says element not found...What other expression can be used to choose an option inside a DropDown?
Also is it possible to do it like mentioned below
driver.find_element_by_xpath("//*[#placeholder='Select Quota']").click()
followed by something else?
This drop down has been construct using select and options tags. So select class should work.
You can try with this code :
select = Select(driver.find_element_by_css_selector("select.ng-tns-c13-11"))
# select by visible text
select.select_by_visible_text('C')
Imports you will have to do :
from selenium.webdriver.support.ui import Select
As the <select> element is a Angular element so you have to induce WebDriverWait for the <select> element to be clickable and utilizing the Select class you can use the following solution:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
# other lines of code
mySelect = Select(WebDriverWait(driver, 20).until(EC.visibilty_of_element_located((By.XPATH, "//select[contains(#class,'ng-tns-') and #aria-label='A']"))))
# select by value
mySelect.select_by_value("LD")
Just need to wait for the LD element to be clickable first, like so...
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//*[#value='LD']")))

Dropdown menus in python / selenium

Trying to autofill a form using python and selenium. Dropdown menu html is:
<select id="typeOfTeacher" class="chosen-select-no-single ng-untouched ng-dirty ng-valid-parse ng-valid ng-valid-required" required="" ng-class="{ 'has-error' : positionDetailForm.typeOfTeacher.$invalid && !positionDetailForm.typeOfTeacher.$pristine }" ng-change="vm.setRequired()" tabindex="-1" ng-model="vm.data.typeOfTeacher" name="typeOfTeacher" data-placeholder="Select" style="display: none;">
<option value="" disabled="" selected="">Select</option>
<option class="ng-binding ng-scope" value="1" ng-repeat="teacherType in vm.teacherTypes">No position at the moment</option>
<option class="ng-binding ng-scope" value="2" ng-repeat="teacherType in vm.teacherTypes">Supply</option>
<option class="ng-binding ng-scope" value="3" ng-repeat="teacherType in vm.teacherTypes">Permanent</option>
</select>
Python code is:
elem = Select(browser.find_element_by_id('typeOfTeacher'))
elem.select_by_value("1")
Error is "element is not currently visible and may not be interacted with".
I have not used the python Select method, but I would guess that the error message means that the menu is not being opened, and therefore an element in the menu is still hidden and cannot be interacted with.
Try something like this:
element = driver.find_element_by_id('typeOfTeacher').click()
driver.find_element_by_css_selector("[value=\"1\"]").click()
This would work
element = driver.find_element_by_id('typeOfTeacher').click()
element.find_element_by_xpath(".//option[#value='1']").click()
It looks like timing issue. You should try using Waits.
I would suggest you, use WebDriverWait to wait until dropdown visible before interaction as below :-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "typeOfTeacher")))
select = Select(element)
select.select_by_value("1")

Categories

Resources