Selenium cannot find element in main window

Question:

I am attempting to download a file from a website using Selenium and Python 3. This requires pressing a confirmation button on an overlay window. The overlay window is not within an iFrame – the HTML is simply dynamically added when the overlay appears – but Selenium is not able to find the button by xPath, returning a NoSuchElementException. Am I missing anything that would cause Selenium not to be able to see the element as it appears in the page source? So far as I can tell, Selenium should be able to locate the button with no issue.

#Initialize Driver
driver = webdriver.Safari()

cmd = "osascript -e 'tell application "Safari" to set bounds of front window to {0, 22, 1500, 1022}'"
os.system(cmd)

#Call up seach link
driver.get(data_url)

wait_a = WebDriverWait(driver, 15)
element = wait_a.until(EC.presence_of_element_located((By.ID, "md-input-3")))

#Initialize and send login information (defined above)
username = driver.find_element_by_id("md-input-3")
password = driver.find_element_by_id("md-input-6")

username.send_keys(crunchbase_username)
password.send_keys(crunchbase_password)

#Click login button
password.send_keys(Keys.ENTER)

#Wait for results page to finish loading
wait = WebDriverWait(driver, 15)
element = wait.until(EC.title_contains("Signals"))

time.sleep(2)

#Press Download Button
driver.find_element_by_xpath("//button[@aria-label='Export your results']").click()
time.sleep(2)

#Press csv button
driver.find_element_by_xpath("//button[@aria-label='Export to CSV']").click()
time.sleep(2)

#Confirm downlaod
driver.find_element_by_xpath("//*[@id='cdk-overlay-36']/md-dialog-container/confirmation-dialog/dialog-layout/div/md-dialog-actions/div/button[2]").click()

#Close driver
#driver.close()

The page source is overly complicated and highly stylized so I will not include it here, but a screenshot of the relevant section of the code in my browser’s web inspector is below. The element which I’m trying to click is highlighted in blue.

Web Inspector Screenshot

I appreciate any help with this.

Asked By: Henry Desai

||

Answers:

Before clicking on the element, execute the following lines:

    WebElement element = driver.findElement(By.xpath(" path_of_your_module "));
((JavaScriptExecutor) driver). executeScript("argument[0].scrollIntoView(true);", element);
Answered By: NAIMISH KUNWAR

It is hard to tell without having access to the page under question and being able to see what’s going. Few general points:

  1. Try css selectors instead of xpath. They are more robust, easier to work with and fast.
  2. Acvoid using dynamically generated IDs. In your screenshot I can’t even see an id that appears in your code.
  3. When you have more than one element of the same kind (like buttons in your case) try getting all webelements under a certain parent and test all of them for having an attribute value that you are looking for.

For example:

elemItems = driver.find_elements_by_css_selector(menuItemSelector)

for element in elements:
    if element.text == "export":
        elemItems[1].click()

Here, you find all the elements of a certain type (buttons for example) and select one that has “export” text in it.

Answered By: Eugene S

I faced the same issue on a dialogOverlay and I fixed it. I realized that on clicking the overlay button that would bring the overlay, selenium was searching for the element before the overlay loads the dynamic content. So I did this:

   def download():
    global browser
    notFound = True
    while(notFound):
        try:
            
            elem = browser.find_element(By.ID, 'btnFormat2')
            elem.click()
            notFound = False
        except BaseException:
            print("----Error Download Element not found")
            
download()

The code will continuously look for the element until its loaded on the overlay.

Answered By: Stones