Python Selenium can't click on button in a pop up

Question:

I am playing around with selenium on https://www.autozone.com/, trying to fill out the add vehicle form using selenium and python

first I click on the add vehicle button

URL = "https://www.autozone.com/"
ADD_VEHICLE_XPATH = "/html/body/div[1]/div/div[2]/div[2]/header/div[2]/div/div/div[2]/div/button"
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.implicitly_wait(WAIT_TIME)
driver.get(URL)
add_vehicle_button = driver.find_element(By.XPATH, ADD_VEHICLE_XPATH)
add_vehicle_button.click()

Then a pop up window pops up, and I try to locate the button for the year dropdown

YEAR_BUTTON_XPATH = "/html/body/div[4]/div[3]/div/div[2]/div/div/div[1]/div/div[2]/div[1]/div/div/div[1]/div/button"
year_button = driver.find_element(By.XPATH, YEAR_BUTTON_XPATH)

This throws the NoSuchElementException
according to this script

def is_in_iframe():
    driver.execute_script("""function iniFrame() {
    if ( window.location !== window.parent.location )
    {
     
        // The page is in an iFrames
        document.write("The page is in an iFrame");
    }
    else {
         
        // The page is not in an iFrame
        document.write("The page is not in an iFrame");
    }
}
 
// Calling iniFrame function
iniFrame();""")

I am not in an iframe after clicking on add vehicle
I have also checked the names of all windows before and after clicking add vehicle, there is only ever 1 window and it is the same before and after clicking.

Some things to note:
I have tried adding both python sleep() and waiting in selenium
The div that contains the pop up and all buttons does not show up until I click add vehicle, and after that it shows up near the bottom
The xpath I’m using is unique to that button

What are some other ways I can try to locate the button? Please let me know if I need to add any more code or description.

Asked By: JGoss

||

Answers:

You need to improve your locators.
Also you need to wait for elements to become clickable before clicking them.
The following code opens the "Add Vehicle" dialog and selects 2020 year.

from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

options = Options()
options.add_argument("start-maximized")

caps = DesiredCapabilities().CHROME
caps["pageLoadStrategy"] = "eager"

webdriver_service = Service('C:webdriverschromedriver.exe')
driver = webdriver.Chrome(options=options, desired_capabilities=caps, service=webdriver_service)
wait = WebDriverWait(driver, 10)

url = "https://www.autozone.com/"

driver.get(url)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='deskTopVehicle-menu-lg']"))).click()
wait.until(EC.element_to_be_clickable((By.ID, "yearheader"))).click()
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid='yearheader-dropdown-list-item-4']"))).click()

This is the screenshot of web page state after applying the code above:

enter image description here

That site containing several JavaScript scripts making the page loading time long, so I added a special settings to driver not to wait for it.
This is what

caps = DesiredCapabilities().CHROME
caps["pageLoadStrategy"] = "eager"

coming for

Answered By: Prophet