fix: unblock Android e2e build (fonts + react-native-keys patch) - #39
Merged
Conversation
Bring the Android agent-device e2e to a genuinely working, gated state on SDK 56 / RN 0.85: - Placeholder Unica77LL fonts before prebuild (gitignored; from private S3). - Compile Relay before the release bundle (Metro resolves co-located queries). - Build a RELEASE APK (embeds JS, drops the expo-dev-client launcher) with SENTRY_DISABLE_AUTO_UPLOAD (no token in OSS CI); install app-release.apk. - Harden launch: retry the flow up to 3x, force-stopping the app between tries, to absorb agent-device's intermittent app-launch flake (home launcher occasionally stays foreground). Drop continue-on-error so the manual job now reflects the real launch-smoke result. - Fix the flow assertion syntax: `is visible "Folio"`. - Cache Gradle + Yarn across runs to speed the build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
MounirDhahri
force-pushed
the
claude/fix-e2e-fonts
branch
from
July 10, 2026 22:02
1082b45 to
d7f0531
Compare
react-native-keys@0.7.13's android/build.gradle doesn't declare compileSdk and can't locate the RN android sources on RN 0.81+, so AGP fails to configure the :react-native-keys project (`does not specify compileSdk`). Apply the same patch Eigen uses (adds the ReactAndroid source path + resolver fallbacks, renames compileSdkVersion->compileSdk, adds SDK fallbacks). Without this, ANY Android build on main fails — not just e2e. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
The iOS job ran only agent-device doctor + test with no prebuild, pod install, Xcode build, or booted simulator — so it reported green while validating nothing. A misleading pass is worse than no job. Replaced it with a clearly-labeled commented-out block plus a step-by-step guide for wiring up a real build+simulator flow (mirroring the Android job). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
The android-emulator-runner action runs its `script:` input line-by-line (each line in its own `sh -c`), so the inline multi-line `until … done` retry loop was split across shells and failed with 'Syntax error: end of file unexpected (expecting done)' — the e2e test never actually ran even though the release APK built and installed cleanly. Move install + retry into e2e/scripts/android-e2e.sh and invoke it as a single line so the loop stays intact in one shell. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
agent-device's `is` command takes a predicate plus a selector expression (e.g. `is visible text="Folio"`). The flow used a bare quoted string (`is visible "Folio"`), which the runtime rejects with 'is requires a selector expression' — so the smoke check failed at step 3 on every retry even though the app launched and the Login screen rendered (steps 1-2, `open`/`wait "Log In"`, both passed). Confirmed 'Folio' is rendered on the Login screen (src/Scenes/Login/Login.tsx). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
Run on 643077f failed at step 2 on all 3 retries: 'nexuslauncher is foreground instead of net.artsy.energy' — the app didn't come to the foreground. This is a boot-timing flake (the same build launched and rendered fine on the prior run); the test started ~9s after boot_completed while the launcher/PackageManager were still settling, so open's launch intent was dropped. Two-layer fix: - Flow: 'open Energy --relaunch' (real cold launch by package) + 'wait --connected' (block until the app is actually foreground) before asserting. - Script: wait for the boot animation to stop + a short settle before the first attempt, so we don't race a half-booted system. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
…acts Run the suite with --debug (verbose CLI/daemon diagnostics), --record-video and --artifacts-dir, and on every attempt (pass or fail) capture a device screenshot, the foreground window/activity, and recent logcat into e2e-artifacts/. Upload e2e-artifacts/ plus agent-device's own test-artifacts/ via actions/upload-artifact (if: always()) so a run can be inspected after the fact — this is what lets us see what's actually on screen when a launch flakes, instead of inferring it from the foreground-package error. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
Alongside the screenshot/logcat, capture an agent-device accessibility snapshot (structured --json + human-readable text) of whatever is on screen on every attempt. Uses --platform android so it attaches to the foreground app without the now-closed test session, and runs before the force-stop so it reflects the failed state. The snapshot shows the actual view tree (labels/roles/refs) — more diagnostic than pixels for 'did the app render'. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
The bb98a12 run proved the app launches and renders on RN 0.85 — the agent-device 'Current surface' at the failure was 'Folio, Log In, With Your Artsy Partner Account, show password icon' (the Login screen). The launcher- foreground flake is gone (open --relaunch fixed it). The only failure was a bad flow step: in a .ad replay, 'wait <arg>' waits for on-screen TEXT, so 'wait --connected' was interpreted as the literal text '--connected' and timed out. --connected is a standalone-CLI-only flag. Remove it; 'wait "Log In"' already blocks until the first screen renders. Also echo foreground.txt + snapshot.txt into the CI log from capture_evidence, since the uploaded artifact is on an egress-blocked host — this keeps runs diagnosable from the logs alone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
The captured foreground dump showed the real cause of the wait "Log In" failures: net.artsy.energy/.MainActivity IS the topResumedActivity (the app launches fine on RN 0.85), but under CI emulator load the Pixel launcher itself ANRs and its 'Application Not Responding' dialog steals window focus, so agent-device sees nexuslauncher as foreground and wait fails. Fix: suppress system error dialogs (settings put global hide_error_dialogs 1) so nothing steals focus, extend the post-boot settle, and give the emulator more headroom (cores: 3, ram-size: 4096M, disable-animations) so the launcher is less likely to ANR while the app cold-starts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR resolves [the Android agent-device e2e build failing before it could reach the app]
Description
Two fixes that let the manual Android e2e job actually build, install, and boot the app on a real emulator in CI. Both were found by triggering the real
workflow_dispatchAndroid run and reading the logs.1. Placeholder fonts before
expo prebuildThe
expo-fontconfig plugin (seeapp.json) reads Artsy'sUnica77LL-*.otffonts fromassets/fonts. Those are gitignored and normally fetched byyarn setup:artsyfrom a private S3 bucket, which isn't available in OSS CI — soexpo prebuildfailed withENOENT ... Unica77LL-Italic.otf. A CI step now creates empty placeholder.otfs before prebuild so it resolves; the smoke test doesn't depend on the real glyphs (the app falls back to system fonts). Artsy engineers still get the real fonts locally viayarn setup:artsy.2. Patch
react-native-keysfor RN 0.83 Androidreact-native-keys@0.7.13'sandroid/build.gradlecouldn't locate the React Native android sources on RN 0.81+ (sources moved toreact-native/ReactAndroid) and used the removedcompileSdkVersionDSL, so./gradlew assembleDebugfailed configuring:react-native-keys. This applies the same patch Eigen uses (.yarn/patches/react-native-keys-npm-0.7.13-...patch): add theReactAndroidsource path + resolver fallbacks, renamecompileSdkVersion→compileSdk, and add SDK-version fallbacks.Verified on a real emulator
Triggered the Android
workflow_dispatchrun after these fixes. It now goes green through the whole native path:expo prebuild(was ❌ missing fonts)./gradlew assembleDebug— debug APK built (was ❌ on:react-native-keys)Streamed Install: Success)launch-smokeflowKnown follow-up (not fixed here)
The
launch-smokeflow itself still fails its assertion on the emulator: the debug build boots into the Expo dev-client launcher ("Fetch development servers",exp://) rather than the app, because there is no Metro bundler / embedded JS bundle in CI, so "Log In" never renders. Making the smoke assertion pass needs either Metro running + a dev-client deep link, or a bundled/release build. The emulator step stayscontinue-on-error: trueand the job stays manual and non-blocking, so this does not gate anything.PR Checklist
To the reviewers 👀
🤖 Generated with Claude Code
https://claude.ai/code/session_01KPWjhmaeq8DnsiiFD9Eg7A
Generated by Claude Code