Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,15 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
i += 1;
}
}
"--diff" => {
obj.insert("diff".to_string(), json!(true));
}
"--output" | "-o" => {
if let Some(p) = rest.get(i + 1) {
obj.insert("output".to_string(), json!(p));
i += 1;
}
}
_ => {}
}
i += 1;
Expand Down
48 changes: 47 additions & 1 deletion src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -643,9 +643,14 @@ async function handleSnapshot(
maxDepth?: number;
compact?: boolean;
selector?: string;
diff?: boolean;
output?: string;
},
browser: BrowserManager
): Promise<Response<SnapshotData>> {
// Save previous snapshot before getSnapshot() updates lastSnapshot
const previousSnapshot = command.diff ? browser.getLastSnapshot() : '';

// Use enhanced snapshot with refs and optional filtering
const { tree, refs } = await browser.getSnapshot({
interactive: command.interactive,
Expand All @@ -655,14 +660,55 @@ async function handleSnapshot(
selector: command.selector,
});

const snapshot = tree || 'Empty page';

// Incremental diff: only return changed lines
if (command.diff && previousSnapshot) {
const oldLines = previousSnapshot.split('\n');
const newLines = snapshot.split('\n');
// Use frequency maps to correctly handle duplicate lines
const oldFreq = new Map<string, number>();
for (const line of oldLines) oldFreq.set(line, (oldFreq.get(line) || 0) + 1);
const newFreq = new Map<string, number>();
for (const line of newLines) newFreq.set(line, (newFreq.get(line) || 0) + 1);

const removed: string[] = [];
for (const [line, count] of oldFreq) {
const diff = count - (newFreq.get(line) || 0);
for (let i = 0; i < diff; i++) removed.push(line);
}
const added: string[] = [];
for (const [line, count] of newFreq) {
const diff = count - (oldFreq.get(line) || 0);
for (let i = 0; i < diff; i++) added.push(line);
}

const diffOutput = [
...removed.map(l => `- ${l}`),
...added.map(l => `+ ${l}`),
].join('\n');
return successResponse(command.id, { snapshot: diffOutput || '(no changes)' });
}

// Save to file instead of returning full snapshot
if (command.output) {
const fs = await import('fs');
const path = await import('path');
const resolvedPath = path.resolve(command.output);
fs.writeFileSync(resolvedPath, snapshot, 'utf-8');
return successResponse(command.id, {
snapshot: `Snapshot saved to ${resolvedPath} (${snapshot.length} chars)`,
});
}

// Simplify refs for output (just role and name)
const simpleRefs: Record<string, { role: string; name?: string }> = {};
for (const [ref, data] of Object.entries(refs)) {
simpleRefs[ref] = { role: data.role, name: data.name };
}

return successResponse(command.id, {
snapshot: tree || 'Empty page',
snapshot,
refs: Object.keys(simpleRefs).length > 0 ? simpleRefs : undefined,
});
}
Expand Down
7 changes: 7 additions & 0 deletions src/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ export class BrowserManager {
return this.refMap;
}

/**
* Get the last snapshot text for diff comparison
*/
getLastSnapshot(): string {
return this.lastSnapshot;
}

/**
* Get a locator from a ref (e.g., "e1", "@e1", "ref=e1")
* Returns null if ref doesn't exist or is invalid
Expand Down
2 changes: 2 additions & 0 deletions src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,8 @@ const snapshotSchema = baseCommandSchema.extend({
maxDepth: z.number().nonnegative().optional(),
compact: z.boolean().optional(),
selector: z.string().optional(),
diff: z.boolean().optional(),
output: z.string().optional(),
});

const evaluateSchema = baseCommandSchema.extend({
Expand Down
2 changes: 2 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,8 @@ export interface ScreenshotCommand extends BaseCommand {

export interface SnapshotCommand extends BaseCommand {
action: 'snapshot';
diff?: boolean;
output?: string;
}

export interface EvaluateCommand extends BaseCommand {
Expand Down