Виявлення помилки JavaScript у Selenium


81

Чи є спосіб захоплення помилок відбувається в DOMв Seleniumі , ймовірно , той же прапор як помилка на сторінці?

Для короткого прикладу, скажімо, я намагаюся прив’язати подію до неіснуючого елемента керування HTML, мій браузер видає помилку, кажучи:

element abcd not found in the console.

Тепер, якщо я хочу, щоб та сама помилка провалила мої тести на селен, і повідомлення, яке відображається в браузері, відображається як повідомлення про помилку.

Чи можна зробити щось подібне?


1
Зараз 2018 рік, чи є чистіше рішення?
Fla

Відповіді:


52

Помістіть цей сценарій на свою сторінку, а потім перевірте в Selenium помилку JSError:

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

3
Це можна легко розширити, щоб також виявити випадок, коли JQuery не завантажився: додайте $ ('body'). Attr ("JQLoaded", "Yes") поза викликом onerror. Тоді в Selenium наявність JSError, АБО відсутність JQLoaded, сигналізує про помилку Javascript.
Нільс,

51
Або ви можете просто сказати, document.body.setAttribute("JSError", msg)замість того, щоб залежати від jQuery
Кос

3
Чи потрібно його додавати на сторінку HTML назавжди, або динамічно під час запуску тестів ?? Я не впевнений, що переконав би розробників додавати цей фрагмент на кожну сторінку. Дякую, що поділилися для мене деталями.
Міхал

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
Дуже подобається це рішення
Роб Г

2
Використовуючи останню версію драйвера Selenium 3.6.0 та Firefox 56.0, метод "GetLog" видає "Посилання на об'єкт, не встановлене на екземпляр об'єкта", не впевнений, чому ... Це працювало в попередній версії WebDriver / Firefox
Девід Роджерс

2
@DavidRogers Я думаю, що це вже не працює на geckodriver через це: github.com/mozilla/geckodriver/issues/284
Крістіан Хуєр

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-Selenium 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
Крістіан Худжер,

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

6

JSErrorCollector виконує цю роботу.

Після налаштування це питання:

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

2
FYI: цей проект наразі підтримує лише Firefox
AlignedDev

1
Останній коміт 4 роки тому, говорить про Firefox 36 та Firebug ... Так багато речей змінилося з тих пір.
Fla

і це оригінальна публікація в цьому блозі? mguillem.wordpress.com/2011/10/11/…
Девід


3

Я хотів би повторити відповідь джаніфену. Ось рішення javascript, яке не залежить від jQuery. Він створює невидимий список 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

Рішення з "window.onerror" у мене не спрацювало.

Тож я хотів би вказати на інше рішення із зміною user-extensions.js, яке мені допомогло:
чи може Selenium виявити, чи є на сторінці помилки JavaScript?

Головна перевага: Вам не потрібно міняти джерело сторінки, щоб зробити перевірку.

І ось як користуватися user-extensions.js:
Використання розширень користувача з Selenium-IDE

Примітка. Це рішення працює лише з Firefox


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, ви можете спробувати цю бібліотеку , призначену мною, яка дозволяє легко збирати помилки JS, отримані в сеансі Chromedriver, використовуючи анотації на тестових методах. Він працює на 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: Це було обговорено тут. Зробіть обшук.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.