Screenshots & Videos (Chụp màn hình & quay video khi chạy test)
automationplaywright
Playwright cung cấp 3 loại bằng chứng khi test chạy: screenshot (ảnh tĩnh), video (quay cả phiên) và trace (xem bài Trace Viewer). Cấu hình qua use.screenshot / use.video với các chế độ on/off/only-on-failure/retain-on-failure — chọn đúng chế độ giúp debug nhanh mà không làm phình artifact CI.
Khái niệm & Bản chất
- Screenshot: ảnh PNG chụp viewport, full page hoặc một element — chụp chủ động bằng
page.screenshot()hoặc tự động khi test fail. - Video: quay toàn bộ browser context thành file
.webm— mỗi test một context nên mỗi test một video riêng trongtest-results/. - Hai thứ này là 'bằng chứng hiện trường': screenshot trả lời 'trang trông thế nào lúc fail', video trả lời 'test đã làm gì trước khi fail'.
- Chế độ cấu hình:
screenshotnhận'on' | 'off' | 'only-on-failure';videonhận'off' | 'on' | 'retain-on-failure' | 'on-first-retry'.
Cách hoạt động & API chính
await page.screenshot({ path: 'a.png' })chụp viewport; thêmfullPage: trueđể chụp hết trang dài;await locator.screenshot()chụp riêng một element.- Config tự động:
use: { screenshot: 'only-on-failure', video: 'retain-on-failure' }— Playwright tự chụp/quay và đính vào HTML report. - Video tuỳ chỉnh kích thước:
video: { mode: 'retain-on-failure', size: { width: 1280, height: 720 } }— mặc định theo viewport. - Video chỉ được ghi ra file khi context đóng — test runner tự lo; nếu tự quản lý context phải
await context.close()mới có file. - Đừng nhầm
page.screenshot()(chụp bằng chứng debug) vớiexpect(page).toHaveScreenshot()(visual comparison / snapshot testing) — hai mục đích khác nhau.
Ví dụ & Cú pháp thực tế
- Bộ cấu hình kinh điển cho CI:
``
ts // playwright.config.ts export default defineConfig({ use: { screenshot: 'only-on-failure', // tự chụp khi fail, đính vào report video: 'retain-on-failure', // chỉ giữ video của test fail trace: 'on-first-retry', }, });`` - Chụp chủ động tại checkpoint quan trọng:
``
ts test('luồng thanh toán', async ({ page }) => { await page.goto('/cart'); // Chụp toàn trang trước khi submit await page.screenshot({ path: 'screenshots/cart-before-pay.png', fullPage: true }); // Chụp riêng nút thanh toán await page.getByRole('button', { name: 'Thanh toán' }).screenshot({ path: 'screenshots/btn-pay.png' }); await page.getByRole('button', { name: 'Thanh toán' }).click(); });`` - Lấy video path sau khi test chạy (vd để attach vào report):
``
ts test.afterEach(async ({ page }, testInfo) => { const video = page.video(); if (video && testInfo.status !== testInfo.expectedStatus) { console.log('Video lưu tại:', await video.path()); } });``
Best practices & Khi nào dùng
- Công thức CI nên nhớ:
screenshot: 'only-on-failure'+video: 'retain-on-failure'+trace: 'on-first-retry'— đủ debug, artifact nhẹ. - Chỉ để
'on'cho screenshot/video khi có yêu cầu lưu bằng chứng kiểm thử (compliance, UAT) — còn lại để mode retain cho đỡ rác. - Với test dài nhiều bước: chụp tay ở các checkpoint quan trọng (sau login, trước submit, sau thanh toán) — khi fail biết ngay kẹt ở đoạn nào.
- Đặt tên file và thư mục có ý nghĩa (
screenshots/cart-empty.png), đừng để auto-name trộn lẫn giữa các lần chạy. - Fail do timing/race condition: screenshot thường không đủ — cần video hoặc trace mới thấy được trình tự sự kiện.
Gotchas, So sánh & Lưu ý
- Video xuất ra định dạng
.webm— Windows Media Player cũ không mở được; xem trong HTML report (nhúng sẵn) hoặc Chrome/VLC là nhanh nhất. fullPage: truetrên trang lazy-load / infinite scroll: phần chưa render có thể ra ảnh trắng — scroll qua hoặc chờ nội dung load xong trước khi chụp.- Ảnh chụp lúc animation đang chạy sẽ không deterministic — nếu cần ảnh ổn định dùng
page.screenshot({ animations: 'disabled' }). locator.screenshot()tự scroll element vào view rồi mới chụp — an toàn hơn tự crop từ ảnh full page.- So sánh nhanh: screenshot = rẻ nhất nhưng ít context; video = xem được hành vi nhưng khó inspect DOM; trace = đắt nhất nhưng debug sâu nhất — đừng bật cả ba ở mode 'on' cho toàn suite.
