playwright download event never fired in headless: how to fix
Gets Playwright download events working in headless runs. Use when the 'download' event never fires or download.path() never resolves headless. Not for uploads.
TL;DR
Downloads work headless; the usual miss is clicking before listening. Start page.waitForEvent('download') before the click using Promise.all, and make sure the browser context was created with acceptDownloads set to true.
The query
playwright download event never fired in headless: how to fixUse this when
- download event never fires in headless mode
- download.path() hangs forever
- export-button tests fail only in CI
Not for
- file uploads
- verifying file contents (read the saved file separately)
- browser download settings UI
Steps
- Create the context with acceptDownloads set to true in the test or project config. Expected output: the context options include acceptDownloads true.
- Restructure so the listener starts before the click: await Promise.all with page.waitForEvent('download') and the click together. Expected output: the waitForEvent promise is created before the click promise.
- Await download.path() to confirm the file landed, and assert on the suggested filename. Expected output: a real file path on disk and the expected filename.
- If the download opens in a new tab, wait for the new page on the context and listen for the download there. Expected output: the download is captured from the correct page.
- Run headless and headed to confirm both modes capture the file. Expected output: passing runs in both modes with the file saved.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_4NloQitH8N2NW6AU6oyJKA
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.