How Ego‑Lite Handles File Uploads and Downloads: CDP‑Based Implementation Explained
Ego‑Lite implements file uploads and downloads through Playwright‑style helpers in the ego-browser package, using the Chrome DevTools Protocol (CDP) directly via the src/driver/files.ts and src/driver/downloads.ts modules.
The citrolabs/ego-lite library provides lightweight browser automation with a focus on CDP‑native operations. File handling follows the Playwright API surface while operating at the protocol level, eliminating heavy dependency chains. This article examines the complete upload and download workflow as implemented in the source code.
File Upload Architecture
The setInputFiles Helper
The primary entry point for uploads is page.setInputFiles(), exported from src/helpers.ts and implemented in src/driver/files.ts. This method populates a file input element with one or more files without simulated user interaction.
// Re-export from helpers.ts (lines 99-100)
export const setInputFiles = driverFiles.setInputFiles;
CDP Implementation Details
The setInputFiles(selector, path) implementation in src/driver/files.ts performs three coordinated steps:
- Path normalization – Converts the
pathargument to an array of absolute file paths - Element resolution – Uses
withHandle()to obtain the DOM element'sobjectIdand current CDP session ID - Protocol invocation – Calls
DOM.setFileInputFileswith the file list and element reference
// Upload multiple files to a file input element
await page.setInputFiles('#file-input', [
'/absolute/path/to/file1.txt',
'/absolute/path/to/file2.jpg',
]);
The operation returns Promise<void> — no value is returned because the upload modifies page state as a side effect. The CDP command DOM.setFileInputFiles is a Chromium‑native operation that directly populates the input's files property.
File Download Handling
Event‑Based Download Capture
Downloads are captured through page.waitForEvent('download'), which delegates to src/driver/downloads.ts. The implementation currently supports only the "download" event; other event names throw descriptive errors.
Download Workflow Stages
The downloads.ts driver implements a multi‑stage download pipeline:
Stage 1: Environment Preparation
- Creates a unique temporary directory under
os.tmpdir()with naming pattern:{pid}-{timestamp}-{randomSuffix} - Invokes
ensureSession()to guarantee an active CDP session - Configures download behavior via
setDownloadBehavior()usingBrowser.setDownloadBehavior(preferred) orPage.setDownloadBehavior(fallback)
Stage 2: Event Listening
Two CDP events are monitored simultaneously:
Page.downloadWillBegin– Captures the downloadguidandsuggestedFilenamePage.downloadProgress– Filters byguid, watching for"completed"or"canceled"state
Stage 3: Completion Handling
Upon successful completion, a facade object provides four methods:
| Method | Return Type | Description |
|---|---|---|
suggestedFilename() |
string |
Filename proposed by the browser |
url() |
string |
Source URL of the download |
path() |
Promise<string> |
Absolute path in temporary directory |
saveAs(targetPath) |
Promise<void> |
Copies file to permanent location |
If the download is canceled, the operation throws an error including the filename.
Timeout Configuration
Both event listeners respect the timeout option, defaulting to state.defaultTimeout when unspecified.
// Wait for download with custom timeout
const download = await page.waitForEvent('download', { timeout: 30_000 });
console.log('Downloading:', download.suggestedFilename());
// Move to permanent storage
await download.saveAs('/my/downloads/' + download.suggestedFilename());
Key Source Files and Responsibilities
Understanding the module structure clarifies where specific behaviors originate:
src/driver/files.ts– Core upload implementation usingDOM.setFileInputFilessrc/driver/downloads.ts– Complete download lifecycle: temp directory management, behavior configuration, event listening, and facade object creationsrc/helpers.ts– Public API surface re-exporting driver functions aspage.*methodssrc/cdp-eval.ts– Low‑levelcdp()wrapper used by both drivers for protocol commandssrc/browser-runtime.ts– ProvidesensureSession()andwaitForBrowserEvent()infrastructure essential for download operations
Summary
- File uploads in Ego‑Lite use CDP's
DOM.setFileInputFilesviasrc/driver/files.ts, accepting absolute paths and operating directly on elementobjectIds - File downloads require configuring browser download behavior, creating temporary directories, and listening for
Page.downloadWillBeginandPage.downloadProgressevents - The facade pattern for downloads provides Playwright‑compatible methods (
suggestedFilename(),saveAs(), etc.) while managing temporary file cleanup implicitly - All operations are promise‑based with configurable timeouts consistent with Ego‑Lite's global timeout state
- The CDP abstraction layer in
cdp-eval.tsand session management inbrowser-runtime.tsenable these features without external browser control dependencies
Frequently Asked Questions
How does Ego‑Lite handle multiple file uploads?
The setInputFiles method normalizes any path argument to an array, then passes the complete list to CDP's DOM.setFileInputFiles command. The browser's native file input mechanism accepts multiple paths simultaneously, populating the input's files FileList in order.
Where are downloaded files stored before saveAs() is called?
Downloads are written to a uniquely‑named temporary directory created under the OS temp folder (os.tmpdir()). The directory name incorporates process PID, timestamp, and random suffix to prevent collisions. The path() method on the download object resolves to this temporary location.
What happens if a download is canceled or fails?
The Page.downloadProgress event watcher detects state: "canceled" and throws an error containing the filename. Successful completion requires state: "completed"; no partial file handling is implemented—canceled downloads remain in the temporary directory until system cleanup.
Can I use waitForEvent for events other than "download"?
Currently no. The src/driver/downloads.ts implementation explicitly validates the event name and throws 'Unsupported event: ${event}' for any value other than "download". This matches Ego‑Lite's scoped feature set focused on file operations rather than general event coverage.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →