feat: demo-mode screenshot suite and cluster build pod - #381
Merged
Conversation
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]>
This was referenced Sep 10, 2026
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.
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, launchesMainActivitythrough the existingEXTRA_NAVIGATE_TOintent 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.scripts/take-screenshots.sh.These images come from the local
Medium_Phone_API_36.1AVD (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 runningghcr.io/cirruslabs/android-sdk:36with 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.gitcarries HEAD forBuildConfig.GIT_SHA), runs./gradlewin the pod, syncsapp/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 filesmake screenshots)Supersedes #271 (Fastlane screengrab PoC), which needed Docker, Ruby, the mock server and a real Teslamate URL.
🤖 Generated with Claude Code