@stanterprise/playwright-reporter 0.0.0-debug-flag-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +472 -0
- package/dist/client/grpcClient.d.ts +10 -0
- package/dist/client/grpcClient.js +158 -0
- package/dist/handlers/index.d.ts +9 -0
- package/dist/handlers/index.js +19 -0
- package/dist/handlers/onBeginHandler.d.ts +5 -0
- package/dist/handlers/onBeginHandler.js +96 -0
- package/dist/handlers/onEndHandler.d.ts +4 -0
- package/dist/handlers/onEndHandler.js +51 -0
- package/dist/handlers/onErrorHandler.d.ts +4 -0
- package/dist/handlers/onErrorHandler.js +15 -0
- package/dist/handlers/onStepBeginHandler.d.ts +4 -0
- package/dist/handlers/onStepBeginHandler.js +38 -0
- package/dist/handlers/onStepEndHandler.d.ts +4 -0
- package/dist/handlers/onStepEndHandler.js +59 -0
- package/dist/handlers/onTestBeginHandler.d.ts +4 -0
- package/dist/handlers/onTestBeginHandler.js +32 -0
- package/dist/handlers/onTestEndHandler.d.ts +4 -0
- package/dist/handlers/onTestEndHandler.js +57 -0
- package/dist/handlers/onTestFailHandler.d.ts +4 -0
- package/dist/handlers/onTestFailHandler.js +24 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +10 -0
- package/dist/reporter.d.ts +22 -0
- package/dist/reporter.js +149 -0
- package/dist/types.d.ts +94 -0
- package/dist/types.js +5 -0
- package/dist/utils/attachmentProcessor.d.ts +21 -0
- package/dist/utils/attachmentProcessor.js +73 -0
- package/dist/utils/debugLogger.d.ts +13 -0
- package/dist/utils/debugLogger.js +75 -0
- package/dist/utils/envRetriever.d.ts +9 -0
- package/dist/utils/envRetriever.js +23 -0
- package/dist/utils/idGenerators.d.ts +20 -0
- package/dist/utils/idGenerators.js +40 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.js +26 -0
- package/dist/utils/metadataHelpers.d.ts +42 -0
- package/dist/utils/metadataHelpers.js +91 -0
- package/dist/utils/optionsMapper.d.ts +7 -0
- package/dist/utils/optionsMapper.js +31 -0
- package/dist/utils/statusMapper.d.ts +12 -0
- package/dist/utils/statusMapper.js +29 -0
- package/dist/utils/timeHelpers.d.ts +26 -0
- package/dist/utils/timeHelpers.js +61 -0
- package/package.json +58 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for Stanterprise Playwright Reporter
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for the Stanterprise Reporter
|
|
6
|
+
*/
|
|
7
|
+
export interface StanterpriseReporterOptions {
|
|
8
|
+
/**
|
|
9
|
+
* gRPC server address
|
|
10
|
+
* @default "localhost:50051" or process.env.STANTERPRISE_GRPC_ADDRESS
|
|
11
|
+
*/
|
|
12
|
+
grpcAddress?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Whether gRPC reporting is enabled
|
|
15
|
+
* @default true or process.env.STANTERPRISE_GRPC_ENABLED !== "false"
|
|
16
|
+
*/
|
|
17
|
+
grpcEnabled?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Timeout for gRPC calls in milliseconds
|
|
20
|
+
* @default 1000
|
|
21
|
+
*/
|
|
22
|
+
grpcTimeout?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Maximum message size for gRPC calls in bytes
|
|
25
|
+
* @default 104857600 (100MB)
|
|
26
|
+
*/
|
|
27
|
+
grpcMaxMessageSize?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Maximum size for attachment content in bytes
|
|
30
|
+
* Attachments larger than this will only include the path reference
|
|
31
|
+
* @default 10485760 (10MB)
|
|
32
|
+
*/
|
|
33
|
+
maxAttachmentSize?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to include verbose logging
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
verbose?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Maximum number of retry attempts for failed gRPC calls
|
|
41
|
+
* @default 3
|
|
42
|
+
*/
|
|
43
|
+
grpcMaxRetries?: number;
|
|
44
|
+
/**
|
|
45
|
+
* Initial delay between retry attempts in milliseconds
|
|
46
|
+
* Actual delay uses exponential backoff: initialDelay * (2 ^ attemptNumber)
|
|
47
|
+
* @default 100
|
|
48
|
+
*/
|
|
49
|
+
grpcRetryDelay?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Whether to enable debug mode, which writes all outgoing gRPC messages to a JSONL file
|
|
52
|
+
* @default false or process.env.STANTERPRISE_DEBUG === "true"
|
|
53
|
+
*/
|
|
54
|
+
debug?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* File path for debug JSONL output when debug mode is enabled
|
|
57
|
+
* @default "stanterprise-debug.jsonl" or process.env.STANTERPRISE_DEBUG_FILE
|
|
58
|
+
*/
|
|
59
|
+
debugFile?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Internal type for managing test execution state
|
|
63
|
+
*/
|
|
64
|
+
export interface TestExecutionContext {
|
|
65
|
+
/**
|
|
66
|
+
* Unique ID combining run ID and test ID
|
|
67
|
+
*/
|
|
68
|
+
uniqueTestExecutionId: string;
|
|
69
|
+
/**
|
|
70
|
+
* The global run ID for this test execution
|
|
71
|
+
*/
|
|
72
|
+
runId: string;
|
|
73
|
+
/**
|
|
74
|
+
* The test ID from Playwright
|
|
75
|
+
*/
|
|
76
|
+
testId: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Internal type for managing step execution state
|
|
80
|
+
*/
|
|
81
|
+
export interface StepExecutionContext extends TestExecutionContext {
|
|
82
|
+
/**
|
|
83
|
+
* Unique ID for the step
|
|
84
|
+
*/
|
|
85
|
+
uniqueStepId: string;
|
|
86
|
+
/**
|
|
87
|
+
* Step title
|
|
88
|
+
*/
|
|
89
|
+
stepTitle: string;
|
|
90
|
+
/**
|
|
91
|
+
* Step start time
|
|
92
|
+
*/
|
|
93
|
+
stepStartTime: Date;
|
|
94
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for processing test attachments
|
|
3
|
+
*/
|
|
4
|
+
import type { TestResult } from "@playwright/test/reporter";
|
|
5
|
+
import { common } from "@stanterprise/protobuf";
|
|
6
|
+
declare const Attachment: typeof common.v1.common.Attachment;
|
|
7
|
+
/**
|
|
8
|
+
* Process Playwright test attachments into protobuf Attachment objects
|
|
9
|
+
* @param result Test result containing attachments
|
|
10
|
+
* @param maxAttachmentSize Maximum size for attachment content (default 1MB, reduced from 10MB)
|
|
11
|
+
*/
|
|
12
|
+
export declare function processAttachments(result: TestResult, maxAttachmentSize?: number): InstanceType<typeof Attachment>[];
|
|
13
|
+
/**
|
|
14
|
+
* Extract error information from test results
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractErrorInfo(result: TestResult): {
|
|
17
|
+
errorMessage: string;
|
|
18
|
+
stackTrace: string;
|
|
19
|
+
errors: string[];
|
|
20
|
+
};
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processAttachments = processAttachments;
|
|
4
|
+
exports.extractErrorInfo = extractErrorInfo;
|
|
5
|
+
const protobuf_1 = require("@stanterprise/protobuf");
|
|
6
|
+
const Attachment = protobuf_1.common.v1.common.Attachment;
|
|
7
|
+
/**
|
|
8
|
+
* Constant for converting bytes to megabytes
|
|
9
|
+
*/
|
|
10
|
+
const BYTES_PER_MB = 1048576;
|
|
11
|
+
/**
|
|
12
|
+
* Process Playwright test attachments into protobuf Attachment objects
|
|
13
|
+
* @param result Test result containing attachments
|
|
14
|
+
* @param maxAttachmentSize Maximum size for attachment content (default 1MB, reduced from 10MB)
|
|
15
|
+
*/
|
|
16
|
+
function processAttachments(result, maxAttachmentSize = 1048576 // 1MB default (reduced from 10MB to prevent large payloads)
|
|
17
|
+
) {
|
|
18
|
+
const attachments = [];
|
|
19
|
+
if (!result.attachments || result.attachments.length === 0) {
|
|
20
|
+
return attachments;
|
|
21
|
+
}
|
|
22
|
+
let totalAttachmentSize = 0;
|
|
23
|
+
const MAX_TOTAL_ATTACHMENT_SIZE = 2097152; // 2MB total limit across all attachments
|
|
24
|
+
for (const attachment of result.attachments) {
|
|
25
|
+
const att = new Attachment({
|
|
26
|
+
name: attachment.name,
|
|
27
|
+
mime_type: attachment.contentType,
|
|
28
|
+
});
|
|
29
|
+
// Always prefer path if available to avoid large payloads
|
|
30
|
+
if (attachment.path) {
|
|
31
|
+
att.uri = attachment.path;
|
|
32
|
+
attachments.push(att);
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (attachment.body) {
|
|
36
|
+
const bodySize = attachment.body.length;
|
|
37
|
+
// Check individual attachment size
|
|
38
|
+
if (bodySize > maxAttachmentSize) {
|
|
39
|
+
console.warn(`Attachment "${attachment.name}" (${(bodySize / BYTES_PER_MB).toFixed(2)}MB) exceeds max size ` +
|
|
40
|
+
`(${(maxAttachmentSize / BYTES_PER_MB).toFixed(2)}MB) and has no path. Skipping content.`);
|
|
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;
|
|
51
|
+
}
|
|
52
|
+
// Include content if within limits
|
|
53
|
+
att.content = attachment.body;
|
|
54
|
+
totalAttachmentSize += bodySize;
|
|
55
|
+
}
|
|
56
|
+
attachments.push(att);
|
|
57
|
+
}
|
|
58
|
+
return attachments;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Extract error information from test results
|
|
62
|
+
*/
|
|
63
|
+
function extractErrorInfo(result) {
|
|
64
|
+
let errorMessage = "";
|
|
65
|
+
let stackTrace = "";
|
|
66
|
+
const errors = [];
|
|
67
|
+
if (result.errors && result.errors.length > 0) {
|
|
68
|
+
errorMessage = result.errors.map((e) => e.message || "").join("\n");
|
|
69
|
+
stackTrace = result.errors.map((e) => e.stack || "").join("\n");
|
|
70
|
+
errors.push(...result.errors.map((e) => e.message || ""));
|
|
71
|
+
}
|
|
72
|
+
return { errorMessage, stackTrace, errors };
|
|
73
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { StanterpriseReporterOptions } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Creates or truncates the debug JSONL file so each test run starts with a clean file.
|
|
4
|
+
* No-op when debug mode is disabled.
|
|
5
|
+
*/
|
|
6
|
+
export declare function initDebugFile(options: StanterpriseReporterOptions): void;
|
|
7
|
+
/**
|
|
8
|
+
* Appends a single JSONL entry for an outgoing gRPC message.
|
|
9
|
+
* Each entry is a JSON object on its own line containing the timestamp,
|
|
10
|
+
* gRPC method path, and the serialized message payload.
|
|
11
|
+
* No-op when debug mode is disabled.
|
|
12
|
+
*/
|
|
13
|
+
export declare function writeDebugEntry(options: StanterpriseReporterOptions, path: string, message: unknown): void;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.initDebugFile = initDebugFile;
|
|
37
|
+
exports.writeDebugEntry = writeDebugEntry;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
/**
|
|
40
|
+
* Creates or truncates the debug JSONL file so each test run starts with a clean file.
|
|
41
|
+
* No-op when debug mode is disabled.
|
|
42
|
+
*/
|
|
43
|
+
function initDebugFile(options) {
|
|
44
|
+
if (!options.debug)
|
|
45
|
+
return;
|
|
46
|
+
const filePath = options.debugFile || "stanterprise-debug.jsonl";
|
|
47
|
+
try {
|
|
48
|
+
fs.writeFileSync(filePath, "");
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
console.error(`Stanterprise Reporter: Failed to initialize debug file "${filePath}":`, e);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Appends a single JSONL entry for an outgoing gRPC message.
|
|
56
|
+
* Each entry is a JSON object on its own line containing the timestamp,
|
|
57
|
+
* gRPC method path, and the serialized message payload.
|
|
58
|
+
* No-op when debug mode is disabled.
|
|
59
|
+
*/
|
|
60
|
+
function writeDebugEntry(options, path, message) {
|
|
61
|
+
if (!options.debug)
|
|
62
|
+
return;
|
|
63
|
+
const filePath = options.debugFile || "stanterprise-debug.jsonl";
|
|
64
|
+
const entry = {
|
|
65
|
+
timestamp: new Date().toISOString(),
|
|
66
|
+
path,
|
|
67
|
+
message,
|
|
68
|
+
};
|
|
69
|
+
try {
|
|
70
|
+
fs.appendFileSync(filePath, JSON.stringify(entry) + "\n");
|
|
71
|
+
}
|
|
72
|
+
catch (e) {
|
|
73
|
+
console.error(`Stanterprise Reporter: Failed to write debug entry to "${filePath}":`, e);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieves environment variables with the STANTERPRISE_META_ prefix
|
|
3
|
+
* and returns them as a Map with the prefix stripped from keys.
|
|
4
|
+
*
|
|
5
|
+
* For example, STANTERPRISE_META_BUILD_ID=123 becomes BUILD_ID=123 in the metadata.
|
|
6
|
+
*
|
|
7
|
+
* @returns Map of metadata key-value pairs with prefix removed
|
|
8
|
+
*/
|
|
9
|
+
export declare function getEnvVariables(): Map<string, string>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getEnvVariables = getEnvVariables;
|
|
4
|
+
/**
|
|
5
|
+
* Retrieves environment variables with the STANTERPRISE_META_ prefix
|
|
6
|
+
* and returns them as a Map with the prefix stripped from keys.
|
|
7
|
+
*
|
|
8
|
+
* For example, STANTERPRISE_META_BUILD_ID=123 becomes BUILD_ID=123 in the metadata.
|
|
9
|
+
*
|
|
10
|
+
* @returns Map of metadata key-value pairs with prefix removed
|
|
11
|
+
*/
|
|
12
|
+
function getEnvVariables() {
|
|
13
|
+
const envValues = process.env;
|
|
14
|
+
const prefix = "STANTERPRISE_META_";
|
|
15
|
+
const filteredEntries = Object.entries(envValues)
|
|
16
|
+
.filter(([key]) => key.startsWith(prefix))
|
|
17
|
+
.map(([key, value]) => {
|
|
18
|
+
// Strip the STANTERPRISE_META_ prefix so metadata keys are cleaner
|
|
19
|
+
const strippedKey = key.substring(prefix.length);
|
|
20
|
+
return [strippedKey, value || ""];
|
|
21
|
+
});
|
|
22
|
+
return new Map(filteredEntries);
|
|
23
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Suite, TestCase, TestStep } from "@playwright/test/reporter";
|
|
2
|
+
/**
|
|
3
|
+
* Generates a unique suite ID based on the suite's title path.
|
|
4
|
+
* @param suite The Playwright Suite object.
|
|
5
|
+
* @returns A unique string ID for the suite.
|
|
6
|
+
*/
|
|
7
|
+
export declare function generateSuiteId(suite: Suite): string;
|
|
8
|
+
/**
|
|
9
|
+
* Generates a unique test ID based on the test case. Currently uses the test's existing ID.
|
|
10
|
+
* @param test The Playwright TestCase object.
|
|
11
|
+
* @returns A unique string ID for the test case.
|
|
12
|
+
*/
|
|
13
|
+
export declare function generateTestId(test: TestCase): string;
|
|
14
|
+
/**
|
|
15
|
+
* Generates a unique step ID based on the step and its parent test case.
|
|
16
|
+
* @param step The Playwright TestStep object.
|
|
17
|
+
* @param test The Playwright TestCase object that the step belongs to.
|
|
18
|
+
* @returns A unique string ID for the step.
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateStepId(step: TestStep, test: TestCase): string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateSuiteId = generateSuiteId;
|
|
7
|
+
exports.generateTestId = generateTestId;
|
|
8
|
+
exports.generateStepId = generateStepId;
|
|
9
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
10
|
+
/**
|
|
11
|
+
* Generates a unique suite ID based on the suite's title path.
|
|
12
|
+
* @param suite The Playwright Suite object.
|
|
13
|
+
* @returns A unique string ID for the suite.
|
|
14
|
+
*/
|
|
15
|
+
function generateSuiteId(suite) {
|
|
16
|
+
return crypto_1.default
|
|
17
|
+
.createHash("sha256")
|
|
18
|
+
.update(suite.titlePath().join(":"))
|
|
19
|
+
.digest("hex");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Generates a unique test ID based on the test case. Currently uses the test's existing ID.
|
|
23
|
+
* @param test The Playwright TestCase object.
|
|
24
|
+
* @returns A unique string ID for the test case.
|
|
25
|
+
*/
|
|
26
|
+
function generateTestId(test) {
|
|
27
|
+
return test.id;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Generates a unique step ID based on the step and its parent test case.
|
|
31
|
+
* @param step The Playwright TestStep object.
|
|
32
|
+
* @param test The Playwright TestCase object that the step belongs to.
|
|
33
|
+
* @returns A unique string ID for the step.
|
|
34
|
+
*/
|
|
35
|
+
function generateStepId(step, test) {
|
|
36
|
+
return crypto_1.default
|
|
37
|
+
.createHash("sha256")
|
|
38
|
+
.update(`${test.id}:${step.titlePath().join(":")}`)
|
|
39
|
+
.digest("hex");
|
|
40
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility exports - centralized access to all utility functions
|
|
3
|
+
*/
|
|
4
|
+
export * from "./statusMapper";
|
|
5
|
+
export * from "./attachmentProcessor";
|
|
6
|
+
export * from "./timeHelpers";
|
|
7
|
+
export * from "./idGenerators";
|
|
8
|
+
export * from "./envRetriever";
|
|
9
|
+
export * from "./metadataHelpers";
|
|
10
|
+
export * from "./debugLogger";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/**
|
|
18
|
+
* Utility exports - centralized access to all utility functions
|
|
19
|
+
*/
|
|
20
|
+
__exportStar(require("./statusMapper"), exports);
|
|
21
|
+
__exportStar(require("./attachmentProcessor"), exports);
|
|
22
|
+
__exportStar(require("./timeHelpers"), exports);
|
|
23
|
+
__exportStar(require("./idGenerators"), exports);
|
|
24
|
+
__exportStar(require("./envRetriever"), exports);
|
|
25
|
+
__exportStar(require("./metadataHelpers"), exports);
|
|
26
|
+
__exportStar(require("./debugLogger"), exports);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for building metadata objects
|
|
3
|
+
*/
|
|
4
|
+
import type { TestCase, TestResult, TestStep } from "@playwright/test/reporter";
|
|
5
|
+
/**
|
|
6
|
+
* Truncate a string to a maximum length with ellipsis indicator
|
|
7
|
+
* @param value String value to truncate
|
|
8
|
+
* @param maxLength Maximum length (default 100KB)
|
|
9
|
+
* @returns Truncated string with warning suffix if truncated
|
|
10
|
+
*/
|
|
11
|
+
export declare function truncateValue(value: string, maxLength?: number): string;
|
|
12
|
+
/**
|
|
13
|
+
* Build metadata from annotations array
|
|
14
|
+
* @param annotations Array of annotations with type and optional description
|
|
15
|
+
* @param prefix Prefix for metadata keys (e.g., "annotation", "result_annotation")
|
|
16
|
+
* @returns Record of metadata key-value pairs
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildAnnotationsMetadata(annotations: Array<{
|
|
19
|
+
type: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
}>, prefix?: string): Record<string, string>;
|
|
22
|
+
/**
|
|
23
|
+
* Build metadata from test case and result annotations
|
|
24
|
+
* Combines annotations from both the test case and the result
|
|
25
|
+
* @param test Test case containing annotations
|
|
26
|
+
* @param result Test result containing additional annotations
|
|
27
|
+
* @returns Record of metadata key-value pairs
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildTestMetadata(test: TestCase, result: TestResult): Record<string, string>;
|
|
30
|
+
/**
|
|
31
|
+
* Build metadata from step annotations and category
|
|
32
|
+
* @param step Test step containing annotations and category
|
|
33
|
+
* @returns Record of metadata key-value pairs
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildStepMetadata(step: TestStep): Record<string, string>;
|
|
36
|
+
/**
|
|
37
|
+
* Convert metadata object to Map for protobuf serialization
|
|
38
|
+
* Protobuf requires Map<string, string> for metadata fields
|
|
39
|
+
* @param metadata Record of metadata key-value pairs
|
|
40
|
+
* @returns Map ready for protobuf constructors
|
|
41
|
+
*/
|
|
42
|
+
export declare function toMetadataMap(metadata: Record<string, string>): Map<string, string>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.truncateValue = truncateValue;
|
|
4
|
+
exports.buildAnnotationsMetadata = buildAnnotationsMetadata;
|
|
5
|
+
exports.buildTestMetadata = buildTestMetadata;
|
|
6
|
+
exports.buildStepMetadata = buildStepMetadata;
|
|
7
|
+
exports.toMetadataMap = toMetadataMap;
|
|
8
|
+
/**
|
|
9
|
+
* Maximum length for a single metadata value (100KB)
|
|
10
|
+
* Large values are often accidentally embedded test data or debug output
|
|
11
|
+
*/
|
|
12
|
+
const MAX_METADATA_VALUE_LENGTH = 102400;
|
|
13
|
+
/**
|
|
14
|
+
* Maximum total metadata size across all values (1MB)
|
|
15
|
+
*/
|
|
16
|
+
const MAX_TOTAL_METADATA_SIZE = 1048576;
|
|
17
|
+
/**
|
|
18
|
+
* Truncate a string to a maximum length with ellipsis indicator
|
|
19
|
+
* @param value String value to truncate
|
|
20
|
+
* @param maxLength Maximum length (default 100KB)
|
|
21
|
+
* @returns Truncated string with warning suffix if truncated
|
|
22
|
+
*/
|
|
23
|
+
function truncateValue(value, maxLength = MAX_METADATA_VALUE_LENGTH) {
|
|
24
|
+
if (value.length <= maxLength) {
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
const truncated = value.substring(0, maxLength - 100);
|
|
28
|
+
return `${truncated}... [TRUNCATED: original length ${value.length} bytes, showing first ${maxLength - 100} bytes]`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build metadata from annotations array
|
|
32
|
+
* @param annotations Array of annotations with type and optional description
|
|
33
|
+
* @param prefix Prefix for metadata keys (e.g., "annotation", "result_annotation")
|
|
34
|
+
* @returns Record of metadata key-value pairs
|
|
35
|
+
*/
|
|
36
|
+
function buildAnnotationsMetadata(annotations, prefix = "annotation") {
|
|
37
|
+
const metadata = {};
|
|
38
|
+
let totalSize = 0;
|
|
39
|
+
for (let index = 0; index < annotations.length; index++) {
|
|
40
|
+
const annotation = annotations[index];
|
|
41
|
+
const typeKey = `${prefix}_${index}_type`;
|
|
42
|
+
const typeValue = annotation.type;
|
|
43
|
+
metadata[typeKey] = typeValue;
|
|
44
|
+
totalSize += typeValue.length;
|
|
45
|
+
if (annotation.description) {
|
|
46
|
+
const descKey = `${prefix}_${index}_description`;
|
|
47
|
+
const descValue = truncateValue(annotation.description);
|
|
48
|
+
// Skip if adding this would exceed total metadata size
|
|
49
|
+
if (totalSize + descValue.length > MAX_TOTAL_METADATA_SIZE) {
|
|
50
|
+
console.warn(`Skipping annotation description for ${typeKey}: would exceed total metadata size limit (${MAX_TOTAL_METADATA_SIZE} bytes)`);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
metadata[descKey] = descValue;
|
|
54
|
+
totalSize += descValue.length;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return metadata;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build metadata from test case and result annotations
|
|
61
|
+
* Combines annotations from both the test case and the result
|
|
62
|
+
* @param test Test case containing annotations
|
|
63
|
+
* @param result Test result containing additional annotations
|
|
64
|
+
* @returns Record of metadata key-value pairs
|
|
65
|
+
*/
|
|
66
|
+
function buildTestMetadata(test, result) {
|
|
67
|
+
return {
|
|
68
|
+
...buildAnnotationsMetadata(test.annotations, "annotation"),
|
|
69
|
+
...buildAnnotationsMetadata(result.annotations, "result_annotation"),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Build metadata from step annotations and category
|
|
74
|
+
* @param step Test step containing annotations and category
|
|
75
|
+
* @returns Record of metadata key-value pairs
|
|
76
|
+
*/
|
|
77
|
+
function buildStepMetadata(step) {
|
|
78
|
+
return {
|
|
79
|
+
category: step.category,
|
|
80
|
+
...buildAnnotationsMetadata(step.annotations, "annotation"),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Convert metadata object to Map for protobuf serialization
|
|
85
|
+
* Protobuf requires Map<string, string> for metadata fields
|
|
86
|
+
* @param metadata Record of metadata key-value pairs
|
|
87
|
+
* @returns Map ready for protobuf constructors
|
|
88
|
+
*/
|
|
89
|
+
function toMetadataMap(metadata) {
|
|
90
|
+
return new Map(Object.entries(metadata));
|
|
91
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { StanterpriseReporterOptions } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Define and map reporter options from provided options and environment variables. Apply defaults where necessary.
|
|
4
|
+
* @param providedOptions Options provided during reporter initialization
|
|
5
|
+
* @returns Mapped and completed StanterpriseReporterOptions
|
|
6
|
+
*/
|
|
7
|
+
export default function defineOptions(providedOptions: StanterpriseReporterOptions): StanterpriseReporterOptions;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = defineOptions;
|
|
4
|
+
/**
|
|
5
|
+
* Define and map reporter options from provided options and environment variables. Apply defaults where necessary.
|
|
6
|
+
* @param providedOptions Options provided during reporter initialization
|
|
7
|
+
* @returns Mapped and completed StanterpriseReporterOptions
|
|
8
|
+
*/
|
|
9
|
+
function defineOptions(providedOptions) {
|
|
10
|
+
const result = {};
|
|
11
|
+
result.grpcAddress =
|
|
12
|
+
providedOptions.grpcAddress ||
|
|
13
|
+
process.env.STANTERPRISE_GRPC_ADDRESS ||
|
|
14
|
+
"localhost:50051";
|
|
15
|
+
result.grpcEnabled =
|
|
16
|
+
providedOptions.grpcEnabled ??
|
|
17
|
+
(process.env.STANTERPRISE_GRPC_ENABLED || "true").toLowerCase() !== "false";
|
|
18
|
+
result.grpcTimeout = providedOptions.grpcTimeout || 1000;
|
|
19
|
+
result.grpcMaxMessageSize = providedOptions.grpcMaxMessageSize || 104857600;
|
|
20
|
+
result.maxAttachmentSize = providedOptions.maxAttachmentSize || 10485760;
|
|
21
|
+
result.verbose = providedOptions.verbose || false;
|
|
22
|
+
result.grpcMaxRetries = providedOptions.grpcMaxRetries ?? 3;
|
|
23
|
+
result.grpcRetryDelay = providedOptions.grpcRetryDelay || 100;
|
|
24
|
+
result.debug =
|
|
25
|
+
providedOptions.debug ?? process.env.STANTERPRISE_DEBUG === "true";
|
|
26
|
+
result.debugFile =
|
|
27
|
+
providedOptions.debugFile ||
|
|
28
|
+
process.env.STANTERPRISE_DEBUG_FILE ||
|
|
29
|
+
"stanterprise-debug.jsonl";
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for mapping Playwright types to protobuf types
|
|
3
|
+
*/
|
|
4
|
+
import type { TestResult } from "@playwright/test/reporter";
|
|
5
|
+
/**
|
|
6
|
+
* Map Playwright test status to protobuf TestStatus
|
|
7
|
+
*/
|
|
8
|
+
export declare function mapTestStatus(status: TestResult["status"]): number;
|
|
9
|
+
/**
|
|
10
|
+
* Map step error to test status
|
|
11
|
+
*/
|
|
12
|
+
export declare function mapStepStatus(hasError: boolean): number;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mapTestStatus = mapTestStatus;
|
|
4
|
+
exports.mapStepStatus = mapStepStatus;
|
|
5
|
+
const protobuf_1 = require("@stanterprise/protobuf");
|
|
6
|
+
const TestStatus = protobuf_1.common.v1.common.TestStatus;
|
|
7
|
+
/**
|
|
8
|
+
* Map Playwright test status to protobuf TestStatus
|
|
9
|
+
*/
|
|
10
|
+
function mapTestStatus(status) {
|
|
11
|
+
switch (status) {
|
|
12
|
+
case "passed":
|
|
13
|
+
return TestStatus.PASSED;
|
|
14
|
+
case "failed":
|
|
15
|
+
return TestStatus.FAILED;
|
|
16
|
+
case "skipped":
|
|
17
|
+
return TestStatus.SKIPPED;
|
|
18
|
+
case "timedOut":
|
|
19
|
+
return TestStatus.FAILED; // Treat timeout as failed
|
|
20
|
+
default:
|
|
21
|
+
return TestStatus.UNKNOWN;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Map step error to test status
|
|
26
|
+
*/
|
|
27
|
+
function mapStepStatus(hasError) {
|
|
28
|
+
return hasError ? TestStatus.FAILED : TestStatus.PASSED;
|
|
29
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for creating timestamps and durations
|
|
3
|
+
*/
|
|
4
|
+
import { google } from "@stanterprise/protobuf";
|
|
5
|
+
declare const Timestamp: typeof google.google.protobuf.Timestamp;
|
|
6
|
+
/**
|
|
7
|
+
* Create a protobuf Timestamp from a JavaScript Date
|
|
8
|
+
*/
|
|
9
|
+
export declare function createTimestamp(date: Date): InstanceType<typeof Timestamp>;
|
|
10
|
+
/**
|
|
11
|
+
* Create a protobuf Timestamp from milliseconds since epoch
|
|
12
|
+
*/
|
|
13
|
+
export declare function createTimestampFromMs(ms: number): InstanceType<typeof Timestamp>;
|
|
14
|
+
/**
|
|
15
|
+
* Create a duration object from milliseconds.
|
|
16
|
+
*
|
|
17
|
+
* NOTE: google.protobuf.Duration is defined in the @stanterprise/protobuf schema
|
|
18
|
+
* but not exported in the package's main barrel export. Since Duration and Timestamp
|
|
19
|
+
* have identical structure (seconds: number, nanos: number) and the protobuf serialization
|
|
20
|
+
* is wire-compatible, we use Timestamp as a Duration substitute. This works correctly at runtime.
|
|
21
|
+
*
|
|
22
|
+
* @param durationMs Duration in milliseconds
|
|
23
|
+
* @returns A Duration object (implemented as Timestamp due to export limitations)
|
|
24
|
+
*/
|
|
25
|
+
export declare function createDuration(durationMs: number): any;
|
|
26
|
+
export {};
|