scope collapser-card semantics exclusion to the header (T-370)

The summarized button semantics (label, expanded/collapsed state)
wrapped the entire card with excludeSemantics, so every expanded
child vanished from the a11y tree — a screen-reader user could expand
a run and hear nothing inside it. The exclusion now wraps only the
header (ticker when collapsed, header row when expanded); inner item
cards stay readable, and the redundant background-toggle tappable is
explicitly excluded so the header stays the single AT stop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 00:47:06 +02:00
co-authored by Claude Fable 5
parent 664a8da72e
commit 77c4341318
5 changed files with 67 additions and 19 deletions
@@ -155,6 +155,25 @@ void main() {
);
});
// T-370: the summarized button semantics used to wrap the WHOLE card with
// excludeSemantics, wiping every expanded child from the a11y tree — a
// screen-reader user could expand a run and hear nothing inside it.
testWidgets('expanded children are present in the semantics tree (T-370)', (tester) async {
final handle = tester.ensureSemantics();
await pump(tester, expanded: true);
expect(find.bySemanticsLabel('Edits, 3 edits, expanded'), findsOneWidget);
expect(find.bySemanticsLabel('item body'), findsOneWidget, reason: 'expanded content must be readable by AT');
handle.dispose();
});
testWidgets('collapsed children are absent from the semantics tree, header summarizes (T-370)', (tester) async {
final handle = tester.ensureSemantics();
await pump(tester);
expect(find.bySemanticsLabel('Edits, 3 edits, collapsed'), findsOneWidget);
expect(find.bySemanticsLabel('item body'), findsNothing);
handle.dispose();
});
testWidgets('no counter + no status renders a bare ticker without error', (tester) async {
await pump(tester, counter: null, status: null, summary: null);
expect(find.text('Edits'), findsOneWidget);