Fix Enter key press not working by adding text field to keyDown events (#972)
This PR fixes an issue where pressing the Enter key via the `press Enter` command had no effect on web pages, even though the command executed successfully without errors. ## Problem The Chrome DevTools Protocol `Input.dispatchKeyEvent` requires a `text` field in `keyDown` events for certain keys to trigger their default browser actions. Without this field, keys like Enter don't actually submit forms or perform their expected actions. ## Changes - Added new `key_text()` function that returns the appropriate text value for special keys: - Enter returns `"\r"` (carriage return) - Tab returns `"\t"` (tab character) - Space returns `" "` (space character) - Single printable characters return themselves - Non-printable keys (Escape, Arrow keys, etc.) return `None` - Modified `press_key_with_modifiers()` to populate both `text` and `unmodified_text` fields in the CDP keyDown event - Added comprehensive unit tests for the new functionality ## Implementation Details The fix ensures that when pressing Enter on a filled search box, the form actually submits as expected, matching the behavior of manually pressing the Enter key. Fixes #966
This commit is contained in:
@@ -282,6 +282,7 @@ pub async fn press_key_with_modifiers(
|
||||
modifiers: Option<i32>,
|
||||
) -> Result<(), String> {
|
||||
let (key_name, code, key_code) = named_key_info(key);
|
||||
let text = key_text(&key_name);
|
||||
|
||||
client
|
||||
.send_command_typed::<_, Value>(
|
||||
@@ -290,8 +291,8 @@ pub async fn press_key_with_modifiers(
|
||||
event_type: "keyDown".to_string(),
|
||||
key: Some(key_name.clone()),
|
||||
code: Some(code.clone()),
|
||||
text: None,
|
||||
unmodified_text: None,
|
||||
text: text.clone(),
|
||||
unmodified_text: text.clone(),
|
||||
windows_virtual_key_code: Some(key_code),
|
||||
native_virtual_key_code: Some(key_code),
|
||||
modifiers,
|
||||
@@ -1000,6 +1001,26 @@ fn punctuation_key_info(ch: char) -> (&'static str, i32) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the `text` value that CDP `Input.dispatchKeyEvent` needs on the
|
||||
/// `keyDown` event so that Chrome performs the default action for the key.
|
||||
/// For example Enter needs `"\r"` to actually submit a form, and Tab needs
|
||||
/// `"\t"` to move focus. Non-printable / navigation keys return `None`.
|
||||
fn key_text(key_name: &str) -> Option<String> {
|
||||
match key_name {
|
||||
"Enter" => Some("\r".to_string()),
|
||||
"Tab" => Some("\t".to_string()),
|
||||
" " => Some(" ".to_string()),
|
||||
_ => {
|
||||
// Single printable characters carry themselves as text.
|
||||
if key_name.len() == 1 {
|
||||
Some(key_name.to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn named_key_info(key: &str) -> (String, String, i32) {
|
||||
match key.to_lowercase().as_str() {
|
||||
"enter" | "return" => ("Enter".to_string(), "Enter".to_string(), 13),
|
||||
@@ -1127,4 +1148,19 @@ mod tests {
|
||||
assert_eq!(key, ch.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_key_text_returns_correct_text_for_special_keys() {
|
||||
assert_eq!(key_text("Enter"), Some("\r".to_string()));
|
||||
assert_eq!(key_text("Tab"), Some("\t".to_string()));
|
||||
assert_eq!(key_text(" "), Some(" ".to_string()));
|
||||
// Single printable characters carry themselves.
|
||||
assert_eq!(key_text("a"), Some("a".to_string()));
|
||||
assert_eq!(key_text("Z"), Some("Z".to_string()));
|
||||
// Non-printable named keys return None.
|
||||
assert_eq!(key_text("Escape"), None);
|
||||
assert_eq!(key_text("ArrowUp"), None);
|
||||
assert_eq!(key_text("Backspace"), None);
|
||||
assert_eq!(key_text("Delete"), None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user