I'm trying to write a script to automate some tasks with Selenium and Python, and every time I try to click on a button
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
driver = webdriver.Chrome(options=options)
xpath = "/html/body/app-root/app-prime/div/mat-sidenav-container//app-detail-component/main//div/span/button[#aria-label='Prenota']"
# Wait for the element to be visible, always true
WebDriverWait(driver, 5).until(expected_conditions.presence_of_element_located((By.XPATH, xpath)))
# Try to click on element, get an error
driver.find_element(By.XPATH, xpath).click()
I get the following error
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
I know for sure that the element gets located correctly and has to match, but it should act only on the first one.
I tried:
Trying to click child tags, such as others divs and span
Waiting for it to be clickable
Waiting with an implicit wait
None of those activities were successful
Edit: Apparently the issue olly exist on my machine
It could be not clickable for a number of reasons. You might want to check if there is some element on the page layered on top so that that element is not interactable at that time, e.g some popup/iframe etc. There could be some other element that will receive click at that time.
You could try an actions click - something like this
myElement = driver.find_element_by_xpath("myXpath")
webdriver.ActionChains(driver).move_to_element(myElement).click(myElement).perform()
One of this should work.
IJavaScriptExecutor executor = (IJavaScriptExecutor)WebDriver.Driver;
executor.ExecuteScript("arguments[0].click();", webElement);
Actions actions = new Actions(WebDriver.Driver);
actions.MoveToElement(webElement).Click().Perform();
Note - these are c sharp code. try to do the same in java.
Related
Using Selenium, I am unable to locate the "email" element on the Udemy website.
Here's what I tried:
browser.get('https://www.udemy.com/join/login-popup/')
browser.implicitly_wait(5)
email = browser.find_element(By.ID, 'email--1')
print(email)
but it gives NoSuchElementException while "email" element isn't even in an iframe, as far as I know.
So, how can I locate this specific element?
In this case, you're probably looking for the element before the page loads.
You should use the WebDriverWait class of Selenium and the condition presence_of_element_located of the expected_conditions, as shown in the example below:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
browser.get('https://www.udemy.com/join/login-popup/')
timeout = 20 # Number of seconds before timing out.
email = WebDriverWait(browser, timeout).until(EC.presence_of_element_located((By.ID, 'email--1')))
email.send_keys("example#email.com")
In the above snippet, Selenium WebDriver waits up to 20 seconds before throwing a TimeoutException, unless it finds the element to return within the above time. WebDriverWait, by default, calls the ExpectedCondition every 500 milliseconds until it returns successfully.
Finally, presence_of_element_located is an expectation for determining whether an element is present on a page's DOM, without necessarily implying that the element is visible. When the element is found, the locator returns the WebElement.
I have an element that after clicking the button it builds a div with Ajax and I can't get the element.
Click button:
Show div:
But in my code doesn't work
vv = drive.find_element_by_xpath('//*[#id="vUPDATE_0001"]')
Error Message:
Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="vUPDATE_0001"]"}
I think what you're looking for is to wait until the div is visible. Luckily, selenium has just that!
You can read more over here.
By using WebDriverWait along with expected_conditions, your example code would look like this:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
timeout = 10 # Wait 10 seconds. If it doesn't appear in 10 seconds then throw an error
vv = WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.XPATH, '//*[#id="vUPDATE_0001"]')))
For many different circumstances, there are different conditions, such as wait for an element to be clickable, or wait an alert to pop up. We are using presence of element located, which is the same as find_element_by_[condition]. Then we are setting the condition with By.XPATH. There are many different conditions which represent their find_element_by_ alternative, such as By.ID, By.CLASS_NAME, and By.NAME.
I'm working on a selenium based python automation project. The code automates some regular tasks by connecting to the company's internal webpage url. However, the code occasionally throws the same exception between two button click actions. Could you please help me to figure out what's the point that I miss? Thanks in advance.
You can find my code snippet and error screenshot here:
selenium.common.exceptions.ElementClickInterceptedException: Message:
element click intercepted: Element ... is not clickable at point (180,
447). Other element would receive the click: ...
pycharm_error_output_screenshot
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
timeout = 200
options = Options()
options.headless = False
driver = webdriver.Chrome(options=options)
driver.implicitly_wait(3)
wait = WebDriverWait(driver, timeout)
driver.get("https://internal_web_appplication_page_for_company_x")
apply_button_v4 = wait.until(EC.visibility_of_element_located((By.XPATH, "//body//button[2]")))
apply_button_v4.click()
both_button = wait.until(EC.element_to_be_clickable((By.XPATH, "// label[3] // span[1]")))
wait.until_not(EC.element_to_be_clickable((By.CLASS_NAME, "map-mask")))
wait.until_not(EC.element_to_be_clickable((By.XPATH, "// *[ contains( # class, 'map-mask')]")))
both_button.click()
The intercepted element is full screen "loading" notification which is visible for a short period of time following any click action.
Moreover, my code works as expected if i put time.sleep(5) before clicking "both_button".
Try below solution for clicking on both_button. There are multiple reasons of this exception like javascript or ajax call , element is not in the view port.
actions = ActionChains(driver)
actions.move_to_element(both_button)
actions.click(both_button)
actions.perform()
Trying got automate a task via Selenium python i have the issue where the for each section does work only the first time, after that does not see the second variable. Also tried to add delays so the webpage would be fully loaded but the same issue.
I tested different scenarios that i found in the internet also so manual tests i did, but looks like the second div is not recognizable also the rest of the divs
for server in browser.find_elements_by_xpath("//*[starts-with(#id,'server-list-')]"):
#try:
print("Server Section----")
time.sleep(5)
#Print server name
print(server.text)
#clicn on button inside the server
server.click()
#back into the server listing
browser.back()
Basically the automation need to enter every server ( div starting with id server-list- ) click on it, after entering on that section click another button and than back to the main page.
A stale element reference exception is thrown because of below reason
element has been deleted entirely.
element is no longer attached to the DOM.
Please check your element is still present on UI with the same element XPath which you are using while interacting with it
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
driver = webdriver.Chrome()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//*[starts-with(#id,'server-list-')]"))
)
for i in range(len(element)):
element[i].click()
driver.back()
element = wait.until(EC.presence_of_element_located((By.XPATH, "//*[starts-with(#id,'server-list-')]")))
finally:
driver.quit()
With limited information provided, you can try code below:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
servers = wait.until(EC.visibility_of_all_elements_located((By.XPATH, "//*[starts-with(#id,'server-list-')]")))
servers_count = len(servers)
for i in range(servers_count):
print(servers[i].text)
servers[i].click()
browser.back()
servers = wait.until(EC.visibility_of_all_elements_located((By.XPATH, "//*[starts-with(#id,'server-list-')]")))
You capture the server list that no more exists after you have drilled into the particular list item. So when you get back to the list that old one does not exist any more hence all the items (including that one you expect to move next to) are stale.
You need to rework your logic so that you get the list of servers each time you get back from the server details and store somethere the flag that would let your script know which items you have already visited.
I can't find a solution how this element cannot be found by using a selenium xpath. Other button on other websites always working just fine. Usually what I would normally do is, just open up a page and inspect the element and I would right click it and copy the xpath. Done.
But this website, www.gsc.com.my (a malaysian cinema booking site). Seems not able to find the button. Is it protected by another security layer?
Lets see the code below,
from selenium import webdriver
chromedriver_path = './chromedriver.exe'
driver = webdriver.Chrome(chromedriver_path)
driver.get('https://www.gsc.com.my')
driver.find_element_by_xpath("""//*[#id="btnNext"]""").click()
The error Message:
no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="btnNext"]"}
Button is located inside an iframe, so you need to switch to that frame before clicking the button:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.webdriver.support import expected_conditions as EC
driver.switch_to.frame('getQuickFilter_ctrl_ifrBox')
wait(driver, 10).until(EC.element_to_be_clickable((By.ID, "btnNext"))).click()
Because there are two elements with id btnNext, you'll have to specify which of them using an index, 1 for the first, 2 for the second.
driver.find_element_by_xpath("""//*[#id="btnNext"][1]""").click()
You can try with this css selector :
div.container input#btnNext
Note that you will need to switch to iframe first , cause the check button is in a iframe.
For switching to iframe :
driver.switch_to.frame(driver.find_element_by_id("getQuickFilter_ctrl_ifrBox"))
and for clicking on check Button
wait = WebDriverWait(driver, 10)
check_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.container input#btnNext")))
check_button.click()