How can I take screenshots and record videos during test execution?
Taking screenshots and recording videos during test execution is crucial for debugging failed tests, creating documentation, and monitoring application behavior. Playwright provides comprehensive built-in support for both screenshots and video recording with flexible configuration options.
Screenshots in Playwright
Basic Screenshot Capture
Playwright offers multiple methods to capture screenshots during test execution:
// Take a screenshot of the entire page
await page.screenshot({ path: 'screenshot.png' });
// Take a screenshot of a specific element
const element = await page.locator('.my-element');
await element.screenshot({ path: 'element-screenshot.png' });
// Take a screenshot and return as buffer
const buffer = await page.screenshot();
Screenshot Configuration Options
You can customize screenshot behavior with various options:
await page.screenshot({
path: 'full-page.png',
fullPage: true, // Capture the full scrollable page
clip: { // Capture specific area
x: 0,
y: 0,
width: 800,
height: 600
},
type: 'jpeg', // 'png' or 'jpeg'
quality: 80, // JPEG quality (0-100)
omitBackground: true, // Transparent background
animations: 'disabled' // Disable animations
});
Automatic Screenshot on Test Failure
Configure Playwright to automatically capture screenshots when tests fail:
// playwright.config.js
module.exports = {
use: {
screenshot: 'only-on-failure',
// Other options: 'off', 'on', 'only-on-failure'
},
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
screenshot: 'only-on-failure'
},
},
],
};
Screenshots in Test Code
Integrate screenshots into your test workflow:
import { test, expect } from '@playwright/test';
test('capture screenshots during test', async ({ page }) => {
await page.goto('https://example.com');
// Take screenshot before action
await page.screenshot({ path: 'before-action.png' });
// Perform action
await page.click('button[type="submit"]');
// Wait for response and take screenshot
await page.waitForSelector('.success-message');
await page.screenshot({ path: 'after-action.png' });
// Screenshot of specific element
const form = page.locator('form');
await form.screenshot({ path: 'form-element.png' });
});
Video Recording in Playwright
Enabling Video Recording
Configure video recording in your Playwright configuration:
// playwright.config.js
module.exports = {
use: {
video: 'on-first-retry',
// Options: 'off', 'on', 'retain-on-failure', 'on-first-retry'
videoSize: { width: 1280, height: 720 },
},
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
video: 'on-first-retry'
},
},
],
};
Video Recording Options
Customize video recording behavior:
module.exports = {
use: {
video: {
mode: 'on-first-retry',
size: { width: 1280, height: 720 }
},
// Video will be saved to test-results directory
},
};
Manual Video Control
Control video recording programmatically:
test('manual video recording', async ({ page }) => {
// Start recording
await page.video()?.path();
await page.goto('https://example.com');
// Perform test actions
await page.fill('input[name="email"]', 'test@example.com');
await page.click('button[type="submit"]');
// Video automatically stops when test ends
});
Python Implementation
Screenshots in Python
from playwright.sync_api import sync_playwright
def test_screenshots():
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
# Take full page screenshot
page.screenshot(path="full-page.png", full_page=True)
# Take element screenshot
element = page.locator(".my-element")
element.screenshot(path="element.png")
# Screenshot with options
page.screenshot(
path="custom-screenshot.png",
clip={"x": 0, "y": 0, "width": 800, "height": 600},
type="jpeg",
quality=90
)
browser.close()
Video Recording in Python
# pytest configuration in conftest.py
import pytest
from playwright.sync_api import sync_playwright
@pytest.fixture(scope="session")
def browser():
with sync_playwright() as p:
browser = p.chromium.launch()
yield browser
browser.close()
@pytest.fixture
def page(browser):
context = browser.new_context(
record_video_dir="videos/",
record_video_size={"width": 1280, "height": 720}
)
page = context.new_page()
yield page
context.close()
Advanced Screenshot and Video Techniques
Custom Screenshot Utilities
Create reusable screenshot utilities:
// utils/screenshot.js
export class ScreenshotHelper {
static async captureStep(page, stepName) {
const timestamp = new Date().toISOString().replace(/:/g, '-');
const filename = `${stepName}-${timestamp}.png`;
await page.screenshot({ path: `screenshots/${filename}` });
return filename;
}
static async captureComparison(page, elementSelector, testName) {
const element = page.locator(elementSelector);
await element.screenshot({
path: `screenshots/${testName}-comparison.png`,
animations: 'disabled'
});
}
}
// Usage in tests
import { ScreenshotHelper } from './utils/screenshot.js';
test('visual regression test', async ({ page }) => {
await page.goto('https://example.com');
await ScreenshotHelper.captureStep(page, 'initial-load');
await page.click('button');
await ScreenshotHelper.captureStep(page, 'after-click');
await ScreenshotHelper.captureComparison(page, '.result-panel', 'results');
});
Video Recording with Custom Paths
test('custom video path', async ({ page }) => {
const context = await page.context();
// Configure video recording
await context.tracing.start({
screenshots: true,
snapshots: true
});
await page.goto('https://example.com');
// Perform test actions
await page.fill('input[type="search"]', 'playwright');
await page.press('input[type="search"]', 'Enter');
// Stop tracing and save
await context.tracing.stop({ path: 'trace.zip' });
});
Best Practices for Screenshots and Videos
1. Organize Media Files
Structure your media files properly:
// playwright.config.js
module.exports = {
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
outputDir: 'test-results/',
// Screenshots and videos will be organized by test file
};
2. Conditional Media Capture
Only capture media when needed:
test('conditional screenshot', async ({ page }) => {
await page.goto('https://example.com');
try {
await page.waitForSelector('.expected-element', { timeout: 5000 });
} catch (error) {
// Take screenshot only on failure
await page.screenshot({ path: 'failure-screenshot.png' });
throw error;
}
});
3. Performance Considerations
Optimize media capture for performance:
// playwright.config.js
module.exports = {
use: {
// Only record video on first retry to save space
video: 'on-first-retry',
// Reduce video size for faster processing
videoSize: { width: 1024, height: 768 },
// Use JPEG for smaller file sizes
screenshot: 'only-on-failure',
},
};
Integration with CI/CD
GitHub Actions Integration
# .github/workflows/playwright.yml
name: Playwright Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Install Playwright
run: npx playwright install --with-deps
- name: Run tests
run: npx playwright test
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: |
playwright-report/
test-results/
retention-days: 30
Debugging with Screenshots and Videos
Use screenshots and videos effectively for debugging:
test('debugging with media', async ({ page }) => {
await page.goto('https://example.com');
// Take screenshot before critical action
await page.screenshot({ path: 'debug-before.png' });
// Enable video recording for this specific test
const context = page.context();
await context.tracing.start({ screenshots: true, snapshots: true });
// Perform actions that might fail
await page.click('button.submit');
// Take screenshot after action
await page.screenshot({ path: 'debug-after.png' });
// Save trace for detailed debugging
await context.tracing.stop({ path: 'debug-trace.zip' });
});
Screenshots and video recording in Playwright provide powerful debugging and documentation capabilities. By configuring these features properly and following best practices, you can significantly improve your test debugging workflow and create valuable documentation for your application's behavior. Similar to how you handle browser sessions in Puppeteer, maintaining proper media capture strategies is essential for effective test automation.
Remember to balance the need for debugging information with performance and storage considerations, especially in CI/CD environments where handling timeouts in Puppeteer becomes crucial for maintaining efficient test execution.