| name | test-app |
| description | QE Testing Skill: Tests the live application through the browser automation and API calls. Never reads source code. MANDATORY TRIGGERS: QE, QA, quality, test, testing, regression, smoke test, UI test, API test, e2e, browser test, test case, bug report, acceptance testing, verify the app, test this feature, make sure nothing is broken, check if X works. |
| argument-hint | <ticket ID or feature to test> |
Bobby QE Skill
Comprehensive quality engineering for web applications. Tests exclusively through the browser automation and API calls — never reads source code. If you can't confirm a behavior by interacting with the running application, it hasn't been verified.
Testing Methods
<testing_boundaries>
QE verifies behavior exclusively through what users can observe:
- UI Testing — Browser-based testing using browser automation (screenshots, clicks, form fills, page reads, navigation). Test what users actually see.
- API Testing — Direct HTTP endpoint testing via curl/bash scripts. Test data contracts, error handling, auth flows, and edge cases.
- Evidence recording — Capture screenshots and HTTP responses as proof for every test result.
When a test cannot be performed through UI or API (e.g., service is down and recovery fails), mark it as BLOCKED with a note rather than falling back to code inspection. Source code reading, code changes, and code-based assertions are outside QE's scope — QE reports what the application actually does, not what code says it should do.
</testing_boundaries>
Before Starting
- Check learnings — Read
.claude/skills/bobby-qe/learnings.md + .claude/skills/bobby-qe/learnings.local.md
- Health check — Verify dev environment:
Service Recovery (Self-Unblocking)
Before marking tests as BLOCKED, attempt to restore services.
Step 1: Health Check
curl -s -o /dev/null -w "%{http_code}" <your dev server URL> || echo "APP DOWN — configure health_checks in .bobbyrc.yml"
Boundaries:
- One restart attempt per service — if it doesn't come back, it's BLOCKED
- Never run migrations, installs, or edit config files
- Never debug application logs for code issues
Ticket Queue: Auto-Processing
When acting as QE, check for tickets in the testing stage:
bobby ticket list testing
Pick up tickets automatically in priority order (critical > high > medium > low). Don't ask which ticket — just start testing.
Per-Ticket Testing Flow
For each ticket in testing:
- Read the ticket —
bobby ticket view {ID} to understand description, acceptance criteria, and dev notes
- Read test cases — check for
test-cases.md in the ticket folder
- Test against every AC item — use UI testing, API testing, or both
- Screenshot every AC — evidence for each, pass or fail
- Write structured test results — save to
qe/test-results/{date}-{ticket-id}/results.json
- Move the ticket:
- All AC pass:
bobby ticket comment {ID} --by bobby-qe "QE passed" then bobby ticket move {ID} ship
- Any AC fails:
bobby ticket move {ID} reject "QE failed: {specific failures}"
- Proceed to next ticket — keep going until the testing queue is empty
UI Testing Procedure
Before You Start
- Get browser tab context
- Create a new tab or use an existing one
- Check if the app is running (navigate and screenshot). If not, run Service Recovery.
- Verify authentication state — log in if needed
For Each Test Case
- Navigate to the target page
- Screenshot the initial state — this is your baseline
- Read the page accessibility tree to verify elements exist
- Check console for errors before interacting
- Execute steps — click buttons, fill forms, navigate
- Screenshot after each significant action
- Verify expected results — check page content, URL, console
- Record result — pass/fail with evidence
What to Check on Every Page
- Page loads without console errors
- All interactive elements are clickable and responsive
- Forms validate inputs properly (empty, invalid, boundary values)
- Loading states appear during async operations
- Error states display meaningful messages
- Navigation links go to correct destinations
- Back button works correctly
- No broken images or missing assets
Common UI Test Patterns
Form testing:
- Submit empty form — verify validation messages
- Submit with invalid data — verify field-level errors
- Submit with valid data — verify success state
- Submit during loading — verify no double submission
- Check tab order and keyboard navigation
List/table testing:
- Data loads and displays correctly
- Pagination works (if present)
- Filtering and search work
- Sorting works
- Empty state displays properly
- Bulk actions work (select all, bulk delete, etc.)
Mobile / responsive testing:
Use the iframe technique for real mobile viewport testing:
const iframe = document.createElement('iframe');
iframe.id = 'mobile-test-frame';
iframe.src = window.location.href;
iframe.style.cssText = 'position:fixed; top:0; left:0; width:375px; height:812px; border:3px solid red; z-index:99999; background:white;';
document.body.appendChild(iframe);
Breakpoints to test: 375px (phone), 768px (tablet), 1024px (small laptop).
API Testing Procedure
For Each API Endpoint
- Happy path — Valid request with expected parameters
- Missing required fields — Verify 400/422 error with clear message
- Invalid data types — Send strings where numbers expected, etc.
- Authentication — Test without token (401), with expired token, with wrong role (403)
- Authorization — Test accessing another user's resources
- Edge cases — Empty arrays, very long strings, special characters
API Test Script Template
#!/bin/bash
BASE_URL="${1:-http://localhost:3000}"
TOKEN="${2}"
PASS=0; FAIL=0; TOTAL=0
assert_status() {
local test_name="$1" expected="$2" actual="$3"
TOTAL=$((TOTAL + 1))
if [ "$expected" = "$actual" ]; then
echo " PASS: $test_name (HTTP $actual)"
PASS=$((PASS + 1))
else
echo " FAIL: $test_name (expected $expected, got $actual)"
FAIL=$((FAIL + 1))
fi
}
echo "Results: $PASS/$TOTAL passed, $FAIL failed"
Storage Layout
The QE workspace lives in the project directory:
qe/
├── test-suites/ # Reusable test case definitions
│ ├── auth.json
│ ├── onboarding.json
│ └── ...
├── regression-plans/ # Named regression plans
│ ├── full-regression.json
│ ├── smoke-test.json
│ └── pre-deploy.json
├── test-results/ # Timestamped test run results
│ └── 2026-03-13-full-regression/
│ ├── results.json
│ ├── summary.md
│ └── screenshots/
└── scripts/ # Reusable test helper scripts
Severity Classifications
- CRITICAL: Security vulnerabilities, data loss, complete feature breakage
- HIGH: Missing error handling on critical paths, auth bypasses, broken core workflows
- MEDIUM: UX issues, silent failures, missing validation, inconsistent behavior
- LOW: Cosmetic issues, minor polish, non-blocking improvements
Bobby Workflow
backlog -> planning -> building -> reviewing -> testing -> shipping -> done
|
blocked
Ticket Integration
bobby ticket list testing
bobby ticket comment TKT-XXX --by bobby-qe "QE passed: all AC verified"
bobby ticket move TKT-XXX ship
bobby ticket move TKT-XXX reject "QE failed: login form shows no error on invalid password"
bobby ticket create -t "Bug title" --type bug -p high --area auth
bobby ticket list
Tips for Effective Testing
- Start with smoke tests before full regression — catch showstoppers early
- Screenshot failures so developers can see exactly what went wrong
- Check console errors on every page transition — JS errors reveal issues the UI hides
- Test as different user types — admin, regular user, unauthenticated visitor
- Try the sad paths — empty states, error states, timeout states, permission denied
- Verify data persistence — after creating/editing something, refresh and confirm it stuck
- Test navigation flows — can users complete an entire workflow start to finish?
- Trust what you see — QE reports what the application actually does, not what code says it should do
- Hard refresh between tickets — Ctrl+Shift+R to clear stale state
Project overrides
If .claude/skills/bobby-qe/SKILL.local.md exists, read it and follow it. It holds this
project's own instructions for this skill and wins wherever it conflicts with anything
above.
SKILL.md is shipped by Bobby and is replaced on every upgrade — edits here are lost.
SKILL.local.md is yours and is never overwritten.