Click on link only with href

Question:

Task: using selenium in Pyhton, I need to click on link, which consists only href:enter image description here

My solution:

from selenium import webdriver
from credentials import DRIVER_PATH, LINK
from selenium.webdriver.common.by import By
import time

DRIVER_PATH = 'C:\Program Files (x86)\Microsoft\Edge\Application\msedgedriver.exe'
LINK = 'https://petstore.octoperf.com/actions/Catalog.action'

class Chart(object):
    def __init__(self, driver):
        self.driver = driver

        self.fish_selection = "//a[@href='/actions/Catalog.action?viewCategory=&categoryId=FISH']"

    def add_to_chart(self):
        self.driver.find_element(By.XPATH, self.fish_selection).click()
        time.sleep(3)


def setup():
    return webdriver.Edge(executable_path=DRIVER_PATH)


def additiontest():
    driver = setup()
    driver.get(LINK)
    driver.maximize_window()
    welcome_page = Chart(driver)
    welcome_page.add_to_chart()
    driver.quit()

if __name__ == "__main__":
    additiontest()

Error:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//a[@href=’/actions/Catalog.action?viewCategory=&categoryId=CATS’]"}
(Session info: MicrosoftEdge=107.0.1418.42)

Asked By: Qvch

||

Answers:

  1. The href value of that element is dynamically changing, so you need to locate that element by fixed part of href attribute.
  2. You need to wait for element to become clickable.
    This should work better:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 20)

wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(@href,'FISH')]"))).click()

UPD
Accordingly to your project structure I think you should use something like this:

class Chart(object):
    def __init__(self, driver):
        self.driver = driver

        self.fish_selection = "//a[contains(@href,'FISH')]"
        self.wait = WebDriverWait(self.driver, 20)

    def add_to_chart(self):
        self.wait.until(EC.element_to_be_clickable((By.XPATH, self.fish_selection))).click()
        time.sleep(3)
Answered By: Prophet