name: e2e-default
description: "Run a fixed OTA regression flow for examples/v0.85.0 with agent-device. Use when the caller wants a built-in end-to-end scenario instead of defining one manually: deploy a known-good OTA bundle, verify a visible UI change plus the deployed bundleId, then deploy an intentionally crashing OTA bundle and verify rollback to the previous stable bundle with RECOVERED and crashedBundleId evidence."
Hot Updater V0.85 E2E Auto
Use this skill for examples/v0.85.0 only.
Always load and follow $agent-device. Read ../e2e/references/runtime-targets.md before running anything.
This skill owns the scenario. Do not ask the caller to provide the test steps.
Rules
- Run iOS and Android sequentially. Never overlap platform runs.
- If the caller does not choose a platform, run iOS first, then Android.
- Use release binaries only. Do not use debug builds or Metro-attached sessions.
- Do not register bundles directly in the standalone DB. Create test bundles only through
pnpm hot-updater deploy .... - Keep the example source clean. Revert every temporary patch immediately after its deploy finishes.
- Use
examples/v0.85.0/dist/manifest.jsonas the source of truth for each deployed bundle id. Capture it immediately after each deploy because the next deploy overwrites it. - Use
agent-device snapshot -i; do not use screenshots unless the caller explicitly asks. - Keep the success marker out of the crash bundle. The success marker must reappear only if rollback returns to the previous stable bundle.
- Public launch status should only be
STABLEorRECOVERED. - For the crash phase, the crash patch must live at module top level, outside
App, so the OTA bundle fails during JS module evaluation. Do not useuseEffect, component-body throws, or button-driven crashes for this skill.
Fixed Scenario
Run this exact two-phase flow per platform:
- Build and install the baseline release app.
- Capture the built-in bundle id from the first clean launch.
- Deploy a known-good OTA bundle with a visible marker.
- Verify the app shows the marker and the deployed bundle id.
- Deploy an intentionally crashing OTA bundle.
- Verify the app recovers to the previous stable bundle and reports the crashed bundle id.
Preflight
Before phase 1:
- Run
pnpm -w build. - Confirm the standalone update server is reachable at
http://localhost:3007/hot-updater/version. - Use the exact workspace:
<repo-root>/examples/v0.85.0. - Build and install the release app for one platform.
- Launch the app and capture a baseline snapshot.
- Record the first clean-launch bundle id shown in the UI as
BUILTIN_BUNDLE_ID. - Confirm the crash history section is empty before continuing.
Command Templates
Use these for one platform at a time.
iOS Build And Install
agent-device ensure-simulator --platform ios --device "iPhone 16" --boot
cd <repo-root>/examples/v0.85.0/ios
pnpx pod-install
xcodebuild -workspace HotUpdaterExample.xcworkspace \
-scheme HotUpdaterExample \
-configuration Release \
-sdk iphonesimulator \
-destination 'id=<simulator-udid>' \
-derivedDataPath /tmp/hotupdater-v085-ios-e2e build
agent-device reinstall HotUpdaterExample \
/tmp/hotupdater-v085-ios-e2e/Build/Products/Release-iphonesimulator/HotUpdaterExample.app \
--platform ios \
--device "iPhone 16"
agent-device open org.reactjs.native.example.HotUpdaterExample \
--platform ios \
--device "iPhone 16" \
--session qa-ios-v085 \
--relaunch
Android Build And Install
cd <repo-root>/examples/v0.85.0/android
./gradlew :app:assembleRelease --rerun-tasks
agent-device reinstall com.hotupdaterexample \
<repo-root>/examples/v0.85.0/android/app/build/outputs/apk/release/app-release.apk \
--platform android \
--serial <serial>
agent-device open com.hotupdaterexample \
--platform android \
--serial <serial> \
--session qa-android-v085 \
--relaunch
OTA Deploy
Run deploy from <repo-root>/examples/v0.85.0.
pnpm hot-updater deploy -p ios -t 1.0.x
pnpm hot-updater deploy -p android -t 1.0.x
Capture Deployed Bundle ID
Run this from <repo-root>/examples/v0.85.0 immediately after each deploy:
node -p "require('./dist/manifest.json').bundleId"
Snapshot And State Inspection
agent-device snapshot -i
agent-device diff snapshot -i
<repo-root>/.agents/skills/e2e/scripts/inspect_ios_state.sh
<repo-root>/.agents/skills/e2e/scripts/inspect_android_state.sh
Scroll And Snapshot Playbook
The example app is intentionally scrollable.
In this skill, capture one section at a time with a fresh snapshot.
Prefer agent-device scrollintoview "<section title>" over manual swipes when
the section heading text is available.
Section Order
Use this default section order:
- top-of-screen launch snapshot
Runtime SnapshotLaunch StatusCrash History- optional deeper sections such as
OTA Asset Preview,Manifest Assets,Runtime Details, andActions
Typical navigation pattern:
agent-device snapshot -i
agent-device scrollintoview "Launch Status"
agent-device snapshot -i
agent-device scrollintoview "Crash History"
agent-device snapshot -i
If text lookup drifts, fall back to agent-device swipe ... or other explicit
scroll gestures and capture a fresh snapshot immediately after the motion.
Baseline Snapshot Expectations
For the first clean launch after install:
- Run
agent-device snapshot -iat the top of the scroll view. - Record
BUILTIN_BUNDLE_IDfrom theBundle IDrow inRuntime Snapshot. - Confirm
Manifest Bundle IDmatches the same built-in id. - Run
agent-device scrollintoview "Crash History". - Run
agent-device snapshot -i. - Confirm the crash history area shows
No crashed bundles recorded. - Treat these snapshots as the baseline reference before any OTA deploy.
Phase 1 Snapshot Flow
After the stable OTA deploy and app relaunch:
- Run
agent-device snapshot -iat the top of the scroll view. - Verify on this top snapshot:
Scenario MarkerE2E AUTO SUCCESSBundle ID = STABLE_BUNDLE_IDManifest Bundle ID = STABLE_BUNDLE_ID
- Run
agent-device scrollintoview "Launch Status". - Run
agent-device snapshot -i. - Verify the status JSON contains
"status": "STABLE". - Run
agent-device scrollintoview "Crash History". - Run
agent-device snapshot -i. - Verify the crash history still shows
No crashed bundles recorded. - Only if asset evidence is needed, run
agent-device scrollintoview "Manifest Assets", snapshot that section, and verify the visible asset hash there.
Phase 2 Snapshot Flow
After the crash OTA deploy and the recovered relaunch:
- Run
agent-device snapshot -iat the top of the recovered scroll view. - Verify on this top snapshot:
Scenario MarkerE2E AUTO SUCCESSBundle ID = STABLE_BUNDLE_IDManifest Bundle ID = STABLE_BUNDLE_ID
- Run
agent-device scrollintoview "Launch Status". - Run
agent-device snapshot -i. - Verify the status JSON contains
"status": "RECOVERED"and"crashedBundleId": "<CRASH_BUNDLE_ID>". - Run
agent-device scrollintoview "Crash History". - Run
agent-device snapshot -i. - Verify the crash history section visibly includes
CRASH_BUNDLE_ID. - Only if asset or action evidence is needed, scroll further to
Manifest Assets,Runtime Details, orActionsand capture another snapshot there.
Diff Guidance
- Use
agent-device diff snapshot -iimmediately after each section change or after recovery relaunch when you want a compact confirmation of what changed. - Do not use diff output as the only evidence for ids or statuses. The final verdict must still come from a readable full snapshot and optional local metadata files.
Phase 1: Stable Bundle
Create a temporary visible marker in examples/v0.85.0/App.tsx.
Use this exact marker text:
const AUTO_E2E_SUCCESS_MARKER = "E2E AUTO SUCCESS";
Render it in the Runtime Snapshot section with:
<InfoRow label="Scenario Marker" value={AUTO_E2E_SUCCESS_MARKER} />
Recommended placement:
- Add the constant near
readRuntimeSnapshot. - Add the
InfoRownext to the other bundle metadata rows inRuntime Snapshot.
Then:
- Deploy OTA for the active platform.
- Capture the deployed id as
STABLE_BUNDLE_IDfromdist/manifest.json. - Revert the temporary success patch immediately after deploy.
- Relaunch the app.
- Capture a fresh snapshot and optional local state dump.
Phase 1 passes only if all of these are true:
- The UI shows
Scenario MarkerandE2E AUTO SUCCESS. Bundle IDequalsSTABLE_BUNDLE_ID.Manifest Bundle IDequalsSTABLE_BUNDLE_ID.- The visible status JSON contains
"status": "STABLE". - The crash history section is still empty.
- If you inspect local files,
metadata.jsonreferencesSTABLE_BUNDLE_IDas the stable bundle and is not verification-pending.
Phase 2: Crash Bundle
Start from the clean baseline source with the success patch already reverted.
Add this temporary crash patch at module scope, outside App, with the real
values substituted:
const AUTO_E2E_SAFE_BUNDLE_IDS = new Set([
"<BUILTIN_BUNDLE_ID>",
"<STABLE_BUNDLE_ID>",
]);
const AUTO_E2E_CURRENT_BUNDLE_ID = HotUpdater.getBundleId();
if (!AUTO_E2E_SAFE_BUNDLE_IDS.has(AUTO_E2E_CURRENT_BUNDLE_ID)) {
throw new Error("hot-updater e2e-default crash bundle");
}
Recommended placement:
- Add this patch near the other module-level helpers, before
function App(). - Do not keep the success marker in this crash bundle patch.
- Do not put the crash logic inside
App,useEffect, or any UI event handler. Those patterns do not reliably produce the crashing OTA bundle this scenario needs.
Then:
- Deploy OTA for the active platform.
- Capture the deployed id as
CRASH_BUNDLE_IDfromdist/manifest.json. - Revert the temporary crash patch immediately after deploy.
- Relaunch the app once to let the bad bundle apply.
- If the app terminates or the session drops, reopen the app once more. The first failing launch is expected.
- Capture a fresh snapshot and local state dump after the recovered launch.
Phase 2 passes only if all of these are true:
- The final recovered UI still shows
Scenario MarkerandE2E AUTO SUCCESS. - The final
Bundle IDequalsSTABLE_BUNDLE_ID, notCRASH_BUNDLE_ID. - The final
Manifest Bundle IDequalsSTABLE_BUNDLE_ID, notCRASH_BUNDLE_ID. - The visible status JSON contains
"status": "RECOVERED". - The visible status JSON contains
"crashedBundleId": "<CRASH_BUNDLE_ID>". - The crash history section contains
CRASH_BUNDLE_ID. launch-report.jsonreportsRECOVEREDwithcrashedBundleId = CRASH_BUNDLE_ID.metadata.jsonis no longer verification-pending and still points atSTABLE_BUNDLE_IDas the stable bundle.
Treat recovery to the built-in bundle as a failure for this scenario. The required behavior is rollback to the previous stable OTA bundle.
Platform Metadata Keys
Use the platform-native JSON keys when checking raw files:
- iOS metadata:
stable_bundle_id,staging_bundle_id,verification_pending - Android metadata:
stableBundleId,stagingBundleId,verificationPending - iOS and Android launch report:
status,crashedBundleId
Reporting
If the caller asks for a report, include:
- Platform
- Binary type used. This should always be
Release. BUILTIN_BUNDLE_IDSTABLE_BUNDLE_IDCRASH_BUNDLE_ID- Whether the success marker appeared after the stable deploy
- Whether the success marker reappeared after recovery
- Final visible
status - Final visible
crashedBundleId - Metadata summary
- Launch report summary
- Crash history summary
- Whether each assertion came from UI snapshot, local metadata, or both
Notes
- In this skill,
<repo-root>means the checked-out repository root. - The example app already renders
Bundle ID,Manifest Bundle ID, status JSON, and crash history inexamples/v0.85.0/App.tsx. - The installed iOS app id is
org.reactjs.native.example.HotUpdaterExample, even thoughhot-updater.config.tsusescom.hotupdaterexamplefor native build config.