ElementNotVisibleException: Message: element not visible
It’s frustrating since virtually all help threads Ive found on Stack Overflow and on other blogs are close but never offered help that actually works. Maybe because my issue is not quite the same or because I write my tests differently, but truly I’ve never gotten any of those solutions to work. The following is a list of things that are either really bad ideas or just never worked for me:
- Sleep the browser
- Programmatically move the cursor 1px in order to find a button hit state
- Injecting click actions into the browser developer console (ewww)
- Use XPATH instead of CSS Locator
- Get the size of the element first then click
Finally just breaking down and looking at the Docs for Waits in Selenium/Python there, of course seems to be some promise. The example they give is as follows:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox() driver.get("http://somedomain/url_that_delays_loading") try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "myDynamicElement")) ) finally: driver.quit()
Scanning the code quickly, I figured this was right up my alley. I copied the code, changed the placeholder element to the one I’m looking for, saved the file, rebuilt Docker, and ran the test. Same failure. Literally this code changed nothing. It didn’t wait, the element was still not visible and the test still failed. Ugg.
I read back through the code more thoroughly and noticed the Expected Condition line of
which caught my eye. Presence. Ahh, right ok. My issue was not that the element was not present, which can also happen. My issue this time as you recall above was that the element was not Visible. Ok, dig deeper into the docs and look at the full list of Expected Conditions which are:
title_is title_contains presence_of_element_located visibility_of_element_located visibility_of presence_of_all_elements_located text_to_be_present_in_element text_to_be_present_in_element_value frame_to_be_available_and_switch_to_it invisibility_of_element_located element_to_be_clickable - it is Displayed and Enabled. staleness_of element_to_be_selected element_located_to_be_selected element_selection_state_to_be element_located_selection_state_to_be alert_is_present
Ahh, look at this. Visibility conditions. This is looking promising! Let’s make a quick change to something like:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Firefox() driver.get("http://somedomain/url_that_delays_loading") try: element = WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.ID, "myDynamicElement")) ) finally: driver.quit()
Save the file, rebuild Docker, run the test. While testing in our dev environment I have Docker run the test with a headed browser, usually Chrome or FF so I’m able to watch it run. This time around something is different. The test properly pauses while the page content is loading in dynamically then once loaded the test proceeded. Success! That was it.