Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ElementNotVisibleException: Message: Element is not currently visible... selenium (python)

I am getting those annoying element is not visible exception using python's selenium, while the element is active, selected, and flashing.

The issue is on the page to make a jfiddle, so instead of making a fiddle of the fiddle itself here is a cut and paste way to log in and have a webdriver (named 'driver') in your ipython terminal (enter username and password into ipython, not the page):

https://gist.github.com/codyc4321/787dd6f62e71cc71ae83

Now there is a driver up and you're logged into jsfiddle, everything I do here fails except picking the box the first time (let's say I wanna drop CSS in the CSS box):

https://gist.github.com/codyc4321/f4c03c0606c2e3e4ff5b

Paste activate_hidden_element and the first codeline in and see the CSS panel light up. For some reason, this highlighted panel is 'not visible', and you can't paste and code in it. The item is

  <div class="window top" id="panel_css" data-panel_type="css">
    <textarea id="id_code_css" rows="10" cols="40" name="code_css"></textarea>
    <a href="#" class="windowLabel" data-panel="css">
      <span class="label">CSS</span><i class="bts bt-gear"></i>
    </a>
  </div>

All the other items (HTML, JS) are essentially the same. Why won't this active box allow text to paste in? Thank you

SOLUTION:

the ugly way I made this service work was to manually fake a cut and paste:

css_content = get_inline_content_and_remove_tags(webpage_content, 'style')

js_content = get_inline_content_and_remove_tags(webpage_content, 'script')

webpage_content = # ...clean cruft...

def copy_paste_to_hidden_element(content=None, html_id=None):
    pyperclip.copy(content)
    activate_hidden_element(html_id=html_id, driver=driver)
    call_sp('xdotool key from+ctrl+v')
    time.sleep(1)

copy_paste_to_hidden_element(content=webpage_content, html_id="panel_html")
copy_paste_to_hidden_element(content=js_content, html_id="panel_js")
copy_paste_to_hidden_element(content=css_content, html_id="panel_css")

It does work, the only minor issue is it can't run in the background, I need to leave the screen alone for about 30 seconds

like image 305
codyc4321 Avatar asked Dec 24 '15 18:12

codyc4321


People also ask

How to handle element not visible exception in Selenium python?

Hence on trying to locate the hidden button (which is not visible on the page and has HTML code available), we get ElementNotVisibleException WebDriver Exception. In order to handle this, we have to use ElementNotVisibleException WebDriver Class in the catch block.

What do you do if the WebElement is not visible?

Element not visible exception can be resolved by using Explicit wait. Explicit wait in selenium will wait until the element is visible. Once it's visible you can perform the necessary operation. WebDriverWait wait = new WebDriverWait(driver,30); WebElement e = wait.

How can we handle element which is not visible on the screen because of resolution issue?

Solution: You need to scroll to element using javascript or Actions class so that element is perfectly visible on screen. By using explicit wait and fluent wait as mentioned above.


1 Answers

JSFiddle editors are powered by CodeMirror which has a programmatic way to set editor values.

For every JSFiddle editor you need to put values into, locate the element with a CodeMirror class, get the CodeMirror object and call setValue():

css_panel = driver.find_element_by_id("panel_css")

code_mirror_element = css_panel.find_element_by_css_selector(".CodeMirror")
driver.execute_script("arguments[0].CodeMirror.setValue(arguments[1]);",
                      code_mirror_element, 
                      "test")

Demo, using JS panel executing the alert("Test"); Javascript code:

>>> from selenium import webdriver
>>>
>>> driver = webdriver.Firefox()
>>> driver.get("https://jsfiddle.net/user/login/")
>>> driver.find_element_by_id("id_username").send_keys("user")
>>> driver.find_element_by_name("password").send_keys("password")
>>> driver.find_element_by_xpath("//input[@value = 'Log in']").click()
>>> 
>>> driver.get("https://jsfiddle.net/")
>>> 
>>> js_panel = driver.find_element_by_id("panel_js")
>>> 
>>> code_mirror_element = js_panel.find_element_by_css_selector(".CodeMirror")
>>> driver.execute_script("arguments[0].CodeMirror.setValue(arguments[1]);", code_mirror_element, "alert('test');")
>>> 
>>> driver.find_element_by_id("run").click()
>>>

It produces:

enter image description here

like image 178
alecxe Avatar answered Oct 10 '22 06:10

alecxe