@chankov/agent-skills 0.3.2 → 0.3.3
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/.versions/0.3.3/.claude/commands/build.md +18 -0
- package/.versions/0.3.3/.claude/commands/code-simplify.md +22 -0
- package/.versions/0.3.3/.claude/commands/design-agent.md +14 -0
- package/.versions/0.3.3/.claude/commands/doctor-agent-skills.md +13 -0
- package/.versions/0.3.3/.claude/commands/plan.md +16 -0
- package/.versions/0.3.3/.claude/commands/prime.md +22 -0
- package/.versions/0.3.3/.claude/commands/review.md +16 -0
- package/.versions/0.3.3/.claude/commands/setup-agent-skills.md +19 -0
- package/.versions/0.3.3/.claude/commands/ship.md +17 -0
- package/.versions/0.3.3/.claude/commands/spec.md +15 -0
- package/.versions/0.3.3/.claude/commands/test.md +19 -0
- package/.versions/0.3.3/.opencode/commands/as-build.md +17 -0
- package/.versions/0.3.3/.opencode/commands/as-code-simplify.md +16 -0
- package/.versions/0.3.3/.opencode/commands/as-design-agent.md +15 -0
- package/.versions/0.3.3/.opencode/commands/as-doctor-agent-skills.md +11 -0
- package/.versions/0.3.3/.opencode/commands/as-plan.md +16 -0
- package/.versions/0.3.3/.opencode/commands/as-prime.md +22 -0
- package/.versions/0.3.3/.opencode/commands/as-review.md +15 -0
- package/.versions/0.3.3/.opencode/commands/as-setup-agent-skills.md +11 -0
- package/.versions/0.3.3/.opencode/commands/as-ship.md +16 -0
- package/.versions/0.3.3/.opencode/commands/as-spec.md +16 -0
- package/.versions/0.3.3/.opencode/commands/as-test.md +21 -0
- package/.versions/0.3.3/.pi/agents/agent-chain.yaml +49 -0
- package/.versions/0.3.3/.pi/agents/bowser.md +19 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/agent-expert.md +98 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/cli-expert.md +41 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/config-expert.md +63 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/ext-expert.md +43 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/keybinding-expert.md +134 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/pi-orchestrator.md +57 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/prompt-expert.md +70 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/skill-expert.md +42 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/theme-expert.md +40 -0
- package/.versions/0.3.3/.pi/agents/pi-pi/tui-expert.md +85 -0
- package/.versions/0.3.3/.pi/agents/teams.yaml +31 -0
- package/.versions/0.3.3/.pi/damage-control-rules.yaml +278 -0
- package/.versions/0.3.3/.pi/extensions/agent-skills-update-check/README.md +58 -0
- package/.versions/0.3.3/.pi/extensions/agent-skills-update-check/index.ts +161 -0
- package/.versions/0.3.3/.pi/extensions/agent-skills-update-check/package.json +6 -0
- package/.versions/0.3.3/.pi/extensions/chrome-devtools-mcp/README.md +39 -0
- package/.versions/0.3.3/.pi/extensions/chrome-devtools-mcp/index.ts +61 -0
- package/.versions/0.3.3/.pi/extensions/chrome-devtools-mcp/package.json +6 -0
- package/.versions/0.3.3/.pi/extensions/compact-and-continue/README.md +42 -0
- package/.versions/0.3.3/.pi/extensions/compact-and-continue/index.ts +120 -0
- package/.versions/0.3.3/.pi/extensions/compact-and-continue/package.json +6 -0
- package/.versions/0.3.3/.pi/extensions/mcp-bridge/README.md +46 -0
- package/.versions/0.3.3/.pi/extensions/mcp-bridge/index.ts +206 -0
- package/.versions/0.3.3/.pi/extensions/mcp-bridge/package.json +6 -0
- package/.versions/0.3.3/.pi/extensions/package-lock.json +1143 -0
- package/.versions/0.3.3/.pi/extensions/package.json +9 -0
- package/.versions/0.3.3/.pi/harnesses/agent-chain/README.md +37 -0
- package/.versions/0.3.3/.pi/harnesses/agent-chain/index.ts +795 -0
- package/.versions/0.3.3/.pi/harnesses/agent-chain/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/agent-team/README.md +38 -0
- package/.versions/0.3.3/.pi/harnesses/agent-team/index.ts +732 -0
- package/.versions/0.3.3/.pi/harnesses/agent-team/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/coms/README.md +36 -0
- package/.versions/0.3.3/.pi/harnesses/coms/index.ts +1595 -0
- package/.versions/0.3.3/.pi/harnesses/coms/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/coms-net/README.md +46 -0
- package/.versions/0.3.3/.pi/harnesses/coms-net/index.ts +1637 -0
- package/.versions/0.3.3/.pi/harnesses/coms-net/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/damage-control/README.md +38 -0
- package/.versions/0.3.3/.pi/harnesses/damage-control/index.ts +207 -0
- package/.versions/0.3.3/.pi/harnesses/damage-control/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/damage-control-continue/README.md +37 -0
- package/.versions/0.3.3/.pi/harnesses/damage-control-continue/index.ts +234 -0
- package/.versions/0.3.3/.pi/harnesses/damage-control-continue/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/minimal/README.md +27 -0
- package/.versions/0.3.3/.pi/harnesses/minimal/index.ts +32 -0
- package/.versions/0.3.3/.pi/harnesses/minimal/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/package-lock.json +35 -0
- package/.versions/0.3.3/.pi/harnesses/package.json +9 -0
- package/.versions/0.3.3/.pi/harnesses/pi-pi/README.md +39 -0
- package/.versions/0.3.3/.pi/harnesses/pi-pi/index.ts +631 -0
- package/.versions/0.3.3/.pi/harnesses/pi-pi/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/purpose-gate/README.md +27 -0
- package/.versions/0.3.3/.pi/harnesses/purpose-gate/index.ts +82 -0
- package/.versions/0.3.3/.pi/harnesses/purpose-gate/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/session-replay/README.md +28 -0
- package/.versions/0.3.3/.pi/harnesses/session-replay/index.ts +214 -0
- package/.versions/0.3.3/.pi/harnesses/session-replay/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/subagent-widget/README.md +36 -0
- package/.versions/0.3.3/.pi/harnesses/subagent-widget/index.ts +479 -0
- package/.versions/0.3.3/.pi/harnesses/subagent-widget/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/system-select/README.md +39 -0
- package/.versions/0.3.3/.pi/harnesses/system-select/index.ts +165 -0
- package/.versions/0.3.3/.pi/harnesses/system-select/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/tilldone/README.md +35 -0
- package/.versions/0.3.3/.pi/harnesses/tilldone/index.ts +724 -0
- package/.versions/0.3.3/.pi/harnesses/tilldone/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/tool-counter/README.md +31 -0
- package/.versions/0.3.3/.pi/harnesses/tool-counter/index.ts +100 -0
- package/.versions/0.3.3/.pi/harnesses/tool-counter/package.json +6 -0
- package/.versions/0.3.3/.pi/harnesses/tool-counter-widget/README.md +27 -0
- package/.versions/0.3.3/.pi/harnesses/tool-counter-widget/index.ts +66 -0
- package/.versions/0.3.3/.pi/harnesses/tool-counter-widget/package.json +6 -0
- package/.versions/0.3.3/.pi/prompts/build.md +24 -0
- package/.versions/0.3.3/.pi/prompts/code-simplify.md +22 -0
- package/.versions/0.3.3/.pi/prompts/doctor-agent-skills.md +13 -0
- package/.versions/0.3.3/.pi/prompts/plan.md +16 -0
- package/.versions/0.3.3/.pi/prompts/review.md +16 -0
- package/.versions/0.3.3/.pi/prompts/setup-agent-skills.md +19 -0
- package/.versions/0.3.3/.pi/prompts/ship.md +17 -0
- package/.versions/0.3.3/.pi/prompts/spec.md +15 -0
- package/.versions/0.3.3/.pi/prompts/test.md +19 -0
- package/.versions/0.3.3/.pi/skills/bowser/SKILL.md +114 -0
- package/.versions/0.3.3/.version +1 -0
- package/.versions/0.3.3/agents/builder.md +6 -0
- package/.versions/0.3.3/agents/code-reviewer.md +93 -0
- package/.versions/0.3.3/agents/documenter.md +6 -0
- package/.versions/0.3.3/agents/plan-reviewer.md +22 -0
- package/.versions/0.3.3/agents/planner.md +6 -0
- package/.versions/0.3.3/agents/scout.md +6 -0
- package/.versions/0.3.3/agents/security-auditor.md +97 -0
- package/.versions/0.3.3/agents/test-engineer.md +89 -0
- package/.versions/0.3.3/hooks/SIMPLIFY-IGNORE.md +90 -0
- package/.versions/0.3.3/hooks/hooks.json +14 -0
- package/.versions/0.3.3/hooks/session-start.sh +74 -0
- package/.versions/0.3.3/hooks/simplify-ignore-test.sh +247 -0
- package/.versions/0.3.3/hooks/simplify-ignore.sh +302 -0
- package/.versions/0.3.3/references/accessibility-checklist.md +159 -0
- package/.versions/0.3.3/references/performance-checklist.md +121 -0
- package/.versions/0.3.3/references/prompting-patterns.md +380 -0
- package/.versions/0.3.3/references/security-checklist.md +134 -0
- package/.versions/0.3.3/references/testing-patterns.md +236 -0
- package/.versions/0.3.3/scripts/coms-net-server.ts +1741 -0
- package/.versions/0.3.3/skills/api-and-interface-design/SKILL.md +294 -0
- package/.versions/0.3.3/skills/browser-testing-with-devtools/SKILL.md +335 -0
- package/.versions/0.3.3/skills/ci-cd-and-automation/SKILL.md +390 -0
- package/.versions/0.3.3/skills/code-review-and-quality/SKILL.md +347 -0
- package/.versions/0.3.3/skills/code-simplification/SKILL.md +331 -0
- package/.versions/0.3.3/skills/context-engineering/SKILL.md +291 -0
- package/.versions/0.3.3/skills/debugging-and-error-recovery/SKILL.md +300 -0
- package/.versions/0.3.3/skills/deprecation-and-migration/SKILL.md +206 -0
- package/.versions/0.3.3/skills/designing-agents/SKILL.md +394 -0
- package/.versions/0.3.3/skills/designing-agents/pi-harness-authoring.md +213 -0
- package/.versions/0.3.3/skills/documentation-and-adrs/SKILL.md +278 -0
- package/.versions/0.3.3/skills/frontend-ui-engineering/SKILL.md +322 -0
- package/.versions/0.3.3/skills/git-workflow-and-versioning/SKILL.md +316 -0
- package/.versions/0.3.3/skills/guided-workspace-setup/SKILL.md +345 -0
- package/.versions/0.3.3/skills/idea-refine/SKILL.md +178 -0
- package/.versions/0.3.3/skills/idea-refine/examples.md +238 -0
- package/.versions/0.3.3/skills/idea-refine/frameworks.md +99 -0
- package/.versions/0.3.3/skills/idea-refine/refinement-criteria.md +113 -0
- package/.versions/0.3.3/skills/idea-refine/scripts/idea-refine.sh +15 -0
- package/.versions/0.3.3/skills/incremental-implementation/SKILL.md +279 -0
- package/.versions/0.3.3/skills/performance-optimization/SKILL.md +350 -0
- package/.versions/0.3.3/skills/planning-and-task-breakdown/SKILL.md +237 -0
- package/.versions/0.3.3/skills/security-and-hardening/SKILL.md +349 -0
- package/.versions/0.3.3/skills/shipping-and-launch/SKILL.md +309 -0
- package/.versions/0.3.3/skills/source-driven-development/SKILL.md +194 -0
- package/.versions/0.3.3/skills/spec-driven-development/SKILL.md +237 -0
- package/.versions/0.3.3/skills/test-driven-development/SKILL.md +379 -0
- package/.versions/0.3.3/skills/using-agent-skills/SKILL.md +176 -0
- package/CHANGELOG.md +17 -0
- package/bin/snapshot-version.js +8 -1
- package/package.json +2 -1
- package/scripts/coms-net-server.ts +1741 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
# Testing Patterns Reference
|
|
2
|
+
|
|
3
|
+
Quick reference for common testing patterns across the stack. Use alongside the `test-driven-development` skill.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Test Structure (Arrange-Act-Assert)](#test-structure-arrange-act-assert)
|
|
8
|
+
- [Test Naming Conventions](#test-naming-conventions)
|
|
9
|
+
- [Common Assertions](#common-assertions)
|
|
10
|
+
- [Mocking Patterns](#mocking-patterns)
|
|
11
|
+
- [React/Component Testing](#reactcomponent-testing)
|
|
12
|
+
- [API / Integration Testing](#api--integration-testing)
|
|
13
|
+
- [E2E Testing (Playwright)](#e2e-testing-playwright)
|
|
14
|
+
- [Test Anti-Patterns](#test-anti-patterns)
|
|
15
|
+
|
|
16
|
+
## Test Structure (Arrange-Act-Assert)
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
it('describes expected behavior', () => {
|
|
20
|
+
// Arrange: Set up test data and preconditions
|
|
21
|
+
const input = { title: 'Test Task', priority: 'high' };
|
|
22
|
+
|
|
23
|
+
// Act: Perform the action being tested
|
|
24
|
+
const result = createTask(input);
|
|
25
|
+
|
|
26
|
+
// Assert: Verify the outcome
|
|
27
|
+
expect(result.title).toBe('Test Task');
|
|
28
|
+
expect(result.priority).toBe('high');
|
|
29
|
+
expect(result.status).toBe('pending');
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Test Naming Conventions
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// Pattern: [unit] [expected behavior] [condition]
|
|
37
|
+
describe('TaskService.createTask', () => {
|
|
38
|
+
it('creates a task with default pending status', () => {});
|
|
39
|
+
it('throws ValidationError when title is empty', () => {});
|
|
40
|
+
it('trims whitespace from title', () => {});
|
|
41
|
+
it('generates a unique ID for each task', () => {});
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Common Assertions
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// Equality
|
|
49
|
+
expect(result).toBe(expected); // Strict equality (===)
|
|
50
|
+
expect(result).toEqual(expected); // Deep equality (objects/arrays)
|
|
51
|
+
expect(result).toStrictEqual(expected); // Deep equality + type matching
|
|
52
|
+
|
|
53
|
+
// Truthiness
|
|
54
|
+
expect(result).toBeTruthy();
|
|
55
|
+
expect(result).toBeFalsy();
|
|
56
|
+
expect(result).toBeNull();
|
|
57
|
+
expect(result).toBeDefined();
|
|
58
|
+
expect(result).toBeUndefined();
|
|
59
|
+
|
|
60
|
+
// Numbers
|
|
61
|
+
expect(result).toBeGreaterThan(5);
|
|
62
|
+
expect(result).toBeLessThanOrEqual(10);
|
|
63
|
+
expect(result).toBeCloseTo(0.3, 5); // Floating point
|
|
64
|
+
|
|
65
|
+
// Strings
|
|
66
|
+
expect(result).toMatch(/pattern/);
|
|
67
|
+
expect(result).toContain('substring');
|
|
68
|
+
|
|
69
|
+
// Arrays / Objects
|
|
70
|
+
expect(array).toContain(item);
|
|
71
|
+
expect(array).toHaveLength(3);
|
|
72
|
+
expect(object).toHaveProperty('key', 'value');
|
|
73
|
+
|
|
74
|
+
// Errors
|
|
75
|
+
expect(() => fn()).toThrow();
|
|
76
|
+
expect(() => fn()).toThrow(ValidationError);
|
|
77
|
+
expect(() => fn()).toThrow('specific message');
|
|
78
|
+
|
|
79
|
+
// Async
|
|
80
|
+
await expect(asyncFn()).resolves.toBe(value);
|
|
81
|
+
await expect(asyncFn()).rejects.toThrow(Error);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Mocking Patterns
|
|
85
|
+
|
|
86
|
+
### Mock Functions
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
const mockFn = jest.fn();
|
|
90
|
+
mockFn.mockReturnValue(42);
|
|
91
|
+
mockFn.mockResolvedValue({ data: 'test' });
|
|
92
|
+
mockFn.mockImplementation((x) => x * 2);
|
|
93
|
+
|
|
94
|
+
expect(mockFn).toHaveBeenCalled();
|
|
95
|
+
expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2');
|
|
96
|
+
expect(mockFn).toHaveBeenCalledTimes(3);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Mock Modules
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
// Mock an entire module
|
|
103
|
+
jest.mock('./database', () => ({
|
|
104
|
+
query: jest.fn().mockResolvedValue([{ id: 1, title: 'Test' }]),
|
|
105
|
+
}));
|
|
106
|
+
|
|
107
|
+
// Mock specific exports
|
|
108
|
+
jest.mock('./utils', () => ({
|
|
109
|
+
...jest.requireActual('./utils'),
|
|
110
|
+
generateId: jest.fn().mockReturnValue('test-id'),
|
|
111
|
+
}));
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Mock at Boundaries Only
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
Mock these: Don't mock these:
|
|
118
|
+
├── Database calls ├── Internal utility functions
|
|
119
|
+
├── HTTP requests ├── Business logic
|
|
120
|
+
├── File system operations ├── Data transformations
|
|
121
|
+
├── External API calls ├── Validation functions
|
|
122
|
+
└── Time/Date (when needed) └── Pure functions
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## React/Component Testing
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
129
|
+
|
|
130
|
+
describe('TaskForm', () => {
|
|
131
|
+
it('submits the form with entered data', async () => {
|
|
132
|
+
const onSubmit = jest.fn();
|
|
133
|
+
render(<TaskForm onSubmit={onSubmit} />);
|
|
134
|
+
|
|
135
|
+
// Find elements by accessible role/label (not test IDs)
|
|
136
|
+
await screen.findByRole('textbox', { name: /title/i });
|
|
137
|
+
fireEvent.change(screen.getByRole('textbox', { name: /title/i }), {
|
|
138
|
+
target: { value: 'New Task' },
|
|
139
|
+
});
|
|
140
|
+
fireEvent.click(screen.getByRole('button', { name: /create/i }));
|
|
141
|
+
|
|
142
|
+
await waitFor(() => {
|
|
143
|
+
expect(onSubmit).toHaveBeenCalledWith({ title: 'New Task' });
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('shows validation error for empty title', async () => {
|
|
148
|
+
render(<TaskForm onSubmit={jest.fn()} />);
|
|
149
|
+
|
|
150
|
+
fireEvent.click(screen.getByRole('button', { name: /create/i }));
|
|
151
|
+
|
|
152
|
+
expect(await screen.findByText(/title is required/i)).toBeInTheDocument();
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## API / Integration Testing
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
import request from 'supertest';
|
|
161
|
+
import { app } from '../src/app';
|
|
162
|
+
|
|
163
|
+
describe('POST /api/tasks', () => {
|
|
164
|
+
it('creates a task and returns 201', async () => {
|
|
165
|
+
const response = await request(app)
|
|
166
|
+
.post('/api/tasks')
|
|
167
|
+
.send({ title: 'Test Task' })
|
|
168
|
+
.set('Authorization', `Bearer ${testToken}`)
|
|
169
|
+
.expect(201);
|
|
170
|
+
|
|
171
|
+
expect(response.body).toMatchObject({
|
|
172
|
+
id: expect.any(String),
|
|
173
|
+
title: 'Test Task',
|
|
174
|
+
status: 'pending',
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('returns 422 for invalid input', async () => {
|
|
179
|
+
const response = await request(app)
|
|
180
|
+
.post('/api/tasks')
|
|
181
|
+
.send({ title: '' })
|
|
182
|
+
.set('Authorization', `Bearer ${testToken}`)
|
|
183
|
+
.expect(422);
|
|
184
|
+
|
|
185
|
+
expect(response.body.error.code).toBe('VALIDATION_ERROR');
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('returns 401 without authentication', async () => {
|
|
189
|
+
await request(app)
|
|
190
|
+
.post('/api/tasks')
|
|
191
|
+
.send({ title: 'Test' })
|
|
192
|
+
.expect(401);
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## E2E Testing (Playwright)
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { test, expect } from '@playwright/test';
|
|
201
|
+
|
|
202
|
+
test('user can create and complete a task', async ({ page }) => {
|
|
203
|
+
// Navigate and authenticate
|
|
204
|
+
await page.goto('/');
|
|
205
|
+
await page.fill('[name="email"]', 'test@example.com');
|
|
206
|
+
await page.fill('[name="password"]', 'testpass123');
|
|
207
|
+
await page.click('button:has-text("Log in")');
|
|
208
|
+
|
|
209
|
+
// Create a task
|
|
210
|
+
await page.click('button:has-text("New Task")');
|
|
211
|
+
await page.fill('[name="title"]', 'Buy groceries');
|
|
212
|
+
await page.click('button:has-text("Create")');
|
|
213
|
+
|
|
214
|
+
// Verify task appears
|
|
215
|
+
await expect(page.locator('text=Buy groceries')).toBeVisible();
|
|
216
|
+
|
|
217
|
+
// Complete the task
|
|
218
|
+
await page.click('[aria-label="Complete Buy groceries"]');
|
|
219
|
+
await expect(page.locator('text=Buy groceries')).toHaveCSS(
|
|
220
|
+
'text-decoration-line', 'line-through'
|
|
221
|
+
);
|
|
222
|
+
});
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Test Anti-Patterns
|
|
226
|
+
|
|
227
|
+
| Anti-Pattern | Problem | Better Approach |
|
|
228
|
+
|---|---|---|
|
|
229
|
+
| Testing implementation details | Breaks on refactor | Test inputs/outputs |
|
|
230
|
+
| Snapshot everything | No one reviews snapshot diffs | Assert specific values |
|
|
231
|
+
| Shared mutable state | Tests pollute each other | Setup/teardown per test |
|
|
232
|
+
| Testing third-party code | Wastes time, not your bug | Mock the boundary |
|
|
233
|
+
| Skipping tests to pass CI | Hides real bugs | Fix or delete the test |
|
|
234
|
+
| Using `test.skip` permanently | Dead code | Remove or fix it |
|
|
235
|
+
| Overly broad assertions | Doesn't catch regressions | Be specific |
|
|
236
|
+
| No async error handling | Swallowed errors, false passes | Always `await` async tests |
|