fix(cli): align protocol action names for wheel, emulatemedia, and find locators (#143)
- mouse wheel: send 'wheel' instead of 'mousewheel' - set media: send 'emulatemedia' instead of 'media', fix reducedMotion to be string enum - find locators: omit 'value' field when not provided (Zod .optional() expects undefined, not null) - Consistently applied to: role, label, placeholder, testid, first, last, nth Fixes #131
This commit is contained in:
+90
-10
@@ -684,15 +684,39 @@ fn parse_find(rest: &[&str], id: &str) -> Result<Value, ParseError> {
|
||||
};
|
||||
|
||||
match *locator {
|
||||
"role" => Ok(json!({ "id": id, "action": "getbyrole", "role": value, "subaction": subaction, "value": fill_value, "name": name, "exact": exact })),
|
||||
"role" => {
|
||||
let mut cmd = json!({ "id": id, "action": "getbyrole", "role": value, "subaction": subaction, "name": name, "exact": exact });
|
||||
if let Some(v) = fill_value { cmd["value"] = json!(v); }
|
||||
Ok(cmd)
|
||||
}
|
||||
"text" => Ok(json!({ "id": id, "action": "getbytext", "text": value, "subaction": subaction, "exact": exact })),
|
||||
"label" => Ok(json!({ "id": id, "action": "getbylabel", "label": value, "subaction": subaction, "value": fill_value, "exact": exact })),
|
||||
"placeholder" => Ok(json!({ "id": id, "action": "getbyplaceholder", "placeholder": value, "subaction": subaction, "value": fill_value, "exact": exact })),
|
||||
"label" => {
|
||||
let mut cmd = json!({ "id": id, "action": "getbylabel", "label": value, "subaction": subaction, "exact": exact });
|
||||
if let Some(v) = fill_value { cmd["value"] = json!(v); }
|
||||
Ok(cmd)
|
||||
}
|
||||
"placeholder" => {
|
||||
let mut cmd = json!({ "id": id, "action": "getbyplaceholder", "placeholder": value, "subaction": subaction, "exact": exact });
|
||||
if let Some(v) = fill_value { cmd["value"] = json!(v); }
|
||||
Ok(cmd)
|
||||
}
|
||||
"alt" => Ok(json!({ "id": id, "action": "getbyalttext", "text": value, "subaction": subaction, "exact": exact })),
|
||||
"title" => Ok(json!({ "id": id, "action": "getbytitle", "text": value, "subaction": subaction, "exact": exact })),
|
||||
"testid" => Ok(json!({ "id": id, "action": "getbytestid", "testId": value, "subaction": subaction, "value": fill_value })),
|
||||
"first" => Ok(json!({ "id": id, "action": "nth", "selector": value, "index": 0, "subaction": subaction, "value": fill_value })),
|
||||
"last" => Ok(json!({ "id": id, "action": "nth", "selector": value, "index": -1, "subaction": subaction, "value": fill_value })),
|
||||
"testid" => {
|
||||
let mut cmd = json!({ "id": id, "action": "getbytestid", "testId": value, "subaction": subaction });
|
||||
if let Some(v) = fill_value { cmd["value"] = json!(v); }
|
||||
Ok(cmd)
|
||||
}
|
||||
"first" => {
|
||||
let mut cmd = json!({ "id": id, "action": "nth", "selector": value, "index": 0, "subaction": subaction });
|
||||
if let Some(v) = fill_value { cmd["value"] = json!(v); }
|
||||
Ok(cmd)
|
||||
}
|
||||
"last" => {
|
||||
let mut cmd = json!({ "id": id, "action": "nth", "selector": value, "index": -1, "subaction": subaction });
|
||||
if let Some(v) = fill_value { cmd["value"] = json!(v); }
|
||||
Ok(cmd)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
@@ -715,7 +739,9 @@ fn parse_find(rest: &[&str], id: &str) -> Result<Value, ParseError> {
|
||||
} else {
|
||||
None
|
||||
};
|
||||
Ok(json!({ "id": id, "action": "nth", "selector": sel, "index": idx, "subaction": sub, "value": fv }))
|
||||
let mut cmd = json!({ "id": id, "action": "nth", "selector": sel, "index": idx, "subaction": sub });
|
||||
if let Some(v) = fv { cmd["value"] = json!(v); }
|
||||
Ok(cmd)
|
||||
}
|
||||
_ => Err(ParseError::UnknownSubcommand {
|
||||
subcommand: locator.to_string(),
|
||||
@@ -756,7 +782,7 @@ fn parse_mouse(rest: &[&str], id: &str) -> Result<Value, ParseError> {
|
||||
Some("wheel") => {
|
||||
let dy = rest.get(1).and_then(|s| s.parse::<i32>().ok()).unwrap_or(100);
|
||||
let dx = rest.get(2).and_then(|s| s.parse::<i32>().ok()).unwrap_or(0);
|
||||
Ok(json!({ "id": id, "action": "mousewheel", "deltaX": dx, "deltaY": dy }))
|
||||
Ok(json!({ "id": id, "action": "wheel", "deltaX": dx, "deltaY": dy }))
|
||||
}
|
||||
Some(sub) => Err(ParseError::UnknownSubcommand {
|
||||
subcommand: sub.to_string(),
|
||||
@@ -854,8 +880,12 @@ fn parse_set(rest: &[&str], id: &str) -> Result<Value, ParseError> {
|
||||
} else {
|
||||
"no-preference"
|
||||
};
|
||||
let reduced = rest.iter().any(|&s| s == "reduced-motion");
|
||||
Ok(json!({ "id": id, "action": "media", "colorScheme": color, "reducedMotion": reduced }))
|
||||
let reduced = if rest.iter().any(|&s| s == "reduced-motion") {
|
||||
"reduce"
|
||||
} else {
|
||||
"no-preference"
|
||||
};
|
||||
Ok(json!({ "id": id, "action": "emulatemedia", "colorScheme": color, "reducedMotion": reduced }))
|
||||
}
|
||||
Some(sub) => Err(ParseError::UnknownSubcommand {
|
||||
subcommand: sub.to_string(),
|
||||
@@ -1447,4 +1477,54 @@ mod tests {
|
||||
assert!(matches!(err, ParseError::MissingArguments { .. }));
|
||||
assert!(err.format().contains("get text"));
|
||||
}
|
||||
|
||||
// === Protocol alignment tests ===
|
||||
|
||||
#[test]
|
||||
fn test_mouse_wheel() {
|
||||
let cmd = parse_command(&args("mouse wheel 100 50"), &default_flags()).unwrap();
|
||||
assert_eq!(cmd["action"], "wheel");
|
||||
assert_eq!(cmd["deltaY"], 100);
|
||||
assert_eq!(cmd["deltaX"], 50);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_media() {
|
||||
let cmd = parse_command(&args("set media dark"), &default_flags()).unwrap();
|
||||
assert_eq!(cmd["action"], "emulatemedia");
|
||||
assert_eq!(cmd["colorScheme"], "dark");
|
||||
assert_eq!(cmd["reducedMotion"], "no-preference");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_set_media_reduced_motion() {
|
||||
let cmd = parse_command(&args("set media light reduced-motion"), &default_flags()).unwrap();
|
||||
assert_eq!(cmd["action"], "emulatemedia");
|
||||
assert_eq!(cmd["colorScheme"], "light");
|
||||
assert_eq!(cmd["reducedMotion"], "reduce");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_first_no_value() {
|
||||
let cmd = parse_command(&args("find first a click"), &default_flags()).unwrap();
|
||||
assert_eq!(cmd["action"], "nth");
|
||||
assert_eq!(cmd["index"], 0);
|
||||
assert!(cmd.get("value").is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_first_with_value() {
|
||||
let cmd = parse_command(&args("find first input fill hello"), &default_flags()).unwrap();
|
||||
assert_eq!(cmd["action"], "nth");
|
||||
assert_eq!(cmd["index"], 0);
|
||||
assert_eq!(cmd["value"], "hello");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_nth_no_value() {
|
||||
let cmd = parse_command(&args("find nth 2 a click"), &default_flags()).unwrap();
|
||||
assert_eq!(cmd["action"], "nth");
|
||||
assert_eq!(cmd["index"], 2);
|
||||
assert!(cmd.get("value").is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user