Khắc phục lỗi JavaScript trong Selenium


81

Có cách nào để ghi lại lỗi xảy ra DOMtrong Seleniumvà có thể gắn cờ giống như một lỗi trong trang không?

Để đưa ra một ví dụ ngắn gọn, giả sử tôi đang cố gắng liên kết một sự kiện trên một điều khiển HTML không tồn tại, trình duyệt của tôi gặp lỗi cho biết:

element abcd not found in the console.

Bây giờ, nếu tôi muốn lỗi tương tự sẽ không thực hiện được các bài kiểm tra selen của mình và thông báo hiển thị trên trình duyệt được hiển thị là thông báo lỗi.

Có thể làm một cái gì đó như thế này?


1
Bây giờ là năm 2018, có giải pháp nào sạch hơn không?
Fla,

Câu trả lời:


52

Đặt tập lệnh này trên trang của bạn và sau đó kiểm tra Selenium cho lỗi JSError:

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

3
Điều này có thể dễ dàng được mở rộng để giải quyết trường hợp JQuery không tải: thêm $ ('body'). Attr ("JQLoaded", "Yes") bên ngoài lệnh gọi onerror. Sau đó, trong Selenium sự hiện diện của JSError, HOẶC không có JQLoaded, báo hiệu lỗi Javascript.
Nils

51
Hoặc bạn chỉ có thể nói document.body.setAttribute("JSError", msg)thay vì phụ thuộc vào jQuery
Kos

3
Nó có phải được thêm vào trang HTML mãi mãi hay tự động khi chạy thử nghiệm ?? Tôi không chắc mình sẽ thuyết phục các nhà phát triển thêm đoạn mã đó trên mỗi trang. Cảm ơn đã chia sẻ chi tiết cho tôi.
Michal

3
Trang liên kết không còn nữa.
Chris B. Behrens

54

Tôi đang làm điều này để nắm bắt các lỗi 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
Thực sự thích giải pháp này
Rob G

2
Sử dụng phiên bản mới nhất của Trình điều khiển Selenium 3.6.0 và Firefox 56.0, phương thức "GetLog" đưa ra thông báo "Tham chiếu đối tượng không được đặt thành phiên bản của đối tượng", không rõ tại sao ... Điều này hoạt động trong phiên bản cũ hơn của WebDriver / Firefox
David Rogers

2
@DavidRogers Tôi nghĩ rằng tính năng này không còn hoạt động trên geckodriver nữa vì điều này: github.com/mozilla/geckodriver/issues/284
Christian Hujer,

19

Không chắc khi nào điều này thay đổi, nhưng ngay bây giờ điều này phù hợp với tôi bằng Python. Tệp là một trang đơn giản có lỗi 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 phiên bản 2.48.0 Linux Firefox 43.0


Điều này cũng hoạt động với webdriver.io. driver.log("browser").then(function(results){ console.log(results.value); }
Tyler Hawkins

Điều này hiện sẽ không hoạt động với Firefox do sự cố này: github.com/mozilla/geckodriver/issues/284
Christian Hujer,

7

Đây là giải pháp python webdriver mà tôi sử dụng:

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

6

JSErrorCollector thực hiện công việc.

Sau khi được định cấu hình, vấn đề là:

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

2
FYI: dự án này hiện chỉ hỗ trợ Firefox
Căn chỉnh

Lần cam kết cuối cùng cách đây 4 năm, nói về Firefox 36 và Firebug ... Vì vậy, nhiều thứ đã thay đổi kể từ đó.
Fla,

và đây có phải là bài đăng blog ban đầu cho điều này? mguillem.wordpress.com/2011/10/11/…
David


3

Tôi muốn lặp lại câu trả lời của jhanifen. Đây là một giải pháp javascript không phụ thuộc vào jQuery. Nó tạo ra một danh sách HTML vô hình ở cuối trang, nơi chứa các lỗi.

(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

Giải pháp với "window.onerror" không hoạt động với tôi.

Vì vậy, tôi muốn chỉ ra một giải pháp khác với việc thay đổi user-extension.js đã giúp tôi:
Liệu Selenium có thể phát hiện xem trang có lỗi JavaScript không?

Ưu điểm chính: Bạn không cần phải thay đổi nguồn trang để kiểm tra.

Và đây là cách sử dụng user-extension.js:
Sử dụng User-Extensions Với Selenium-IDE

Lưu ý: Giải pháp này chỉ hoạt động với Firefox


2

Đây là giải pháp của tôi đầy cảm hứng bởi phản hồi của 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'}

1

Nếu bạn đang sử dụng java, bạn có thể dùng thử thư viện này do tôi cung cấp, cho phép dễ dàng thu thập các lỗi JS nhận được trong phiên Chromedriver, bằng cách sử dụng chú thích về phương pháp thử nghiệm. Nó hoạt động trên JUnit5 với chú thích mở rộng và trên TestNG với trình nghe phân tích cú pháp chú thích. Chú thích chứa các giá trị boolean cho phép bạn quyết định xem bạn muốn xác nhận hay ghi lại các lỗi đã tìm thấy sau khi thực hiện kiểm tra.

Ví dụ về 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

Tôi sử dụng những điều sau đây TestCase.tearDown()trong các bài kiểm tra Python Selenium của mình khiến bài kiểm tra không thành công trong trường hợp lỗi 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)}')

Điều này được truyền cảm hứng từ câu trả lời @kleptog và @ d3ming.


0

Bạn thử đưa sự kiện windows.onerror vào trang của mình hoặc bật hộp thoại hiển thị lỗi trong tùy chọn IE. Nếu bạn chọn sau trong Se1 sẽ bị treo. Tái bút: Điều này đã được thảo luận ở đây. Thực hiện tìm kiếm.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.