</>

Technology

Playwright

Difficulty

Intermediate

Interview Question

How would you verify that a file was downloaded and contains specific content in Playwright?

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 });
});

Follow AutomateQA

Related Topics