@stanterprise/playwright-reporter 0.0.14 → 0.0.15

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.
@@ -42,6 +42,12 @@ function handleOnTestEndEvent(test, result, runId, client, options) {
42
42
  // Serialize once to capture payload size for potential error logging
43
43
  const serializedPayload = request.serializeBinary();
44
44
  const payloadSize = serializedPayload.length;
45
+ // Warn if payload is unusually large (>1MB)
46
+ if (payloadSize > 1048576) {
47
+ console.warn(`Large payload detected for test "${test.title}": ${(payloadSize / BYTES_PER_MB).toFixed(2)}MB. ` +
48
+ `Attachments: ${attachments.length}, Metadata keys: ${Object.keys(metadata).length}, ` +
49
+ `Error length: ${errorMessage.length + stackTrace.length} bytes`);
50
+ }
45
51
  // Fire-and-forget to avoid slowing tests
46
52
  (0, grpcClient_1.reportUnary)(options, client, "/testsystem.v1.observer.TestEventCollector/ReportTestEnd", request, options.grpcTimeout).catch((e) => {
47
53
  console.error(`Failed to report test end for "${test.title}" (payload size: ${(payloadSize / BYTES_PER_MB).toFixed(2)}MB)`, e);
@@ -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.15",
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": {