Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

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",
    );
}