Восстановление после ошибок

Protractor — инструмент для энд-ту-энд тестирования Angular и не-Angular приложений на JavaScript. В процессе выполнения тестов нередко возникают ошибки, вызванные синхронизацией, нестабильностью элементов на странице или непредвиденными исключениями. Умение корректно восстанавливаться после ошибок является ключевым аспектом надежного автоматизированного тестирования.

Обработка исключений с помощью try-catch

Основной способ перехвата ошибок в Protractor — использование конструкции try-catch. Это позволяет предотвратить полное завершение теста при возникновении ошибки и реализовать стратегию восстановления.

it('должен безопасно кликнуть по кнопке', async () => {
    try {
        const button = element(by.css('.submit-btn'));
        await button.click();
    } catch (error) {
        console.error('Не удалось кликнуть по кнопке:', error.message);
        // Альтернативное действие для восстановления
        const fallbackButton = element(by.css('.alternative-btn'));
        await fallbackButton.click();
    }
});

Ключевые моменты:

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

Использование ожиданий для предотвращения ошибок

Большинство ошибок в Protractor связано с тем, что элемент ещё не готов к взаимодействию. Методы ExpectedConditions позволяют задавать условия, при которых действие будет выполняться безопасно.

const EC = protractor.ExpectedConditions;
const inputField = element(by.css('#username'));

await browser.wait(EC.visibilityOf(inputField), 5000, 'Поле username не появилось');
await inputField.sendKeys('test_user');

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

  • visibilityOf, elementToBeClickable, presenceOf — самые часто используемые условия.
  • Время ожидания следует выбирать в зависимости от скорости приложения, избегая слишком больших задержек.
  • Использование ожиданий значительно снижает количество сбоев из-за временной недоступности элементов.

Повторные попытки выполнения действий

Иногда ошибка возникает не системно, а случайно из-за временных факторов (например, загрузка страницы). В таких случаях полезно реализовать механизм повторных попыток (retry).

async function clickWithRetry(element, attempts = 3) {
    for (let i = 0; i < attempts; i++) {
        try {
            await element.click();
            return;
        } catch (err) {
            if (i === attempts - 1) throw err;
            await browser.sleep(500); // пауза перед повтором
        }
    }
}

Преимущества метода:

  • Уменьшение количества ложных сбоев тестов.
  • Возможность тонкой настройки количества попыток и интервала между ними.
  • Совместимость с асинхронными действиями и ожиданиями.

Снятие скриншотов при ошибках

Для анализа ошибок часто используется автоматическое создание скриншотов. Protractor предоставляет возможности работы с браузерными снимками.

afterEach(async function() {
    if (this.currentTest.state === 'failed') {
        const png = await browser.takeScreenshot();
        const fs = require('fs');
        fs.writeFileSync(`./screenshots/${this.currentTest.title}.png`, png, { encoding: 'base64' });
    }
});

Рекомендации:

  • Хранить скриншоты в отдельной директории с уникальными названиями.
  • Использовать их совместно с логами ошибок для полного анализа.
  • Можно интегрировать с CI/CD системами для автоматического прикрепления к отчётам.

Очистка состояния после ошибки

После возникновения ошибки важно вернуть приложение в стабильное состояние, чтобы последующие тесты не были нарушены. Основные подходы:

  • Перезагрузка страницы через browser.refresh().
  • Очистка полей ввода или сброс состояния через API.
  • Закрытие модальных окон или уведомлений, мешающих взаимодействию с элементами.
try {
    await element(by.css('.dangerous-action')).click();
} catch (err) {
    console.warn('Действие не удалось, выполняется восстановление');
    await browser.refresh();
}

Принцип: всегда предусматривать шаги по восстановлению до следующей ключевой проверки теста.

Логирование и трассировка

Логирование ошибок должно быть структурированным. Вместо простого console.log рекомендуется использовать модули вроде winston или log4js, чтобы хранить:

  • Название теста и шаг.
  • Сообщение об ошибке и стек.
  • Время возникновения и состояние браузера.

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

Рекомендации по стратегии восстановления

  1. Изолировать критические действия — каждая ключевая операция должна иметь собственную обработку ошибок.
  2. Использовать ожидания и проверки состояния перед взаимодействием с элементами.
  3. Минимизировать цепочки зависимостей между шагами теста, чтобы сбой одного действия не ломал весь сценарий.
  4. Регулярно анализировать логи и скриншоты для выявления повторяющихся проблем и их устранения.
  5. Применять повторные попытки только для временных сбоев, не маскируя реальных багов.

Эффективная обработка ошибок и восстановление после них делают тесты на Protractor стабильными и надежными, что особенно важно при работе с динамическими и сложными веб-приложениями.