Testar UI-tillstånd och animationer med Playwright
Hur man skriver stabila tester för animerat användargränssnitt med Playwright: styr tiden med page.clock, emulerar reducerad rörelse och mörkt läge, och skärmdumpar med animationer inaktiverade.
Core Takeaway
Gör animationstesterna deterministiska: styr tiden med page.clock, som täcker timers, requestAnimationFrame och prestanda; emulera användarinställningar med page.emulateMedia({ reducedMotion, colorScheme }); hävda tillstånd snarare än mittanimerade pixlar; och ta skärmdumpar med animationer inaktiverade. Testa den reducerade rörelsebanan som ett förstklassigt fodral.
Varför animationstester är fläckiga
Animationer beror på tid, och realtiden varierar mellan körningar och maskiner. En skärmdump tagen 10 millisekunder tidigt eller sent visar en annan bildruta. Fixningen är att kontrollera tid och inställningar, och att testa tillstånden som animationer rör sig mellan snarare än enskilda bildrutor.
Kontrolltid
Playwright:s Clock API låter ett testinstallera en falsk klocka och sedan pausa, spola framåt eller köra tid under en viss tid. Den täcker setTimeout, setInterval, requestAnimationFrame och prestanda, så att du till exempel kan spola framåt efter en laddningsfördröjning och kontrollera att framgångsstatusen visas.
Emulera användarinställningar
page.emulateMedia() kan ställa in reducerad Motion till "reducera" och colorScheme till "mörk" eller "ljus". Kör nyckelflöden med reducerad rörelse för att bekräfta att inget viktigt beror på animering, och i båda teman för att fånga kontrastproblem.
Stabila skärmdumpar
Playwright Test kan jämföra skärmdumpar med expect(page).toHaveScreenshot(), och skärmdumpsalternativ inkluderar animationer: "disabled", vilket stoppar CSS-animationer och övergångar för fångsten. Använd visuella jämförelser för sluttillstånd och DOM- eller tillgänglighetspåståenden för beteende.
Testa canvas-baserade komponenter
Canvas-animationer, som de som ritats av Lottie, Rive eller ExodeUI körtider, är inte synliga i DOM. Testa indata som din kod skickar och händelserna den tar emot, behåll verkliga tillgängliga element vid sidan av duken och använd skärmdumpar för visuella kontroller efter att tiden har kontrollerats.
Produktionsimplementeringsutdrag
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' });
});Nyckel Principles att komma ihåg
- Styr tiden med page.clock (timers, requestAnimationFrame, prestanda)
- Emulera reducerad rörelse och färgschema med page.emulateMedia
- Påstå tillstånd och tillgänglig text, inte mittanimerade pixlar
- Skärmdump med animationer: "inaktiverad"
- Testa den reducerade rörelsebanan som ett förstklassigt fodral
Vanliga frågor
Källor
- Clock — Playwright dokument
- Page.emulateMedia and screenshot options — Playwright dokument
- Visual comparisons — Playwright dokument