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.