So I know that when I have DEBUG in my Django settings set to False, Selenium fails to have access to the static files, resulting in something looking like:
However, when I run my Selenium tests regardless they are able to interact with the DOM and select items from the dropdown! The test code I have is currently
from selenium.webdriver import Chrome
from selenium.webdriver.support.ui import Select
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from urllib.parse import urljoin
import time
driver = webdriver.Chrome()
driver.get("localhost:8000/")
time.sleep(3)
driver.find_element_by_id('select-dance').click()
select = Select(driver.find_element_by_xpath('//*[#id="select-dance"]'))
select.select_by_value('1')
driver.find_element_by_id('select-date-range').click()
select = Select(driver.find_element_by_xpath('//*[#id="select-date-range"]'))
select.select_by_value('1')
driver.find_element_by_id('location').click()
When I set DEBUG to True, the page renders how I want it to because it has access to the static files. But whenever I try to run the tests I always get the error
selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable
This seems to happen for any element I refer to. For some reason, when I try to click on the dropdown directly, it always highlights this input and the select tag always seems to be 'hidden', so I wonder if that may be causing the error
Thank you all for your help, I don't know why Selenium is not being allowed to directly access the select tag for drop down.
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
You are right. You are trying to interact with <select> dom which is not visible and it is throwing element not visible exception.
We have two automate this case exactly similar like the manual steps,
i.e.,
Click the element which is intractable.
Wait for the dropdown appears.
Click the value from the dropdown.
In your case for selecting first value in dance select box, the code can rewritten as below.
# this is click the input element which is intractable
# Here the input box which contains value 'dance event' is clicked
driver.find_element_by_css_selector('input.select-dropdown[value*="dance event"]').click
# Then we are waiting for the first value of the dropdown which is not disabled
wait = WebDriverWait(driver, 60)
element = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'input.select-dropdown[value*="dance event"]+ul>li:not(.disabled)')))
# Click the element first value of the dropdown
element.click()
Related
I am having some issues with Selenium not clicking the pop-up privacy button on https://www.transfermarkt.com/
Here is my code so far:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.transfermarkt.com/')
accept_button = driver.find_element_by_xpath('/html/body/div/div[2]/div[3]/div[2]/button')
accept_button.click()
It comes up saying:
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div/div[2]/div[3]/div[2]/button"}
Anyone have any thoughts?
I believe the issue is that the element you are trying to click is inside an iframe. In order to click that element you'll have to first switch to that frame. I noticed the iframe has title="SP Consent Message" so I'll use a CSS Selector to identify it based on that. Your code with the added line:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.transfermarkt.com/')
driver.switch_to.frame(driver.find_element_by_css_selector('iframe[title="SP Consent Message"]'))
accept_button = driver.find_element_by_xpath('/html/body/div/div[2]/div[3]/div[2]/button')
accept_button.click()
Note that you may have to switch back to the default frame to continue your test, I'm not 100% sure as that iframe has gone away.
Also it seems like some folks don't get that popup when the hit the website, not sure why, may be something you want to look in to to determine how you want to test this.
Like #Prophet says you should improve the xpath for the button (again it seems to have a unique title so I would use CSS Selector 'button[title="ACCEPT ALL"]'), but this works for me to click it.
There are 2 issues here:
You need to add wait / delay before accept_button = driver.find_element_by_xpath('/html/body/div/div[2]/div[3]/div[2]/button') to let the page load
It's very, very bad practice to use absolute XPaths. You have to define an unique, short and clear related XPath expression.
Additionally, I see no pop-up privacy button when I open that page. So, maybe that element is indeed not there.
I'm trying to click on an element in a dropdown list, and Selenium is able to locate and click the button that makes the list appear, but it doesn't seem to to be able to locate the list itself when it pops up. I have found the HTML that controls the list and tried various find_element_by methods, and none are able to locate it.
I've tried using the Select module, as well as switch_to_frame (which I'm not sure I'm doing correctly), and I've had no luck at all. Any help would be appreciated.
EDIT:
Upon further investigation, there appears to be something "off" with the HTML. When I copied the XPATH from the Chrome inspector, it gave me /html/body/div[5]/div/div/ul/li[3]/div/button, however if you notice, the first div element is div[5], but looking at the html, there are only 4 div elements that are children of the body. Also, when I copy the CSS Selector, I get body > div:nth-child(13) > div > div > ul > li:nth-child(3) > div > button, but there are only 12 total children of the body. Even stranger is the fact that both leaving these locators as they are and attempted to correct for them yield the same results, which is the error.
Here is my code:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
browser = webdriver.Chrome()
url = <url>
browser.get(url)
export1 = browser.find_element_by_xpath("//*[#id=\"react-main-content\"]/div[1]/section/div[1]/div[3]/div[2]/div/button")
time.sleep(1)
export1.click()
# This is the element it's unable to locate
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[4]/div/div/ul/li[3]/li/button")))
# Execution never reaches this point
export2 = browser.find_element_by_xpath("/html/body/div[4]/div/div/ul/li[3]/li/button")
export2.click()
Here is the HTML (I can't get it to format correctly, so here's a screenshot. The Highlighted section is the drop down I'm looking for):
Here is the webpage with the dropdown open and the element in the dropdown I'm trying to locate highlighted.
There seems to be a mistake in an xpath. you have already traversed through the list and you need not do it again. Try this one instead.
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[4]/div/div/ul/li[3]/button")))
I figured it out. Silly me assumed that the HTML from the website being opened in one browser window would match the HTML from the browser window Selenium opens (and seeing as I used the HTML from that same window to locate several other elements, why wouldn't I?). That, however, was not the case.
After pausing execution of my program and examining the HTML of the website in the browser window Selenium opens, I noticed that the location of the element I'm trying to locate is different, so I copied the XPATH from the Selenium browser window and the issue is now resolved.
I've written some code in python in combination with selenium to reach the target page where the data I'm after is located. My below code can almost get there. I just need a little twitch on it to make it work flawlessly.
Firstly, the browsers leads to a page where a default Login button located under Public User Login title then it clicks on that button. When a new page appears, It clicks on the Advanced tab located on the top of that page under the title of Account Search. Upon clicking on that tab there is a list of items visible under the title of Parcel Classification. Now, I need to choose 02.C - PROPERTY BURDENED BY CONSERVATION EASEMENTS from options and press the search button. That's it.
My scraper can do the whole thing accordingly but the problem is: when it selects the preferable option (I've mentioned the text above), there is another option (the very first blank space of those options) by default remains selected. That is why, when my scraper clicks on the search button, it populates wrong results (a page with no results).
How can I deselect the first blank space and continue on with the rest. Thanks in advance for taking a look into it.
The link to that webpage: Web_Link
This is what I've tried so far:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
driver.get("replace_with_above_link")
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#middle_left input[name='submit']"))).click()
wait.until(EC.presence_of_element_located((By.LINK_TEXT, "Advanced"))).click()
Select(wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,".tableHtmlLayout #accountTypeID")))).select_by_visible_text('02.C - PROPERTY BURDENED BY CONSERVATION EASEMENTS')
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".buttons input[type='submit']"))).click()
driver.quit()
If i understand the problem correctly, you want to deselect the first option before you select your target option? How about doing something like this?
wait.until(EC.presence_of_element_located((By.LINK_TEXT, "Advanced"))).click()
account_selector = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,".tableHtmlLayout #accountTypeID")))
Select(account_selector).deselect_by_index(0)
Select(account_selector).select_by_visible_text('02.C - PROPERTY BURDENED BY CONSERVATION EASEMENTS')
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".buttons input[type='submit']"))).click()
I have created the following simple selenium test in order to start a browser, navigate to the google main page and to insert some text in the search box:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
browser = webdriver.Firefox()
browser.get('http://www.google.com')
elem = browser.find_element_by_xpath('//input') # Find the search box
elem.send_keys('do a test search' + Keys.RETURN)
However, I get the following error in the send_keys line:
selenium.common.exceptions.ElementNotInteractableException: Message: Element is not visible
Maybe this is a bad way to select the prominent input box on the google page? How to do it better?
(Remark: This is just supposed to be a simple setup to get selenium going. The system under test will be a different webpage, but I just want to make sure it works in this simple case...)
There are couple of hidden input elements located before search input field.
browser.find_element_by_xpath('//input') means return FIRST "input" node in DOM. That's why your elem is actually hidden node and not interactable.
Try below instead
elem = browser.find_element_by_name("q")
I want to select an item from a drop down using selenium python. The project uses react.js. The dropdown html appears in a div.
code inspect for dropdown
As this is under div, not select, when i try to select specific value, i got an error message.
Error message:
selenium.common.exceptions.UnexpectedTagNameException: Message: Select
only works on elements, not on div
How can I solve this issue?
You cannot use Select class to operate dropdowns which are not implemented using select and option elements.
You have to handle this kind of dropdown "manually" - generally speaking - click it to open it up, locate the desired dropdown item/option and click it. E.g., judging by you concise HTML snippet, to open up the dropdown you can try:
# open up the dropdown
dropdown = driver.find_element_by_css_selector(".Select-control")
# or dropdown = driver.find_element_by_css_selector(".Select-control .Select-input")
dropdown.click()
# TODO: select option
Sometimes, simply focusing the dropdown and typing the desired item/option text would auto-select it - if this is the case, you can try:
from selenium.webdriver.common.action_chains import ActionChains
actions = ActionChains(driver)
actions.move_to_element(dropdown).send_keys("Desired option text").perform()
And, if there are any animations or time delays (to, for example, retrieve the options from the server) you may need to add Explicit Waits to handle the possible timing issues.
These are all general tips, I am operating under assumptions and I have no way to check if anything above works for your use case.