Dropdown menus in python / selenium - python

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

Related

Cannot click on radio button in fieldset

I am using python with selenium to automate some process but I am having problems to click a radio button. This is the situation:
Code:
<div class="cart">
<form method="post" id="pmntFrm" name="chsPmntRt" action="/cart" class="form-validate">
<fieldset>
<div class="payment-field">
<input onchange="load('payment', 1)" type="radio" name="paymentmethod_id" id="payment_id_1" value="123">
<label for="payment_id_1" class="">
//foo
</label>
<input onchange="load('payment', 2)" type="radio" name="paymentmethod_id" id="payment_id_2" value="456">
<label for="payment_id_2" class="">
//foo
</label>
</div>
</fieldset>
</form>
</div>
I have tried click on it using:
driver.find_element_by_xpath(".//input[#type='radio' and #value='1']").click()
and I receive this error Message=Message: element not interactable
Also I read in other thread that maybe the problem is that the fieldset is in a different but is not.
I really apreciate if someone can help me with this topic.
Thank you and have a nice day!
To wait for the element to be clickable induce a webdriver wait and then click. Also don't use . it's for child elements not root driver.
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH,"//input[#type='radio' and #value='1']"))).click()
Or the label
wait.until(EC.element_to_be_clickable((By.XPATH,"//label[#for='payment_id_1']"))).click()
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

How to make textbox input in selenium with xpath

I made script that automatically picks a product from kith.com and go to the checkout:
element3 = driver.find_element_by_xpath('//*[#id="CheckoutData_BillingFirstName"]')
element3.send_keys("My First Name")
Kiths website:
<div class="col-sm-8 col-xs-12 fval">
<input class="form-control input-validation-error" data-val="true" data-val-countryaddressvalidation="" data-val-countryaddressvalidation-countryaddressvalidationpropname="" data-val-required="Billing First Name is required" data-val-unsupportedcharacters="Please use English characters only" data-val-unsupportedcharacters-unsupportedcharacterspattern="^[A-Za-z0-9,""'`\s#&%$#\*\(\)\[\]._\-\s\\/]*$" id="CheckoutData_BillingFirstName" maxlength="40" name="CheckoutData.BillingFirstName" placeholder="First Name" type="text" value=""><span class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
</div>
How can I locate the input form and send keys to it?
I am getting the same error every time :
Unable to locate element: {"method":"xpath","selector":"//*[#id="CheckoutData_BillingFirstName"]"}
Your target element inside a <frame>:
<iframe src="https://fs.global-e.com/Checkout/v2/f77781eb-a7c0-43e2-822a-3ca96e8658f0?gaSesID=361925132.674171348.583&gaMerchantClientInfo=undefined#undefined&chkcuid=3ef950c0-4c7d-4cfe-bab5-3a1ed7035318&isNECAllowed=true&vph=631&ift=87" class="Intrnl_CO_Container" id="Intrnl_CO_Container" name="Intrnl_CO_Container" allowtransparency="true" width="100%" scrolling="no" marginheight="0" marginwidth="0" frameborder="0" height="1000px" style="height: 2196px;"></iframe>
You need to switch it first:
#after clicked checkout button
time.sleep(10)
driver.switch_to.frame(driver.find_element_by_id("Intrnl_CO_Container"))
time.sleep(10)
element3 = driver.find_element_by_xpath('//*[#id="CheckoutData_BillingFirstName"]')
element3.send_keys("My First Name")
But there is a better way to wait in selenium, for detail you can read the #pcalkins suggestion.
After clicked checkout button, you can add following code:
#after clicked checkout button
wait = WebDriverWait(driver, 20)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, 'Intrnl_CO_Container')))
element3 = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="CheckoutData_BillingFirstName"]'))).click()
element3.send_keys("My First Name")
Please import:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

UnexpectedTagNameException: Select only works on <select> elements, not on "<form>" error selecting a drop-down value using Selenium and Python

I am trying to select an option from this dropdown with Selenium using Python
<div class="form-group mt-2 mb-3 p-3">
<form id="did_atd_provide_pnc">
<fieldset>
<label for="did_atd_provide_pnc">Did ATD Consultants provide a Plan & Cost review for
this project*?</label>
<select class="form-control form-control-sm required-field atd_provided_dropdown" id="did_atd_provide_pnc"
name="did_atd_provide_pnc" data-error-name="Did ATD Provide P&C">
<option value="">-----</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</fieldset>
</form>
</div>
I am writing this code
select = Select(driver.find_element_by_id('did_atd_provide_pnc'))
select.select_by_visible_text('No')
But I am getting this error
UnexpectedTagNameException: Select only works on <select> elements, not on "<form>"
Is there any other solution I can test this case with any other reliable solution?
You were close enough. However the first element to be identified through find_element_by_id('did_atd_provide_pnc') is the <form> tag, where as your desired element is the <select> tag.
Hence, the Select() throws error with the <form> element as:
UnexpectedTagNameException: Select only works on <select> elements, not on "<form>"
Solution
To select <option> with text as No you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following xpath based Locator Strategies:
Using xpath and select_by_visible_text():
Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[#id='did_atd_provide_pnc' and #name='did_atd_provide_pnc']")))).select_by_visible_text("No")
Using xpath select_by_value():
Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[#id='did_atd_provide_pnc' and #name='did_atd_provide_pnc']")))).select_by_value("No")
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
References
You can find a couple of relevant detailed discussions in:
UnexpectedTagNameException: Message: Select only works on elements, not on error selecting an Dropdown option using Selenium and Python

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 Selenium - Python 3

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

Categories

Resources