facett-filedialog/tests/a11y.rs
//! **FC-4/FC-5 interaction-layer proof for facett-filedialog.** Before FC-4 the
//! whole listing was painted on a single `Sense::hover()` alloc — selection was a
//! mere `rect_filled` accent — so zero accesskit nodes existed: a robot driver /
//! screen reader / `egui_kittest` `get_by_label` could see *none* of the file
//! rows, let alone which one was selected. This renders a real [`FileDialog`] over
//! a known injected listing through `egui_kittest`, marks one row selected, and
//! asserts:
//!
//! * every file/dir row rode in as a labelled `Role::Button` node retrievable by
//! its file name (egui's `SelectableLabel` maps to `accesskit::Role::Button`),
//! and
//! * the *selected* row reports `Toggled::True` while an unselected row does not —
//! the selection state is now real accessibility data, not just painted pixels.
//!
//! FC-5: the rows are keyed on the stable file *name* (the helper hashes `&e.name`,
//! not the loop index), so identity survives reorder/insert/delete.
use egui::accesskit::{Role, Toggled};
use egui_kittest::Harness;
use egui_kittest::kittest::{NodeT, Queryable};
use facett_core::Facet;
use facett_filedialog::{DialogMode, Entry, FileDialog};
#[test]
fn rows_expose_buttons_and_the_selected_row_reports_toggled_true() {
let mut d = FileDialog::new(DialogMode::OpenMany, "/proj");
// Inject a real listing (no disk): sorts dirs-first, then by name, so visible
// order is: src, Cargo.toml, readme.md.
d.set_entries(vec![Entry::file("readme.md"), Entry::dir("src"), Entry::file("Cargo.toml")]);
// Move the cursor off index 0 and onto the "Cargo.toml" file row (cursor 1),
// then toggle it into the multi-select picks so it is genuinely selected.
d.move_cursor(1); // src=0, Cargo.toml=1
d.toggle_pick(); // picks = ["Cargo.toml"]
let mut harness = Harness::new_ui(move |ui| {
d.ui(ui);
});
harness.run();
// (1) Every row rode in as a labelled Button node, findable by file name (FC-4).
for name in ["src", "Cargo.toml", "readme.md"] {
let node = harness.get_by_label(name).accesskit_node();
assert_eq!(node.role(), Role::Button, "row {name:?} must expose a Role::Button node (FC-4)");
}
// (2) The selected row (the picked "Cargo.toml", also the cursor) reports the
// selection as real accessibility data — Toggled::True.
let selected = harness.get_by_label("Cargo.toml").accesskit_node();
assert_eq!(
selected.toggled(),
Some(Toggled::True),
"the selected (picked + cursored) row must report Toggled::True (FC-4 selection)"
);
// (3) An unselected row must NOT report Toggled::True — proves the toggle is
// driven by real per-row state, not blanket-set.
let unselected = harness.get_by_label("readme.md").accesskit_node();
assert_ne!(
unselected.toggled(),
Some(Toggled::True),
"an unpicked, non-cursor row must not be reported as selected"
);
#[cfg(feature = "testmatrix")]
facett_core::testmatrix::emit(
"FileDialog",
"fc4_rows_and_selection",
selected.toggled() == Some(Toggled::True) && unselected.toggled() != Some(Toggled::True),
"Cargo.toml picked=Toggled::True, readme.md not selected",
);
}