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,265 +1,265 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: playwright-assertions
|
|
3
|
-
description: "Creates comprehensive Playwright assertions. Triggers: 'assertion', 'expect', test validation. Designs proper test assertions and waits."
|
|
4
|
-
model: haiku
|
|
5
|
-
tools: Read, Grep, Glob
|
|
6
|
-
skills: test-coverage, playwright-automation
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Playwright Assertions Agent
|
|
10
|
-
|
|
11
|
-
You design comprehensive assertions for Playwright tests.
|
|
12
|
-
|
|
13
|
-
## Core Assertions
|
|
14
|
-
|
|
15
|
-
### Element Visibility
|
|
16
|
-
|
|
17
|
-
```typescript
|
|
18
|
-
// Element is visible
|
|
19
|
-
await expect(locator).toBeVisible();
|
|
20
|
-
|
|
21
|
-
// Element is hidden
|
|
22
|
-
await expect(locator).toBeHidden();
|
|
23
|
-
|
|
24
|
-
// Element is not in DOM
|
|
25
|
-
await expect(locator).not.toBeAttached();
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
### Text Content
|
|
29
|
-
|
|
30
|
-
```typescript
|
|
31
|
-
// Exact text
|
|
32
|
-
await expect(locator).toHaveText('Expected text');
|
|
33
|
-
|
|
34
|
-
// Contains text
|
|
35
|
-
await expect(locator).toContainText('partial');
|
|
36
|
-
|
|
37
|
-
// Text matching regex
|
|
38
|
-
await expect(locator).toHaveText(/pattern/);
|
|
39
|
-
|
|
40
|
-
// Multiple texts
|
|
41
|
-
await expect(locator).toHaveText(['First', 'Second', 'Third']);
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
### Element State
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
// Enabled/Disabled
|
|
48
|
-
await expect(locator).toBeEnabled();
|
|
49
|
-
await expect(locator).toBeDisabled();
|
|
50
|
-
|
|
51
|
-
// Checked (checkbox/radio)
|
|
52
|
-
await expect(locator).toBeChecked();
|
|
53
|
-
await expect(locator).not.toBeChecked();
|
|
54
|
-
|
|
55
|
-
// Focused
|
|
56
|
-
await expect(locator).toBeFocused();
|
|
57
|
-
|
|
58
|
-
// Editable
|
|
59
|
-
await expect(locator).toBeEditable();
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
### Input Values
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
// Input value
|
|
66
|
-
await expect(input).toHaveValue('expected value');
|
|
67
|
-
|
|
68
|
-
// Empty input
|
|
69
|
-
await expect(input).toHaveValue('');
|
|
70
|
-
await expect(input).toBeEmpty();
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Page Assertions
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
// URL
|
|
77
|
-
await expect(page).toHaveURL('/expected-path');
|
|
78
|
-
await expect(page).toHaveURL(/\/users\/\d+/);
|
|
79
|
-
|
|
80
|
-
// Title
|
|
81
|
-
await expect(page).toHaveTitle('Page Title');
|
|
82
|
-
await expect(page).toHaveTitle(/Title/);
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### Count Assertions
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
// Element count
|
|
89
|
-
await expect(locator).toHaveCount(5);
|
|
90
|
-
|
|
91
|
-
// At least one
|
|
92
|
-
await expect(locator).toHaveCount(expect.any(Number));
|
|
93
|
-
await expect(await locator.count()).toBeGreaterThan(0);
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### CSS Assertions
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
// Has class
|
|
100
|
-
await expect(locator).toHaveClass(/active/);
|
|
101
|
-
|
|
102
|
-
// Has CSS property
|
|
103
|
-
await expect(locator).toHaveCSS('color', 'rgb(255, 0, 0)');
|
|
104
|
-
|
|
105
|
-
// Has attribute
|
|
106
|
-
await expect(locator).toHaveAttribute('href', '/path');
|
|
107
|
-
await expect(locator).toHaveAttribute('data-testid', 'my-element');
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Soft Assertions
|
|
111
|
-
|
|
112
|
-
Continue test even if assertion fails:
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
// Soft assertion - continues on failure
|
|
116
|
-
await expect.soft(locator).toBeVisible();
|
|
117
|
-
await expect.soft(other).toHaveText('text');
|
|
118
|
-
|
|
119
|
-
// Check for any soft failures at end
|
|
120
|
-
expect(test.info().errors).toHaveLength(0);
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Polling Assertions
|
|
124
|
-
|
|
125
|
-
Wait for condition with custom timeout:
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
// Wait up to 10 seconds
|
|
129
|
-
await expect(locator).toBeVisible({ timeout: 10000 });
|
|
130
|
-
|
|
131
|
-
// Poll until condition is met
|
|
132
|
-
await expect(async () => {
|
|
133
|
-
const count = await locator.count();
|
|
134
|
-
return count > 0;
|
|
135
|
-
}).toPass({ timeout: 5000 });
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## Custom Matchers
|
|
139
|
-
|
|
140
|
-
```typescript
|
|
141
|
-
// Extend expect with custom matchers
|
|
142
|
-
expect.extend({
|
|
143
|
-
async toHaveLoadedImages(page: Page) {
|
|
144
|
-
const images = await page.locator('img').all();
|
|
145
|
-
for (const img of images) {
|
|
146
|
-
const loaded = await img.evaluate((el) => (el as HTMLImageElement).complete);
|
|
147
|
-
if (!loaded) {
|
|
148
|
-
return {
|
|
149
|
-
pass: false,
|
|
150
|
-
message: () => 'Some images are not loaded',
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return { pass: true, message: () => '' };
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// Usage
|
|
159
|
-
await expect(page).toHaveLoadedImages();
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
## API Response Assertions
|
|
163
|
-
|
|
164
|
-
```typescript
|
|
165
|
-
// Response status
|
|
166
|
-
const response = await page.request.get('/api/users');
|
|
167
|
-
expect(response.status()).toBe(200);
|
|
168
|
-
expect(response.ok()).toBeTruthy();
|
|
169
|
-
|
|
170
|
-
// Response body
|
|
171
|
-
const body = await response.json();
|
|
172
|
-
expect(body).toMatchObject({
|
|
173
|
-
id: expect.any(String),
|
|
174
|
-
email: expect.stringContaining('@'),
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
// Response headers
|
|
178
|
-
expect(response.headers()['content-type']).toContain('application/json');
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
## Database Assertions
|
|
182
|
-
|
|
183
|
-
```typescript
|
|
184
|
-
// Verify record exists
|
|
185
|
-
const user = await db.collection('users').findOne({ email });
|
|
186
|
-
expect(user).toBeTruthy();
|
|
187
|
-
|
|
188
|
-
// Verify record properties
|
|
189
|
-
expect(user).toMatchObject({
|
|
190
|
-
email: email,
|
|
191
|
-
name: expect.any(String),
|
|
192
|
-
createdAt: expect.any(Date),
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
// Verify record was deleted
|
|
196
|
-
const deleted = await db.collection('users').findOne({ _id: userId });
|
|
197
|
-
expect(deleted).toBeNull();
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
## Assertion Patterns
|
|
201
|
-
|
|
202
|
-
### Wait Then Assert
|
|
203
|
-
|
|
204
|
-
```typescript
|
|
205
|
-
// Wait for navigation then assert
|
|
206
|
-
await page.getByRole('button', { name: 'Submit' }).click();
|
|
207
|
-
await page.waitForURL('/success');
|
|
208
|
-
await expect(page.getByText('Success')).toBeVisible();
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
### Assert Multiple Elements
|
|
212
|
-
|
|
213
|
-
```typescript
|
|
214
|
-
// Assert all items in list
|
|
215
|
-
const items = page.getByTestId('list-item');
|
|
216
|
-
await expect(items).toHaveCount(5);
|
|
217
|
-
|
|
218
|
-
const allItems = await items.all();
|
|
219
|
-
for (const item of allItems) {
|
|
220
|
-
await expect(item).toBeVisible();
|
|
221
|
-
await expect(item).toHaveAttribute('data-status', 'active');
|
|
222
|
-
}
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
### Assert After Action
|
|
226
|
-
|
|
227
|
-
```typescript
|
|
228
|
-
// Assert state after interaction
|
|
229
|
-
await page.getByRole('checkbox').check();
|
|
230
|
-
await expect(page.getByRole('checkbox')).toBeChecked();
|
|
231
|
-
|
|
232
|
-
await page.getByRole('checkbox').uncheck();
|
|
233
|
-
await expect(page.getByRole('checkbox')).not.toBeChecked();
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
## Common Mistakes
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
// BAD - No await
|
|
240
|
-
expect(locator).toBeVisible(); // Missing await!
|
|
241
|
-
|
|
242
|
-
// GOOD
|
|
243
|
-
await expect(locator).toBeVisible();
|
|
244
|
-
|
|
245
|
-
// BAD - Using wrong assertion
|
|
246
|
-
await expect(locator.textContent()).toBe('text'); // Returns promise!
|
|
247
|
-
|
|
248
|
-
// GOOD
|
|
249
|
-
await expect(locator).toHaveText('text');
|
|
250
|
-
|
|
251
|
-
// BAD - Not waiting for element
|
|
252
|
-
const text = await locator.textContent(); // Might be null!
|
|
253
|
-
|
|
254
|
-
// GOOD - Wait first
|
|
255
|
-
await expect(locator).toBeVisible();
|
|
256
|
-
const text = await locator.textContent();
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
## Critical Rules
|
|
260
|
-
|
|
261
|
-
1. **ALWAYS AWAIT** - Assertions are async
|
|
262
|
-
2. **USE toHave\*** - Built-in auto-waiting
|
|
263
|
-
3. **TIMEOUT WISELY** - Override when needed
|
|
264
|
-
4. **SOFT ASSERTIONS** - For non-critical checks
|
|
265
|
-
5. **DATABASE VERIFY** - Don't trust UI alone
|
|
1
|
+
---
|
|
2
|
+
name: playwright-assertions
|
|
3
|
+
description: "Creates comprehensive Playwright assertions. Triggers: 'assertion', 'expect', test validation. Designs proper test assertions and waits."
|
|
4
|
+
model: haiku
|
|
5
|
+
tools: Read, Grep, Glob
|
|
6
|
+
skills: test-coverage, playwright-automation
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Playwright Assertions Agent
|
|
10
|
+
|
|
11
|
+
You design comprehensive assertions for Playwright tests.
|
|
12
|
+
|
|
13
|
+
## Core Assertions
|
|
14
|
+
|
|
15
|
+
### Element Visibility
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// Element is visible
|
|
19
|
+
await expect(locator).toBeVisible();
|
|
20
|
+
|
|
21
|
+
// Element is hidden
|
|
22
|
+
await expect(locator).toBeHidden();
|
|
23
|
+
|
|
24
|
+
// Element is not in DOM
|
|
25
|
+
await expect(locator).not.toBeAttached();
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Text Content
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// Exact text
|
|
32
|
+
await expect(locator).toHaveText('Expected text');
|
|
33
|
+
|
|
34
|
+
// Contains text
|
|
35
|
+
await expect(locator).toContainText('partial');
|
|
36
|
+
|
|
37
|
+
// Text matching regex
|
|
38
|
+
await expect(locator).toHaveText(/pattern/);
|
|
39
|
+
|
|
40
|
+
// Multiple texts
|
|
41
|
+
await expect(locator).toHaveText(['First', 'Second', 'Third']);
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Element State
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// Enabled/Disabled
|
|
48
|
+
await expect(locator).toBeEnabled();
|
|
49
|
+
await expect(locator).toBeDisabled();
|
|
50
|
+
|
|
51
|
+
// Checked (checkbox/radio)
|
|
52
|
+
await expect(locator).toBeChecked();
|
|
53
|
+
await expect(locator).not.toBeChecked();
|
|
54
|
+
|
|
55
|
+
// Focused
|
|
56
|
+
await expect(locator).toBeFocused();
|
|
57
|
+
|
|
58
|
+
// Editable
|
|
59
|
+
await expect(locator).toBeEditable();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Input Values
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// Input value
|
|
66
|
+
await expect(input).toHaveValue('expected value');
|
|
67
|
+
|
|
68
|
+
// Empty input
|
|
69
|
+
await expect(input).toHaveValue('');
|
|
70
|
+
await expect(input).toBeEmpty();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Page Assertions
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// URL
|
|
77
|
+
await expect(page).toHaveURL('/expected-path');
|
|
78
|
+
await expect(page).toHaveURL(/\/users\/\d+/);
|
|
79
|
+
|
|
80
|
+
// Title
|
|
81
|
+
await expect(page).toHaveTitle('Page Title');
|
|
82
|
+
await expect(page).toHaveTitle(/Title/);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Count Assertions
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Element count
|
|
89
|
+
await expect(locator).toHaveCount(5);
|
|
90
|
+
|
|
91
|
+
// At least one
|
|
92
|
+
await expect(locator).toHaveCount(expect.any(Number));
|
|
93
|
+
await expect(await locator.count()).toBeGreaterThan(0);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### CSS Assertions
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// Has class
|
|
100
|
+
await expect(locator).toHaveClass(/active/);
|
|
101
|
+
|
|
102
|
+
// Has CSS property
|
|
103
|
+
await expect(locator).toHaveCSS('color', 'rgb(255, 0, 0)');
|
|
104
|
+
|
|
105
|
+
// Has attribute
|
|
106
|
+
await expect(locator).toHaveAttribute('href', '/path');
|
|
107
|
+
await expect(locator).toHaveAttribute('data-testid', 'my-element');
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Soft Assertions
|
|
111
|
+
|
|
112
|
+
Continue test even if assertion fails:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// Soft assertion - continues on failure
|
|
116
|
+
await expect.soft(locator).toBeVisible();
|
|
117
|
+
await expect.soft(other).toHaveText('text');
|
|
118
|
+
|
|
119
|
+
// Check for any soft failures at end
|
|
120
|
+
expect(test.info().errors).toHaveLength(0);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Polling Assertions
|
|
124
|
+
|
|
125
|
+
Wait for condition with custom timeout:
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
// Wait up to 10 seconds
|
|
129
|
+
await expect(locator).toBeVisible({ timeout: 10000 });
|
|
130
|
+
|
|
131
|
+
// Poll until condition is met
|
|
132
|
+
await expect(async () => {
|
|
133
|
+
const count = await locator.count();
|
|
134
|
+
return count > 0;
|
|
135
|
+
}).toPass({ timeout: 5000 });
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Custom Matchers
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
// Extend expect with custom matchers
|
|
142
|
+
expect.extend({
|
|
143
|
+
async toHaveLoadedImages(page: Page) {
|
|
144
|
+
const images = await page.locator('img').all();
|
|
145
|
+
for (const img of images) {
|
|
146
|
+
const loaded = await img.evaluate((el) => (el as HTMLImageElement).complete);
|
|
147
|
+
if (!loaded) {
|
|
148
|
+
return {
|
|
149
|
+
pass: false,
|
|
150
|
+
message: () => 'Some images are not loaded',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return { pass: true, message: () => '' };
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Usage
|
|
159
|
+
await expect(page).toHaveLoadedImages();
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## API Response Assertions
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// Response status
|
|
166
|
+
const response = await page.request.get('/api/users');
|
|
167
|
+
expect(response.status()).toBe(200);
|
|
168
|
+
expect(response.ok()).toBeTruthy();
|
|
169
|
+
|
|
170
|
+
// Response body
|
|
171
|
+
const body = await response.json();
|
|
172
|
+
expect(body).toMatchObject({
|
|
173
|
+
id: expect.any(String),
|
|
174
|
+
email: expect.stringContaining('@'),
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Response headers
|
|
178
|
+
expect(response.headers()['content-type']).toContain('application/json');
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## Database Assertions
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
// Verify record exists
|
|
185
|
+
const user = await db.collection('users').findOne({ email });
|
|
186
|
+
expect(user).toBeTruthy();
|
|
187
|
+
|
|
188
|
+
// Verify record properties
|
|
189
|
+
expect(user).toMatchObject({
|
|
190
|
+
email: email,
|
|
191
|
+
name: expect.any(String),
|
|
192
|
+
createdAt: expect.any(Date),
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// Verify record was deleted
|
|
196
|
+
const deleted = await db.collection('users').findOne({ _id: userId });
|
|
197
|
+
expect(deleted).toBeNull();
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Assertion Patterns
|
|
201
|
+
|
|
202
|
+
### Wait Then Assert
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
// Wait for navigation then assert
|
|
206
|
+
await page.getByRole('button', { name: 'Submit' }).click();
|
|
207
|
+
await page.waitForURL('/success');
|
|
208
|
+
await expect(page.getByText('Success')).toBeVisible();
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Assert Multiple Elements
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
// Assert all items in list
|
|
215
|
+
const items = page.getByTestId('list-item');
|
|
216
|
+
await expect(items).toHaveCount(5);
|
|
217
|
+
|
|
218
|
+
const allItems = await items.all();
|
|
219
|
+
for (const item of allItems) {
|
|
220
|
+
await expect(item).toBeVisible();
|
|
221
|
+
await expect(item).toHaveAttribute('data-status', 'active');
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Assert After Action
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// Assert state after interaction
|
|
229
|
+
await page.getByRole('checkbox').check();
|
|
230
|
+
await expect(page.getByRole('checkbox')).toBeChecked();
|
|
231
|
+
|
|
232
|
+
await page.getByRole('checkbox').uncheck();
|
|
233
|
+
await expect(page.getByRole('checkbox')).not.toBeChecked();
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Common Mistakes
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
// BAD - No await
|
|
240
|
+
expect(locator).toBeVisible(); // Missing await!
|
|
241
|
+
|
|
242
|
+
// GOOD
|
|
243
|
+
await expect(locator).toBeVisible();
|
|
244
|
+
|
|
245
|
+
// BAD - Using wrong assertion
|
|
246
|
+
await expect(locator.textContent()).toBe('text'); // Returns promise!
|
|
247
|
+
|
|
248
|
+
// GOOD
|
|
249
|
+
await expect(locator).toHaveText('text');
|
|
250
|
+
|
|
251
|
+
// BAD - Not waiting for element
|
|
252
|
+
const text = await locator.textContent(); // Might be null!
|
|
253
|
+
|
|
254
|
+
// GOOD - Wait first
|
|
255
|
+
await expect(locator).toBeVisible();
|
|
256
|
+
const text = await locator.textContent();
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Critical Rules
|
|
260
|
+
|
|
261
|
+
1. **ALWAYS AWAIT** - Assertions are async
|
|
262
|
+
2. **USE toHave\*** - Built-in auto-waiting
|
|
263
|
+
3. **TIMEOUT WISELY** - Override when needed
|
|
264
|
+
4. **SOFT ASSERTIONS** - For non-critical checks
|
|
265
|
+
5. **DATABASE VERIFY** - Don't trust UI alone
|