Intercept and verify a download
The pattern is the same as waitForResponse — set up the promise BEFORE the click, then await it after. If you click first and then call waitForEvent('download'), the download event may fire before you start listening and you'll miss it.
The Download object gives you the filename, a path to the temp file, and methods to save it or read its content.
test('export orders as CSV', async ({ page }) => {
await page.goto('/orders')
// Встановлюємо очікування ДО кліку
const downloadPromise = page.waitForEvent('download')
await page.getByRole('button', { name: 'Export CSV' }).click()
// Чекаємо завантаження
const download = await downloadPromise
// Перевіряємо ім'я файлу
expect(download.suggestedFilename()).toMatch(/orders-d{4}-d{2}-d{2}.csv/)
// Зберегти куди треба
await download.saveAs('/tmp/test-export.csv')
})
Read the downloaded file content
After intercepting the download, you can read the file content to assert on what's actually inside. download.path() returns the path to the temp file Playwright saved. Then use Node.js fs to read it.
import fs from 'fs'
test('exported CSV contains correct order data', async ({ page }) => {
await page.goto('/orders')
// Фільтруємо по статусу перед експортом
await page.getByRole('combobox', { name: 'Status' }).selectOption('pending')
const downloadPromise = page.waitForEvent('download')
await page.getByRole('button', { name: 'Export CSV' }).click()
const download = await downloadPromise
// Читаємо вміст
const filePath = await download.path()
const content = fs.readFileSync(filePath!, 'utf-8')
// Перевіряємо структуру CSV
const lines = content.split('\n')
expect(lines[0]).toContain('Order ID,Customer,Status,Total')
// Всі рядки мають статус pending
for (const line of lines.slice(1).filter(Boolean)) {
expect(line).toContain('pending')
}
})
Handle multiple downloads
If one action triggers multiple downloads (a zip archive plus a manifest, for example), or if downloads happen at unpredictable moments, use the event listener pattern instead of waitForEvent.
test('bulk export downloads all files', async ({ page }) => {
await page.goto('/reports')
const downloads: string[] = []
page.on('download', async download => {
downloads.push(download.suggestedFilename())
})
await page.getByRole('button', { name: 'Export all reports' }).click()
// Чекаємо поки завантаження завершаться
await expect.poll(() => downloads.length, { timeout: 10000 }).toBe(3)
expect(downloads).toContain('orders.csv')
expect(downloads).toContain('customers.csv')
expect(downloads).toContain('summary.pdf')
})