import Kernel from '@onkernel/sdk';
import { chromium } from 'playwright';
import fs from 'fs';
import pTimeout from 'p-timeout';
const DOWNLOAD_DIR = '/tmp/downloads';
const kernel = new Kernel();
async function main() {
const kernelBrowser = await kernel.browsers.create();
console.log('live view:', kernelBrowser.browser_live_view_url);
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());
const client = await context.newCDPSession(page);
await client.send('Browser.setDownloadBehavior', {
behavior: 'allow',
downloadPath: DOWNLOAD_DIR,
eventsEnabled: true,
});
// Set up CDP listeners to capture download filename and completion
let downloadFilename: string | undefined;
let downloadCompletedResolve!: () => void;
const downloadCompleted = new Promise<void>((resolve) => {
downloadCompletedResolve = resolve;
});
client.on('Browser.downloadWillBegin', (event) => {
downloadFilename = event.suggestedFilename ?? 'unknown';
console.log('Download started:', downloadFilename);
});
client.on('Browser.downloadProgress', (event) => {
if (event.state === 'completed' || event.state === 'canceled') {
downloadCompletedResolve();
}
});
console.log('Navigating to download test page');
await page.goto('https://browser-tests-alpha.vercel.app/api/download-test');
await page.getByRole('link', { name: 'Download File' }).click();
try {
await pTimeout(downloadCompleted, {
milliseconds: 10_000,
message: new Error('Download timed out after 10 seconds'),
});
console.log('Download completed');
} catch (err) {
console.error(err);
throw err;
}
if (!downloadFilename) {
throw new Error('Unable to determine download filename');
}
const remotePath = `${DOWNLOAD_DIR}/${downloadFilename}`;
console.log(`Reading file: ${remotePath}`);
const resp = await kernel.browsers.fs.readFile(kernelBrowser.session_id, {
path: remotePath,
});
const bytes = await resp.bytes();
fs.mkdirSync('downloads', { recursive: true });
const localPath = `downloads/${downloadFilename}`;
fs.writeFileSync(localPath, bytes);
console.log(`Saved to ${localPath}`);
await browser.close();
}
main();