sequant 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +237 -0
- package/dist/bin/cli.d.ts +8 -0
- package/dist/bin/cli.d.ts.map +1 -0
- package/dist/bin/cli.js +70 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/src/commands/doctor.d.ts +8 -0
- package/dist/src/commands/doctor.d.ts.map +1 -0
- package/dist/src/commands/doctor.js +171 -0
- package/dist/src/commands/doctor.js.map +1 -0
- package/dist/src/commands/init.d.ts +11 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +124 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/run.d.ts +18 -0
- package/dist/src/commands/run.d.ts.map +1 -0
- package/dist/src/commands/run.js +229 -0
- package/dist/src/commands/run.js.map +1 -0
- package/dist/src/commands/status.d.ts +5 -0
- package/dist/src/commands/status.d.ts.map +1 -0
- package/dist/src/commands/status.js +45 -0
- package/dist/src/commands/status.js.map +1 -0
- package/dist/src/commands/update.d.ts +10 -0
- package/dist/src/commands/update.d.ts.map +1 -0
- package/dist/src/commands/update.js +124 -0
- package/dist/src/commands/update.js.map +1 -0
- package/dist/src/index.d.ts +15 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +13 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lib/fs.d.ts +10 -0
- package/dist/src/lib/fs.d.ts.map +1 -0
- package/dist/src/lib/fs.js +44 -0
- package/dist/src/lib/fs.js.map +1 -0
- package/dist/src/lib/manifest.d.ts +14 -0
- package/dist/src/lib/manifest.d.ts.map +1 -0
- package/dist/src/lib/manifest.js +37 -0
- package/dist/src/lib/manifest.js.map +1 -0
- package/dist/src/lib/stacks.d.ts +22 -0
- package/dist/src/lib/stacks.d.ts.map +1 -0
- package/dist/src/lib/stacks.js +131 -0
- package/dist/src/lib/stacks.js.map +1 -0
- package/dist/src/lib/templates.d.ts +16 -0
- package/dist/src/lib/templates.d.ts.map +1 -0
- package/dist/src/lib/templates.js +118 -0
- package/dist/src/lib/templates.js.map +1 -0
- package/dist/src/lib/workflow/cli-args.d.ts +138 -0
- package/dist/src/lib/workflow/cli-args.d.ts.map +1 -0
- package/dist/src/lib/workflow/cli-args.js +210 -0
- package/dist/src/lib/workflow/cli-args.js.map +1 -0
- package/dist/src/lib/workflow/execute-issues.d.ts +42 -0
- package/dist/src/lib/workflow/execute-issues.d.ts.map +1 -0
- package/dist/src/lib/workflow/execute-issues.js +463 -0
- package/dist/src/lib/workflow/execute-issues.js.map +1 -0
- package/dist/src/lib/workflow/logger.d.ts +168 -0
- package/dist/src/lib/workflow/logger.d.ts.map +1 -0
- package/dist/src/lib/workflow/logger.js +249 -0
- package/dist/src/lib/workflow/logger.js.map +1 -0
- package/dist/src/lib/workflow/types.d.ts +89 -0
- package/dist/src/lib/workflow/types.d.ts.map +1 -0
- package/dist/src/lib/workflow/types.js +23 -0
- package/dist/src/lib/workflow/types.js.map +1 -0
- package/package.json +69 -0
- package/stacks/go.yaml +22 -0
- package/stacks/nextjs.yaml +28 -0
- package/stacks/python.yaml +24 -0
- package/stacks/rust.yaml +23 -0
- package/templates/hooks/post-tool.sh +301 -0
- package/templates/hooks/pre-tool.sh +350 -0
- package/templates/memory/constitution.md +60 -0
- package/templates/scripts/cleanup-worktree.sh +78 -0
- package/templates/scripts/list-worktrees.sh +50 -0
- package/templates/scripts/new-feature.sh +156 -0
- package/templates/settings.json +26 -0
- package/templates/skills/assess/SKILL.md +428 -0
- package/templates/skills/clean/SKILL.md +196 -0
- package/templates/skills/docs/SKILL.md +323 -0
- package/templates/skills/exec/SKILL.md +426 -0
- package/templates/skills/fullsolve/SKILL.md +479 -0
- package/templates/skills/loop/SKILL.md +310 -0
- package/templates/skills/qa/SKILL.md +261 -0
- package/templates/skills/qa/references/code-quality-exemplars.md +112 -0
- package/templates/skills/qa/references/code-review-checklist.md +77 -0
- package/templates/skills/qa/references/quality-gates.md +95 -0
- package/templates/skills/qa/references/testing-requirements.md +109 -0
- package/templates/skills/qa/scripts/quality-checks.sh +109 -0
- package/templates/skills/reflect/SKILL.md +159 -0
- package/templates/skills/reflect/references/documentation-tiers.md +70 -0
- package/templates/skills/reflect/references/phase-reflection.md +95 -0
- package/templates/skills/reflect/scripts/workflow-queries.ts +165 -0
- package/templates/skills/security-review/SKILL.md +344 -0
- package/templates/skills/security-review/references/security-checklists.md +377 -0
- package/templates/skills/solve/SKILL.md +242 -0
- package/templates/skills/spec/SKILL.md +169 -0
- package/templates/skills/spec/references/parallel-groups.md +72 -0
- package/templates/skills/spec/references/verification-criteria.md +104 -0
- package/templates/skills/test/SKILL.md +508 -0
- package/templates/skills/testgen/SKILL.md +561 -0
- package/templates/skills/verify/SKILL.md +266 -0
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testgen
|
|
3
|
+
description: "Generate test stubs from /spec verification criteria"
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: sequant
|
|
7
|
+
version: "1.0"
|
|
8
|
+
allowed-tools:
|
|
9
|
+
- Read
|
|
10
|
+
- Write
|
|
11
|
+
- Edit
|
|
12
|
+
- Glob
|
|
13
|
+
- Grep
|
|
14
|
+
- Bash(gh issue view:*)
|
|
15
|
+
- Bash(gh issue comment:*)
|
|
16
|
+
- Bash(npm test:*)
|
|
17
|
+
- Bash(git worktree list:*)
|
|
18
|
+
- Bash(ls:*)
|
|
19
|
+
- Bash(mkdir:*)
|
|
20
|
+
- mcp__supabase__*
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Test Generation Command
|
|
24
|
+
|
|
25
|
+
You are the "Test Generation Agent" for the current repository.
|
|
26
|
+
|
|
27
|
+
## Purpose
|
|
28
|
+
|
|
29
|
+
When invoked as `/testgen <issue-number>`, your job is to:
|
|
30
|
+
|
|
31
|
+
1. Read verification criteria from the latest `/spec` comment on the GitHub issue
|
|
32
|
+
2. Parse each AC's verification method and test scenario
|
|
33
|
+
3. Generate appropriate test stubs based on verification method type
|
|
34
|
+
4. Output stubs to the correct directories with TODO markers
|
|
35
|
+
5. Post a summary comment to the GitHub issue
|
|
36
|
+
|
|
37
|
+
## Invocation
|
|
38
|
+
|
|
39
|
+
- `/testgen 123` - Generate test stubs for issue #123 based on /spec comment
|
|
40
|
+
- `/testgen` - Generate stubs for the most recently discussed issue in conversation
|
|
41
|
+
|
|
42
|
+
## Workflow
|
|
43
|
+
|
|
44
|
+
### Step 1: Read Verification Criteria from GitHub Issue
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
gh issue view <issue-number> --json comments --jq '.comments | reverse | .[0].body'
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Look for the `/spec` planning comment containing verification criteria blocks:
|
|
51
|
+
|
|
52
|
+
```markdown
|
|
53
|
+
### AC-1: [Description]
|
|
54
|
+
|
|
55
|
+
**Verification Method:** Unit Test | Integration Test | Manual Test | Browser Test
|
|
56
|
+
|
|
57
|
+
**Test Scenario:**
|
|
58
|
+
- Given: [Initial state]
|
|
59
|
+
- When: [Action]
|
|
60
|
+
- Then: [Expected outcome]
|
|
61
|
+
|
|
62
|
+
**Integration Points:**
|
|
63
|
+
- [External system or component]
|
|
64
|
+
|
|
65
|
+
**Assumptions to Validate:**
|
|
66
|
+
- [ ] [Assumption 1]
|
|
67
|
+
- [ ] [Assumption 2]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Step 2: Parse Verification Criteria
|
|
71
|
+
|
|
72
|
+
For each AC, extract:
|
|
73
|
+
- **AC number and description**
|
|
74
|
+
- **Verification method** (Unit Test, Integration Test, Browser Test, Manual Test, N/A)
|
|
75
|
+
- **Test scenario** (Given/When/Then)
|
|
76
|
+
- **Integration points**
|
|
77
|
+
- **Assumptions to validate**
|
|
78
|
+
|
|
79
|
+
### Step 2.1: Identify Failure Scenarios from /spec
|
|
80
|
+
|
|
81
|
+
Scan the `/spec` comment for failure scenarios to generate additional test stubs:
|
|
82
|
+
|
|
83
|
+
**Explicit Error Handling Sections:**
|
|
84
|
+
Look for these section headers in the `/spec` output:
|
|
85
|
+
- "Error handling"
|
|
86
|
+
- "Edge cases"
|
|
87
|
+
- "What could go wrong"
|
|
88
|
+
- "Risks & Mitigations"
|
|
89
|
+
|
|
90
|
+
Extract scenarios from these sections and add as failure path stubs.
|
|
91
|
+
|
|
92
|
+
**Negative Requirements:**
|
|
93
|
+
Look for patterns indicating what should NOT happen:
|
|
94
|
+
- "should NOT allow"
|
|
95
|
+
- "must NOT"
|
|
96
|
+
- "reject"
|
|
97
|
+
- "block"
|
|
98
|
+
- "prevent"
|
|
99
|
+
- "deny"
|
|
100
|
+
- "fail when"
|
|
101
|
+
- "throw when"
|
|
102
|
+
|
|
103
|
+
Each negative requirement becomes a failure path test stub.
|
|
104
|
+
|
|
105
|
+
**Inferred Failure Scenarios:**
|
|
106
|
+
Based on the action verb in each AC, infer common failure scenarios:
|
|
107
|
+
|
|
108
|
+
| Action Verb | Happy Path | Inferred Failure Paths |
|
|
109
|
+
|-------------|------------|------------------------|
|
|
110
|
+
| Create | Successfully creates X | - Fail to create when invalid input<br>- Handle duplicate X<br>- Reject unauthorized create |
|
|
111
|
+
| Fetch/Read | Returns X data | - Handle missing X (404)<br>- Handle fetch timeout<br>- Handle malformed response |
|
|
112
|
+
| Update | Successfully updates X | - Reject update with invalid data<br>- Handle concurrent updates<br>- Reject unauthorized update |
|
|
113
|
+
| Delete | Successfully deletes X | - Handle delete of non-existent X<br>- Handle delete when X is in use<br>- Reject unauthorized delete |
|
|
114
|
+
| Submit | Successfully submits form | - Show validation errors<br>- Handle server rejection<br>- Handle network timeout |
|
|
115
|
+
| Authenticate | Login succeeds | - Reject invalid credentials<br>- Handle locked account<br>- Handle session timeout |
|
|
116
|
+
|
|
117
|
+
### Step 3: Generate Test Stubs by Verification Method
|
|
118
|
+
|
|
119
|
+
#### Unit Test → Jest stub in `__tests__/`
|
|
120
|
+
|
|
121
|
+
**Output file:** `__tests__/[feature-name].test.ts`
|
|
122
|
+
|
|
123
|
+
**Template:**
|
|
124
|
+
```typescript
|
|
125
|
+
// Generated test stub for Issue #<issue-number>
|
|
126
|
+
// AC-<N>: <description>
|
|
127
|
+
// Run with: npm test -- __tests__/<feature-name>.test.ts
|
|
128
|
+
|
|
129
|
+
describe('<Feature Name>', () => {
|
|
130
|
+
describe('AC-<N>: <description>', () => {
|
|
131
|
+
it('should <expected behavior from Then clause>', () => {
|
|
132
|
+
// Given: <initial state>
|
|
133
|
+
// TODO: Set up test fixtures
|
|
134
|
+
|
|
135
|
+
// When: <action>
|
|
136
|
+
// TODO: Call the function/method being tested
|
|
137
|
+
|
|
138
|
+
// Then: <expected outcome>
|
|
139
|
+
// TODO: Add assertions
|
|
140
|
+
|
|
141
|
+
throw new Error('Test stub - implement this test');
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// === FAILURE PATHS ===
|
|
145
|
+
describe('error handling', () => {
|
|
146
|
+
it('should throw when <invalid condition>', () => {
|
|
147
|
+
// Given: <invalid input or state>
|
|
148
|
+
// TODO: Set up invalid test conditions
|
|
149
|
+
|
|
150
|
+
// When: <action with invalid input>
|
|
151
|
+
// TODO: Call the function with invalid input
|
|
152
|
+
|
|
153
|
+
// Then: <error thrown or graceful failure>
|
|
154
|
+
// TODO: Expect error to be thrown or handled gracefully
|
|
155
|
+
|
|
156
|
+
throw new Error('Failure path stub - implement this test');
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should return null/empty when <edge case>', () => {
|
|
160
|
+
// Given: <edge case condition>
|
|
161
|
+
// TODO: Set up edge case (empty array, null input, etc.)
|
|
162
|
+
|
|
163
|
+
// When: <action>
|
|
164
|
+
// TODO: Call the function
|
|
165
|
+
|
|
166
|
+
// Then: <graceful handling>
|
|
167
|
+
// TODO: Assert null, empty, or default value returned
|
|
168
|
+
|
|
169
|
+
throw new Error('Edge case stub - implement this test');
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
#### Integration Test → Template in `__tests__/integration/`
|
|
177
|
+
|
|
178
|
+
**Output file:** `__tests__/integration/[feature-name].integration.test.ts`
|
|
179
|
+
|
|
180
|
+
**Template:**
|
|
181
|
+
```typescript
|
|
182
|
+
// Generated integration test stub for Issue #<issue-number>
|
|
183
|
+
// AC-<N>: <description>
|
|
184
|
+
// Run with: npm test -- __tests__/integration/<feature-name>.integration.test.ts
|
|
185
|
+
|
|
186
|
+
import { exec } from 'child_process';
|
|
187
|
+
import * as fs from 'fs';
|
|
188
|
+
import * as path from 'path';
|
|
189
|
+
import { promisify } from 'util';
|
|
190
|
+
|
|
191
|
+
const execAsync = promisify(exec);
|
|
192
|
+
|
|
193
|
+
describe('<Feature Name> - Integration', () => {
|
|
194
|
+
// === SANDBOX ISOLATION ===
|
|
195
|
+
// Each test run gets a unique temp directory to prevent test pollution
|
|
196
|
+
// and support parallel test execution.
|
|
197
|
+
const TEST_DIR = `/tmp/sequant-test-${process.pid}-${Date.now()}`;
|
|
198
|
+
|
|
199
|
+
// Integration Points:
|
|
200
|
+
// - <integration point 1>
|
|
201
|
+
// - <integration point 2>
|
|
202
|
+
|
|
203
|
+
// Assumptions to Validate:
|
|
204
|
+
// - [ ] <assumption 1>
|
|
205
|
+
// - [ ] <assumption 2>
|
|
206
|
+
|
|
207
|
+
beforeAll(async () => {
|
|
208
|
+
// Create isolated test directory
|
|
209
|
+
fs.mkdirSync(TEST_DIR, { recursive: true });
|
|
210
|
+
process.env.TEST_TMP_DIR = TEST_DIR;
|
|
211
|
+
|
|
212
|
+
// TODO: Set up integration test environment
|
|
213
|
+
// - Ensure external dependencies are available
|
|
214
|
+
// - Set up test data/fixtures
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
afterAll(async () => {
|
|
218
|
+
// TODO: Clean up integration test environment
|
|
219
|
+
// - Remove test data
|
|
220
|
+
// - Reset external state
|
|
221
|
+
|
|
222
|
+
// DEBUGGING: Comment out the next line to inspect test artifacts after failure
|
|
223
|
+
fs.rmSync(TEST_DIR, { recursive: true, force: true });
|
|
224
|
+
delete process.env.TEST_TMP_DIR;
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// For database isolation (future): Create test schema in beforeAll,
|
|
228
|
+
// drop in afterAll. Pattern: `test_schema_${process.pid}_${Date.now()}`
|
|
229
|
+
|
|
230
|
+
describe('AC-<N>: <description>', () => {
|
|
231
|
+
it('should <expected behavior from Then clause>', async () => {
|
|
232
|
+
// Given: <initial state>
|
|
233
|
+
// TODO: Set up test preconditions
|
|
234
|
+
// Use TEST_DIR for any file operations, e.g.:
|
|
235
|
+
// const testFile = path.join(TEST_DIR, 'test-output.log');
|
|
236
|
+
|
|
237
|
+
// When: <action>
|
|
238
|
+
// TODO: Execute the integration action
|
|
239
|
+
|
|
240
|
+
// Then: <expected outcome>
|
|
241
|
+
// TODO: Verify integration result
|
|
242
|
+
|
|
243
|
+
throw new Error('Integration test stub - implement this test');
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Assumption validation tests
|
|
247
|
+
it('validates assumption: <assumption 1>', async () => {
|
|
248
|
+
// TODO: Verify this assumption holds true
|
|
249
|
+
// This test documents and validates a critical assumption
|
|
250
|
+
|
|
251
|
+
throw new Error('Assumption validation stub - implement this test');
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// === ERROR SCENARIOS ===
|
|
256
|
+
describe('error scenarios', () => {
|
|
257
|
+
it('should handle <external service failure>', async () => {
|
|
258
|
+
// Given: <external dependency is unavailable/erroring>
|
|
259
|
+
// TODO: Mock external service to return error
|
|
260
|
+
|
|
261
|
+
// When: <action that depends on external service>
|
|
262
|
+
// TODO: Execute the integration action
|
|
263
|
+
|
|
264
|
+
// Then: <graceful degradation or clear error>
|
|
265
|
+
// TODO: Verify error is caught and handled appropriately
|
|
266
|
+
|
|
267
|
+
throw new Error('Error scenario stub - implement this test');
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
it('should recover from <transient failure>', async () => {
|
|
271
|
+
// Given: <temporary failure condition>
|
|
272
|
+
// TODO: Simulate transient failure (network timeout, temporary 503)
|
|
273
|
+
|
|
274
|
+
// When: <action with retry logic>
|
|
275
|
+
// TODO: Execute with potential retry
|
|
276
|
+
|
|
277
|
+
// Then: <successful recovery or clear failure after retries>
|
|
278
|
+
// TODO: Verify retry behavior or graceful degradation
|
|
279
|
+
|
|
280
|
+
throw new Error('Recovery stub - implement this test');
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('should handle concurrent operations safely', async () => {
|
|
284
|
+
// Given: <multiple simultaneous operations>
|
|
285
|
+
// TODO: Set up parallel execution
|
|
286
|
+
|
|
287
|
+
// When: <concurrent actions>
|
|
288
|
+
// TODO: Run operations in parallel
|
|
289
|
+
|
|
290
|
+
// Then: <no data corruption, proper isolation>
|
|
291
|
+
// TODO: Verify data integrity
|
|
292
|
+
|
|
293
|
+
throw new Error('Concurrency stub - implement this test');
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### Browser Test → Scenarios for `/test` command
|
|
300
|
+
|
|
301
|
+
**Output:** GitHub comment with test scenarios (not a file)
|
|
302
|
+
|
|
303
|
+
**Template:**
|
|
304
|
+
```markdown
|
|
305
|
+
## Browser Test Scenarios for AC-<N>
|
|
306
|
+
|
|
307
|
+
**For use with `/test <issue-number>`**
|
|
308
|
+
|
|
309
|
+
### Scenario 1: <scenario name>
|
|
310
|
+
|
|
311
|
+
**Given:**
|
|
312
|
+
- <precondition 1>
|
|
313
|
+
- <precondition 2>
|
|
314
|
+
|
|
315
|
+
**Steps:**
|
|
316
|
+
1. Navigate to <URL>
|
|
317
|
+
2. <action 1>
|
|
318
|
+
3. <action 2>
|
|
319
|
+
|
|
320
|
+
**Expected:**
|
|
321
|
+
- [ ] <verification 1>
|
|
322
|
+
- [ ] <verification 2>
|
|
323
|
+
|
|
324
|
+
**Chrome DevTools MCP Commands:**
|
|
325
|
+
```javascript
|
|
326
|
+
// Navigation
|
|
327
|
+
mcp__chrome-devtools__navigate_page({ url: "<URL>" })
|
|
328
|
+
|
|
329
|
+
// Snapshot to find elements
|
|
330
|
+
mcp__chrome-devtools__take_snapshot()
|
|
331
|
+
|
|
332
|
+
// Interact with elements
|
|
333
|
+
mcp__chrome-devtools__click({ uid: "<element-uid>" })
|
|
334
|
+
mcp__chrome-devtools__fill({ uid: "<input-uid>", value: "<test-value>" })
|
|
335
|
+
|
|
336
|
+
// Verify results
|
|
337
|
+
mcp__chrome-devtools__take_screenshot()
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Negative Test Scenarios
|
|
341
|
+
|
|
342
|
+
**Scenario: Invalid form submission**
|
|
343
|
+
- Given: Form is displayed with required fields
|
|
344
|
+
- When: Submit with empty required fields
|
|
345
|
+
- Expected:
|
|
346
|
+
- [ ] Validation errors displayed inline
|
|
347
|
+
- [ ] Form not submitted to server
|
|
348
|
+
- [ ] Focus moves to first error field
|
|
349
|
+
- [ ] Error message is descriptive
|
|
350
|
+
|
|
351
|
+
**Scenario: Unauthorized access attempt**
|
|
352
|
+
- Given: User is not logged in / lacks permission
|
|
353
|
+
- When: Navigate to protected route directly
|
|
354
|
+
- Expected:
|
|
355
|
+
- [ ] Redirect to login or access denied page
|
|
356
|
+
- [ ] No protected content visible in DOM
|
|
357
|
+
- [ ] Appropriate error message shown
|
|
358
|
+
- [ ] No sensitive data in network requests
|
|
359
|
+
|
|
360
|
+
**Scenario: Network failure graceful degradation**
|
|
361
|
+
- Given: Page is loaded successfully
|
|
362
|
+
- When: Network becomes unavailable during action
|
|
363
|
+
- Expected:
|
|
364
|
+
- [ ] User-friendly error message displayed
|
|
365
|
+
- [ ] No unhandled exceptions in console
|
|
366
|
+
- [ ] Retry option available (if applicable)
|
|
367
|
+
- [ ] User can recover by retrying
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
#### Manual Test → Checklist
|
|
371
|
+
|
|
372
|
+
**Output:** GitHub comment with checklist (not a file)
|
|
373
|
+
|
|
374
|
+
**Template:**
|
|
375
|
+
```markdown
|
|
376
|
+
## Manual Test Checklist for AC-<N>
|
|
377
|
+
|
|
378
|
+
### Prerequisites
|
|
379
|
+
- [ ] <prerequisite 1>
|
|
380
|
+
- [ ] <prerequisite 2>
|
|
381
|
+
|
|
382
|
+
### Test Steps
|
|
383
|
+
1. **Setup:** <setup step>
|
|
384
|
+
2. **Action:** <action to perform>
|
|
385
|
+
3. **Verify:** <what to check>
|
|
386
|
+
|
|
387
|
+
### Expected Results
|
|
388
|
+
- [ ] <expected result 1>
|
|
389
|
+
- [ ] <expected result 2>
|
|
390
|
+
|
|
391
|
+
### Error Handling Verification
|
|
392
|
+
- [ ] Invalid input shows appropriate error message
|
|
393
|
+
- [ ] Network failure shows user-friendly error
|
|
394
|
+
- [ ] Timeout shows loading state then error
|
|
395
|
+
- [ ] Concurrent operations don't cause data corruption
|
|
396
|
+
|
|
397
|
+
### Edge Cases
|
|
398
|
+
- [ ] Empty state displays correctly (no data)
|
|
399
|
+
- [ ] Maximum values handled (long strings, large numbers)
|
|
400
|
+
- [ ] Minimum values handled (0, empty string, null)
|
|
401
|
+
- [ ] Special characters handled properly (unicode, emojis, HTML)
|
|
402
|
+
|
|
403
|
+
### Notes
|
|
404
|
+
- <any special considerations>
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
#### N/A - Trivial → Skip with note
|
|
408
|
+
|
|
409
|
+
If an AC has verification method "N/A - Trivial", skip test generation and note why.
|
|
410
|
+
|
|
411
|
+
### Step 4: Locate Feature Worktree
|
|
412
|
+
|
|
413
|
+
If generating file-based tests (Unit Test, Integration Test), find the worktree:
|
|
414
|
+
|
|
415
|
+
```bash
|
|
416
|
+
git worktree list | grep -E "feature.*<issue-number>"
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
Or check:
|
|
420
|
+
```bash
|
|
421
|
+
ls ../worktrees/feature/<issue-number>-*/
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
Create test directories if needed:
|
|
425
|
+
```bash
|
|
426
|
+
mkdir -p __tests__/integration
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Step 5: Write Test Files
|
|
430
|
+
|
|
431
|
+
For each test file generated:
|
|
432
|
+
1. Check if file already exists (don't overwrite)
|
|
433
|
+
2. Write the generated stub to the appropriate directory
|
|
434
|
+
3. Ensure file is executable and has proper imports
|
|
435
|
+
|
|
436
|
+
### Step 6: Post Summary to GitHub Issue
|
|
437
|
+
|
|
438
|
+
Create a comment summarizing what was generated:
|
|
439
|
+
|
|
440
|
+
```markdown
|
|
441
|
+
## Test Stubs Generated
|
|
442
|
+
|
|
443
|
+
| AC | Verification | Happy Path | Failure Paths |
|
|
444
|
+
|----|--------------|------------|---------------|
|
|
445
|
+
| AC-1 | Unit Test | 1 test | 2 error cases |
|
|
446
|
+
| AC-2 | Integration | 1 test | 3 error scenarios |
|
|
447
|
+
| AC-3 | Browser Test | 2 scenarios | 3 negative scenarios |
|
|
448
|
+
| AC-4 | Manual Test | 2 items | 8 failure checks |
|
|
449
|
+
| AC-5 | N/A - Trivial | Skipped | - |
|
|
450
|
+
|
|
451
|
+
**Counts explained:**
|
|
452
|
+
- **Happy Path:** Number of positive/success test stubs or scenarios
|
|
453
|
+
- **Failure Paths:** Number of error handling, edge case, and negative test stubs
|
|
454
|
+
|
|
455
|
+
### Unit Test Stubs
|
|
456
|
+
- `__tests__/<feature>.test.ts`
|
|
457
|
+
- Happy path: X test cases
|
|
458
|
+
- Error handling: Y failure stubs
|
|
459
|
+
|
|
460
|
+
### Integration Test Stubs
|
|
461
|
+
- `__tests__/integration/<feature>.integration.test.ts`
|
|
462
|
+
- Happy path: X test cases
|
|
463
|
+
- Assumption validators: Y tests
|
|
464
|
+
- Error scenarios: Z failure stubs
|
|
465
|
+
|
|
466
|
+
### Browser Test Scenarios
|
|
467
|
+
**Positive scenarios:** [count]
|
|
468
|
+
[Browser test scenarios here]
|
|
469
|
+
|
|
470
|
+
**Negative scenarios:** [count]
|
|
471
|
+
[Negative scenarios here]
|
|
472
|
+
|
|
473
|
+
### Manual Test Checklists
|
|
474
|
+
**Expected results:** [count] items
|
|
475
|
+
[Manual test checklists here]
|
|
476
|
+
|
|
477
|
+
**Error handling verification:** 4 items
|
|
478
|
+
**Edge cases:** 4 items
|
|
479
|
+
|
|
480
|
+
---
|
|
481
|
+
|
|
482
|
+
**Next steps:**
|
|
483
|
+
1. Implement the test stubs (replace `throw new Error(...)` with actual test logic)
|
|
484
|
+
2. Run `/exec <issue>` to implement the feature
|
|
485
|
+
3. Verify tests pass with `npm test`
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
Generated with [Claude Code](https://claude.com/claude-code)
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
## Error Handling
|
|
492
|
+
|
|
493
|
+
### No Verification Criteria Found
|
|
494
|
+
|
|
495
|
+
If the issue doesn't have verification criteria in the /spec comment:
|
|
496
|
+
|
|
497
|
+
```markdown
|
|
498
|
+
## Unable to Generate Tests
|
|
499
|
+
|
|
500
|
+
No verification criteria found in the latest /spec comment for Issue #<N>.
|
|
501
|
+
|
|
502
|
+
**Next steps:**
|
|
503
|
+
1. Run `/spec <issue>` first to create a plan with verification criteria
|
|
504
|
+
2. Ensure each AC has a "Verification Method" and "Test Scenario"
|
|
505
|
+
3. Then run `/testgen <issue>` again
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Missing Worktree
|
|
509
|
+
|
|
510
|
+
If generating file-based tests and no worktree exists:
|
|
511
|
+
|
|
512
|
+
```markdown
|
|
513
|
+
## Worktree Not Found
|
|
514
|
+
|
|
515
|
+
Cannot generate test files - no feature worktree exists for Issue #<N>.
|
|
516
|
+
|
|
517
|
+
**Options:**
|
|
518
|
+
1. Run `/exec <issue>` first (creates worktree automatically)
|
|
519
|
+
2. Create worktree manually: `./scripts/dev/new-feature.sh <issue>`
|
|
520
|
+
3. Use the browser/manual test scenarios from this comment
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Existing Test Files
|
|
524
|
+
|
|
525
|
+
If test files already exist:
|
|
526
|
+
- Don't overwrite existing tests
|
|
527
|
+
- Note which files were skipped
|
|
528
|
+
- Suggest reviewing existing tests against new verification criteria
|
|
529
|
+
|
|
530
|
+
## Example Output
|
|
531
|
+
|
|
532
|
+
For Issue #452 (hooks):
|
|
533
|
+
|
|
534
|
+
**Generated files:**
|
|
535
|
+
- `__tests__/integration/hooks.integration.test.ts`
|
|
536
|
+
|
|
537
|
+
**GitHub comment:**
|
|
538
|
+
```markdown
|
|
539
|
+
## Test Stubs Generated for Issue #452
|
|
540
|
+
|
|
541
|
+
| AC | Verification | Happy Path | Failure Paths |
|
|
542
|
+
|----|--------------|------------|---------------|
|
|
543
|
+
| AC-1 | Integration | 1 test | 3 error scenarios |
|
|
544
|
+
|
|
545
|
+
### Integration Test Stubs
|
|
546
|
+
|
|
547
|
+
**File:** `__tests__/integration/hooks.integration.test.ts`
|
|
548
|
+
- Happy path: 1 test case
|
|
549
|
+
- Assumption validators: 1 test
|
|
550
|
+
- Error scenarios: 3 failure stubs
|
|
551
|
+
|
|
552
|
+
**Assumptions to validate before implementation:**
|
|
553
|
+
- [ ] Claude Code passes tool data via stdin JSON (NOT env vars)
|
|
554
|
+
- [ ] stdin JSON contains tool_name field
|
|
555
|
+
- [ ] stdin JSON contains tool_input field
|
|
556
|
+
- [ ] Hook can parse JSON with jq
|
|
557
|
+
- [ ] Hook has write permission to /tmp
|
|
558
|
+
|
|
559
|
+
---
|
|
560
|
+
Generated with [Claude Code](https://claude.com/claude-code)
|
|
561
|
+
```
|