facett-geomap/tests/a11y.rs
//! **FC-4 interaction-layer proof for `facett-geomap`.** Build a real `GeoMap`
//! (Swedish points + two named hotspots), render it headless through
//! `egui_kittest`, and assert the AccessKit tree carries:
//!
//! 1. the **pane summary** node — an `Image` role whose label names the title +
//! both layer counts and whose `numeric_value` is the point count, and
//! 2. one **per-hotspot** node — a `Button` role whose label is `"{label} ·
//! {count} points"` and whose `numeric_value` is the hotspot count.
//!
//! If a robot driver / screen reader / `get_by_label` can find these, the
//! custom-painted geomap is FC-4 compliant. (Before the fix the pane had a
//! `Sense::click_and_drag()` response but **no** `widget_info`, and the painted
//! hotspots emitted zero accessibility nodes.)
//!
//! Run: `cargo test -p facett-geomap --test a11y`
use std::cell::RefCell;
use egui::accesskit::Role;
use egui_kittest::Harness;
use egui_kittest::kittest::{NodeT, Queryable};
use facett_core::Facet;
use facett_geomap::{GeoMap, Hotspot};
#[test]
fn pane_summary_and_hotspot_nodes_are_queryable() {
// Inject real input: 4 Swedish points + two named hotspots (Malmö, Göteborg).
let map = RefCell::new(GeoMap::new(
"Sweden",
vec![
(18.0686, 59.3293), // Stockholm
(11.9746, 57.7089), // Göteborg
(13.0038, 55.6050), // Malmö
(17.6389, 59.8586), // Uppsala
],
vec![
Hotspot::new(13.0038, 55.6050, 320, "Malmö"),
Hotspot::new(11.9746, 57.7089, 210, "Göteborg"),
],
));
let mut harness = Harness::new_ui(|ui| {
map.borrow_mut().ui(ui);
});
harness.run();
// ── 1. the pane summary node: title + all layer counts, value = points ──
let pane = harness
.get_by_label("Sweden — 4 points · 2 hotspots · 0 basemap ways")
.accesskit_node();
assert_eq!(pane.role(), Role::Image, "the whole geomap pane is an Image-role summary node");
assert_eq!(
pane.numeric_value(),
Some(4.0),
"pane numeric_value must be the point count (4), read back exactly"
);
// ── 2. a per-hotspot node: "{label} · {count} points", value = count ─────
let malmo = harness.get_by_label("Malmö · 320 points").accesskit_node();
assert_eq!(malmo.role(), Role::Button, "each hotspot is a clickable Button node");
assert_eq!(
malmo.numeric_value(),
Some(320.0),
"hotspot numeric_value must be its count (320)"
);
// the second hotspot is independently queryable too.
let goteborg = harness.get_by_label("Göteborg · 210 points").accesskit_node();
assert_eq!(goteborg.role(), Role::Button);
assert_eq!(goteborg.numeric_value(), Some(210.0), "second hotspot count rides in too");
// Feed the matrix: ok iff the FC-4 a11y nodes are queryable with the right
// values (pane=4 points, Malmö=320, Göteborg=210).
#[cfg(feature = "testmatrix")]
facett_core::testmatrix::emit(
"GeoMap",
"fc4_accesskit_nodes",
pane.numeric_value() == Some(4.0)
&& malmo.numeric_value() == Some(320.0)
&& goteborg.numeric_value() == Some(210.0),
"pane=4 points, hotspots Malmö=320 / Göteborg=210 queryable",
);
}