fix: resolve 3 protocol bugs, improve CLI and snapshot code quality (#487)
## Summary - Fix `allowFileAccess` being silently stripped from launch commands by adding it to the Zod schema in `protocol.ts` (the `--allow-file-access` CLI flag was not reaching the browser) - Fix `trace stop` requiring a path argument despite help text documenting it as optional -- now works with or without a path - Fix `addscript`/`addstyle` silently succeeding when neither `content` nor `url` is provided -- now returns a validation error - Replace hardcoded ANSI escape code with `color::error_indicator()` in `main.rs` to respect `NO_COLOR` - Fix double-parse pattern and add descriptive expect messages in `commands.rs` - Fix incomplete string escaping in `snapshot.ts` `buildSelector` (use `JSON.stringify` instead of manual quote escaping) - Simplify redundant ternary in `snapshot.ts` cursor-interactive role assignment - Sync docs changelog with CHANGELOG.md (v0.8.1 through v0.10.0)
This commit is contained in:
+31
-10
@@ -345,10 +345,8 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
|
||||
|
||||
// Default: selector or timeout
|
||||
if let Some(arg) = rest.first() {
|
||||
if arg.parse::<u64>().is_ok() {
|
||||
Ok(
|
||||
json!({ "id": id, "action": "wait", "timeout": arg.parse::<u64>().unwrap() }),
|
||||
)
|
||||
if let Ok(timeout) = arg.parse::<u64>() {
|
||||
Ok(json!({ "id": id, "action": "wait", "timeout": timeout }))
|
||||
} else {
|
||||
Ok(json!({ "id": id, "action": "wait", "selector": arg }))
|
||||
}
|
||||
@@ -684,7 +682,8 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
|
||||
Ok(cmd)
|
||||
}
|
||||
Some(n) if n.parse::<i32>().is_ok() => {
|
||||
Ok(json!({ "id": id, "action": "tab_switch", "index": n.parse::<i32>().unwrap() }))
|
||||
let index = n.parse::<i32>().expect("already checked parse succeeds");
|
||||
Ok(json!({ "id": id, "action": "tab_switch", "index": index }))
|
||||
}
|
||||
_ => Ok(json!({ "id": id, "action": "tab_list" })),
|
||||
},
|
||||
@@ -746,11 +745,11 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
|
||||
match rest.first().copied() {
|
||||
Some("start") => Ok(json!({ "id": id, "action": "trace_start" })),
|
||||
Some("stop") => {
|
||||
let path = rest.get(1).ok_or_else(|| ParseError::MissingArguments {
|
||||
context: "trace stop".to_string(),
|
||||
usage: "trace stop <path>",
|
||||
})?;
|
||||
Ok(json!({ "id": id, "action": "trace_stop", "path": path }))
|
||||
let mut cmd = json!({ "id": id, "action": "trace_stop" });
|
||||
if let Some(path) = rest.get(1) {
|
||||
cmd["path"] = json!(path);
|
||||
}
|
||||
Ok(cmd)
|
||||
}
|
||||
Some(sub) => Err(ParseError::UnknownSubcommand {
|
||||
subcommand: sub.to_string(),
|
||||
@@ -2572,4 +2571,26 @@ mod tests {
|
||||
assert_eq!(cmd["action"], "launch");
|
||||
assert_eq!(cmd["cdpPort"], 1);
|
||||
}
|
||||
|
||||
// === Trace Tests ===
|
||||
|
||||
#[test]
|
||||
fn test_trace_start() {
|
||||
let cmd = parse_command(&args("trace start"), &default_flags()).unwrap();
|
||||
assert_eq!(cmd["action"], "trace_start");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trace_stop_with_path() {
|
||||
let cmd = parse_command(&args("trace stop ./trace.zip"), &default_flags()).unwrap();
|
||||
assert_eq!(cmd["action"], "trace_stop");
|
||||
assert_eq!(cmd["path"], "./trace.zip");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trace_stop_without_path() {
|
||||
let cmd = parse_command(&args("trace stop"), &default_flags()).unwrap();
|
||||
assert_eq!(cmd["action"], "trace_stop");
|
||||
assert!(cmd.get("path").is_none() || cmd["path"].is_null());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -470,7 +470,7 @@ fn main() {
|
||||
if flags.json {
|
||||
println!(r#"{{"success":false,"error":"{}"}}"#, msg);
|
||||
} else {
|
||||
eprintln!("\x1b[31m✗\x1b[0m {}", msg);
|
||||
eprintln!("{} {}", color::error_indicator(), msg);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -344,6 +344,11 @@ pub fn print_response(resp: &Response, json_mode: bool, action: Option<&str>) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Trace stop without path
|
||||
if data.get("traceStopped").is_some() {
|
||||
println!("{} Trace stopped", color::success_indicator());
|
||||
return;
|
||||
}
|
||||
// Path-based operations (screenshot/pdf/trace/har/download/state/video)
|
||||
if let Some(path) = data.get("path").and_then(|v| v.as_str()) {
|
||||
match action.unwrap_or("") {
|
||||
|
||||
Reference in New Issue
Block a user