@michalfidor/playswag 1.0.0 → 1.2.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/LICENSE +21 -0
- package/README.md +133 -8
- package/assets/.gitkeep +1 -0
- package/assets/logo.png +0 -0
- package/dist/cjs/index.cjs +682 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/reporter.cjs +854 -31
- package/dist/cjs/reporter.cjs.map +1 -1
- package/dist/esm/index.js +673 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/reporter.js +856 -33
- package/dist/esm/reporter.js.map +1 -1
- package/dist/types/index.d.ts +78 -2
- package/dist/types/reporter.d.ts +1 -1
- package/dist/types/{types-Co4QW1no.d.ts → types-C6OARvDH.d.ts} +79 -2
- package/package.json +3 -2
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Michał Fidor
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -52,7 +52,7 @@ export default defineConfig({
|
|
|
52
52
|
|
|
53
53
|
// Optional
|
|
54
54
|
outputDir: './playswag-coverage',
|
|
55
|
-
outputFormats: ['console', 'json'], //
|
|
55
|
+
outputFormats: ['console', 'json'], // also: 'html', 'badge'
|
|
56
56
|
|
|
57
57
|
threshold: {
|
|
58
58
|
endpoints: 80, // warn / fail if < 80% of endpoints are hit
|
|
@@ -74,6 +74,8 @@ npx playwright test
|
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
Coverage is printed to the terminal and written to `./playswag-coverage/playswag-coverage.json`.
|
|
77
|
+
To also get an interactive HTML report, add `'html'` to `outputFormats` — the reporter will print a
|
|
78
|
+
clickable `file://` link at the end of the run (suppressed when `CI=true`).
|
|
77
79
|
|
|
78
80
|
---
|
|
79
81
|
|
|
@@ -94,7 +96,7 @@ interface PlayswagConfig {
|
|
|
94
96
|
outputDir?: string;
|
|
95
97
|
|
|
96
98
|
/** Which output formats to produce. @default ['console', 'json'] */
|
|
97
|
-
outputFormats?: Array<'console' | 'json'>;
|
|
99
|
+
outputFormats?: Array<'console' | 'json' | 'html' | 'badge'>;
|
|
98
100
|
|
|
99
101
|
/**
|
|
100
102
|
* Base URL of the API under test.
|
|
@@ -111,7 +113,7 @@ interface PlayswagConfig {
|
|
|
111
113
|
consoleOutput?: {
|
|
112
114
|
enabled?: boolean; // @default true
|
|
113
115
|
showUncoveredOnly?: boolean; // @default false
|
|
114
|
-
|
|
116
|
+
showOperations?: boolean; // @default true — per-operation table
|
|
115
117
|
showParams?: boolean; // @default false
|
|
116
118
|
showBodyProperties?: boolean; // @default false
|
|
117
119
|
};
|
|
@@ -122,11 +124,34 @@ interface PlayswagConfig {
|
|
|
122
124
|
pretty?: boolean; // @default true
|
|
123
125
|
};
|
|
124
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Options for the standalone HTML coverage report.
|
|
129
|
+
* Enable by adding 'html' to outputFormats.
|
|
130
|
+
*/
|
|
131
|
+
htmlOutput?: {
|
|
132
|
+
enabled?: boolean; // @default true
|
|
133
|
+
fileName?: string; // @default 'playswag-coverage.html'
|
|
134
|
+
title?: string; // @default 'API Coverage Report'
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Options for the SVG coverage badge.
|
|
139
|
+
* Enable by adding 'badge' to outputFormats.
|
|
140
|
+
*/
|
|
141
|
+
badge?: {
|
|
142
|
+
enabled?: boolean; // @default true
|
|
143
|
+
fileName?: string; // @default 'playswag-badge.svg'
|
|
144
|
+
/** Which coverage dimension drives the badge percentage. */
|
|
145
|
+
dimension?: 'endpoints' | 'statusCodes' | 'parameters' | 'bodyProperties'; // @default 'endpoints'
|
|
146
|
+
label?: string; // @default 'API Coverage'
|
|
147
|
+
};
|
|
148
|
+
|
|
125
149
|
threshold?: {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
150
|
+
// Plain number: informational warning only (respects failOnThreshold globally)
|
|
151
|
+
endpoints?: number | { min: number; fail?: boolean };
|
|
152
|
+
statusCodes?: number | { min: number; fail?: boolean };
|
|
153
|
+
parameters?: number | { min: number; fail?: boolean };
|
|
154
|
+
bodyProperties?: number | { min: number; fail?: boolean };
|
|
130
155
|
};
|
|
131
156
|
|
|
132
157
|
/**
|
|
@@ -152,6 +177,48 @@ projects: [
|
|
|
152
177
|
test.use({ playswagEnabled: false });
|
|
153
178
|
```
|
|
154
179
|
|
|
180
|
+
## Tracking custom request contexts
|
|
181
|
+
|
|
182
|
+
The built-in `request` fixture is wrapped automatically. If your tests use **additional
|
|
183
|
+
`APIRequestContext` instances** — for example contexts created with `request.newContext()`
|
|
184
|
+
or returned by a custom fixture — use the `trackRequest` fixture to wrap them:
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
import { test, expect } from '@michalfidor/playswag';
|
|
188
|
+
|
|
189
|
+
// request.newContext()
|
|
190
|
+
test('uses a second context', async ({ request, trackRequest }) => {
|
|
191
|
+
const adminCtx = trackRequest(await request.newContext({ extraHTTPHeaders: { 'x-role': 'admin' } }));
|
|
192
|
+
const res = await adminCtx.get('/api/admin/stats');
|
|
193
|
+
expect(res.ok()).toBeTruthy();
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
`trackRequest` is most useful inside **custom fixtures** that create their own contexts:
|
|
198
|
+
|
|
199
|
+
```ts
|
|
200
|
+
import { test as base } from '@michalfidor/playswag';
|
|
201
|
+
|
|
202
|
+
const test = base.extend<{ adminRequest: import('@playwright/test').APIRequestContext }>({
|
|
203
|
+
adminRequest: async ({ trackRequest }, use) => {
|
|
204
|
+
const raw = await ContextFactory.getContextByUserAccessToken('admin');
|
|
205
|
+
await use(trackRequest(raw));
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
export { test };
|
|
210
|
+
|
|
211
|
+
// Then in tests:
|
|
212
|
+
test('admin can list users', async ({ adminRequest }) => {
|
|
213
|
+
const res = await adminRequest.get('/api/admin/users');
|
|
214
|
+
expect(res.ok()).toBeTruthy();
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
All calls made through any `trackRequest`-wrapped context are recorded alongside
|
|
219
|
+
calls from the main `request` fixture. They all end up in the same per-test
|
|
220
|
+
attachment and contribute to the coverage report.
|
|
221
|
+
|
|
155
222
|
---
|
|
156
223
|
|
|
157
224
|
## Multiple spec files
|
|
@@ -168,6 +235,61 @@ Duplicate `method + path` entries across files are de-duplicated (last one wins,
|
|
|
168
235
|
|
|
169
236
|
---
|
|
170
237
|
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## HTML report
|
|
241
|
+
|
|
242
|
+
Add `'html'` to `outputFormats` to generate a self-contained, zero-dependency HTML file alongside
|
|
243
|
+
the JSON report:
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
outputFormats: ['console', 'json', 'html'],
|
|
247
|
+
htmlOutput: {
|
|
248
|
+
fileName: 'playswag-coverage.html', // written to outputDir
|
|
249
|
+
title: 'My API Coverage',
|
|
250
|
+
},
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
After the run, the reporter prints a clickable link:
|
|
254
|
+
|
|
255
|
+
```
|
|
256
|
+
[playswag] HTML report → file:///path/to/playswag-coverage/playswag-coverage.html
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
(On CI the `file://` link is omitted; only the relative path is logged.)
|
|
260
|
+
|
|
261
|
+
The report includes:
|
|
262
|
+
- Summary cards with progress bars for all four dimensions
|
|
263
|
+
- Operations table with **All / Covered / Uncovered** filter buttons and per-tag filtering
|
|
264
|
+
- Click any row to expand status codes, parameters, body properties, and the tests that hit it
|
|
265
|
+
- Unmatched hits section (calls that matched no spec operation)
|
|
266
|
+
- Dark / light theme toggle (persisted to `localStorage`)
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## SVG badge
|
|
271
|
+
|
|
272
|
+
Add `'badge'` to `outputFormats` to write a shields.io-style SVG badge:
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
outputFormats: ['console', 'json', 'badge'],
|
|
276
|
+
badge: {
|
|
277
|
+
dimension: 'endpoints', // the percentage shown on the badge
|
|
278
|
+
label: 'API coverage',
|
|
279
|
+
fileName: 'playswag-badge.svg',
|
|
280
|
+
},
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
Commit the badge and embed it in your README:
|
|
284
|
+
|
|
285
|
+
```markdown
|
|
286
|
+

|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Colour thresholds: **green** ≥ 80 % · **orange** ≥ 50 % · **red** < 50 %.
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
171
293
|
## Console output example
|
|
172
294
|
|
|
173
295
|
```
|
|
@@ -193,6 +315,9 @@ Duplicate `method + path` entries across files are de-duplicated (last one wins,
|
|
|
193
315
|
{
|
|
194
316
|
"specFiles": ["./openapi.yaml"],
|
|
195
317
|
"timestamp": "2026-03-04T12:00:00.000Z",
|
|
318
|
+
"playwrightVersion": "1.50.0",
|
|
319
|
+
"playswagVersion": "1.0.0",
|
|
320
|
+
"totalTestCount": 12,
|
|
196
321
|
"summary": {
|
|
197
322
|
"endpoints": { "total": 6, "covered": 5, "percentage": 83.3 },
|
|
198
323
|
"statusCodes": { "total": 11, "covered": 7, "percentage": 63.6 },
|
|
@@ -239,7 +364,7 @@ testInfo.attach( onTestEnd():
|
|
|
239
364
|
onEnd():
|
|
240
365
|
parse OpenAPI spec(s)
|
|
241
366
|
match hits → path templates
|
|
242
|
-
calculate
|
|
367
|
+
calculate 4-dimension coverage
|
|
243
368
|
print console report
|
|
244
369
|
write JSON file
|
|
245
370
|
```
|
package/assets/.gitkeep
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Drop your logo file (logo.png) into this directory. It is referenced from README.md.
|
package/assets/logo.png
ADDED
|
Binary file
|