# How to Perform Mouse Drag Operations in ego-browser Using Coordinate Arrays vs. Selectors

> Master ego browser mouse drag operations. Learn to use coordinate arrays and selectors with the dragMouse helper for efficient UI automation. Optimize your tests.

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

---

**Use the `dragMouse` helper with an array of `MouseTarget` values, where each target can be a coordinate array `[x, y]`, a CSS selector string, or a selector object with offsets `{selector, x?, y?}`.**

The `ego-browser` package within the citrolabs/ego-lite repository exposes a low-level pointer driver capable of executing complex mouse drag sequences through Chrome DevTools Protocol (CDP) events. When automating drag operations, you can choose between absolute viewport coordinates for pixel-perfect control or CSS selectors for element-centric navigation, depending on your interaction requirements.

## Understanding the MouseTarget Type Definition

The flexibility of ego-browser's drag system stems from the `MouseTarget` type defined in [[`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/pointer.ts#L13-L18). This union type accepts several distinct forms, allowing each waypoint in a drag sequence to specify its location differently.

The type supports:

- **`[x, y]`** – A tuple of absolute viewport coordinates in CSS pixels
- **`{x, y}`** – An object containing absolute viewport coordinates  
- **`string`** – A CSS selector resolved to the element's center point
- **`{selector, x?, y?}`** – A selector with optional pixel offsets from the element's top-left corner

All public mouse helpers—including `click`, `doubleClick`, `hover`, and **`dragMouse`**—share this target format, as documented in [[`skills/ego-browser/SKILL.md`](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/SKILL.md)](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/SKILL.md#l128-l135).

## Dragging with Coordinate Arrays

Coordinate arrays provide **absolute viewport positioning** without requiring DOM elements at the target locations. This approach is essential when interacting with canvas-based interfaces, maps, or custom-rendered graphics where logical elements exist without corresponding DOM nodes.

When you pass `[x, y]` or `{x, y}` as a target, the driver interprets these as CSS pixel values relative to the viewport origin. The implementation in [[`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/pointer.ts#L38-L90) validates the array length and dispatches CDP mouse events at the specified coordinates.

```javascript
// Drag from viewport position (100, 100) to (300, 300) with 10ms delay between steps
await dragMouse([[100, 100], [300, 300]], { delay: 10, label: 'drag box' });

```

## Dragging with CSS Selectors

For standard DOM interactions, selector-based targeting automatically resolves elements to their geometric centers, eliminating the need to calculate coordinates manually.

### Selector Strings

Passing a plain string selector triggers the `resolveMouseTarget` function, which internally calls `waitForSelector` and `elementCenter` to locate the element and compute its center point.

```javascript
// Drag the center of #drag-source to the center of #drag-target
await dragMouse(['#drag-source', '#drag-target'], { label: 'drag card' });

```

### Selector Objects with Offsets

When you need to drag from a specific corner or handle rather than the center, use the object form with optional `x` and `y` offsets. The driver resolves the selector to the element's **top-left corner**, then adds the specified pixel offsets.

```javascript
// Start at the top-left of #myCanvas, offset by (10, 20), then move to absolute coordinate (400, 400)
await dragMouse(
  [{ selector: '#myCanvas', x: 10, y: 20 }, [400, 400]],
  { label: 'canvas drag', delay: 5 }
);

```

The resolution logic in [[`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/pointer.ts#L44-L55) handles the conversion from selector to viewport coordinates before the drag sequence begins.

## Combining Coordinate Arrays and Selectors

The `MouseTarget` array accepts **mixed target types**, enabling complex interaction patterns that begin at an element, travel through specific coordinates, and end at another element.

```javascript
// Start at #source, pass through coordinate (250, 250), end at #target
await dragMouse(
  ['#source', [250, 250], '#target'],
  { button: 'left', delay: 15, label: 'complex drag' }
);

```

This mixed approach is particularly useful for testing drag-and-drop interactions that must avoid intermediate obstacles or follow specific geometric paths.

## Implementation Architecture

The `drag` implementation in [[`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/pointer.ts#L38-L90) validates the target array, resolves each entry to an absolute viewport point using `resolveMouseTarget`, and dispatches a series of CDP mouse events (`mousePressed`, `mouseMoved`, `mouseReleased`) with the specified timing delays.

The public **`dragMouse`** helper exported from [[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) serves as a thin wrapper around `pointer.drag`, forwarding the target array and options (button, delay, label) while maintaining the same interface documented in [`SKILL.md`](https://github.com/citrolabs/ego-lite/blob/main/SKILL.md). For CLI usage, [[`src/format.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/format.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/format.ts) maps the `page.mouse.drag` command to this underlying implementation.

## Summary

- **Coordinate arrays** (`[x, y]`, `{x, y}`) provide absolute viewport positioning for canvas and non-DOM interactions
- **Selector strings** resolve automatically to element center points via `elementCenter` and `waitForSelector`
- **Selector objects** (`{selector, x?, y?}`) calculate positions from the element's top-left corner with optional offsets
- **Mixed arrays** allow sequences combining any target types for complex drag paths
- All targets are resolved to viewport coordinates in [`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts) before CDP event dispatch

## Frequently Asked Questions

### How does ego-browser resolve selectors to coordinates during a drag operation?

The `resolveMouseTarget` function in [`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts) (lines 44-55) first waits for the selector to match using `waitForSelector`, then calculates the element's center point via `elementCenter`. If the target includes `x` or `y` offsets, it uses the element's top-left position as the base and adds the offsets to determine the final viewport coordinates.

### Can I use coordinate arrays and selectors in the same drag sequence?

Yes. The `dragMouse` helper accepts a `MouseTarget[]` array where each element can be independently specified as a coordinate array, selector string, or selector object. This allows you to start a drag at a DOM element, pass through specific screen coordinates, and end at another element in a single operation.

### When should I use coordinate arrays instead of selectors?

Use **coordinate arrays** when interacting with elements that lack stable DOM representations, such as HTML5 canvas drawings, WebGL surfaces, or complex mapping libraries. Use **selectors** for standard HTML elements where the browser can automatically calculate geometric centers, reducing fragility from layout changes.

### What CDP events does the drag operation dispatch?

According to the implementation in [`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts), the `drag` method dispatches `Input.dispatchMouseEvent` commands with types `mousePressed` (at the start), `mouseMoved` (for each intermediate target), and `mouseReleased` (at the final destination), with optional delays between movements specified in the options parameter.