How to Verify File Downloads in Playwright (The Right Way)

Day 2: File Download Verification in Playwright — Beyond Just Clicking a Link



#30DaysOfPlaywrightAutomation

One of the most overlooked areas in test automation is file download validation.

When we see a "Download Report" button, we often write a simple .click() and move on.
But let’s be honest:

Just clicking the button doesn’t mean the file actually downloaded.

In this post, I’ll show you how to properly verify file downloads using Playwright — including saving them to disk and checking their contents.


🚫 Why .click() Isn't Enough

Using .click() might trigger the download UI, but it doesn’t verify the file:

  • Did the file actually download?
  • Was it saved properly?
  • Does it have the correct name or content?

This becomes even more important in:

  • Invoice generators
  • Export buttons in dashboards
  • Financial statements
  • PDF or CSV exports


✅ The Right Way: page.waitForEvent('download')

Playwright provides a powerful way to wait for and handle downloads:

const [download] = await Promise.all([
  page.waitForEvent('download'),
  page.click('text=Download Report'),
]);

const path = await download.path();
console.log('Downloaded file path:', path);

🔍 What’s happening here?

  • waitForEvent('download') listens for any file download event
  • You wrap it in a Promise.all with the trigger action (like .click())
  • Once Playwright detects the file, you can access the file path

This gives you 100% confidence that the file download happened and was captured.


📁 Bonus: Save the File to a Specific Path

Want to save the file to a custom folder for future validation or post-processing?

Use the saveAs() method:

await download.saveAs('downloads/monthly_report.pdf');

You can even integrate this with your test framework to:

  • Compare file names
  • Check extensions
  • Parse CSV/JSON contents for assertions


💡 Pro Tip: Content Validation

If you’re downloading CSV, JSON, or TXT files, you can even:

  • Read the contents using Node.js fs module
  • Assert expected headers or data rows
  • Validate file integrity (e.g., MD5 hash check for sensitive docs)

This turns your test from just functional to fully end-to-end.


✅ Real-World Example

Let’s say you're testing a dashboard with a “Download Sales Report” button. The goal is to:

  • Click the button
  • Wait for the file to download
  • Verify that the filename is sales-report-2025.pdf

Here’s how:

const [download] = await Promise.all([
  page.waitForEvent('download'),
  page.click('text=Download Sales Report'),
]);

const suggestedFilename = download.suggestedFilename();
expect(suggestedFilename).toBe('sales-report-2025.pdf');

Final Thoughts

In automation, it’s not enough to simulate the user action.
You need to validate the outcome.

Verifying file downloads gives your tests an extra layer of confidence and accuracy, especially in enterprise or data-heavy apps.

In Day 3, we’ll explore mocking API responses in Playwright — so your tests can be faster and more stable, even when the backend is unreliable.


🔁 Stay Connected

📲 Follow @thebughacker on Instagram
💬 Tag your progress with #30DaysOfPlaywrightAutomation
🧠 Let’s keep building smarter tests, one day at a time.

Previous Post Next Post

Contact Form