start-vibing 2.0.11 → 2.0.13
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/README.md +177 -177
- package/dist/cli.js +19 -2
- package/package.json +42 -42
- package/template/.claude/CLAUDE.md +174 -174
- package/template/.claude/agents/01-orchestration/agent-selector.md +130 -130
- package/template/.claude/agents/01-orchestration/checkpoint-manager.md +142 -142
- package/template/.claude/agents/01-orchestration/context-manager.md +138 -138
- package/template/.claude/agents/01-orchestration/error-recovery.md +182 -182
- package/template/.claude/agents/01-orchestration/orchestrator.md +114 -114
- package/template/.claude/agents/01-orchestration/parallel-coordinator.md +141 -141
- package/template/.claude/agents/01-orchestration/task-decomposer.md +121 -121
- package/template/.claude/agents/01-orchestration/workflow-router.md +114 -114
- package/template/.claude/agents/02-typescript/bun-runtime-expert.md +197 -197
- package/template/.claude/agents/02-typescript/esm-resolver.md +193 -193
- package/template/.claude/agents/02-typescript/import-alias-enforcer.md +158 -158
- package/template/.claude/agents/02-typescript/ts-generics-helper.md +183 -183
- package/template/.claude/agents/02-typescript/ts-migration-helper.md +238 -238
- package/template/.claude/agents/02-typescript/ts-strict-checker.md +180 -180
- package/template/.claude/agents/02-typescript/ts-types-analyzer.md +199 -199
- package/template/.claude/agents/02-typescript/type-definition-writer.md +187 -187
- package/template/.claude/agents/02-typescript/zod-schema-designer.md +212 -212
- package/template/.claude/agents/02-typescript/zod-validator.md +158 -158
- package/template/.claude/agents/03-testing/playwright-assertions.md +265 -265
- package/template/.claude/agents/03-testing/playwright-e2e.md +247 -247
- package/template/.claude/agents/03-testing/playwright-fixtures.md +234 -234
- package/template/.claude/agents/03-testing/playwright-multi-viewport.md +256 -256
- package/template/.claude/agents/03-testing/playwright-page-objects.md +247 -247
- package/template/.claude/agents/03-testing/test-cleanup-manager.md +248 -248
- package/template/.claude/agents/03-testing/test-data-generator.md +254 -254
- package/template/.claude/agents/03-testing/tester-integration.md +278 -278
- package/template/.claude/agents/03-testing/tester-unit.md +207 -207
- package/template/.claude/agents/03-testing/vitest-config.md +287 -287
- package/template/.claude/agents/04-docker/container-health.md +255 -255
- package/template/.claude/agents/04-docker/deployment-validator.md +225 -225
- package/template/.claude/agents/04-docker/docker-compose-designer.md +281 -281
- package/template/.claude/agents/04-docker/docker-env-manager.md +235 -235
- package/template/.claude/agents/04-docker/docker-multi-stage.md +241 -241
- package/template/.claude/agents/04-docker/dockerfile-optimizer.md +208 -208
- package/template/.claude/agents/05-database/database-seeder.md +273 -273
- package/template/.claude/agents/05-database/mongodb-query-optimizer.md +230 -230
- package/template/.claude/agents/05-database/mongoose-aggregation.md +306 -306
- package/template/.claude/agents/05-database/mongoose-index-optimizer.md +182 -182
- package/template/.claude/agents/05-database/mongoose-schema-designer.md +267 -267
- package/template/.claude/agents/06-security/auth-session-validator.md +68 -68
- package/template/.claude/agents/06-security/input-sanitizer.md +80 -80
- package/template/.claude/agents/06-security/owasp-checker.md +97 -97
- package/template/.claude/agents/06-security/permission-auditor.md +100 -100
- package/template/.claude/agents/06-security/security-auditor.md +84 -84
- package/template/.claude/agents/06-security/sensitive-data-scanner.md +83 -83
- package/template/.claude/agents/07-documentation/api-documenter.md +136 -136
- package/template/.claude/agents/07-documentation/changelog-manager.md +105 -105
- package/template/.claude/agents/07-documentation/documenter.md +76 -76
- package/template/.claude/agents/07-documentation/domain-updater.md +81 -81
- package/template/.claude/agents/07-documentation/jsdoc-generator.md +114 -114
- package/template/.claude/agents/07-documentation/readme-generator.md +135 -135
- package/template/.claude/agents/08-git/branch-manager.md +58 -58
- package/template/.claude/agents/08-git/commit-manager.md +63 -63
- package/template/.claude/agents/08-git/pr-creator.md +76 -76
- package/template/.claude/agents/09-quality/code-reviewer.md +71 -71
- package/template/.claude/agents/09-quality/quality-checker.md +67 -67
- package/template/.claude/agents/10-research/best-practices-finder.md +89 -89
- package/template/.claude/agents/10-research/competitor-analyzer.md +106 -106
- package/template/.claude/agents/10-research/pattern-researcher.md +93 -93
- package/template/.claude/agents/10-research/research-cache-manager.md +76 -76
- package/template/.claude/agents/10-research/research-web.md +98 -98
- package/template/.claude/agents/10-research/tech-evaluator.md +101 -101
- package/template/.claude/agents/11-ui-ux/accessibility-auditor.md +136 -136
- package/template/.claude/agents/11-ui-ux/design-system-enforcer.md +125 -125
- package/template/.claude/agents/11-ui-ux/skeleton-generator.md +118 -118
- package/template/.claude/agents/11-ui-ux/ui-desktop.md +132 -132
- package/template/.claude/agents/11-ui-ux/ui-mobile.md +98 -98
- package/template/.claude/agents/11-ui-ux/ui-tablet.md +110 -110
- package/template/.claude/agents/12-performance/api-latency-analyzer.md +156 -156
- package/template/.claude/agents/12-performance/bundle-analyzer.md +113 -113
- package/template/.claude/agents/12-performance/memory-leak-detector.md +137 -137
- package/template/.claude/agents/12-performance/performance-profiler.md +115 -115
- package/template/.claude/agents/12-performance/query-optimizer.md +124 -124
- package/template/.claude/agents/12-performance/render-optimizer.md +154 -154
- package/template/.claude/agents/13-debugging/build-error-fixer.md +207 -207
- package/template/.claude/agents/13-debugging/debugger.md +149 -149
- package/template/.claude/agents/13-debugging/error-stack-analyzer.md +141 -141
- package/template/.claude/agents/13-debugging/network-debugger.md +208 -208
- package/template/.claude/agents/13-debugging/runtime-error-fixer.md +181 -181
- package/template/.claude/agents/13-debugging/type-error-resolver.md +185 -185
- package/template/.claude/agents/14-validation/final-validator.md +93 -93
- package/template/.claude/agents/_backup/analyzer.md +134 -134
- package/template/.claude/agents/_backup/code-reviewer.md +279 -279
- package/template/.claude/agents/_backup/commit-manager.md +219 -219
- package/template/.claude/agents/_backup/debugger.md +280 -280
- package/template/.claude/agents/_backup/documenter.md +237 -237
- package/template/.claude/agents/_backup/domain-updater.md +197 -197
- package/template/.claude/agents/_backup/final-validator.md +169 -169
- package/template/.claude/agents/_backup/orchestrator.md +149 -149
- package/template/.claude/agents/_backup/performance.md +232 -232
- package/template/.claude/agents/_backup/quality-checker.md +240 -240
- package/template/.claude/agents/_backup/research.md +315 -315
- package/template/.claude/agents/_backup/security-auditor.md +192 -192
- package/template/.claude/agents/_backup/tester.md +566 -566
- package/template/.claude/agents/_backup/ui-ux-reviewer.md +247 -247
- package/template/.claude/config/README.md +30 -30
- package/template/.claude/config/mcp-config.json +344 -344
- package/template/.claude/config/project-config.json +53 -53
- package/template/.claude/config/quality-gates.json +46 -46
- package/template/.claude/config/security-rules.json +45 -45
- package/template/.claude/config/testing-config.json +164 -164
- package/template/.claude/hooks/SETUP.md +126 -126
- package/template/.claude/hooks/run-hook.ts +176 -176
- package/template/.claude/hooks/stop-validator.ts +914 -824
- package/template/.claude/hooks/user-prompt-submit.ts +886 -886
- package/template/.claude/scripts/mcp-quick-install.ts +151 -151
- package/template/.claude/scripts/setup-mcps.ts +651 -651
- package/template/.claude/settings.json +275 -275
- package/template/.claude/skills/bun-runtime/SKILL.md +430 -430
- package/template/.claude/skills/codebase-knowledge/domains/claude-system.md +431 -431
- package/template/.claude/skills/codebase-knowledge/domains/mcp-integration.md +295 -295
- package/template/.claude/skills/debugging-patterns/SKILL.md +485 -485
- package/template/.claude/skills/docker-patterns/SKILL.md +555 -555
- package/template/.claude/skills/git-workflow/SKILL.md +454 -454
- package/template/.claude/skills/mongoose-patterns/SKILL.md +499 -499
- package/template/.claude/skills/nextjs-app-router/SKILL.md +327 -327
- package/template/.claude/skills/performance-patterns/SKILL.md +547 -547
- package/template/.claude/skills/playwright-automation/SKILL.md +438 -438
- package/template/.claude/skills/react-patterns/SKILL.md +389 -389
- package/template/.claude/skills/research-cache/SKILL.md +222 -222
- package/template/.claude/skills/shadcn-ui/SKILL.md +511 -511
- package/template/.claude/skills/tailwind-patterns/SKILL.md +465 -465
- package/template/.claude/skills/test-coverage/SKILL.md +467 -467
- package/template/.claude/skills/trpc-api/SKILL.md +434 -434
- package/template/.claude/skills/typescript-strict/SKILL.md +367 -367
- package/template/.claude/skills/zod-validation/SKILL.md +403 -403
- package/template/CLAUDE.md +117 -117
|
@@ -1,254 +1,254 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: test-data-generator
|
|
3
|
-
description: 'AUTOMATICALLY invoke BEFORE writing tests that need data. Triggers: new tests created, mock data needed, factory pattern. Generates realistic test data and fixtures. PROACTIVELY creates data factories.'
|
|
4
|
-
model: haiku
|
|
5
|
-
tools: Read, Write, Edit, Grep, Glob
|
|
6
|
-
skills: test-coverage
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Test Data Generator Agent
|
|
10
|
-
|
|
11
|
-
You generate realistic test data and factories for testing.
|
|
12
|
-
|
|
13
|
-
## Data Factory Pattern
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
// tests/factories/user.factory.ts
|
|
17
|
-
import { ObjectId } from 'mongodb';
|
|
18
|
-
|
|
19
|
-
interface User {
|
|
20
|
-
_id: ObjectId;
|
|
21
|
-
email: string;
|
|
22
|
-
name: string;
|
|
23
|
-
role: 'admin' | 'user' | 'viewer';
|
|
24
|
-
createdAt: Date;
|
|
25
|
-
updatedAt: Date;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
type UserOverrides = Partial<Omit<User, '_id'>>;
|
|
29
|
-
|
|
30
|
-
let counter = 0;
|
|
31
|
-
|
|
32
|
-
export function createUser(overrides: UserOverrides = {}): User {
|
|
33
|
-
counter++;
|
|
34
|
-
const now = new Date();
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
_id: new ObjectId(),
|
|
38
|
-
email: `user${counter}_${Date.now()}@test.com`,
|
|
39
|
-
name: `Test User ${counter}`,
|
|
40
|
-
role: 'user',
|
|
41
|
-
createdAt: now,
|
|
42
|
-
updatedAt: now,
|
|
43
|
-
...overrides,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function createAdmin(overrides: UserOverrides = {}): User {
|
|
48
|
-
return createUser({ role: 'admin', ...overrides });
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function createUsers(count: number, overrides: UserOverrides = {}): User[] {
|
|
52
|
-
return Array.from({ length: count }, () => createUser(overrides));
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## Factory Index
|
|
57
|
-
|
|
58
|
-
```typescript
|
|
59
|
-
// tests/factories/index.ts
|
|
60
|
-
export * from './user.factory';
|
|
61
|
-
export * from './product.factory';
|
|
62
|
-
export * from './order.factory';
|
|
63
|
-
|
|
64
|
-
// Convenience function for unique identifiers
|
|
65
|
-
export function uniqueId(prefix = 'test'): string {
|
|
66
|
-
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export function uniqueEmail(prefix = 'user'): string {
|
|
70
|
-
return `${prefix}_${Date.now()}@test.com`;
|
|
71
|
-
}
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
## Complex Data Factories
|
|
75
|
-
|
|
76
|
-
```typescript
|
|
77
|
-
// tests/factories/order.factory.ts
|
|
78
|
-
import { ObjectId } from 'mongodb';
|
|
79
|
-
import { createUser } from './user.factory';
|
|
80
|
-
import { createProduct } from './product.factory';
|
|
81
|
-
|
|
82
|
-
interface OrderItem {
|
|
83
|
-
productId: ObjectId;
|
|
84
|
-
quantity: number;
|
|
85
|
-
price: number;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
interface Order {
|
|
89
|
-
_id: ObjectId;
|
|
90
|
-
userId: ObjectId;
|
|
91
|
-
items: OrderItem[];
|
|
92
|
-
total: number;
|
|
93
|
-
status: 'pending' | 'paid' | 'shipped' | 'delivered';
|
|
94
|
-
createdAt: Date;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export function createOrderItem(overrides = {}): OrderItem {
|
|
98
|
-
const product = createProduct();
|
|
99
|
-
return {
|
|
100
|
-
productId: product._id,
|
|
101
|
-
quantity: 1,
|
|
102
|
-
price: product.price,
|
|
103
|
-
...overrides,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function createOrder(overrides: Partial<Order> = {}): Order {
|
|
108
|
-
const user = createUser();
|
|
109
|
-
const items = overrides.items || [createOrderItem(), createOrderItem()];
|
|
110
|
-
const total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
_id: new ObjectId(),
|
|
114
|
-
userId: user._id,
|
|
115
|
-
items,
|
|
116
|
-
total,
|
|
117
|
-
status: 'pending',
|
|
118
|
-
createdAt: new Date(),
|
|
119
|
-
...overrides,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Faker Integration
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
// tests/factories/utils.ts
|
|
128
|
-
// Simple random data generators (no external deps)
|
|
129
|
-
|
|
130
|
-
export const random = {
|
|
131
|
-
email: () => `user_${Date.now()}_${Math.random().toString(36).slice(2)}@test.com`,
|
|
132
|
-
|
|
133
|
-
name: () => {
|
|
134
|
-
const firstNames = ['John', 'Jane', 'Bob', 'Alice', 'Charlie'];
|
|
135
|
-
const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones'];
|
|
136
|
-
return `${firstNames[Math.floor(Math.random() * firstNames.length)]} ${
|
|
137
|
-
lastNames[Math.floor(Math.random() * lastNames.length)]
|
|
138
|
-
}`;
|
|
139
|
-
},
|
|
140
|
-
|
|
141
|
-
phone: () => `+1${Math.floor(Math.random() * 9000000000 + 1000000000)}`,
|
|
142
|
-
|
|
143
|
-
uuid: () => crypto.randomUUID(),
|
|
144
|
-
|
|
145
|
-
number: (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min,
|
|
146
|
-
|
|
147
|
-
boolean: () => Math.random() > 0.5,
|
|
148
|
-
|
|
149
|
-
date: (start: Date, end: Date) =>
|
|
150
|
-
new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())),
|
|
151
|
-
|
|
152
|
-
pick: <T>(array: T[]) => array[Math.floor(Math.random() * array.length)],
|
|
153
|
-
};
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
## Database Seeding
|
|
157
|
-
|
|
158
|
-
```typescript
|
|
159
|
-
// tests/helpers/seed.ts
|
|
160
|
-
import { Db } from 'mongodb';
|
|
161
|
-
import { createUsers, createProducts, createOrders } from '../factories';
|
|
162
|
-
|
|
163
|
-
export async function seedDatabase(db: Db) {
|
|
164
|
-
// Create base users
|
|
165
|
-
const users = createUsers(10);
|
|
166
|
-
await db.collection('users').insertMany(users);
|
|
167
|
-
|
|
168
|
-
// Create products
|
|
169
|
-
const products = Array.from({ length: 20 }, () => createProduct());
|
|
170
|
-
await db.collection('products').insertMany(products);
|
|
171
|
-
|
|
172
|
-
// Create orders for some users
|
|
173
|
-
const orders = users.slice(0, 5).map((user) => createOrder({ userId: user._id }));
|
|
174
|
-
await db.collection('orders').insertMany(orders);
|
|
175
|
-
|
|
176
|
-
return { users, products, orders };
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
export async function seedTestUser(db: Db, role: 'admin' | 'user' = 'user') {
|
|
180
|
-
const user = createUser({ role });
|
|
181
|
-
await db.collection('users').insertOne(user);
|
|
182
|
-
return user;
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
## Test Data Helpers
|
|
187
|
-
|
|
188
|
-
```typescript
|
|
189
|
-
// tests/helpers/data.ts
|
|
190
|
-
|
|
191
|
-
// Unique identifiers that won't collide
|
|
192
|
-
export function testEmail(prefix = 'test') {
|
|
193
|
-
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}@test.com`;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
export function testId(prefix = 'id') {
|
|
197
|
-
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
// Valid test data
|
|
201
|
-
export const validPasswords = ['Password123!', 'StrongP@ss1', 'MySecure#Pass2'];
|
|
202
|
-
|
|
203
|
-
export const invalidEmails = ['notanemail', '@missing-local.com', 'missing@.com', 'missing@domain'];
|
|
204
|
-
|
|
205
|
-
// Form data builders
|
|
206
|
-
export function buildRegisterData(overrides = {}) {
|
|
207
|
-
return {
|
|
208
|
-
email: testEmail(),
|
|
209
|
-
password: 'Password123!',
|
|
210
|
-
name: 'Test User',
|
|
211
|
-
...overrides,
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
export function buildLoginData(overrides = {}) {
|
|
216
|
-
return {
|
|
217
|
-
email: testEmail(),
|
|
218
|
-
password: 'Password123!',
|
|
219
|
-
...overrides,
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## Usage in Tests
|
|
225
|
-
|
|
226
|
-
```typescript
|
|
227
|
-
import { test, expect } from '../fixtures';
|
|
228
|
-
import { createUser, testEmail, buildRegisterData } from '../factories';
|
|
229
|
-
|
|
230
|
-
test('should register new user', async ({ page, db, trackCreated }) => {
|
|
231
|
-
const userData = buildRegisterData();
|
|
232
|
-
|
|
233
|
-
await page.goto('/register');
|
|
234
|
-
await page.getByTestId('email').fill(userData.email);
|
|
235
|
-
await page.getByTestId('password').fill(userData.password);
|
|
236
|
-
await page.getByTestId('name').fill(userData.name);
|
|
237
|
-
await page.getByRole('button', { name: 'Register' }).click();
|
|
238
|
-
|
|
239
|
-
await expect(page).toHaveURL('/dashboard');
|
|
240
|
-
|
|
241
|
-
// Verify in DB
|
|
242
|
-
const user = await db.collection('users').findOne({ email: userData.email });
|
|
243
|
-
expect(user).toBeTruthy();
|
|
244
|
-
trackCreated('users', user!._id);
|
|
245
|
-
});
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## Critical Rules
|
|
249
|
-
|
|
250
|
-
1. **UNIQUE IDENTIFIERS** - Use timestamps/random in test data
|
|
251
|
-
2. **FACTORY PATTERN** - Consistent data creation
|
|
252
|
-
3. **OVERRIDE SUPPORT** - Allow customizing factory output
|
|
253
|
-
4. **TRACK FOR CLEANUP** - All created data must be trackable
|
|
254
|
-
5. **NO HARDCODED DATA** - Always generate dynamically
|
|
1
|
+
---
|
|
2
|
+
name: test-data-generator
|
|
3
|
+
description: 'AUTOMATICALLY invoke BEFORE writing tests that need data. Triggers: new tests created, mock data needed, factory pattern. Generates realistic test data and fixtures. PROACTIVELY creates data factories.'
|
|
4
|
+
model: haiku
|
|
5
|
+
tools: Read, Write, Edit, Grep, Glob
|
|
6
|
+
skills: test-coverage
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Test Data Generator Agent
|
|
10
|
+
|
|
11
|
+
You generate realistic test data and factories for testing.
|
|
12
|
+
|
|
13
|
+
## Data Factory Pattern
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
// tests/factories/user.factory.ts
|
|
17
|
+
import { ObjectId } from 'mongodb';
|
|
18
|
+
|
|
19
|
+
interface User {
|
|
20
|
+
_id: ObjectId;
|
|
21
|
+
email: string;
|
|
22
|
+
name: string;
|
|
23
|
+
role: 'admin' | 'user' | 'viewer';
|
|
24
|
+
createdAt: Date;
|
|
25
|
+
updatedAt: Date;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type UserOverrides = Partial<Omit<User, '_id'>>;
|
|
29
|
+
|
|
30
|
+
let counter = 0;
|
|
31
|
+
|
|
32
|
+
export function createUser(overrides: UserOverrides = {}): User {
|
|
33
|
+
counter++;
|
|
34
|
+
const now = new Date();
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
_id: new ObjectId(),
|
|
38
|
+
email: `user${counter}_${Date.now()}@test.com`,
|
|
39
|
+
name: `Test User ${counter}`,
|
|
40
|
+
role: 'user',
|
|
41
|
+
createdAt: now,
|
|
42
|
+
updatedAt: now,
|
|
43
|
+
...overrides,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function createAdmin(overrides: UserOverrides = {}): User {
|
|
48
|
+
return createUser({ role: 'admin', ...overrides });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function createUsers(count: number, overrides: UserOverrides = {}): User[] {
|
|
52
|
+
return Array.from({ length: count }, () => createUser(overrides));
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Factory Index
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
// tests/factories/index.ts
|
|
60
|
+
export * from './user.factory';
|
|
61
|
+
export * from './product.factory';
|
|
62
|
+
export * from './order.factory';
|
|
63
|
+
|
|
64
|
+
// Convenience function for unique identifiers
|
|
65
|
+
export function uniqueId(prefix = 'test'): string {
|
|
66
|
+
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function uniqueEmail(prefix = 'user'): string {
|
|
70
|
+
return `${prefix}_${Date.now()}@test.com`;
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Complex Data Factories
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
// tests/factories/order.factory.ts
|
|
78
|
+
import { ObjectId } from 'mongodb';
|
|
79
|
+
import { createUser } from './user.factory';
|
|
80
|
+
import { createProduct } from './product.factory';
|
|
81
|
+
|
|
82
|
+
interface OrderItem {
|
|
83
|
+
productId: ObjectId;
|
|
84
|
+
quantity: number;
|
|
85
|
+
price: number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
interface Order {
|
|
89
|
+
_id: ObjectId;
|
|
90
|
+
userId: ObjectId;
|
|
91
|
+
items: OrderItem[];
|
|
92
|
+
total: number;
|
|
93
|
+
status: 'pending' | 'paid' | 'shipped' | 'delivered';
|
|
94
|
+
createdAt: Date;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function createOrderItem(overrides = {}): OrderItem {
|
|
98
|
+
const product = createProduct();
|
|
99
|
+
return {
|
|
100
|
+
productId: product._id,
|
|
101
|
+
quantity: 1,
|
|
102
|
+
price: product.price,
|
|
103
|
+
...overrides,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function createOrder(overrides: Partial<Order> = {}): Order {
|
|
108
|
+
const user = createUser();
|
|
109
|
+
const items = overrides.items || [createOrderItem(), createOrderItem()];
|
|
110
|
+
const total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
_id: new ObjectId(),
|
|
114
|
+
userId: user._id,
|
|
115
|
+
items,
|
|
116
|
+
total,
|
|
117
|
+
status: 'pending',
|
|
118
|
+
createdAt: new Date(),
|
|
119
|
+
...overrides,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Faker Integration
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// tests/factories/utils.ts
|
|
128
|
+
// Simple random data generators (no external deps)
|
|
129
|
+
|
|
130
|
+
export const random = {
|
|
131
|
+
email: () => `user_${Date.now()}_${Math.random().toString(36).slice(2)}@test.com`,
|
|
132
|
+
|
|
133
|
+
name: () => {
|
|
134
|
+
const firstNames = ['John', 'Jane', 'Bob', 'Alice', 'Charlie'];
|
|
135
|
+
const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones'];
|
|
136
|
+
return `${firstNames[Math.floor(Math.random() * firstNames.length)]} ${
|
|
137
|
+
lastNames[Math.floor(Math.random() * lastNames.length)]
|
|
138
|
+
}`;
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
phone: () => `+1${Math.floor(Math.random() * 9000000000 + 1000000000)}`,
|
|
142
|
+
|
|
143
|
+
uuid: () => crypto.randomUUID(),
|
|
144
|
+
|
|
145
|
+
number: (min: number, max: number) => Math.floor(Math.random() * (max - min + 1)) + min,
|
|
146
|
+
|
|
147
|
+
boolean: () => Math.random() > 0.5,
|
|
148
|
+
|
|
149
|
+
date: (start: Date, end: Date) =>
|
|
150
|
+
new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime())),
|
|
151
|
+
|
|
152
|
+
pick: <T>(array: T[]) => array[Math.floor(Math.random() * array.length)],
|
|
153
|
+
};
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Database Seeding
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// tests/helpers/seed.ts
|
|
160
|
+
import { Db } from 'mongodb';
|
|
161
|
+
import { createUsers, createProducts, createOrders } from '../factories';
|
|
162
|
+
|
|
163
|
+
export async function seedDatabase(db: Db) {
|
|
164
|
+
// Create base users
|
|
165
|
+
const users = createUsers(10);
|
|
166
|
+
await db.collection('users').insertMany(users);
|
|
167
|
+
|
|
168
|
+
// Create products
|
|
169
|
+
const products = Array.from({ length: 20 }, () => createProduct());
|
|
170
|
+
await db.collection('products').insertMany(products);
|
|
171
|
+
|
|
172
|
+
// Create orders for some users
|
|
173
|
+
const orders = users.slice(0, 5).map((user) => createOrder({ userId: user._id }));
|
|
174
|
+
await db.collection('orders').insertMany(orders);
|
|
175
|
+
|
|
176
|
+
return { users, products, orders };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function seedTestUser(db: Db, role: 'admin' | 'user' = 'user') {
|
|
180
|
+
const user = createUser({ role });
|
|
181
|
+
await db.collection('users').insertOne(user);
|
|
182
|
+
return user;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Test Data Helpers
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
// tests/helpers/data.ts
|
|
190
|
+
|
|
191
|
+
// Unique identifiers that won't collide
|
|
192
|
+
export function testEmail(prefix = 'test') {
|
|
193
|
+
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}@test.com`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export function testId(prefix = 'id') {
|
|
197
|
+
return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Valid test data
|
|
201
|
+
export const validPasswords = ['Password123!', 'StrongP@ss1', 'MySecure#Pass2'];
|
|
202
|
+
|
|
203
|
+
export const invalidEmails = ['notanemail', '@missing-local.com', 'missing@.com', 'missing@domain'];
|
|
204
|
+
|
|
205
|
+
// Form data builders
|
|
206
|
+
export function buildRegisterData(overrides = {}) {
|
|
207
|
+
return {
|
|
208
|
+
email: testEmail(),
|
|
209
|
+
password: 'Password123!',
|
|
210
|
+
name: 'Test User',
|
|
211
|
+
...overrides,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function buildLoginData(overrides = {}) {
|
|
216
|
+
return {
|
|
217
|
+
email: testEmail(),
|
|
218
|
+
password: 'Password123!',
|
|
219
|
+
...overrides,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Usage in Tests
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
import { test, expect } from '../fixtures';
|
|
228
|
+
import { createUser, testEmail, buildRegisterData } from '../factories';
|
|
229
|
+
|
|
230
|
+
test('should register new user', async ({ page, db, trackCreated }) => {
|
|
231
|
+
const userData = buildRegisterData();
|
|
232
|
+
|
|
233
|
+
await page.goto('/register');
|
|
234
|
+
await page.getByTestId('email').fill(userData.email);
|
|
235
|
+
await page.getByTestId('password').fill(userData.password);
|
|
236
|
+
await page.getByTestId('name').fill(userData.name);
|
|
237
|
+
await page.getByRole('button', { name: 'Register' }).click();
|
|
238
|
+
|
|
239
|
+
await expect(page).toHaveURL('/dashboard');
|
|
240
|
+
|
|
241
|
+
// Verify in DB
|
|
242
|
+
const user = await db.collection('users').findOne({ email: userData.email });
|
|
243
|
+
expect(user).toBeTruthy();
|
|
244
|
+
trackCreated('users', user!._id);
|
|
245
|
+
});
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Critical Rules
|
|
249
|
+
|
|
250
|
+
1. **UNIQUE IDENTIFIERS** - Use timestamps/random in test data
|
|
251
|
+
2. **FACTORY PATTERN** - Consistent data creation
|
|
252
|
+
3. **OVERRIDE SUPPORT** - Allow customizing factory output
|
|
253
|
+
4. **TRACK FOR CLEANUP** - All created data must be trackable
|
|
254
|
+
5. **NO HARDCODED DATA** - Always generate dynamically
|