1

but I am trying to write a unit test for my website that runs through all the links and returns an A ok or no go if the site is working. But I am having trouble with the program it's not able to constantly click the link in the site navigation bar. I've tried multiple waits implicit. Explicit, expected condition but the page loads and half the time it will click the link and go to that part of the site and the other half the program just stops and nothing is clicked.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
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.webdriver import ActionChains

PATH = "C:\Program Files (x86)\chromedriver.exe"

drive = webdriver.Chrome(PATH)
drive.get("https://www.blackhempfamily.com/")

wait = WebDriverWait(drive, 10)
link = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "Why Black Hemp?")))
link.click()
0

4 Answers 4

3

Would be a better tag to use.

wait.until(EC.element_to_be_clickable((By.XPATH, "//p[text()='Why Black Hemp?']")))
Sign up to request clarification or add additional context in comments.

Comments

1

Try it with xpath instead, and with element to be located (not clickable), as it is a paragraph. This worked for me:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
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.webdriver import ActionChains

PATH = "C:\Program Files (x86)\chromedriver.exe"

drive = webdriver.Chrome(PATH)
drive.get("https://www.blackhempfamily.com/")

linkWait = EC.element_to_be_located((By.XPATH, "//div/p[contains(., 'Why Black Hemp?')]"))
WebDriverWait(drive, 10).until(linkWait)
link = drive.find_element_by_xpath("//div/p[contains(., 'Why Black Hemp?')]")
link.click()

Comments

0

The element you're searching for is not a link. It's a paragraph (p). I added a sleep call to give the page more load time.

Try this code:

time.sleep(3)
wait = WebDriverWait(drive, 10)
#link = wait.until(EC.element_to_be_clickable((By.LINK_TEXT, "Why Black Hemp?")))
link = drive.find_element_by_xpath('//*[@id="idh09fqo2label"]')
link.click()

3 Comments

neither of the lines worked still I get to the site home page then like the whole page kinda blinks and then the program stops doing nothing.
I tested a few more times. It did miss once. Adding sleep seemed to solve the problem.
Using sleep() is not a good practice and why are you using find_element_by_xpath() to find an ID? Use find_element_by_id() instead. Your current code doesn't even use the wait you instantiated, why have that code in there?
0

So, it took a while ... but, I think that I was able to figure this out. The actions that you need to do are:

  1. Click "Why Black Hemp?"
  2. Wait until the page stops scrolling
  3. Scroll to the top of the page
  4. Wait until the page stops scrolling
  5. **Attempt to scroll down so you can get the nav bar to display
  6. Repeat until your heart is content / Test Passes with "A-OK"

In order for this to be achieved, you need to have the following imports

from selenium import webdriver
from selenium.webdriver.chrome.webdriver import WebDriver as ChromeWebDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as DriverWait
from selenium.webdriver.support import expected_conditions as DriverConditions
from selenium.common.exceptions import WebDriverException
import time

Step 1 - Click your "Why Black Hemp?" nav bar element

chrome_driver.find_element(By.XPATH, "//nav[contains(@id, 'navContainer')]//p[text()='Why Black Hemp?']/../../..").click()

Step 2 - Check to see if our page is still scrolling

# Checks to see if our page is still scrolling
    while is_same_position == False:
        windowPosition1 = chrome_driver.execute_script("return document.body.scrollHeight;")
        time.sleep(2)
        windowPosition2 = chrome_driver.execute_script("return document.body.scrollHeight;")
        if(windowPosition1 == windowPosition2):
            is_same_position = True
            final_window_position = windowPosition1

Step 3 - Scroll to the top of the page

chrome_driver.execute_script("window.scrollTo(0, {0})".format((0 - final_window_position)))

Step 4 - Check to see if our page is still scrolling

# Checks to see if our page is still scrolling
    while is_same_position == False:
        windowPosition1 = chrome_driver.execute_script("return document.body.scrollHeight;")
        time.sleep(2)
        windowPosition2 = chrome_driver.execute_script("return document.body.scrollHeight;")
        if(windowPosition1 == windowPosition2):
            is_same_position = True

Step 5 - Attempt to scroll down until our header tag does not have the style of visibility: hidden

# Scrolls down until our nav bar is displayed
    for scrollNum in range(10):
        chrome_driver.execute_script("window.scrollTo(0, {0})".format(scrollNum * 100 + 200))
        time.sleep(2)
        if is_displayed(chrome_driver, "//header[contains(@style, 'visibility: hidden')]") == False:
            break

Step 6 - Repeat until your heart is content

MAIN CODE - For Reference

from selenium import webdriver
from selenium.webdriver.chrome.webdriver import WebDriver as ChromeWebDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as DriverWait
from selenium.webdriver.support import expected_conditions as DriverConditions
from selenium.common.exceptions import WebDriverException
import time


def get_chrome_driver():
    """This sets up our Chrome Driver and returns it as an object"""
    chrome_options = webdriver.ChromeOptions() 
    chrome_options.add_argument("window-size=1500,1000")
        
    # Removes the "This is being controlled by automation" alert / notification
    chrome_options.add_experimental_option("excludeSwitches", ['enable-automation'])
    path_to_chrome = "F:\Selenium_Drivers\Windows_Chrome85_Driver\chromedriver.exe"
    return webdriver.Chrome(executable_path = path_to_chrome,
                            options = chrome_options)


def wait_displayed(driver : ChromeWebDriver, xpath : str, int = 3):
    try:
        DriverWait(driver, int).until(
            DriverConditions.presence_of_element_located(locator = (By.XPATH, xpath))
        )
    except:
        raise WebDriverException(f'Timeout: Failed to find {xpath}')
    

def is_displayed(driver : ChromeWebDriver, xpath : str, int = 3):
    try:
        webElement = DriverWait(driver, int).until(
            DriverConditions.presence_of_element_located(locator = (By.XPATH, xpath))
        )
        return True if webElement != None else False
    except:
        return False


# Gets our chrome driver and opens our site
chrome_driver = get_chrome_driver()
chrome_driver.get("https://www.blackhempfamily.com/")


# Repeats this 5 times
for repeat in range(5):
    print("Attempt to click our link. Try #{0}".format(repeat + 1))
    
    is_same_position = False
    final_window_position = 0
    
    # Checks to see if our website's elements display
    wait_displayed(chrome_driver, "//nav[contains(@id, 'navContainer')]")
    wait_displayed(chrome_driver, "//nav[contains(@id, 'navContainer')]//p[text()='Why Black Hemp?']")
    wait_displayed(chrome_driver, "//nav[contains(@id, 'navContainer')]//p[text()='Shop Black Hemp']")

    # Clicks our "Why Black Hemp?" tab
    chrome_driver.find_element(By.XPATH, "//nav[contains(@id, 'navContainer')]//p[text()='Why Black Hemp?']/../../..").click()
    
    # Checks to see if our page is still scrolling
    while is_same_position == False:
        windowPosition1 = chrome_driver.execute_script("return document.body.scrollHeight;")
        time.sleep(2)
        windowPosition2 = chrome_driver.execute_script("return document.body.scrollHeight;")
        if(windowPosition1 == windowPosition2):
            is_same_position = True
            final_window_position = windowPosition1
    
    # Checks to see if our "Natural Moisture" text displays
    wait_displayed(chrome_driver, "(//h2//span[contains(., 'Natural Moisture')]/../..)[1]")
    
    # Scrolls back to the top of the page
    chrome_driver.execute_script("window.scrollTo(0, {0})".format((0 - final_window_position)))
    is_same_position = False
    
    # Checks to see if our page is still scrolling
    while is_same_position == False:
        windowPosition1 = chrome_driver.execute_script("return document.body.scrollHeight;")
        time.sleep(2)
        windowPosition2 = chrome_driver.execute_script("return document.body.scrollHeight;")
        if(windowPosition1 == windowPosition2):
            is_same_position = True
    
    # Scrolls down until our nav bar is displayed
    for scrollNum in range(10):
        chrome_driver.execute_script("window.scrollTo(0, {0})".format(scrollNum * 100 + 200))
        time.sleep(2)
        if is_displayed(chrome_driver, "//header[contains(@style, 'visibility: hidden')]") == False:
            break


chrome_driver.quit()
chrome_driver.stop_client()
print('Congratulations! You clicked your link multiple times!')

2 Comments

Thank you very much for this I'm building a test program for all the links and elements in blackhempfamily.com but this definitely helped me out. You put me on to some more parts of python I should investigate. Thank you again.
No problem. @cartier_5 . I would appreciate an upvote if it helped ;) #ThirstyForTheUpVote

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.