Тестирование состояний пользовательского интерфейса и анимации с помощью Playwright
Как написать стабильные тесты для анимированного пользовательского интерфейса с помощью Playwright: управление временем с помощью page.clear, эмуляция замедленного движения и темного режима, а также снимки экрана с отключенной анимацией.
Главное
Сделайте тесты анимации детерминированными: управляйте временем с помощью page.lock, который охватывает таймеры, requestAnimationFrame и производительность; эмулировать пользовательские настройки с помощью page.emulateMedia({ ReducedMotion, colorScheme }); утверждать состояния, а не пиксели в середине анимации; и делать снимки экрана с отключенной анимацией. Проверьте путь с уменьшенным движением как первоклассный случай.
Почему тесты анимации не работают
Анимация зависит от времени, а реальное время варьируется в зависимости от прогона и машины. Скриншот, сделанный на 10 миллисекунд раньше или позже, показывает другой кадр. Исправление состоит в том, чтобы контролировать время и настройки, а также проверять анимацию состояний, перемещающихся между отдельными кадрами, а не между отдельными кадрами.
Контрольное время
API часов Playwright позволяет тесту установить поддельные часы, а затем приостановить, перемотать вперед или запустить время на заданную продолжительность. Он охватывает setTimeout, setInterval, requestAnimationFrame и производительность, поэтому вы можете, например, перемотать вперед задержку загрузки и проверить, появляется ли состояние успеха.
Эмулировать пользовательские настройки
page.emulateMedia() может установить для значения «уменьшить» для функции «уменьшение» и для параметра colorScheme значение «темный» или «светлый». Запустите ключевые потоки с уменьшенным движением, чтобы убедиться, что от анимации не зависит ничего важного, и в обеих темах, чтобы выявить проблемы с контрастом.
Стабильные скриншоты
Playwright Test может сравнивать снимки экрана с помощью функции define(page).toHaveScreenshot(), а параметры снимков экрана включают анимацию: «отключено», что останавливает анимацию и переходы CSS для захвата. Используйте визуальные сравнения для конечных состояний и DOM или утверждения доступности для поведения.
Тестирование компонентов на основе холста
Анимации холста, например, нарисованные средами выполнения Lottie, Rive или ExodeUI, не отображаются в DOM. Тестируйте входные данные, которые отправляет ваш код, и события, которые он получает, сохраняйте реальные доступные элементы рядом с холстом и используйте снимки экрана для визуальных проверок после контроля времени.
Пример реализации для продакшена
import { test, expect } from '@playwright/test';
test('save button shows success, also with reduced motion', async ({ page }) => {
await page.clock.install(); // fake timers + rAF
await page.emulateMedia({ reducedMotion: 'reduce' }); // test the calm path
await page.goto('/settings');
await page.getByRole('button', { name: 'Save' }).click();
await expect(page.getByRole('status')).toHaveText('Saving…');
await page.clock.runFor(2000); // skip the wait deterministically
await expect(page.getByRole('status')).toHaveText('Saved');
await expect(page).toHaveScreenshot('saved.png', { animations: 'disabled' });
});Ключевые принципы
- Управляйте временем с помощью page.lock (таймеры, requestAnimationFrame, производительность)
- Эмулируйте ReducedMotion и ColorScheme с помощью page.emulateMedia.
- Утверждайте состояния и доступный текст, а не пиксели в середине анимации.
- Скриншот с анимацией: «отключено»
- Испытайте путь с уменьшенным движением как первоклассный случай
Частые вопросы
Источники
- Clock — Документация Playwright
- Page.emulateMedia and screenshot options — Документация Playwright
- Visual comparisons — Документация Playwright