Fix CLI/protocol mismatches for select, frame main, and headers (#45)
* fix: align CLI command payloads with protocol * fix(cli): support multi-value select in CLI
This commit is contained in:
+36
-5
@@ -153,13 +153,18 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
|
|||||||
"select" => {
|
"select" => {
|
||||||
let sel = rest.get(0).ok_or_else(|| ParseError::MissingArguments {
|
let sel = rest.get(0).ok_or_else(|| ParseError::MissingArguments {
|
||||||
context: "select".to_string(),
|
context: "select".to_string(),
|
||||||
usage: "select <selector> <value>",
|
usage: "select <selector> <value...>",
|
||||||
})?;
|
})?;
|
||||||
let val = rest.get(1).ok_or_else(|| ParseError::MissingArguments {
|
let _val = rest.get(1).ok_or_else(|| ParseError::MissingArguments {
|
||||||
context: "select".to_string(),
|
context: "select".to_string(),
|
||||||
usage: "select <selector> <value>",
|
usage: "select <selector> <value...>",
|
||||||
})?;
|
})?;
|
||||||
Ok(json!({ "id": id, "action": "select", "selector": sel, "value": val }))
|
let values = &rest[1..];
|
||||||
|
if values.len() == 1 {
|
||||||
|
Ok(json!({ "id": id, "action": "select", "selector": sel, "values": values[0] }))
|
||||||
|
} else {
|
||||||
|
Ok(json!({ "id": id, "action": "select", "selector": sel, "values": values }))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"drag" => {
|
"drag" => {
|
||||||
let src = rest.get(0).ok_or_else(|| ParseError::MissingArguments {
|
let src = rest.get(0).ok_or_else(|| ParseError::MissingArguments {
|
||||||
@@ -408,7 +413,7 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
|
|||||||
// === Frame ===
|
// === Frame ===
|
||||||
"frame" => {
|
"frame" => {
|
||||||
if rest.get(0).map(|s| *s) == Some("main") {
|
if rest.get(0).map(|s| *s) == Some("main") {
|
||||||
Ok(json!({ "id": id, "action": "frame_main" }))
|
Ok(json!({ "id": id, "action": "mainframe" }))
|
||||||
} else {
|
} else {
|
||||||
let sel = rest.get(0).ok_or_else(|| ParseError::MissingArguments {
|
let sel = rest.get(0).ok_or_else(|| ParseError::MissingArguments {
|
||||||
context: "frame".to_string(),
|
context: "frame".to_string(),
|
||||||
@@ -1249,6 +1254,32 @@ mod tests {
|
|||||||
assert_eq!(cmd["text"], "some text");
|
assert_eq!(cmd["text"], "some text");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_select() {
|
||||||
|
let cmd = parse_command(&args("select #menu option1"), &default_flags()).unwrap();
|
||||||
|
assert_eq!(cmd["action"], "select");
|
||||||
|
assert_eq!(cmd["selector"], "#menu");
|
||||||
|
assert_eq!(cmd["values"], "option1");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_select_multiple_values() {
|
||||||
|
let cmd = parse_command(
|
||||||
|
&args("select #menu opt1 opt2 opt3"),
|
||||||
|
&default_flags(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(cmd["action"], "select");
|
||||||
|
assert_eq!(cmd["selector"], "#menu");
|
||||||
|
assert_eq!(cmd["values"], json!(["opt1", "opt2", "opt3"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_frame_main() {
|
||||||
|
let cmd = parse_command(&args("frame main"), &default_flags()).unwrap();
|
||||||
|
assert_eq!(cmd["action"], "mainframe");
|
||||||
|
}
|
||||||
|
|
||||||
// === Tabs ===
|
// === Tabs ===
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
+4
-3
@@ -423,9 +423,9 @@ Examples:
|
|||||||
"select" => r##"
|
"select" => r##"
|
||||||
agent-browser select - Select a dropdown option
|
agent-browser select - Select a dropdown option
|
||||||
|
|
||||||
Usage: agent-browser select <selector> <value>
|
Usage: agent-browser select <selector> <value...>
|
||||||
|
|
||||||
Selects an option in a <select> dropdown by its value attribute.
|
Selects one or more options in a <select> dropdown by value.
|
||||||
|
|
||||||
Global Options:
|
Global Options:
|
||||||
--json Output as JSON
|
--json Output as JSON
|
||||||
@@ -434,6 +434,7 @@ Global Options:
|
|||||||
Examples:
|
Examples:
|
||||||
agent-browser select "#country" "US"
|
agent-browser select "#country" "US"
|
||||||
agent-browser select @e5 "option2"
|
agent-browser select @e5 "option2"
|
||||||
|
agent-browser select "#menu" "opt1" "opt2" "opt3"
|
||||||
"##,
|
"##,
|
||||||
"drag" => r##"
|
"drag" => r##"
|
||||||
agent-browser drag - Drag and drop
|
agent-browser drag - Drag and drop
|
||||||
@@ -1233,7 +1234,7 @@ Core Commands:
|
|||||||
focus <sel> Focus element
|
focus <sel> Focus element
|
||||||
check <sel> Check checkbox
|
check <sel> Check checkbox
|
||||||
uncheck <sel> Uncheck checkbox
|
uncheck <sel> Uncheck checkbox
|
||||||
select <sel> <val> Select dropdown option
|
select <sel> <val...> Select dropdown option
|
||||||
drag <src> <dst> Drag and drop
|
drag <src> <dst> Drag and drop
|
||||||
upload <sel> <files...> Upload files
|
upload <sel> <files...> Upload files
|
||||||
scroll <dir> [px] Scroll (up/down/left/right)
|
scroll <dir> [px] Scroll (up/down/left/right)
|
||||||
|
|||||||
@@ -15,6 +15,22 @@ describe('parseCommand', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should parse navigate with headers', () => {
|
||||||
|
const result = parseCommand(
|
||||||
|
cmd({
|
||||||
|
id: '1',
|
||||||
|
action: 'navigate',
|
||||||
|
url: 'https://example.com',
|
||||||
|
headers: { Authorization: 'Bearer token' },
|
||||||
|
})
|
||||||
|
);
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
if (result.success) {
|
||||||
|
expect(result.command.action).toBe('navigate');
|
||||||
|
expect(result.command.headers).toEqual({ Authorization: 'Bearer token' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
it('should reject navigate without url', () => {
|
it('should reject navigate without url', () => {
|
||||||
const result = parseCommand(cmd({ id: '1', action: 'navigate' }));
|
const result = parseCommand(cmd({ id: '1', action: 'navigate' }));
|
||||||
expect(result.success).toBe(false);
|
expect(result.success).toBe(false);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ const navigateSchema = baseCommandSchema.extend({
|
|||||||
action: z.literal('navigate'),
|
action: z.literal('navigate'),
|
||||||
url: z.string().min(1),
|
url: z.string().min(1),
|
||||||
waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),
|
waitUntil: z.enum(['load', 'domcontentloaded', 'networkidle']).optional(),
|
||||||
|
headers: z.record(z.string()).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const clickSchema = baseCommandSchema.extend({
|
const clickSchema = baseCommandSchema.extend({
|
||||||
|
|||||||
Reference in New Issue
Block a user