@facet-coverage/core 0.3.0 → 0.4.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/README.md +64 -575
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +224 -25
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/core/FacetParser.d.ts +36 -1
- package/dist/core/FacetParser.d.ts.map +1 -1
- package/dist/core/FacetParser.js +106 -0
- package/dist/core/FacetParser.js.map +1 -1
- package/dist/core/TestScanner.d.ts +4 -1
- package/dist/core/TestScanner.d.ts.map +1 -1
- package/dist/core/TestScanner.js +42 -13
- package/dist/core/TestScanner.js.map +1 -1
- package/dist/core/Validator.d.ts +4 -0
- package/dist/core/Validator.d.ts.map +1 -1
- package/dist/core/Validator.js +22 -4
- package/dist/core/Validator.js.map +1 -1
- package/dist/types.d.ts +25 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**Test every facet of your features**
|
|
6
6
|
|
|
7
|
-
*
|
|
7
|
+
*Write requirements naturally. Know what's tested. Track multi-stakeholder coverage automatically.*
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/@facet-coverage/core)
|
|
10
10
|
[](https://opensource.org/licenses/MIT)
|
|
@@ -15,641 +15,132 @@
|
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
- [What is Facet?](#what-is-facet)
|
|
21
|
-
- [Installation](#installation)
|
|
22
|
-
- [Quick Start](#quick-start)
|
|
23
|
-
- [Linking Tests to Facets](#linking-tests-to-facets)
|
|
24
|
-
- [Project Structure](#project-structure)
|
|
25
|
-
- [CLI Commands](#cli-commands)
|
|
26
|
-
- [Playwright Integration](#playwright-integration)
|
|
27
|
-
- [Configuration](#configuration)
|
|
28
|
-
- [ID Patterns](#id-patterns)
|
|
29
|
-
- [Programmatic API](#programmatic-api)
|
|
30
|
-
- [Benefits](#benefits)
|
|
31
|
-
- [How Facet Differs](#how-facet-differs)
|
|
32
|
-
- [Key Principles](#key-principles)
|
|
33
|
-
- [Contributing](#contributing)
|
|
34
|
-
- [License](#license)
|
|
18
|
+
## Why Facet?
|
|
35
19
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
## What is Facet?
|
|
39
|
-
|
|
40
|
-
Facet is a modern testing framework that lets you document features from multiple stakeholder perspectives while maintaining exact traceability to your tests.
|
|
20
|
+
Traditional testing asks "what did developers test?" Facet asks "what do stakeholders need, and is it tested?"
|
|
41
21
|
|
|
42
|
-
|
|
22
|
+
Real products serve multiple stakeholders—product owners, compliance teams, UX designers, security architects—each with their own requirements. Facet lets every stakeholder write requirements in natural language, then tracks whether tests actually cover them.
|
|
43
23
|
|
|
44
|
-
|
|
45
|
-
|-------------|-------------|
|
|
46
|
-
| **Business requirements** | Product owner specifications |
|
|
47
|
-
| **Compliance mandates** | Regulatory requirements (PCI-DSS, GDPR, etc.) |
|
|
48
|
-
| **UX standards** | Design system and accessibility rules |
|
|
49
|
-
| **Technical specs** | Architecture and API contracts |
|
|
50
|
-
|
|
51
|
-
All connected to the same tests. All tracked for coverage.
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Installation
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
bun add -d @facet-coverage/core
|
|
59
|
-
```
|
|
24
|
+
**One feature. Many facets. All tracked.**
|
|
60
25
|
|
|
61
26
|
---
|
|
62
27
|
|
|
63
28
|
## Quick Start
|
|
64
29
|
|
|
65
|
-
###
|
|
30
|
+
### Install
|
|
66
31
|
|
|
67
32
|
```bash
|
|
68
|
-
|
|
33
|
+
bun add -d @facet-coverage/core
|
|
69
34
|
```
|
|
70
35
|
|
|
71
|
-
|
|
36
|
+
### 1. Each stakeholder writes their requirements
|
|
72
37
|
|
|
73
|
-
**
|
|
38
|
+
**Business Team** — `facets/business.md`
|
|
74
39
|
```markdown
|
|
75
40
|
## Guest Purchase Flow
|
|
76
|
-
|
|
77
|
-
A user who isn't logged in should be able to buy products. They add
|
|
78
|
-
items to cart, click checkout, provide email and payment details,
|
|
79
|
-
and get an order confirmation.
|
|
80
|
-
|
|
81
|
-
### Edge Cases
|
|
82
|
-
- Empty cart at checkout
|
|
83
|
-
- Invalid email format
|
|
84
|
-
- Payment gateway timeout
|
|
41
|
+
Users should complete purchases without creating an account.
|
|
85
42
|
```
|
|
86
43
|
|
|
87
|
-
**
|
|
44
|
+
**Compliance Team** — `facets/compliance.md`
|
|
88
45
|
```markdown
|
|
89
|
-
## PCI-DSS Payment Requirements
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
1. **Encryption in transit** - TLS 1.2+ required
|
|
94
|
-
2. **No CVV storage** - Use payment gateway, never store CVV
|
|
95
|
-
3. **Card masking** - Display only last 4 digits
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### 2. Generate Structure & Types
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
bunx facet generate features/checkout/facets/
|
|
46
|
+
## PCI-DSS Payment Requirements {#pci-dss}
|
|
47
|
+
1. **Encryption in transit** {#tls} - TLS 1.2+ required
|
|
48
|
+
2. **No CVV storage** {#cvv} - Never store CVV
|
|
49
|
+
3. **Card masking** {#masking} - Show only last 4 digits
|
|
102
50
|
```
|
|
103
51
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
**structure.json:**
|
|
109
|
-
|
|
110
|
-
```json
|
|
111
|
-
{
|
|
112
|
-
"feature": "checkout",
|
|
113
|
-
"facets": [
|
|
114
|
-
{
|
|
115
|
-
"id": "business:guest-purchase-flow",
|
|
116
|
-
"source": {
|
|
117
|
-
"file": "facets/business.md",
|
|
118
|
-
"section": "guest-purchase-flow"
|
|
119
|
-
},
|
|
120
|
-
"type": "business"
|
|
121
|
-
},
|
|
122
|
-
{
|
|
123
|
-
"id": "compliance:pci-dss-payment-requirements",
|
|
124
|
-
"source": {
|
|
125
|
-
"file": "facets/compliance.md",
|
|
126
|
-
"section": "pci-dss-payment-requirements"
|
|
127
|
-
},
|
|
128
|
-
"type": "compliance"
|
|
129
|
-
}
|
|
130
|
-
]
|
|
131
|
-
}
|
|
52
|
+
**UX Team** — `facets/ux.md`
|
|
53
|
+
```markdown
|
|
54
|
+
## Mobile Checkout Experience
|
|
55
|
+
Large touch targets (44px min), single column layout, inline validation.
|
|
132
56
|
```
|
|
133
57
|
|
|
134
|
-
###
|
|
135
|
-
|
|
136
|
-
Import the generated types and use `facet()` in your tests:
|
|
58
|
+
### 2. Tests link to requirements
|
|
137
59
|
|
|
138
60
|
```typescript
|
|
139
|
-
// features/checkout/tests/checkout.spec.ts
|
|
140
|
-
import { test, expect } from 'bun:test'; // or jest, vitest, mocha...
|
|
141
61
|
import { Facets, facet } from '../.facet/facets';
|
|
142
62
|
|
|
143
|
-
test('guest user completes purchase', () => {
|
|
144
|
-
//
|
|
63
|
+
test('guest user completes purchase on mobile', () => {
|
|
64
|
+
// This test proves requirements for 3 different stakeholders
|
|
145
65
|
facet(Facets.BUSINESS_GUEST_PURCHASE_FLOW);
|
|
146
|
-
facet(Facets.
|
|
147
|
-
|
|
148
|
-
// Your test code
|
|
149
|
-
const order = checkout(cart, 'user@example.com', '4242...');
|
|
150
|
-
expect(order.confirmed).toBe(true);
|
|
151
|
-
expect(order.maskedCard).toBe('•••• 4242'); // PCI-DSS compliance
|
|
152
|
-
});
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
The `facet()` function is type-safe - TypeScript will error if you use an invalid facet ID!
|
|
156
|
-
|
|
157
|
-
### 4. Run Coverage
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
bunx facet analyze
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
**Output:**
|
|
164
|
-
```
|
|
165
|
-
Facet Coverage Report
|
|
166
|
-
|
|
167
|
-
Overall: 100%
|
|
168
|
-
|
|
169
|
-
By Type:
|
|
170
|
-
business: 100% (1/1)
|
|
171
|
-
compliance: 100% (1/1)
|
|
172
|
-
|
|
173
|
-
Reports generated:
|
|
174
|
-
.facet-coverage/coverage.json
|
|
175
|
-
.facet-coverage/coverage.html
|
|
176
|
-
.facet-coverage/coverage.md
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
---
|
|
180
|
-
|
|
181
|
-
## Project Structure
|
|
182
|
-
|
|
183
|
-
```
|
|
184
|
-
project/
|
|
185
|
-
├── features/
|
|
186
|
-
│ ├── checkout/
|
|
187
|
-
│ │ ├── facets/
|
|
188
|
-
│ │ │ ├── business.md # Product owner writes
|
|
189
|
-
│ │ │ ├── compliance.md # Compliance team writes
|
|
190
|
-
│ │ │ └── ux.md # UX designer writes
|
|
191
|
-
│ │ ├── .facet/
|
|
192
|
-
│ │ │ ├── structure.json # Generated facet definitions
|
|
193
|
-
│ │ │ └── facets.ts # Generated TypeScript types
|
|
194
|
-
│ │ └── tests/
|
|
195
|
-
│ │ └── checkout.spec.ts
|
|
196
|
-
│ │
|
|
197
|
-
│ └── authentication/
|
|
198
|
-
│ ├── facets/
|
|
199
|
-
│ ├── .facet/
|
|
200
|
-
│ └── tests/
|
|
201
|
-
│
|
|
202
|
-
├── .facet-coverage/ # Coverage reports
|
|
203
|
-
│ ├── coverage.json
|
|
204
|
-
│ ├── coverage.html
|
|
205
|
-
│ └── coverage.md
|
|
206
|
-
│
|
|
207
|
-
└── facet.config.js # Configuration
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
---
|
|
211
|
-
|
|
212
|
-
## Linking Tests to Facets
|
|
213
|
-
|
|
214
|
-
Use the `facet()` function inside your tests - just like `expect()` but for coverage tracking!
|
|
215
|
-
|
|
216
|
-
### Recommended: Type-Safe with `facet()` Function
|
|
66
|
+
facet(Facets.COMPLIANCE_PCI_DSS);
|
|
67
|
+
facet(Facets.UX_MOBILE_CHECKOUT_EXPERIENCE);
|
|
217
68
|
|
|
218
|
-
|
|
219
|
-
import { test, expect } from 'bun:test'; // or jest, vitest, mocha...
|
|
220
|
-
import { Facets, facet } from '../.facet/facets';
|
|
69
|
+
const order = checkout(cart, 'user@example.com', '4242424242424242');
|
|
221
70
|
|
|
222
|
-
test('guest user can complete a purchase', () => {
|
|
223
|
-
// Declare which facets this test covers - type-safe with autocomplete!
|
|
224
|
-
facet(Facets.BUSINESS_GUEST_PURCHASE_FLOW);
|
|
225
|
-
facet(Facets.COMPLIANCE_PCI_DSS_PAYMENT_REQUIREMENTS);
|
|
226
|
-
|
|
227
|
-
// Your test code
|
|
228
|
-
const order = checkout(cart, email, card);
|
|
229
71
|
expect(order.confirmed).toBe(true);
|
|
72
|
+
expect(order.maskedCard).toBe('•••• 4242'); // PCI-DSS compliance
|
|
230
73
|
});
|
|
231
74
|
|
|
232
|
-
test('
|
|
233
|
-
//
|
|
234
|
-
facet(Facets.
|
|
75
|
+
test('TLS encryption enforced', () => {
|
|
76
|
+
// Track specific compliance sub-requirements
|
|
77
|
+
facet(Facets.COMPLIANCE_PCI_DSS__TLS);
|
|
235
78
|
|
|
236
|
-
expect(
|
|
79
|
+
expect(paymentEndpoint.protocol).toBe('https');
|
|
237
80
|
});
|
|
238
81
|
```
|
|
239
82
|
|
|
240
|
-
|
|
241
|
-
- Full TypeScript autocomplete
|
|
242
|
-
- Compile-time validation (invalid facet IDs cause errors)
|
|
243
|
-
- Clean, readable syntax
|
|
244
|
-
- Works with any testing framework
|
|
245
|
-
|
|
246
|
-
**Generated `facets.ts` includes:**
|
|
247
|
-
- `FacetId` - Union type of all valid facet IDs
|
|
248
|
-
- `Facets` - Object with constants for each facet
|
|
249
|
-
- `facet()` - Type-safe function to declare coverage
|
|
250
|
-
|
|
251
|
-
### Alternative: Comment Annotations
|
|
252
|
-
|
|
253
|
-
For quick setup without imports, use comment annotations:
|
|
254
|
-
|
|
255
|
-
```typescript
|
|
256
|
-
// @facet business:guest-purchase-flow, compliance:pci-dss
|
|
257
|
-
test('guest user completes purchase', () => {
|
|
258
|
-
// Your test code
|
|
259
|
-
});
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
### All Linking Methods
|
|
263
|
-
|
|
264
|
-
| Method | Type-Safe | Syntax |
|
|
265
|
-
|--------|-----------|--------|
|
|
266
|
-
| `facet()` function | Yes | `facet(Facets.ID)` inside test body |
|
|
267
|
-
| Comment annotation | No | `// @facet id` above test |
|
|
268
|
-
| Playwright annotation | Yes | `{ annotation: facet(...) }` in test options |
|
|
269
|
-
|
|
270
|
-
---
|
|
271
|
-
|
|
272
|
-
## CLI Commands
|
|
273
|
-
|
|
274
|
-
### Generate Structure & Types
|
|
83
|
+
### 3. See coverage across all perspectives
|
|
275
84
|
|
|
276
85
|
```bash
|
|
277
|
-
# Generate structure.json and facets.ts from facet documents
|
|
278
|
-
bunx facet generate <facets-dir>
|
|
279
|
-
|
|
280
|
-
# Options
|
|
281
|
-
bunx facet generate features/checkout/facets/ -o ./custom-output # Custom output dir
|
|
282
|
-
bunx facet generate features/checkout/facets/ -t business # Override type
|
|
283
|
-
bunx facet generate features/checkout/facets/ --no-types # Skip TypeScript generation
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
### Analyze Coverage
|
|
287
|
-
|
|
288
|
-
```bash
|
|
289
|
-
# Run coverage analysis
|
|
290
86
|
bunx facet analyze
|
|
291
|
-
|
|
292
|
-
# Options
|
|
293
|
-
bunx facet analyze -c facet.config.js # Custom config
|
|
294
|
-
bunx facet analyze -f html # Specific format
|
|
295
|
-
bunx facet analyze -t 80 # Set threshold
|
|
296
|
-
bunx facet analyze --json # JSON output for CI
|
|
297
|
-
bunx facet analyze --silent # No console output
|
|
298
|
-
```
|
|
299
|
-
|
|
300
|
-
### Validate
|
|
301
|
-
|
|
302
|
-
```bash
|
|
303
|
-
# Validate structure and test links
|
|
304
|
-
bunx facet validate
|
|
305
|
-
|
|
306
|
-
# Options
|
|
307
|
-
bunx facet validate --strict # Require all tests linked
|
|
308
|
-
bunx facet validate --json # JSON output
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
### Watch Mode
|
|
312
|
-
|
|
313
|
-
```bash
|
|
314
|
-
# Re-run on changes
|
|
315
|
-
bunx facet watch
|
|
316
|
-
|
|
317
|
-
# Options
|
|
318
|
-
bunx facet watch -v # Validate before analysis
|
|
319
87
|
```
|
|
320
88
|
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
## Playwright Integration
|
|
324
|
-
|
|
325
|
-
> **Note:** Playwright works with [comment annotations](#method-1-comment-annotations-any-framework) and [generated types](#method-2-type-safe-with-generated-types-recommended) out of the box. This section covers the **optional** enhanced integration with a custom reporter and annotation helper.
|
|
326
|
-
|
|
327
|
-
### Why Use the Playwright Integration?
|
|
328
|
-
|
|
329
|
-
- **Automatic coverage on test run** - Coverage reports generated after `playwright test`
|
|
330
|
-
- **Runtime annotation capture** - Works with dynamic test generation
|
|
331
|
-
- **Native annotation syntax** - Uses Playwright's built-in annotation system
|
|
332
|
-
|
|
333
|
-
### Reporter Setup
|
|
334
|
-
|
|
335
|
-
```typescript
|
|
336
|
-
// playwright.config.ts
|
|
337
|
-
import { FacetCoverageReporter } from '@facet-coverage/core/playwright';
|
|
338
|
-
|
|
339
|
-
export default {
|
|
340
|
-
reporter: [
|
|
341
|
-
['html'],
|
|
342
|
-
[FacetCoverageReporter, {
|
|
343
|
-
output: {
|
|
344
|
-
dir: '.facet-coverage',
|
|
345
|
-
formats: ['json', 'html', 'markdown']
|
|
346
|
-
},
|
|
347
|
-
thresholds: {
|
|
348
|
-
global: 80,
|
|
349
|
-
byType: {
|
|
350
|
-
compliance: 100
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}]
|
|
354
|
-
]
|
|
355
|
-
};
|
|
356
89
|
```
|
|
90
|
+
Facet Coverage Report
|
|
91
|
+
Overall: 83% (5/6)
|
|
357
92
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
import { facet } from '@facet-coverage/core/playwright';
|
|
363
|
-
|
|
364
|
-
// Single facet
|
|
365
|
-
test('my test', {
|
|
366
|
-
annotation: facet('guest-checkout-flow')
|
|
367
|
-
}, async ({ page }) => {
|
|
368
|
-
// ...
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
// Multiple facets
|
|
372
|
-
test('comprehensive test', {
|
|
373
|
-
annotation: facet(
|
|
374
|
-
'guest-checkout-flow',
|
|
375
|
-
'pci-card-masking',
|
|
376
|
-
'mobile-checkout-ux'
|
|
377
|
-
)
|
|
378
|
-
}, async ({ page }) => {
|
|
379
|
-
// ...
|
|
380
|
-
});
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
---
|
|
384
|
-
|
|
385
|
-
## Configuration
|
|
386
|
-
|
|
387
|
-
Facet Coverage supports multiple configuration file formats. The CLI looks for config files in this order:
|
|
388
|
-
|
|
389
|
-
1. `facet.config.js` (ESM or CommonJS)
|
|
390
|
-
2. `facet.config.mjs` (ESM only)
|
|
391
|
-
3. `facet.config.json` (JSON)
|
|
392
|
-
|
|
393
|
-
### Configuration Formats
|
|
394
|
-
|
|
395
|
-
**JavaScript (ESM):**
|
|
396
|
-
|
|
397
|
-
```javascript
|
|
398
|
-
// facet.config.js
|
|
399
|
-
export default {
|
|
400
|
-
// Glob pattern(s) for finding facet markdown files
|
|
401
|
-
facetPattern: ['features/**/*.facet.md', 'features/**/facets/*.md'],
|
|
402
|
-
|
|
403
|
-
// Where structure files are generated
|
|
404
|
-
structureFiles: ['features/**/.facet/structure.json'],
|
|
405
|
-
|
|
406
|
-
// Where tests live
|
|
407
|
-
testDir: './features/**/tests',
|
|
408
|
-
testPatterns: ['**/*.spec.ts', '**/*.test.ts'],
|
|
409
|
-
|
|
410
|
-
// Validation options
|
|
411
|
-
validation: {
|
|
412
|
-
requireSourceExists: true,
|
|
413
|
-
requireSectionExists: true,
|
|
414
|
-
requireAllTestsLinked: false
|
|
415
|
-
},
|
|
416
|
-
|
|
417
|
-
// Output options
|
|
418
|
-
output: {
|
|
419
|
-
dir: '.facet-coverage',
|
|
420
|
-
formats: ['json', 'html', 'markdown']
|
|
421
|
-
},
|
|
422
|
-
|
|
423
|
-
// Coverage thresholds
|
|
424
|
-
thresholds: {
|
|
425
|
-
global: 75,
|
|
426
|
-
byType: {
|
|
427
|
-
compliance: 100,
|
|
428
|
-
business: 80,
|
|
429
|
-
ux: 70
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
};
|
|
433
|
-
```
|
|
434
|
-
|
|
435
|
-
**JSON:**
|
|
436
|
-
|
|
437
|
-
```json
|
|
438
|
-
{
|
|
439
|
-
"facetPattern": ["features/**/*.facet.md", "features/**/facets/*.md"],
|
|
440
|
-
"structureFiles": ["features/**/.facet/structure.json"],
|
|
441
|
-
"testDir": "./features/**/tests",
|
|
442
|
-
"testPatterns": ["**/*.spec.ts", "**/*.test.ts"],
|
|
443
|
-
"validation": {
|
|
444
|
-
"requireSourceExists": true,
|
|
445
|
-
"requireSectionExists": true,
|
|
446
|
-
"requireAllTestsLinked": false
|
|
447
|
-
},
|
|
448
|
-
"output": {
|
|
449
|
-
"dir": ".facet-coverage",
|
|
450
|
-
"formats": ["json", "html", "markdown"]
|
|
451
|
-
},
|
|
452
|
-
"thresholds": {
|
|
453
|
-
"global": 75,
|
|
454
|
-
"byType": {
|
|
455
|
-
"compliance": 100
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
### Configuration Options
|
|
462
|
-
|
|
463
|
-
| Option | Type | Default | Description |
|
|
464
|
-
|--------|------|---------|-------------|
|
|
465
|
-
| `facetPattern` | `string \| string[]` | `['features/**/*.facet.md', 'features/**/facets/*.md']` | Glob pattern(s) for finding facet files |
|
|
466
|
-
| `structureFiles` | `string[]` | `['features/**/.facet/structure.json']` | Glob patterns for structure files |
|
|
467
|
-
| `testDir` | `string` | `'./features/**/tests'` | Test directory pattern |
|
|
468
|
-
| `testPatterns` | `string[]` | `['**/*.spec.ts', '**/*.test.ts']` | Test file patterns |
|
|
469
|
-
| `validation.requireSourceExists` | `boolean` | `true` | Check if source files exist |
|
|
470
|
-
| `validation.requireSectionExists` | `boolean` | `true` | Check if sections exist in files |
|
|
471
|
-
| `validation.requireAllTestsLinked` | `boolean` | `false` | Require every test links to a facet |
|
|
472
|
-
| `output.dir` | `string` | `'.facet-coverage'` | Output directory for reports |
|
|
473
|
-
| `output.formats` | `string[]` | `['json', 'html', 'markdown']` | Report formats to generate |
|
|
474
|
-
| `thresholds.global` | `number` | `75` | Overall coverage threshold % |
|
|
475
|
-
| `thresholds.byType` | `object` | `{}` | Per-type coverage thresholds |
|
|
476
|
-
|
|
477
|
-
---
|
|
478
|
-
|
|
479
|
-
## ID Patterns
|
|
480
|
-
|
|
481
|
-
### Auto-Generated (Recommended)
|
|
482
|
-
|
|
483
|
-
```
|
|
484
|
-
Pattern: {filename}:{section-slug}
|
|
485
|
-
|
|
486
|
-
Examples:
|
|
487
|
-
- business:guest-purchase-flow
|
|
488
|
-
- compliance:pci-dss-payment-requirements
|
|
489
|
-
- ux:mobile-checkout-experience
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
### Custom Slugs
|
|
493
|
-
|
|
494
|
-
```json
|
|
495
|
-
{
|
|
496
|
-
"id": "guest-checkout-flow",
|
|
497
|
-
"source": {
|
|
498
|
-
"file": "facets/business.md",
|
|
499
|
-
"section": "guest-purchase-flow"
|
|
500
|
-
},
|
|
501
|
-
"type": "business"
|
|
502
|
-
}
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
### Flexible Linking
|
|
506
|
-
|
|
507
|
-
```typescript
|
|
508
|
-
// All three formats work:
|
|
509
|
-
facet('guest-checkout-flow') // Custom slug
|
|
510
|
-
facet('business:guest-purchase-flow') // Auto-generated
|
|
511
|
-
facet('facets/business.md#guest-purchase-flow') // Direct path
|
|
512
|
-
```
|
|
513
|
-
|
|
514
|
-
---
|
|
515
|
-
|
|
516
|
-
## Programmatic API
|
|
517
|
-
|
|
518
|
-
```typescript
|
|
519
|
-
import {
|
|
520
|
-
StructureReader,
|
|
521
|
-
TestScanner,
|
|
522
|
-
CoverageCalculator,
|
|
523
|
-
Validator,
|
|
524
|
-
JsonReporter,
|
|
525
|
-
HtmlReporter,
|
|
526
|
-
MarkdownReporter
|
|
527
|
-
} from '@facet-coverage/core';
|
|
528
|
-
|
|
529
|
-
// Read structures
|
|
530
|
-
const reader = new StructureReader();
|
|
531
|
-
const structures = await reader.readAllStructures();
|
|
532
|
-
|
|
533
|
-
// Scan tests
|
|
534
|
-
const scanner = new TestScanner();
|
|
535
|
-
const tests = await scanner.scanAllTests();
|
|
536
|
-
|
|
537
|
-
// Calculate coverage
|
|
538
|
-
const calculator = new CoverageCalculator();
|
|
539
|
-
const report = await calculator.calculateCoverage();
|
|
540
|
-
|
|
541
|
-
// Validate
|
|
542
|
-
const validator = new Validator();
|
|
543
|
-
const result = await validator.validate();
|
|
544
|
-
|
|
545
|
-
// Generate reports
|
|
546
|
-
const jsonReporter = new JsonReporter();
|
|
547
|
-
jsonReporter.write(report);
|
|
548
|
-
|
|
549
|
-
const htmlReporter = new HtmlReporter();
|
|
550
|
-
htmlReporter.write(report);
|
|
551
|
-
|
|
552
|
-
const mdReporter = new MarkdownReporter();
|
|
553
|
-
mdReporter.write(report);
|
|
93
|
+
business: 100% (1/1) ✓
|
|
94
|
+
compliance: 80% (4/5)
|
|
95
|
+
✗ pci-dss/cvv - No CVV storage
|
|
96
|
+
ux: 100% (1/1) ✓
|
|
554
97
|
```
|
|
555
98
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
## Benefits
|
|
559
|
-
|
|
560
|
-
<table>
|
|
561
|
-
<tr>
|
|
562
|
-
<td width="50%">
|
|
563
|
-
|
|
564
|
-
### For Product Owners
|
|
565
|
-
- Write in natural language
|
|
566
|
-
- Focus on business value
|
|
567
|
-
- See what's tested immediately
|
|
568
|
-
- Documentation evolves with product
|
|
569
|
-
|
|
570
|
-
### For Compliance Teams
|
|
571
|
-
- Direct regulation mapping
|
|
572
|
-
- Audit-ready traceability
|
|
573
|
-
- 100% coverage enforcement
|
|
574
|
-
- Automated compliance reports
|
|
575
|
-
|
|
576
|
-
### For UX Designers
|
|
577
|
-
- Document user flows naturally
|
|
578
|
-
- Link designs to tests
|
|
579
|
-
- Track accessibility coverage
|
|
580
|
-
- Mobile/desktop requirements clear
|
|
581
|
-
|
|
582
|
-
</td>
|
|
583
|
-
<td width="50%">
|
|
584
|
-
|
|
585
|
-
### For Developers
|
|
586
|
-
- One test covers multiple facets
|
|
587
|
-
- Clear requirements from all stakeholders
|
|
588
|
-
- Know exactly what's covered
|
|
589
|
-
- Easy maintenance
|
|
590
|
-
|
|
591
|
-
### For QA Teams
|
|
592
|
-
- Complete visibility
|
|
593
|
-
- Automated gap detection
|
|
594
|
-
- Multi-perspective coverage
|
|
595
|
-
- Progress tracking
|
|
596
|
-
|
|
597
|
-
</td>
|
|
598
|
-
</tr>
|
|
599
|
-
</table>
|
|
99
|
+
**Now you know:** The compliance team's CVV requirement isn't tested yet.
|
|
600
100
|
|
|
601
101
|
---
|
|
602
102
|
|
|
603
|
-
##
|
|
604
|
-
|
|
605
|
-
| Approach | Focus | Facet's Difference |
|
|
606
|
-
|----------|-------|-------------------|
|
|
607
|
-
| **TDD** | Code correctness via unit tests | Facet tracks *what* is covered, not *how* to write code |
|
|
608
|
-
| **BDD** | Behavior via Given-When-Then | Facet uses free-form natural language, not structured syntax |
|
|
609
|
-
| **ATDD** | Acceptance criteria drive development | Facet maps multiple perspectives to tests, not just acceptance |
|
|
610
|
-
| **Traditional Coverage** | Lines/branches executed | Facet measures *requirement* coverage, not code coverage |
|
|
611
|
-
|
|
612
|
-
**Key insight:** TDD/BDD/ATDD are *development methodologies*. Facet is a *coverage framework*. Use them together.
|
|
613
|
-
|
|
614
|
-
### Why Facet Works for AI-Driven Testing
|
|
103
|
+
## Documentation
|
|
615
104
|
|
|
616
|
-
|
|
105
|
+
| Guide | Description |
|
|
106
|
+
|-------|-------------|
|
|
107
|
+
| [Getting Started](docs/getting-started.md) | Full quickstart with project structure |
|
|
108
|
+
| [Core Concepts](docs/concepts.md) | What Facet is and how it works |
|
|
109
|
+
| [Configuration](docs/configuration.md) | Config options and examples |
|
|
110
|
+
| [CLI Reference](docs/cli.md) | All available commands |
|
|
111
|
+
| [Playwright Integration](docs/playwright.md) | Enhanced Playwright support |
|
|
112
|
+
| [Programmatic API](docs/api.md) | Use Facet in code |
|
|
113
|
+
| [ID Patterns](docs/id-patterns.md) | Stable IDs, sub-facets, and nested features |
|
|
617
114
|
|
|
618
|
-
|
|
619
|
-
- **Multi-perspective facets** → AI generates tests covering business, compliance, UX in one pass
|
|
620
|
-
- **Type-safe linking** → AI can programmatically verify coverage completeness
|
|
621
|
-
- **Gap detection** → AI identifies untested facets and generates missing tests
|
|
115
|
+
### Background
|
|
622
116
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
Facet bridges human intent and AI execution with traceable, verifiable coverage.
|
|
117
|
+
| Document | Description |
|
|
118
|
+
|----------|-------------|
|
|
119
|
+
| [Vision](docs/vision.md) | Philosophy behind multi-stakeholder coverage |
|
|
120
|
+
| [Testing Phases](docs/testing-phases.md) | Where Facet fits in testing |
|
|
121
|
+
| [Comparisons](docs/comparisons.md) | How Facet differs from BDD, Cucumber, etc. |
|
|
629
122
|
|
|
630
123
|
---
|
|
631
124
|
|
|
632
|
-
## Key
|
|
125
|
+
## Key Features
|
|
633
126
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
| **Lightweight** | Markdown + JSON, nothing heavy |
|
|
642
|
-
| **Flexible** | Adopt incrementally, customize freely |
|
|
127
|
+
- **Natural language** - Write requirements as Markdown, no Gherkin syntax
|
|
128
|
+
- **Multi-perspective** - Business, compliance, UX, technical facets per feature
|
|
129
|
+
- **Sub-facets** - Track fine-grained requirements with hierarchical IDs
|
|
130
|
+
- **Type-safe linking** - Generated TypeScript types prevent broken references
|
|
131
|
+
- **Framework agnostic** - Works with Jest, Vitest, Playwright, Mocha, Bun
|
|
132
|
+
- **Gap detection** - See what's untested across all stakeholder perspectives
|
|
133
|
+
- **CI-ready** - Threshold enforcement and JSON output for pipelines
|
|
643
134
|
|
|
644
135
|
---
|
|
645
136
|
|
|
646
137
|
## Contributing
|
|
647
138
|
|
|
648
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
139
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
649
140
|
|
|
650
141
|
1. Fork the repository
|
|
651
142
|
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
652
|
-
3. Commit your changes
|
|
143
|
+
3. Commit your changes
|
|
653
144
|
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
654
145
|
5. Open a Pull Request
|
|
655
146
|
|
|
@@ -665,6 +156,4 @@ MIT License - see the [LICENSE](LICENSE) file for details.
|
|
|
665
156
|
|
|
666
157
|
**[Report Bug](https://github.com/iraycd/facet-coverage/issues) | [Request Feature](https://github.com/iraycd/facet-coverage/issues)**
|
|
667
158
|
|
|
668
|
-
If you find this project useful, please consider giving it a star!
|
|
669
|
-
|
|
670
159
|
</div>
|