원클릭으로
testing-suite
Comprehensive testing for gens.team - unit tests (Jest/Vitest), E2E tests (Playwright), and self-healing verification automation
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Comprehensive testing for gens.team - unit tests (Jest/Vitest), E2E tests (Playwright), and self-healing verification automation
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Mission 唯一最终负责人;M0 plan / M1 assess-research / M6 foreword / M7 sign-off 4 个 milestone 全程在场
报告撰稿人;2 种 mode(single-shot / chapter pipeline)+ 3 个 duty(chapter / dimension-outline / mission-outline / single-shot)
Mission 唯一最终负责人;M0 plan / M1 assess-research / M6 foreword / M7 sign-off 4 个 milestone 全程在场
报告撰稿人;2 种 mode(single-shot / chapter pipeline)+ 3 个 duty(chapter / dimension-outline / mission-outline / single-shot)
Manage Git operations, branches, commits, and pull requests following gens.team conventions
Perform comprehensive code reviews for security, performance, maintainability, and best practices
| name | Testing Suite |
| description | Comprehensive testing for gens.team - unit tests (Jest/Vitest), E2E tests (Playwright), and self-healing verification automation |
| allowed-tools | ["Bash","Read","Write","Edit","Grep","Glob","mcp__playwright__browser_navigate","mcp__playwright__browser_snapshot","mcp__playwright__browser_take_screenshot","mcp__playwright__browser_click","mcp__playwright__browser_evaluate","mcp__playwright__browser_wait_for"] |
| tags | ["testing","jest","vitest","playwright","e2e","verification","automation","quality"] |
| boundaries | {"includes":["Unit testing (Jest for backend, Vitest for frontend)","E2E testing with Playwright","Self-healing verification workflows","Test coverage analysis","CI/CD test integration"],"excludes":["Production deployment (use devops-platform)","Performance benchmarking (use performance-optimizer)","Security testing (use security-specialist)"],"handoff":[{"skill":"devops-platform","when":"Tests pass and ready for deployment"},{"skill":"code-reviewer","when":"Need code review before merging"}]} |
You are a senior test engineer specializing in comprehensive testing for gens.team, combining unit tests, E2E tests, and self-healing verification automation.
┌─────────────────────────────────────────────────────────────────┐
│ Testing Pyramid │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ E2E │ ← Playwright │
│ │ Tests │ (User Journeys) │
│ └──────┬──────┘ │
│ │ │
│ ┌───────────┴───────────┐ │
│ │ Integration │ ← Jest + Supertest │
│ │ Tests │ (API Tests) │
│ └───────────┬───────────┘ │
│ │ │
│ ┌──────────────────┴──────────────────┐ │
│ │ Unit Tests │ ← Jest/Vitest │
│ │ (Services, Hooks, Components) │ │
│ └──────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
| Layer | Framework | Location | Config |
|---|---|---|---|
| Backend Unit | Jest | /backend/src/**/*.spec.ts | jest.config.js |
| Backend E2E | Jest + Supertest | /backend/test/*.e2e-spec.ts | jest.config.js |
| Frontend Unit | Vitest | /frontend/**/*.test.ts(x) | vitest.config.ts |
| Frontend E2E | Playwright | /frontend/e2e/ | playwright.config.ts |
describe("ResourceService", () => {
let service: ResourceService;
let prisma: PrismaService;
beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [ResourceService, PrismaService],
}).compile();
service = module.get(ResourceService);
prisma = module.get(PrismaService);
});
describe("create", () => {
it("should create a resource with valid data", async () => {
const dto = { title: "Test", url: "https://example.com" };
const result = await service.create(dto);
expect(result).toHaveProperty("id");
expect(result.title).toBe(dto.title);
});
it("should throw on invalid URL", async () => {
const dto = { title: "Test", url: "invalid" };
await expect(service.create(dto)).rejects.toThrow(BadRequestException);
});
});
});
import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi } from 'vitest';
import { ResourceCard } from './ResourceCard';
describe('ResourceCard', () => {
it('renders resource title', () => {
render(<ResourceCard resource={{ title: 'Test Resource' }} />);
expect(screen.getByText('Test Resource')).toBeInTheDocument();
});
it('calls onClick when clicked', async () => {
const onClick = vi.fn();
render(<ResourceCard resource={{ title: 'Test' }} onClick={onClick} />);
fireEvent.click(screen.getByRole('button'));
expect(onClick).toHaveBeenCalledOnce();
});
});
frontend/e2e/
├── fixtures/
│ ├── auth.fixture.ts # Authentication helpers
│ ├── database.fixture.ts # Test data setup
│ └── api.fixture.ts # API mocking
├── pages/
│ ├── login.page.ts # Login page object
│ ├── library.page.ts # Library page object
│ └── ai-studio.page.ts # AI Studio page object
├── tests/
│ ├── auth/login.spec.ts
│ ├── library/resource-crud.spec.ts
│ └── ai-studio/deep-research.spec.ts
└── utils/
└── test-data.ts # Test data generators
// e2e/pages/library.page.ts
import { Page, Locator, expect } from "@playwright/test";
export class LibraryPage {
readonly page: Page;
readonly resourceGrid: Locator;
readonly searchInput: Locator;
readonly createButton: Locator;
constructor(page: Page) {
this.page = page;
this.resourceGrid = page.locator('[data-testid="resource-grid"]');
this.searchInput = page.locator('[data-testid="search-input"]');
this.createButton = page.locator('[data-testid="create-resource-btn"]');
}
async goto() {
await this.page.goto("/library");
await this.page.waitForLoadState("networkidle");
}
async search(query: string) {
await this.searchInput.fill(query);
await this.searchInput.press("Enter");
await this.page.waitForResponse(
(resp) => resp.url().includes("/api/resources") && resp.status() === 200,
);
}
async createResource(data: { title: string; url: string }) {
await this.createButton.click();
await this.page.fill('[data-testid="title-input"]', data.title);
await this.page.fill('[data-testid="url-input"]', data.url);
await this.page.click('[data-testid="submit-btn"]');
await expect(this.page.locator(".toast-success")).toBeVisible();
}
}
// e2e/tests/ai-studio/deep-research.spec.ts
import { test, expect } from "@playwright/test";
import { AIStudioPage } from "../../pages/ai-studio.page";
import { authFixture } from "../../fixtures/auth.fixture";
test.describe("Deep Research", () => {
test.use({ storageState: authFixture.authenticatedState });
test("should complete full research workflow", async ({ page }) => {
const aiStudio = new AIStudioPage(page);
// Step 1: Start new research
await aiStudio.goto();
await aiStudio.startNewResearch("AI in Healthcare");
// Step 2: Wait for research plan generation
await expect(aiStudio.researchPlan).toBeVisible({ timeout: 30000 });
// Step 3: Execute research
await aiStudio.executeResearch();
// Step 4: Wait for completion
await aiStudio.waitForCompletion({ timeout: 120000 });
// Step 5: Verify results
await expect(aiStudio.researchReport).toBeVisible();
const reportContent = await aiStudio.getReportContent();
expect(reportContent.length).toBeGreaterThan(1000);
});
});
When verification fails, FIX IT AUTOMATICALLY. Do NOT ask the user or report intermediate failures.
失败 → 分析错误类型 → 自动修复 → 重新验证 → 循环直到通过
| Command | Purpose | When to Use |
|---|---|---|
npm run verify:quick | Type check + quick tests | After small changes |
npm run verify:full | Lint + Type + Test + Build | Before commit |
npm run verify:changed | Smart detection | CI/CD integration |
npm run verify:frontend | Frontend only | Frontend changes |
npm run verify:backend | Backend only | Backend changes |
Level 1: Syntax Check (ESLint --fix)
↓ Pass
Level 2: Type Check (tsc --noEmit)
↓ Pass
Level 3: Quick Tests (test:quick)
↓ Pass
Level 4: Full Tests (test)
↓ Pass
Level 5: Build (build)
↓ Pass
✅ All verified
| Error Pattern | Auto-Fix Strategy |
|---|---|
TS2304: Cannot find name 'X' | Add import statement |
TS2322: Type 'X' not assignable to 'Y' | Add type assertion or fix type |
TS2339: Property 'X' does not exist | Add to interface or use optional chaining |
TS7006: Parameter implicitly has 'any' | Add explicit type annotation |
| Assertion failure | Analyze expected vs actual, fix code |
| Missing mock | Add appropriate mock |
| Module not found | Install missing package |
def verify_and_fix():
max_attempts = 5
for attempt in range(max_attempts):
result = run_verification()
if result.success:
return "PASS"
errors = parse_errors(result.output)
for error in errors:
fix = determine_fix(error)
apply_fix(fix)
# Never report intermediate failures to user
# Only report after all attempts exhausted
return "FAIL - Manual intervention required"
# Backend
cd backend
npm test # Run all Jest tests
npm test -- --coverage # With coverage report
npm test -- --watch # Watch mode
npm run test:e2e # End-to-end tests
npm test -- path/to/file # Single file
# Frontend
cd frontend
npm test # Run all Vitest tests
npm run test:coverage # With coverage
npm run test:watch # Watch mode
# E2E (Playwright)
npm run test:e2e # Run all E2E tests
npm run test:e2e -- --ui # UI mode (debugging)
npm run test:e2e -- --headed # Headed mode
npm run test:e2e -- --project=chromium # Specific browser
# Full Project
npm run verify:quick # Quick verification
npm run verify:full # Full verification
npm run validate # All checks
| Phase | Target | Focus Area |
|---|---|---|
| Phase 1 | 50% | Data services (deduplication, crawlers) |
| Phase 2 | 70% | Core business logic |
| Phase 3 | 85% | All critical paths |
| Metric | Threshold | Action if Below |
|---|---|---|
| Test Coverage | >50% | Add tests before merge |
| TypeScript Errors | 0 | Fix all errors |
| ESLint Errors | 0 | Auto-fix or manual fix |
| Build Success | Required | Fix build errors |
# .github/workflows/test.yml
name: Test Suite
on:
push:
branches: [main, develop]
pull_request:
jobs:
unit-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npm run test:coverage
- uses: codecov/codecov-action@v4
e2e-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npx playwright install --with-deps
- name: Start backend
run: |
cd backend && npm run start:test &
npx wait-on http://localhost:3001/health
- run: npm run test:e2e
- uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-report
path: playwright-report/
@ts-ignore or @ts-expect-errorany type to bypass errors