Логгирование в Selenium Webdriver

Логгирование важно как для разработчиков так и для пользователей Webdriver. Пользователи хотят иметь возможность быстро понять почему упал тест, в то время как разработчик хочет получить информацию, почему Webdriver упал. Хорошее логгирование может сделать дебаггинг намного проще.

Типы логов

Webdriver может быть использован в различных конфигурациях. К примеру, клиент запускающий тест (Java) может напрямую взаимодействовать с драйвером (локальный запуск), который контролирует браузер, или опосредованно через сервер (удаленный запуск). В зависимости от конфигурации могут быть доступны различные типы логов. Поэтому webdriver предоставляет возможность узнать типы поддерживаемых логов.

Set<String> logTypes = getWebDriver().manage().logs().getAvailableLogTypes();

В целом при дебагинге определенной конфигурации было бы полезно получить доступ к логам каждого отдельного компонента конфигурации. А это: клиент (Java bindings), сервер (если Grid), драйвер и браузер. Все же логи всех компонентов не могут быть доступны во всех конфигурациях. Пример с использованием сервера (или не использованием) - самый простой, но логи также могут не поддерживаться или их невозможно будет получить из-за браузера. Впридачу к этому, иногда могут быть доступны и некоторые другие типы логов. Например, могут быть доступны логи, предназначенные для сбора данных о производительности на стороне клиента.

Таким образом, известные типы доступных для webdriver логов:

Типы логов Значение
browser Логи от javascript консоли браузера
client Логи от клиентской части протокола Webdriver (например, Java bindings)
driver Внутренние логи драйвера (например, логи FirefoxDriver)
performance Логи относящиеся к производительности на странице (тайминги загрузки ресурсов)
server Логи от Selenium сервера

Более подробно о типах логов и их получении можно найти на странице спецификации JsonWireProtocol https://code.google.com/p/selenium/wiki/JsonWireProtocol

Логи состоят из записей, каждая из которых содержит время (timestamp), уровень (log level) и сообщение.

Уровни логгирования (log levels)

Предназначение уровней логгирования - это предоставить пользователю способ фильтрации сообщений лога в зависимости от уровня интереса пользователя. Например, если цель логгирования - дебаггинг, то практически все сообщения будут нужны, в то время как при общем мониторинге понадобится меньше информации.

Для Webdriver были разработаны следующие уровни логгирования (в порядке возрастания детализированности):

  • OFF: Логгирование отключено
  • SEVERE: Сообщения об ошибках. К примеру, при неизвестной команде.
  • WARNING: Предупреждения о том, что могло быть неверным, хоть ситуация и было успешно обработано. Например, перехваченное исключение.
  • INFO: Сообщения информативного характера. Например, о полученных командах.
  • DEBUG: Сообщения для дебаггинга. Например, информация о состоянии драйвера.
  • ALL: Все сообщения. Это способ получить все сообщения независимо от его уровня.

Языки программирования вроде Java или Python предоставляют свои API логгирования со своими уровнями. Интерфейс вебдрайвера Log может работать с Java LogType, как в примере ниже. Однако следует иметь в виду, что внутри webdriver API уровень логгирования языка программирования должен быть преобразован в уровень логгирования Webdriver, прежде чем отправится запрос.

Получение логов

Если тип лога поддерживается, то его можно получить через интерфейс вебдрайвера. Для получения логов удаленного нода (Selenium Grid) используется wire protocol для его передачи на сервер (hub). При сценарии, один и тот же лог запрашивается несколько раз, одни и те же записи не будут получены дважды. В целях сохранения памяти после каждого запроса о получении лога, буфер этого лога обнуляется. Таким образом, каждое сообщение лога можно получить лишь раз независимо от количества попыток.

Для получения логов в Java следует использовать Log интерфейс:

Logs logs = driver.manage().logs();
LogEntries logEntries = logs.get(LogType.DRIVER);

for (LogEntry logEntry : logEntries) {
    System.out.println(logEntry.getMessage());
}

Более подробно об этом интерфейсе можно найти на http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/logging/Logs.html

Конфигурация логгирования

Бывают ситуации, когда логгирование необходимо полностью отключить, или сделать минимальным количество сообщений. Например, в случае, когда драйвер работает на устройстве с ограниченными ресурсами. Для поддержки таких ситуаций должна быть возможность конфигурировать логгирование как отдельная настройка в вебдрайвере. Реализовано это путем передачи драйверу списка пар тип лога - уровень логгирования. В большинстве реализаций клиентской части это сделано через DesiredCapabilities класс.

Пример для Firefox:

LoggingPreferences logs = new LoggingPreferences();
logs.enable(LogType.BROWSER, Level.OFF);
logs.enable(LogType.CLIENT, Level.SEVERE);
logs.enable(LogType.DRIVER, Level.WARNING);
logs.enable(LogType.PERFORMANCE, Level.INFO);
logs.enable(LogType.SERVER, Level.ALL);

DesiredCapabilities desiredCapabilities = DesiredCapabilities.firefox();
desiredCapabilities.setCapability(CapabilityType.LOGGING_PREFS, logs);

WebDriver driver = new FirefoxDriver(desiredCapabilities);

Поведение по умолчанию - это собирать все сообщения и позволить пользователю отфильтровать их, как ему нужно. Если же для определенного типа логов было настроено другое поведение, то сообщения, более детализированного уровня, нежели установленный, не будут собираться.