# Test Manager

> Manual test management for PRs. Generates test plans, creates tracking issues, manages testing status. Trigger when: test a PR, test status, mark tests as complete, przetestuj PR, status testów, oznacz testy jako ukończone.

- Skill: `zrozoom/test-manager` (Agent Skill)
- Install (CLI): `npx skillmds@latest add zrozoom/test-manager`
- Raw SKILL.md: https://api.skillmd.com/api/skills/zrozoom/test-manager/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: ZroZoom (https://skillmd.com/u/zrozoom)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/zrozoom/test-manager

---


# Test Manager Skill

> Manual test management for PRs

## Commands

### `/test [PR#]`
Generates a test plan and creates a tracking issue.

### `/test-status`
Shows the status of all PRs in testing.

### `/test-complete [PR#] [pass|fail]`
Marks tests as complete.

---

## Implementation

### /test Command

```typescript
// Pseudocode
async function handleTestCommand(prNumber?: number) {
  // 1. Get PR info
  const pr = prNumber
    ? await getPR(prNumber)
    : await getCurrentBranchPR();

  if (!pr) {
    return "No PR found. Create PR first with /pr";
  }

  // 2. Check CI status
  const checks = await getChecks(pr.number);
  if (!checks.allPassed) {
    return `CI not passed yet. Wait for: ${checks.pending.join(', ')}`;
  }

  // 3. Get changed files
  const files = await getChangedFiles(pr.number);

  // 4. Generate test plan
  const testPlan = generateTestPlan(files, pr);

  // 5. Create test issue
  const issue = await createTestIssue(pr, testPlan);

  // 6. Add label to PR
  await addLabel(pr.number, 'testing');

  // 7. Comment on PR
  await commentOnPR(pr.number, `Test plan: #${issue.number}`);

  return `Test plan created: ${issue.url}`;
}
```

### Test Plan Generator

```typescript
function generateTestPlan(files: string[], pr: PR): TestPlan {
  const testAreas = new Set<string>();

  for (const file of files) {
    // Map files to test areas
    if (file.includes('Navigation') || file.includes('Header')) {
      testAreas.add('navigation');
    }
    if (file.includes('Modal')) {
      testAreas.add('modals');
    }
    if (file.includes('Form') || file.includes('Input')) {
      testAreas.add('forms');
    }
    if (file.includes('auth') || file.includes('Auth')) {
      testAreas.add('authentication');
    }
    // ... more mappings
  }

  return {
    prNumber: pr.number,
    title: pr.title,
    areas: Array.from(testAreas),
    testCases: generateTestCases(testAreas),
    matrix: getTestMatrix(testAreas)
  };
}
```

### Test Case Templates

```typescript
const TEST_TEMPLATES = {
  navigation: [
    { id: 'NAV-001', name: 'Logo navigation', steps: ['Click logo', 'Verify home page'] },
    { id: 'NAV-002', name: 'Mobile menu', steps: ['Resize to mobile', 'Open menu', 'Click link'] },
    { id: 'NAV-003', name: 'Scroll behavior', steps: ['Scroll page', 'Verify header changes'] },
  ],
  modals: [
    { id: 'MOD-001', name: 'Open/close', steps: ['Open modal', 'Close with X', 'Close with ESC'] },
    { id: 'MOD-002', name: 'Focus trap', steps: ['Open modal', 'Tab through elements'] },
  ],
  forms: [
    { id: 'FRM-001', name: 'Validation', steps: ['Submit empty', 'Check errors'] },
    { id: 'FRM-002', name: 'Success flow', steps: ['Fill valid data', 'Submit', 'Check success'] },
  ],
  authentication: [
    { id: 'AUTH-001', name: 'Login', steps: ['Enter credentials', 'Submit', 'Verify logged in'] },
    { id: 'AUTH-002', name: 'Logout', steps: ['Click logout', 'Verify logged out'] },
    { id: 'AUTH-003', name: 'Role check', steps: ['Login as each role', 'Verify permissions'] },
  ]
};
```

---

## Test Issue Template

```markdown
# 🧪 Test Plan: PR #{{number}}

**PR**: {{title}}
**Author**: @{{author}}
**Deploy Preview**: {{deployUrl}}

## Quick Checks
- [ ] CI passed
- [ ] Deploy preview works
- [ ] No console errors

## Test Matrix

| Viewport | Light | Dark |
|----------|-------|------|
| Mobile (375px) | ⬜ | ⬜ |
| Tablet (768px) | ⬜ | ⬜ |
| Desktop (1440px) | ⬜ | ⬜ |

## Test Cases

{{#each testCases}}
### {{id}}: {{name}}
- [ ] {{#each steps}}{{this}}{{/each}}
{{/each}}

## Roles (if applicable)
- [ ] Guest
- [ ] User
- [ ] Teacher
- [ ] Admin

## Result
- [ ] ✅ PASS - Ready to merge
- [ ] ❌ FAIL - Issues found (list below)

### Issues Found
<!-- List any issues here -->

---
_Generated by Test Manager | PR #{{number}}_
```

---

## Jira QA Tickets (Atlassian MCP)

After creating a PR, create a QA ticket in Jira assigned to the tester.

### Project Data

> Read all values from `.agent/context/project-ids.md`. If any placeholder is still `<...>`, halt and ask the user to fill it in.

- **Cloud ID**: `<JIRA_CLOUD_ID>`
- **Project key**: `<JIRA_PROJECT_KEY>`
- **Issue type**: `Task` (or your project's QA issue type)
- **Tester (assignee)**: `<TESTER_ACCOUNT_ID>`

### Ticket Structure

```markdown
## Context
PR: {PR link}
GitHub Issue: #{number} — {title}
{1-2 sentences on what changed}

## Test Scenarios

### T1: {scenario name}
**Preconditions:** {what must be true before testing}
1. {step 1}
2. {step 2}
**Expected result:** {what the tester should see}

### T2: ...

## Acceptance Criteria
- [ ] T1: {short description}
- [ ] T2: {short description}
```

### Workflow

1. `mcp__claude_ai_Atlassian__createJiraIssue` — create the ticket
2. Assignee = `<TESTER_ACCOUNT_ID>` (resolve from `.agent/context/project-ids.md`)
3. Summary: `QA: Manual testing PR #{number} — {short description}`

---

## Labels Setup

Run once to create labels:
```bash
gh label create "ready-for-review" --color "0052cc" --description "PR ready for code review"
gh label create "testing" --color "fbca04" --description "Manual testing in progress"
gh label create "tested" --color "0e8a16" --description "Manual testing passed"
gh label create "needs-fixes" --color "d93f0b" --description "Issues found in testing"
```

---

## PM Queries

### Daily standup query
```bash
echo "=== PRs Status ==="
echo "Awaiting review:"
gh pr list --label "ready-for-review" --json number,title --jq '.[] | "  #\(.number): \(.title)"'

echo "In testing:"
gh pr list --label "testing" --json number,title --jq '.[] | "  #\(.number): \(.title)"'

echo "Tested, ready to merge:"
gh pr list --label "tested" --json number,title --jq '.[] | "  #\(.number): \(.title)"'

echo "Needs fixes:"
gh pr list --label "needs-fixes" --json number,title --jq '.[] | "  #\(.number): \(.title)"'
```

### Weekly metrics
```bash
# PRs merged this week
gh pr list --state merged --search "merged:>=2026-01-25" --json number,title

# Average time in testing
# (requires more complex query with timestamps)
```

