Conversation
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f8e9c309db
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| keytool -genkeypair \ | ||
| -keystore "$KEYSTORE" \ | ||
| -storepass android \ | ||
| -keypass android \ | ||
| -alias androiddebugkey \ | ||
| -keyalg RSA \ | ||
| -keysize 2048 \ | ||
| -validity 10000 \ | ||
| -dname "CN=Android Debug,O=Android,C=US" >/dev/null 2>&1 |
There was a problem hiding this comment.
Use a persistent signing key for helper APK releases
This build script generates a new keystore for every run and signs the APK with that ephemeral key. Android package replacement requires the same signing certificate, so devices that already have an older helper installed will reject later install -r -t updates with signature mismatch errors, which means ensureAndroidSnapshotHelper cannot upgrade in place and will repeatedly fall back to stock snapshots. Keep a stable release keystore (or uninstall before install) so helper updates remain installable.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Addressed in b42b80e: the build now signs with a checked-in helper debug keystore instead of generating a new key per build. The runtime uninstall/retry path for INSTALL_FAILED_UPDATE_INCOMPATIBLE remains as an extra recovery path.
| default: | ||
| xml.append(character); |
There was a problem hiding this comment.
Preserve control whitespace when writing XML attributes
The default branch writes raw characters directly into XML attributes, including newline/tab/carriage-return characters. In XML attribute parsing those characters are normalized, so multiline Android text/content descriptions lose their original structure (for example line breaks becoming spaces), which can change snapshot text and break text-based matching/assertions. Encode these whitespace control characters as entities to preserve fidelity.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Addressed in b42b80e: the XML writer now entity-escapes newline, carriage return, and tab characters in attributes so parsed snapshot text keeps those control-whitespace characters instead of letting XML attribute normalization collapse them.
f8e9c30 to
69a4dae
Compare
69a4dae to
55e7da9
Compare
Summary
Add a provider-neutral Android snapshot helper APK with release packaging, manifest/checksum support, public helper APIs, npm-bundled helper artifact resolution, and helper-first Android snapshot fallback metadata.
The bundled helper is now the default Android snapshot path when the npm package includes
android-snapshot-helper/dist: the first snapshot verifies/installs the APK if missing or outdated, and any install/capture failure falls back to stock UIAutomator withandroidSnapshot.fallbackReason. The earlier env-var gate and its now-obsolete config module were removed; directhelperArtifactinjection remains for tests and provider integrations.Follow-up hardening in this branch keeps helper APK releases on a persistent debug signing key, marks that keystore as binary, bundles the helper APK/manifest into npm packages during
prepack, allowlists manifest install args before executing provider ADB, validates manifest SHA-256 shape up front, caps manifest/APK downloads, cleans owned helper cache directories, documents the stable release contract and-tinstall requirement, preserves and decodes XML attribute control whitespace, removes the CodeQL-flagged attribute regex path, captures interactive Android window roots for keyboards/system overlays with active-window fallback metadata, tolerates disappearing accessibility windows during helper traversal, resolves sdkmanager explicitly in CI/release workflows, keeps the helper subpath visible to Fallow, removes duplicate helper packaging work from CI, and splits the TypeScript helper implementation into artifact/install/capture/types modules behind the same public facade.The public
parseAndroidSnapshotHelperSnapshot()convenience wrapper was dropped; providers can composeparseAndroidSnapshotHelperOutput()withparseAndroidSnapshotHelperXml()when they need to parse raw instrumentation output.Touched files: 36. Scope stayed within Android snapshot helper implementation, packaging/release workflow, snapshot metadata plumbing, tests, and docs.
Follow-up issue: #455 tracks install-result caching, standalone release APK smoke, toast capture investigation, and secondary-display investigation.
Validation
pnpm formatpnpm lintpnpm typecheckpnpm buildpnpm test:unit src/platforms/android/__tests__/snapshot-helper.test.ts src/platforms/android/__tests__/snapshot.test.tspnpm test:smokeAGENT_DEVICE_STATE_DIR=<tmp> node --experimental-strip-types src/bin.ts test test/integration/replays/android --retries 2 --report-junit test/artifacts/replays-android-full-helper.junit.xml(6 passed, 0 failed)androidSnapshot.backend = "android-helper",captureMode = "interactive-windows",windowCount = 2,nodeCount = 91pnpm test:unit src/platforms/android/__tests__/index.test.ts src/platforms/android/__tests__/snapshot-helper.test.ts src/platforms/android/__tests__/snapshot.test.ts src/__tests__/client-shared.test.tspnpm test:unit src/platforms/android/__tests__/snapshot-helper.test.ts src/platforms/android/__tests__/snapshot.test.ts src/__tests__/client-shared.test.tspnpm test:unit src/__tests__/client-metro-packaged.test.tspnpm package:android-snapshot-helperpnpm package:android-snapshot-helper:npmnpm pack --dry-run --json --ignore-scriptsverified npm tarball includes helper APK + manifest and excludes.idsignode --experimental-strip-typespnpm check:fallow --base origin/mainpnpm check:quickpnpm check:toolingpnpm check:unitgit diff --checkapksigner verify --print-certspnpm test-app:installpnpm test-app:typecheckPixel_9_Pro_XLAVD withexamples/test-appvia Expo Go and helper artifact:androidSnapshot.backend = "android-helper",waitForIdleTimeoutMs = 500,nodeCount = 69dismiss-noticepress +diff snapshot -ihome-open-catalog, fillid="catalog-search"withtart, helper snapshot saw filtered catalog contentload-diagnostics, helper snapshot sawretry-diagnosticsKnown gap: no standalone release APK install smoke outside Expo Go; helper APK itself was built and exercised on the emulator above.