Answer
Scenario: Verify Downloaded File Content
Test: Download and Verify CSV Report
TypeScript
import { test, expect } from '@playwright/test';
import path from 'path';
import fs from 'fs';
test('download CSV and verify content', async ({ page }) => {
await page.goto('/reports');
// Select report options
await page.getByLabel('Report Type').selectOption('sales');
await page.getByLabel('Date Range').selectOption('last-30-days');
// Trigger download and capture it
const downloadPromise = page.waitForEvent('download');
await page.getByRole('button', { name: 'Export CSV' }).click();
const download = await downloadPromise;
// Verify download metadata
expect(download.suggestedFilename()).toMatch(/sales-report.*\.csv/);
// Save to a known path
const downloadPath = path.join('test-downloads', download.suggestedFilename());
await download.saveAs(downloadPath);
// Verify file exists
expect(fs.existsSync(downloadPath)).toBe(true);
// Verify file size (non-empty)
const stats = fs.statSync(downloadPath);
expect(stats.size).toBeGreaterThan(0);
// Read and verify CSV content
const content = fs.readFileSync(downloadPath, 'utf-8');
const lines = content.trim().split('\n');
// Check headers
expect(lines[0]).toContain('Date');
expect(lines[0]).toContain('Product');
expect(lines[0]).toContain('Amount');
// Check data rows exist
expect(lines.length).toBeGreaterThan(1);
// Verify specific data
const dataRows = lines.slice(1);
const total = dataRows
.map(row => parseFloat(row.split(',')[2] || '0'))
.reduce((sum, val) => sum + val, 0);
expect(total).toBeGreaterThan(0);
// Cleanup
fs.unlinkSync(downloadPath);
});
Test: Download and Verify PDF (Binary Check)
TypeScript
test('verify PDF download', async ({ page }) => {
await page.goto('/invoices/123');
const downloadPromise = page.waitForEvent('download');
await page.getByRole('button', { name: 'Download PDF' }).click();
const download = await downloadPromise;
// Verify it's a PDF by reading the magic bytes
const filePath = await download.path();
expect(filePath).toBeTruthy();
const buffer = fs.readFileSync(filePath!);
// PDF files start with "%PDF"
const magic = buffer.slice(0, 4).toString('ascii');
expect(magic).toBe('%PDF');
// Optionally check file size is reasonable
expect(buffer.length).toBeGreaterThan(1000); // At least 1KB
// For text content verification, use a PDF parser
// npm install pdf-parse
// const pdf = await pdfParse(buffer);
// expect(pdf.text).toContain('Invoice #123');
// expect(pdf.text).toContain('Total: $999.00');
});
Test: Verify Excel File
TypeScript
import * as XLSX from 'xlsx'; // npm install xlsx
test('verify Excel report download', async ({ page }) => {
await page.goto('/reports/export');
const [download] = await Promise.all([
page.waitForEvent('download'),
page.getByRole('button', { name: 'Export Excel' }).click(),
]);
const savePath = `test-downloads/${download.suggestedFilename()}`;
await download.saveAs(savePath);
// Parse Excel
const workbook = XLSX.readFile(savePath);
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const data = XLSX.utils.sheet_to_json(sheet);
expect(data.length).toBeGreaterThan(0);
expect(data[0]).toHaveProperty('Name');
expect(data[0]).toHaveProperty('Email');
});
Setup Test Downloads Directory
TypeScript
// playwright.config.ts
export default defineConfig({
use: {
acceptDownloads: true, // Default: true
},
});
TypeScript
// In test beforeAll
test.beforeAll(() => {
if (!fs.existsSync('test-downloads')) {
fs.mkdirSync('test-downloads', { recursive: true });
}
});
test.afterAll(() => {
// Clean up downloads directory
fs.rmSync('test-downloads', { recursive: true, force: true });
});
