medium priority low complexity testing pending testing specialist Tier 2

Acceptance Criteria

Widget test verifies that the Semantics node for the error headline has a non-empty `label` matching the resolved headline string
Widget test verifies that the Semantics node for the action string has a non-empty `label` matching the resolved action string
Widget test verifies that the outermost Semantics wrapper has `liveRegion: true` so VoiceOver/TalkBack announces changes automatically
Widget test verifies that when `errorCode` changes from null to a valid code, the liveRegion Semantics node is present in the updated tree
Widget test verifies that the two-part layout (headline above, action below) renders correctly with a short headline (<20 chars) and a long action string (>100 chars) without overflow
Golden test captures the collapsed/error-visible state and is committed to `test/goldens/plain_language_error_display/`
ContrastRatioValidator (or equivalent utility) confirms error text color vs. background color meets WCAG 2.2 AA minimum ratio of 4.5:1 for normal text
All tests pass with `flutter test --update-goldens` on first run and `flutter test` on subsequent runs without golden mismatches
No test uses `sleep()` or arbitrary `Future.delayed` — all async settling done via `tester.pumpAndSettle()`
Test file named `plain_language_error_display_accessibility_test.dart` and located under `test/widgets/accessibility/`

Technical Requirements

frameworks
Flutter
flutter_test
apis
Semantics (Flutter framework)
ContrastRatioValidator (internal)
SemanticsHandle (flutter_test)
data models
accessibility_preferences
performance requirements
All widget tests must complete in under 5 seconds total on CI hardware
Golden images must be committed at 1x device pixel ratio to minimize binary diff size in git
security requirements
Test fixtures must not contain real user PII — use synthetic error codes and placeholder messages only
ui components
PlainLanguageErrorDisplay

Execution Context

Execution Tier
Tier 2

Tier 2 - 518 tasks

Can start after Tier 1 completes

Implementation Notes

Use `tester.ensureSemantics()` at the top of each Semantics test and store the handle to dispose at teardown — forgetting this causes test pollution. For the liveRegion test, wrap the widget in a `StatefulBuilder` so you can call `setState(() => errorCode = 'some-code')` and then `pumpAndSettle()` to trigger the update. For contrast ratio, extract the foreground and background Color values from the app's design token constants (do not hardcode hex values in tests — reference the same source tokens the widget uses so the test breaks if tokens change). Golden tests should be run with `--tags golden` and excluded from the default test run to avoid CI flakiness from font rendering differences across platforms — configure this in `dart_test.yaml`.

Testing Requirements

This task IS the testing task. Tests required: (1) Semantics label unit tests for headline and action nodes using `tester.getSemantics(find.byType(PlainLanguageErrorDisplay))` and `SemanticsController`; (2) liveRegion assertion test — enable semantics with `tester.ensureSemantics()`, trigger error code change, pump, assert `SemanticsNode.hasFlag(SemanticsFlag.isLiveRegion)`; (3) layout overflow tests with `tester.pumpWidget()` wrapped in a constrained box at 320dp wide; (4) golden tests via `matchesGoldenFile()`; (5) contrast ratio assertion using design token color values. Coverage target: 100% of PlainLanguageErrorDisplay widget code paths exercised by this test file.

Component
Plain Language Error Display
ui low
Epic Risks (4)
high impact medium prob technical

The WizardStateManager BLoC must guarantee that step transitions only occur on explicit user action, never automatically. Subtle reactive patterns in Bloc (e.g. stream listeners triggering add() calls) could inadvertently auto-advance the wizard, violating the core cognitive accessibility rule and creating a regression that is difficult to detect without dedicated tests.

Mitigation & Contingency

Mitigation: Write a dedicated unit test that subscribes to the BLoC stream and asserts no StepChanged event is emitted for 5 seconds after a state update, without an explicit user-sourced event being dispatched. Make this test part of the CI gate for the WizardStateManager.

Contingency: If an auto-advance regression is discovered post-integration, introduce a mandatory UserActionToken parameter on all step-transition events so the BLoC can structurally refuse transitions that do not originate from a user gesture handler.

medium impact medium prob integration

The ConfirmBeforeSubmitScreen requires deep-linking back to specific wizard steps for corrections. Implementing bidirectional navigation within a multi-step wizard while preserving all previously entered state is architecturally non-trivial and may conflict with the existing StatefulShellRoute navigation setup described in the app architecture.

Mitigation & Contingency

Mitigation: Design the ConfirmBeforeSubmitScreen's back-navigation links to dispatch a GoToStep event on the WizardStateManager rather than using GoRouter's pop() chain. This keeps navigation state entirely in the BLoC and avoids coupling to the router's stack semantics.

Contingency: If BLoC-driven step navigation proves incompatible with the router, implement the correction flow as a dedicated sub-route that pre-populates its form from the WizardStateManager's current draft, then merges the edited field back into the draft on completion before returning to the confirm screen.

medium impact medium prob technical

The CognitiveAccessibilityAudit utility must inspect live widget trees for violations such as icon-only buttons. Flutter's widget tree inspection APIs are available in test mode but have limitations in identifying semantic intent (e.g. distinguishing a decorative icon from a navigation button). False negatives could give a false sense of compliance.

Mitigation & Contingency

Mitigation: Augment the audit with a convention-based approach: require all navigation buttons to use a named wrapper widget (e.g. LabelledNavigationButton) that the audit can detect by type, rather than relying solely on widget-tree semantics analysis.

Contingency: If widget-tree detection proves insufficiently reliable, scope the CognitiveAccessibilityAudit to route-configuration analysis (verifying back navigation availability per route) and static analysis of wizard step count definitions via the CognitiveLoadRuleEngine, which provides deterministic results.

low impact high prob scope

The InlineContextualHelpWidget sources content from a bundled JSON asset via the HelpContentRegistry. If help texts are missing for newly added screens or fields (a likely scenario as the 61-feature app grows), the widget silently shows nothing, degrading the accessibility experience without any visible failure.

Mitigation & Contingency

Mitigation: Integrate a CognitiveAccessibilityAudit check that verifies every registered (screenId, fieldId) pair that requests help has a corresponding entry in the HelpContentRegistry bundle. Run this check in CI as part of the audit report.

Contingency: Add a debug-mode overlay that highlights fields with missing help entries using a visible warning indicator, making coverage gaps immediately obvious to developers during local development before they reach CI.