捕获Selenium中的JavaScript错误


81

有没有办法捕获inDOM中发生的错误Selenium并可能将其标记为页面中的错误?

举个简单的例子,假设我试图在一个不存在的HTML控件上绑定一个事件,我的浏览器抛出一个错误:

element abcd not found in the console.

现在,如果我希望同一错误无法通过我的硒测试,并且浏览器上显示的消息将显示为错误消息。

是否可以做这样的事情?


1
现在是2018年,有没有更清洁的解决方案?
Fla

Answers:


52

将此脚本放在页面上,然后在Selenium中检查JSError:

<script type="text/javascript">
    window.onerror=function(msg){
        $("body").attr("JSError",msg);
    }
</script>

3
这可以很容易地扩展以捕获未加载JQuery的情况:在onerror调用之外添加$('body')。attr(“ JQLoaded”,“ Yes”)。然后,在Selenium中,存在JSError或不存在JQLoaded,都表示Javascript错误。
尼尔斯2012年

51
或者,您可以说document.body.setAttribute("JSError", msg)而不是依赖jQuery
Kos

3
是否必须将其永久添加到HTML页面,或者在运行测试时动态添加?我不确定我会说服开发人员在每个页面上添加该代码段。感谢您分享我的详细信息。
Michal

3
链接的页面不再可用。
克里斯·贝伦斯

54

我这样做是为了捕获JavaScript错误:

[TestCleanup]
public void TestCleanup()
{
    var errorStrings = new List<string> 
    { 
        "SyntaxError", 
        "EvalError", 
        "ReferenceError", 
        "RangeError", 
        "TypeError", 
        "URIError" 
    };

    var jsErrors = Driver.Manage().Logs.GetLog(LogType.Browser).Where(x => errorStrings.Any(e => x.Message.Contains(e)));

    if (jsErrors.Any())
    {
        Assert.Fail("JavaScript error(s):" + Environment.NewLine + jsErrors.Aggregate("", (s, entry) => s + entry.Message + Environment.NewLine));
    }
}

3
真的很喜欢这种解决方案
Rob G

2
使用最新版本的Selenium驱动程序3.6.0和Firefox 56.0时,“ GetLog”方法将引发“对象引用未设置为对象的实例”,不确定为什么...在旧版本的WebDriver / Firefox
David Rogers

2
@DavidRogers我认为这不再适用于geckodriver,因为:github.com/mozilla/geckodriver/issues/284
Christian Hujer,

19

不知道什么时候改变了,但是现在这对我来说适用于Python。该文件是带有javascript错误的简单页面。

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-硒版本2.48.0 Linux Firefox 43.0


这也适用于webdriver.io。 driver.log("browser").then(function(results){ console.log(results.value); }
泰勒·霍金斯

由于以下原因,当前该功能不适用于Firefox:github.com/mozilla/geckodriver/issues/284
Christian Hujer,

7

这是我使用的python webdriver解决方案:

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



3

我想重复贾尼芬的答案。这是一个不依赖jQuery的JavaScript解决方案。它在页面底部创建了一个不可见的HTML列表,从而确定了错误。

(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);
    };
})();


2

在这里,我的解决方案受到詹妮芬的回应启发:

// 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'}

1

如果您使用的是Java,欢迎尝试由我提供的该库该库可以使用测试方法上的注释轻松收集Chromedriver会话中收到的JS错误。它适用于带有扩展注释的JUnit5,以及适用于具有解析注释的侦听器的TestNG。批注包含布尔值,使您可以决定在执行测试后是要断言还是记录发现的错误。

JUnit5示例:

@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();
}

1

TestCase.tearDown()在Python Selenium测试中使用以下命令,如果JavaScript错误,该测试将失败:

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)}')

这是受@kleptog和@ d3ming答案的启发。


0

您尝试在页面中包含windows.onerror事件,或在IE选项中启用显示错误对话框。如果您选择在Se1的后面将挂起。PS:这里已经讨论过了。进行搜索。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.