Implement Switch Access traversal order simulation
epic-navigation-and-gesture-accessibility-service-and-audit-task-008 — Implement the Switch Access traversal simulation in AccessibilityAuditRunner using Flutter's SemanticsController to enumerate the semantics tree in traversal order for key flows (activity registration wizard, contact detail, navigation tabs). Assert that traversal order is logical and no interactive element is unreachable. Record all traversal violations in the audit result model.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 2 - 518 tasks
Can start after Tier 1 completes
Implementation Notes
Use WidgetTester.semantics to get the root SemanticsNode, then walk the tree using SemanticsNode.childrenInTraversalOrder. For 'unreachable' detection, build a directed graph from traversal order and run a reachability check from the root. For 'illogical order' detection, sort nodes by (rect.top, rect.left) and compare against traversal order — flag nodes whose position deviates by more than one position from the sorted baseline. Ensure the wizard screens are pumped with all required BLoC/Riverpod providers before traversal.
Use tester.pumpAndSettle() with a timeout before each traversal capture. Model SwitchAccessTraversalViolation as a freezed data class for immutability and easy JSON serialization. This audit is especially critical for Blindeforbundet and NHF users who rely on switch access due to motor or visual impairments.
Testing Requirements
Unit tests: verify SwitchAccessTraversalViolation model serializes/deserializes correctly; verify traversal order comparator logic with hand-crafted node trees. Integration tests: run the audit on a real widget tree pumped in flutter_test — assert zero violations on a known-good scaffold, assert expected violations on a deliberately broken scaffold (orphaned node, reversed order). Test coverage target: 90% of traversal enumeration logic. Key scenario: inject a semantics node with no predecessor link and assert it is detected as unreachable.
Flutter's SemanticsController used in integration tests is an internal or semi-internal API that can break between Flutter stable releases. If the audit runner relies heavily on undocumented semantics tree traversal, a Flutter upgrade could silently disable the audit checks without a build failure, creating false confidence.
Mitigation & Contingency
Mitigation: Use only the public flutter_test accessibility APIs (meetsGuideline, SemanticsController.ensureSemantics) and wrap all SemanticsController calls in a versioned helper class with explicit assertions that the expected semantics tree shape is still available. Pin the Flutter SDK range in pubspec.yaml.
Contingency: If SemanticsController APIs break on a Flutter upgrade, fall back to widget-level golden tests that include the semantics tree snapshot, combined with manual Switch Access and VoiceOver QA checklists executed before each release.
Flutter integration tests that simulate Switch Access traversal on multiple screens can be slow (30–120 seconds per test flow), which may make the audit runner impractical to run on every CI commit if the test suite already has long run times.
Mitigation & Contingency
Mitigation: Scope the audit runner to a dedicated integration test target that runs on pull requests targeting main and on nightly builds, not on every push. Parallelise test shards in CI to keep wall-clock time acceptable. Profile audit run times during development and trim any flows that duplicate coverage.
Contingency: If CI run times exceed acceptable thresholds, split the audit runner into a fast smoke suite (touch targets and semantic labels only, runs on every PR) and a thorough traversal suite (Switch Access simulation, runs nightly), with the nightly failure blocking the release branch rather than every PR.