Создание скриншотов

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


Настройка окружения для скриншотов

Для работы со скриншотами необходимы:

  1. Protractor — последняя стабильная версия.
  2. Node.js — для работы с файловой системой.
  3. Модуль fs — для сохранения изображений на диск.
  4. Опционально: сторонние библиотеки для отчетов, например, Allure или Protractor-Reporter.

Простейший способ подключения встроенного модуля:

const fs = require('fs');

Это позволяет сохранять бинарные данные скриншота в файл.


Получение скриншота

Protractor использует WebDriver API. Основной метод для получения скриншота — browser.takeScreenshot(). Он возвращает промис, который разрешается в строку в формате base64.

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

browser.takeScreenshot().then((png) => {
    const stream = fs.createWriteStream('screenshot.png');
    stream.write(Buffer.from(png, 'base64'));
    stream.end();
});

Пояснения:

  • browser.takeScreenshot() — асинхронный метод, который снимает скриншот текущего состояния браузера.
  • Buffer.from(png, 'base64') — преобразует строку base64 в бинарные данные.
  • fs.createWriteStream и stream.write — сохраняют изображение на диск.

Создание функции для повторного использования

Для удобства можно обернуть процесс снятия скриншота в отдельную функцию:

function saveScreenshot(filename) {
    return browser.takeScreenshot().then((png) => {
        return new Promise((resolve, reject) => {
            const stream = fs.createWriteStream(filename);
            stream.write(Buffer.from(png, 'base64'));
            stream.end();
            stream.on('finish', resolve);
            stream.on('error', reject);
        });
    });
}

Использование функции в тесте:

it('должен сделать скриншот главной страницы', async () => {
    await browser.get('https://example.com');
    await saveScreenshot('homepage.png');
});

Такой подход облегчает интеграцию скриншотов в отчеты и повторное использование кода.


Скриншоты при ошибках

Часто требуется сохранять скриншоты автоматически при падении теста. Для этого в Protractor используют хуки Jasmine или Mocha.

Пример для Jasmine:

afterEach(async function() {
    if (this.currentTest.state === 'failed') {
        const testName = this.currentTest.fullTitle().replace(/\s+/g, '_');
        await saveScreenshot(`screenshots/${testName}.png`);
    }
});

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

  • afterEach выполняется после каждого теста.
  • this.currentTest.state проверяет статус теста.
  • Генерация имени файла через fullTitle() помогает легко идентифицировать тест.

Скриншоты элементов

Иногда требуется снимать скриншот не всей страницы, а отдельного элемента. Для этого используется метод takeScreenshot() на веб-элементе:

const elementToCapture = element(by.css('.my-element'));
elementToCapture.takeScreenshot().then((png) => {
    fs.writeFileSync('element.png', Buffer.from(png, 'base64'));
});

Важно:

  • Метод доступен начиная с WebDriver версии 4.
  • Скриншот будет содержать только видимую область элемента.

Настройка папки для скриншотов

Чтобы поддерживать порядок в проекте, обычно создают отдельную папку:

const screenshotDir = 'screenshots/';
if (!fs.existsSync(screenshotDir)) {
    fs.mkdirSync(screenshotDir);
}

Можно комбинировать с динамическими именами файлов:

const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const filename = `${screenshotDir}homepage_${timestamp}.png`;
await saveScreenshot(filename);

Это предотвращает перезапись файлов при повторных запусках тестов.


Интеграция со сторонними отчетами

  • Allure Reporter: позволяет автоматически прикреплять скриншоты к шагам теста. Для этого достаточно вызвать allure.createAttachment() и передать бинарные данные скриншота.
  • Protractor-Reporter: предоставляет собственные методы для сохранения скриншотов при падении тестов и генерации HTML-отчетов.

Советы по производительности

  1. Снимать скриншоты только при необходимости — например, при падении теста или для ключевых шагов.
  2. Уменьшать размер изображений перед сохранением для ускорения генерации отчетов.
  3. Использовать асинхронные методы записи в файл, чтобы не блокировать выполнение тестов.

Совместимость с различными браузерами

Protractor поддерживает Chrome, Firefox, Edge и другие через WebDriver. Методы browser.takeScreenshot() и element.takeScreenshot() работают во всех основных браузерах, но визуальное отображение может отличаться из-за рендеринга.


Практические примеры

Скриншот после входа в систему:

it('логин и скриншот', async () => {
    await browser.get('https://example.com/login');
    await element(by.name('username')).sendKeys('user');
    await element(by.name('password')).sendKeys('pass');
    await element(by.buttonText('Войти')).click();
    await browser.sleep(1000); // дождаться рендеринга страницы
    await saveScreenshot('screenshots/dashboard.png');
});

Скриншот элемента с проверкой текста:

it('скриншот элемента', async () => {
    const message = element(by.css('.welcome-msg'));
    expect(await message.getText()).toContain('Добро пожаловать');
    await message.takeScreenshot().then((png) => {
        fs.writeFileSync('screenshots/welcome_msg.png', Buffer.from(png, 'base64'));
    });
});

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