skills/ah-check-qa/SKILL.md
Run UI/UX quality assurance checks with the 'ah' prefix. Use for 'ah check qa', or to verify visual correctness, responsive layout, interactive elements, E2E smoke flows, console/network errors, or before/after screenshots. Modular via a `checks` switch (presets smoke|visual|perf|a11y|full or a group list; defaults to a fast `smoke` check). Uses the agent-browser CLI against any localhost dev server, Storybook, or live URL.
npx skillsauth add arinhubcom/arinhub ah-check-qaInstall 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.
Run UI/UX quality checks via agent-browser: visual inspection, screenshots,
Core Web Vitals audits, interaction testing, E2E flow verification. Auto-discovers routes,
detects dev server, generates QA report with screenshots as evidence.
Load the agent-browser skill and run agent-browser skills get core for command syntax/flags help.
Diagnostic scripts in scripts/. Inject by piping their content into
agent-browser eval --stdin (wrapped as an IIFE) after reading their content --
no manual editing, they scan full page.
before to capture baseline screenshots for later comparison.
Without before when baselines already exist, auto-enters comparison mode.checks <preset|group-list> scopes which checks run. Accepts a
preset name (see Check Scope below) or a comma-separated group list (e.g.
checks visual,console). Unknown tokens -> warn and fall back to smoke. Default
when omitted: smoke (fast structural + console/network + E2E check). Run the full
battery with checks full. Composes with before/baseline and focus.The procedure's checks are grouped so a run can target just what matters. Steps 0
(detect env), 1 (route discovery), 2 (browser), 3 (overlays), and 11 (report) always run;
baseline before mode (step 4) is unchanged. Steps 5-10 run only when their group is in
the selected scope.
| group | covers |
|---|---|
| structure | 5a a11y / structural snapshot review |
| visual | 5b multi-viewport screenshots + 5e visual-audit script |
| vitals | 5c Core Web Vitals |
| trace | 5d + 7 performance trace start / stop / analyze |
| console | 5f console + network errors |
| dark | 5g dark-mode testing (only if HAS_DARK_MODE) |
| interaction | 6 interactive audit, spot-checks, form behavior |
| e2e | 8 navigation / key-flow / state-persistence smoke |
| resilience | 9 resilience / break testing |
| compare | 10 before/after comparison (only if baseline exists) |
Presets compose groups:
| preset | groups |
|---|---|
| smoke (default) | structure, console, e2e |
| visual | structure, visual, dark, compare |
| perf | vitals, trace |
| a11y | structure, interaction |
| full | every group (the legacy behavior) |
Resolve the selection to a concrete SELECTED_GROUPS set once, up front, before step 5.
If no URL provided, find running dev server:
# Check common dev server ports
for port in 3000 3001 5173 5174 4321 8080 8888 6006; do
if curl -s -o /dev/null -w "%{http_code}" "http://localhost:${port}" | grep -qE "^[23]"; then
echo "Dev server found at http://localhost:${port}"
break
fi
done
If no dev server running, stop and tell user to start one.
Detect framework from package.json dependencies:
| Dependency | Framework | Route source |
|---|---|---|
| next | Next.js | app/ or pages/ directory |
| @remix-run/react | Remix | app/routes/ directory |
| vite, react-router | Vite + React Router | Search for createBrowserRouter or <Route |
| nuxt | Nuxt | pages/ directory |
| @angular/core | Angular | app-routing.module.ts or app.routes.ts |
| astro | Astro | src/pages/ directory |
Set up directories:
REPO_NAME=$(basename -s .git "$(git remote get-url origin)" 2>/dev/null || basename "$PWD")
QA_DIR=~/.agents/arinhub/qa-reports
SCREENSHOTS_DIR=${QA_DIR}/${REPO_NAME}/screenshots
mkdir -p "${QA_DIR}" "${SCREENSHOTS_DIR}"
Detect dark mode support via common indicators:
# Check for dark mode in Tailwind config, CSS custom properties, or theme providers
grep -rl "darkMode\|dark:\|prefers-color-scheme\|data-theme\|ThemeProvider" \
--include="*.ts" --include="*.tsx" --include="*.css" --include="*.js" --include="*.jsx" \
--include="*.json" . | head -5
If dark mode detected, set HAS_DARK_MODE=true to include dark mode testing in Step 4.
Scan project to build list of testable routes. Adapt search to detected framework. Vite + React example:
# Find page/route files
find src -name "*.tsx" -o -name "*.jsx" | head -30
# Search for route definitions
grep -rn "path:" src/ --include="*.tsx" --include="*.ts" | head -20
grep -rn "<Route" src/ --include="*.tsx" --include="*.jsx" | head -20
For Next.js:
find app -name "page.tsx" -o -name "page.jsx" 2>/dev/null | head -20
find pages -name "*.tsx" -o -name "*.jsx" 2>/dev/null | grep -v "_app\|_document\|api/" | head -20
Build ROUTES list from discovered files. If focus argument provided, filter to
matching routes only. If no routes discovered, test root URL only.
Route prioritization: When more than 10 routes discovered, prioritize in this order rather than testing everything:
/users/:id) -- test one instance of each patternCap at 8-10 routes unless user explicitly asks for full coverage. Mention skipped routes in report so nothing is silently ignored.
agent-browser tab
The browser auto-starts on the first command. If you hit connection problems:
agent-browser doctor
After navigating to any route throughout this procedure, wait for page to finish loading before screenshots or audits. SPAs and SSR-hydrated apps often show spinners or skeleton screens that disappear once data arrives.
# agent-browser open waits for load on navigation; for a standalone settle after
# the page is already open, pause briefly to let pending requests finish.
sleep 2
After page settles, check for and dismiss blocking overlays (cookie banners, newsletter popups, onboarding modals). These interfere with screenshots and interaction tests:
# Interactive snapshot here (`-i` exposes @e refs) -- fixed-position/backdrop detail
# helps spot overlays. Elsewhere prefer plain `snapshot` when you only need structure;
# add `-i` when you need actionable element refs, since that output is larger.
agent-browser snapshot -i
# Look for common patterns: cookie consent, modal backdrops, dialog elements
# If found, dismiss by clicking accept/close/dismiss buttons, then re-snapshot
agent-browser click @e3
agent-browser snapshot -i
Common overlay indicators in a11y snapshot:
dialog or alertdialogDismiss overlays once at session start. If they reappear on navigation (unlikely but possible), dismiss again. Note any dismissed overlays in report as informational findings.
before argument)Follow procedure in baseline-mode.md. If this mode active, exit after capturing baselines -- skip steps 5-11.
For each discovered route (respecting priority order from Step 1). Each sub-step below runs
only if its group (see Check Scope) is in SELECTED_GROUPS; skip the rest and note them
skipped (not in checks scope) in the report.
structure)agent-browser open "${ROUTE_URL}"
agent-browser snapshot
Review a11y snapshot for structural issues:
img nodes without accessible names)visual)Capture at three breakpoints, check layout issues at each:
# Mobile
agent-browser set viewport 375 812
agent-browser screenshot "${SCREENSHOTS_DIR}/current-mobile-${ROUTE_SLUG}.png"
agent-browser snapshot
# Tablet
agent-browser set viewport 768 1024
agent-browser screenshot "${SCREENSHOTS_DIR}/current-tablet-${ROUTE_SLUG}.png"
# Desktop
agent-browser set viewport 1280 800
agent-browser screenshot "${SCREENSHOTS_DIR}/current-desktop-${ROUTE_SLUG}.png"
At each viewport, review snapshot for responsive issues:
vitals)agent-browser has no Lighthouse. Capture Core Web Vitals instead:
agent-browser vitals "${ROUTE_URL}"
Extract metrics: LCP, CLS, TTFB, FCP, INP. Record any that exceed "good" thresholds (e.g. LCP > 2.5s, CLS > 0.1, INP > 200ms) with descriptions. Note: Lighthouse-specific category scores (Accessibility, Best Practices, SEO) are not available via agent-browser -- rely on the snapshot and audit scripts for accessibility/structure findings.
trace)Start trace after screenshots and the vitals audit are done -- those involve viewport resizes and page manipulation that would pollute the trace. From here, trace captures script injections, clicks, hovers, form fills through Steps 5e-5f and 6.
agent-browser trace start
visual)Read scripts/visual-audit.js and inject it:
{ printf '('; cat scripts/visual-audit.js; printf ')()'; } | agent-browser eval --stdin
Script returns JSON { summary, issues } (broken images, text overflow, elements
outside viewport, empty visible containers). summary has true counts (total,
byType, bySeverity, truncated); issues capped at 50, sorted severity-first.
Use summary for tallies, issues for specifics -- record all findings.
console)agent-browser console
# Only the failed/slow requests matter below -- a chatty route can flood context,
# so focus on error statuses where supported.
agent-browser network requests
From network requests, identify:
dark)If HAS_DARK_MODE=true (detected in Step 0), test current route in dark mode after
light-mode checks above. Catches color contrast failures, invisible text on dark
backgrounds, images without transparent backgrounds clashing with dark surfaces, and
hardcoded colors that ignore theme variables.
# Switch to dark color scheme.
# Note: if agent-browser exposes no color-scheme emulation, force it from the page
# by setting the preference (e.g. toggle the app's theme switch via a click, or
# `agent-browser eval "document.documentElement.classList.add('dark')"` /
# set `data-theme="dark"`) to match how the app activates dark mode.
agent-browser eval "document.documentElement.classList.add('dark')"
# Pause to let the theme transition settle
sleep 1
# Screenshot at desktop viewport (one viewport is enough for theme checks)
agent-browser screenshot "${SCREENSHOTS_DIR}/current-dark-${ROUTE_SLUG}.png"
# Run the visual audit again in dark mode -- different issues surface
{ printf '('; cat scripts/visual-audit.js; printf ')()'; } | agent-browser eval --stdin
Tag any dark-mode-specific findings with [dark] in report. Common dark mode issues:
# Restore light mode before moving to the next route
agent-browser eval "document.documentElement.classList.remove('dark')"
Skip dark mode testing if app has no dark mode support -- false positives from forcing dark scheme on a light-only app are not useful.
interaction)Run only if interaction is in SELECTED_GROUPS; otherwise skip and note it
skipped (not in checks scope) in the report.
Read scripts/interactive-audit.js and inject it:
{ printf '('; cat scripts/interactive-audit.js; printf ')()'; } | agent-browser eval --stdin
Script scans all interactive elements (buttons, links, inputs, selects) and checks: visibility, accessible label, minimum touch target size, pointer-events not disabled, tabindex reachability. Returns categorized issue list.
Pick 3-5 key interactive elements from the interactive snapshot (primary buttons,
navigation links, form inputs) and verify they respond to interaction. Get element
refs (@e1, @e2, ...) from agent-browser snapshot -i; they go stale after the
page changes, so re-snapshot when that happens:
# Click a primary button, then re-snapshot to check the result
agent-browser click @e3
agent-browser snapshot -i
# Verify state changed (new content, navigation, modal opened)
# Hover a navigation item
agent-browser hover @e3
agent-browser snapshot -i
# Verify hover state appears (dropdown, tooltip, style change)
If page contains form elements, test basic form behavior:
# Fill an input
agent-browser fill @e3 "[email protected]"
agent-browser snapshot -i
# Submit with empty required fields (validation check)
agent-browser click @e5
agent-browser snapshot -i
# Verify validation messages appear
trace)Run only if trace is in SELECTED_GROUPS (it pairs with Step 5d -- if 5d was skipped,
skip this too). Otherwise note it skipped (not in checks scope) in the report.
Trace running since Step 5d, capturing visual audit script injection, console/network checks, clicks, hovers, form fills -- the real interaction exercise without screenshot/vitals-audit noise. Stop and analyze now:
agent-browser trace stop /tmp/qa-trace-${ROUTE_SLUG}.json
# Analyze the saved trace for the insights listed below
Look for:
Record findings with severity:
e2e)Run only if e2e is in SELECTED_GROUPS; otherwise skip and note it
skipped (not in checks scope) in the report.
Multi-step flow testing to verify pages work end-to-end.
# Start from homepage
agent-browser open "${BASE_URL}"
agent-browser snapshot -i
# Identify navigation links from the snapshot
# Click through main navigation items using their @e refs, then re-snapshot
agent-browser click @e1
agent-browser snapshot -i
# Verify page changed (snapshot shows different content)
# Test back navigation
agent-browser back
agent-browser snapshot -i
# Verify returned to previous page
Identify primary user flow from route structure (e.g., homepage -> listing -> detail, or dashboard -> settings). Navigate through it:
agent-browser open "${BASE_URL}"
agent-browser snapshot -i
# Navigate to first discovered sub-route via link click
agent-browser click @e1
agent-browser snapshot -i
# Continue deeper if more routes exist
agent-browser click @e2
agent-browser snapshot -i
At each step, verify:
agent-browser consoleTest that page state survives reload:
# If on a page with filters/selections, interact with one
agent-browser click @e1
agent-browser snapshot -i
# Reload the page
agent-browser reload
agent-browser snapshot -i
# Compare: did the state persist (URL params, visible selections)?
resilience)Run only if resilience is in SELECTED_GROUPS (excluded from the default smoke
preset); otherwise skip and note it skipped (not in checks scope) in the report.
Follow procedure in resilience-testing.md. Sub-steps labeled 9a through 9g in report and procedure.
compare)Run only if compare is in SELECTED_GROUPS and baseline screenshots exist; otherwise
skip and note it skipped (not in checks scope) in the report.
Check if baseline screenshots exist:
if [ -f "${SCREENSHOTS_DIR}/latest-baseline.txt" ]; then
BASELINE_DIR=$(cat "${SCREENSHOTS_DIR}/latest-baseline.txt")
fi
If baseline exists, compare current screenshots against it. For each pair:
Include both screenshot paths in report so user can view them.
Compile all findings into report file. Read format from report-format.md.
REPORT_FILE=${QA_DIR}/qa-report-${REPO_NAME}-$(date +%Y%m%d-%H%M%S).md
Write report following template, then present report path and summary to user:
not in checks scope) -- so a narrowed run is never mistaken for full coveragenpm run dev, npx storybook, etc.).agent-browser doctor and retry.agent-browser snapshot over agent-browser screenshot for analysis.
Snapshots provide structured a11y data; screenshots are evidence for the report./iframe.html?id=...) to avoid
Storybook's own UI interfering with audits.latest-baseline.txt). Each before run creates a new timestamped directory,
so old baselines are preserved.agent-browser back and agent-browser forward for history navigation,
agent-browser reload for page reload.For the full agent-browser command list and flags, load the agent-browser skill
and run agent-browser skills get core.
development
Use when: (1) building a skill/command that orchestrates other skills by spawning subagents, (2) a delegated sub-skill reads git working-tree state (e.g. `git branch --show-current`) instead of taking it as an argument, (3) a sub-skill is supposed to "reflect on this session" / capture session learnings (like revise-claude-md) but runs in a subagent, (4) base branch ends up wrong or a session-reflection step sees an empty/trivial context. Keywords: orchestrator, subagent isolated context, git branch --show-current, base branch checkout, revise-claude-md, this session.
development
Run the full ArinHub feature-development pipeline end-to-end with the "ah" prefix. Use for "ah workflow", "ah run workflow", "ah full workflow", a GitHub issue URL to take from issue to PR, or any request to run the whole ah pipeline at once. Takes a feature description + issue number + base branch, OR a GitHub issue URL (resolved via references/resolve-gh-issue.md). Sequentially launches subagents: ah-create-prd-adr -> ah-create-tasks -> ah-implement-tasks -> optional ah-check-qa verification -> ah-finalize-code (creates the PR), anchored with /goal and guarded by retry + escalation.
testing
Verify that a PR or local changes fully implement requirements from a linked GitHub issue, with the "ah" prefix. Use for "ah verify requirements coverage", "ah verify requirements coverage issue 42", "ah verify requirements coverage PR 123", or both ("PR 123, issue 42").
development
Submit a completed code review with line-specific comments and suggestions to a GitHub PR, with the "ah" prefix. Use for "ah submit code review 123".