Coverage lane 5 (#250) — instrumented Compose UI/E2E tests for the ui/** view layer, covering five screens that had no UI test, following the lane 3 (PR #270) pattern.
Screens covered
OutboxScreen (OutboxScreenTest): empty state (no retry action), queued-vs-failed row rendering, retry action calls back into the repo, cancel removes the row and records the cancellation.
DraftsScreen (DraftsScreenTest): empty state, subject/recipient/body rendering + blank-field fallbacks, opening a draft, delete removes the row and records the deletion.
ProblemReportsScreen (ProblemReportsScreenTest): empty state with the always-present create button + auto-delete notice, crash/manual kind rows, opening a report, and the create-manual-report → open-for-review flow — driven by a real file-backed ReportStore (temp dir) + real DiagnosticsCollector.
AccountPickerScreen (AccountPickerScreenTest): the onboarding/login vendor picker — every setup choice is listed, tapping an app-password vendor routes with the right MailProvider, tapping "Other" routes to manual setup (Outlook row deliberately not tapped — it launches a browser).
SignaturesScreen (SignaturesScreenTest): empty state, name + single default-badge rendering, making another signature the default (radio → DB round-trip via a real in-memory Room DB + SignatureRepository), and delete removes the row.
Also extends the shared FakeMailRepository to back observeOutbox()/observeDrafts() with mutable state and record cancel/retry, so the screens' actions are exercised end to end. No production code changed.
Emulator: one honest local run was attempted on a hand-provisioned api36 cold-boot emulator; the device wedged offline mid-run (the known local-emulator instability, #269 — not a test defect). CI runs the full multi-API E2E matrix and is the reliable validator here.
Remaining (follow-up)
#250 is broad; this PR takes the five highest-value untested screens. Still uncovered by a dedicated UI test (mostly OAuth/permission-launcher or trivial static screens): AppPasswordSetupScreen, AddAnotherAccountScreen, LockScreen, SignatureEditScreen, ReportReviewScreen, and the compose/formatColorSwatch/ColorSwatchRow components. Existing tests already cover Mailbox, Reader, Compose, Settings, AccountSettings, ManualSetup, FolderDrawer, and the onboarding steps.
Closes #250
Coverage lane 5 (#250) — instrumented Compose UI/E2E tests for the `ui/**` view layer, covering five screens that had **no** UI test, following the lane 3 (PR #270) pattern.
## Screens covered
- **OutboxScreen** (`OutboxScreenTest`): empty state (no retry action), queued-vs-failed row rendering, retry action calls back into the repo, cancel removes the row and records the cancellation.
- **DraftsScreen** (`DraftsScreenTest`): empty state, subject/recipient/body rendering + blank-field fallbacks, opening a draft, delete removes the row and records the deletion.
- **ProblemReportsScreen** (`ProblemReportsScreenTest`): empty state with the always-present create button + auto-delete notice, crash/manual kind rows, opening a report, and the create-manual-report → open-for-review flow — driven by a real file-backed `ReportStore` (temp dir) + real `DiagnosticsCollector`.
- **AccountPickerScreen** (`AccountPickerScreenTest`): the onboarding/login vendor picker — every setup choice is listed, tapping an app-password vendor routes with the right `MailProvider`, tapping "Other" routes to manual setup (Outlook row deliberately not tapped — it launches a browser).
- **SignaturesScreen** (`SignaturesScreenTest`): empty state, name + single default-badge rendering, making another signature the default (radio → DB round-trip via a real in-memory Room DB + `SignatureRepository`), and delete removes the row.
Also extends the shared `FakeMailRepository` to back `observeOutbox()`/`observeDrafts()` with mutable state and record cancel/retry, so the screens' actions are exercised end to end. No production code changed.
## Validation
- **Always-green gate:** `:app:compileDebugAndroidTestKotlin` + `:app:ktlintCheck` + `:app:detekt` — all pass locally (JDK 21).
- **Emulator:** one honest local run was attempted on a hand-provisioned api36 cold-boot emulator; the device wedged offline mid-run (the known local-emulator instability, #269 — not a test defect). **CI runs the full multi-API E2E matrix** and is the reliable validator here.
## Remaining (follow-up)
`#250` is broad; this PR takes the five highest-value untested screens. Still uncovered by a dedicated UI test (mostly OAuth/permission-launcher or trivial static screens): `AppPasswordSetupScreen`, `AddAnotherAccountScreen`, `LockScreen`, `SignatureEditScreen`, `ReportReviewScreen`, and the `compose/format` `ColorSwatch`/`ColorSwatchRow` components. Existing tests already cover Mailbox, Reader, Compose, Settings, AccountSettings, ManualSetup, FolderDrawer, and the onboarding steps.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Closes #250
Coverage lane 5 (#250) — instrumented Compose UI/E2E tests for the
ui/**view layer, covering five screens that had no UI test, following the lane 3 (PR #270) pattern.Screens covered
OutboxScreenTest): empty state (no retry action), queued-vs-failed row rendering, retry action calls back into the repo, cancel removes the row and records the cancellation.DraftsScreenTest): empty state, subject/recipient/body rendering + blank-field fallbacks, opening a draft, delete removes the row and records the deletion.ProblemReportsScreenTest): empty state with the always-present create button + auto-delete notice, crash/manual kind rows, opening a report, and the create-manual-report → open-for-review flow — driven by a real file-backedReportStore(temp dir) + realDiagnosticsCollector.AccountPickerScreenTest): the onboarding/login vendor picker — every setup choice is listed, tapping an app-password vendor routes with the rightMailProvider, tapping "Other" routes to manual setup (Outlook row deliberately not tapped — it launches a browser).SignaturesScreenTest): empty state, name + single default-badge rendering, making another signature the default (radio → DB round-trip via a real in-memory Room DB +SignatureRepository), and delete removes the row.Also extends the shared
FakeMailRepositoryto backobserveOutbox()/observeDrafts()with mutable state and record cancel/retry, so the screens' actions are exercised end to end. No production code changed.Validation
:app:compileDebugAndroidTestKotlin+:app:ktlintCheck+:app:detekt— all pass locally (JDK 21).Remaining (follow-up)
#250is broad; this PR takes the five highest-value untested screens. Still uncovered by a dedicated UI test (mostly OAuth/permission-launcher or trivial static screens):AppPasswordSetupScreen,AddAnotherAccountScreen,LockScreen,SignatureEditScreen,ReportReviewScreen, and thecompose/formatColorSwatch/ColorSwatchRowcomponents. Existing tests already cover Mailbox, Reader, Compose, Settings, AccountSettings, ManualSetup, FolderDrawer, and the onboarding steps.🤖 Generated with Claude Code