high priority high complexity testing pending testing specialist Tier 2

Acceptance Criteria

AccessibilityAuditRunner.runSwitchAccessTraversalAudit() enumerates all SemanticsNode instances in traversal order for the activity registration wizard (all 5 steps), contact detail screen, and bottom navigation tabs
Traversal order follows a logical top-left to bottom-right reading order with no jumps that would confuse switch access users
Every interactive element (buttons, text fields, dropdowns, toggles) present in the UI is reachable via sequential switch access traversal — no orphaned nodes
Each SwitchAccessTraversalViolation record captures: violationType (unreachable | illogical_order), routeName, semanticsNodeId, nodeLabel, nodeRect, and a human-readable description
The audit covers at minimum: activity type selection screen, all wizard steps (contact → date → time → duration → summary), contact detail screen, and all 5 bottom navigation tabs
A traversal with zero logical violations produces an empty violations list and exits with success status
The audit runner correctly handles dynamic content (e.g., conditional wizard fields) by waiting for widget settle before traversal enumeration
The implementation does not depend on platform-specific accessibility APIs — uses only Flutter SemanticsController available in flutter_test

Technical Requirements

frameworks
Flutter
flutter_test
flutter_driver (if needed for integration context)
apis
SemanticsController (flutter_test)
WidgetTester.semantics
SemanticsNode.rect
SemanticsNode.isInvisibleToUser
SemanticsNode.hasFlag(SemanticsFlag.isEnabled)
data models
SwitchAccessTraversalViolation
AccessibilityAuditResult
NavigationState
performance requirements
Full traversal audit for all three key flows must complete within 30 seconds on CI hardware
Semantics tree enumeration must not cause widget rebuilds or side effects
security requirements
Audit runner must not log or persist any personally identifiable information encountered in semantics labels
Test fixtures must use anonymized mock data
ui components
ActivityWizard
ContactDetailScreen
BottomNavigationBar

Execution Context

Execution Tier
Tier 2

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.

Component
Accessibility Audit Runner
infrastructure medium
Epic Risks (2)
high impact medium prob dependency

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.

low impact medium prob resource

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.