@stanterprise/playwright-reporter 0.0.14 → 0.0.16

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.
@@ -37,11 +37,19 @@ function handleOnTestEndEvent(test, result, runId, client, options) {
37
37
  errors: errors,
38
38
  metadata: (0, utils_1.toMetadataMap)(metadata),
39
39
  tags: test.tags,
40
+ retry_index: result.retry,
41
+ retry_count: test.retries,
40
42
  }),
41
43
  });
42
44
  // Serialize once to capture payload size for potential error logging
43
45
  const serializedPayload = request.serializeBinary();
44
46
  const payloadSize = serializedPayload.length;
47
+ // Warn if payload is unusually large (>1MB)
48
+ if (payloadSize > 1048576) {
49
+ console.warn(`Large payload detected for test "${test.title}": ${(payloadSize / BYTES_PER_MB).toFixed(2)}MB. ` +
50
+ `Attachments: ${attachments.length}, Metadata keys: ${Object.keys(metadata).length}, ` +
51
+ `Error length: ${errorMessage.length + stackTrace.length} bytes`);
52
+ }
45
53
  // Fire-and-forget to avoid slowing tests
46
54
  (0, grpcClient_1.reportUnary)(options, client, "/testsystem.v1.observer.TestEventCollector/ReportTestEnd", request, options.grpcTimeout).catch((e) => {
47
55
  console.error(`Failed to report test end for "${test.title}" (payload size: ${(payloadSize / BYTES_PER_MB).toFixed(2)}MB)`, e);
@@ -17,6 +17,7 @@ function handleOnTestFailEvent(test, result, runId, grpcClient, options) {
17
17
  stack_trace: stackTrace,
18
18
  timestamp: (0, utils_1.createTimestampFromMs)(Date.now()),
19
19
  attachments: attachments,
20
+ retry_index: result.retry,
20
21
  });
21
22
  // Fire-and-forget to avoid slowing tests
22
23
  (0, grpcClient_1.reportUnary)(options, grpcClient, "/testsystem.v1.observer.TestEventCollector/ReportTestFailure", request, options.grpcTimeout).catch((e) => console.error("Failed to report test failure", e));
package/dist/reporter.js CHANGED
@@ -135,7 +135,9 @@ class StanterpriseReporter {
135
135
  console.error(`Stanterprise Reporter: Standard error output - ${chunk.toString()}`);
136
136
  }
137
137
  onStdOut(chunk, test, result) {
138
- // console.log(`Stanterprise Reporter: Standard output - ${chunk.toString()}`);
138
+ if (this.options.verbose) {
139
+ console.log(`Stanterprise Reporter: Standard output - ${chunk.toString()}`);
140
+ }
139
141
  }
140
142
  }
141
143
  exports.default = StanterpriseReporter;
@@ -7,7 +7,7 @@ declare const Attachment: typeof common.v1.common.Attachment;
7
7
  /**
8
8
  * Process Playwright test attachments into protobuf Attachment objects
9
9
  * @param result Test result containing attachments
10
- * @param maxAttachmentSize Maximum size for attachment content (default 10MB)
10
+ * @param maxAttachmentSize Maximum size for attachment content (default 1MB, reduced from 10MB)
11
11
  */
12
12
  export declare function processAttachments(result: TestResult, maxAttachmentSize?: number): InstanceType<typeof Attachment>[];
13
13
  /**
@@ -11,14 +11,16 @@ const BYTES_PER_MB = 1048576;
11
11
  /**
12
12
  * Process Playwright test attachments into protobuf Attachment objects
13
13
  * @param result Test result containing attachments
14
- * @param maxAttachmentSize Maximum size for attachment content (default 10MB)
14
+ * @param maxAttachmentSize Maximum size for attachment content (default 1MB, reduced from 10MB)
15
15
  */
16
- function processAttachments(result, maxAttachmentSize = 10485760 // 10MB default
16
+ function processAttachments(result, maxAttachmentSize = 1048576 // 1MB default (reduced from 10MB to prevent large payloads)
17
17
  ) {
18
18
  const attachments = [];
19
19
  if (!result.attachments || result.attachments.length === 0) {
20
20
  return attachments;
21
21
  }
22
+ let totalAttachmentSize = 0;
23
+ const MAX_TOTAL_ATTACHMENT_SIZE = 2097152; // 2MB total limit across all attachments
22
24
  for (const attachment of result.attachments) {
23
25
  const att = new Attachment({
24
26
  name: attachment.name,
@@ -27,19 +29,29 @@ function processAttachments(result, maxAttachmentSize = 10485760 // 10MB default
27
29
  // Always prefer path if available to avoid large payloads
28
30
  if (attachment.path) {
29
31
  att.uri = attachment.path;
32
+ attachments.push(att);
33
+ continue;
30
34
  }
31
- else if (attachment.body) {
32
- // Only include body content if it's within size limit
35
+ if (attachment.body) {
33
36
  const bodySize = attachment.body.length;
34
- if (bodySize <= maxAttachmentSize) {
35
- att.content = attachment.body;
36
- }
37
- else {
38
- // Skip large attachments without path - log warning
37
+ // Check individual attachment size
38
+ if (bodySize > maxAttachmentSize) {
39
39
  console.warn(`Attachment "${attachment.name}" (${(bodySize / BYTES_PER_MB).toFixed(2)}MB) exceeds max size ` +
40
40
  `(${(maxAttachmentSize / BYTES_PER_MB).toFixed(2)}MB) and has no path. Skipping content.`);
41
41
  // Still add the attachment metadata without content
42
+ attachments.push(att);
43
+ continue;
44
+ }
45
+ // Check total accumulated size
46
+ if (totalAttachmentSize + bodySize > MAX_TOTAL_ATTACHMENT_SIZE) {
47
+ console.warn(`Attachment "${attachment.name}" (${(bodySize / BYTES_PER_MB).toFixed(2)}MB) would exceed total attachment size limit ` +
48
+ `(${(MAX_TOTAL_ATTACHMENT_SIZE / BYTES_PER_MB).toFixed(2)}MB). Skipping content.`);
49
+ attachments.push(att);
50
+ continue;
42
51
  }
52
+ // Include content if within limits
53
+ att.content = attachment.body;
54
+ totalAttachmentSize += bodySize;
43
55
  }
44
56
  attachments.push(att);
45
57
  }
@@ -4,6 +4,28 @@ exports.buildAnnotationsMetadata = buildAnnotationsMetadata;
4
4
  exports.buildTestMetadata = buildTestMetadata;
5
5
  exports.buildStepMetadata = buildStepMetadata;
6
6
  exports.toMetadataMap = toMetadataMap;
7
+ /**
8
+ * Maximum length for a single metadata value (100KB)
9
+ * Large values are often accidentally embedded test data or debug output
10
+ */
11
+ const MAX_METADATA_VALUE_LENGTH = 102400;
12
+ /**
13
+ * Maximum total metadata size across all values (1MB)
14
+ */
15
+ const MAX_TOTAL_METADATA_SIZE = 1048576;
16
+ /**
17
+ * Truncate a string to a maximum length with ellipsis indicator
18
+ * @param value String value to truncate
19
+ * @param maxLength Maximum length (default 100KB)
20
+ * @returns Truncated string with warning suffix if truncated
21
+ */
22
+ function truncateValue(value, maxLength = MAX_METADATA_VALUE_LENGTH) {
23
+ if (value.length <= maxLength) {
24
+ return value;
25
+ }
26
+ const truncated = value.substring(0, maxLength - 100);
27
+ return `${truncated}... [TRUNCATED: original length ${value.length} bytes, showing first ${maxLength - 100} bytes]`;
28
+ }
7
29
  /**
8
30
  * Build metadata from annotations array
9
31
  * @param annotations Array of annotations with type and optional description
@@ -12,12 +34,25 @@ exports.toMetadataMap = toMetadataMap;
12
34
  */
13
35
  function buildAnnotationsMetadata(annotations, prefix = "annotation") {
14
36
  const metadata = {};
15
- annotations.forEach((annotation, index) => {
16
- metadata[`${prefix}_${index}_type`] = annotation.type;
37
+ let totalSize = 0;
38
+ for (let index = 0; index < annotations.length; index++) {
39
+ const annotation = annotations[index];
40
+ const typeKey = `${prefix}_${index}_type`;
41
+ const typeValue = annotation.type;
42
+ metadata[typeKey] = typeValue;
43
+ totalSize += typeValue.length;
17
44
  if (annotation.description) {
18
- metadata[`${prefix}_${index}_description`] = annotation.description;
45
+ const descKey = `${prefix}_${index}_description`;
46
+ const descValue = truncateValue(annotation.description);
47
+ // Skip if adding this would exceed total metadata size
48
+ if (totalSize + descValue.length > MAX_TOTAL_METADATA_SIZE) {
49
+ console.warn(`Skipping annotation description for ${typeKey}: would exceed total metadata size limit (${MAX_TOTAL_METADATA_SIZE} bytes)`);
50
+ continue;
51
+ }
52
+ metadata[descKey] = descValue;
53
+ totalSize += descValue.length;
19
54
  }
20
- });
55
+ }
21
56
  return metadata;
22
57
  }
23
58
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stanterprise/playwright-reporter",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Custom Playwright test reporter that sends test results to Stanterprise via gRPC",
5
5
  "homepage": "https://github.com/stanterprise/stanterprise-playwright-reporter#readme",
6
6
  "bugs": {
@@ -53,6 +53,6 @@
53
53
  "@grpc/grpc-js": "^1.14.1",
54
54
  "@protobuf-ts/grpc-transport": "^2.11.1",
55
55
  "@protobuf-ts/grpcweb-transport": "^2.11.1",
56
- "@stanterprise/protobuf": "^0.0.20"
56
+ "@stanterprise/protobuf": "^0.0.21"
57
57
  }
58
58
  }