feat: add keyboard command for raw keyboard input (#521)
Adds `keyboard type` and `keyboard insertText` subcommands that operate on the currently focused element without requiring a selector. Essential for contenteditable editors (Lexical, ProseMirror, CodeMirror, Monaco) where `type <selector>` doesn't trigger the editor's internal event pipeline (beforeinput/DOM mutation). - `keyboard type <text>` — page.keyboard.type() with real keystrokes - `keyboard insertText <text>` — page.keyboard.insertText() Note: `keyboard press` intentionally omitted — the existing top-level `press` command already operates on current focus. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -263,6 +263,38 @@ pub fn parse_command(args: &[String], flags: &Flags) -> Result<Value, ParseError
|
||||
})?;
|
||||
Ok(json!({ "id": id, "action": "keyup", "key": key }))
|
||||
}
|
||||
"keyboard" => {
|
||||
let sub = rest.first().ok_or_else(|| ParseError::MissingArguments {
|
||||
context: "keyboard".to_string(),
|
||||
usage: "keyboard <type|inserttext> <text>",
|
||||
})?;
|
||||
match *sub {
|
||||
"type" => {
|
||||
let text: String = rest[1..].join(" ");
|
||||
if text.is_empty() {
|
||||
return Err(ParseError::MissingArguments {
|
||||
context: "keyboard type".to_string(),
|
||||
usage: "keyboard type <text>",
|
||||
});
|
||||
}
|
||||
Ok(json!({ "id": id, "action": "keyboard", "subaction": "type", "text": text }))
|
||||
}
|
||||
"inserttext" | "insertText" => {
|
||||
let text: String = rest[1..].join(" ");
|
||||
if text.is_empty() {
|
||||
return Err(ParseError::MissingArguments {
|
||||
context: "keyboard inserttext".to_string(),
|
||||
usage: "keyboard inserttext <text>",
|
||||
});
|
||||
}
|
||||
Ok(json!({ "id": id, "action": "keyboard", "subaction": "insertText", "text": text }))
|
||||
}
|
||||
_ => Err(ParseError::UnknownSubcommand {
|
||||
subcommand: sub.to_string(),
|
||||
valid_options: &["type", "inserttext"],
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
// === Scroll ===
|
||||
"scroll" => {
|
||||
|
||||
@@ -713,6 +713,11 @@ Global Options:
|
||||
Examples:
|
||||
agent-browser type "#search" "hello"
|
||||
agent-browser type @e2 "additional text"
|
||||
|
||||
See Also:
|
||||
For typing into contenteditable editors (Lexical, ProseMirror, etc.)
|
||||
without a selector, use 'keyboard type' instead:
|
||||
agent-browser keyboard type "# My Heading"
|
||||
"##
|
||||
}
|
||||
"hover" => {
|
||||
@@ -926,6 +931,42 @@ Examples:
|
||||
agent-browser keyup Control
|
||||
"##
|
||||
}
|
||||
"keyboard" => {
|
||||
r##"
|
||||
agent-browser keyboard - Raw keyboard input (no selector needed)
|
||||
|
||||
Usage: agent-browser keyboard <subcommand> <text>
|
||||
|
||||
Sends keyboard input to whatever element currently has focus.
|
||||
Unlike 'type' which requires a selector, 'keyboard' operates on
|
||||
the current focus — essential for contenteditable editors like
|
||||
Lexical, ProseMirror, CodeMirror, and Monaco.
|
||||
|
||||
Subcommands:
|
||||
type <text> Type text character-by-character with real
|
||||
key events (keydown, keypress, keyup per char)
|
||||
inserttext <text> Insert text without key events (like paste)
|
||||
|
||||
Note: For key combos (Enter, Control+a), use the 'press' command
|
||||
directly — it already operates on the current focus.
|
||||
|
||||
Global Options:
|
||||
--json Output as JSON
|
||||
--session <name> Use specific session
|
||||
|
||||
Examples:
|
||||
agent-browser keyboard type "Hello, World!"
|
||||
agent-browser keyboard type "# My Heading"
|
||||
agent-browser keyboard inserttext "pasted content"
|
||||
|
||||
Use Cases:
|
||||
# Type into a Lexical/ProseMirror contenteditable editor:
|
||||
agent-browser click "[contenteditable]"
|
||||
agent-browser keyboard type "# My Heading"
|
||||
agent-browser press Enter
|
||||
agent-browser keyboard type "Some paragraph text"
|
||||
"##
|
||||
}
|
||||
|
||||
// === Scroll ===
|
||||
"scroll" => {
|
||||
@@ -1958,6 +1999,8 @@ Core Commands:
|
||||
type <sel> <text> Type into element
|
||||
fill <sel> <text> Clear and fill
|
||||
press <key> Press key (Enter, Tab, Control+a)
|
||||
keyboard type <text> Type text with real keystrokes (no selector)
|
||||
keyboard inserttext <text> Insert text without key events
|
||||
hover <sel> Hover element
|
||||
focus <sel> Focus element
|
||||
check <sel> Check checkbox
|
||||
|
||||
Reference in New Issue
Block a user