Skip to content

feat: demo-mode screenshot suite and cluster build pod - #381

Merged
vide merged 3 commits into
mainfrom
feat/demo-mode-screenshots
Sep 10, 2026
Merged

feat: demo-mode screenshot suite and cluster build pod#381
vide merged 3 commits into
mainfrom
feat/demo-mode-screenshots

Conversation

@vide

@vide vide commented Sep 10, 2026

Copy link
Copy Markdown
Owner

What this does

Replaces the hand-run adb screenshot script with an instrumented suite that captures the README gallery from demo mode, and adds the tooling to run Gradle on the homelab cluster instead of the laptop. This is PR 1 of the plan; PR 2 adds the GitHub Actions workflow that runs the suite on a hosted emulator and opens a PR with refreshed images.

All 11 gallery images in docs/screenshots/ are regenerated from demo data (no more manual blurring of the car name and location), and Current Charge joins the gallery.

Screenshot suite

  • ScreenshotsTest + ScreenshotSpecs (app/src/androidTest/.../screenshots/): one Parameterized test case per screen. Enters demo mode by writing the settings DataStore directly (same process as the app), pre-answers the notification prompt, launches MainActivity through the existing EXTRA_NAVIGATE_TO intent extras, waits for a string that only exists once the data is on screen, crops by the window's real system-bar insets, scales to 576 px and writes a JPEG into AGP's additional-test-output directory. Detail screens are reached by tapping the first clickable row that has the expected text as a descendant. Visited Countries waits for the row count to settle. On a failed wait it dumps the accessibility hierarchy and a raw frame next to the output, which is how the three wrong markers in this PR were found.
  • DemoMode.clock (internal, system clock by default): lets the suite pin the demo clock so the live charging session is in a known phase. Only used when the device clock can be pinned too, otherwise the dashboard's "since" durations would disagree with the data.
  • scripts/screenshots.sh / make screenshots [SCREENS=a,b]: picks the device, sets light theme, 24h clock, animations off, hides ANR dialogs, pins both clocks on rootable devices (default: today 09:00 UTC, inside a charging phase), runs the suite, copies the images and regenerates the README gallery between <!-- screenshots:start/end --> from the manifest the suite writes. Device state is restored on exit.
  • Removes scripts/take-screenshots.sh.

These images come from the local Medium_Phone_API_36.1 AVD (Play image, so not rootable, run inside a charging phase). Once PR 2 lands, the CI emulator is the canonical source.

Remote builds

  • util/k8s-build/matedroid-build.yaml: namespace, PVC and a Deployment running ghcr.io/cirruslabs/android-sdk:36 with a persistent Gradle home. Applied by hand, not through ArgoCD (developer tooling, not an app).
  • scripts/remote-gradle.sh <tasks> / make remote-check: rsyncs the tree in (git-ignored files, .git/ and build dirs excluded; a stub .git carries HEAD for BuildConfig.GIT_SHA), runs ./gradlew in the pod, syncs app/build/{outputs,reports,test-results} back. Cold lint + unit tests: 3m16s; warm lint: 1m09s.

Checks

  • ./scripts/remote-gradle.sh lintDebug testDebugUnitTest: build successful, 154 unit tests, lint clean for the new files
  • Screenshot suite: 11/11 captured on the local emulator (make screenshots)

Supersedes #271 (Fastlane screengrab PoC), which needed Docker, Ruby, the mock server and a real Teslamate URL.

🤖 Generated with Claude Code

vide and others added 3 commits September 10, 2026 11:24
DemoTeslamateApi read Instant.now() directly, so the dataset's anchor and
the live charging session followed wall-clock time. DemoMode.clock (internal,
system clock by default) lets the screenshot suite pin both to a fixed
instant; the app never touches it.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Adds util/k8s-build/matedroid-build.yaml (namespace, PVC, Deployment with
the cirruslabs Android SDK image and a persistent Gradle home) and
scripts/remote-gradle.sh, which rsyncs the working tree into the pod,
runs ./gradlew there and syncs outputs, reports and test results back.

The laptop was OOM-killing Gradle whenever an emulator ran alongside it.
Device-bound tasks stay local; everything else goes to the pod.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
ScreenshotsTest drives the app in demo mode on any device or emulator, one
Parameterized case per screen: it enters demo mode by writing the settings
directly, launches MainActivity through the EXTRA_NAVIGATE_TO deep links,
waits for a marker that only exists once data is on screen, crops by the
window's real system-bar insets and writes 576 px JPEGs plus a gallery
manifest into AGP's additional test output. Detail screens are reached by
tapping the first row whose descendants carry the expected text; failed
waits dump the accessibility hierarchy for diagnosis.

scripts/screenshots.sh prepares the device (light theme, 24h clock, no
animations, ANR dialogs hidden, clocks pinned where the device is rootable),
runs the suite, copies the images and regenerates the README gallery block
from the manifest. Replaces scripts/take-screenshots.sh.

All gallery images are regenerated from demo data, so nothing needs blurring
any more, and Current Charge joins the gallery.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
@vide
vide merged commit ca873e6 into main Sep 10, 2026
1 check passed
@vide
vide deleted the feat/demo-mode-screenshots branch September 10, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant