You try including windows.onerror event in your page or enable the show error dialog box in IE options. If you choose the later in Se1 will hang.
PS: This has been discussed here. Do a search.
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''}]
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'}
I would like to iterate on the answer of jhanifen. Here is a javascript solution that does not depend on jQuery. It creates an invisible HTML list on the bottom of the page, which contians the errors.
(function () {
var ul = null;
function createErrorList() {
ul = document.createElement('ul');
ul.setAttribute('id', 'js_error_list');
ul.style.display = 'none';
document.body.appendChild(ul);
}
window.onerror = function(msg){
if (ul === null)
createErrorList();
var li = document.createElement("li");
li.appendChild(document.createTextNode(msg));
ul.appendChild(li);
};
})();
from selenium.common.exceptions import WebDriverException
import logging
def check_browser_errors(driver):
"""
Checks browser for errors, returns a list of errors
:param driver:
:return:
"""
try:
browser_logs = driver.get_log('browser')
except (ValueError, WebDriverException) as e:
# Some browsers does not support getting logs
logging.debug("Could not get browser logs for driver %s due to exception: %s",
driver, e)
return []
errors = [entry for entry in browser_logs if entry['level'] == 'SEVERE']
return errors
If you're using java, you're welcome to try this library comitted by me which allows to easily collect JS errors received in Chromedriver session, using annotations on test methods. It works on on JUnit5 with extended annotation, and on TestNG with a listener parsing the annotation.
The annotation contains boolean values which let you decide whether you want to assert or log the found errors after test execution.
JUnit5 example:
@Test
@JSErrorsCollectorJUnit
void referenceErrorTest(TestInfo testInfo) throws InterruptedException {
// Create a new instance of ChromeDriver.
driver = new ChromeDriver();
// Set your test name to point its ChromeDriver session in HashMap.
JSErrorsDriverHolder.setDriverForTest(testInfo.getDisplayName(), driver);
// Navigate to URL.
driver.get("http://testjs.site88.net");
// The click on the button in the test site should cause JS reference error.
driver.findElement(By.name("testClickButton")).click();
waitBeforeClosingBrowser();
}
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)}')