high priority medium complexity testing pending testing specialist Tier 5

Acceptance Criteria

Integration test mounts a full ProviderScope with all five foundation providers registered (no overrides) and verifies no ProviderException is thrown
Test verifies SensitiveFieldConfigurationRegistry is readable and returns expected registered field configurations without error
Test verifies AccessibilitySettingsRepository emits an initial AccessibilitySettings value on first stream listen
Test verifies SemanticsServiceFacade can be read from the provider container and its interface methods are callable
Test verifies ScreenReaderDetectionService emits an initial ScreenReaderState value and re-evaluates when AccessibilityFeatures is changed via mock
Test mounts a SemanticsWrapperWidget within the full provider scope and verifies it reads from ScreenReaderDetectionService (active state) and AccessibilitySettingsRepository (preferences)
Test verifies that changing AccessibilitySettings in the repository causes SemanticsWrapperWidget to rebuild with updated semantics
Test verifies that a simulated screen reader activation (via mock WidgetsBinding) causes SemanticsWrapperWidget to transition from no-semantics to semantics-wrapped mode
All five provider dependency edges are confirmed (no missing dependencies, no circular dependencies)
Tests are located in integration_test/ or test/integration/ and clearly labelled as integration tests

Technical Requirements

frameworks
Flutter
flutter_test
Riverpod
apis
ProviderScope
ProviderContainer
ProviderObserver
WidgetsBinding mock
AccessibilityFeatures
StreamController
data models
AccessibilitySettings
ScreenReaderState
SensitiveFieldConfig
performance requirements
Full integration test suite completes within 30 seconds
No network calls; all Supabase dependencies must be mocked or disabled
security requirements
Supabase client must be mocked to prevent real data access during tests
No real BankID or Vipps calls; stub authentication layer
ui components
SemanticsWrapperWidget
Test harness app widget

Execution Context

Execution Tier
Tier 5

Tier 5 - 253 tasks

Can start after Tier 4 completes

Implementation Notes

The key challenge in this integration test is isolating Flutter's WidgetsBinding while still testing real provider wiring. Use TestWidgetsFlutterBinding (automatically set by flutter_test) and create a FakeAccessibilityFeatures helper that allows toggling screen reader state in tests. For Supabase, inject a FakeSupabaseClient that returns empty streams and no-op operations. For ScreenReaderDetectionService, the service should be wired through its Riverpod provider so the test verifies the actual provider graph, not just the service in isolation.

The integration test should be the single authoritative test confirming 'all five components work together correctly', forming a regression baseline for future epics that build on this foundation.

Testing Requirements

Use flutter_test with testWidgets() for widget-mounted integration tests. Create a TestApp widget that wraps content in ProviderScope with the real provider graph (no overrides except WidgetsBinding and Supabase). Use a ProviderObserver to detect any unhandled provider errors during the test. For stream assertions, use tester.pump() to advance the frame and then read the provider's current value using ProviderContainer.read().

For wiring verification, use ProviderContainer.listen() to subscribe to each provider's stream and assert at least one emission. For the SemanticsWrapperWidget wiring test, use tester.ensureSemantics() and assert semantics node presence/absence based on screen reader state changes. Organise tests as individual testWidgets() blocks, one per foundation component, plus one end-to-end wiring test.

Component
Semantics Wrapper Widget
ui medium
Dependencies (5)
Write unit tests for SemanticsServiceFacade covering announcement queuing, priority handling, mock injection, and locale handling. Verify the facade correctly abstracts platform differences between iOS VoiceOver and Android TalkBack announcement APIs using Flutter test framework. epic-screen-reader-support-foundation-task-006 Write tests for ScreenReaderDetectionService covering initial detection, foreground re-evaluation, stream emission on state change, and correct platform differentiation. Use Flutter test framework with mock AccessibilityFeatures to simulate VoiceOver and TalkBack states. epic-screen-reader-support-foundation-task-008 Write comprehensive widget tests for SemanticsWrapperWidget verifying correct semantic label assignment, role attribution, state flags, decorative exclusion, dynamic label resolution, and interaction with screen reader detection state. Use flutter_test SemanticsController to assert semantics tree correctness. epic-screen-reader-support-foundation-task-011 Implement the SensitiveFieldConfigurationRegistry class with runtime-updatable field registration, lookup API (isSensitive(fieldId), getWarningKey(fieldId)), and default configuration seeded with known sensitive fields (personnummer, full name, address, health data). Expose as a Riverpod provider. epic-screen-reader-support-foundation-task-002 Implement the AccessibilitySettingsRepository backed by SharedPreferences or Hive. Expose a Stream<AccessibilitySettings> for reactive updates, plus synchronous read and async write methods. Ensure settings persist across app restarts and are loaded at startup. Register as a Riverpod StreamProvider. epic-screen-reader-support-foundation-task-004
Epic Risks (2)
high impact medium prob technical

Flutter's SemanticsService behaves differently between iOS (VoiceOver) and Android (TalkBack) in edge cases — e.g., announcement queuing, focus-gain timing, and attribute support. If the facade does not correctly abstract these differences, announcements may be silent or misfired on one platform, causing regression on the other platform to go unnoticed until device testing.

Mitigation & Contingency

Mitigation: Write platform-divergence unit tests early using SemanticsServiceFacade mocks. Validate announcement delivery on a physical iPhone (VoiceOver) and Android device (TalkBack) at the end of each sprint. Document known platform differences in the facade's inline API comments.

Contingency: If a platform difference cannot be abstracted cleanly, expose a platform-specific override path in the facade and implement targeted workarounds per platform, accepting the added complexity in exchange for correct behaviour.

medium impact medium prob scope

Accessibility preferences stored in local storage may need new fields as higher-tier epics are implemented (e.g., announcement verbosity, sensitive-field guard toggle). Schema changes to an already-persisted store risk data migration failures or silent defaults on existing installs, breaking user preferences.

Mitigation & Contingency

Mitigation: Design the AccessibilitySettingsRepository with a versioned JSON schema from the start, using merge-with-defaults on read so new fields fall back gracefully. Define the full expected field list upfront based on all downstream epic requirements before writing the first record.

Contingency: If migration fails on a live install, fall back to full reset-to-defaults with a one-time in-app notification informing the user that accessibility preferences have been reset and inviting them to reconfigure.