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')
Related
been dealing with a countries dropdown using Selenium Python;
here is the Div tag of the drop-down menu:
<div cdk-overlay-origin="" class="mat-select-trigger ng-tns-c95-29"><div class="mat-select-value ng-tns-c95-29" id="mat-select-value-1"><span class="mat-select-placeholder mat-select-min-line ng-tns-c95-29 ng-star-inserted"></span><!----><!----></div><div class="mat-select-arrow-wrapper ng-tns-c95-29"><div class="mat-select-arrow ng-tns-c95-29"></div></div></div><!---->
and here is the Div tag for the targeted option:
<div class="mat-select-value ng-tns-c95-29" id="mat-select-value-1"><!----><span class="mat-select-value-text ng-tns-c95-29 ng-star-inserted" style=""><span class="mat-select-min-line ng-tns-c95-29 ng-star-inserted">MAROKO</span><!----><!----></span><!----></div><div class="mat-select-arrow-wrapper ng-tns-c95-29"><div class="mat-select-arrow ng-tns-c95-29"></div></div>
and here's the specific Span Tag for the targeted option
<span class="mat-select-min-line ng-tns-c95-29 ng-star-inserted">MAROKO</span><!----><!---->
the code used to select an option from that dropdown is :
Country=browser.find_element(By.ID, 'mat-select-value-1')
time.sleep(5)
drop=Select(Country)
time.sleep(5)
drop.select_by_visible_text("MAROKO")
output
Exception has occurred: UnexpectedTagNameException
Message: Select only works on <select> elements, not on <div>
File "C:\Users\test\form.py", line 31, in <module>
drop=Select(Country)
I went with drop.select_by_visible_text since I believe it's the only available option!
Imports used
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support import expected_conditions as EC
import time
I would appreciate any helpful comment.
Cheers
Tried this
specifcly this;
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[#id="mat-radio-2"]/label/span[1]/span[1][text()='MAROKO']"))).click()
but it seems that there's a syntax error
You can use the selenium's Select() class only for html <select> tags. But this dropdown is implemented with <div>, so you can handle it just like html elements.
First you need to click the dropdown to expand the options and then click the option you need:
WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, '//div[#class="mat-select-trigger ng-tns-c95-29"]'))).click()
WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.ID, 'mat-select-value-1'))).click()
I've created the locators using the html parts you provided. Perharps you will need to update them.
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
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
Here are all the parts of the element I am trying to click according to 'Inspect':
<div class="ui-dialog-buttonpane ui-widget-content ui-helper-clearfix">
::before
<div class="ui-dialog-buttonset">
<button type="button" class="done ui-button ui-corner-all ui-widget">
Done</button>
</div>
::after
</div>
When I want to click it, I assume it is on the ::before part as it is showing and clickable. In the code, I make sure to scroll and wait two seconds before clicking to make sure that the button is visible and yet I get:
selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable
But I don't understand how it's not interactable. When I hover over it in the inspector, everything in <button>...</button> highlights, so the button I want to click must be in there, right?
Here are few things that I have tried:
browser.find_element_by_css_selector('button[type=button]').click()
browser.find_elements_by_xpath("//*[contains(text(), 'Done')]").click()
# The above returns a list for some reason?
browser.find_elements_by_css_selector('done.ui-button.ui-corner-all.ui-widget')
I wish I could remember all that I tried, but regardless I hope someone can help me.
To click on the element as the desired element is a dynamic element you have to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.ui-dialog-buttonpane.ui-widget-content.ui-helper-clearfix"))).click()
Using XPATH:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='ui-dialog-buttonpane ui-widget-content ui-helper-clearfix']"))).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
You can find a detailed discussion in selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable using Selenium
When you use .find_elements (note the plural) it will return a list instead of a single element like .find_element (singular) does. Have you tried
browser.find_element_by_xpath("//button[.='Done']")
If you get a len() on these .find_elements calls... is it 1? I'm wondering if there isn't more than one button that matches the locators you are using and the first isn't visible but you want the second or third, etc.
You can use ActionChains to move to element
from selenium.webdriver.common.action_chains import ActionChains
element = driver.find_elements_by_css_selector("div.ui-dialog-buttonpane.ui-widget-content.ui-helper-clearfix")
actions = ActionChains(driver)
actions.move_to_element(element).perform()
or u can scroll till element is in view using scrollIntoView():
driver.execute_script("arguments[0].scrollIntoView();", element)