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

Для создания скриншотов в Protractor используется встроенный интерфейс WebDriver и модуль fs для работы с файловой системой. Важно убедиться, что проект настроен корректно: установлен Protractor, настроен protractor.conf.js и подключены необходимые модули Node.js.

Пример подключения модулей:

const fs = require('fs');
const path = require('path');

Скриншоты можно сохранять в любую папку проекта, но рекомендуется создать отдельную директорию, например screenshots, для удобной организации файлов.

const screenshotPath = path.join(__dirname, 'screenshots');
if (!fs.existsSync(screenshotPath)) {
    fs.mkdirSync(screenshotPath);
}

Основы создания скриншотов

В Protractor для получения скриншота используется метод browser.takeScreenshot(). Этот метод возвращает Promise, который разрешается в строку формата Base64.

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

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

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

  • takeScreenshot() всегда возвращает Base64, поэтому важно конвертировать его в бинарный формат перед записью на диск.
  • Название файла можно формировать динамически, чтобы избежать перезаписи:
const fileName = `screenshot_${new Date().getTime()}.png`;

Скриншоты на разных этапах теста

Часто требуется делать скриншоты в конкретных точках сценария, например после логина, перед проверкой критического элемента или при падении теста. В Protractor это реализуется через цепочку промисов или async/await.

Пример с async/await:

it('должен сделать скриншот после входа в систему', async () => {
    await browser.get('https://example.com/login');
    await element(by.id('username')).sendKeys('testuser');
    await element(by.id('password')).sendKeys('password');
    await element(by.id('loginButton')).click();

    const png = await browser.takeScreenshot();
    fs.writeFileSync(path.join(screenshotPath, 'after_login.png'), Buffer.from(png, 'base64'));
});

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

Реализовать автоматическую съемку скриншота при падении теста можно через хуки afterEach в Jasmine или Mocha.

Пример для Jasmine:

afterEach(async function() {
    if (this.currentTest && this.currentTest.failedExpectations.length > 0) {
        const png = await browser.takeScreenshot();
        const fileName = `error_${new Date().getTime()}.png`;
        fs.writeFileSync(path.join(screenshotPath, fileName), Buffer.from(png, 'base64'));
    }
});

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

  • this.currentTest.failedExpectations содержит список всех ошибок, произошедших в тесте.
  • Формирование уникального имени файла предотвращает потерю предыдущих скриншотов.

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

Иногда нужно зафиксировать только определенный элемент на странице, а не весь экран. В этом случае применяется метод takeScreenshot() у элемента.

const elementToCapture = element(by.css('.important-section'));
const png = await elementToCapture.takeScreenshot();
fs.writeFileSync(path.join(screenshotPath, 'element_screenshot.png'), Buffer.from(png, 'base64'));

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

  • Снижает размер файлов.
  • Упрощает анализ проблем, сосредотачиваясь на конкретном элементе.
  • Позволяет интегрировать скриншоты в отчеты тестирования, показывая только релевантные части интерфейса.

Настройка формата и качества

Метод takeScreenshot() всегда возвращает PNG. Для других форматов, таких как JPEG, требуется дополнительная конвертация с помощью сторонних библиотек, например sharp или jimp.

Пример конвертации PNG в JPEG с sharp:

const sharp = require('sharp');

const pngBuffer = Buffer.from(await browser.takeScreenshot(), 'base64');
await sharp(pngBuffer)
    .jpeg({ quality: 80 })
    .toFile(path.join(screenshotPath, 'screenshot.jpg'));

Организация и хранение скриншотов

Рекомендуется использовать структуру директорий по тестовым сценариям или датам, чтобы легко находить нужные файлы. Пример структуры:

/screenshots
    /login
        after_login.png
        error_167812345.png
    /dashboard
        overview.png
        error_167812346.png

Дополнительно можно сохранять в JSON-файл метаданные: URL страницы, имя теста, время создания скриншота, что помогает при автоматическом анализе результатов.

const metadata = {
    testName: 'login test',
    url: await browser.getCurrentUrl(),
    timestamp: new Date().toISOString()
};
fs.writeFileSync(path.join(screenshotPath, 'metadata.json'), JSON.stringify(metadata, null, 2));

Практические рекомендации

  • Всегда использовать уникальные имена файлов.
  • Сохранять скриншоты при падениях тестов и на ключевых этапах.
  • Организовывать структуру директорий для упрощения поиска.
  • Для больших проектов интегрировать скриншоты в отчеты, например с помощью allure-reporter или protractor-beautiful-reporter.
  • При необходимости уменьшать размер изображений через конвертацию, чтобы не перегружать систему хранения.

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