在 Selenium 中捕获 JavaScript 错误

发布于 2024-10-03 00:37:09 字数 240 浏览 1 评论 0原文

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

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

在控制台中找不到元素 abcd。

现在,如果我希望同样的错误使我的硒测试失败,并且浏览器上显示的消息显示为错误消息。

可以做这样的事情吗?

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 example, let's say I'm trying to bind an event on a non-existing HTML control, my browser throws an error saying:

element abcd not found in the console.

Now, if I want the same error to fail my selenium tests and the message that is shown on the browser is shown as the error message.

Is it possible to do something like this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

花辞树 2024-10-10 00:37:09

我这样做是为了捕获 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));
    }
}

I'm doing this to capture JavaScript errors:

[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));
    }
}
心不设防 2024-10-10 00:37:09

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

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

Put this script on your page and then check in Selenium for the JSError:

<script type="text/javascript">
    window.onerror=function(msg){
        $("body").attr("JSError",msg);
    }
</script>
初懵 2024-10-10 00:37:09

不确定这是什么时候改变的,但现在这对我来说在 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-Selenium 版本 2.48.0
Linux 火狐 43.0

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

如歌彻婉言 2024-10-10 00:37:09

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

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

Here's the python webdriver solution I use:

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
星星的轨迹 2024-10-10 00:37:09

JSErrorCollector 完成这项工作。

配置完成后,需要执行以下操作:

List<JavaScriptError> jsErrorList = JavaScriptError.readErrors(driver);

JSErrorCollector does the job.

Once configured, it's a matter of:

List<JavaScriptError> jsErrorList = JavaScriptError.readErrors(driver);
孤云独去闲 2024-10-10 00:37:09

非基于 window.onerror 的解决方案(我没有尝试):http://sejq.blogspot.com/2008/12/can-selenium-detect-if-page-has.html

Non-window.onerror-based solution (I did not try): http://sejq.blogspot.com/2008/12/can-selenium-detect-if-page-has.html

财迷小姐 2024-10-10 00:37:09

“window.onerror”的解决方案对我不起作用。

所以我想指出另一个改变 user-extensions.js 的解决方案,这对我有帮助:
Selenium 可以检测页面是否存在 JavaScript 错误吗?< /a>

主要优点:您不必更改页面源来进行检查。

以下是如何使用 user-extensions.js:
通过 Selenium-IDE 使用用户扩展

注意:此解决方案仅适用于 Firefox

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

微暖i 2024-10-10 00:37:09

我想重申一下詹尼芬的答案。这是一个不依赖于 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);
    };
})();

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);
    };
})();
往事随风而去 2024-10-10 00:37:09

这是我的解决方案,受到 jhanifen 回应的启发:

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

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'}
dawn曙光 2024-10-10 00:37:09

我在 Python Selenium 测试中使用以下 TestCase.tearDown() ,这使得在出现 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 答案的启发。

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.

说好的呢 2024-10-10 00:37:09

如果您使用的是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();
}

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();
}
你如我软肋 2024-10-10 00:37:09

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文