critical priority medium complexity testing pending testing specialist Tier 8

Acceptance Criteria

Screen title 'Sign in' (or localised equivalent) is annotated with Semantics(header: true) and announced as a heading by both VoiceOver and TalkBack
Email TextField has Semantics label 'Email address' and textField role; hint describes expected format
Password TextField has Semantics label 'Password' and textField role; hint describes minimum requirements if applicable
PasswordVisibilityToggle has Semantics(button: true) with label 'Show password' / 'Hide password' toggling correctly on state change
Submit button has Semantics label 'Sign in' and correct enabled/disabled state reflected in Semantics(enabled:)
Focus order on iOS VoiceOver: screen title → email field → password field → visibility toggle → submit button → forgot password link
Focus order on Android TalkBack matches the same logical order as VoiceOver
Error banner (from task-009) is announced immediately via liveRegion when it appears — no manual focus movement required
Loading indicator during authentication has Semantics label 'Signing in, please wait' to avoid silent spinner
No Semantics node has an empty label where a label is expected
All interactive elements have a minimum touch target of 48×48 logical pixels as verified by Semantics tree inspection
Audit findings documented with before/after diff of Semantics annotations changed

Technical Requirements

frameworks
Flutter
flutter_test (SemanticsController)
Semantics widget
performance requirements
Semantic tree updates synchronously with widget state changes — no deferred announcements
security requirements
Password field must not expose its value in the Semantics tree (obscureText: true inherently prevents this in Flutter, but verify)
Error messages announced via liveRegion must not include raw error codes or internal identifiers
ui components
Semantics widget (label, hint, button, textField, header, liveRegion, enabled properties)
MergeSemantics / ExcludeSemantics where appropriate
All three components: PasswordVisibilityToggle, LoginForm, LoginScreen

Execution Context

Execution Tier
Tier 8

Tier 8 - 48 tasks

Can start after Tier 7 completes

Implementation Notes

Start with tester.ensureSemantics() in a dedicated audit test file to enumerate the full Semantics tree programmatically — this surfaces all nodes including those lacking labels. For PasswordVisibilityToggle, the IconButton's tooltip property alone is insufficient for accessibility on all platforms; wrap with explicit Semantics(label: obscureText ? 'Show password' : 'Hide password', button: true, excludeSemantics: true) to override. For the screen heading, use Semantics(header: true) on the Text widget or its parent, not on the Scaffold.

The liveRegion on the error banner (from task-009) should be validated here — insert the error state via BLoC mock and assert SemanticsNode.hasFlag(SemanticsFlag.isLiveRegion). On iOS, VoiceOver reads 'obscured text field' for password inputs automatically if obscureText is true — do not re-annotate this. Prioritise fixes in this order: missing labels → wrong roles → incorrect focus order → live region validation. WCAG 2.2 AA compliance is a hard requirement for this project given the accessibility-first mandate from all partner organisations.

Testing Requirements

Automated widget tests using flutter_test SemanticsController: (1) tester.ensureSemantics() enabled; (2) find each expected Semantics node by label and assert correct flags (isButton, isTextField, isHeader, hasLiveRegion); (3) assert focus order via SemanticsController.simulateTap and expectation on next focusable node. Manual device testing required: run on physical iPhone (VoiceOver) and physical Android device (TalkBack) and step through all interactive elements recording any announcement gaps. Document each finding with component name, property affected, before value, after value. Regression test: re-run all existing widget tests after annotation fixes to ensure no layout or functional regressions.

Component
Login Screen
ui low
Epic Risks (3)
high impact medium prob scope

Automated accessibility checks (e.g., flutter_accessibility_service) may pass while manual VoiceOver/TalkBack testing reveals focus-order issues, missing semantic roles, or live region announcements that fire too early or not at all. Discovering these late risks delaying the MVP release.

Mitigation & Contingency

Mitigation: Conduct manual VoiceOver and TalkBack testing on physical devices at the end of every sprint, not only at release. Define accessibility acceptance criteria per component and include them in the DoD. Use Semantics widgets explicitly rather than relying on implicit semantics from Flutter's default widgets for all interactive elements.

Contingency: Maintain a prioritized accessibility bug backlog separate from the main backlog. If critical VoiceOver issues are found close to release, create an explicit accessibility hotfix sprint before TestFlight distribution to Blindeforbundet testers.

medium impact medium prob technical

Keyboard height varies significantly between iOS and Android, between device sizes (iPhone SE vs iPad), and with third-party keyboards. The KeyboardAwareLayout may not correctly adjust scroll offset in all combinations, causing input fields to remain hidden behind the keyboard on certain device/keyboard configurations.

Mitigation & Contingency

Mitigation: Test on a matrix of devices including iPhone SE (small viewport), a mid-size Android phone, and a tablet. Implement the layout using MediaQuery.viewInsets.bottom rather than a fixed padding value to correctly respond to any keyboard height. Include edge cases for floating keyboards on iPads.

Contingency: If device-specific issues are found after release, implement a bottom-padding fallback using BottomPadding inset and allow users to manually scroll. Log affected device/OS combinations for targeted fixes.

high impact low prob dependency

If the design token system's colour palette is updated without re-running contrast validation, form field labels, error messages, or placeholder text could fall below the WCAG 2.2 AA 4.5:1 ratio, causing a compliance regression.

Mitigation & Contingency

Mitigation: Integrate a contrast ratio validator (e.g., a CI lint step using the contrast-ratio-validator component) that checks all colour pairs used in the login form on every pull request. Document which token pairs are used for labels, errors, and backgrounds in the login form.

Contingency: If a contrast regression is detected post-merge, hot-patch the affected design token value. Do not ship a TestFlight build with known WCAG AA failures to Blindeforbundet testers.