Bruce Brown
Bruce Brown

Reputation: 11

Python Selenium - getting 'ElementNotVisibleException' error while trying to click on link

All I am trying to do is: go to "http://news.google.com" and click on the "Technology" link on the side menu. Here's my code:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import unittest, time, re

class GoogleTech(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url = "https://www.google.com/"
        self.verificationErrors = []
        self.accept_next_alert = True


    def test_googletech(self):
        driver = self.driver
        driver.get("http://news.google.com")
        #driver.find_element_by_xpath("//div[@id='main-wrapper']/div[@id='main-pane']/div[@class='background']/div[@class='centered']/div[@id='nav-menu-wrapper']/div[@class='browse-sidebar']/ul[@id='anchorman-two-browse-nav']/li[@class='nav-item nv-en_us:tc']/a[contains(text(),'Technology')]").click()
        #driver.find_element_by_xpath("//ul[@id='anchorman-two-browse-nav']/li/a[contains(text(),'Technology')]").click()
        #driver.find_element_by_xpath("//ul[@id='anchorman-two-browse-nav']/li[@class='nav-item nv-en_us:tc']/a[contains(text(),'Technology')]").click()
        #driver.find_element_by_xpath("html/body/div[3]/div[1]/div/div/div[2]/div/ul/li[6]/a").click()
        #driver.find_element_by_link_text("Technology").click()
        wait = WebDriverWait(driver, 10)
        link = wait.until(EC.presence_of_element_located((By.XPATH, "//ul[@id='anchorman-two-browse-nav']/li/a[contains(text(),'Technology')]")))
        link.click()
        time.sleep(10)
        ...

I've tried many combinations (all the commented out lines plus more!), but still cannot get it to work. I've check to make sure that the element I am using does exists (using Element Inspector) before entering it into the code. But even the "find_element_by_link_text" is giving me a NoSuchElementException exception. Can someone please tell me what I am doing wrong?

UPDATE: After doing further tests, I now have a better understanding of when this error is occuring for the news.google.com page. So, basically, the side menu, that contains the "Technology" link, is set to scrollable (I believe this error is only happening because the link is in scrollable area). The error is show up if the browser (that the Selenium script opens up when you run it), does not show the "Technology" link ie. You have to maximize the browser or scroll down to see the link. You can test this error out yourself - when the test opens up the browser, quickly resize the browser window so that the "Technology" link is not showing, and the test will fail. If your initial browser window doesn't show "Technology" link when it first opens, it will fail unless you maximize the browser window or scroll down really quickly until the "Technology" link is displayed. The error can take two forms - if you are using the wait.until method, you will get a Timeoutexception. If you are not using the wait.until method, you will see the ElementNotVisibleException. I've tested in both Chrome and Firefox and for both, I am seeing this problem. I am new to Selenium, but I believe this is not normal behavior, can someone please confirm? If this normal, then can someone please tell me how I can make sure my test runs correctly each time?

Upvotes: 1

Views: 4236

Answers (1)

Jess
Jess

Reputation: 3146

I think you want to use element_to_be_clickable as your ExpectedCondition.

That means that your driver will keep polling Selenium until it finds that the element is visible and enabled source

Try the below solution

 link = wait.until(EC.element_to_be_clickable((By.XPATH, "//ul[@id='anchorman-two-browse-nav']/li/a[contains(text(),'Technology')]")))

 link.click()
 time.sleep(10)

Upvotes: 2

Related Questions