Логирование взаимодействий с браузером

Логирование является неотъемлемой частью автоматизированного тестирования, позволяя отслеживать поведение тестов, выявлять ошибки и понимать последовательность действий, выполненных в браузере. В Protractor логирование можно разделить на несколько ключевых аспектов: базовое логирование действий, использование встроенных возможностей WebDriver, настройка логов браузера и интеграция с внешними логирующими библиотеками.


1. Основы логирования в Protractor

В Protractor существует несколько способов ведения логов:

  1. Консольное логирование через console.log Это самый простой метод, который подходит для быстрых проверок:

    it('должен открыть страницу и проверить заголовок', async () => {
        await browser.get('https://example.com');
        console.log('Страница открыта');
        const title = await browser.getTitle();
        console.log('Заголовок страницы:', title);
    });

    Этот подход подходит для отладки, но не обеспечивает структурированного хранения данных и гибкой фильтрации.

  2. Использование browser.manage().logs() Protractor, будучи надстройкой над WebDriverJS, позволяет получать логи браузера, драйвера и клиента WebDriver. Пример получения браузерных логов:

    it('должен получить логи браузера', async () => {
        await browser.get('https://example.com');
        const logs = await browser.manage().logs().get('browser');
        logs.forEach(log => console.log(`[${log.level.name}] ${log.message}`));
    });

    Типы логов, которые можно использовать:

    • 'browser' — логи браузера (ошибки JS, предупреждения)
    • 'driver' — логи WebDriver
    • 'client' — логи клиентской части WebDriverJS
    • 'performance' — логи производительности (для Chrome)

2. Логирование действий пользователя

Protractor поддерживает асинхронные действия с элементами страницы. Для полной трассировки тестов полезно логировать каждое взаимодействие:

async function clickElement(locator, description) {
    const elementToClick = element(locator);
    console.log(`Попытка кликнуть по элементу: ${description}`);
    await elementToClick.click();
    console.log(`Элемент "${description}" успешно кликнут`);
}

it('должен выполнить клик по кнопке', async () => {
    await browser.get('https://example.com');
    await clickElement(by.css('.submit-button'), 'Кнопка отправки формы');
});

Преимущества такого подхода:

  • Возможность точно определить, на каком шаге теста произошла ошибка.
  • Простота интеграции с внешними системами логирования.

3. Настройка логирования в конфигурации Protractor

В файле protractor.conf.js можно настроить уровень логирования WebDriver и Protractor:

exports.config = {
    framework: 'jasmine',
    seleniumAddress: 'http://localhost:4444/wd/hub',
    specs: ['spec.js'],
    capabilities: {
        browserName: 'chrome',
        loggingPrefs: {
            browser: 'ALL', // все логи браузера
            driver: 'INFO', // уровень логов драйвера
            performance: 'OFF'
        }
    },
    onPrepare: () => {
        browser.manage().window().maximize();
    }
};

Особенности loggingPrefs:

  • Позволяет фильтровать логи по уровню важности: ALL, DEBUG, INFO, WARNING, SEVERE, OFF.
  • Работает только для поддерживаемых браузеров (Chrome, Firefox с определёнными настройками).

4. Интеграция с внешними библиотеками

Для больших проектов консольного логирования недостаточно. Используются библиотеки типа winston или log4js, которые позволяют:

  • Настраивать ротацию логов и хранение файлов.
  • Создавать структурированные логи в формате JSON.
  • Легко интегрироваться с системами мониторинга (ELK, Splunk).

Пример использования winston:

const winston = require('winston');

const logger = winston.createLogger({
    level: 'info',
    format: winston.format.combine(
        winston.format.timestamp(),
        winston.format.printf(({ timestamp, level, message }) => `${timestamp} [${level}] ${message}`)
    ),
    transports: [
        new winston.transports.Console(),
        new winston.transports.File({ filename: 'test.log' })
    ]
});

it('должен логировать действия через winston', async () => {
    await browser.get('https://example.com');
    logger.info('Страница открыта');
    const title = await browser.getTitle();
    logger.info(`Заголовок страницы: ${title}`);
});

5. Асинхронное логирование и обработка ошибок

При работе с Protractor важно логировать ошибки с асинхронными действиями. Для этого используется конструкция try/catch:

it('должен обработать ошибку при клике', async () => {
    try {
        await element(by.css('.nonexistent')).click();
    } catch (err) {
        console.error('Ошибка при клике по элементу:', err.message);
        throw err; // проброс ошибки для корректного завершения теста
    }
});

Зачем это нужно:

  • Исключает “тихие” сбои тестов.
  • Позволяет сохранить подробный лог ошибок, включая стек вызовов.

6. Логирование производительности

Protractor позволяет собирать логи производительности через performance:

it('должен собрать логи производительности', async () => {
    await browser.get('https://example.com');
    const perfLogs = await browser.manage().logs().get('performance');
    perfLogs.forEach(log => console.log(log.message));
});

Эти данные полезны для анализа времени загрузки страниц, откликов AJAX-запросов и поведения SPA-приложений.


7. Советы по организации логирования

  • Разделять логи по типам: действия пользователя, ошибки, браузерные сообщения, производительность.
  • Использовать внешние библиотеки для крупных проектов.
  • Логи должны быть читаемыми, с метками времени и описанием действия.
  • При интеграции CI/CD сохранять логи в артефактах сборки для последующего анализа.

Логирование в Protractor — это мощный инструмент для повышения прозрачности тестов и быстрого выявления проблем, особенно в сложных проектах с множеством взаимодействий и асинхронных операций.