FileDummy Logo
FileDummy
Testing & QA with Files

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.

October 20, 202610 min read1,420 views
playwrightcypresse2e-testingpdffile-download

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.

TypeScript
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
});
Verified Test Asset.pdf

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.

JavaScript
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 afterEach hooks to prevent test disk exhaustion.
NDL

Nguyen Dai Long

Author

Backend 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.

0/3000

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.

Related Articles