Flight test
The pre-flight checklist before promoting a beta build to production. Verifies the build holds up on real cars, not just your dev-server.
The beta track gets your bundle in front of real testers. Flight
testing is what you do during the beta — the systematic checks
that catch issues your local dev-server can't see. Run this before
running beta promote-production.
First time? Start at Beta testing for the publish + invite flow. This page is for the post-invite, pre-promotion phase.
When to run a flight test
Always, for any change touching:
- Bridge calls (
getContext,callApi, car-status subscriptions). - Manifest fields the host enforces (
safeWhileDriving,permissions,minHostVersion,urlorigin). @i99dash/admin-sdkcalls — privileged ops have user-consent and session-cap dimensions you can't simulate locally.- Anything that runs while moving (the safety gate is a real input).
Skip it for copy-only or CSS-only changes if you have screenshot diffs in CI.
Pre-flight checklist (~10 minutes per beta)
Print, paste in a checklist tool, or just skim — but don't skip the ones marked (blocker).
1. Catalog presence
- (blocker) App appears under the tester's "Beta available" card on first launch.
- Release notes from
--release-notesrender in the consent sheet, no truncation, locale-correct (test at leastenandar). - Icon + name match the manifest. No "default app" placeholder.
2. Safety gate
- (blocker) With
safeWhileDriving: true: app loads while car is moving (toggle dev-server's driving switch first to reproduce, then verify on a real car at >5 km/h). - With
safeWhileDriving: falseor unset: app shows the host's "not available while driving" card. - No crash, no white screen, no flicker on the moving → parked transition.
3. Context handling
- (blocker) Different VINs render different content (or explicit "no car bound" state).
- Locale flip (
en→ar) flips text direction and translations. No layout breakage. -
isDarkflip matches the host theme — no white flash on dark bring-up.
4. Network paths
- (blocker) Backend
callApipaths are on the host's allow-list. Adisallowed_pathenvelope means the manifest origin needs ops review. - Transient failures degrade gracefully — no infinite spinners.
- Offline launch (airplane mode) shows the right empty state.
5. Subscriptions
- (blocker)
onStatusChangecleans up — observe in DevTools that disconnect/reconnect doesn't grow a sub count. - Background → foreground (lock-screen, app-switch) doesn't lose events; the SDK's catch-up replay fires once on resume.
- Stale data (
status.staleness === 'very_stale') renders a visible "no signal" cue, not stale numbers as if fresh.
6. Privileged ops (admin-sdk only)
- (blocker) First call after install triggers the consent sheet. Approving persists; subsequent calls don't re-prompt until expiry.
- Tier-2 templates (
sys.reboot,pm.install) trigger a fresh step-up prompt at action time even after install consent. - Session-cap expiry (90 days) is auto-refreshed; no manual user action required mid-session.
-
session_cap_expiredenvelopes resolve on a single retry after ~500 ms.
7. Performance
- (blocker) Cold start (first launch from a cleared cache) is < 1.5 s on the head-unit hardware. Bundle size < 1 MB uncompressed.
- No memory growth across 10 minutes of typical use (DevTools → Memory → Heap snapshots before/after).
- No console errors or
console.warnspam from the SDK in dev mode.
8. Crash + recovery
- (blocker) Force-killing the host while your app is open doesn't leave the user in a broken state on relaunch.
- A simulated bridge failure (
fakeBridgewiththrow) lands the user on a fallback UI, not an unhandled-rejection toast.
Flight-test the testers
Beta-track features the SDK can't validate but you can:
- Tester roster reflects reality. Run
beta testers <app>after a few days; remove anyone whose status is stillinvitedafter 48 h (likely a typo'd Telegram username). - At least 5 active testers. Below that, you don't have
meaningful coverage. Use
beta invite-batch. - Tester feedback channel exists. A
betaTelegram chat or Discord works; relying on issue creation alone undercounts the noise.
Promotion criteria
Don't promote to production until all blockers pass for at least 3 days and you've collected feedback from 3+ testers including:
- 1 with a different car make / model than yours (cross-checks the car-status payload variance).
- 1 on a different locale (RTL flip exposes layout bugs).
- 1 who actually drives with the mini-app open (safety gate exercised in the wild).
When all three boxes are green, run:
sdk-i99dash beta promote-production com.example.myappThe current beta bundle becomes the production version with no
rebuild. Same SHA-256, same CDN URL, same (id, version) pair.
After promotion
Set a calendar reminder to check in 24 h after the promotion:
- Crash-free rate isn't worse than the previous production build.
-
beta testers <app>roster is unchanged — testers should have automatically rolled to the production build (the consent lifts on promotion).
If anything regresses, you have a fast rollback:
# Re-promote the prior version
sdk-i99dash publish --track production --bundle prior-version-build/A new bundle SHA, but the user-visible content matches what was on production yesterday.
Related
- Beta testing — the publish + invite
- promote flow this checklist sits inside.
- Best practices — the rules these blockers exist to catch the absence of.
- Subscriptions — debugging the cleanup blockers in the subscription section.
- Troubleshooting — every symptom we've seen in the wild, with root cause + fix.