Creating wait to load HTML object on page with Selenium

In this tutorial, I will write a custom function that will be used to wait since the HTML object is loaded on-page for a certain time

Welcome, everyone, to Selenium with Python fifth tutorial part. In this tutorial, I will write a function used to wait since the object is loaded on-page. Sometimes if we open a new tab or a new page on another page and use the CheckExistsByXpath function. Our function may return False even when the object is on-page. This may happen when the page loads faster than the object we are looking for; for example, our object appears only after some time.

So this is the main reason I am making the WaitToLoadXpath function that uses xpath, retries in seconds, and quotations. So in this function, we are using the same "CheckExistsByXpath" function, but instead of checking existence one time, we are doing this by default 5 seconds, every half second. If our object wasn't found on-page, we are returning False, and we can do something else. If our function returns True, we know that our object exists on-page. But here comes the Quotation input, other pages may be written in a way, that object may exist, but to have nothing in that object means they would return "". They may be hidden or something like that. So I added one more function: if our object doesn't have anything, it will return False. I haven't tested it fully, so it may not work in all cases. But here is the code:

def WaitToLoadXpath(driver, xpath, retries = 5, Quotation = False): DriverName = CheckExistsByXpath(driver,xpath) WhileRetries = 0 if Quotation == False: while DriverName == False and WhileRetries < retries*2: DriverName = CheckExistsByXpath(driver,xpath) time.sleep(0.5) WhileRetries += 1 #print("WhileRetries:", WhileRetries) #print("DriverName:", DriverName) if WhileRetries == retries*2: return False if Quotation == True: while DriverName == False and WhileRetries < retries*2: DriverName = CheckExistsByXpath(driver,xpath) time.sleep(0.5) WhileRetries += 1 print("WhileRetries:", WhileRetries) print("DriverName:", DriverName) if WhileRetries == retries*2: return False if DriverName != False: try: DriverName_text = DriverName.text except StaleElementReferenceException: DriverName_text = '' except NoSuchWindowException: return False while DriverName_text == '' and WhileRetries < retries*2: DriverName = CheckExistsByXpath(driver,xpath) try: DriverName_text = DriverName.text except StaleElementReferenceException: DriverName_text = '' except AttributeError: DriverName_text = '' print("DriverName_text == '':", DriverName_text) time.sleep(0.5) WhileRetries += 1 if WhileRetries == retries*2: return False return True

And here comes the final up to date code:

from selenium import webdriver import time from selenium.webdriver import ActionChains from selenium.webdriver.common.keys import Keys from selenium.common.exceptions import WebDriverException from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import NoSuchFrameException from selenium.common.exceptions import NoSuchWindowException from selenium.common.exceptions import ElementNotInteractableException from selenium.common.exceptions import StaleElementReferenceException from selenium.common.exceptions import MoveTargetOutOfBoundsException from selenium.common.exceptions import UnexpectedAlertPresentException from selenium.common.exceptions import ElementClickInterceptedException from selenium.common.exceptions import JavascriptException import random def CheckExistsById(driver, CheckId): try: DriverId = driver.find_element_by_id(CheckId) except NoSuchWindowException: return False return DriverId def CheckExistsByName(driver, CheckName): try: DriverName = driver.find_element_by_name(CheckName) except NoSuchWindowException: return False return DriverName def CheckExistsByXpath(driver, xpath): try: path = driver.find_element_by_xpath(xpath) except NoSuchWindowException: return False except WebDriverException: return False except StaleElementReferenceException: return False return path def CheckExistsArrayByXpath(driver, xpath): try: path = driver.find_elements_by_xpath(xpath) except NoSuchWindowException: return False except WebDriverException: return False except StaleElementReferenceException: return False return path def MinimizeWindow(driver): try: driver.minimize_window() except UnexpectedAlertPresentException: return False return True def DriverClose(driver): try: driver.close() except NoSuchWindowException: print("NoSuchWindowException in driver.close()") return False return True def SimpleClick(driver, ObjectToClick): try: ObjectToClick.click() except ElementNotInteractableException: return False except ElementClickInterceptedException: return False except TypeError: return False return True def StartBrowser(browser=1, browser_location='', driver_path=''): if browser == 1: driver = webdriver.Firefox() if browser == 2: driver = webdriver.Chrome() if browser == 3: options = webdriver.ChromeOptions() options.binary_location = browser_location driver = webdriver.Chrome(executable_path=driver_path, chrome_options=options) #driver.implicitly_wait(30) #driver.set_window_size(1920,1080) #driver.maximize_window() return driver def NewTab(driver, Link, default_page=0, custom=0): window_count = len(driver.window_handles) driver.execute_script('''window.open("'''+Link+'''","_blank");''') while len(driver.window_handles) != window_count+1: time.sleep(0.5) if custom == 0: driver.switch_to.window(driver.window_handles[-1]) if custom != 0: driver.switch_to.window(driver.window_handles[custom]) time.sleep(2) if driver.current_url == Link: current_window = driver.current_window_handle return current_window if driver.current_url == "about:blank": time.sleep(2) DriverClose() driver.switch_to.window(driver.window_handles[default_page]) print("current window was about:blank we closed it, trying again in 10s") time.sleep(10) NewTab(driver, Link, default_page, custom) if driver.current_url != Link: pass def VirtualClick(driver, click_object, UseRandom=True): try: size = click_object.size except StaleElementReferenceException: print("StaleElementReferenceException") return False sizeList = list(size.values()) height = int(sizeList[0])-1 width = int(sizeList[1])-1 if UseRandom == True: try: height_rand = random.randint(1,height) except ValueError: height_rand = 1 try: width_rand = random.randint(1,width) except ValueError: width_rand = 1 if UseRandom == False: height_rand = height width_rand = width action = webdriver.common.action_chains.ActionChains(driver) try: action.move_to_element_with_offset(click_object, width_rand, height_rand) except StaleElementReferenceException: return False action.click() try: action.perform() except MoveTargetOutOfBoundsException: print("MoveTargetOutOfBoundsException with action.perform()") return False except StaleElementReferenceException: print("StaleElementReferenceException with action.perform()") return False return True def WaitToLoadXpath(driver, xpath, retries = 5, Quotation = False): DriverName = CheckExistsByXpath(driver,xpath) WhileRetries = 0 if Quotation == False: while DriverName == False and WhileRetries < retries*2: DriverName = CheckExistsByXpath(driver,xpath) time.sleep(0.5) WhileRetries += 1 #print("WhileRetries:", WhileRetries) #print("DriverName:", DriverName) if WhileRetries == retries*2: return False if Quotation == True: while DriverName == False and WhileRetries < retries*2: DriverName = CheckExistsByXpath(driver,xpath) time.sleep(0.5) WhileRetries += 1 print("WhileRetries:", WhileRetries) print("DriverName:", DriverName) if WhileRetries == retries*2: return False if DriverName != False: try: DriverName_text = DriverName.text except StaleElementReferenceException: DriverName_text = '' except NoSuchWindowException: return False while DriverName_text == '' and WhileRetries < retries*2: DriverName = CheckExistsByXpath(driver,xpath) try: DriverName_text = DriverName.text except StaleElementReferenceException: DriverName_text = '' except AttributeError: DriverName_text = '' print("DriverName_text == '':", DriverName_text) time.sleep(0.5) WhileRetries += 1 if WhileRetries == retries*2: return False return True browser_location = "C:/Users/HOME/Desktop/chrome-win/chrome.exe" driver_path = "C:/Users/HOME/Desktop/chrome-win/chromedriver.exe" driver = StartBrowser(1, browser_location, driver_path) time.sleep(1) driver.get("https://www.google.com") time.sleep(1) NewTab(driver, "https://www.google.com/gmail/about/new/") if WaitToLoadXpath(driver, "//div[@class='h-c-header__cta']/ul/li[2]/a") != False: signin = CheckExistsByXpath(driver, "//div[@class='h-c-header__cta']/ul/li[2]/a") #if WaitToLoadXpath(driver, "//a[starts-with(.,'Sign In')]") != False: # signin = CheckExistsByXpath(driver, "//a[starts-with(.,'Sign In')]") VirtualClick(driver, signin) time.sleep(0.5) driver.switch_to.window(driver.window_handles[-1]) if WaitToLoadXpath(driver, "//input[@type='email']") != False: email = CheckExistsByXpath(driver, "//input[@type='email']") email.send_keys("email") next = CheckExistsByXpath(driver, "//span[@class='RveJvd snByac']") VirtualClick(driver, next)

So here above is the final code I got now. At the end of the code, I added few more lines to test if everything works for us. I struggled while trying to log in to Gmail because they are changing their main page code from time to time. I wrote everything while recording the video, so I didn't have time to think of a good solution for this, but this may be a task for you. I am not wasting time on this simple task, and in the next tutorial, I will move to a certain task.