* diff

* fixes

* fixes

* fixes

* fixes

* fixes

* better docs
This commit is contained in:
Chris Tate
2026-02-19 23:51:09 -06:00
committed by GitHub
parent 9732031087
commit d5a667ea2d
21 changed files with 2446 additions and 88 deletions
+166
View File
@@ -27,6 +27,35 @@ pub fn print_response(resp: &Response, json_mode: bool, action: Option<&str>) {
println!("{}", url);
return;
}
// Diff responses -- route by action to avoid fragile shape probing
if let Some(obj) = data.as_object() {
match action {
Some("diff_snapshot") => {
print_snapshot_diff(obj);
return;
}
Some("diff_screenshot") => {
print_screenshot_diff(obj);
return;
}
Some("diff_url") => {
if let Some(snap_data) =
obj.get("snapshot").and_then(|v| v.as_object())
{
println!("{}", color::bold("Snapshot diff:"));
print_snapshot_diff(snap_data);
}
if let Some(ss_data) =
obj.get("screenshot").and_then(|v| v.as_object())
{
println!("\n{}", color::bold("Screenshot diff:"));
print_screenshot_diff(ss_data);
}
return;
}
_ => {}
}
}
// Snapshot
if let Some(snapshot) = data.get("snapshot").and_then(|v| v.as_str()) {
println!("{}", snapshot);
@@ -1850,6 +1879,65 @@ Examples:
"##
}
"diff" => {
r##"
agent-browser diff - Compare page states
Subcommands:
diff snapshot Compare current snapshot to last snapshot in session
diff screenshot --baseline <f> Visual pixel diff against a baseline image
diff url <url1> <url2> Compare two pages
Snapshot Diff:
Usage: agent-browser diff snapshot [options]
Options:
-b, --baseline <file> Compare against a saved snapshot file
-s, --selector <sel> Scope snapshot to a CSS selector or @ref
-c, --compact Use compact snapshot format
-d, --depth <n> Limit snapshot tree depth
Without --baseline, compares against the last snapshot taken in this session.
Screenshot Diff:
Usage: agent-browser diff screenshot --baseline <file> [options]
Options:
-b, --baseline <file> Baseline image to compare against (required)
-o, --output <file> Path for the diff image (default: temp dir)
-t, --threshold <0-1> Color distance threshold (default: 0.1)
-s, --selector <sel> Scope screenshot to element
--full Full page screenshot
URL Diff:
Usage: agent-browser diff url <url1> <url2> [options]
Options:
--screenshot Also compare screenshots (default: snapshot only)
--full Full page screenshots
--wait-until <strategy> Navigation wait strategy: load, domcontentloaded, networkidle (default: load)
-s, --selector <sel> Scope snapshots to a CSS selector or @ref
-c, --compact Use compact snapshot format
-d, --depth <n> Limit snapshot tree depth
Global Options:
--json Output as JSON
--session <name> Use specific session
Examples:
agent-browser diff snapshot
agent-browser diff snapshot --baseline before.txt
agent-browser diff screenshot --baseline before.png
agent-browser diff screenshot --baseline before.png --output diff.png --threshold 0.2
agent-browser diff url https://staging.example.com https://prod.example.com
agent-browser diff url https://v1.example.com https://v2.example.com --screenshot
"##
}
_ => return false,
};
println!("{}", help.trim());
@@ -1922,6 +2010,11 @@ Storage:
Tabs:
tab [new|list|close|<n>] Manage tabs
Diff:
diff snapshot Compare current vs last snapshot
diff screenshot --baseline Compare current vs baseline image
diff url <u1> <u2> Compare two pages
Debug:
trace start|stop [path] Record Playwright trace
profiler start|stop [path] Record Chrome DevTools profile
@@ -2053,6 +2146,79 @@ iOS Simulator (requires Xcode and Appium):
);
}
fn print_snapshot_diff(data: &serde_json::Map<String, serde_json::Value>) {
let changed = data
.get("changed")
.and_then(|v| v.as_bool())
.unwrap_or(false);
if !changed {
println!("{} No changes detected", color::success_indicator());
return;
}
if let Some(diff) = data.get("diff").and_then(|v| v.as_str()) {
for line in diff.lines() {
if line.starts_with("+ ") {
println!("{}", color::green(line));
} else if line.starts_with("- ") {
println!("{}", color::red(line));
} else {
println!("{}", color::dim(line));
}
}
let additions = data.get("additions").and_then(|v| v.as_i64()).unwrap_or(0);
let removals = data.get("removals").and_then(|v| v.as_i64()).unwrap_or(0);
let unchanged = data.get("unchanged").and_then(|v| v.as_i64()).unwrap_or(0);
println!(
"\n{} additions, {} removals, {} unchanged",
color::green(&additions.to_string()),
color::red(&removals.to_string()),
unchanged
);
}
}
fn print_screenshot_diff(data: &serde_json::Map<String, serde_json::Value>) {
let mismatch = data
.get("mismatchPercentage")
.and_then(|v| v.as_f64())
.unwrap_or(0.0);
let is_match = data
.get("match")
.and_then(|v| v.as_bool())
.unwrap_or(false);
let dim_mismatch = data
.get("dimensionMismatch")
.and_then(|v| v.as_bool())
.unwrap_or(false);
if dim_mismatch {
println!(
"{} Images have different dimensions",
color::error_indicator()
);
} else if is_match {
println!("{} Images match (0% difference)", color::success_indicator());
} else {
println!(
"{} {:.2}% pixels differ",
color::error_indicator(),
mismatch
);
}
if let Some(diff_path) = data.get("diffPath").and_then(|v| v.as_str()) {
println!(" Diff image: {}", color::green(diff_path));
}
let total = data.get("totalPixels").and_then(|v| v.as_i64()).unwrap_or(0);
let different = data
.get("differentPixels")
.and_then(|v| v.as_i64())
.unwrap_or(0);
println!(
" {} different / {} total pixels",
color::red(&different.to_string()),
total
);
}
pub fn print_version() {
println!("agent-browser {}", env!("CARGO_PKG_VERSION"));
}