13 sections covering every flow that unit tests can't:
1. Smoke (mobile header, sidebar, page titles, tab strips)
2. Account pairing (live QR, sync groups, send-test)
3. Re-pair / unpair (status flips, no spurious reconnect)
4. Reminders — single-message one-off (5-step wizard)
5. Reminders — multi-message stack with media swap
6. Reminders — recurrence picker (Daily / Weekly / Monthly /
Yearly + multi-rule, descriptions are sentences not raw cron)
7. Reminders — edit each section preserves the message stack
(regression guard for the parts-2..N drop bug)
8. Reminders list — swipe + lifecycle (no reshuffle on Pause /
Restart, shelf collapses after action)
9. Activity — swipe archive / delete + Archived tab + restore
10. Send-test feedback round trip (Sending… → Sent ✓)
11. Media upload limits (size caps, HEIC/MOV → document fallback)
12. PWA install (standalone display, offline shell)
13. Theme toggle (desktop only)
Captures the policy decisions that aren't immediately obvious from
the code:
- browser-extension hydration warnings are expected, app code is
not at fault — Incognito clears them
- HEIC/MOV uploads are NOT rejected; they fall back to document
delivery
- cron rules render as descriptive sentences in the UI
- status changes don't reorder the reminders list
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
186 lines
7.9 KiB
Markdown
186 lines
7.9 KiB
Markdown
# Manual test: Web app end-to-end
|
|
|
|
Run after every major web change. Captures the daily-ops flows that
|
|
unit tests can't verify (live Baileys QR, WhatsApp delivery, swipe
|
|
gestures on a real touch device).
|
|
|
|
## Prerequisites
|
|
|
|
- `scripts/dev.sh up` is running. The bot, web, postgres, and tools
|
|
containers are all healthy.
|
|
- Browser open on the host, ideally on a phone for the swipe tests.
|
|
LAN URL is `http://<host-ip>:9000` (e.g. `192.168.0.253:9000`); the
|
|
reverse-proxy URL is `https://wabot.04080616.xyz`.
|
|
- A WhatsApp test phone with at least one group you can fire test
|
|
messages into.
|
|
|
|
## 1. Smoke
|
|
|
|
1. Visit `/` — dashboard renders with three stat cards (Accounts
|
|
connected, Active reminders, Recent runs). No console errors
|
|
beyond the known browser-extension hydration warning ("Encountered
|
|
a script tag while rendering"). The "Recent runs" card description
|
|
reads "3 most recent runs" and links to `/activity`.
|
|
2. Mobile header on the phone shows the `cm` brand pill (left), the
|
|
current page title in the centre, and a hamburger menu (right).
|
|
Tap the menu → a right-side drawer opens with the five nav items.
|
|
Tapping any item closes the drawer and routes to the page.
|
|
3. Click `cm` brand pill → navigates to dashboard. Same on the
|
|
desktop sidebar header (`cm WhatsApp Bot`).
|
|
4. Status tab strips on `/reminders` (4 tabs) span the row evenly;
|
|
on `/activity` (6 tabs incl. Archived) the strip scrolls
|
|
horizontally on narrow widths.
|
|
|
|
## 2. Account pairing (live QR)
|
|
|
|
1. `/accounts` → "New Account" → form → enter "Web Test 1" → "Add
|
|
Account". Redirects to `/accounts/<id>` with status `Unpaired`.
|
|
2. Tap the "Pair WhatsApp" card. Redirects to
|
|
`/accounts/<id>/pairing`. Within ~5 s a QR appears below
|
|
"Waiting for scan…".
|
|
3. Scan with WhatsApp on the test phone (Linked Devices →
|
|
Link a Device).
|
|
4. After scan, status flips to "✅ Connected as +60xxx" and the page
|
|
auto-redirects to the account detail. Phone number visible.
|
|
5. Hit "Sync Groups" — group rows appear.
|
|
6. Tap a group → opens the group detail. Type "Test from web" →
|
|
Send Test. Toast shows "Sending…", then "Sent ✓". The phone's
|
|
WhatsApp shows the message in the group within ~5 s.
|
|
|
|
## 3. Re-pair / unpair
|
|
|
|
1. From the account detail, tap "Re-pair WhatsApp" → re-routes to
|
|
`/pairing` with a fresh QR. Cancel by going back.
|
|
2. Tap "Unpair" → confirm dialog. Confirm. Status flips to
|
|
`Unpaired` immediately (no flicker through `Disconnected`). Bot
|
|
logs show no spurious 5-second reconnect.
|
|
3. Re-pair the same account by scanning again — old session files
|
|
cleared, fresh handshake.
|
|
|
|
## 4. Reminders — single message, one-off
|
|
|
|
1. `/reminders` → "New Reminder".
|
|
2. Step 1 (Account): pick the test account.
|
|
3. Step 2 (Message): type "Hello world" in a single text block.
|
|
Continue.
|
|
4. Step 3 (When): pick "now + 2 minutes" (a date+time, no repeat).
|
|
5. Step 4 (Groups): pick the test group.
|
|
6. Step 5 (Review): all sections show correct values. Tap "Schedule
|
|
Reminder".
|
|
7. Within ~2.5 minutes the reminder fires. WhatsApp shows "Hello
|
|
world" in the group.
|
|
8. Reload `/reminders/<id>` — status `ended`, run history has one
|
|
row with `Success`.
|
|
|
|
## 5. Reminders — multi-message stack with media swap
|
|
|
|
1. `/reminders/new` → step 2.
|
|
2. Add a text block "Block 1". "+ Add file" → upload a JPEG image.
|
|
Caption "img caption". "+ Add text" "Block 3 PS".
|
|
3. Continue through When / Groups / Review. Review pane shows three
|
|
message parts in order with the JPEG filename rendered.
|
|
4. Schedule. Bot fires three messages in sequence with a ~1.5 s
|
|
gap. WhatsApp shows them in order.
|
|
|
|
## 6. Reminders — recurrence picker (cron-backed)
|
|
|
|
1. `/reminders/new` → step 3 (When). Switch the recurrence picker
|
|
from "No Repeats" to "Daily" → set time 09:00 → continue.
|
|
Description on the review pane reads "Every day at 09:00", NOT
|
|
raw cron text.
|
|
2. Edit recurrence to Weekly Mon, Wed, Fri 17:30. Review reads
|
|
"Every week on Mon, Wed, Fri at 17:30".
|
|
3. Edit recurrence to Monthly with multiple days (1, 15) at 09:00.
|
|
Review reads "Every month on days 1, 15 at 09:00".
|
|
4. Edit recurrence to Yearly with months Jan, Apr at day 1 at 09:00.
|
|
Review reads "Every year in Jan, Apr on day 1 at 09:00".
|
|
5. Add a SECOND recurrence row alongside the first. Review summary
|
|
joins both with " · ".
|
|
6. Schedule (set first fire close to now). Verify both rules fire.
|
|
|
|
## 7. Reminders — edit each section preserves the message stack
|
|
|
|
1. Create a reminder with a 3-message stack. Schedule for the
|
|
future.
|
|
2. From `/reminders/<id>`, click the Account section → switch to
|
|
another connected account → Save. The reminder's message list
|
|
on the detail page still shows all 3 parts. (Regression guard
|
|
for the previous bug where editing the account dropped parts
|
|
2..N.)
|
|
3. Same exercise on the Message section: open, swap the JPEG for
|
|
a different image (file picker on the media block), Save.
|
|
Reminder still has 3 parts; the second part now points at the
|
|
new media.
|
|
4. Same on When (change time) and Groups (toggle a group).
|
|
|
|
## 8. Reminders list — swipe + lifecycle
|
|
|
|
1. `/reminders` (mobile). Swipe a row LEFT → red "Delete" shelf
|
|
appears on the right.
|
|
2. Swipe the same row RIGHT → amber "Pause" or "Restart" shelf on
|
|
the left (depending on current status).
|
|
3. Tap "Pause" on an active row. The row stays in the same list
|
|
position (no reshuffle) and its status pill flips to "Paused".
|
|
The shelf collapses immediately (no leftover open state).
|
|
4. Swipe right again → "Restart". Tap. Status flips back to active,
|
|
row position unchanged, shelf closed.
|
|
5. Swipe left → "Delete". Confirm. Row removed, run history
|
|
preserved on `/activity`.
|
|
|
|
## 9. Activity — swipe to archive / delete
|
|
|
|
1. `/activity`. Swipe a row LEFT → red "Delete" shelf.
|
|
2. Swipe RIGHT on a non-archived row → amber "Archive" shelf. Tap.
|
|
Row disappears from the All / Success / Partial / Failed /
|
|
Skipped tabs.
|
|
3. Switch to the "Archived" tab → archived row is here. Swipe
|
|
RIGHT → "Restore". Tap. Row leaves Archived, returns to All.
|
|
4. "Clear history" button at the top hard-deletes everything and
|
|
is hidden when on the Archived tab.
|
|
|
|
## 10. Send-test feedback round trip
|
|
|
|
1. Group detail → type a quick message → Send Test.
|
|
2. Toast "Sending…" appears. Within ~5 s it changes to "Sent ✓".
|
|
3. Phone's WhatsApp shows the message in the group.
|
|
|
|
## 11. Media upload limits
|
|
|
|
1. `/reminders/new` step 2, upload a 4 MB JPEG → accepted, file
|
|
shows in the media block.
|
|
2. Upload a 6 MB JPEG → "Image too large (6.0 MB > 5.0 MB limit on
|
|
WhatsApp)".
|
|
3. Upload a HEIC photo (e.g. straight off an iPhone) → accepted,
|
|
delivered as a document on WhatsApp instead of inline image.
|
|
Recipient sees a downloadable .heic file.
|
|
4. Upload a `.mov` (QuickTime) → accepted, delivered as a document.
|
|
5. Upload a 110 MB document (PDF) → rejected: "Document too large
|
|
(110.0 MB > 100.0 MB limit on WhatsApp)".
|
|
|
|
## 12. PWA install
|
|
|
|
1. Phone Chrome → menu → "Install App" / "Add to Home Screen".
|
|
2. Open from the home screen. The header chrome (URL bar, tabs)
|
|
is gone — fullscreen standalone display.
|
|
3. Brand icon shows the placeholder dark `cm` square.
|
|
4. Force the phone offline (airplane mode) → relaunch the PWA.
|
|
Cached navigation shell loads (white-on-dark spinner / shell);
|
|
network-dependent pages show the offline shell instead of a
|
|
browser error page.
|
|
|
|
## 13. Theme toggle
|
|
|
|
1. Desktop sidebar footer → click the theme button → page swaps
|
|
between light / dark / system.
|
|
2. Mobile drawer no longer contains the theme toggle (intentional
|
|
— it lives only in the desktop sidebar now).
|
|
|
|
## Sign-off
|
|
|
|
- [ ] All sections passed
|
|
- [ ] No console errors beyond the known browser-extension
|
|
"Encountered a script tag" hydration noise (Incognito with
|
|
extensions disabled is clean)
|
|
- [ ] Bot logs show no unexpected ERROR / WARN entries during the run
|
|
- [ ] Tester / date / build SHA recorded
|