#776: test that app shortcuts still run after a mouse click on a row

A mouse click gives a Project row no keyboard focus, and the arrow keys
only move keyboard focus when a row already had it, so Delete /
Backspace, Cmd+D and Enter keep working for mouse users, also after an
arrow key moved the selection. Pin that down with a headless test.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
vangel76andClaude Opus 5.5 committed 2026-10-11 12:58:03 +02:00
1 parent 132bd21078
commit 884cb9987b
1 file changed
+40
@@ -182,3 +182,43 @@ fn a_focused_row_keeps_the_arrows_and_focus_follows_the_selection() {
assert_eq!(selection(&h), vec![rows[0]]);
assert!(h.get_by_label(&names[0]).is_focused());
}
/// A mouse click on a row gives no keyboard focus to the row, so the app's shortcuts run as
/// before the arrow keys came: Delete / Backspace delete, Cmd+D duplicates, Enter renames, also
/// after an arrow key moved the selection.
#[test]
fn shortcuts_still_run_after_a_mouse_click_and_the_arrows() {
let focus = |h: &Harness<'_, EffectcraftApp>| h.ctx.memory(|m| m.focused());
for delete_key in [Key::Delete, Key::Backspace] {
let (mut h, folder, _, _) = harness();
let empty = ItemId(h.state_mut().session.execute("project.newFolder", json!({"name": "Empty"})).unwrap()["item"].as_u64().unwrap());
h.run_steps(2);
click(&mut h, &format!("project.item.{}.name", empty.0));
assert_eq!(selection(&h), vec![empty]);
assert_eq!(focus(&h), None, "a click gives the row no keyboard focus");
key(&mut h, delete_key, Modifiers::NONE);
assert!(h.state().session.project.item(empty).is_none(), "{delete_key:?} deletes the clicked item");
// Click, an arrow, then the shortcut.
let empty2 = ItemId(h.state_mut().session.execute("project.newFolder", json!({"name": "Empty 2"})).unwrap()["item"].as_u64().unwrap());
h.run_steps(2);
let rows = rows(&h);
let at = rows.iter().position(|r| *r == empty2).unwrap();
let from = if at > 0 { rows[at - 1] } else { rows[at + 1] };
click(&mut h, &format!("project.item.{}.name", from.0));
key(&mut h, if at > 0 { Key::ArrowDown } else { Key::ArrowUp }, Modifiers::NONE);
assert_eq!(selection(&h), vec![empty2]);
assert_eq!(focus(&h), None, "the arrows don't take keyboard focus after a click");
key(&mut h, delete_key, Modifiers::NONE);
assert!(h.state().session.project.item(empty2).is_none(), "{delete_key:?} deletes the item the arrow moved to");
assert!(h.state().session.project.item(folder).is_some());
}
let (mut h, folder, _, solid) = harness();
// Folders can't be duplicated (engine rule): duplicate the solid.
click(&mut h, &format!("project.item.{}.name", solid.0));
let n = h.state().session.project.items.len();
key(&mut h, Key::D, Modifiers::COMMAND);
assert_eq!(h.state().session.project.items.len(), n + 1, "Cmd+D duplicates the clicked item");
click(&mut h, &format!("project.item.{}.name", folder.0));
key(&mut h, Key::Enter, Modifiers::NONE);
assert!(h.state().auto.find(&format!("project.item.{}.nameEdit", folder.0)).is_some(), "Enter renames the clicked item");
}