How could I check to see if an element is not displayed. I would think it looks something like this.
if(element.is_not_displayed):
doSomething()
else
doSomethingElse()
To start with, there is no is_not_displayed attribute in Selenium.
To simulate a similar logic, instead of an if-else loop you may use a try-except{} loop inducing WebDriverWait for the invisibility_of_element() and you can use the following Locator Strategy:
try:
WebDriverWait(driver, 30).until(EC.invisibility_of_element(element))
doSomething()
except TimeoutException:
doSomethingElse()
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.common.exceptions import TimeoutException
You have to use until_not as shown bellow
WebDriverWait(driver, "time you want to wait".until_not(EC.presence_of_element_located((By.ID,"someID")))
Example:
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID,"transpdiv-0"))) #here yout wait to the element appear
WebDriverWait(driver, 300).until_not(EC.presence_of_element_located((By.ID,"transpdiv-0"))) #here you wait the element disappear
Note: you have to add the same imports like undetect Selenium says:
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.common.exceptions import TimeoutException
Related
I'm automating a bot to book a certain time (preferred time and second preferred time).
I need help to use if else statement to allow the browser to search for the preferred time and if not present to search for the second preferred time.
Below is my code:
preferred_time=driver.find_element(By.XPATH,'//div[#class="booking-start-time-label"][contains(., "12:33pm")]')
preferred_time.click()
second_preferd_time= driver.find_element(By.XPATH,'//div[#class="booking-start-time-label"][contains(., "1:33pm")]')
second_preferd_time.click()
An ideal approach will be to try to click on the initial desired element inducing WebDriverWait for element_to_be_clickable() and incase it fails catch the TimeoutException and attempt to click on the second desired element as follows:
try:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//div[#class="booking-start-time-label"][contains(., "12:33pm")]'))).click()
except TimeoutException:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//div[#class="booking-start-time-label"][contains(., "1:33pm")]'))).click()
Note: You have to add the following imports :
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
link = driver.find_element_by_partial_link_text('/wse/gupmenug.menu?p_sistema_c=ESCOLAR&p_sistemaid_n=1&p_menupredid_n=1&p_pidm_n=425370')
How can i fix this?
Your locator indeed looks invalid.
using the expected conditions and better locators it will be something like this:
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 20)
wait.until(EC.visibility_of_element_located((By.XPATH, "//a[text()='ALUMNOS']"))).click()
wait.until(EC.visibility_of_element_located((By.XPATH, "//a[text()='ESCOLAR']"))).click()
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
import time
print('\n')
print("PROGRAM STARTING")
print('~~~~~~')
print('\n')
# initiate driver
driver = webdriver.Chrome()
driver.get('http://arcselfservice.sbcounty.gov/web/user/disclaimer')
#begin
driver.find_element_by_xpath('//*[#id="submitDisclaimerAccept"]').click()
driver.find_element_by_xpath('/html/body/div[2]/div[2]/div/div[3]/div[2]/div/div/div[2]/a[1]').click()
I have been stuck on this error for a long time, for some reason it can't find the element even though I am specifying the xpath. There doesn't seem to be any iframes, and implicit or explicit wait doesn't work either. Please help.
So the issue was waiting for the element to come up and then clicking it.
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[2]/div[2]/div/div[3]/div[2]/div/div/div[2]/a[1]"))).click()
Another way if you want to change to the other tags later.
path = "//a/div/h1[text()='{}']/../..".format("Fictitious Business Names Application")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH ,path))).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
The error is coming because the element is taking time to be available for use. Kindly use the explicit wait for the element extraction.
A small snippet can be:
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH ,'/html/body/div[2]/div[2]/div/div[3]/div[2]/div/div/div[2]/a[1]'))).click()
Just dont forget to import
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
This is just an example, but I want if Hello in html source on explicit wait, how do I make it work?
if "Hello" in html_source:
WebDriverWait wait = new WebDriverWait(driver,10)
wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("foobar")))
From selenium documentation
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.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//*[text()='Hello']")))
print(driver.page_source)
except:
print("element could not be found within the 10 second timeout period")
If you want a better answer, I suggest you ask a better question and use examples.
<div id="loader-mid" style="position: absolute; top: 118.5px; left: 554px; display: none;">
<div class="a">Loading</div>
<div class="b">please wait...</div>
</div>
And want to wait until it disappears. I have following code but it wait sometimes too long and at some point of code it suddenly freeze all process and I don't know why.
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
self.wait = WebDriverWait(driver, 10)
self.wait.until(EC.invisibility_of_element_located((By.XPATH, "//*[#id='loader_mid'][contains(#style, 'display: block')]")))
and also I tried this one:
self.wait.until_not(EC.presence_of_element_located((By.XPATH, "//*[#id='loader_mid'][contains(#style, 'display: block')]")))
I don't know exactly how to check but maybe my element is always present on the page and selenium thought that it is there, the only thing that changes is parameter display changes from none to block. I think I can get attribute like string and check if there is word "block" but it is so wrong I thing... Help me please.
Reiterated your answer (with some error handling) to make it easier for people to find the solution :)
Importing required classes:
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
Configuration variables:
SHORT_TIMEOUT = 5 # give enough time for the loading element to appear
LONG_TIMEOUT = 30 # give enough time for loading to finish
LOADING_ELEMENT_XPATH = '//*[#id="xPath"]/xPath/To/The/Loading/Element'
Code solution:
try:
# wait for loading element to appear
# - required to prevent prematurely checking if element
# has disappeared, before it has had a chance to appear
WebDriverWait(driver, SHORT_TIMEOUT
).until(EC.presence_of_element_located((By.XPATH, LOADING_ELEMENT_XPATH)))
# then wait for the element to disappear
WebDriverWait(driver, LONG_TIMEOUT
).until_not(EC.presence_of_element_located((By.XPATH, LOADING_ELEMENT_XPATH)))
except TimeoutException:
# if timeout exception was raised - it may be safe to
# assume loading has finished, however this may not
# always be the case, use with caution, otherwise handle
# appropriately.
pass
Use expected condition : invisibility_of_element_located
This works fine for me.
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
WebDriverWait(driver, timeout).until(EC.invisibility_of_element_located((By.ID, "loader-mid")))
The following code creates an infinite loop until the element disappears:
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.common.exceptions import TimeoutException
while True:
try:
WebDriverWait(driver, 1).until(EC.presence_of_element_located((By.XPATH, 'your_xpath')))
except TimeoutException:
break
Ok, here is how i solved this issue for my project,
imports
from selenium.common.exceptions import TimeoutException
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait as wait
Now the code part
browser = webdriver.Chrome(service=Service("./chromedriver.exe"))
browser.get("https://dashboard.hcaptcha.com/signup?type=accessibility")
try:
d = wait(browser, 10).until(EC.invisibility_of_element_located((By.ID, 'loader-mid')))
if d: # just a check you can ignore it.
print("yes")
sleep(3)
else:
print("F")
except TimeoutException:
print("timeout error occurred.")
pass
browser.quit()
Or you can use Implicit wait
driver.implicitly_wait(10) # seconds
# do something after...