Визуальное тестирование компонентов с использованием Playwright позволяет автоматизировать проверку корректности отображения UI-элементов в приложении. В отличие от функциональных тестов, где проверяется поведение системы, визуальные тесты фокусируются на том, как элементы интерфейса выглядят на экране.
Визуальные тесты необходимы для предотвращения непреднамеренных изменений в дизайне, которые могут возникнуть после внесения изменений в код. Это включает в себя проверку таких аспектов, как цвета, шрифты, размеры элементов, выравнивание и расположение.
Визуальные тесты можно разделить на два типа:
В Playwright визуальные тесты можно интегрировать с различными библиотеками для захвата и сравнения скриншотов. Одна из популярных библиотек для таких целей – playwright-visual-regression.
Для начала необходимо установить зависимости для Playwright и библиотеки для визуального тестирования:
npm install @playwright/test playwright-visual-regression
Кроме этого, понадобится настройка проекта для работы с тестами:
import { test, expect } from '@playwright/test';
import { visualRegressionTest } from 'playwright-visual-regression';
После установки можно создать базовый тест, который будет делать скриншоты веб-страниц и сравнивать их с эталонными изображениями.
Основной принцип заключается в захвате скриншота с интерфейсом и его сравнении с заранее подготовленным эталонным изображением.
test('Check visual appearance of the button', async ({ page }) => {
// Открытие страницы
await page.goto('https://example.com');
// Найти элемент кнопки
const button = await page.locator('button#submit');
// Сравнение скриншота элемента
await expect(button).toHaveScreenshot();
});
Здесь toHaveScreenshot автоматически делает снимок
экрана элемента и сравнивает его с эталонным. Если изображения
отличаются, тест будет считаться неуспешным.
Для более гибкой настройки можно указать опции для сравнения изображений, такие как порог отклонения или использование разных методов для нахождения различий.
test('Check visual appearance with custom tolerance', async ({ page }) => {
const button = await page.locator('button#submit');
await expect(button).toHaveScreenshot({
maxDiffPixels: 50, // Максимальное количество пикселей, которые могут отличаться
threshold: 0.1, // Порог, на котором тест считается пройденным
});
});
Опция maxDiffPixels позволяет контролировать
максимальное количество пикселей, которые могут быть различными на
изображениях. Параметр threshold задает порог отклонений
для сравнения, указывая, какой процент изображения может быть
различен.
Playwright позволяет детально настраивать скриншоты с помощью следующих параметров:
await page.screenshot({ path: 'screenshot.png', fullPage: true });
await page.screenshot({
path: 'element.png',
clip: { x: 0, y: 0, width: 200, height: 100 }
});
Если на странице имеется динамический контент, такой как анимации или элементы, которые подгружаются асинхронно, важно обеспечить, чтобы тесты не делали скриншоты до того, как элементы полностью загрузятся. Для этого можно использовать методы ожидания.
test('Check visual appearance of dynamically loaded content', async ({ page }) => {
await page.goto('https://example.com');
// Ожидание, пока элемент станет видимым
const element = await page.locator('.dynamic-content');
await element.waitFor({ state: 'visible' });
// Сравнение скриншота
await expect(element).toHaveScreenshot();
});
Такой подход гарантирует, что скриншот будет сделан только после полной загрузки всех динамических элементов.
При тестировании компонентных библиотек или UI-компонентов важно, чтобы тесты охватывали различные состояния компонентов. Например, можно проверять внешний вид кнопок в разных состояниях (нормальное, наведенное, отключенное).
test('Check button appearance in different states', async ({ page }) => {
await page.goto('https://example.com');
// Нормальное состояние
const button = await page.locator('button#submit');
await expect(button).toHaveScreenshot('button-normal.png');
// Наведенное состояние
await button.hover();
await expect(button).toHaveScreenshot('button-hovered.png');
// Отключенное состояние
await button.setAttribute('disabled', 'true');
await expect(button).toHaveScreenshot('button-disabled.png');
});
Каждое состояние компонента проверяется с помощью отдельного скриншота, что позволяет убедиться в корректности внешнего вида на всех этапах взаимодействия пользователя с интерфейсом.
Для автоматизации визуального тестирования в процессе разработки и деплоя важно интегрировать их в процесс CI/CD. Это позволит автоматически запускать визуальные тесты при каждом изменении кода, выявляя неожиданные изменения в интерфейсе.
Для этого необходимо добавить в конфигурацию CI/CD систему, которая будет запускать тесты с Playwright. Например, для GitHub Actions можно создать следующий workflow:
name: Playwright Visual Tests
on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run tests
run: npx playwright test
Этот workflow будет запускать тесты каждый раз при изменении ветки
main в репозитории, обеспечивая быструю обратную связь и
предотвращая внедрение дефектов в визуальное оформление.
Одним из важных аспектов визуальных тестов является работа с изменениями в дизайне. Если изменения в интерфейсе были запланированы, необходимо обновить эталонные скриншоты, чтобы тесты не фейлились из-за обновлений.
Для этого можно использовать команду для обновления эталонных изображений:
npx playwright test --update-snapshots
Этот процесс позволяет поддерживать актуальные эталонные изображения и предотвращает ложные срабатывания тестов.
Использование Playwright для визуального тестирования компонентов помогает разработчикам гарантировать, что внешний вид интерфейса останется неизменным даже при внесении изменений в код. Автоматизация этого процесса обеспечивает быстрый фидбек и высокое качество продукта. Важно правильно настроить тесты, чтобы они покрывали все состояния компонентов и позволяли легко адаптировать скриншоты при необходимости.