omgkit 2.1.1 → 2.3.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/package.json +1 -1
- package/plugin/skills/databases/mongodb/SKILL.md +81 -28
- package/plugin/skills/databases/prisma/SKILL.md +87 -32
- package/plugin/skills/databases/redis/SKILL.md +80 -27
- package/plugin/skills/devops/aws/SKILL.md +80 -26
- package/plugin/skills/devops/github-actions/SKILL.md +84 -32
- package/plugin/skills/devops/kubernetes/SKILL.md +94 -32
- package/plugin/skills/devops/performance-profiling/SKILL.md +59 -863
- package/plugin/skills/frameworks/django/SKILL.md +158 -24
- package/plugin/skills/frameworks/express/SKILL.md +153 -33
- package/plugin/skills/frameworks/fastapi/SKILL.md +153 -34
- package/plugin/skills/frameworks/laravel/SKILL.md +146 -33
- package/plugin/skills/frameworks/nestjs/SKILL.md +137 -25
- package/plugin/skills/frameworks/rails/SKILL.md +594 -28
- package/plugin/skills/frameworks/react/SKILL.md +94 -962
- package/plugin/skills/frameworks/spring/SKILL.md +528 -35
- package/plugin/skills/frameworks/vue/SKILL.md +147 -25
- package/plugin/skills/frontend/accessibility/SKILL.md +145 -36
- package/plugin/skills/frontend/frontend-design/SKILL.md +114 -29
- package/plugin/skills/frontend/responsive/SKILL.md +131 -28
- package/plugin/skills/frontend/shadcn-ui/SKILL.md +133 -43
- package/plugin/skills/frontend/tailwindcss/SKILL.md +105 -37
- package/plugin/skills/frontend/threejs/SKILL.md +110 -35
- package/plugin/skills/languages/javascript/SKILL.md +195 -34
- package/plugin/skills/methodology/brainstorming/SKILL.md +98 -30
- package/plugin/skills/methodology/defense-in-depth/SKILL.md +83 -37
- package/plugin/skills/methodology/dispatching-parallel-agents/SKILL.md +92 -31
- package/plugin/skills/methodology/executing-plans/SKILL.md +117 -28
- package/plugin/skills/methodology/finishing-development-branch/SKILL.md +111 -32
- package/plugin/skills/methodology/problem-solving/SKILL.md +65 -311
- package/plugin/skills/methodology/receiving-code-review/SKILL.md +76 -27
- package/plugin/skills/methodology/requesting-code-review/SKILL.md +93 -22
- package/plugin/skills/methodology/root-cause-tracing/SKILL.md +75 -40
- package/plugin/skills/methodology/sequential-thinking/SKILL.md +75 -224
- package/plugin/skills/methodology/systematic-debugging/SKILL.md +81 -35
- package/plugin/skills/methodology/test-driven-development/SKILL.md +120 -26
- package/plugin/skills/methodology/testing-anti-patterns/SKILL.md +88 -35
- package/plugin/skills/methodology/token-optimization/SKILL.md +73 -34
- package/plugin/skills/methodology/verification-before-completion/SKILL.md +128 -28
- package/plugin/skills/methodology/writing-plans/SKILL.md +105 -20
- package/plugin/skills/omega/omega-architecture/SKILL.md +178 -40
- package/plugin/skills/omega/omega-coding/SKILL.md +247 -41
- package/plugin/skills/omega/omega-sprint/SKILL.md +208 -46
- package/plugin/skills/omega/omega-testing/SKILL.md +253 -42
- package/plugin/skills/omega/omega-thinking/SKILL.md +263 -51
- package/plugin/skills/security/better-auth/SKILL.md +83 -34
- package/plugin/skills/security/oauth/SKILL.md +118 -35
- package/plugin/skills/security/owasp/SKILL.md +112 -35
- package/plugin/skills/testing/playwright/SKILL.md +141 -38
- package/plugin/skills/testing/pytest/SKILL.md +137 -38
- package/plugin/skills/testing/vitest/SKILL.md +124 -39
- package/plugin/skills/tools/document-processing/SKILL.md +111 -838
- package/plugin/skills/tools/image-processing/SKILL.md +126 -659
- package/plugin/skills/tools/mcp-development/SKILL.md +85 -758
- package/plugin/skills/tools/media-processing/SKILL.md +118 -735
- package/plugin/stdrules/SKILL_STANDARDS.md +490 -0
|
@@ -1,64 +1,226 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: omega-
|
|
3
|
-
description:
|
|
2
|
+
name: managing-omega-sprints
|
|
3
|
+
description: Orchestrates AI-native sprint management with autonomous agent coordination and continuous delivery. Use when running development sprints with AI agent teams or coordinating parallel task execution.
|
|
4
|
+
category: omega
|
|
5
|
+
triggers:
|
|
6
|
+
- omega sprint
|
|
7
|
+
- sprint planning
|
|
8
|
+
- AI team management
|
|
9
|
+
- agent orchestration
|
|
4
10
|
---
|
|
5
11
|
|
|
6
|
-
# Omega
|
|
12
|
+
# Managing Omega Sprints
|
|
7
13
|
|
|
8
|
-
|
|
14
|
+
Execute **AI-native sprint management** with autonomous agent orchestration, intelligent task routing, and continuous delivery cycles.
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
```yaml
|
|
19
|
+
# 1. Define sprint vision
|
|
20
|
+
Vision:
|
|
21
|
+
Objective: "Implement OAuth2 authentication"
|
|
22
|
+
Success: ["3 providers", "95% completion rate", "OWASP compliant"]
|
|
23
|
+
|
|
24
|
+
# 2. Break into agent-executable tasks
|
|
25
|
+
Tasks:
|
|
26
|
+
- { id: "types", agent: "architect", tokens: 5K }
|
|
27
|
+
- { id: "google-oauth", agent: "fullstack", tokens: 8K, depends: ["types"] }
|
|
28
|
+
- { id: "tests", agent: "tester", tokens: 6K, depends: ["google-oauth"] }
|
|
29
|
+
|
|
30
|
+
# 3. Execute with autonomy level
|
|
31
|
+
Execution:
|
|
32
|
+
Autonomy: "semi-auto"
|
|
33
|
+
Checkpoints: ["phase-complete", "error-threshold"]
|
|
34
|
+
QualityGates: ["coverage > 80%", "no-critical-bugs"]
|
|
9
35
|
```
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
| Feature | Description | Guide |
|
|
40
|
+
|---------|-------------|-------|
|
|
41
|
+
| Sprint Lifecycle | Vision, Plan, Execute, Deliver, Retrospect | AI-native 5-phase cycle |
|
|
42
|
+
| Task Breakdown | Atomic, testable, agent-sized tasks | Hours not days per task |
|
|
43
|
+
| Agent Routing | Match tasks to optimal agents | Capability + load scoring |
|
|
44
|
+
| Autonomy Levels | Full-auto to supervised modes | Balance speed and oversight |
|
|
45
|
+
| Quality Gates | Automated checkpoints | Coverage, security, performance |
|
|
46
|
+
| Parallel Execution | Swarm-based task processing | Maximize parallelization |
|
|
47
|
+
| Sprint Analytics | Velocity, quality, efficiency metrics | Continuous improvement |
|
|
48
|
+
|
|
49
|
+
## Common Patterns
|
|
50
|
+
|
|
51
|
+
### Sprint Lifecycle
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
VISION ──> PLAN ──> EXECUTE ──> DELIVER ──> RETROSPECT
|
|
55
|
+
│ │ │ │ │
|
|
56
|
+
▼ ▼ ▼ ▼ ▼
|
|
57
|
+
Define Break into Agents Ship to Learn and
|
|
58
|
+
success agent-ready work production improve
|
|
59
|
+
criteria tasks parallel
|
|
13
60
|
```
|
|
14
61
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
62
|
+
### Vision Definition
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
interface SprintVision {
|
|
66
|
+
objective: string;
|
|
67
|
+
businessValue: string;
|
|
68
|
+
successCriteria: SuccessCriterion[];
|
|
69
|
+
scope: {
|
|
70
|
+
included: string[];
|
|
71
|
+
excluded: string[];
|
|
72
|
+
risks: Risk[];
|
|
73
|
+
};
|
|
74
|
+
qualityGates: QualityGate[];
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const vision: SprintVision = {
|
|
78
|
+
objective: "Implement user authentication with OAuth2",
|
|
79
|
+
businessValue: "Reduce signup friction by 60%",
|
|
80
|
+
successCriteria: [
|
|
81
|
+
{ metric: "OAuth providers", target: 3 },
|
|
82
|
+
{ metric: "Auth completion rate", target: "95%" },
|
|
83
|
+
{ metric: "Security audit", target: "OWASP compliant" }
|
|
84
|
+
],
|
|
85
|
+
qualityGates: [
|
|
86
|
+
{ type: 'coverage', threshold: 80 },
|
|
87
|
+
{ type: 'security-scan', threshold: 'no-critical' }
|
|
88
|
+
]
|
|
89
|
+
};
|
|
22
90
|
```
|
|
23
91
|
|
|
24
|
-
|
|
25
|
-
1. Review backlog
|
|
26
|
-
2. Select tasks for sprint
|
|
27
|
-
3. Estimate (optional)
|
|
28
|
-
4. Assign to agents
|
|
92
|
+
### Task Breakdown
|
|
29
93
|
|
|
30
|
-
|
|
94
|
+
```typescript
|
|
95
|
+
interface SprintTask {
|
|
96
|
+
id: string;
|
|
97
|
+
title: string;
|
|
98
|
+
type: 'feature' | 'bugfix' | 'test' | 'docs';
|
|
99
|
+
priority: 'critical' | 'high' | 'medium';
|
|
100
|
+
estimatedTokens: number;
|
|
101
|
+
dependencies: string[];
|
|
102
|
+
suggestedAgent: AgentType;
|
|
103
|
+
acceptanceCriteria: string[];
|
|
104
|
+
}
|
|
31
105
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
106
|
+
// Layer-based breakdown
|
|
107
|
+
const tasks = [
|
|
108
|
+
// Layer 1: Foundation
|
|
109
|
+
{ id: 'types', title: 'Define TypeScript interfaces', agent: 'architect' },
|
|
110
|
+
{ id: 'schema', title: 'Create DB migrations', depends: ['types'] },
|
|
111
|
+
|
|
112
|
+
// Layer 2: Implementation (parallel)
|
|
113
|
+
{ id: 'google', title: 'Google OAuth', depends: ['types'] },
|
|
114
|
+
{ id: 'github', title: 'GitHub OAuth', depends: ['types'] },
|
|
115
|
+
|
|
116
|
+
// Layer 3: Quality
|
|
117
|
+
{ id: 'tests', title: 'Integration tests', depends: ['google', 'github'] }
|
|
118
|
+
];
|
|
119
|
+
```
|
|
36
120
|
|
|
37
121
|
### Agent Routing
|
|
38
|
-
| Task Type | Agent |
|
|
39
|
-
|-----------|-------|
|
|
40
|
-
| feature | fullstack-developer |
|
|
41
|
-
| bugfix | debugger |
|
|
42
|
-
| research | oracle |
|
|
43
|
-
| docs | docs-manager |
|
|
44
|
-
| test | tester |
|
|
45
|
-
|
|
46
|
-
## Retrospective
|
|
47
|
-
```markdown
|
|
48
|
-
## What Went Well
|
|
49
|
-
- [Success]
|
|
50
122
|
|
|
51
|
-
|
|
52
|
-
|
|
123
|
+
```typescript
|
|
124
|
+
type AgentType = 'architect' | 'fullstack' | 'debugger' | 'tester' | 'reviewer';
|
|
53
125
|
|
|
54
|
-
|
|
55
|
-
|
|
126
|
+
const routingRules: Record<TaskType, AgentType[]> = {
|
|
127
|
+
feature: ['fullstack', 'frontend', 'backend'],
|
|
128
|
+
bugfix: ['debugger', 'fullstack'],
|
|
129
|
+
test: ['tester'],
|
|
130
|
+
docs: ['docs-manager'],
|
|
131
|
+
research: ['oracle', 'architect']
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Scoring algorithm
|
|
135
|
+
function calculateFitScore(agent: Agent, task: Task): number {
|
|
136
|
+
let score = 0;
|
|
137
|
+
score += capabilityMatch * 40; // Core capabilities
|
|
138
|
+
score += specializationMatch * 30; // Domain expertise
|
|
139
|
+
score += (1 - loadFactor) * 20; // Availability
|
|
140
|
+
score += hasContext ? 10 : 0; // Context continuity
|
|
141
|
+
return score;
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Autonomy Levels
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const autonomyConfigs = {
|
|
149
|
+
'full-auto': {
|
|
150
|
+
checkpoints: [{ trigger: 'phase-complete', action: 'notify' }],
|
|
151
|
+
approvalRequired: ['production-deploy']
|
|
152
|
+
},
|
|
153
|
+
'semi-auto': {
|
|
154
|
+
checkpoints: [
|
|
155
|
+
{ trigger: 'task-complete', action: 'notify' },
|
|
156
|
+
{ trigger: 'phase-complete', action: 'review', timeout: 3600 }
|
|
157
|
+
],
|
|
158
|
+
approvalRequired: ['merge-to-main', 'production-deploy']
|
|
159
|
+
},
|
|
160
|
+
'supervised': {
|
|
161
|
+
checkpoints: [{ trigger: 'task-complete', action: 'review' }],
|
|
162
|
+
approvalRequired: ['all-merges', 'all-deploys']
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Sprint Metrics
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
interface SprintMetrics {
|
|
171
|
+
velocity: { completed: number; planned: number; ratio: number };
|
|
172
|
+
quality: { bugs: number; coverage: number; score: number };
|
|
173
|
+
efficiency: { totalTokens: number; parallelization: number };
|
|
174
|
+
agents: Map<AgentType, { tasks: number; efficiency: number }>;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Dashboard template
|
|
178
|
+
`
|
|
179
|
+
SPRINT DASHBOARD: ${name}
|
|
180
|
+
────────────────────────────────────
|
|
181
|
+
PROGRESS QUALITY AGENTS
|
|
182
|
+
████████░░ 80% Coverage: 87% arch: idle
|
|
183
|
+
24/30 tasks Bugs: 2 dev-1: working
|
|
184
|
+
Security: OK tester: queued
|
|
185
|
+
`
|
|
56
186
|
```
|
|
57
187
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
188
|
+
### Retrospective Framework
|
|
189
|
+
|
|
190
|
+
```markdown
|
|
191
|
+
## Sprint Retrospective
|
|
192
|
+
|
|
193
|
+
### Summary
|
|
194
|
+
- Velocity: X/Y tasks (Z%)
|
|
195
|
+
- Quality: Coverage %, Bugs introduced
|
|
196
|
+
- Efficiency: Tokens used, Parallelization ratio
|
|
197
|
+
|
|
198
|
+
### What Went Well
|
|
199
|
+
1. [Success] - Why it worked - How to replicate
|
|
200
|
+
|
|
201
|
+
### What Could Improve
|
|
202
|
+
1. [Challenge] - Root cause - Proposed solution
|
|
203
|
+
|
|
204
|
+
### Action Items
|
|
205
|
+
| Action | Priority | Owner |
|
|
206
|
+
|--------|----------|-------|
|
|
207
|
+
| [Action] | High | [Agent] |
|
|
208
|
+
|
|
209
|
+
### Learnings to Encode
|
|
210
|
+
- [Pattern to add to agent prompts]
|
|
64
211
|
```
|
|
212
|
+
|
|
213
|
+
## Best Practices
|
|
214
|
+
|
|
215
|
+
| Do | Avoid |
|
|
216
|
+
|----|-------|
|
|
217
|
+
| Define clear success criteria before sprint | Starting without vision and scope |
|
|
218
|
+
| Break tasks small enough for single-agent | Tasks with circular dependencies |
|
|
219
|
+
| Enable maximum parallelization | Skipping quality gates under pressure |
|
|
220
|
+
| Set appropriate autonomy based on risk | Ignoring retrospective insights |
|
|
221
|
+
| Track metrics consistently | Over-committing capacity |
|
|
222
|
+
| Run retrospectives after every sprint | Context-switching agents unnecessarily |
|
|
223
|
+
| Encode learnings into agent prompts | Deploying without automated tests |
|
|
224
|
+
| Use quality gates to prevent regressions | Letting blockers sit unaddressed |
|
|
225
|
+
| Maintain sprint rhythm for predictability | Skipping the retrospective phase |
|
|
226
|
+
| Celebrate wins to build momentum | Forgetting to update documentation |
|
|
@@ -1,71 +1,282 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: omega-
|
|
3
|
-
description:
|
|
2
|
+
name: testing-omega-quality
|
|
3
|
+
description: Implements comprehensive testing across all quality dimensions - accuracy, performance, security, and accessibility. Use when building test strategies or ensuring production-grade quality assurance.
|
|
4
|
+
category: omega
|
|
5
|
+
triggers:
|
|
6
|
+
- omega testing
|
|
7
|
+
- comprehensive testing
|
|
8
|
+
- test strategy
|
|
9
|
+
- quality assurance
|
|
4
10
|
---
|
|
5
11
|
|
|
6
|
-
# Omega
|
|
12
|
+
# Testing Omega Quality
|
|
13
|
+
|
|
14
|
+
Master **comprehensive testing strategies** covering all quality dimensions - accuracy, performance, security, and accessibility.
|
|
15
|
+
|
|
16
|
+
## Quick Start
|
|
17
|
+
|
|
18
|
+
```yaml
|
|
19
|
+
# 1. Define test strategy with 4 dimensions
|
|
20
|
+
TestStrategy:
|
|
21
|
+
Accuracy: { unit: 80%, integration: 60%, e2e: "critical paths" }
|
|
22
|
+
Performance: { p95: "<200ms", concurrent: 50 }
|
|
23
|
+
Security: { injection: true, auth: true, xss: true }
|
|
24
|
+
Accessibility: { wcag: "2.1 AA", keyboard: true }
|
|
25
|
+
|
|
26
|
+
# 2. Follow the test pyramid
|
|
27
|
+
Pyramid:
|
|
28
|
+
Unit: 80% # Fast, isolated, business logic
|
|
29
|
+
Component: 70% # UI components with mocks
|
|
30
|
+
Integration: 60% # API endpoints, data flow
|
|
31
|
+
E2E: "critical" # Happy paths, auth, checkout
|
|
32
|
+
|
|
33
|
+
# 3. Run quality gates in CI
|
|
34
|
+
Gates: ["coverage > 80%", "no-security-issues", "a11y-pass"]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Features
|
|
38
|
+
|
|
39
|
+
| Feature | Description | Guide |
|
|
40
|
+
|---------|-------------|-------|
|
|
41
|
+
| 4D Testing | Accuracy, Performance, Security, Accessibility | Cover all quality dimensions |
|
|
42
|
+
| Test Pyramid | Unit, Component, Integration, E2E layers | More units, fewer E2E |
|
|
43
|
+
| Property-Based | Test with generated inputs | Catch edge cases automatically |
|
|
44
|
+
| Performance | Response time, load, memory testing | Percentile-based thresholds |
|
|
45
|
+
| Security | SQL injection, XSS, auth bypass tests | OWASP-aligned coverage |
|
|
46
|
+
| Accessibility | WCAG compliance, keyboard, screen reader | Automated a11y scanning |
|
|
47
|
+
| Visual Regression | Screenshot comparison testing | Catch UI regressions |
|
|
48
|
+
|
|
49
|
+
## Common Patterns
|
|
50
|
+
|
|
51
|
+
### The Omega Test Pyramid
|
|
7
52
|
|
|
8
|
-
## Testing Pyramid
|
|
9
53
|
```
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
54
|
+
/\
|
|
55
|
+
/E2E\ <- Critical paths only (slowest)
|
|
56
|
+
/─────\
|
|
57
|
+
/ Visual \ <- Screenshot comparisons
|
|
58
|
+
/───────────\
|
|
59
|
+
/ Integration \ <- Service boundaries, APIs
|
|
60
|
+
/───────────────\
|
|
61
|
+
/ Component \ <- UI components isolated
|
|
62
|
+
/───────────────────\
|
|
63
|
+
/ Unit \ <- Fast, business logic (most)
|
|
64
|
+
/─────────────────────────\
|
|
17
65
|
```
|
|
18
66
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
67
|
+
### Four Quality Dimensions
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
interface OmegaTestSuite {
|
|
71
|
+
accuracy: {
|
|
72
|
+
happyPath: Test[]; // Normal use cases
|
|
73
|
+
edgeCases: Test[]; // Boundary conditions
|
|
74
|
+
errorCases: Test[]; // Failure handling
|
|
75
|
+
};
|
|
76
|
+
performance: {
|
|
77
|
+
responseTime: Test[]; // p50, p95, p99 latency
|
|
78
|
+
throughput: Test[]; // Requests per second
|
|
79
|
+
memory: Test[]; // Leak detection
|
|
80
|
+
};
|
|
81
|
+
security: {
|
|
82
|
+
authentication: Test[];
|
|
83
|
+
authorization: Test[];
|
|
84
|
+
injection: Test[]; // SQL, XSS prevention
|
|
85
|
+
};
|
|
86
|
+
accessibility: {
|
|
87
|
+
wcag: Test[]; // WCAG 2.1 AA
|
|
88
|
+
keyboard: Test[]; // Tab navigation
|
|
89
|
+
screenReader: Test[]; // ARIA labels
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
```
|
|
23
93
|
|
|
24
|
-
|
|
94
|
+
### Unit Testing Patterns
|
|
25
95
|
|
|
26
|
-
### 1. Happy Path
|
|
27
96
|
```typescript
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
97
|
+
// Arrange-Act-Assert pattern
|
|
98
|
+
describe('calculateDiscount', () => {
|
|
99
|
+
it('applies 10% discount for orders over $100', () => {
|
|
100
|
+
// Arrange
|
|
101
|
+
const order = createOrder({ subtotal: 150 });
|
|
102
|
+
|
|
103
|
+
// Act
|
|
104
|
+
const result = calculateDiscount(order);
|
|
105
|
+
|
|
106
|
+
// Assert
|
|
107
|
+
expect(result.discount).toBe(15);
|
|
108
|
+
expect(result.total).toBe(135);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Parameterized edge cases
|
|
113
|
+
it.each([
|
|
114
|
+
['missing @', 'userexample.com', false],
|
|
115
|
+
['valid format', 'user@example.com', true],
|
|
116
|
+
['empty string', '', false],
|
|
117
|
+
])('validateEmail %s: %s -> %s', (_desc, email, expected) => {
|
|
118
|
+
expect(validateEmail(email)).toBe(expected);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Property-based testing
|
|
122
|
+
it('sorted array has same length as input', () => {
|
|
123
|
+
fc.assert(fc.property(fc.array(fc.nat()), (arr) => {
|
|
124
|
+
return sortArray(arr).length === arr.length;
|
|
125
|
+
}));
|
|
31
126
|
});
|
|
32
127
|
```
|
|
33
128
|
|
|
34
|
-
###
|
|
129
|
+
### Integration Testing
|
|
130
|
+
|
|
35
131
|
```typescript
|
|
36
|
-
|
|
37
|
-
|
|
132
|
+
describe('UserService Integration', () => {
|
|
133
|
+
let db: TestDatabase;
|
|
134
|
+
|
|
135
|
+
beforeAll(async () => { db = await createTestDatabase(); });
|
|
136
|
+
afterAll(async () => { await cleanupTestDatabase(db); });
|
|
137
|
+
|
|
138
|
+
it('persists user to database', async () => {
|
|
139
|
+
const user = await userService.createUser({
|
|
140
|
+
email: 'test@example.com', name: 'Test'
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const dbUser = await db.query('SELECT * FROM users WHERE id = $1', [user.id]);
|
|
144
|
+
expect(dbUser.email).toBe('test@example.com');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('rolls back transaction on failure', async () => {
|
|
148
|
+
vi.spyOn(db, 'commit').mockRejectedValueOnce(new Error('DB error'));
|
|
149
|
+
|
|
150
|
+
await expect(userService.transfer(from, to, 50)).rejects.toThrow();
|
|
151
|
+
|
|
152
|
+
// Verify no changes persisted
|
|
153
|
+
expect(await userService.getBalance(from)).toBe(originalBalance);
|
|
154
|
+
});
|
|
38
155
|
});
|
|
39
156
|
```
|
|
40
157
|
|
|
41
|
-
###
|
|
158
|
+
### Performance Testing
|
|
159
|
+
|
|
42
160
|
```typescript
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
161
|
+
describe('API Performance', () => {
|
|
162
|
+
it('responds within SLA', async () => {
|
|
163
|
+
const times: number[] = [];
|
|
164
|
+
for (let i = 0; i < 100; i++) {
|
|
165
|
+
const start = performance.now();
|
|
166
|
+
await api.get('/users');
|
|
167
|
+
times.push(performance.now() - start);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
expect(percentile(times, 50)).toBeLessThan(50); // p50 < 50ms
|
|
171
|
+
expect(percentile(times, 95)).toBeLessThan(100); // p95 < 100ms
|
|
172
|
+
expect(percentile(times, 99)).toBeLessThan(200); // p99 < 200ms
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('handles concurrent load', async () => {
|
|
176
|
+
const requests = Array(50).fill(null).map(() => api.get('/users'));
|
|
177
|
+
const responses = await Promise.all(requests);
|
|
178
|
+
|
|
179
|
+
expect(responses.every(r => r.status === 200)).toBe(true);
|
|
180
|
+
});
|
|
46
181
|
});
|
|
47
182
|
```
|
|
48
183
|
|
|
49
|
-
###
|
|
184
|
+
### Security Testing
|
|
185
|
+
|
|
50
186
|
```typescript
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
187
|
+
describe('Security Tests', () => {
|
|
188
|
+
const sqlPayloads = ["'; DROP TABLE users; --", "' OR '1'='1"];
|
|
189
|
+
const xssPayloads = ['<script>alert("xss")</script>', '<img onerror=alert(1)>'];
|
|
190
|
+
|
|
191
|
+
it.each(sqlPayloads)('prevents SQL injection: %s', async (payload) => {
|
|
192
|
+
const response = await api.get(`/users?search=${encodeURIComponent(payload)}`);
|
|
193
|
+
expect(response.status).not.toBe(500);
|
|
194
|
+
expect(await db.query('SELECT * FROM users')).toBeDefined();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it.each(xssPayloads)('escapes XSS payload: %s', async (payload) => {
|
|
198
|
+
await api.post('/posts', { content: payload });
|
|
199
|
+
const html = (await api.get('/posts')).body.posts[0].content;
|
|
200
|
+
expect(html).not.toContain('<script>');
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('rate limits login attempts', async () => {
|
|
204
|
+
for (let i = 0; i < 10; i++) {
|
|
205
|
+
await api.post('/login', { email: 'x', password: 'wrong' });
|
|
206
|
+
}
|
|
207
|
+
const response = await api.post('/login', { email: 'x', password: 'wrong' });
|
|
208
|
+
expect(response.status).toBe(429);
|
|
209
|
+
});
|
|
55
210
|
});
|
|
56
211
|
```
|
|
57
212
|
|
|
58
|
-
###
|
|
213
|
+
### Accessibility Testing
|
|
214
|
+
|
|
59
215
|
```typescript
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
216
|
+
test.describe('Accessibility', () => {
|
|
217
|
+
test('page has no WCAG violations', async ({ page }) => {
|
|
218
|
+
await page.goto('/');
|
|
219
|
+
const results = await new AxeBuilder({ page })
|
|
220
|
+
.withTags(['wcag2a', 'wcag2aa', 'wcag21aa'])
|
|
221
|
+
.analyze();
|
|
222
|
+
expect(results.violations).toEqual([]);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
test('keyboard navigation works', async ({ page }) => {
|
|
226
|
+
await page.goto('/');
|
|
227
|
+
const focusable = 'a, button, input, [tabindex]:not([tabindex="-1"])';
|
|
228
|
+
const elements = await page.locator(focusable).all();
|
|
229
|
+
|
|
230
|
+
for (const _ of elements) {
|
|
231
|
+
await page.keyboard.press('Tab');
|
|
232
|
+
const focused = await page.evaluate(() => document.activeElement?.tagName);
|
|
233
|
+
expect(focused).toBeDefined();
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
test('images have alt text', async ({ page }) => {
|
|
238
|
+
const images = await page.locator('img').all();
|
|
239
|
+
for (const img of images) {
|
|
240
|
+
expect(await img.getAttribute('alt')).toBeTruthy();
|
|
241
|
+
}
|
|
242
|
+
});
|
|
63
243
|
});
|
|
64
244
|
```
|
|
65
245
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
246
|
+
### E2E Critical Path
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
test('complete purchase flow', async ({ page }) => {
|
|
250
|
+
// Login
|
|
251
|
+
await loginAsTestUser(page);
|
|
252
|
+
|
|
253
|
+
// Add to cart
|
|
254
|
+
await page.goto('/products/test-product');
|
|
255
|
+
await page.click('[data-testid="add-to-cart"]');
|
|
256
|
+
|
|
257
|
+
// Checkout
|
|
258
|
+
await page.click('[data-testid="checkout-button"]');
|
|
259
|
+
await page.fill('[data-testid="card-number"]', '4242424242424242');
|
|
260
|
+
await page.click('[data-testid="place-order"]');
|
|
261
|
+
|
|
262
|
+
// Verify
|
|
263
|
+
await expect(page).toHaveURL(/\/orders\/[a-z0-9-]+/);
|
|
264
|
+
await expect(page.locator('[data-testid="order-status"]'))
|
|
265
|
+
.toHaveText('Order Confirmed');
|
|
266
|
+
});
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Best Practices
|
|
270
|
+
|
|
271
|
+
| Do | Avoid |
|
|
272
|
+
|----|-------|
|
|
273
|
+
| Test all four quality dimensions | Testing only happy paths |
|
|
274
|
+
| Follow the test pyramid (more units) | Relying heavily on E2E tests |
|
|
275
|
+
| Use descriptive test names | Testing implementation details |
|
|
276
|
+
| Test edge cases systematically | Writing flaky tests |
|
|
277
|
+
| Keep tests independent (no shared state) | Using sleep/delays for timing |
|
|
278
|
+
| Use factories for test data | Hardcoding test data |
|
|
279
|
+
| Mock external dependencies in unit tests | Over-mocking in integration tests |
|
|
280
|
+
| Run tests in CI on every commit | Ignoring failing tests |
|
|
281
|
+
| Fix flaky tests immediately | Skipping tests without reason |
|
|
282
|
+
| Chase meaningful coverage, not 100% | Testing framework code |
|