playwright-api-logger 2.1.0 → 2.3.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 CHANGED
@@ -32,10 +32,11 @@ flowchart LR
32
32
  PR[Proxy over APIRequestContext]
33
33
  AL[ApiLogger]
34
34
  CG[CurlGenerator]
35
+ RP["ApiLoggerReporter<br/>(merge + summary)"]
35
36
  end
36
37
 
37
38
  subgraph O[Output]
38
- LOG["logs/TEST_*.log<br/>request, response, curl, duration"]
39
+ LOG["logs/*.log<br/>structured JSON per test"]
39
40
  RC[Ready-to-use curl for Postman / terminal]
40
41
  end
41
42
 
@@ -43,8 +44,9 @@ flowchart LR
43
44
  W --> PR
44
45
  C --> PR
45
46
  PR --> AL
46
- AL --> LOG
47
47
  AL --> CG
48
+ AL -->|"raw files"| RP
49
+ RP -->|"merged"| LOG
48
50
  CG --> RC
49
51
  ```
50
52
 
@@ -56,6 +58,7 @@ API_LOGS=false → Logging OFF (zero overhead, default)
56
58
  ## Features
57
59
 
58
60
  - **One-line integration** — just wrap `request` with `withApiLogging()`, zero changes to controllers/clients
61
+ - **Playwright Reporter** — auto-merges related log files (when `titlePath`/`file` are set), prints summary
59
62
  - **Structured logs** — one JSON document per test with `preconditions`, `steps`, and `teardown` sections
60
63
  - **Step descriptions** — describe what each API call does with `.describe()`
61
64
  - **Curl Export** — copy from log, paste into terminal or import into Postman
@@ -78,34 +81,111 @@ npm install playwright-api-logger
78
81
  import { withApiLogging } from 'playwright-api-logger';
79
82
 
80
83
  export const test = base.extend({
81
- apiClient: async ({ request }, use, testInfo) => {
82
- const loggedRequest = withApiLogging(request, testInfo);
83
- const apiClient = new ApiClient(loggedRequest);
84
- await use(apiClient);
85
- loggedRequest.__logger.finalize(
84
+ loggedRequest: async ({ request }, use, testInfo) => {
85
+ const logged = withApiLogging(request, testInfo);
86
+ await use(logged);
87
+ logged.__logger.finalize(
86
88
  testInfo.status === 'passed' ? 'PASSED' : 'FAILED'
87
89
  );
88
90
  },
91
+ apiClient: async ({ loggedRequest }, use) => {
92
+ await use(new ApiClient(loggedRequest));
93
+ },
89
94
  });
90
95
  ```
91
96
 
92
97
  No changes to your controllers, clients, or test files.
93
98
 
99
+ ### Add the Reporter (recommended)
100
+
101
+ Add the reporter to `playwright.config.ts` for automatic log merging and summary:
102
+
103
+ ```typescript
104
+ // playwright.config.ts
105
+ import { defineConfig } from '@playwright/test';
106
+
107
+ export default defineConfig({
108
+ reporter: [
109
+ ['list'],
110
+ ['playwright-api-logger/reporter']
111
+ ],
112
+ // ...
113
+ });
114
+ ```
115
+
116
+ The reporter will:
117
+ - **Auto-merge** related log files from `beforeAll` + `test` + `afterAll` into one structured document. For merge to work, log files must have `test.file` and `test.titlePath` (≥3 elements). Hooks don't receive `testInfo` — pass these manually, e.g. via `withApiLogging(request, { sharedKey, testFile, titlePath, context })`.
118
+ - **Print summary** after the test run (number of log files, total API requests, duration)
119
+
120
+ ```
121
+ [playwright-api-logger] 5 log files, 23 API requests (4.2s)
122
+ [playwright-api-logger] Logs: /path/to/project/logs
123
+ ```
124
+
125
+ Reporter options:
126
+
127
+ ```typescript
128
+ ['playwright-api-logger/reporter', {
129
+ logDirectory: 'custom-logs', // default: 'logs'
130
+ merge: true, // auto-merge related files (default: true)
131
+ printSummary: true, // print summary at end (default: true)
132
+ }]
133
+ ```
134
+
135
+ ### Merge with beforeAll/afterAll hooks
136
+
137
+ Two patterns:
138
+
139
+ **A) Reporter merge** — separate loggers produce separate files; Reporter merges them when they share `testFile` and `titlePath` (≥3 elements). Each logger (including in hooks) must set these:
140
+
141
+ ```typescript
142
+ test.beforeAll(async ({ request }) => {
143
+ const logged = withApiLogging(request, {
144
+ testName: 'Setup',
145
+ testFile: 'tests/api/users.spec.ts',
146
+ titlePath: ['', 'Users API', 'Setup'],
147
+ context: 'preconditions',
148
+ });
149
+ // ... use logged, finalize in afterAll
150
+ });
151
+ ```
152
+
153
+ **B) sharedKey** — one logger instance shared across hooks + test via `getSharedLogger` / `LoggerRegistry`. Produces one file per group; Reporter merge is not used.
154
+
94
155
  ### With preconditions and step descriptions
95
156
 
157
+ Expose `loggedRequest` as a fixture to access the logger in tests:
158
+
159
+ ```typescript
160
+ // fixtures.ts
161
+ export const test = base.extend({
162
+ loggedRequest: async ({ request }, use, testInfo) => {
163
+ const logged = withApiLogging(request, testInfo);
164
+ await use(logged);
165
+ logged.__logger.finalize(
166
+ testInfo.status === 'passed' ? 'PASSED' : 'FAILED'
167
+ );
168
+ },
169
+ apiClient: async ({ loggedRequest }, use) => {
170
+ await use(new ApiClient(loggedRequest));
171
+ },
172
+ });
173
+ ```
174
+
96
175
  ```typescript
97
- test('GET Without token (401)', async ({ apiClient, request }) => {
98
- const loggedRequest = (request as any).__logger as ApiLogger;
176
+ // test file
177
+ test('GET Without token (401)', async ({ apiClient, loggedRequest }) => {
178
+ const logger = loggedRequest.__logger;
99
179
 
100
180
  // Mark following calls as preconditions
101
- loggedRequest.startPreconditions();
102
- loggedRequest.describe('Get employee ID for test');
181
+ logger.startPreconditions();
182
+ logger.describe('Get employee ID for test');
103
183
  const employees = await apiClient.getEmployees({ page: 1, size: 1 });
104
184
  const employeeId = employees.items[0].id;
105
185
 
106
186
  // Switch to test steps
107
- loggedRequest.startTest();
108
- loggedRequest.describe('Get children without auth token');
187
+ logger.startTest();
188
+ logger.describe('Get children without auth token');
109
189
  const response = await apiClient.getChildrenWithoutAuth(employeeId);
110
190
  expect(response.status).toBe(401);
111
191
  });
@@ -123,6 +203,111 @@ API_LOGS=false
123
203
  API_LOGS=true npx playwright test
124
204
  ```
125
205
 
206
+ ### Try the demo (this repo)
207
+
208
+ Run the demo test to see log files in `logs/`:
209
+
210
+ ```bash
211
+ npm run test:demo
212
+ ```
213
+
214
+ Creates `logs/demo-api-calls_*.log` — inspect the structured JSON output.
215
+
216
+ ## Usage variants
217
+
218
+ | Variant | When to use |
219
+ |---------|--------------|
220
+ | **Fixture** | Recommended for projects — one setup, `loggedRequest` in every test |
221
+ | **Direct in test** | Demo, one-off tests, custom options |
222
+ | **Options object** | Hooks (no `testInfo`), custom `logDirectory`, `sharedKey` |
223
+ | **Factory functions** | Standalone logger without request proxy (e.g. custom clients) |
224
+ | **LoggerRegistry** | Advanced: shared logger across hooks via `getSharedLogger` / `finalizeSharedLogger` |
225
+
226
+ ### 1. Fixture (recommended)
227
+
228
+ ```typescript
229
+ export const test = base.extend({
230
+ loggedRequest: async ({ request }, use, testInfo) => {
231
+ const logged = withApiLogging(request, testInfo);
232
+ await use(logged);
233
+ logged.__logger.finalize(testInfo.status === 'passed' ? 'PASSED' : 'FAILED');
234
+ },
235
+ });
236
+ ```
237
+
238
+ ### 2. Direct in test
239
+
240
+ Call `withApiLogging()` inside the test body. Useful for demos or when you need custom options:
241
+
242
+ ```typescript
243
+ test('my API test', async ({ request }) => {
244
+ const logged = withApiLogging(request, {
245
+ testName: 'My API test',
246
+ testFile: 'tests/api.spec.ts',
247
+ titlePath: ['', 'API', 'my API test'],
248
+ logDirectory: 'logs',
249
+ });
250
+
251
+ await logged.get('https://api.example.com/users');
252
+ logged.__logger.finalize('PASSED');
253
+ });
254
+ ```
255
+
256
+ ### 3. Options instead of testInfo
257
+
258
+ Pass `ApiLoggingOptions` when `testInfo` is not available (e.g. in `beforeAll`/`afterAll`):
259
+
260
+ ```typescript
261
+ // Hooks don't receive testInfo — pass options manually
262
+ test.beforeAll(async ({ request }) => {
263
+ const logged = withApiLogging(request, {
264
+ sharedKey: 'my-suite',
265
+ testName: 'Setup',
266
+ testFile: 'tests/api/users.spec.ts',
267
+ titlePath: ['', 'Users API', 'Setup'],
268
+ context: 'preconditions',
269
+ logDirectory: 'logs',
270
+ });
271
+ // ... use logged
272
+ });
273
+ ```
274
+
275
+ ### 4. Factory functions
276
+
277
+ Create a standalone `ApiLogger` without wrapping a request. Use when you have a custom API client that accepts a logger:
278
+
279
+ ```typescript
280
+ import { createApiLogger, createSetupLogger, createTeardownLogger } from 'playwright-api-logger';
281
+
282
+ // Test context (default)
283
+ const logger = createApiLogger('my-test');
284
+
285
+ // Preconditions context
286
+ const setupLogger = createSetupLogger('setup-test');
287
+
288
+ // Teardown context
289
+ const teardownLogger = createTeardownLogger('teardown-test');
290
+
291
+ // Use with custom client
292
+ logger.logApiCall('GET', url, headers, body, status, ...);
293
+ logger.finalize('PASSED');
294
+ ```
295
+
296
+ ### 5. LoggerRegistry (advanced)
297
+
298
+ For shared logger across `beforeAll` / `test` / `afterAll` without using `withApiLogging`:
299
+
300
+ ```typescript
301
+ import { getSharedLogger, finalizeSharedLogger } from 'playwright-api-logger';
302
+
303
+ const key = 'my-describe-block';
304
+ const logger = getSharedLogger(key, { testName: 'My Test', logDirectory: 'logs' });
305
+ // ... make API calls via your client
306
+ finalizeSharedLogger(key, 'PASSED');
307
+ ```
308
+
309
+ Or use `sharedKey` in `withApiLogging` — it uses `LoggerRegistry` internally.
310
+
126
311
  ## Log Output
127
312
 
128
313
  One structured JSON document per test:
@@ -140,6 +325,7 @@ logs/
140
325
  "test": {
141
326
  "name": "GET Without token (401)",
142
327
  "file": "tests/api/employees/children.spec.ts",
328
+ "titlePath": ["", "GET /api/v1/employees/{id}/children", "GET Without token (401)"],
143
329
  "startedAt": "2026-03-16T18:33:03.654Z",
144
330
  "finishedAt": "2026-03-16T18:33:04.300Z",
145
331
  "duration": 646,
@@ -196,9 +382,24 @@ logs/
196
382
 
197
383
  Main integration point. Wraps `APIRequestContext` with a Proxy that logs all HTTP calls.
198
384
 
385
+ **Arguments:**
386
+ - `request` — Playwright `APIRequestContext`
387
+ - `testInfoOrOptions` — `TestInfo` (auto-extracts `title`, `file`, `titlePath`) or `ApiLoggingOptions`
388
+
199
389
  ```typescript
390
+ // With testInfo (from fixture)
200
391
  const loggedRequest = withApiLogging(request, testInfo);
201
- loggedRequest.__logger // access the ApiLogger instance
392
+
393
+ // With options (hooks, custom config)
394
+ const loggedRequest = withApiLogging(request, {
395
+ testName: 'My Test',
396
+ testFile: 'tests/api.spec.ts',
397
+ titlePath: ['', 'Suite', 'My Test'],
398
+ logDirectory: 'logs',
399
+ sharedKey: 'my-suite', // for beforeAll/test/afterAll
400
+ });
401
+
402
+ loggedRequest.__logger // access the ApiLogger instance
202
403
  ```
203
404
 
204
405
  ### `ApiLogger` — context & description
@@ -214,6 +415,20 @@ loggedRequest.__logger // access the ApiLogger instance
214
415
  | `isEnabled()` | Check if logging is active |
215
416
  | `getLogFilePath()` | Get current log file path |
216
417
 
418
+ ### `ApiLoggerReporter` — Playwright Reporter
419
+
420
+ Auto-merges related log files and prints summary. Add to `playwright.config.ts`:
421
+
422
+ ```typescript
423
+ reporter: [['list'], ['playwright-api-logger/reporter']]
424
+ ```
425
+
426
+ | Option | Default | Description |
427
+ |--------|---------|-------------|
428
+ | `logDirectory` | `'logs'` | Directory for log files |
429
+ | `merge` | `true` | Auto-merge related log files by describe block |
430
+ | `printSummary` | `true` | Print API request summary after test run |
431
+
217
432
  ### `CurlGenerator`
218
433
 
219
434
  | Method | Description |
@@ -232,13 +447,32 @@ loggedRequest.__logger // access the ApiLogger instance
232
447
  {
233
448
  testName?: string; // Test name (default: 'unknown-test')
234
449
  testFile?: string; // Test file path
235
- context?: LogContext; // 'preconditions' | 'test' | 'teardown'
236
- logDirectory?: string; // Custom log dir (default: 'logs/')
237
- maskAuthTokens?: boolean; // Mask auth headers (default: true)
238
- logger?: ApiLogger; // Share logger across phases
450
+ titlePath?: string[]; // Test hierarchy path (auto-detected from testInfo)
451
+ context?: LogContext; // 'preconditions' | 'test' | 'teardown'
452
+ logDirectory?: string; // Custom log dir (default: 'logs/')
453
+ maskAuthTokens?: boolean; // Mask auth headers (default: true)
454
+ logger?: ApiLogger; // Reuse existing logger instance
455
+ sharedKey?: string; // Same key in beforeAll/test/afterAll → one log file
239
456
  }
240
457
  ```
241
458
 
459
+ ### Factory functions
460
+
461
+ | Function | Description |
462
+ |----------|-------------|
463
+ | `createApiLogger(testName, contextOrConfig?)` | Create logger with test context. Second arg: `LogContext` ('preconditions'\|'test'\|'teardown') or `Partial<LoggerConfig>` (e.g. `{ logDirectory }`) |
464
+ | `createSetupLogger(testName, config?)` | Create logger with `preconditions` context. Optional `config` (e.g. `{ logDirectory }`) |
465
+ | `createTeardownLogger(testName, config?)` | Create logger with `teardown` context. Optional `config` (e.g. `{ logDirectory }`) |
466
+
467
+ ### LoggerRegistry
468
+
469
+ | Function | Description |
470
+ |----------|-------------|
471
+ | `getSharedLogger(key, config)` | Get or create shared logger by key |
472
+ | `finalizeSharedLogger(key, result, info?)` | Write log and remove from registry |
473
+ | `hasSharedLogger(key)` | Check if logger exists |
474
+ | `removeSharedLogger(key)` | Remove without finalizing |
475
+
242
476
  ## Migration from v1 → v2
243
477
 
244
478
  ```diff
@@ -15,6 +15,7 @@ export declare class ApiLogger {
15
15
  private enabled;
16
16
  private testName;
17
17
  private testFile?;
18
+ private titlePath?;
18
19
  private currentContext;
19
20
  private logDirectory;
20
21
  private logFilePath;
@@ -74,14 +75,15 @@ export declare class ApiLogger {
74
75
  }
75
76
  /**
76
77
  * Factory function for creating test-context loggers
78
+ * @param contextOrConfig - LogContext ('preconditions'|'test'|'teardown') or Partial<LoggerConfig>
77
79
  */
78
- export declare function createApiLogger(testName: string, context?: LogContext): ApiLogger;
80
+ export declare function createApiLogger(testName: string, contextOrConfig?: LogContext | Partial<LoggerConfig>): ApiLogger;
79
81
  /**
80
82
  * Factory for setup/preconditions context
81
83
  */
82
- export declare function createSetupLogger(testName: string): ApiLogger;
84
+ export declare function createSetupLogger(testName: string, config?: Partial<LoggerConfig>): ApiLogger;
83
85
  /**
84
86
  * Factory for teardown context
85
87
  */
86
- export declare function createTeardownLogger(testName: string): ApiLogger;
88
+ export declare function createTeardownLogger(testName: string, config?: Partial<LoggerConfig>): ApiLogger;
87
89
  //# sourceMappingURL=ApiLogger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ApiLogger.d.ts","sourceRoot":"","sources":["../src/ApiLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EACL,UAAU,EACV,YAAY,EAKb,MAAM,SAAS,CAAC;AAEjB,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,aAAa,CAAsB;IAG3C,OAAO,CAAC,eAAe,CAAC,CAAS;gBAErB,MAAM,GAAE,YAAiB;IAerC,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,iBAAiB;IAgBzB;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAInC;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAIrC;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,SAAS,IAAI,IAAI;IAIjB;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,UAAU,CACR,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,SAAS,EAC7D,WAAW,EAAE,GAAG,EAChB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACnD,YAAY,EAAE,GAAG,EACjB,QAAQ,EAAE,MAAM,GACf,IAAI;IAuDP;;OAEG;IACH,OAAO,CAAC,cAAc;IAYtB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAyC7F;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IASxB,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B,SAAS,IAAI,OAAO;CAGrB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,UAAmB,GAAG,SAAS,CAEzF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAE7D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAEhE"}
1
+ {"version":3,"file":"ApiLogger.d.ts","sourceRoot":"","sources":["../src/ApiLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EACL,UAAU,EACV,YAAY,EAKb,MAAM,SAAS,CAAC;AAEjB,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAC,CAAW;IAC7B,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,SAAS,CAAS;IAG1B,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,aAAa,CAAsB;IAG3C,OAAO,CAAC,eAAe,CAAC,CAAS;gBAErB,MAAM,GAAE,YAAiB;IAgBrC,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,iBAAiB;IAgBzB;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAInC;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAIrC;;OAEG;IACH,kBAAkB,IAAI,IAAI;IAI1B;;OAEG;IACH,SAAS,IAAI,IAAI;IAIjB;;OAEG;IACH,aAAa,IAAI,IAAI;IAIrB;;OAEG;IACH,UAAU,CACR,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,SAAS,EAC7D,WAAW,EAAE,GAAG,EAChB,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EACnD,YAAY,EAAE,GAAG,EACjB,QAAQ,EAAE,MAAM,GACf,IAAI;IAuDP;;OAEG;IACH,OAAO,CAAC,cAAc;IAYtB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IA0C7F;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,gBAAgB;IASxB,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B,SAAS,IAAI,OAAO;CAGrB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,eAAe,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,GACnD,SAAS,CASX;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC7B,SAAS,CAEX;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC7B,SAAS,CAEX"}
package/dist/ApiLogger.js CHANGED
@@ -32,6 +32,7 @@ class ApiLogger {
32
32
  this.enabled = process.env.API_LOGS === 'true';
33
33
  this.testName = config.testName || 'unknown-test';
34
34
  this.testFile = config.testFile;
35
+ this.titlePath = config.titlePath;
35
36
  this.currentContext = config.context || 'test';
36
37
  this.logDirectory = config.logDirectory || this.getDefaultLogDirectory();
37
38
  this.maskAuthTokens = config.maskAuthTokens ?? true;
@@ -174,6 +175,7 @@ class ApiLogger {
174
175
  test: {
175
176
  name: this.testName,
176
177
  file: this.testFile || additionalInfo?.testFile,
178
+ titlePath: this.titlePath || additionalInfo?.titlePath,
177
179
  startedAt: this.startedAt,
178
180
  finishedAt,
179
181
  duration: endTime - startTime,
@@ -234,20 +236,27 @@ class ApiLogger {
234
236
  exports.ApiLogger = ApiLogger;
235
237
  /**
236
238
  * Factory function for creating test-context loggers
239
+ * @param contextOrConfig - LogContext ('preconditions'|'test'|'teardown') or Partial<LoggerConfig>
237
240
  */
238
- function createApiLogger(testName, context = 'test') {
239
- return new ApiLogger({ testName, context });
241
+ function createApiLogger(testName, contextOrConfig) {
242
+ const isContext = (x) => x === 'preconditions' || x === 'test' || x === 'teardown';
243
+ const config = !contextOrConfig
244
+ ? { testName, context: 'test' }
245
+ : isContext(contextOrConfig)
246
+ ? { testName, context: contextOrConfig }
247
+ : { testName, context: 'test', ...contextOrConfig };
248
+ return new ApiLogger(config);
240
249
  }
241
250
  /**
242
251
  * Factory for setup/preconditions context
243
252
  */
244
- function createSetupLogger(testName) {
245
- return new ApiLogger({ testName, context: 'preconditions' });
253
+ function createSetupLogger(testName, config) {
254
+ return new ApiLogger({ testName, ...config, context: 'preconditions' });
246
255
  }
247
256
  /**
248
257
  * Factory for teardown context
249
258
  */
250
- function createTeardownLogger(testName) {
251
- return new ApiLogger({ testName, context: 'teardown' });
259
+ function createTeardownLogger(testName, config) {
260
+ return new ApiLogger({ testName, ...config, context: 'teardown' });
252
261
  }
253
262
  //# sourceMappingURL=ApiLogger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ApiLogger.js","sourceRoot":"","sources":["../src/ApiLogger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ApiLogger.js","sourceRoot":"","sources":["../src/ApiLogger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Global registry for sharing ApiLogger instances across
3
+ * beforeAll / test / afterAll in a Playwright test.describe block.
4
+ *
5
+ * Solves the problem: Playwright creates separate fixture instances
6
+ * for beforeAll, each test(), and afterAll — without a shared store
7
+ * each gets its own logger and writes a separate file.
8
+ *
9
+ * With LoggerRegistry, all phases write to the SAME structured log.
10
+ */
11
+ import { ApiLogger } from './ApiLogger';
12
+ import { LoggerConfig } from './types';
13
+ /**
14
+ * Get or create a shared logger by key.
15
+ * First call creates the logger, subsequent calls return the same instance.
16
+ *
17
+ * @param key - Unique key for the logger (e.g. describe block name)
18
+ * @param config - Logger config (only used on first call when creating)
19
+ * @returns Shared ApiLogger instance
20
+ *
21
+ * @example
22
+ * test.describe('GET /api/v1/employees', () => {
23
+ * const LOG_KEY = 'get-employees';
24
+ *
25
+ * test.beforeAll(async ({ apiClient }) => {
26
+ * const logger = getSharedLogger(LOG_KEY, { testName: 'GET employees' });
27
+ * logger.startPreconditions();
28
+ * // ... apiClient calls logged to preconditions
29
+ * });
30
+ *
31
+ * test('should return 200', async ({ apiClient }) => {
32
+ * const logger = getSharedLogger(LOG_KEY);
33
+ * logger.startTest();
34
+ * // ... apiClient calls logged to steps
35
+ * });
36
+ *
37
+ * test.afterAll(() => {
38
+ * finalizeSharedLogger(LOG_KEY, 'PASSED');
39
+ * });
40
+ * });
41
+ */
42
+ export declare function getSharedLogger(key: string, config?: LoggerConfig): ApiLogger;
43
+ /**
44
+ * Finalize a shared logger: write the structured document and remove from registry.
45
+ *
46
+ * @param key - The logger key used in getSharedLogger()
47
+ * @param result - Test result: 'PASSED' | 'FAILED' | 'SKIPPED'
48
+ * @param additionalInfo - Optional extra info to include
49
+ */
50
+ export declare function finalizeSharedLogger(key: string, result: 'PASSED' | 'FAILED' | 'SKIPPED', additionalInfo?: Record<string, any>): void;
51
+ /**
52
+ * Check if a shared logger exists for the given key.
53
+ */
54
+ export declare function hasSharedLogger(key: string): boolean;
55
+ /**
56
+ * Remove a shared logger without finalizing (cleanup).
57
+ */
58
+ export declare function removeSharedLogger(key: string): void;
59
+ //# sourceMappingURL=LoggerRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoggerRegistry.d.ts","sourceRoot":"","sources":["../src/LoggerRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAIvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,YAAY,GAAG,SAAS,CAK7E;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,EACvC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACnC,IAAI,CAMN;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAEpD"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /**
3
+ * Global registry for sharing ApiLogger instances across
4
+ * beforeAll / test / afterAll in a Playwright test.describe block.
5
+ *
6
+ * Solves the problem: Playwright creates separate fixture instances
7
+ * for beforeAll, each test(), and afterAll — without a shared store
8
+ * each gets its own logger and writes a separate file.
9
+ *
10
+ * With LoggerRegistry, all phases write to the SAME structured log.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.getSharedLogger = getSharedLogger;
14
+ exports.finalizeSharedLogger = finalizeSharedLogger;
15
+ exports.hasSharedLogger = hasSharedLogger;
16
+ exports.removeSharedLogger = removeSharedLogger;
17
+ const ApiLogger_1 = require("./ApiLogger");
18
+ const registry = new Map();
19
+ /**
20
+ * Get or create a shared logger by key.
21
+ * First call creates the logger, subsequent calls return the same instance.
22
+ *
23
+ * @param key - Unique key for the logger (e.g. describe block name)
24
+ * @param config - Logger config (only used on first call when creating)
25
+ * @returns Shared ApiLogger instance
26
+ *
27
+ * @example
28
+ * test.describe('GET /api/v1/employees', () => {
29
+ * const LOG_KEY = 'get-employees';
30
+ *
31
+ * test.beforeAll(async ({ apiClient }) => {
32
+ * const logger = getSharedLogger(LOG_KEY, { testName: 'GET employees' });
33
+ * logger.startPreconditions();
34
+ * // ... apiClient calls logged to preconditions
35
+ * });
36
+ *
37
+ * test('should return 200', async ({ apiClient }) => {
38
+ * const logger = getSharedLogger(LOG_KEY);
39
+ * logger.startTest();
40
+ * // ... apiClient calls logged to steps
41
+ * });
42
+ *
43
+ * test.afterAll(() => {
44
+ * finalizeSharedLogger(LOG_KEY, 'PASSED');
45
+ * });
46
+ * });
47
+ */
48
+ function getSharedLogger(key, config) {
49
+ if (!registry.has(key)) {
50
+ registry.set(key, new ApiLogger_1.ApiLogger(config));
51
+ }
52
+ return registry.get(key);
53
+ }
54
+ /**
55
+ * Finalize a shared logger: write the structured document and remove from registry.
56
+ *
57
+ * @param key - The logger key used in getSharedLogger()
58
+ * @param result - Test result: 'PASSED' | 'FAILED' | 'SKIPPED'
59
+ * @param additionalInfo - Optional extra info to include
60
+ */
61
+ function finalizeSharedLogger(key, result, additionalInfo) {
62
+ const logger = registry.get(key);
63
+ if (logger) {
64
+ logger.finalize(result, additionalInfo);
65
+ registry.delete(key);
66
+ }
67
+ }
68
+ /**
69
+ * Check if a shared logger exists for the given key.
70
+ */
71
+ function hasSharedLogger(key) {
72
+ return registry.has(key);
73
+ }
74
+ /**
75
+ * Remove a shared logger without finalizing (cleanup).
76
+ */
77
+ function removeSharedLogger(key) {
78
+ registry.delete(key);
79
+ }
80
+ //# sourceMappingURL=LoggerRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoggerRegistry.js","sourceRoot":"","sources":["../src/LoggerRegistry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAoCH,0CAKC;AASD,oDAUC;AAKD,0CAEC;AAKD,gDAEC;AAxED,2CAAwC;AAGxC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,SAAgB,eAAe,CAAC,GAAW,EAAE,MAAqB;IAChE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,qBAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;AAC5B,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,oBAAoB,CAClC,GAAW,EACX,MAAuC,EACvC,cAAoC;IAEpC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QACxC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,GAAW;IACzC,OAAO,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAAC,GAAW;IAC5C,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  export { ApiLogger, createApiLogger, createSetupLogger, createTeardownLogger } from './ApiLogger';
2
2
  export { CurlGenerator } from './CurlGenerator';
3
3
  export { withApiLogging } from './withApiLogging';
4
+ export { getSharedLogger, finalizeSharedLogger, hasSharedLogger, removeSharedLogger } from './LoggerRegistry';
5
+ export { default as ApiLoggerReporter } from './reporter';
4
6
  export type { ApiLoggingOptions } from './withApiLogging';
7
+ export type { ApiLoggerReporterOptions } from './reporter';
5
8
  export type { LoggerConfig, RequestLogData, ResponseLogData, StepLogEntry, TestLogDocument, LogEntry, LogContext, } from './types';
6
9
  export type { RequestData } from './CurlGenerator';
7
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EACV,YAAY,EACZ,cAAc,EACd,eAAe,EACf,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAClG,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC9G,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,YAAY,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EACV,YAAY,EACZ,cAAc,EACd,eAAe,EACf,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,UAAU,GACX,MAAM,SAAS,CAAC;AACjB,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.withApiLogging = exports.CurlGenerator = exports.createTeardownLogger = exports.createSetupLogger = exports.createApiLogger = exports.ApiLogger = void 0;
6
+ exports.ApiLoggerReporter = exports.removeSharedLogger = exports.hasSharedLogger = exports.finalizeSharedLogger = exports.getSharedLogger = exports.withApiLogging = exports.CurlGenerator = exports.createTeardownLogger = exports.createSetupLogger = exports.createApiLogger = exports.ApiLogger = void 0;
4
7
  var ApiLogger_1 = require("./ApiLogger");
5
8
  Object.defineProperty(exports, "ApiLogger", { enumerable: true, get: function () { return ApiLogger_1.ApiLogger; } });
6
9
  Object.defineProperty(exports, "createApiLogger", { enumerable: true, get: function () { return ApiLogger_1.createApiLogger; } });
@@ -10,4 +13,11 @@ var CurlGenerator_1 = require("./CurlGenerator");
10
13
  Object.defineProperty(exports, "CurlGenerator", { enumerable: true, get: function () { return CurlGenerator_1.CurlGenerator; } });
11
14
  var withApiLogging_1 = require("./withApiLogging");
12
15
  Object.defineProperty(exports, "withApiLogging", { enumerable: true, get: function () { return withApiLogging_1.withApiLogging; } });
16
+ var LoggerRegistry_1 = require("./LoggerRegistry");
17
+ Object.defineProperty(exports, "getSharedLogger", { enumerable: true, get: function () { return LoggerRegistry_1.getSharedLogger; } });
18
+ Object.defineProperty(exports, "finalizeSharedLogger", { enumerable: true, get: function () { return LoggerRegistry_1.finalizeSharedLogger; } });
19
+ Object.defineProperty(exports, "hasSharedLogger", { enumerable: true, get: function () { return LoggerRegistry_1.hasSharedLogger; } });
20
+ Object.defineProperty(exports, "removeSharedLogger", { enumerable: true, get: function () { return LoggerRegistry_1.removeSharedLogger; } });
21
+ var reporter_1 = require("./reporter");
22
+ Object.defineProperty(exports, "ApiLoggerReporter", { enumerable: true, get: function () { return __importDefault(reporter_1).default; } });
13
23
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAAkG;AAAzF,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,iHAAA,oBAAoB,OAAA;AAC5E,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,yCAAkG;AAAzF,sGAAA,SAAS,OAAA;AAAE,4GAAA,eAAe,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,iHAAA,oBAAoB,OAAA;AAC5E,iDAAgD;AAAvC,8GAAA,aAAa,OAAA;AACtB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,mDAA8G;AAArG,iHAAA,eAAe,OAAA;AAAE,sHAAA,oBAAoB,OAAA;AAAE,iHAAA,eAAe,OAAA;AAAE,oHAAA,kBAAkB,OAAA;AACnF,uCAA0D;AAAjD,8HAAA,OAAO,OAAqB"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Playwright Reporter for playwright-api-logger
3
+ *
4
+ * Automatically merges related log files (e.g. from beforeAll + test + afterAll)
5
+ * into a single structured document per test group.
6
+ *
7
+ * Usage in playwright.config.ts:
8
+ * ```typescript
9
+ * reporter: [
10
+ * ['list'],
11
+ * ['playwright-api-logger/reporter', { logDirectory: 'logs' }]
12
+ * ]
13
+ * ```
14
+ */
15
+ import type { Reporter, FullConfig, Suite, FullResult } from '@playwright/test/reporter';
16
+ export interface ApiLoggerReporterOptions {
17
+ /** Log directory (default: 'logs') */
18
+ logDirectory?: string;
19
+ /** Merge related log files from same describe block (default: true) */
20
+ merge?: boolean;
21
+ /** Print summary after test run (default: true) */
22
+ printSummary?: boolean;
23
+ }
24
+ declare class ApiLoggerReporter implements Reporter {
25
+ private logDirectory;
26
+ private merge;
27
+ private printSummary;
28
+ constructor(options?: ApiLoggerReporterOptions);
29
+ /**
30
+ * Ensure log directory exists before tests start
31
+ */
32
+ onBegin(_config: FullConfig, _suite: Suite): void;
33
+ /**
34
+ * Post-process log files: merge related files, print summary
35
+ */
36
+ onEnd(_result: FullResult): void;
37
+ /**
38
+ * Scan log directory, group related files by describe block, merge into single documents
39
+ */
40
+ private mergeRelatedLogs;
41
+ /**
42
+ * Read and parse all .log files from the log directory
43
+ */
44
+ private readLogFiles;
45
+ /**
46
+ * Group log files by their describe block path.
47
+ * Files from the same test file + same describe block → same group.
48
+ *
49
+ * Only groups files that have titlePath with at least 3 elements
50
+ * (project + describe + test name), otherwise they're standalone tests.
51
+ */
52
+ private groupByDescribeBlock;
53
+ /**
54
+ * Merge a group of related log files into a single structured document.
55
+ *
56
+ * Strategy:
57
+ * - Sort files by startedAt timestamp
58
+ * - First file's steps → preconditions section
59
+ * - Middle files' steps → test steps section
60
+ * - Last file's steps → teardown section
61
+ * - If only 2 files: first → preconditions, second → steps
62
+ * - Note: Per-document section assignments (preconditions/steps/teardown) are
63
+ * flattened and reassigned by file order; manual context in a single file
64
+ * is not preserved when merging.
65
+ */
66
+ private mergeGroup;
67
+ /**
68
+ * Collect all steps from a log document (from all sections)
69
+ */
70
+ private collectAllSteps;
71
+ /**
72
+ * Re-number step entries sequentially
73
+ */
74
+ private renumberSteps;
75
+ /**
76
+ * Determine the overall result for a group of log files.
77
+ * FAILED wins over PASSED, PASSED wins over SKIPPED.
78
+ */
79
+ private resolveGroupResult;
80
+ /**
81
+ * Print a summary of log files after the test run
82
+ */
83
+ private logSummary;
84
+ }
85
+ export default ApiLoggerReporter;
86
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,KAAK,EACL,UAAU,EACX,MAAM,2BAA2B,CAAC;AAGnC,MAAM,WAAW,wBAAwB;IACvC,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mDAAmD;IACnD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAQD,cAAM,iBAAkB,YAAW,QAAQ;IACzC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,YAAY,CAAU;gBAElB,OAAO,GAAE,wBAA6B;IAQlD;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,GAAG,IAAI;IAUjD;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAahC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAwBxB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6BpB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IA2B5B;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,UAAU;IAgGlB;;OAEG;IACH,OAAO,CAAC,eAAe;IAQvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,UAAU;CAuCnB;AAED,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ /**
3
+ * Playwright Reporter for playwright-api-logger
4
+ *
5
+ * Automatically merges related log files (e.g. from beforeAll + test + afterAll)
6
+ * into a single structured document per test group.
7
+ *
8
+ * Usage in playwright.config.ts:
9
+ * ```typescript
10
+ * reporter: [
11
+ * ['list'],
12
+ * ['playwright-api-logger/reporter', { logDirectory: 'logs' }]
13
+ * ]
14
+ * ```
15
+ */
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ const fs_1 = __importDefault(require("fs"));
21
+ const path_1 = __importDefault(require("path"));
22
+ class ApiLoggerReporter {
23
+ constructor(options = {}) {
24
+ this.logDirectory = options.logDirectory
25
+ ? path_1.default.resolve(options.logDirectory)
26
+ : path_1.default.join(process.cwd(), 'logs');
27
+ this.merge = options.merge !== false;
28
+ this.printSummary = options.printSummary !== false;
29
+ }
30
+ /**
31
+ * Ensure log directory exists before tests start
32
+ */
33
+ onBegin(_config, _suite) {
34
+ try {
35
+ if (!fs_1.default.existsSync(this.logDirectory)) {
36
+ fs_1.default.mkdirSync(this.logDirectory, { recursive: true });
37
+ }
38
+ }
39
+ catch {
40
+ // Ignore — ApiLogger will also try to create it
41
+ }
42
+ }
43
+ /**
44
+ * Post-process log files: merge related files, print summary
45
+ */
46
+ onEnd(_result) {
47
+ try {
48
+ if (this.merge) {
49
+ this.mergeRelatedLogs();
50
+ }
51
+ if (this.printSummary) {
52
+ this.logSummary();
53
+ }
54
+ }
55
+ catch (error) {
56
+ console.warn('[playwright-api-logger] Reporter error:', error);
57
+ }
58
+ }
59
+ /**
60
+ * Scan log directory, group related files by describe block, merge into single documents
61
+ */
62
+ mergeRelatedLogs() {
63
+ if (!fs_1.default.existsSync(this.logDirectory))
64
+ return;
65
+ const logFiles = this.readLogFiles();
66
+ if (logFiles.length === 0)
67
+ return;
68
+ // Group files by describe block (file + titlePath prefix)
69
+ const groups = this.groupByDescribeBlock(logFiles);
70
+ // Merge groups that have multiple files
71
+ for (const [groupKey, group] of groups) {
72
+ if (group.length <= 1)
73
+ continue;
74
+ try {
75
+ this.mergeGroup(groupKey, group);
76
+ }
77
+ catch (error) {
78
+ console.warn(`[playwright-api-logger] Failed to merge group "${groupKey}":`, error);
79
+ }
80
+ }
81
+ }
82
+ /**
83
+ * Read and parse all .log files from the log directory
84
+ */
85
+ readLogFiles() {
86
+ const files = [];
87
+ for (const filename of fs_1.default.readdirSync(this.logDirectory)) {
88
+ if (!filename.endsWith('.log'))
89
+ continue;
90
+ const filePath = path_1.default.join(this.logDirectory, filename);
91
+ try {
92
+ const content = fs_1.default.readFileSync(filePath, 'utf-8');
93
+ const data = JSON.parse(content);
94
+ // Validate minimum structure + startedAt for merge (avoids NaN sort keys)
95
+ const startedAt = data?.test?.startedAt;
96
+ if (data?.test &&
97
+ data?.summary &&
98
+ startedAt &&
99
+ !isNaN(new Date(startedAt).getTime())) {
100
+ files.push({ filePath, filename, data });
101
+ }
102
+ }
103
+ catch {
104
+ // Skip malformed files
105
+ }
106
+ }
107
+ return files;
108
+ }
109
+ /**
110
+ * Group log files by their describe block path.
111
+ * Files from the same test file + same describe block → same group.
112
+ *
113
+ * Only groups files that have titlePath with at least 3 elements
114
+ * (project + describe + test name), otherwise they're standalone tests.
115
+ */
116
+ groupByDescribeBlock(files) {
117
+ const groups = new Map();
118
+ for (const file of files) {
119
+ const titlePath = file.data.test?.titlePath;
120
+ const testFile = file.data.test?.file;
121
+ if (!titlePath || titlePath.length < 3 || !testFile) {
122
+ // Standalone test or missing info — don't group
123
+ continue;
124
+ }
125
+ // Group key: file + describe block path (all titlePath except last element)
126
+ const describePath = titlePath.slice(0, -1).join(' > ');
127
+ const groupKey = `${testFile}::${describePath}`;
128
+ if (!groups.has(groupKey)) {
129
+ groups.set(groupKey, []);
130
+ }
131
+ groups.get(groupKey).push(file);
132
+ }
133
+ return groups;
134
+ }
135
+ /**
136
+ * Merge a group of related log files into a single structured document.
137
+ *
138
+ * Strategy:
139
+ * - Sort files by startedAt timestamp
140
+ * - First file's steps → preconditions section
141
+ * - Middle files' steps → test steps section
142
+ * - Last file's steps → teardown section
143
+ * - If only 2 files: first → preconditions, second → steps
144
+ * - Note: Per-document section assignments (preconditions/steps/teardown) are
145
+ * flattened and reassigned by file order; manual context in a single file
146
+ * is not preserved when merging.
147
+ */
148
+ mergeGroup(_groupKey, group) {
149
+ // Sort by startedAt timestamp (earliest first)
150
+ group.sort((a, b) => {
151
+ const timeA = new Date(a.data.test.startedAt).getTime();
152
+ const timeB = new Date(b.data.test.startedAt).getTime();
153
+ return timeA - timeB;
154
+ });
155
+ // Build merged document
156
+ const firstDoc = group[0].data;
157
+ const lastDoc = group[group.length - 1].data;
158
+ // Use the describe block name as merged test name
159
+ const titlePath = firstDoc.test.titlePath;
160
+ const describeName = titlePath
161
+ ? titlePath.slice(1, -1).join(' > ')
162
+ : firstDoc.test.name;
163
+ const merged = {
164
+ test: {
165
+ name: describeName || firstDoc.test.name,
166
+ file: firstDoc.test.file,
167
+ titlePath: titlePath ? titlePath.slice(0, -1) : undefined,
168
+ startedAt: firstDoc.test.startedAt,
169
+ finishedAt: lastDoc.test.finishedAt || lastDoc.test.startedAt,
170
+ result: this.resolveGroupResult(group),
171
+ },
172
+ preconditions: [],
173
+ steps: [],
174
+ teardown: [],
175
+ summary: {
176
+ totalRequests: 0,
177
+ preconditions: 0,
178
+ testSteps: 0,
179
+ teardown: 0,
180
+ totalDuration: 0,
181
+ },
182
+ };
183
+ if (group.length === 2) {
184
+ // 2 files: first → preconditions, second → steps
185
+ merged.preconditions = this.collectAllSteps(group[0].data);
186
+ merged.steps = this.collectAllSteps(group[1].data);
187
+ }
188
+ else {
189
+ // 3+ files: first → preconditions, middle → steps, last → teardown
190
+ merged.preconditions = this.collectAllSteps(group[0].data);
191
+ for (let i = 1; i < group.length - 1; i++) {
192
+ merged.steps.push(...this.collectAllSteps(group[i].data));
193
+ }
194
+ merged.teardown = this.collectAllSteps(group[group.length - 1].data);
195
+ }
196
+ // Re-number steps in each section
197
+ this.renumberSteps(merged.preconditions);
198
+ this.renumberSteps(merged.steps);
199
+ this.renumberSteps(merged.teardown);
200
+ // Calculate summary
201
+ const allSteps = [
202
+ ...merged.preconditions,
203
+ ...merged.steps,
204
+ ...merged.teardown,
205
+ ];
206
+ merged.summary = {
207
+ totalRequests: allSteps.length,
208
+ preconditions: merged.preconditions.length,
209
+ testSteps: merged.steps.length,
210
+ teardown: merged.teardown.length,
211
+ totalDuration: allSteps.reduce((sum, s) => sum + s.duration, 0),
212
+ };
213
+ // Calculate total test duration
214
+ if (merged.test.startedAt && merged.test.finishedAt) {
215
+ merged.test.duration =
216
+ new Date(merged.test.finishedAt).getTime() -
217
+ new Date(merged.test.startedAt).getTime();
218
+ }
219
+ // Write merged file (use first file's path)
220
+ fs_1.default.writeFileSync(group[0].filePath, JSON.stringify(merged, null, 2) + '\n');
221
+ // Remove other files in the group
222
+ for (let i = 1; i < group.length; i++) {
223
+ try {
224
+ fs_1.default.unlinkSync(group[i].filePath);
225
+ }
226
+ catch {
227
+ // Ignore cleanup errors
228
+ }
229
+ }
230
+ }
231
+ /**
232
+ * Collect all steps from a log document (from all sections)
233
+ */
234
+ collectAllSteps(doc) {
235
+ return [
236
+ ...(doc.preconditions || []),
237
+ ...(doc.steps || []),
238
+ ...(doc.teardown || []),
239
+ ];
240
+ }
241
+ /**
242
+ * Re-number step entries sequentially
243
+ */
244
+ renumberSteps(steps) {
245
+ steps.forEach((step, index) => {
246
+ step.step = index + 1;
247
+ });
248
+ }
249
+ /**
250
+ * Determine the overall result for a group of log files.
251
+ * FAILED wins over PASSED, PASSED wins over SKIPPED.
252
+ */
253
+ resolveGroupResult(group) {
254
+ const results = group.map((g) => g.data.test.result).filter(Boolean);
255
+ if (results.includes('FAILED'))
256
+ return 'FAILED';
257
+ if (results.includes('PASSED'))
258
+ return 'PASSED';
259
+ return 'SKIPPED';
260
+ }
261
+ /**
262
+ * Print a summary of log files after the test run
263
+ */
264
+ logSummary() {
265
+ if (!fs_1.default.existsSync(this.logDirectory))
266
+ return;
267
+ const logFiles = fs_1.default
268
+ .readdirSync(this.logDirectory)
269
+ .filter((f) => f.endsWith('.log'));
270
+ if (logFiles.length === 0)
271
+ return;
272
+ let totalRequests = 0;
273
+ let totalDuration = 0;
274
+ for (const filename of logFiles) {
275
+ try {
276
+ const content = fs_1.default.readFileSync(path_1.default.join(this.logDirectory, filename), 'utf-8');
277
+ const data = JSON.parse(content);
278
+ totalRequests += data.summary?.totalRequests || 0;
279
+ totalDuration += data.summary?.totalDuration || 0;
280
+ }
281
+ catch {
282
+ // Skip malformed files
283
+ }
284
+ }
285
+ const durationStr = totalDuration > 1000
286
+ ? `${(totalDuration / 1000).toFixed(1)}s`
287
+ : `${totalDuration}ms`;
288
+ console.log('');
289
+ console.log(` \x1b[36m[playwright-api-logger]\x1b[0m ${logFiles.length} log file${logFiles.length === 1 ? '' : 's'}, ${totalRequests} API request${totalRequests === 1 ? '' : 's'} (${durationStr})`);
290
+ console.log(` \x1b[36m[playwright-api-logger]\x1b[0m Logs: ${this.logDirectory}`);
291
+ }
292
+ }
293
+ exports.default = ApiLoggerReporter;
294
+ //# sourceMappingURL=reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -2,6 +2,7 @@ export type LogContext = 'preconditions' | 'test' | 'teardown';
2
2
  export interface LoggerConfig {
3
3
  testName?: string;
4
4
  testFile?: string;
5
+ titlePath?: string[];
5
6
  context?: LogContext;
6
7
  logDirectory?: string;
7
8
  maskAuthTokens?: boolean;
@@ -31,6 +32,7 @@ export interface TestLogDocument {
31
32
  test: {
32
33
  name: string;
33
34
  file?: string;
35
+ titlePath?: string[];
34
36
  startedAt: string;
35
37
  finishedAt?: string;
36
38
  duration?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;KAC1C,CAAC;IACF,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,2CAA2C;AAC3C,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,MAAM,GAAG,UAAU,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;KAC1C,CAAC;IACF,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,2CAA2C;AAC3C,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,UAAU,CAAC;IACpB,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd"}
@@ -10,14 +10,18 @@ export interface ApiLoggingOptions {
10
10
  testName?: string;
11
11
  /** Test file path (auto-detected from testInfo if provided) */
12
12
  testFile?: string;
13
+ /** Test title path hierarchy (auto-detected from testInfo if provided) */
14
+ titlePath?: string[];
13
15
  /** Log context: 'preconditions' | 'test' | 'teardown' (default: 'test') */
14
16
  context?: LogContext;
15
17
  /** Custom log directory (default: 'logs/') */
16
18
  logDirectory?: string;
17
19
  /** Mask Authorization headers (default: true) */
18
20
  maskAuthTokens?: boolean;
19
- /** Existing logger to share across setup/test/teardown phases */
21
+ /** Existing logger instance to reuse */
20
22
  logger?: ApiLogger;
23
+ /** Shared logger key — use same key in beforeAll/test/afterAll to write ONE log file */
24
+ sharedKey?: string;
21
25
  }
22
26
  /**
23
27
  * Wrap Playwright's APIRequestContext with automatic logging.
@@ -33,15 +37,12 @@ export interface ApiLoggingOptions {
33
37
  * const apiClient = new ApiClient(loggedRequest);
34
38
  *
35
39
  * @example
36
- * // With preconditions and test steps:
37
- * const loggedRequest = withApiLogging(request, testInfo);
38
- * loggedRequest.__logger.startPreconditions();
39
- * loggedRequest.__logger.describe('Get employee for test');
40
- * await apiClient.getEmployees();
41
- * loggedRequest.__logger.startTest();
42
- * loggedRequest.__logger.describe('Try to access without token');
43
- * await apiClient.getWithoutAuth();
44
- * loggedRequest.__logger.finalize('PASSED');
40
+ * // Shared logger across beforeAll/test/afterAll:
41
+ * const loggedRequest = withApiLogging(request, {
42
+ * sharedKey: 'my-describe',
43
+ * testName: 'My Test',
44
+ * context: 'preconditions'
45
+ * });
45
46
  */
46
47
  export declare function withApiLogging(request: APIRequestContext, testInfoOrOptions?: TestInfo | ApiLoggingOptions): APIRequestContext & {
47
48
  __logger: ApiLogger;
@@ -1 +1 @@
1
- {"version":3,"file":"withApiLogging.d.ts","sourceRoot":"","sources":["../src/withApiLogging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAe,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAgB,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,iEAAiE;IACjE,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,iBAAiB,EAC1B,iBAAiB,CAAC,EAAE,QAAQ,GAAG,iBAAiB,GAC/C,iBAAiB,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,CAmG7C"}
1
+ {"version":3,"file":"withApiLogging.d.ts","sourceRoot":"","sources":["../src/withApiLogging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAe,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAgB,MAAM,SAAS,CAAC;AAGnD,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iDAAiD;IACjD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wCAAwC;IACxC,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,iBAAiB,EAC1B,iBAAiB,CAAC,EAAE,QAAQ,GAAG,iBAAiB,GAC/C,iBAAiB,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,CAoH7C"}
@@ -6,6 +6,7 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.withApiLogging = withApiLogging;
8
8
  const ApiLogger_1 = require("./ApiLogger");
9
+ const LoggerRegistry_1 = require("./LoggerRegistry");
9
10
  /**
10
11
  * Wrap Playwright's APIRequestContext with automatic logging.
11
12
  * All HTTP calls (get, post, put, patch, delete, head, fetch) are intercepted and logged.
@@ -20,15 +21,12 @@ const ApiLogger_1 = require("./ApiLogger");
20
21
  * const apiClient = new ApiClient(loggedRequest);
21
22
  *
22
23
  * @example
23
- * // With preconditions and test steps:
24
- * const loggedRequest = withApiLogging(request, testInfo);
25
- * loggedRequest.__logger.startPreconditions();
26
- * loggedRequest.__logger.describe('Get employee for test');
27
- * await apiClient.getEmployees();
28
- * loggedRequest.__logger.startTest();
29
- * loggedRequest.__logger.describe('Try to access without token');
30
- * await apiClient.getWithoutAuth();
31
- * loggedRequest.__logger.finalize('PASSED');
24
+ * // Shared logger across beforeAll/test/afterAll:
25
+ * const loggedRequest = withApiLogging(request, {
26
+ * sharedKey: 'my-describe',
27
+ * testName: 'My Test',
28
+ * context: 'preconditions'
29
+ * });
32
30
  */
33
31
  function withApiLogging(request, testInfoOrOptions) {
34
32
  let options;
@@ -37,15 +35,32 @@ function withApiLogging(request, testInfoOrOptions) {
37
35
  options = {
38
36
  testName: testInfo.title,
39
37
  testFile: testInfo.file,
38
+ titlePath: testInfo.titlePath,
40
39
  context: 'test',
41
40
  };
42
41
  }
43
42
  else {
44
43
  options = testInfoOrOptions || {};
45
44
  }
46
- // Use shared logger or create new
45
+ // Resolve logger: shared existing new
47
46
  let logger;
48
- if (options.logger) {
47
+ if (options.sharedKey) {
48
+ // Shared logger by key — same instance across beforeAll/test/afterAll
49
+ const config = {
50
+ testName: options.testName,
51
+ testFile: options.testFile,
52
+ titlePath: options.titlePath,
53
+ context: options.context || 'test',
54
+ logDirectory: options.logDirectory,
55
+ maskAuthTokens: options.maskAuthTokens,
56
+ };
57
+ logger = (0, LoggerRegistry_1.getSharedLogger)(options.sharedKey, config);
58
+ // Switch context for this phase
59
+ if (options.context) {
60
+ logger.setContext(options.context);
61
+ }
62
+ }
63
+ else if (options.logger) {
49
64
  logger = options.logger;
50
65
  if (options.context) {
51
66
  logger.setContext(options.context);
@@ -55,6 +70,7 @@ function withApiLogging(request, testInfoOrOptions) {
55
70
  const config = {
56
71
  testName: options.testName,
57
72
  testFile: options.testFile,
73
+ titlePath: options.titlePath,
58
74
  context: options.context || 'test',
59
75
  logDirectory: options.logDirectory,
60
76
  maskAuthTokens: options.maskAuthTokens,
@@ -1 +1 @@
1
- {"version":3,"file":"withApiLogging.js","sourceRoot":"","sources":["../src/withApiLogging.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"withApiLogging.js","sourceRoot":"","sources":["../src/withApiLogging.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,14 +1,26 @@
1
1
  {
2
2
  "name": "playwright-api-logger",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "Comprehensive API request/response logger with curl export for Playwright tests",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./reporter": {
13
+ "types": "./dist/reporter.d.ts",
14
+ "default": "./dist/reporter.js"
15
+ }
16
+ },
7
17
  "files": [
8
18
  "dist"
9
19
  ],
10
20
  "scripts": {
11
21
  "build": "tsc",
22
+ "test": "npx playwright test",
23
+ "test:demo": "API_LOGS=true npx playwright test tests/demo-log.spec.ts",
12
24
  "prepublishOnly": "npm run build"
13
25
  },
14
26
  "keywords": [
@@ -19,7 +31,8 @@
19
31
  "testing",
20
32
  "postman",
21
33
  "form-data",
22
- "multipart"
34
+ "multipart",
35
+ "reporter"
23
36
  ],
24
37
  "author": "AZANIR",
25
38
  "license": "MIT",