Mobile device verification - Manual Test Plan โ
| Field | Value |
|---|---|
| Branch / PR | test/mobile-pwa-device-verification |
| Environment | Deployed dev, https://dev.ourlantern.app |
| Build flags / config | none |
| Build (commit) | dev at time of run |
| Tester | Mechelle |
| Date |
This plan contains only what a physical phone can answer. Everything an emulator could reach was run headlessly and is recorded under "Already verified" below, so nothing here is a scenario that could have been automated and handed over instead.
5 scenarios, all Android. The iOS half is blocked on hardware, see the note at the end.
Summary โ
| # | Scenario | Result | Notes |
|---|---|---|---|
| 1 | Install to home screen | [ ] pass [ ] fail [ ] blocked | |
| 2 | Installed shell looks right | [ ] pass [ ] fail [ ] blocked | |
| 3 | Push permission and token registration | [ ] pass [ ] fail [ ] blocked | |
| 4 | Push actually arrives on a locked phone | [ ] pass [ ] fail [ ] blocked | |
| 5 | Airplane-mode offline, installed app | [ ] pass [ ] fail [ ] blocked |
Setup / preconditions โ
- Android phone, Chrome. Use your normal test account.
- Start signed OUT for scenario 1 so the install prompt is not affected by app state.
- If Lantern is already installed from an earlier run, uninstall it first (long-press the icon, Uninstall) so scenario 1 tests a real first install.
- Scenario 4 needs a second device or the admin portal to trigger the notification, and someone to wave at you. Ask an agent session to run
npm run e2e:alpha-loopif you want a wave generated on demand.
Already verified headlessly, do not re-test โ
Recorded so this plan stays short and you are not re-running things that already have evidence:
- Manifest parses with no errors,
display: standalone,start_url: /, both icons reachable (200). - The browser reports the app installable (
Page.getInstallabilityErrorsreturned empty). Scenario 1 is checking that the real Chrome install UX follows, not whether the criteria are met. - Service worker
/sw.jsregisters and reachesactivated; workbox precache holds 43 entries. - Loads offline after caching, both signed out and signed in.
- No horizontal overflow at 412px, 375px or 320px.
- Touch targets: 4 are under 24x24 but all are exempt under WCAG 2.5.8's spacing exception (nearest neighbour 60-69px).
- Core loop works on a phone form factor: sign in, light, wave, accept, chat, message, verified in Firestore.
- Push is configured end to end on deployed dev:
VITE_FIREBASE_VAPID_KEYis indeploy-dev.ymland present in the served main chunk, andfirebase-messaging-sw.jsis served 200. So scenarios 3 and 4 are testing delivery to a real device, not configuration.
Scenarios โ
1. Install to home screen โ
- Goal: A first-time visitor can install Lantern from Chrome on Android.
- Preconditions: Lantern not currently installed. Signed out.
- Steps:
- Open https://dev.ourlantern.app in Chrome.
- Wait about 10 seconds on the landing page.
- Look for an install affordance: an "Install app" / "Add to Home screen" banner, or the same option in the Chrome menu (three dots).
- Install it.
- Find the Lantern icon on your home screen or app drawer.
- Expected: An install option is offered, installation completes, and a Lantern icon appears with the lantern artwork (not a generic globe or a letter).
- Verify: The icon image is the Lantern icon. Note whether the install was offered automatically or only via the menu.
Result: [ ] pass [ ] fail [ ] blocked
Actual:
Evidence: (screenshot of the icon on your home screen)
Follow-up:2. Installed shell looks right โ
- Goal: The installed app opens as an app, not a browser tab.
- Preconditions: Scenario 1 completed.
- Steps:
- Open Lantern from the home screen icon.
- Watch the launch: note any splash screen and its colour.
- Once loaded, look at the top and bottom of the screen.
- Scroll the page up and down.
- Expected: No browser URL bar and no Chrome tab strip. The status bar area picks up the amber theme colour rather than looking like a browser. Content is not cut off by the notch or the gesture bar at either end of a scroll.
- Verify: Confirm specifically that no address bar is visible at any point after launch.
Result: [ ] pass [ ] fail [ ] blocked
Actual:
Evidence: (screenshot of the app at rest, top and bottom visible)
Follow-up:3. Push permission and token registration โ
- Goal: The app can ask for notification permission and register for push on a real device.
- Preconditions: Installed app, signed in.
- Steps:
- Open the installed app and sign in.
- Go to notification settings (Profile, then Settings).
- Turn notifications on.
- Accept the Android permission prompt when it appears.
- Return to the app and confirm the setting stayed on.
- Expected: Android's own permission dialog appears, and after accepting, the in-app toggle remains on rather than silently reverting.
- Verify: The toggle is still on after leaving the settings screen and coming back.
Result: [ ] pass [ ] fail [ ] blocked
Actual:
Evidence: (screenshot of the toggle after returning to the screen)
Follow-up:4. Push actually arrives on a locked phone โ
- Goal: A notification is delivered to the device when the app is not in the foreground. This is the scenario that cannot be emulated at all.
- Preconditions: Scenario 3 passed. A second account able to wave at you.
- Steps:
- Confirm you are lit at a venue.
- Lock the phone, screen off.
- Have the second account wave at you (or ask an agent session to run the alpha loop).
- Wait up to 60 seconds.
- Wake the phone without unlocking, and look at the lock screen.
- Tap the notification and see where it lands.
- Expected: A notification appears on the lock screen naming the wave. Tapping it opens the installed Lantern app on the relevant screen, not a fresh browser tab.
- Verify: Note whether it opened the INSTALLED app or a browser. Note the delay between the wave and the notification.
Result: [ ] pass [ ] fail [ ] blocked
Actual:
Evidence: (photo of the lock-screen notification)
Follow-up:5. Airplane-mode offline, installed app โ
- Goal: The installed app degrades honestly with no connection at all. Emulated offline passes, but that is the browser's network stack rather than a real radio.
- Preconditions: Installed app, opened and used at least once while online.
- Steps:
- Open the app online and let it load fully, then close it.
- Turn on airplane mode. Confirm wifi and mobile data are both off.
- Open Lantern from the home screen.
- Wait about 20 seconds.
- Try to navigate to another screen.
- Turn airplane mode off and watch the app for another 30 seconds without restarting it.
- Expected: The app opens rather than showing Chrome's dinosaur page. Content that needs the network shows an empty or offline state rather than a blank screen or a spinner forever. When connectivity returns, the app recovers without a manual restart.
- Verify: Note exactly what the app shows offline: real content, an offline message, an endless spinner, or a blank screen. That distinction matters more than pass or fail.
Result: [ ] pass [ ] fail [ ] blocked
Actual:
Evidence: (screenshot while in airplane mode)
Follow-up:iOS: blocked on hardware โ
There is no iPhone on the team, so the iOS half of this cannot be run. It is tracked in #722, which covers borrowing a device or using BrowserStack.
The iOS-specific behaviours that stay unverified until then, and none of them are inferable from the Android result:
- iOS installs only via Safari's Share menu, with no install prompt, so scenario 1 has no iOS equivalent.
- iOS web push requires the app to be installed to the home screen first, and needs iOS 16.4 or later.
- iOS evicts service worker caches more aggressively, so scenario 5 may behave differently.
- Safari's standalone mode handles safe areas differently from Chrome, so scenario 2 needs its own run.