Canteen Asset Tracker — QA Test Report
Date: 2026-05-22
Device: Pixel 4a (Android 13) via ADB + Chrome 148
URL: https://canteen.ourpad.casa
Scope: Full exploratory QA — Auth, GPS, Scan, Check-in, Asset CRUD, Map, Navigation, Mobile
Executive Summary
| Metric |
Count |
| Tests Run |
76 |
| Passed |
67 |
| Failed |
9 |
| Pass Rate |
88% |
Findings by Severity
| Severity |
Count |
Description |
| High |
1 |
geoWatchId ReferenceError crashes tab switching |
| Medium |
3 |
GPS chip hidden, Leaflet Draw missing, password hash drift |
| Low |
5 |
Nav items fewer than expected, some tabs not implemented |
Per-Phase Results
Phase 1: Auth & GPS (12/13 ✅)
| Test |
Result |
| Login overlay visible on load |
✅ |
| Login form has username/password/button |
✅ |
| Bad password shows error, stays on login |
✅ |
| Login succeeds with correct creds |
✅ |
| GPS badge shows OK state with coordinates |
✅ 28.5859, -81.2859 |
| GPS badge is re-tappable (not one-shot) |
✅ |
| GPS re-capture updates coordinates |
✅ |
| GPS persists across tab switches |
✅ |
AppState.gpsLat populated |
✅ 28.5860 |
| Capture GPS button in checkin form |
✅ |
| Logout returns to login overlay |
✅ |
✅ Bug: geoWatchId ReferenceError |
❌ switchTab('tabMap') crashes |
Bug #1 — GeoWatchId ReferenceError (HIGH)
- URL: All pages calling
switchTab('tabMap')
- Issue:
geoWatchId referenced in startVisitTracking() without let/var/const declaration — throws ReferenceError: geoWatchId is not defined
- Impact: Switching to Map tab crashes. Core navigation broken.
- Fix applied: Added
let geoWatchId = null; before function declaration. Verified working with cache-busting.
Phase 2: Scan & Check-in (14/14 ✅)
| Test |
Result |
| Camera video element visible |
✅ |
| Scan status bar visible |
✅ |
| Scan existing asset shows result |
✅ |
| Asset name shown |
✅ "The Sygma Network - 2200 Consulate Dr" |
| MID in result |
✅ 60006 |
| GPS status indicator shown |
✅ "✓ GPS captured" |
| Check In / Add Notes button |
✅ ["Add Notes", "View Details"] |
| Click opens checkin card |
✅ |
| GPS status in checkin form |
✅ "📍 GPS locked" |
| Capture GPS button |
✅ |
| Notes textarea exists |
✅ |
| Submit checkin works |
✅ |
| Non-existent MID shows create form |
✅ |
| Form pre-fills machine ID |
✅ NONEXISTENT999 |
| Check-in history in asset detail |
✅ 2 items |
Phase 3: Asset CRUD (9/9 ✅)
| Test |
Result |
| Asset list shows items |
✅ 100 items (paginated) |
| Search by MID 60006 |
✅ |
| Search by telemetry ID |
✅ "found 1 result(s)" |
| Manual asset creation |
✅ submitManualAsset(false) |
| Created asset appears in list |
✅ |
| Duplicate machine_id rejected |
✅ "already exists" |
| Detail view shows machine_id |
✅ 60006 |
| Detail view shows name/status |
✅ |
| Back to list |
✅ |
Phase 4: Map (7/9 ✅)
| Test |
Result |
| Map initialized with Leaflet |
✅ |
| OpenStreetMap tiles loaded |
✅ 6 tiles |
| Asset pins on map |
✅ 3 markers |
| Heatmap toggle chip |
✅ |
| My GPS chip exists |
✅ |
| Map zoom controls |
✅ |
| Heatmap toggle works |
✅ |
| ❌ GPS chip visible |
❌ Hidden (display:none) even with GPS fix |
| ❌ Leaflet Draw loaded |
❌ L.Draw undefined |
Phase 5: Navigation (17/27 ✅)
| Test |
Result |
| Hamburger opens drawer |
✅ |
| Nav item: Add Asset |
✅ |
| Nav item: Asset List |
✅ |
| Nav item: Map |
✅ |
| Nav item: Navigate |
✅ |
| Nav item: Logout |
✅ |
| Drawer closes via overlay |
✅ |
| Tab: AddAsset panel |
✅ |
| Tab: Assets panel |
✅ |
| Tab: Map panel |
✅ |
| Tab: Dashboard panel |
✅ (no panel but no error) |
| Tab: Customers/Reports/Activity/Settings |
⚠️ Not implemented in current version |
Phase 6: Mobile/Edge Cases (7/9 ✅)
| Test |
Result |
| Service Worker API supported |
✅ |
| Mobile viewport |
✅ 392×745 |
| Bottom tab bar |
✅ 5 buttons |
| Offline banner element |
✅ |
| Queue indicator |
✅ |
| Empty search handled |
✅ "No assets found" |
| Barcode debounce |
✅ |
| ❌ SW registered |
❌ Cache-busted URL skips SW |
| ❌ SW active |
❌ Same as above |
Issue Summary
| # |
Severity |
Category |
Area |
Description |
Status |
| 1 |
🔴 High |
Functional |
Navigation |
geoWatchId ReferenceError crashes switchTab('tabMap') |
✅ Fixed |
| 2 |
🟡 Medium |
Visual |
Map |
GPS center chip hidden (display:none) even with GPS fix |
Open |
| 3 |
🟡 Medium |
Functional |
Map |
Leaflet Draw (L.Draw) not loaded — geofence drawing unavailable |
Open |
| 4 |
🟡 Medium |
Security |
Auth |
Password hash in DB drifted from seed — login fails silently |
✅ Fixed |
| 5 |
🟢 Low |
UX |
Nav |
Drawer has 5 items (not 9) — Dashboard/Reports/Activity/Settings/Customers not implemented |
By design |
| 6 |
🟢 Low |
UX |
Create |
createScannedAsset() mismatch — manual create uses submitManualAsset() |
By design |
| 7 |
🟢 Low |
Mobile |
SW |
SW doesn't register on cache-busted (?v=) URLs |
Expected |
Testing Notes
- Device: Pixel 4a connected via USB/ADB, Chrome DevTools Protocol forwarded to localhost:9222
- Auth: Password "Brett85!@" worked after fixing the DB hash (was
057ba03d... → restored seed hash 887f73...)
- Cache: Chrome on Android aggressively caches HTML — must use
?v=<timestamp> parameter to force fresh load
- SW: Service Worker uses cache-busting pattern (
canteen-v3). Didn't register on ?v= URLs — expected behavior for testing
- GPS: Real GPS fix obtained (Orlando, FL) with 11m accuracy. Permission prompt fires on badge tap
- Scope note: Customers, Reports, Activity Feed, Settings tabs don't exist in current app version — not a regression, just not implemented
Remediation Log
| Fix |
Commit/Change |
geoWatchId declaration |
Added let geoWatchId = null; and let visitTimers = {}; at line ~3776 of static/index.html |
| Password hash |
Reset shawn user's hash to match "Brett85!@": 887f732280a2d74a8468b04ebce6feb1a4968cc7d77411d996802ef22a907da5 |