Reputation: 7408
Courtesy of this answer I've got this bit of Selenium working:
import contextlib
from selenium import webdriver
with contextlib.closing(webdriver.Chrome()) as driver:
driver.get("http://www.bing.com/images")
driver.find_element_by_id("sbi_t").click()
element = driver.find_element_by_id("sbi_file_upload")
element.send_keys("//Loch Ness Monster.jpg")
However, when I switch from webdriver.Chrome()
to webdriver.Firefox()
, I start getting selenium.common.exceptions.ElementNotVisibleException: Message: Element is not currently visible and so may not be interacted with
. My guess is that the error is related to the magic that Selenium performs to work with operating system file upload selector dialogs. I would think that's probably also why my attempts to wait until the element becomes visible aren't working: the "magic" does not involve the element ever becoming visible. Here's what I tried:
# https://stackoverflow.com/a/15142611/2829764, found via https://stackoverflow.com/q/6101461/2829764
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
...
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "sbi_file_upload")))
I'm using Firefox 36.0.1, Selenium 2.45.0, and Python 2.7.9. Incidentally, Selenium had stopped working with Firefox when I updated Firefox to 36.0.1 but I updated my Selenium today and the particular problem I was having went away.
Upvotes: 1
Views: 2230
Reputation:
Try This , If is_displayed()
method gives an exception
from selenium import webdriver
def is_Displayed(class_name):
ele=driver.execute_script("return document.getElementsByClassName('"+class_name+"')[0].style.visibility = 'visible';")
if ele=="visible":
return True
else:
return False
def test_check_element():
global driver
driver=webdriver.Safari()//e.g Firefox() , Chrome()
driver.maximize_window()
driver.implicitly_wait(30)
driver.get("url")
submitBtn=driver.find_element_by_xpath("//button[@title='Submit']").get_attribute("class")
if is_Displayed(submitBtn)== True:
print "Displayed "
else:
print "Not Displayed"
Upvotes: 0
Reputation: 21
The solution 'make the element visible in firefox ' was great for me
driver.execute_script('arguments[0].style = "";
arguments[0].style.display = "block";
arguments[0].style.visibility = "visible";', file_input)
Upvotes: 2
Reputation: 7408
Lightly modified version of @alexce's answer. It's the only thing I've found that works consistently on my machine.
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
import selenium
driver = webdriver.Firefox()
driver.get('http://www.bing.com/images')
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "sbi_t")))
driver.find_element_by_id("sbi_t").click()
try:
WebDriverWait(driver, 1).until(EC.visibility_of_element_located((By.ID, "sbi_file_upload")))
raise Exception("This never seems to happen")
except selenium.common.exceptions.TimeoutException:
pass
button = driver.find_element_by_id('sbi_gh')
driver.execute_script('arguments[0].style.display = "block";', button)
button.click() # submitting the form, empty file
driver.back()
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, "sbi_t")))
driver.find_element_by_id("sbi_t").click()
file_input = driver.find_element_by_id('sbi_file_upload')
driver.execute_script('arguments[0].style = ""; arguments[0].style.display = "block"; arguments[0].style.visibility = "visible";', file_input)
file_input.send_keys("//Loch Ness Monster.jpg")
Upvotes: 2
Reputation: 473983
The element you are sending keys to has an opacity value set to 0
:
<input id="sbi_file_upload" name="imageBinary" type="file" accept="image/*" style="opacity: 0;">
And Firefox
(correctly) thinks the element is invisible:
>>> from selenium import webdriver
>>> driver = webdriver.Firefox()
>>> driver.get("http://www.bing.com/images")
>>> driver.find_element_by_id("sbi_t").click()
>>> element = driver.find_element_by_id("sbi_file_upload")
>>> element.is_displayed()
False
Here are the relevant issues that actually are the reason for the behavior we see:
The solution here would be to make the input
visible so that we can send the keys to it. I've found a rather weird way to make the input visible - it involves sending an empty file value first, going back and making the input
visible through execute_script()
. Hope, you'll make it work without an extra back()
step:
>>> driver = webdriver.Firefox()
>>> driver.get('http://www.bing.com/images')
>>> driver.maximize_window()
>>>
>>> driver.find_element_by_id("sbi_t").click()
>>>
>>> button = driver.find_element_by_id('sbi_gh')
>>> driver.execute_script('arguments[0].style.display = "block";', button)
>>> button.click() # submitting the form, empty file
>>>
>>> driver.back()
>>> driver.find_element_by_id("sbi_t").click()
>>>
>>> file_input = driver.find_element_by_id('sbi_file_upload')
>>> file_input.is_displayed()
False
>>>
>>> driver.execute_script('arguments[0].style = ""; arguments[0].style.display = "block"; arguments[0].style.visibility = "visible";', file_input)
>>>
>>> file_input.is_displayed()
True
And now you can send keys to file input - tested, works for me.
Upvotes: 2