@clipboard-health/playwright-reporter-llm 2.8.2 → 2.8.4

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
@@ -262,48 +262,83 @@ See [`docs/example-report.json`](./docs/example-report.json) for a complete repo
262
262
 
263
263
  ### Browser lifecycle attachment contract
264
264
 
265
- Fixtures can attach `browser-network-lifecycle` or `browser-network-lifecycle.json` with content type `application/json` and this versioned shape:
265
+ Producers should import `encodeBrowserLifecycleAttachment` instead of defining their own schema or size limit. The encoder sanitizes records, orders `no_response_headers`, `headers_without_body_completion`, and `network_failure` records before routine `completed` records, and returns a body guaranteed not to exceed the shared 64 KiB limit:
266
+
267
+ ```typescript
268
+ import {
269
+ encodeBrowserLifecycleAttachment,
270
+ type BrowserLifecycleRecord,
271
+ } from "@clipboard-health/playwright-reporter-llm";
272
+
273
+ const records: BrowserLifecycleRecord[] = [];
274
+ const encoded = encodeBrowserLifecycleAttachment({ records });
275
+
276
+ await testInfo.attach("browser-network-lifecycle", {
277
+ body: encoded.body,
278
+ contentType: "application/json",
279
+ });
280
+ ```
281
+
282
+ `BROWSER_LIFECYCLE_ATTACHMENT_SCHEMA` exposes the version, maximum bytes, and maximum records. `encoded.attachment.truncated` is set when the caller reports earlier truncation or the encoder drops invalid or over-limit records; the result also reports observed, included, and dropped record counts.
283
+
284
+ The encoder emits schema version 2. Each version identifies one wire shape; version 2 uses the producer's nested lifecycle events:
266
285
 
267
286
  ```json
268
287
  {
269
- "schemaVersion": 1,
288
+ "schemaVersion": 2,
270
289
  "truncated": false,
271
290
  "records": [
272
291
  {
273
292
  "method": "GET",
274
293
  "origin": "https://api.example.com",
275
294
  "pathTemplate": "/api/v1/:workplaceId/cases",
276
- "requestStartedAt": "2026-07-20T18:35:43.100Z",
277
- "requestStartedMonotonicMs": 12345.1,
278
- "responseHeadersAt": "2026-07-20T18:35:43.168Z",
279
- "responseHeadersMonotonicMs": 12413.1,
280
- "completedAt": "2026-07-20T18:35:43.170Z",
281
- "completedMonotonicMs": 12415.1,
282
- "requestStarted": true,
283
- "responseHeadersReceived": true,
284
- "loadingFinished": true,
285
- "loadingFailed": false,
286
- "pendingAtTimeout": false,
287
295
  "playwrightRequestKey": "request-17",
288
296
  "cdpRequestId": "1234.56",
289
297
  "loaderId": "loader-1",
290
298
  "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
291
299
  "spanId": "00f067aa0ba902b7",
292
300
  "apiGatewayRequestId": "A0XEghTXPHcEScg=",
301
+ "requestStarted": {
302
+ "cdp": {
303
+ "utc": "2026-07-20T18:35:43.100Z",
304
+ "monotonicMilliseconds": 12345.1
305
+ }
306
+ },
307
+ "responseReceived": {
308
+ "cdp": {
309
+ "utc": "2026-07-20T18:35:43.168Z",
310
+ "monotonicMilliseconds": 12413.1
311
+ }
312
+ },
313
+ "loadingFinished": {
314
+ "cdp": {
315
+ "utc": "2026-07-20T18:35:43.170Z",
316
+ "monotonicMilliseconds": 12415.1
317
+ }
318
+ },
293
319
  "protocol": "h2",
294
- "connectionId": 17,
295
- "connectionReused": true,
296
- "remoteIPAddress": "10.0.0.12",
297
- "remotePort": 443,
298
- "responseEncodedDataLength": 256,
299
- "completedEncodedDataLength": 677,
320
+ "connection": {
321
+ "id": 17,
322
+ "reused": true,
323
+ "remoteEndpoint": {
324
+ "ipAddress": "10.0.0.12",
325
+ "port": 443
326
+ }
327
+ },
328
+ "encodedBytes": {
329
+ "data": 421,
330
+ "responseHeaders": 256,
331
+ "total": 677
332
+ },
300
333
  "classification": "completed"
301
334
  }
302
335
  ]
303
336
  }
304
337
  ```
305
338
 
306
- For a failure, the same record can supply `failedAt`, `failedMonotonicMs`, `errorText` (restricted to Chromium `net::ERR_*` values), `canceled`, `blockedReason`, and `corsErrorStatus`. Unknown fields are discarded. Origins are reduced to scheme/host/port, query and fragment text is removed from `pathTemplate`, identifiers are format/length checked, and only the documented allowlist is emitted. The reporter reads at most 64 KiB and retains at most 100 records per attempt; `clientLifecycle.truncated` marks producer- or reporter-side record truncation. It does not mutate the original Playwright attachment, so other configured reporters such as Playwright HTML continue to render the sanitized attachment.
339
+ For a failure, `loadingFailed` can supply a nested CDP or Playwright timestamp plus `errorText` (restricted to Chromium `net::ERR_*` values), `canceled`, `blockedReason`, and `corsErrorStatus`. The reporter prefers the CDP timestamp and falls back to Playwright. Unknown fields are discarded. Origins are reduced to scheme/host/port, query and fragment text is removed from `pathTemplate`, identifiers are format/length checked, and only the documented allowlist is emitted.
340
+
341
+ Fixtures can attach the encoded body as `browser-network-lifecycle` or `browser-network-lifecycle.json` with content type `application/json`, either directly in `body` or through `path`. The reporter independently enforces the same byte and record limits; `clientLifecycle.truncated` marks producer- or reporter-side truncation. The legacy flat version-1 reader remains for existing attachments, but new producers should only emit version 2 through the shared encoder.
307
342
 
308
343
  ## Why not Playwright's built-in JSON reporter?
309
344
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/playwright-reporter-llm",
3
- "version": "2.8.2",
3
+ "version": "2.8.4",
4
4
  "description": "Playwright reporter that outputs structured JSON for LLM agents. Minimal console output, flat schema, easy to filter to failures.",
5
5
  "keywords": [
6
6
  "agent",
package/src/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
+ export type { BrowserLifecycleAttachment, BrowserLifecycleClassification, BrowserLifecycleConnection, BrowserLifecycleEncodedBytes, BrowserLifecycleEvent, BrowserLifecycleFailureEvent, BrowserLifecycleRecord, BrowserLifecycleTimestamp, EncodeBrowserLifecycleAttachmentInput, EncodedBrowserLifecycleAttachment, ParseBrowserLifecycleAttachmentInput, } from "./lib/clientLifecycleContract";
2
+ export { BROWSER_LIFECYCLE_ATTACHMENT_SCHEMA, encodeBrowserLifecycleAttachment, parseBrowserLifecycleAttachment, } from "./lib/clientLifecycleContract";
1
3
  export { default } from "./lib/reporter";
2
4
  export type { AttemptResult, ClientLifecycle, ClientLifecycleClassification, ConsoleEntry, FailureArtifacts, FlatStep, GlobalError, LlmReporterOptions, LlmTestEntry, LlmTestReport, NetworkBody, NetworkGroup, NetworkInstance, NetworkReport, NetworkSummary, NetworkTimingBreakdown, TestAttachment, TestEnvironment, TestError, TestLocation, TestStatus, TestSummary, TimelineConsoleEntry, TimelineEntry, TimelineNetworkEntry, TimelineStepEntry, } from "./lib/types";
package/src/index.js CHANGED
@@ -1,7 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = void 0;
3
+ exports.default = exports.parseBrowserLifecycleAttachment = exports.encodeBrowserLifecycleAttachment = exports.BROWSER_LIFECYCLE_ATTACHMENT_SCHEMA = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ var clientLifecycleContract_1 = require("./lib/clientLifecycleContract");
6
+ Object.defineProperty(exports, "BROWSER_LIFECYCLE_ATTACHMENT_SCHEMA", { enumerable: true, get: function () { return clientLifecycleContract_1.BROWSER_LIFECYCLE_ATTACHMENT_SCHEMA; } });
7
+ Object.defineProperty(exports, "encodeBrowserLifecycleAttachment", { enumerable: true, get: function () { return clientLifecycleContract_1.encodeBrowserLifecycleAttachment; } });
8
+ Object.defineProperty(exports, "parseBrowserLifecycleAttachment", { enumerable: true, get: function () { return clientLifecycleContract_1.parseBrowserLifecycleAttachment; } });
5
9
  var reporter_1 = require("./lib/reporter");
6
10
  Object.defineProperty(exports, "default", { enumerable: true, get: function () { return tslib_1.__importDefault(reporter_1).default; } });
7
11
  //# sourceMappingURL=index.js.map
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/playwright-reporter-llm/src/index.ts"],"names":[],"mappings":";;;;AAAA,2CAAyC;AAAhC,4HAAA,OAAO,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/playwright-reporter-llm/src/index.ts"],"names":[],"mappings":";;;;AAaA,yEAIuC;AAHrC,8IAAA,mCAAmC,OAAA;AACnC,2IAAA,gCAAgC,OAAA;AAChC,0IAAA,+BAA+B,OAAA;AAEjC,2CAAyC;AAAhC,4HAAA,OAAO,OAAA"}
@@ -0,0 +1,80 @@
1
+ import { type BrowserLifecycleClassification } from "./internal/clientLifecycleSanitization";
2
+ export type { BrowserLifecycleClassification } from "./internal/clientLifecycleSanitization";
3
+ declare const SCHEMA_VERSION = 2;
4
+ export declare const BROWSER_LIFECYCLE_ATTACHMENT_SCHEMA: Readonly<{
5
+ version: 2;
6
+ maximumBytes: 65536;
7
+ maximumRecords: 100;
8
+ }>;
9
+ export interface BrowserLifecycleTimestamp {
10
+ utc: string;
11
+ monotonicMilliseconds?: number;
12
+ }
13
+ export type BrowserLifecycleEvent = {
14
+ cdp: BrowserLifecycleTimestamp;
15
+ playwright?: BrowserLifecycleTimestamp;
16
+ } | {
17
+ cdp?: BrowserLifecycleTimestamp;
18
+ playwright: BrowserLifecycleTimestamp;
19
+ };
20
+ export interface BrowserLifecycleFailureEvent {
21
+ cdp?: BrowserLifecycleTimestamp;
22
+ playwright?: BrowserLifecycleTimestamp;
23
+ errorText?: string;
24
+ canceled?: boolean;
25
+ blockedReason?: string;
26
+ corsErrorStatus?: string;
27
+ }
28
+ export interface BrowserLifecycleConnection {
29
+ id?: number;
30
+ reused?: boolean;
31
+ remoteEndpoint?: {
32
+ ipAddress?: string;
33
+ port?: number;
34
+ };
35
+ }
36
+ export interface BrowserLifecycleEncodedBytes {
37
+ data?: number;
38
+ responseHeaders?: number;
39
+ total?: number;
40
+ }
41
+ export interface BrowserLifecycleRecord {
42
+ method: string;
43
+ origin: string;
44
+ pathTemplate: string;
45
+ requestStarted: BrowserLifecycleEvent;
46
+ responseReceived?: BrowserLifecycleEvent;
47
+ loadingFinished?: BrowserLifecycleEvent;
48
+ loadingFailed?: BrowserLifecycleFailureEvent;
49
+ playwrightRequestKey?: string;
50
+ cdpRequestId?: string;
51
+ loaderId?: string;
52
+ traceId?: string;
53
+ spanId?: string;
54
+ apiGatewayRequestId?: string;
55
+ protocol?: string;
56
+ connection?: BrowserLifecycleConnection;
57
+ encodedBytes?: BrowserLifecycleEncodedBytes;
58
+ classification: BrowserLifecycleClassification;
59
+ }
60
+ export interface BrowserLifecycleAttachment {
61
+ schemaVersion: typeof SCHEMA_VERSION;
62
+ truncated: boolean;
63
+ records: BrowserLifecycleRecord[];
64
+ }
65
+ export interface EncodeBrowserLifecycleAttachmentInput {
66
+ records: readonly BrowserLifecycleRecord[];
67
+ truncated?: boolean;
68
+ }
69
+ export interface EncodedBrowserLifecycleAttachment {
70
+ body: Buffer;
71
+ attachment: BrowserLifecycleAttachment;
72
+ observedRecordCount: number;
73
+ includedRecordCount: number;
74
+ droppedRecordCount: number;
75
+ }
76
+ export declare function encodeBrowserLifecycleAttachment({ records, truncated, }: EncodeBrowserLifecycleAttachmentInput): EncodedBrowserLifecycleAttachment;
77
+ export interface ParseBrowserLifecycleAttachmentInput {
78
+ content: Uint8Array;
79
+ }
80
+ export declare function parseBrowserLifecycleAttachment({ content, }: ParseBrowserLifecycleAttachmentInput): BrowserLifecycleAttachment | undefined;
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BROWSER_LIFECYCLE_ATTACHMENT_SCHEMA = void 0;
4
+ exports.encodeBrowserLifecycleAttachment = encodeBrowserLifecycleAttachment;
5
+ exports.parseBrowserLifecycleAttachment = parseBrowserLifecycleAttachment;
6
+ const clientLifecycleSanitization_1 = require("./internal/clientLifecycleSanitization");
7
+ const typeGuards_1 = require("./internal/typeGuards");
8
+ const SCHEMA_VERSION = 2;
9
+ const MAXIMUM_BYTES = 65_536;
10
+ const MAXIMUM_RECORDS = 100;
11
+ exports.BROWSER_LIFECYCLE_ATTACHMENT_SCHEMA = Object.freeze({
12
+ version: SCHEMA_VERSION,
13
+ maximumBytes: MAXIMUM_BYTES,
14
+ maximumRecords: MAXIMUM_RECORDS,
15
+ });
16
+ function encodeBrowserLifecycleAttachment({ records, truncated = false, }) {
17
+ const sanitizedRecords = records
18
+ .map((record) => sanitizeRecord(record))
19
+ .filter((record) => record !== undefined);
20
+ const prioritizedRecords = prioritizeRecords(sanitizedRecords);
21
+ const includedRecords = [];
22
+ const emptyAttachmentBytes = Math.max(serializeAttachment({ records: [], truncated: false }).body.byteLength, serializeAttachment({ records: [], truncated: true }).body.byteLength);
23
+ let includedRecordBytes = 0;
24
+ for (const record of prioritizedRecords) {
25
+ if (includedRecords.length >= MAXIMUM_RECORDS) {
26
+ break;
27
+ }
28
+ const recordBytes = Buffer.byteLength(JSON.stringify(record));
29
+ const separatorBytes = includedRecords.length === 0 ? 0 : 1;
30
+ if (emptyAttachmentBytes + includedRecordBytes + separatorBytes + recordBytes <=
31
+ MAXIMUM_BYTES) {
32
+ includedRecords.push(record);
33
+ includedRecordBytes += separatorBytes + recordBytes;
34
+ }
35
+ }
36
+ const droppedRecordCount = records.length - includedRecords.length;
37
+ const { attachment, body } = serializeAttachment({
38
+ records: includedRecords,
39
+ truncated: truncated || droppedRecordCount > 0,
40
+ });
41
+ return {
42
+ body,
43
+ attachment,
44
+ observedRecordCount: records.length,
45
+ includedRecordCount: attachment.records.length,
46
+ droppedRecordCount: records.length - attachment.records.length,
47
+ };
48
+ }
49
+ function parseBrowserLifecycleAttachment({ content, }) {
50
+ if (content.byteLength > MAXIMUM_BYTES) {
51
+ return undefined;
52
+ }
53
+ let parsedValue;
54
+ try {
55
+ parsedValue = JSON.parse(Buffer.from(content).toString("utf8"));
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ const attachment = (0, typeGuards_1.asRecord)(parsedValue);
61
+ if (!attachment) {
62
+ return undefined;
63
+ }
64
+ const records = attachment["records"];
65
+ if ((0, typeGuards_1.asNumber)(attachment["schemaVersion"]) !== SCHEMA_VERSION ||
66
+ !Array.isArray(records) ||
67
+ (0, typeGuards_1.asBoolean)(attachment["truncated"]) === undefined) {
68
+ return undefined;
69
+ }
70
+ const sanitizedRecords = [];
71
+ for (const record of records.slice(0, MAXIMUM_RECORDS)) {
72
+ const sanitizedRecord = sanitizeRecord(record);
73
+ if (!sanitizedRecord) {
74
+ continue;
75
+ }
76
+ sanitizedRecords.push(sanitizedRecord);
77
+ }
78
+ if (records.length > 0 && sanitizedRecords.length === 0) {
79
+ return undefined;
80
+ }
81
+ return {
82
+ schemaVersion: SCHEMA_VERSION,
83
+ truncated: (0, typeGuards_1.asBoolean)(attachment["truncated"]) === true || sanitizedRecords.length < records.length,
84
+ records: sanitizedRecords,
85
+ };
86
+ }
87
+ function sanitizeRecord(value) {
88
+ const record = (0, typeGuards_1.asRecord)(value);
89
+ if (!record) {
90
+ return undefined;
91
+ }
92
+ const method = (0, clientLifecycleSanitization_1.sanitizeLifecycleMethod)(record["method"]);
93
+ const origin = (0, clientLifecycleSanitization_1.sanitizeLifecycleOrigin)(record["origin"]);
94
+ const pathTemplate = (0, clientLifecycleSanitization_1.sanitizeLifecyclePathTemplate)(record["pathTemplate"]);
95
+ const classification = (0, clientLifecycleSanitization_1.sanitizeLifecycleClassification)(record["classification"]);
96
+ const requestStarted = sanitizeEvent(record["requestStarted"]);
97
+ if (!method || !origin || !pathTemplate || !classification || !requestStarted) {
98
+ return undefined;
99
+ }
100
+ const sanitized = {
101
+ method,
102
+ origin,
103
+ pathTemplate,
104
+ requestStarted,
105
+ classification,
106
+ };
107
+ copyEvent({ source: record, target: sanitized, field: "responseReceived" });
108
+ copyEvent({ source: record, target: sanitized, field: "loadingFinished" });
109
+ copyFailureEvent({ source: record, target: sanitized });
110
+ copySafeIdentifier({ source: record, target: sanitized, field: "playwrightRequestKey" });
111
+ copySafeIdentifier({ source: record, target: sanitized, field: "cdpRequestId" });
112
+ copySafeIdentifier({ source: record, target: sanitized, field: "loaderId" });
113
+ copySafeIdentifier({ source: record, target: sanitized, field: "apiGatewayRequestId" });
114
+ copyTraceIdentifiers({ source: record, target: sanitized });
115
+ copyConnection({ source: record, target: sanitized });
116
+ copyEncodedBytes({ source: record, target: sanitized });
117
+ const protocol = (0, clientLifecycleSanitization_1.sanitizeLifecycleProtocol)(record["protocol"]);
118
+ if (protocol) {
119
+ sanitized.protocol = protocol;
120
+ }
121
+ return sanitized;
122
+ }
123
+ function prioritizeRecords(records) {
124
+ return clientLifecycleSanitization_1.CLIENT_LIFECYCLE_CLASSIFICATION_PRIORITY.flatMap((classification) => records.filter((record) => record.classification === classification));
125
+ }
126
+ function serializeAttachment({ records, truncated, }) {
127
+ const attachment = {
128
+ schemaVersion: SCHEMA_VERSION,
129
+ truncated,
130
+ records,
131
+ };
132
+ return {
133
+ attachment,
134
+ body: Buffer.from(JSON.stringify(attachment)),
135
+ };
136
+ }
137
+ function copyEvent({ source, target, field }) {
138
+ const event = sanitizeEvent(source[field]);
139
+ if (event) {
140
+ target[field] = event;
141
+ }
142
+ }
143
+ function copyFailureEvent({ source, target }) {
144
+ const value = source["loadingFailed"];
145
+ const sourceEvent = (0, typeGuards_1.asRecord)(value);
146
+ if (!sourceEvent) {
147
+ return;
148
+ }
149
+ const event = sanitizeEvent(value) ?? {};
150
+ const errorText = (0, clientLifecycleSanitization_1.sanitizeLifecycleNetworkError)(sourceEvent["errorText"]);
151
+ if (errorText) {
152
+ event.errorText = errorText;
153
+ }
154
+ const canceled = (0, typeGuards_1.asBoolean)(sourceEvent["canceled"]);
155
+ if (canceled !== undefined) {
156
+ event.canceled = canceled;
157
+ }
158
+ copyFailureIdentifier({ source: sourceEvent, target: event, field: "blockedReason" });
159
+ copyFailureIdentifier({ source: sourceEvent, target: event, field: "corsErrorStatus" });
160
+ if (Object.keys(event).length > 0) {
161
+ target.loadingFailed = event;
162
+ }
163
+ }
164
+ function sanitizeEvent(value) {
165
+ const source = (0, typeGuards_1.asRecord)(value);
166
+ if (!source) {
167
+ return undefined;
168
+ }
169
+ const cdp = sanitizeTimestamp(source["cdp"]);
170
+ const playwright = sanitizeTimestamp(source["playwright"]);
171
+ if (cdp) {
172
+ return { cdp, ...(playwright && { playwright }) };
173
+ }
174
+ return playwright ? { playwright } : undefined;
175
+ }
176
+ function sanitizeTimestamp(value) {
177
+ const timestamp = (0, typeGuards_1.asRecord)(value);
178
+ const utc = (0, typeGuards_1.asString)(timestamp?.["utc"]);
179
+ if (!utc) {
180
+ return undefined;
181
+ }
182
+ const timestampMs = Date.parse(utc);
183
+ if (!Number.isFinite(timestampMs)) {
184
+ return undefined;
185
+ }
186
+ const sanitized = {
187
+ utc: new Date(timestampMs).toISOString(),
188
+ };
189
+ const monotonicMilliseconds = (0, clientLifecycleSanitization_1.sanitizeLifecycleNonNegativeNumber)(timestamp?.["monotonicMilliseconds"]);
190
+ if (monotonicMilliseconds !== undefined) {
191
+ sanitized.monotonicMilliseconds = monotonicMilliseconds;
192
+ }
193
+ return sanitized;
194
+ }
195
+ function copySafeIdentifier({ source, target, field }) {
196
+ const value = (0, clientLifecycleSanitization_1.sanitizeLifecycleIdentifier)(source[field]);
197
+ if (value) {
198
+ target[field] = value;
199
+ }
200
+ }
201
+ function copyFailureIdentifier({ source, target, field }) {
202
+ const value = (0, clientLifecycleSanitization_1.sanitizeLifecycleIdentifier)(source[field]);
203
+ if (value) {
204
+ target[field] = value;
205
+ }
206
+ }
207
+ function copyTraceIdentifiers({ source, target }) {
208
+ const traceId = (0, clientLifecycleSanitization_1.sanitizeLifecycleTraceId)(source["traceId"]);
209
+ if (traceId) {
210
+ target.traceId = traceId;
211
+ }
212
+ const spanId = (0, clientLifecycleSanitization_1.sanitizeLifecycleSpanId)(source["spanId"]);
213
+ if (spanId) {
214
+ target.spanId = spanId;
215
+ }
216
+ }
217
+ function copyConnection({ source, target }) {
218
+ const connectionSource = (0, typeGuards_1.asRecord)(source["connection"]);
219
+ if (!connectionSource) {
220
+ return;
221
+ }
222
+ const connection = {};
223
+ const id = (0, clientLifecycleSanitization_1.sanitizeLifecycleNonNegativeNumber)(connectionSource["id"]);
224
+ if (id !== undefined) {
225
+ connection.id = id;
226
+ }
227
+ const reused = (0, typeGuards_1.asBoolean)(connectionSource["reused"]);
228
+ if (reused !== undefined) {
229
+ connection.reused = reused;
230
+ }
231
+ const endpointSource = (0, typeGuards_1.asRecord)(connectionSource["remoteEndpoint"]);
232
+ if (endpointSource) {
233
+ const remoteEndpoint = {};
234
+ const ipAddress = (0, clientLifecycleSanitization_1.sanitizeLifecycleIpAddress)(endpointSource["ipAddress"]);
235
+ if (ipAddress) {
236
+ remoteEndpoint.ipAddress = ipAddress;
237
+ }
238
+ const port = (0, clientLifecycleSanitization_1.sanitizeLifecycleNonNegativeNumber)(endpointSource["port"]);
239
+ if (port !== undefined) {
240
+ remoteEndpoint.port = port;
241
+ }
242
+ if (Object.keys(remoteEndpoint).length > 0) {
243
+ connection.remoteEndpoint = remoteEndpoint;
244
+ }
245
+ }
246
+ if (Object.keys(connection).length > 0) {
247
+ target.connection = connection;
248
+ }
249
+ }
250
+ function copyEncodedBytes({ source, target }) {
251
+ const bytesSource = (0, typeGuards_1.asRecord)(source["encodedBytes"]);
252
+ if (!bytesSource) {
253
+ return;
254
+ }
255
+ const encodedBytes = {};
256
+ for (const field of ["data", "responseHeaders", "total"]) {
257
+ const value = (0, clientLifecycleSanitization_1.sanitizeLifecycleNonNegativeNumber)(bytesSource[field]);
258
+ if (value !== undefined) {
259
+ encodedBytes[field] = value;
260
+ }
261
+ }
262
+ if (Object.keys(encodedBytes).length > 0) {
263
+ target.encodedBytes = encodedBytes;
264
+ }
265
+ }
266
+ //# sourceMappingURL=clientLifecycleContract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clientLifecycleContract.js","sourceRoot":"","sources":["../../../../../packages/playwright-reporter-llm/src/lib/clientLifecycleContract.ts"],"names":[],"mappings":"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"}