VoiceOver and TalkBack accessibility validation
epic-structured-post-session-report-screen-task-007 — Perform structured accessibility testing of the complete post-session report screen on a physical iOS device using VoiceOver and on a physical Android device using TalkBack. Verify focus order, semantic labels on all interactive elements, live-region announcements for form validation errors and submission status, and that the draft indicator banner and session-lock message are correctly announced. Document all findings and fix any WCAG 2.2 AA violations.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 4 - 323 tasks
Can start after Tier 3 completes
Implementation Notes
Begin with Flutter's SemanticsDebugger (debugShowSemanticsNodes: true in MaterialApp) to inspect the semantic tree before physical device testing — catch obvious issues early. For dynamic form fields, the DynamicFieldRenderer must pass a semanticsLabel to each field widget based on the schema field's label property — never rely on placeholder text alone for semantic labelling. For live regions, use a dedicated LiveRegionAnnouncer utility that calls SemanticsService.announce() as a fallback for widgets that cannot use Semantics(liveRegion: true) directly (e.g., bottom sheets that are mounted after the triggering event). For focus order, use the FocusTraversalGroup widget to define explicit traversal order through the form sections (dynamic fields → way-forward section → submit button).
The draft indicator and session-lock banner must use Semantics(container: true, label: '...') so they are treated as standalone semantic nodes. Document each fix with a before/after description and the specific Semantics widget change applied.
Testing Requirements
Manual testing on physical devices is required — simulators do not accurately reproduce VoiceOver/TalkBack behaviour. iOS: iPhone running latest iOS with VoiceOver enabled; test all scenarios in the structured test script. Android: device running Android 13+ with TalkBack enabled; test all scenarios. Automated: flutter_test accessibility checks using tester.semantics and SemanticsHandle to verify semantic labels, live regions, and focus order in widget tests.
Use Flutter's built-in SemanticsDebugger overlay to inspect the accessibility tree during development. Document findings in a spreadsheet with columns: Element, Screen Reader, OS/Version, WCAG Criterion, Finding, Severity (A/AA/AAA), Status (Fixed/Deferred/Accepted).
End-to-end integration tests that span Flutter UI → Supabase → RLS → storage are inherently flaky in CI due to network timing, test database state, and Supabase cold-start latency. Flaky tests erode confidence and slow the release pipeline.
Mitigation & Contingency
Mitigation: Use a dedicated Supabase test project with seeded org and user fixtures. Wrap all E2E tests in retry logic with a fixed seed and tear-down hooks. Keep E2E tests in a separate test suite that runs on-demand rather than on every PR, with unit and widget tests as the primary CI gate.
Contingency: If E2E tests remain unreliable, replace the Supabase calls in integration tests with a verified fake (in-memory repository implementations) and promote the real Supabase tests to a nightly scheduled run rather than blocking PR merges.
Health status, course interest, and assistive device fields contain personal health data. If any logger, analytics event, or crash reporter captures field values — through automated error serialisation or developer-added debug logs — the feature could violate GDPR and Blindeforbundet's data processor agreement.
Mitigation & Contingency
Mitigation: Audit all log statements in the report feature's code paths before the epic is marked done. Apply a PII-safe logging wrapper that strips field values from any serialised form state before it reaches the logger. Add a CI lint rule that flags direct logger calls within report-related files.
Contingency: If PII is found in logs post-launch, immediately disable the affected logging call and rotate any credentials that were exposed. Notify the data protection officer and document the incident per GDPR Article 33 requirements.