Convert passed QA Contract criteria to automated tests
Convert verified QA Contract criteria (G#N, AC#N) into permanent automated tests. Ensures passing scenarios become regression tests.
From qa-commit's Verification Report:
| Criteria Type | Test Framework | Location |
|---------------|----------------|----------|
| G#N (Backend) | Jest | apps/api/**/*.test.ts |
| AC#N (UI State) | Storybook | **/*.stories.tsx |
| AC#N (Interaction) | Playwright | tests/e2e/**/*.spec.ts |
Grep: "G#[N]" or "[scenario name]" in test files
Skip if test already exists.
For each passed G#N without existing test:
// apps/api/src/[feature]/__tests__/[feature].test.ts
describe('[Feature Name]', () => {
// G#1: [Scenario name]
it('should [expected behavior]', async () => {
// Arrange
const input = { /* test data */ };
// Act
const response = await request(app)
.[method]('[endpoint]')
.send(input);
// Assert
expect(response.status).toBe([status]);
expect(response.body).toMatchObject({ /* expected */ });
});
// G#2: [Scenario name]
it('should return [error] when [condition]', async () => {
// Test implementation
});
});
npm run test -- --grep "[scenario name]"
For state-based AC#N:
// apps/web/src/[component]/[Component].stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Component } from './Component';
const meta: Meta<typeof Component> = {
title: 'Features/[Feature]/[Component]',
component: Component,
};
export default meta;
type Story = StoryObj<typeof Component>;
// AC#1: Renders without error
export const Default: Story = {
args: { /* default props */ },
};
// AC#2: Shows loading state
export const Loading: Story = {
args: { isLoading: true },
};
// AC#3: Shows error state
export const Error: Story = {
args: { error: 'Something went wrong' },
};
// AC#4: Shows empty state
export const Empty: Story = {
args: { data: [] },
};
npm run storybook -- --smoke-test
For interaction-based AC#N:
// tests/e2e/[feature].spec.ts
import { test, expect } from '@playwright/test';
test.describe('[Feature Name]', () => {
// AC#5: User can submit form
test('should allow form submission', async ({ page }) => {
await page.goto('/[route]');
await page.fill('[name="field"]', 'value');
await page.click('[type="submit"]');
await expect(page.locator('.success')).toBeVisible();
});
// AC#6: Keyboard navigation works
test('should support keyboard navigation', async ({ page }) => {
await page.goto('/[route]');
await page.keyboard.press('Tab');
await expect(page.locator(':focus')).toHaveAttribute('name', 'first-field');
});
});
npx playwright test [feature].spec.ts
Run all generated tests:
# Backend
npm run test
# Storybook
npm run storybook -- --smoke-test
# E2E (if applicable)
npx playwright test
## Test Hardening Report
### Generated Tests
| Criteria | Type | File | Status |
|----------|------|------|--------|
| G#1 | Jest | `[path]` | CREATED/EXISTS |
| G#2 | Jest | `[path]` | CREATED/EXISTS |
| AC#1 | Storybook | `[path]` | CREATED/EXISTS |
| AC#3 | Playwright | `[path]` | CREATED/EXISTS |
### Test Results
| Suite | Total | Passed | Failed |
|-------|-------|--------|--------|
| Jest | [N] | [N] | 0 |
| Storybook | [N] | [N] | 0 |
| Playwright | [N] | [N] | 0 |
### Coverage Update
- Backend: [N]% → [N]%
- Frontend: [N]% → [N]%
When invoked from debug skill Phase 7 (Harden):
// Regression test for [issue description]
// Debug session: [date]
it('should not [bug behavior] when [condition]', async () => {
// Reproduction steps from debug
});
Invoked by:
qa-commit - After GREEN verdictdebug - Phase 7 HardenOr manually with "use test-hardening skill".
下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer