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

nordisk/facett

facett-table/tests/a11y.rs

//! **FC-4 / FC-5 proof for `facett-table`.** Render a real [`Table`] with rows,
//! select one through the real selection API, render it headless under
//! `egui_kittest`, and assert the *selected row* rides into the AccessKit tree as
//! a queryable, `Toggled::True` node — and that an *unselected* row reports
//! `Toggled::False`.
//!
//! Why the `"row: …"` label prefix: egui_extras already emits an AccessKit node
//! per *cell* (so the cell text "knut" is itself queryable). If the row node used
//! the bare identity it could collide with a cell's text and make `get_by_label`
//! ambiguous. Prefixing with `"row: "` gives the row node an unambiguous label
//! distinct from every cell, so the selection toggle is addressable on its own.

use egui::accesskit::{Role, Toggled};
use egui_kittest::Harness;
use egui_kittest::kittest::{NodeT, Queryable};

use facett_core::Facet;
use facett_table::Table;

/// A 2-column, 2-row table with stable RowIds (FC-5), row 1 pre-selected.
fn selected_table() -> Table {
    let mut t = Table::new("repos", vec!["name".into(), "version".into()])
        .with_row_ids(vec!["pkg-knut".into(), "pkg-korp".into()]);
    t.push_row(vec!["knut".into(), "0.1".into()]);
    t.push_row(vec!["korp".into(), "0.2".into()]);
    t.select_row(1); // real selection API selects the second row
    t
}

#[test]
fn selected_row_reports_toggled_true_in_accesskit_tree() {
    let mut table = selected_table();
    // Sanity: the real selection state is what we think it is before rendering.
    assert_eq!(table.selected_rows(), vec![1]);

    let mut harness = Harness::new_ui(move |ui| {
        table.ui(ui);
    });
    harness.run();

    // The SELECTED row (RowId "pkg-korp") is queryable by its prefixed label and
    // reports its selection as Toggled::True — the FC-4 gap this fix closes.
    let selected = harness.get_by_label("row: pkg-korp").accesskit_node();
    // egui maps WidgetType::SelectableLabel → Role::Button (a togglable button).
    assert_eq!(selected.role(), Role::Button, "selectable-label row maps to a Button role");
    assert_eq!(
        selected.toggled(),
        Some(Toggled::True),
        "the selected row must surface Toggled::True so a driver/screen reader can read it"
    );

    // The UNSELECTED row is also addressable and reports Toggled::False.
    let unselected = harness.get_by_label("row: pkg-knut").accesskit_node();
    assert_eq!(unselected.toggled(), Some(Toggled::False), "unselected row must report Toggled::False");
    // Feed the matrix: ok iff selection rides into the a11y tree (FC-4/FC-5).
    #[cfg(feature = "testmatrix")]
    facett_core::testmatrix::emit(
        "Table",
        "fc4_selected_row_toggle",
        selected.toggled() == Some(Toggled::True) && unselected.toggled() == Some(Toggled::False),
        "selected=Toggled::True, unselected=Toggled::False",
    );
}

#[test]
fn row_node_label_does_not_collide_with_cell_text() {
    // Without RowIds the identity is the index; the cell text ("knut") still has
    // its own node, and the row node ("row: 0") is a distinct, unambiguous label.
    let mut table = Table::new("repos", vec!["name".into()]);
    table.push_row(vec!["knut".into()]);
    table.select_row(0);

    let mut harness = Harness::new_ui(move |ui| {
        table.ui(ui);
    });
    harness.run();

    // The cell text is queryable on its own (emitted by egui_extras)…
    let _cell = harness.get_by_label("knut");
    // …and the ROW node is a separate, selected node keyed on the index identity.
    let row = harness.get_by_label("row: 0").accesskit_node();
    assert_eq!(row.toggled(), Some(Toggled::True));
    // Feed the matrix: ok iff the row node label is distinct from cell text (FC-5).
    #[cfg(feature = "testmatrix")]
    facett_core::testmatrix::emit(
        "Table",
        "fc5_row_label_no_collision",
        row.toggled() == Some(Toggled::True),
        "row: 0 node distinct from cell 'knut', Toggled::True",
    );
}