การทดสอบสถานะ UI และภาพเคลื่อนไหวด้วย Playwright
วิธีเขียนการทดสอบที่เสถียรสำหรับ UI แบบเคลื่อนไหวด้วย Playwright: การควบคุมเวลาด้วย page.clock, จำลองการเคลื่อนไหวที่ลดลงและโหมดมืด และภาพหน้าจอที่ปิดใช้งานภาพเคลื่อนไหว
หลัก Takeaway
ทำการทดสอบแอนิเมชั่นตามที่กำหนด: ควบคุมเวลาด้วย page.clock ซึ่งครอบคลุมตัวจับเวลา, requestAnimationFrame และประสิทธิภาพ จำลองการตั้งค่าผู้ใช้ด้วย page.emulateMedia({ ลดการเคลื่อนไหว, colorScheme }); ยืนยันสถานะมากกว่าพิกเซลแอนิเมชั่นกลาง และถ่ายภาพหน้าจอโดยปิดใช้งานภาพเคลื่อนไหว ทดสอบเส้นทางการลดการเคลื่อนไหวเป็นกรณีชั้นหนึ่ง
เหตุใดการทดสอบแอนิเมชั่นจึงไม่สม่ำเสมอ
แอนิเมชันขึ้นอยู่กับเวลา และเรียลไทม์จะแตกต่างกันไประหว่างการวิ่งและเครื่องจักร ภาพหน้าจอที่ถ่ายเร็วหรือช้า 10 มิลลิวินาทีจะแสดงเฟรมที่แตกต่างกัน การแก้ไขคือการควบคุมเวลาและการตั้งค่า และเพื่อทดสอบสถานะการเคลื่อนไหวระหว่างแต่ละเฟรม
การควบคุมเวลา
Clock API ของ Playwright ช่วยให้การทดสอบติดตั้งนาฬิกาปลอม จากนั้นหยุดชั่วคราว กรอไปข้างหน้า หรือรันไทม์ตามระยะเวลาที่กำหนด โดยครอบคลุมถึง setTimeout, setInterval, requestAnimationFrame และประสิทธิภาพ ดังนั้นคุณจึงสามารถยกตัวอย่างการกรอไปข้างหน้าผ่านความล่าช้าในการโหลดและตรวจสอบสถานะความสำเร็จที่ปรากฏขึ้น
จำลองการตั้งค่าของผู้ใช้
page.emulateMedia() สามารถตั้งค่าลดการเคลื่อนไหวเป็น "ลด" และ colorScheme เป็น "มืด" หรือ "สว่าง" เรียกใช้โฟลว์คีย์โดยเปิดการเคลื่อนไหวที่ลดลงเพื่อยืนยันว่าไม่มีอะไรสำคัญขึ้นอยู่กับภาพเคลื่อนไหว และในทั้งสองธีมเพื่อตรวจจับปัญหาคอนทราสต์
ภาพหน้าจอที่เสถียร
การทดสอบ Playwright สามารถเปรียบเทียบภาพหน้าจอกับ Expect(page).toHaveScreenshot() และตัวเลือกภาพหน้าจอจะมีภาพเคลื่อนไหว: "disabled" ซึ่งจะหยุดภาพเคลื่อนไหวและการเปลี่ยนภาพ 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' });
});คีย์ Principles ที่ต้องจำ
- ควบคุมเวลาด้วย page.clock (ตัวจับเวลา, requestAnimationFrame, ประสิทธิภาพ)
- จำลอง RedMotion และ ColorScheme ด้วย page.emulateMedia
- ยืนยันสถานะและข้อความที่เข้าถึงได้ ไม่ใช่พิกเซลภาพเคลื่อนไหวในช่วงกลาง
- ภาพหน้าจอพร้อมภาพเคลื่อนไหว: "ปิดการใช้งาน"
- ทดสอบเส้นทางการลดการเคลื่อนไหวเป็นกรณีชั้นหนึ่ง
คำถามที่พบบ่อย
แหล่งที่มา
- Clock — เอกสาร Playwright
- Page.emulateMedia and screenshot options — เอกสาร Playwright
- Visual comparisons — เอกสาร Playwright