Is there a way to capture errors occurring in the DOM
in Selenium
and probably flag the same as an error in the page?
To give a brief exam
I use the following TestCase.tearDown()
in my Python Selenium tests that makes the test fail in case of JavaScript errors:
def tearDown(self):
browser_logs = driver.get_log("browser")
errors = [logentry['message'] for logentry in browser_logs if logentry['level'] == 'SEVERE']
if errors:
self.fail(f'The following JavaScript errors occurred: {"; ".join(errors)}')
This is inspired by @kleptog and @d3ming answers.
Solution with "window.onerror" didn't work for me.
So I'd like to point out another solution with altering user-extensions.js which helped me:
Can Selenium detect if the page has JavaScript errors?
Main advantage: You don't have to change the page source to do the check.
And here is how to use user-extensions.js:
Using User-Extensions With Selenium-IDE
Note: This solution works only with Firefox
Not sure when this changed, but right now this works for me in Python. The file is a simple page with a javascript error.
In [11]: driver.get("file:///tmp/a.html")
In [12]: driver.get_log("browser")
Out[12]:
[{u'level': u'SEVERE',
u'message': u'ReferenceError: foo is not defined',
u'timestamp': 1450769357488,
u'type': u''},
{u'level': u'INFO',
u'message': u'The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol.',
u'timestamp': 1450769357498,
u'type': u''}]
Python-Selenium version 2.48.0 Linux Firefox 43.0
Here's the python webdriver solution I use:
def check_browser_errors(driver):
"""
Checks browser for errors, returns a list of errors
:param driver:
:return:
"""
try:
browserlogs = driver.get_log('browser')
except (ValueError, WebDriverException) as e:
# Some browsers does not support getting logs
LOGGER.debug("Could not get browser logs for driver %s due to exception: %s",
driver, e)
return []
errors = []
for entry in browserlogs:
if entry['level'] == 'SEVERE':
errors.append(entry)
return errors
Non-window.onerror
-based solution (I did not try): http://sejq.blogspot.com/2008/12/can-selenium-detect-if-page-has.html
Here my solution inspiring by jhanifen's response:
// common.js - js file common to the entire app
globalError = []
window.onerror = function (msg, url, line, col, error) {
globalError.push({msg:msg, url:url, line:line})
};
# tests.py
def tearDown(driver):
# assert on js error
ret = driver.selenium.execute_script("return globalError ")
driver.assertFalse(ret, "errors %r " % ret)
# ret will be a dict looking like
# {'line': 50, 'url': 'http://localhost:8081/static/js/common.js', 'msg': 'Uncaught ReferenceError: s is not defined'}