From 0b67cb952a471fe559712e16503541f651e91f9d Mon Sep 17 00:00:00 2001 From: Jason Ross Date: Sat, 4 Jul 2026 00:22:24 -0500 Subject: [PATCH] fix(test-infra): make local_instrumented.sh CWD-independent The wrapper jar path was resolved from the script's own location, but gradlew picks the *project* to build from the process's current directory, not from its own script location. Invoking the helper from a CWD outside its tree (e.g. another worktree) silently built the wrong repo's :app, once observed as a ClassNotFoundException for a test class that only existed in the intended worktree. cd to the already-resolved repo/worktree root before invoking gradlew so connectedDebugAndroidTest always targets the correct tree regardless of the caller's CWD. Update the README's usage note to match. Closes #284 Co-Authored-By: Claude Opus 4.8 --- .claude/skills/preflight/local_instrumented.README.md | 9 ++++++++- .claude/skills/preflight/local_instrumented.sh | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.claude/skills/preflight/local_instrumented.README.md b/.claude/skills/preflight/local_instrumented.README.md index 6128726..44ece27 100644 --- a/.claude/skills/preflight/local_instrumented.README.md +++ b/.claude/skills/preflight/local_instrumented.README.md @@ -8,12 +8,19 @@ Managed Devices (GMD). Companion to `api37_e2e.py`; born from issue #269. ## Usage ```bash -# from the repo root, in Git Bash: +# in Git Bash, from anywhere — invoke the script by path: .claude/skills/preflight/local_instrumented.sh org.libremail.ui.compose.ComposeScreenE2ETest # multiple classes (comma-separated, no spaces): .claude/skills/preflight/local_instrumented.sh org.libremail.a.FooTest,org.libremail.b.BarTest ``` +The script is CWD-independent: it resolves its own repo/worktree root from its script +location (three directories up from `.claude/skills/preflight`) and `cd`s there before +invoking gradlew, so it always builds *that* tree's `:app` — never whatever tree your +shell happens to be sitting in. This matters most when you have several worktrees +checked out side by side; run the copy of this script that lives inside the worktree you +want to test, regardless of your current directory (issue #284). + It cold-boots **one** emulator (`-no-snapshot`, no GMD), waits for `sys.boot_completed`, runs `:app:connectedDebugAndroidTest` filtered to the class(es) you pass, then tears the emulator down and verifies no orphaned `qemu` process is left behind (exit **3** if one is). diff --git a/.claude/skills/preflight/local_instrumented.sh b/.claude/skills/preflight/local_instrumented.sh index b19ef77..328ac63 100755 --- a/.claude/skills/preflight/local_instrumented.sh +++ b/.claude/skills/preflight/local_instrumented.sh @@ -129,6 +129,14 @@ command -v tasklist >/dev/null 2>&1 || die "tasklist not found — this helper t die "AVD '${AVD_NAME}' not found under '${AVD_HOME}'. Set LOCAL_INSTRUMENTED_AVD / ANDROID_AVD_HOME. (GMD AVDs are created by any local apiXXDebugAndroidTest run.)" +# Move into the resolved repo/worktree root before invoking gradlew. GRADLEW above is an +# absolute path, but the gradlew wrapper script picks the *project* to build from the +# process's current directory, not from its own script location — so without this `cd`, +# running this helper from a different tree (e.g. another worktree, or the main repo +# while iterating on a worktree's copy of this script) silently builds the CALLER's CWD +# tree instead of this one (issue #284). +cd "${REPO_ROOT}" || die "Could not cd to repo root '${REPO_ROOT}'." + export JAVA_HOME="${JDK_HOME}" export ANDROID_AVD_HOME="${AVD_HOME}"