Test PDF File Downloads with Playwright and Cypress
Write E2E tests for PDF and file downloads using Playwright and Cypress. Verify download completion, file size, and content type with working code examples.
Verifying file downloads in end-to-end (E2E) automation suites ensures that reporting tools, invoices, and export features work reliably across browser engines. Here is how to test file downloads using Playwright and Cypress.
Testing File Downloads in Playwright
Playwright provides first-class support for browser download events via the waitForEvent('download') API.
import { test, expect } from '@playwright/test';
import fs from 'fs';
import path from 'path';
test('Verify PDF download event and file size', async ({ page }) => {
await page.goto('https://filedummy.dev/pdf/5mb');
// Start waiting for download before clicking the trigger
const downloadPromise = page.waitForEvent('download');
await page.click('button:has-text("Download 5MB PDF")');
const download = await downloadPromise;
// Validate suggested filename
expect(download.suggestedFilename()).toBe('sample-5mb.pdf');
// Save to temporary test directory
const downloadPath = path.join('/tmp', download.suggestedFilename());
await download.saveAs(downloadPath);
// Assert file exists on disk and verify byte size
const stats = fs.statSync(downloadPath);
expect(stats.size).toBe(5 * 1024 * 1024); // 5,242,880 bytes
});
Download a standardized 5MB PDF to test Playwright download events and assertions.
Download 5MB PDF Sample →Testing File Downloads in Cypress
In Cypress, downloads triggered by the browser are automatically saved to the cypress/downloads folder.
describe('Cypress PDF Download Verification', () => {
it('downloads and verifies 5MB PDF', () => {
cy.visit('https://filedummy.dev/pdf/5mb');
cy.contains('button', 'Download 5MB PDF').click();
// Verify file exists in default download path
const filename = 'cypress/downloads/sample-5mb.pdf';
cy.readFile(filename, 'binary', { timeout: 15000 }).should((buffer) => {
expect(buffer.length).to.be.at.least(5000000);
});
});
});
Key E2E Download Testing Considerations
- Avoid headless browser download blocks: Ensure browser preferences permit automatic downloads without a system dialog.
- Timeout margins: Large file downloads need generous timeouts in CI environments where network latency varies.
- Clean up artifacts: Delete downloaded files in
afterEachhooks to prevent test disk exhaustion.
Nguyen Dai Long
AuthorBackend Lead • Distributed Systems & Cloud Edge Architecture Specialist
4+ years designing high-throughput file ingestion pipelines, database architectures, and distributed edge storage on Cloudflare R2 & AWS S3. Founder of FileDummy and the NDL Ecosystem.
Was this article helpful?
Click Like to support the author and help other developers discover this guide.
Engineering Discussion & Feedback (0)
Share benchmark results, report edge cases, or ask technical questions.
No comments yet. Be the first developer to start the discussion!
Frequently Asked Questions
How do I test file downloads in Playwright without a browser UI?â–¾
Use page.waitForEvent('download') to capture a Download object. Call download.saveAs(path) to save it locally, then verify with fs.statSync(path).size. Playwright download interception works in headless mode across Chromium, Firefox, and WebKit.
How do I test file downloads in Cypress?â–¾
Cypress does not natively intercept browser downloads. Use cy.intercept() to intercept the download URL, then fetch it with cy.request() and verify the response headers (Content-Type, Content-Disposition) and body size.
How do I verify the downloaded file is a valid PDF in an E2E test?â–¾
Read the first 4 bytes of the saved file and check for %PDF. In Node.js: const buf = fs.readFileSync(path); const isPDF = buf.slice(0, 4).toString() === '%PDF'. For deeper validation, use pdf-parse to verify the file can be parsed without errors.