⚡ Playwright Download Debugging Nightmare? Stop guessing & master robust file verification.
How do you programmatically handle and verify file downloads with Playwright in a robust, cross-platform manner?
📌 Problem Statement
Automating file downloads is notoriously tricky. Asynchronous events, temporary file locations, and content verification across diverse operating systems often lead to flaky end-to-end tests. A reliable, cross-platform strategy is essential for accurate test outcomes.
💡 Solution & Code Walkthrough
Playwright's page.waitForEvent('download') is key to mastering downloads. This robust approach ensures you capture, save, and validate files reliably.
✅ Anticipate: Start listening for the download event before triggering the download action.
✅ Trigger: Perform the UI action (e.g., click a link) that initiates the file download.
✅ Save: Use download.saveAs() to move the file from Playwright's temporary directory to a controlled, accessible local path.
✅ Verify: Assert file existence, its name, and crucially, its content using Node.js's fs module.
✅ Clean Up: Remove the downloaded file post-verification to maintain a clean test environment.
import { test, expect } from '@playwright/test';
import * as fs from 'fs';
import * as path from 'path';
test('verify file download content & cleanup', async ({ page }) => {
await page.goto('https://the-internet.herokuapp.com/download'); // Example download page URL
const downloadPath = path.join(__dirname, 'downloaded_file.txt');
// 1. Anticipate download event before trigger
const [download] = await Promise.all([
page.waitForEvent('download'),
page.click('text="some-file.txt"') // 2. Trigger download by clicking the link
]);
// 3. Save the downloaded file to a specific path
await download.saveAs(downloadPath);
// 4. Verify file properties & content
expect(fs.existsSync(downloadPath)).toBeTruthy();
expect(download.suggestedFilename()).toBe('some-file.txt');
const fileContent = fs.readFileSync(downloadPath, 'utf-8');
expect(fileContent).toContain('This is the content of the file.');
// 5. Clean up: Remove file after verification
fs.unlinkSync(downloadPath);
expect(fs.existsSync(downloadPath)).toBeFalsy();
});
🔑 Key Takeaways
• Always use page.waitForEvent('download') before the action.
• Explicitly download.saveAs() for full control over the file's location.
• Leverage Node.js fs module for deep verification (existence, name, content).
• Implement fs.unlinkSync() for robust post-test cleanup.
❓ Quick Summary Q&A
Q: Why waitForEvent first?
A: Downloads happen fast; waitForEvent ensures Playwright is listening before the action initiates it, preventing race conditions.
Q: How do I verify file content?
A: Use fs.readFileSync(filePath, 'utf-8') to read content, then expect().toContain() for verification.
Q: Is download.saveAs() mandatory?
A: Yes, if you need to access, verify, or persist the file beyond Playwright's temporary handling.
TAGS: playwright, typescript, testing, automation, e2e, filedownload
────────────────────────────────────────
🚀 Elevate your testing skills. Download our app!
App Store: ────────────────────────────────────────
📲 𝐅𝐑𝐄𝐄 𝐌𝐎𝐁𝐈𝐋𝐄 𝐀𝐏𝐏 — 𝟔𝟎𝟎+ 𝐒𝐃𝐄𝐓 𝐐&𝐀𝐬
Practice real-world interview scenarios offline on the free QA Automation & SDET Prep app:
🤖 𝐆𝐨𝐨𝐠𝐥𝐞 𝐏𝐥𝐚𝐲 (𝐀𝐧𝐝𝐫𝐨𝐢𝐝):
https://play.google.com/store/apps/details?id=com.app.seleniuminterviewquestions&referrer=utm_source%3Ddevto%26utm_medium%3Darticle%26utm_campaign%3Dselenium_20260923
🍎 𝐀𝐩𝐩 𝐒𝐭𝐨𝐫𝐞 (𝐢𝐎𝐒):
https://apps.apple.com/app/id6786760948?pt=128640464&ct=devto_selenium_20260923&mt=8
────────────────────────────────────────
Play Store: ────────────────────────────────────────
📲 𝐅𝐑𝐄𝐄 𝐌𝐎𝐁𝐈𝐋𝐄 𝐀𝐏𝐏 — 𝟔𝟎𝟎+ 𝐒𝐃𝐄𝐓 𝐐&𝐀𝐬
Practice real-world interview scenarios offline on the free QA Automation & SDET Prep app:
🤖 𝐆𝐨𝐨𝐠𝐥𝐞 𝐏𝐥𝐚𝐲 (𝐀𝐧𝐝𝐫𝐨𝐢𝐝):
https://play.google.com/store/apps/details?id=com.app.seleniuminterviewquestions&referrer=utm_source%3Ddevto%26utm_medium%3Darticle%26utm_campaign%3Dselenium_20260923
🍎 𝐀𝐩𝐩 𝐒𝐭𝐨𝐫𝐞 (𝐢𝐎𝐒):
https://apps.apple.com/app/id6786760948?pt=128640464&ct=devto_selenium_20260923&mt=8
────────────────────────────────────────
────────────────────────────────────────
Top comments (0)