{ "output": "# Plan: Paywall Smoke Tests (Phase 6)\n\n## Objective\nFinalize Phase 6 by resolving the remaining PR review feedback on the paywall smoke tests. The primary goals are to revert the unintended production code changes (hiding the FABs in read-only mode), update the tests to assert the correct disabled state semantics, and resolve two test/doc drift issues in S19 and S20.\n\n## Key Files & Context\n- `app/src/main/java/com/servicebook/ui/vehicles/VehicleListScreen.kt`: To revert FAB visibility logic.\n- `app/src/main/java/com/servicebook/ui/records/VehicleDetailScreen.kt`: To revert FAB visibility logic.\n- `app/src/androidTest/java/com/servicebook/SmokeTest.kt`: To update assertions and add missing steps.\n- `docs/plan-smoke-tests.md`: To ensure docs and tests remain synchronized.\n- `app/coverage-baselines/gmd_smoke.ec`: Baseline to be regenerated.\n\n## Implementation Steps\n\n1. **Revert FAB Hiding Logic in Production Code**:\n - **`VehicleListScreen.kt`**: Restore the `ExtendedFloatingActionButton` to be visible when `state.isReadOnly` is true, but rendered with `contentColor = MaterialTheme.colorScheme.onPrimaryContainer.copy(alpha = 0.38f)` and a `semantics` block containing `stateDescription = disabledDescription`. Route clicks to `BlockedWriteAttempted`.\n - **`VehicleDetailScreen.kt`**: Restore identical disabled FAB logic when `state.isReadOnly` is true. Route clicks to `BlockedWriteAttempted`.\n\n2. **Update S19 (`readOnlyBannerAcrossScreens`) in `SmokeTest.kt`**:\n - **Swipe-to-Dismiss**: Before navigating to `VehicleDetailScreen`, perform a swipe-to-dismiss gesture on the \"Car A\" node (`performTouchInput { swipeLeft() }`). Assert that \"Car A\" is still displayed (swipe-delete is disabled in read-only mode).\n - **FAB Disabled Assertion**: On `VehicleDetailScreen`, instead of asserting the FAB is absent (`awaitTagGone`), assert that it exists and has the correct `stateDescription` (`disabled_upgrade_description`).\n - Use `hasStateDescription(activity.getString(R.string.disabled_upgrade_description))` for the semantic assertion.\n\n3. **Update S20 (`readOnlyLiftsOnPremium`) in `SmokeTest.kt`**:\n - **Extend Test**: After verifying the \"Add Vehicle\" FAB navigates successfully to `AddEditVehicleScreen`, press back to return to the `VehicleListScreen`.\n - Tap \"Car A\" to navigate to `VehicleDetailScreen`.\n - Assert that the `PaywallStatusCard` (`TestTags.PAYWALL_STATUS_CARD`) is absent.\n - Assert that the \"Add Record\" FAB is visible and does not have the `disabled_upgrade_description` semantics (or simply assert its presence since the disabled state changes its semantics).\n\n4. **Update `docs/plan-smoke-tests.md`**:\n - Ensure the S19 and S20 documentation explicitly matches the newly updated test steps (they mostly do, but confirm the swipe step is correctly tracked and the S20 detail screen check is documented).\n\n## Verification & Testing\n- Run `./gradlew pixel2api33DebugAndroidTest` to verify that all existing and new smoke tests (S01-S20) pass.\n- Verify the total runtime of the suite remains under 2 minutes 30 seconds.\n- Run `./gradlew generateGmdCoverage` to update the `gmd_smoke.ec` baseline file.\n\n" }