Testando estados de UI e animações com Playwright
Como escrever testes estáveis para UI animada com Playwright: controlando o tempo com page.clock, emulando movimento reduzido e modo escuro e capturas de tela com animações desativadas.
Ponto principal
Torne os testes de animação determinísticos: controle o tempo com page.clock, que cobre timers, requestAnimationFrame e desempenho; emular configurações do usuário com page.emulateMedia({ reduziuMotion, colorScheme }); afirmar em estados em vez de pixels no meio da animação; e faça capturas de tela com animações desativadas. Teste o caminho de movimento reduzido como um caso de primeira classe.
Por que os testes de animação são instáveis
As animações dependem do tempo e o tempo real varia entre execuções e máquinas. Uma captura de tela tirada 10 milissegundos antes ou depois mostra um quadro diferente. A solução é controlar o tempo e as configurações e testar os estados em que as animações se movem, em vez de quadros individuais.
Tempo de controle
A API Clock do Playwright permite que um teste instale um relógio falso e depois pause, avance ou execute o tempo por um período definido. Ele cobre setTimeout, setInterval, requestAnimationFrame e desempenho, para que você possa, por exemplo, avançar rapidamente após um atraso de carregamento e verificar se o estado de sucesso aparece.
Emular configurações do usuário
page.emulateMedia() pode definir reduzidoMotion como "reduzir" e colorScheme como "escuro" ou "claro". Execute fluxos principais com movimento reduzido para confirmar que nada importante depende da animação e em ambos os temas para detectar problemas de contraste.
Capturas de tela estáveis
O teste Playwright pode comparar capturas de tela com expect(page).toHaveScreenshot(), e as opções de captura de tela incluem animações: "disabled", que interrompe animações e transições CSS para a captura. Use comparações visuais para estados finais e declarações de DOM ou acessibilidade para comportamento.
Testando componentes baseados em canvas
Animações de tela, como aquelas desenhadas pelos tempos de execução Lottie, Rive ou ExodeUI, não são visíveis no DOM. Teste as entradas que seu código envia e os eventos que ele recebe, mantenha elementos reais acessíveis ao lado da tela e use capturas de tela para verificações visuais após o controle do tempo.
Trecho de implementação em produção
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' });
});Princípios-chave para lembrar
- Controle o tempo com page.clock (temporizadores, requestAnimationFrame, desempenho)
- Emule lowerMotion e colorScheme com page.emulateMedia
- Afirmar em estados e texto acessível, não em pixels no meio da animação
- Captura de tela com animações: "desativado"
- Teste o caminho de movimento reduzido como um caso de primeira classe
Perguntas frequentes
Fontes
- Clock — Documentos Playwright
- Page.emulateMedia and screenshot options — Documentos Playwright
- Visual comparisons — Documentos Playwright