# How to Upload Files Using `setInputFiles` in ego-browser

> Learn to upload files with setInputFiles in ego-browser. Attach local files to inputs using Chrome DevTools Protocol and selector strings or Playwright locators.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-07-28

---

**Use the `setInputFiles` helper exposed by `citrolabs/ego-lite` to attach local files to file input elements via Chrome DevTools Protocol commands, supporting both direct selector strings and Playwright-style locator chains.**

The `ego-browser` package provides a robust file upload mechanism through the `setInputFiles` function. This helper abstracts the complexity of Chrome DevTools Protocol (CDP) interactions, allowing agent scripts to set file paths on `<input type="file">` elements using absolute paths. Whether automating single document uploads or batch photo galleries, the implementation in [`src/driver/files.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/files.ts) delivers a consistent, promise-based API.

## How `setInputFiles` Works Under the Hood

The helper operates across two architectural layers: the low-level driver that communicates with the browser runtime, and the high-level façade exposed to agent scripts.

### Driver Implementation in [`src/driver/files.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/files.ts)

At the core of the upload functionality lies the driver implementation. The `setInputFiles` function normalizes input paths into an array and invokes the CDP command `DOM.setFileInputFiles`:

```ts
// src/driver/files.ts
export async function setInputFiles(selector, path) {
  const files = Array.isArray(path) ? path : [path];
  await withHandle(selector, async ({ objectId, sessionId }) => {
    await cdp("DOM.setFileInputFiles", { files, objectId }, sessionId);
  });
}

```

This code retrieves the DOM object handle using `withHandle`, then pushes the file paths directly to the browser's file input controller via the `objectId` and `sessionId` parameters.

### Public API Exposure in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)

According to the `citrolabs/ego-lite` source code, the driver function is re-exported through the helpers module to become part of the public API:

```ts
// src/helpers.ts
export { setInputFiles } from "./driver/files.js";

```

Additionally, every **locator** object automatically includes a `setInputFiles` method that forwards arguments to the driver, enabling Playwright-style syntax:

```ts
// src/helpers.ts – locator façade
setInputFiles: (filesValue) => files.setInputFiles(selector, filesValue),

```

## Practical File Upload Examples

You can invoke file uploads through two primary patterns: direct helper calls for immediate selector targeting, or locator-based methods for fluent chaining.

### Direct Helper Call with Selectors

Use the standalone helper when working with raw selector strings. This approach works best in straightforward automation scripts:

```ts
// Upload a single file
await setInputFiles('input#upload', '/absolute/path/to/file.png');

// Upload multiple files simultaneously
await setInputFiles('input[name="photos"]', [
  '/abs/path/photo1.jpg',
  '/abs/path/photo2.jpg',
]);

```

### Playwright-Style Locator Method

For more maintainable code, use the locator pattern provided by the page façade. This method returns a promise that resolves when the CDP command completes:

```ts
// Using the page façade with a single file
await page.locator('input#upload').setInputFiles('/abs/file.pdf');

// With a CSS selector stored in a variable
const selector = 'input[name="documents"]';
await page.locator(selector).setInputFiles([
  '/abs/doc1.docx',
  '/abs/doc2.docx',
]);

```

### Chaining Upload with Subsequent Actions

Because locators return chainable objects, you can attach files and immediately trigger form submissions:

```ts
await page
  .locator('#avatar')
  .setInputFiles('/abs/avatar.png')
  .click();            // Triggers submit after file attachment

```

## Summary

- **`setInputFiles`** is the primary helper for file uploads in `citrolabs/ego-lite`, implemented in [`src/driver/files.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/files.ts).
- The function uses **CDP's `DOM.setFileInputFiles`** command to inject file paths into DOM elements.
- Accepts both **single strings** and **arrays** of absolute file paths.
- Available as a **standalone helper** or as a **locator method** via the façade in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts).
- All calls return **`Promise<void>`** and resolve after the browser confirms file attachment.

## Frequently Asked Questions

### What CDP command does `setInputFiles` use internally?

The helper invokes **`DOM.setFileInputFiles`** through the Chrome DevTools Protocol. This command requires the DOM object's `objectId` and a `sessionId`, which the driver retrieves via the `withHandle` utility before transmitting the file path array to the browser runtime.

### Can I upload multiple files in a single call?

Yes. Pass an array of absolute paths instead of a single string. The driver automatically normalizes single paths into arrays, but accepts explicit arrays for multiple files: `['/abs/path/file1.jpg', '/abs/path/file2.jpg']`.

### Does `setInputFiles` support relative file paths?

The implementation expects **absolute paths**. The underlying CDP command requires fully qualified paths to locate files on the local filesystem. Always resolve relative paths to absolute paths before invoking the helper.

### Is there a separate `uploadFile` helper in ego-browser?

No. The `citrolabs/ego-lite` repository provides **`setInputFiles`** as the canonical helper for file uploads. This single function handles both single and multiple file attachments through the CDP layer, eliminating the need for a distinct `uploadFile` method.