Open thoughtextreme opened 4 years ago
Here's an even simpler repro case
sanjuro2:~ fulcrum$ cat inner.html
<html>
<head>
<title>Inner</title>
</head>
<body>
Inner
</body>
</html>
sanjuro2:~ fulcrum$ cat outer.html
<html>
<head>
<title>Outer</title>
</head>
<body>
Outer
<iframe src="inner.html">iframe</iframe>
</body>
</html>
sanjuro2:~ fulcrum$ source ~/venv/helium/bin/activate
(helium) sanjuro2:~ fulcrum$ python3
Python 3.7.3 (default, Mar 27 2019, 09:23:15)
[Clang 10.0.1 (clang-1001.0.46.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from helium import *
>>> driver=start_firefox()
>>> go_to('file:///Users/fulcrum/inner.html')
>>> driver.current_url
'file:///Users/fulcrum/inner.html'
>>> find_all(S('body'))
[<body>Inner</body>]
>>> go_to('file:///Users/fulcrum/outer.html')
>>> driver.current_url
'file:///Users/fulcrum/outer.html'
>>> find_all(S('body'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/fulcrum/venv/helium/lib/python3.7/site-packages/helium/__init__.py", line 563, in __repr__
element_html = self.web_element.get_attribute('outerHTML')
File "/Users/fulcrum/venv/helium/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py", line 141, in get_attribute
self, name)
File "/Users/fulcrum/venv/helium/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 636, in execute_script
'args': converted_args})['value']
File "/Users/fulcrum/venv/helium/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/Users/fulcrum/venv/helium/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: The element reference of <body> is stale; either the element is no longer attached to the DOM, it is not in the current frame context, or the document has been refreshed
I'll be happy to accept a pull request that adds a test for this and fixes it :-)
hi @mherrmann
The problem related to occurrence of stale elements is due to "web_element.get_attribute" happening on main/parent web element. When iframes present we need to switch to the iframe and then execute "web_element.get_attribute('outerHTML')"
The following are code changes, if you think this makes any sense can raise a PR and checkin
in "/helium/init.py" file, class "class HTMLElement(GUIElement)" ,we can ----------------------------------------- CODE SNIP STARTS ----------------------------------------- ` def repr(self):
if self._is_bound():
try:
element_html = self.web_element.get_attribute('outerHTML')
except:
for new_frame in range(sys.maxsize):
try:
self._driver.switch_to.frame(new_frame)
except WebDriverException:
break
element_html = self.web_element.get_attribute('outerHTML')
return get_easily_readable_snippet(element_html)
else:
return super(HTMLElement, self).__repr__()`
----------------------------------------- CODE SNIP ENDS -----------------------------------------
@karthik233 thanks. There are a few problems with the snippet you posted I think:
try ... except
without any exception type is too general. Ideally, it should catch precisely the exception type that can be raised by .get_attribute(...)
.switch_to.frame(0)
above fails for any reason, then element_html
will be undefined.switch_to(...)
in a loop up to sys.maxsize
for a simple __repr__
call seems overkill, especially if switch_to(...)
changes the web driver's state. I would just try ... except <appropriate exception type>
and in the case of that exception return a string such as "<StaleElementException occurred computing __repr__>"
.Hi @mherrmann ,
thanks for your reply. will improve. Any other corner cases we need to cover?
Hi, I have an SPA that I'm trying to do some automated testing with
helium works fine when the elements are in the main page, but the app uses AJAX to load some content into an iframe, so when I try to find those elements to click on, I get an exception
the following demonstrates the issue: