Kernel browsers run in fully sandboxed environments with writable filesystems. When your automation downloads a file, it’s saved inside the browser’s filesystem and can be retrieved using Kernel’s File I/O APIs.
Files can only be retrieved while the browser session is still active. Once the browser session is destroyed or times out, all files from that session are permanently deleted and no longer accessible.
Playwright performs downloads via the browser itself, so there are a few steps:
Create a browser session
Configure browser download behavior using CDP
Perform the download
Retrieve the file from the browser’s filesystem
With behavior: 'default', user-initiated downloads (e.g., clicking a download link) are saved to the browser’s default download directory. The CDP downloadProgress event includes a filePath field when the download completes, indicating exactly where the file was saved. This path can then be used with Kernel’s File I/O APIs to retrieve the file.
If the download is programmatically initiated (e.g., triggered via JavaScript rather than a user click), behavior must be set to "allow" with a specified downloadPath. Downloads triggered programmatically are blocked by default in Chromium, so "default" won’t work.
Playwright’s setInputFiles() method allows you to upload files directly to file input elements. You can fetch a file from a URL and pass the buffer directly to setInputFiles().
Copy
Ask AI
import Kernel from '@onkernel/sdk';import { chromium } from 'playwright';const IMAGE_URL = 'https://www.kernel.sh/brand_assets/Kernel-Logo_Accent.png';const kernel = new Kernel();async function main() { // Create Kernel browser session const kernelBrowser = await kernel.browsers.create(); console.log('Live view:', kernelBrowser.browser_live_view_url); // Connect Playwright const browser = await chromium.connectOverCDP(kernelBrowser.cdp_ws_url); const context = browser.contexts()[0] || (await browser.newContext()); const page = context.pages()[0] || (await context.newPage()); // Navigate to a page with a file input await page.goto('https://browser-tests-alpha.vercel.app/api/upload-test'); // Fetch file and pass buffer directly to setInputFiles const response = await fetch(IMAGE_URL); const buffer = Buffer.from(await response.arrayBuffer()); await page.locator('input[type="file"]').setInputFiles([{ name: 'Kernel-Logo_Accent.png', mimeType: 'image/png', buffer: buffer, }]); console.log('File uploaded'); await kernel.browsers.deleteByID(kernelBrowser.session_id); console.log('Browser deleted');}main();
The CDP downloadProgress event signals when the browser finishes writing a file, but there may be a brief delay before the file becomes available through Kernel’s File I/O APIs. This is especially true for larger downloads. We recommend polling listFiles to confirm the file exists before attempting to read it.