Skip to content

feat: automated widget screenshot via UIAutomator2 + GitHub Actions - #6

Merged
digitalby merged 34 commits into
mainfrom
feature/real-screenshots
Apr 6, 2026
Merged

feat: automated widget screenshot via UIAutomator2 + GitHub Actions#6
digitalby merged 34 commits into
mainfrom
feature/real-screenshots

Conversation

@digitalby

Copy link
Copy Markdown
Owner

Summary

  • Adds a UIAutomator2 instrumented test (WidgetScreenshotTest) that places the Debug Mode widget on the AOSP Launcher3 home screen and captures a full-resolution screenshot via UiDevice.takeScreenshot()
  • Adds a GitHub Actions workflow (.github/workflows/screenshots.yml) that runs the test on a KVM-accelerated API 33 emulator and commits the result back to the branch automatically
  • Commits the resulting screenshot to fastlane/metadata/android/en-US/images/phoneScreenshots/01_widget.png

Test plan

  • Workflow ran green on the feature/real-screenshots branch (see CI history)
  • 01_widget.png shows the widget on the home screen with USB Debugging chip visible
  • Re-triggering the workflow via workflow_dispatch produces an updated screenshot without manual steps

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 130cfd638a

ℹ️ 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".

private fun takeScreenshot() {
val out = File("/sdcard/Pictures/01_widget.png")
out.parentFile?.mkdirs()
device.takeScreenshot(out, 1.0f, 100)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail test when screenshot capture reports failure

UiDevice.takeScreenshot(...) returns a boolean and does not throw on all write failures, but this result is currently ignored. If /sdcard/Pictures/01_widget.png cannot be written (for example due to storage access constraints), the instrumentation test still passes and CI can treat the run as successful while keeping a stale screenshot. Check the return value and fail the test when capture returns false.

Useful? React with 👍 / 👎.

Comment thread .github/workflows/screenshots.yml Outdated
adb shell cmd statusbar collapse
sleep 1
adb shell am instrument -w -e class info.yuryv.androiddebugmode.screenshot.WidgetScreenshotTest info.yuryv.androiddebugmode.test/androidx.test.runner.AndroidJUnitRunner
adb pull /sdcard/Pictures/01_widget.png fastlane/metadata/android/en-US/images/phoneScreenshots/01_widget.png || true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Stop masking missing screenshot pull failures

The workflow swallows adb pull errors with || true, so a missing /sdcard/Pictures/01_widget.png does not fail the job. In that scenario the run can end as "successful" with "Screenshot unchanged" even though capture failed, which defeats the automation goal. Let this command fail (or add an explicit file-existence check) so broken screenshot runs are surfaced.

Useful? React with 👍 / 👎.

digitalby and others added 29 commits April 6, 2026 05:43
Hierarchy/text dumps go via Log.d("WDIAG") since the test process cannot
write files outside /sdcard/ without the accessibility service. CI now
pulls all /sdcard/Pictures/ screenshots and captures logcat filtered to
WDIAG so widget picker state is visible in artifacts on failure.
…eads-up notifications

Launcher3 needs a force-stop/restart to pick up newly installed widget providers;
without it the app section never appears in the picker. Heads-up notifications
(serial console) were appearing mid-transition and interfering with the widget
picker. Also switch scrollUntilVisible to UiScrollable so the scroll stays
inside the Launcher3 RecyclerView and cannot accidentally dismiss the picker.
…ble TextView

UIAutomator ACTION_CLICK does nothing on a non-clickable view; device.click(x,y)
sends a raw touch event that propagates to the parent container's onClick. Also
prefer By.clickable(true).hasDescendant(By.text("Widgets")) so the correct target
is identified before falling back to coordinate tap.
…ment failure

set -e ensures CI fails if adb instrument exits non-zero. Pre-click screen
capture and CLICK_TARGET log reveal exactly what element is being tapped and
whether the notification shade is already open at click time.
…is accessible

The emulator's persistent Serial console notification expands the notification
shade and covers the Launcher3 widget picker during its open transition. Force-
collapse it via cmd statusbar collapse both in CI (before test) and in the test
itself (after clicking Widgets, before waiting for the picker scrollable).
…popup row

By.clickable(true).hasDescendant(By.text("Widgets")) returns the outermost
clickable container covering all 3 popup items, not the specific Widgets row.
device.click() on that container doesn't reach the individual item's onClick.
shell("input tap x y") at the Widgets TextView centre goes through the native
input pipeline and is delivered directly to the OptionItem's click handler.
The widget tile sits at ~y=830 (⅓ of 2400px screen); dropping at displayHeight/3
was placing the drag endpoint inside the picker itself. Dropping at displayHeight/8
(y=300) ensures the gesture crosses into the home screen area above the picker
during Launcher3's drag-to-place transition. Increase steps to 120 for a slower
gesture that gives Launcher3 time to register the long-press-to-drag.
…drag to guarantee long-press fires before movement
@digitalby
digitalby force-pushed the feature/real-screenshots branch from 9532126 to 1d61198 Compare April 6, 2026 03:43
@digitalby
digitalby merged commit a4bc78e into main Apr 6, 2026
@digitalby
digitalby deleted the feature/real-screenshots branch April 6, 2026 03:49
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