Linear: https://linear.app/engineereddev/issue/ENG-268
What's in this PR (three commits):
- Harness
scripts/e2e/android.ts(nowmise run e2e:android): harness MinIO and the built server on a random port (PUBLIC_URL=http://10.0.2.2:<port>, proxy mode),dev-client setup+pair-uri, a secondclisender session, credentials handed to the device through an app-private file (not runner args), the managed-device task,adbDoze control, a secret scan over Gradle output, instrumentation results, server log and logcat, and full teardown. RealServerSmokeTest(UiAutomator + Compose): deep-link pair → Confirm → Pair; Connected; note → Copy → clipboard read from the foregroundMainActivity; link → Open (ACTION_VIEWvia espresso-intents) and Copy; 1 MiB file → Download → Open/Share → SHA-256 via MediaStore; Home composer send-back confirmed by the harness; Home + forced Doze + note + unforce → notification within 30 s. Skips cleanly without harness arguments, so the plain Gradle task still runs the other 14 tests.- Production fix (separate commit, bug from ENG-266): the 1 MiB download made 101 notification posts in one second, Android shed the terminal "Download complete" post, and Open/Share never appeared. Upload/download progress posts now need a changed percentage and ≥ 500 ms spacing; initial and terminal posts bypass the throttle.
TransferProgressThrottle+ JVM tests. - Test-only dependencies: UiAutomator 2.3.0, Espresso Intents 3.7.0.
mise.tomle2e:androidtask andapp/build.gradle.ktsrunner settings changed.
Verify (lead, on 8176869):
mise run check:android→ exit 0./gradlew testDebugUnitTest --rerun→ exit 0 (350 tests, 0 failures)mise run e2e:android→ exit 0, twice in a row; each run: "PASS managed-device suite including real-server smoke", "Secret scan (Gradle, instrumentation results, server, logcat): 0 matches", "PASS emulator, server, MinIO and credential cleanup"- Afterwards: no
pneumo-e2e-containers, no MinIO or emulator listeners.
Deviations: proxy mode only (permitted); ATD has no interactive shade, so the test fires the real posted notification's PendingIntents; clipboard read from the foreground activity (no debug probe); credentials via an app-private file.
🤖 Generated with Claude Code