.claude/skills/ado-test/SKILL.md
Use when testing and verifying a bug fix or feature for an ADO ticket. Triggers on /ado-test, "test ticket", or requests to test a ticket number.
npx skillsauth add Vvanlaar/orch ado-testInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Fetch ADO ticket + linked PR → understand what changed → test the fix on acc → update ticket state to "Tested".
Read
~/.claude/skills/_ado-shared.mdfor auth, env vars, fetch/update ticket patterns, and Windows/MSYS2 notes.
| Setting | Value |
|---------|-------|
| Environment | acc (acceptance) |
| Default publication | testsuite.acc.bbvms.com |
| Base URL | https://testsuite.acc.bbvms.com/{endpoint} |
| Email | [email protected] |
| Password | iwilltestthingsLIKEABOSS |
$expand=all (see shared) — extract description, acceptance criteria, test notes, repro stepsMicrosoft.VSTS.Common.Resolution field or relations (same as ado-review)gh pr diff <NUMBER> --repo <OWNER/REPO> — understand exactly what code changedPR link is typically in Microsoft.VSTS.Common.Resolution as an <a href="..."> tag:
node -e "const html='RESOLUTION_HTML'; const m=html.match(/href=\"(https:\/\/github\.com\/[^\"]+)\"/); console.log(m?m[1]:'NO_PR_FOUND')"
Also check relations for ArtifactLink entries with vstfs:///Git/PullRequestId/. If none found, ask user.
# Once you have PR number + repo:
gh pr diff <NUMBER> --repo <OWNER/REPO>
gh pr view <NUMBER> --repo <OWNER/REPO> --json title,body,files
Use when the ticket involves the native Android SDK.
Repo: bluebillywig/bbnativeplayersdk-demo
Path: app/apk/debug/app-debug.apk (branch: master)
Before testing, verify the APK commit matches the expected SDK version:
gh api "repos/bluebillywig/bbnativeplayersdk-demo/commits?path=app/apk/debug/app-debug.apk&per_page=1" \
--jq '.[0] | {sha: .sha[:7], message: .commit.message, date: .commit.author.date}'
The commit message should reference the SDK version from the ticket (e.g. upped bbnativeplayersdk to 8.43-0-SNAPSHOT, apk). If the version doesn't match the ticket, do not proceed — ask the user to push the correct APK first.
/tmp/ resolves to C:\tmp\ in MSYS2 — always use $LOCALAPPDATA/Temp.
Check cached APK first; only re-download if the GitHub commit SHA has changed:
APK_PATH="$LOCALAPPDATA/Temp/app-debug.apk"
SHA_PATH="$LOCALAPPDATA/Temp/app-debug.apk.sha"
# Get latest commit SHA for the APK file
LATEST_SHA=$(gh api "repos/bluebillywig/bbnativeplayersdk-demo/commits?path=app/apk/debug/app-debug.apk&per_page=1" \
--jq '.[0].sha')
LATEST_MSG=$(gh api "repos/bluebillywig/bbnativeplayersdk-demo/commits?path=app/apk/debug/app-debug.apk&per_page=1" \
--jq '.[0].commit.message')
echo "Latest: $LATEST_MSG ($LATEST_SHA)"
CACHED_SHA=$(cat "$SHA_PATH" 2>/dev/null || echo "none")
if [ "$LATEST_SHA" = "$CACHED_SHA" ] && [ -f "$APK_PATH" ]; then
echo "APK up to date, using cached version"
else
echo "New version detected — downloading..."
# Remove old APK before downloading new one
rm -f "$APK_PATH"
curl -sL -o "$APK_PATH" \
"https://github.com/bluebillywig/bbnativeplayersdk-demo/raw/master/app/apk/debug/app-debug.apk"
echo "$LATEST_SHA" > "$SHA_PATH"
echo "Downloaded: $(ls -lh "$APK_PATH" | awk '{print $5}')"
fi
emulator is not on PATH. Use full path. ANDROID_SDK_ROOT must be set. Use PowerShell to detach the process (bash & doesn't work for Windows GUI apps):
# List AVDs
/c/Users/vince/AppData/Local/Android/Sdk/emulator/emulator.exe -list-avds
# Start (PowerShell detaches properly; bash & does not)
powershell.exe -Command "Start-Process -FilePath 'C:\Users\vince\AppData\Local\Android\Sdk\emulator\emulator.exe' -ArgumentList '-avd','<AVD_NAME>','-no-snapshot-load' -WindowStyle Normal"
# Poll for boot (takes ~45s)
for i in $(seq 1 30); do
BOOT=$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r\n')
if [ "$BOOT" = "1" ]; then echo "BOOTED"; break; fi
echo "[$i] waiting..."; sleep 5
done
Available AVDs: Medium_Phone_API_35 (system image missing — don't use), Pixel_8_Pro (API 36, works ✅)
adb install -r "$LOCALAPPDATA/Temp/app-debug.apk"
# Launch (package name for bbnativeplayersdk-demo):
adb shell monkey -p com.bluebillywig.bbnativeplayersdk_demo -c android.intent.category.LAUNCHER 1
screencap -p flag is deprecated on newer API levels. Use exec-out pipe:
adb exec-out screencap -p > "$LOCALAPPDATA/Temp/screen.png"
# Then Read: C:\Users\vince\AppData\Local\Temp\screen.png
Get exact tap coordinates from UI dump — always use MSYS_NO_PATHCONV=1 to prevent path translation:
MSYS_NO_PATHCONV=1 adb shell uiautomator dump /data/local/tmp/ui.xml
MSYS_NO_PATHCONV=1 adb shell "cat /data/local/tmp/ui.xml" > "$LOCALAPPDATA/Temp/ui.xml"
node << 'NS'
const xml = require('fs').readFileSync(require('path').join(require('os').tmpdir(), 'ui.xml'), 'utf8');
[...xml.matchAll(/text="([^"]+)"[^>]*bounds="\[(\d+),(\d+)\]\[(\d+),(\d+)\]"/g)].forEach(m => {
const cx = Math.round((+m[2] + +m[4]) / 2), cy = Math.round((+m[3] + +m[5]) / 2);
console.log(`"${m[1]}" => tap ${cx},${cy}`);
});
NS
adb shell input tap <X> <Y>
For NumberPicker scroll: adb shell input swipe <x> <from_y> <x> <to_y> 300 (swipe up = next item).
adb logcat -c # clear buffer
MSYS_NO_PATHCONV=1 adb logcat -d -s BBNativePlayer:* BBNativePlayerView:* ProgramController:* \
| grep -i "seek\|error\|exception" | head -40
adb shell pm list packages | grep -i <appname>
adb uninstall <com.package.name>
mcp__chrome-devtools__new_page url="https://testsuite.acc.bbvms.com" (redirects to /ovp/#/login)mcp__chrome-devtools__take_snapshot — get form UIDsmcp__chrome-devtools__fill_form elements=[
{"uid": "1_6", "value": "[email protected]"},
{"uid": "1_8", "value": "iwilltestthingsLIKEABOSS"}
]
mcp__chrome-devtools__click uid="1_11"/ovp/#/homeUse evaluate_script to make session-authenticated API calls:
mcp__chrome-devtools__evaluate_script function="async () => {
const response = await fetch('/sapi/endpoint', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'sesstoken': 'set' },
body: JSON.stringify({ ... })
});
return { status: response.status, body: await response.text() };
}"
Session maintained via VMS_SESSION cookie. sesstoken: set required for write operations.
For /sapi/ endpoints without browser session, use rpctoken:
{id}-{secret} (from OVP: Publication Settings > Upload credentials){id}-{totp_code} — TOTP via HOTP algorithm, 120s window, 10-digit outputcurl -H "rpctoken: {id}-{totp_code}" "https://testsuite.acc.bbvms.com/sapi/mediaclip?id=1"
source ~/.env && B64=$(printf ':%s' "$ADO_PAT" | base64 -w0)
curl -s -H "Authorization: Basic $B64" -X PATCH \
-H "Content-Type: application/json-patch+json" \
"https://dev.azure.com/bluebillywig/BBNew/_apis/wit/workitems/<ID>?api-version=7.0" \
-d '[{"op":"replace","path":"/fields/System.State","value":"Tested"}]'
## Test Results: ADO #<ID> — <Title>
**Environment:** testsuite.acc.bbvms.com
**State:** Tested ✅ / Failed ❌
### What was tested
<brief description>
### Results
| Test | Result | Notes |
|------|--------|-------|
| <test name> | ✅/❌ | <details> |
### Static Code Verification ✅/❌
<findings — stale refs, imports, etc.>
### Conclusion
**ADO #<ID> fix verified/failed.** <1-sentence summary>
| Mistake | Fix |
|---------|-----|
| Using -u ":$ADO_PAT" for auth | Use manual base64 (see shared) |
| Testing on prod | Default to acc environment |
| Skipping ticket fetch | Always read ticket first — acceptance criteria drive the test |
| Not checking for stale code | Search codebase even for "simple" fixes |
| Setting state without testing | Verify all criteria before moving to "Tested" |
| Writing to /tmp/ | Resolves to C:\tmp\ — use $LOCALAPPDATA/Temp or require('os').tmpdir() |
| adb shell uiautomator dump /sdcard/... | MSYS2 translates path — use MSYS_NO_PATHCONV=1 adb shell uiautomator dump /data/local/tmp/ui.xml |
| adb pull /sdcard/... | MSYS2 translates /sdcard → C:\...\sdcard — use adb shell "cat /path" instead |
| Starting emulator with & in bash | Doesn't detach on Windows — use powershell.exe -Command "Start-Process ..." |
| emulator not on PATH | Full path: /c/Users/vince/AppData/Local/Android/Sdk/emulator/emulator.exe |
| screencap -p /sdcard/... | Use adb exec-out screencap -p > "$LOCALAPPDATA/Temp/screen.png" instead |
| Reading screenshot with Read tool | Path must be Windows: C:\Users\vince\AppData\Local\Temp\screen.png |
| Tapping wrong coords | Get exact coords via uiautomator dump + node; screen is 1344x2992 on Pixel_8_Pro |
| Medium_Phone_API_35 AVD | System image not installed — use Pixel_8_Pro (API 36) |
tools
Sync GitHub repos from bluebillywig org to an ADO "Repository" picklist field on all work item types
development
Build a new desktop app release (Electron). Triggers on "build desktop", "new release", "desktop release", "build the app"
development
Generic Azure DevOps operations — edit tickets, query work items, add comments, change fields, move sprints, assign users, link items, and more. Triggers on "ado", "edit ticket", "update ticket", "move ticket", "assign ticket", "link ticket", "query ado", "search ado", "add comment to ticket", or ticket number mentions with edit/update intent.
development
Use when starting work on an Azure DevOps ticket. Triggers on "start ticket", "work on ticket", ticket number with implementation intent, or requests to plan a feature from a ticket.