End-to-end test run — 5 September 2026
Two Android emulators (rider on emulator-5554, driver on emulator-5556)
driven against the live stack at api.ridekit.dev, with the admin panel at
demo.ridekit.dev. Not a seeded localhost, not mocks.
Every screen was driven by ELEMENT (resource-id / accessibility label) rather
than by pixel coordinates, so a layout change breaks the run loudly instead of
tapping the wrong thing and photographing the result. Screenshots are in
docs/media/.
Verified working, end to end
| Flow | Evidence |
|---|---|
| Rider registration from scratch | New number +919012340077 → OTP → signed in. rider/T01–T03 |
| Wallet top-up (real money path) | Razorpay checkout branded RideKit → test card → 3DS → ₹100 credited. Ledger entry topup 10000 debit / 10000 credit — balanced double-entry, verified in Postgres. rider/T05–T13 |
| City ride | Book → offer → accept → arrive → start → complete → rate. Fare ₹110.53, driver ₹88.43, commission ₹22.10 (sums exactly). rider/06–17, driver/03–10 |
| Parcel delivery | Book → offer (labelled as a parcel) → accept → arrive → proof photo → collection code → out for delivery → proof photo → delivery code → delivered. Driver earnings ₹88.43 → ₹134.89. driver/W21–W29 |
| Hourly rental | 1 hr / 10 km package ₹90 → accept → arrive → start → live meter (rider sees "10.0 km left") → rider ends it → ₹90 paid. Driver ₹134.89 → ₹206.89 (₹72 share = 80%). rider/R24–R29, driver/R23–R30 |
| Intercity quote | Mumbai → Pune, 119.9 km: base ₹36 + distance ₹959.07 + driver allowance ₹300 = ₹1,295.07, tolls stated as paid on the road. rider/R32 |
| Driver withdrawal | ₹500 requested → balance reserved ₹3,052.26 → ₹2,552.26, ledger debit posted → admin process → mark paid → driver's app shows "Paid". driver/T05–T08 |
| Multi-vehicle | Registered a Honda Activa as a Bike, approved it in admin, switched to it, went online on it, took a bike parcel. driver/T09–T17 |
| Rider↔driver chat | "On my way" sent from the driver, received on the rider. driver/T25, rider/T35 |
| Raise your fare | Full ₹10–₹150 ladder at the dead end; +₹150 applied and recorded server-side (raise_minor = 15000), dispatch re-run. rider/R34 |
| Admin panel | All 22 operator screens loaded and rendered, dispatch console with a live Leaflet map and queue. Zero findings. admin/01–22 |
| Rider screens | home, search, confirm, tracking, wallet, parcels, parcel-track, scheduled, places, history, profile, safety, referral, language, settings, delete-account, rental, intercity, chat, rate — all render. |
| Driver screens | home, menu, earnings, quests, destination mode, heatmap, documents, vehicles, add-vehicle, history, profile, settings, help, trip, parcel, journey, chat, rate — all render. |
Bugs found and fixed in this run
- Drivers silently received no offers. Socket.IO does not auto-reconnect
after
io server disconnect, which is exactly how the gateway rejects an expired JWT. The UI still said "You're online". Four rides died as "no drivers available" with a driver 464 m away. - A live Google Maps key was committed in both apps' generated
AndroidManifest.xml— it would have shipped in every buyer's zip. - In-app chat had never worked. The route both apps call was guarded by
dispatcher permissions and stamped every message
support; rider and driver each got 403 on send and history, and the apps rendered an empty thread. - Bike and Auto did not exist as vehicle types, while both apps advertised them. A driver could not register a bike; a rider tapping "Bike" got cars.
- A verified driver could not upload a document — the only control routed to onboarding, which for them renders "You're verified!".
- Quick-reply chips rendered as 500px capsules (horizontal ScrollView with
no
flexGrow: 0/alignItems). - My own regressions, caught on device: a socket-triggered token refresh raced the HTTP one and logged users out; the raise panel was hidden at the dead end; and it printed "New total: ₹0.00" beside a ₹1,295 fare.
Known gaps, not yet addressed
- Registration never asks for a name. The rider greeting reads "Rider" and the driver sees the sender as literally "Sender".
- Fares render with paise (
₹110.53). Indian ride-hailing rounds to whole rupees on screen. - Destination search is not biased to the rider's city — typing "Bandra" in Mumbai returns Bandra in Bihar and Madhya Pradesh above local matches.
- A live parcel is not auto-resumed. A passenger ride resumes into tracking on launch; a parcel is only reachable via Menu → My packages.
- A demo ride has been "in progress" for 47 days (
#b7288340) and shows in the dispatch console. - SOS and crash/reboot resume were NOT driven to completion. Both need
a live trip on two devices at once, and by that point the machine was at load
20-60 with two emulators running: the driver emulator's Android framework
crashed once (
Can't find service: activity, recovered by restarting it) anduiautomator dumpbegan timing out at 60s. Blind coordinate taps were tried instead and repeatedly hit "Go offline", which is worse than not testing — it produces confident-looking results that mean nothing. Stopped rather than push a machine that had already been flagged as overloaded. - The videos in
media/video/capture failed attempts, not a completed ride, for the same reason. They should be re-recorded on a quieter machine, one emulator at a time if necessary.
Not reachable with this account
- Business / corporate rides — the menu row is gated behind
ownsCompany, which the test rider is not. Correct behaviour, not a defect.
How to re-run
scratchpad/ui.py <device> dump|tap|wait|type # drive by element
scratchpad/walk.py <device> <app> <steps-file> # walk screens, verify each rendered
admin-capture.mjs # Playwright over the live admin
Constraints learned the hard way: boot emulators one at a time (both plus a gradle build pushes load past 20 on 8 cores and uiautomator starts timing out); the dispatch radius is 5 km; the offer TTL is 15 s, so a UI dump between booking and accepting eats most of it.
source: docs/testing/END-TO-END-2026-09-05.md (ships identically in the product zip)