// SPDX-License-Identifier: Apache-2.0 // Download a file with the browser, then read it on the gateway and save a copy here. // // The browser saves downloads in the user's own folder on the gateway; wp.files lists them, extracts text or rows // (PDF, DOCX, XLSX, CSV…) and streams them; saveFile() from webpilot-si/node writes one to disk (resumable). // // export WEBPILOT_URL=http://localhost:8931 WEBPILOT_TOKEN=cbu_... // python examples/fixture_site.py & // node download.ts # the fixture's report.csv // node download.ts https://example.org/files "Annual report" # any page and link text import { WebPilot, type FileInfo } from "webpilot-si"; import { saveFile } from "webpilot-si/node"; const FIXTURE = process.env["WEBPILOT_FIXTURE"] ?? "http://host.docker.internal:8765"; const page = process.argv[2] ?? `${FIXTURE}/files`; const linkText = process.argv[3] ?? "Download report"; const wp = new WebPilot(); const before = new Set((await wp.files.list().toArray()).map((f) => f.name)); const tab = await wp.open(page, { mode: "act" }); try { const link = (await tab.snapshot()).first(linkText, { role: "link" }); await tab.click(link.ref); let file: FileInfo | undefined; for (let i = 0; i < 30 && !file; i++) { // the download finishes in the background; wait until it is listed file = (await wp.files.list().toArray()).find((f) => !before.has(f.name)); if (!file) await new Promise((r) => setTimeout(r, 1000)); } if (!file) throw new Error("no new file after 30 s"); console.log(`downloaded ${file.name} (${file.size} bytes, ${file.mime})`); if (/\.(csv|xlsx|xls)$/i.test(file.name)) { let n = 0; for await (const row of wp.files.rows(file.name)) { console.log(" ", row); if (++n === 5) break; } } else { console.log((await wp.files.text(file.name)).text.slice(0, 500)); } console.log("saved to", await saveFile(wp, file.name, ".")); await wp.files.delete(file.name); // clean up on the gateway } finally { await tab.close(); }