So I am trying to run the following code to select an option from a drop-down toolbar:
## Drop-down menu
time.sleep(5) # wait for element to load in page otherwise selenium won't be able to find it
element_dropdown = driver.find_element("id","conference-dropdowns")
element_dropdown.click()
# Select visible text
time.sleep(5)
select = Select(element_dropdown)
select.select_by_visible_text("Bulk Upload")
But then I get the following error:
UnexpectedTagNameException: Message: Select only works on <select> elements, not on <label>
How do I resolve this issue? Why am I getting this error? See structure below. Thanks so much in advance.
The desired element isn't within any html-select tag, but they are within <label> tag.
So you won't be able to use Select() class.
Solution
The click element with text as Bulk Upload you need to induce WebDriverWait for the element_to_be_clickable() and you can use the following locator strategy:
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[#class='dropdown-submenu']//label[#class='submenu' and contains(., 'Bulk Upload')]"))).click()
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
The Exception says everything: you can use Select class only with <select> object.
Simply try to
click() on button to expand drop-down menu
wait for required option to be clickable
click() on option
Related
I am trying to select a value from a dropdown menu using the Selenium Select method but I am unable to correctly locate the right element as illustrated in other Stackoverflow posts as my element lacks an ID as in other Stackoverflow posts. I have tried using the Xpath, Class_Name and CSS_Selector as an alternative but I keep getting an error "Unable to locate element".
This is the HTML:
<select class="lf-simpelselect lf-bottom-margin" data-bind="options: activiteitenOptions, value: activiteit, optionsText: 'Naam', optionsValue: 'Id', visible: toonActiviteiten()" style=""><option value="0bdae2c9-6ebc-4396-b3bb-0e587f9bbe86">Latin Jam</option><option value="c18aef82-be4d-4881-ae96-28aa72161c17">Kiddo Swing 6-8 jr</option><option value="8cbe6618-68cd-47f1-8a79-29db71498292">Ballet </option><option value="8d03eb2f-02ea-434d-8520-30b2f02e18f1">Pilates</option><option value="30358ec5-9751-4b13-8514-4db7b541c540">Gold 40+</option><option value="b811c4be-703b-4193-8f60-57bdb574a60a">Feminine</option><option value="2c6b4f41-6953-4347-99b9-70c33f48da07">City Jam</option><option value="696ba3a2-a453-4550-9cbe-7a00d46dfb14">Dojo</option><option value="fc8b9e43-401f-4e38-8d0b-8afba5f1226b">Power Jam</option><option value="7192a0d5-65b1-43a0-80d6-987b90cf505c">Dans Mix 9 - 12 jr</option><option value="820cf6c6-c9a6-4759-939e-988c646a69f7">Barre Workout</option><option value="e9bfd01d-b183-483a-b809-b2d9dd62354d">Latin House 18+</option><option value="505e1c62-9e68-4569-a7ef-b6566ff1b56d">Afro</option><option value="e4899faa-969e-4953-af1f-bc7eba080bec">Hip Hop</option><option value="796f9e98-f54c-486c-bc62-e6a2e74a5f45">Contemporary Flow </option><option value="88845fb5-e1ab-418d-ba3c-ed1131821835">Modern</option><option value="cb7fa275-b034-4f04-8265-ef747fe73179">Dancehall</option></select>
The code of my try at using the Select() to change the value is as follows:
url = "https://prd.mylogifit.com/logifitweb/genericwidgetbyid.html?a=Touchee&widgetId=73f1f696-5063-4fb7-9a8d-c588ef149eb4"
browser = webdriver.Chrome(executable_path='./chromedriver')
browser.get(url)
# Select lesson type (afro)
lesson_droplist = Select(browser.find_element(By.CLASS_NAME, 'lf-simpelselect lf-bottom-margin'))
lesson_droplist.select_by_value("Afro")
How do I use the Select method to change the drop-down value from Hip-Hop to Afro?
To select the <option> with text as Pilates as the desired element is a dynamic element, you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
driver.get("https://prd.mylogifit.com/logifitweb/genericwidgetbyid.html?a=Touchee&widgetId=73f1f696-5063-4fb7-9a8d-c588ef149eb4")
Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.lf-simpelselect.lf-bottom-margin[data-bind*='activiteitenOptions']")))).select_by_visible_text('Pilates')
Using XPATH:
driver.get("https://prd.mylogifit.com/logifitweb/genericwidgetbyid.html?a=Touchee&widgetId=73f1f696-5063-4fb7-9a8d-c588ef149eb4")
Select(WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//select[#class='lf-simpelselect lf-bottom-margin' and contains(#data-bind, 'activiteitenOptions')]")))).select_by_visible_text('Pilates')
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
from selenium.webdriver.support.ui import Select
Browser snapshot:
References
You can find a couple of relevant discussions in:
How to select an option from the dropdown menu using Selenium and Python
from selenium.webdriver.support.ui import Select
lesson_droplist = Select(driver.find_element(By.CLASS_NAME, "lf-simpelselect"))
lesson_droplist.select_by_visible_text("Afro")
You should select by visible text not value
If you want to select by value then
lesson_droplist= Select(driver.find_element(By.CLASS_NAME, "lf-simpelselect"))
lesson_droplist.select_by_value("505e1c62-9e68-4569-a7ef-b6566ff1b56d") #Afro's value
The Class name has more than one matches, that is why you are getting that error, try the below XPath:
from selenium.webdriver.support.select import Select
dropdown = Select(driver.find_element(By.XPATH, "(.//select[#class='lf-simpelselect lf-bottom-margin'])[2]"))
dropdown.select_by_visible_text("Afro")
You can use XPath with some solution for waiting. There are two option time library or WebDriverWait.
You can try this one for time libray:
import time
time.sleep(3)
dropdown = Select(browser.find_element(By.XPATH, "(.//select[#class='lf-simpelselect lf-bottom-margin'])[2]"))
dropdown.select_by_visible_text("Afro")
time.sleep(3)
text = browser.find_element(By.XPATH, "//div[#data-bind='text: lesOmschrijving()']").text
print(text)
You can try this for WebDriverWait(but its just wait for this XPath and you might be need another waiting for getting another text):
wait.until(EC.presence_of_element_located((By.XPATH, "(.//select[#class='lf-simpelselect lf-bottom-margin'])[2]")))
Generally, you need an wait to make sure the relevant elements are loaded in the browser.
I am trying to select a dropdown value using Selenium in Python but not able to do so. The code I get from "Copy Selector" is this.
#mui-12848
The complete HTML is
<input aria-invalid="false" autocomplete="off" type="text" class="MuiInputBase-input MuiOutlinedInput-input MuiAutocomplete-input Reports-autocompleteInput-133 MuiAutocomplete-inputFocused MuiInputBase-inputAdornedEnd MuiOutlinedInput-inputAdornedEnd" aria-autocomplete="list" autocapitalize="none" spellcheck="false" value="Monthly" id="mui-12848" aria-activedescendant="mui-12848-option-1" aria-controls="mui-12848-popup">
I have tried
s1 = Select(browser.find_element_by_id("mui-12848"))
s1.select_by_visible_text('Quarterly')
which gives the following error
UnexpectedTagNameException: Message: Select only works on elements, not on
I have also tried
browser.find_element(By.XPATH("//*[#id='mui-12848'][2]")).click();
which gives the following error
TypeError: 'str' object is not callable
Any help is appreciated.
Following is the Screenshot
Your input type for that HTML element is text, it's not a Select or a dropdown. The selenium class supports Select.
This error message...
UnexpectedTagNameException: Message: Select only works on elements, not on
...implies that you tried to use Select() class which works only on <select> element where as the desired element was an <input> element.
To click on the <input> element you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element_by_css_selector("input[class*='MuiInputBase-input'][id^='mui'][value='Monthly']").click()
Using xpath:
driver.find_element_by_xpath("//input[contains(#class, 'MuiInputBase-input') and starts-with(#id, 'mui')][#value='Monthly']").click()
Ideally, to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[class*='MuiInputBase-input'][id^='mui'][value='Monthly']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[contains(#class, 'MuiInputBase-input') and starts-with(#id, 'mui')][#value='Monthly']"))).click()
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
The syntax is incorrect.
It should be like driver.find_element(By.XPATH, "//*[#id='mui-12848']").click()
Moreover, you cannot include the index inside the locator. You will need to use find_elements first and then use the index on top of that: driver.find_elements(By.XPATH,"//*[#id='mui-12848']")[2].click()
Try using expected_conditions. See below. Replace browser = ..... with your code.
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
browser = .....
# ADD YOUR CODE TO GET TO THE PAGE WITH THE BUTTON
to_click = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, "//*[#id='mui-12848'][2]")))
to_click.click()
I'm working with Selenium as a newbie and also as a newbie developer.
I try to solve this XPath but with no results that is why I'm looking for help.
So I want to click in the checkbox which has a dynamic id but it is not that easy to find this checkbox based on tittle="Viewers"
Please notice there is a whole list of checkboxes with names on right from a checkbox in div which I want to include in my tests.
HTML:
<span class="row-selection"><input type="checkbox" value="on" id="gwt-uid-2215" tabindex="0"><label for="gwt-uid-2215"></label></span> <div class="row-label" title="Viewers">Viewers</div>
Snapshot;
The desired element is a GWT enabled element so to click on the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following xpath based Locator Strategy:
Using xpath based on title attribute:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#title='Viewers']//preceding::span[1]//label"))).click()
Using xpath based on innerHTML:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[text()='Viewers']//preceding::span[1]//label"))).click()
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
I'm trying to get Python / Selenium to properly click on a dropdown menu and select "IT" but the best I could do was find the element and get an error stating I couldn't input text on what I have found.
Basically, the user would click on that menu and select IT or type IT and press enter.
HTML code:
<div class="form-group">
<label class="col-md-3 control-label" for="id_tenant_group">Tenant group</label>
<div class="col-md-9">
<select name="tenant_group" nullable="true" class="netbox-select2-api form-control" data-url="/api/tenancy/tenant-groups/" data-filter-for-tenant="group_id" placeholder="None" id="id_tenant_group">
<option value="" selected>---------</option>
<option value="2">IT</option>
<option value="1">OT</option>
</select>
</div>
When I inspect the element, I can see there is a span element that triggers an event showing another span where finally my option can be seen.
I cannot select via visible text, because other menus also contain the same "---------" visible text.
I've captured a couple screenshots to illustrate the issue, hope that helps.
html code browser inspect
To be honest I am really lost, any suggestions will be much appreciated.
EDIT:
I've attempted the following:
tenant_g_element = Select(browser.find_element(By.XPATH, '//span[#id="select2-id_tenant_group-container"]'))
tenant_g_element.selectByVisibleText("IT")
But I've got the following error:
selenium.common.exceptions.UnexpectedTagNameException: Message: Select only works on <select> elements, not on span
Your first line is wrong. It should be something like this:
tenant_g_element = Select(browser.find_element(By.ID, 'id_tenant_group'))
because your has the attribute id="id_tenant_group". There is no need to use By.XPATH...if you have some reason to need that, then you'll need to look up how to specify an XPATH (note that //span is going to find a <span>, not a <select> for example).
This error message...
selenium.common.exceptions.UnexpectedTagNameException: Message: Select only works on elements, not on span
...implies that the element which you are passing to Select class is not a <select> node but a <span> element which isn't supported.
Seems your locator was identifying a <span> element instead of the <select> element. Hence you see the error. Additionally, selectByVisibleText() is not a valid Python method, instead you need to use select_by_visible_text().
Solution
To click on the option with text as IT, you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR and select_by_value():
tenant_g_element = Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "select.netbox-select2-api.form-control#id_tenant_group[name='tenant_group']"))))
tenant_g_element.select_by_value("2")
Using XPATH and select_by_visible_text():
tenant_g_element = Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[#class='netbox-select2-api form-control' and #id='id_tenant_group'][#name='tenant_group']"))))
tenant_g_element.select_by_visible_text("IT")
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
from selenium.webdriver.support.ui import Select
Your Xpath seems wrong. You are trying to locate a span tag but you should locate select element. Additionally you should apply webdriver wait for of select element
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
select = Select(WebDriverWait(driver, 50).until(
EC.presence_of_element_located((By.ID, "id_tenant_group"))))
WebDriverWait(driver, 50).until(
EC.presence_of_element_located((By.XPATH, "//select[#id='id_tenant_group']/option[2]")))
WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, "//select[#id='id_tenant_group']//options[contains(.,'IT')]")))
select.select_by_visible_text('IT')
Tried something like this in python unable I want to click on cross using Selenium.
driver.find_element_by_xpath("//span[contains(#onclick, 'parent.$WZRK_WR.closeIframe('60005','intentPreview');')]").click()
As per the HTML you have shared to click on the element depicted as X, first you need to induce WebDriverWait while switching to the <iframe> and again induce WebDriverWait for the desired element to be clickable and you can use the following solution:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='wiz-iframe-intent']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='CT_Interstitial']//span[#class='CT_InterstitialClose']"))).click()
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
Open below URL and Click on Add to Chrome button.
Xpath Helper- https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl?hl=en
Once plugin added to Chrome. Open your application/webpage and press SHIFT+CTRL+X. Black window will appear on top then you can play with xpath.
If xpath is invalid- then you will get xpath error and if no matches found then it will display NULL.
Note- To check element attribute still you can use F12 that is nothing but default inspect element for all browser then check attribute and create your own xpath and try.
Xpath Syntax
// tagname[#attribute-name=’value1′] and if you are not sure about tag name then no worry you can try with * also
//*[#attribute-name='value1']
You are dealing with an iframe. Follow below steps :
You'll need to switch control to iframe.
Then perform your action (in this case 'Click close').
Switch the control back to default frame.
You can try with this css_selector :
div.CT_InterstitialContents+span.CT_InterstitialClose[onclick]
Xpath would be :
//div[#class='CT_InterstitialContents']/following-sibling::span[#class='CT_InterstitialClose' and onclick]
Try to use this xPath:
//div[#id = 'contentDiv']/div/div/span[#class = 'CT_InterstitialClose']
Code:
close_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#id = 'contentDiv']/div/div/span[#class = 'CT_InterstitialClose']")))
close_btn.click()
Imports:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
Explanation:
WebDriverWait is used to wait until element will be clickable, and only then clicks on it. In this example WebDriverWait will wait at least 10 seconds until element will be clickable.
PS: as I see in the screenshot your element is probably in iframe. That means you have to switch to this iframe first, to be able to interact with the elements in it. The code sample for it would be like this:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "XPATH_TO_FRAME")))
# do stuff
close_btn = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[#id = 'contentDiv']/div/div/span[#class = 'CT_InterstitialClose']")))
close_btn.click()
# switch back to default content
driver.switch_to.default_content()
You can write xpath using class name of span. Please refer an example below.
//span[#class='amountCharged']